1#include <stdio.h> 2#include <netdb.h> 3#include <string.h> 4#include <stdlib.h> 5#include <getopt.h> 6#include <ctype.h> 7 8#include <iptables.h> 9 10#include <linux/netfilter_ipv4/ipt_ipp2p.h> 11 12#ifndef XTABLES_VERSION 13#define XTABLES_VERSION IPTABLES_VERSION 14#endif 15 16#ifdef IPT_LIB_DIR 17#define xtables_match iptables_match 18#define xtables_register_match register_match 19#endif 20 21static void 22help(void) 23{ 24 printf( 25 "IPP2P v%s options:\n" 26 " --ipp2p Grab all known p2p packets\n" 27 " --edk [TCP&UDP] All known eDonkey/eMule/Overnet packets\n" 28 " --dc [TCP] All known Direct Connect packets\n" 29 " --kazaa [TCP&UDP] All known KaZaA packets\n" 30 " --gnu [TCP&UDP] All known Gnutella packets\n" 31 " --bit [TCP&UDP] All known BitTorrent packets\n" 32 " --apple [TCP] All known AppleJuice packets\n" 33 " --winmx [TCP] All known WinMX\n" 34 " --soul [TCP] All known SoulSeek\n" 35 " --ares [TCP] All known Ares\n\n" 36 " EXPERIMENTAL protocols (please send feedback to: ipp2p@ipp2p.org) :\n" 37 " --mute [TCP] All known Mute packets\n" 38 " --waste [TCP] All known Waste packets\n" 39 " --xdcc [TCP] All known XDCC packets (only xdcc login)\n\n" 40 " DEBUG SUPPPORT, use only if you know why\n" 41 " --debug Generate kernel debug output, THIS WILL SLOW DOWN THE FILTER\n" 42 "\nNote that the follwing options will have the same meaning:\n" 43 " '--ipp2p' is equal to '--edk --dc --kazaa --gnu --bit --apple --winmx --soul --ares'\n" 44 "\nIPP2P was intended for TCP only. Due to increasing usage of UDP we needed to change this.\n" 45 "You can now use -p udp to search UDP packets only or without -p switch to search UDP and TCP packets.\n" 46 "\nSee README included with this package for more details or visit http://www.ipp2p.org\n" 47 "\nExamples:\n" 48 " iptables -A FORWARD -m ipp2p --ipp2p -j MARK --set-mark 0x01\n" 49 " iptables -A FORWARD -p udp -m ipp2p --kazaa --bit -j DROP\n" 50 " iptables -A FORWARD -p tcp -m ipp2p --edk --soul -j DROP\n\n" 51 , IPP2P_VERSION); 52} 53 54static struct option opts[] = { 55 { "ipp2p", 0, 0, '1' }, 56 { "edk", 0, 0, '2' }, 57 { "dc", 0, 0, '7' }, 58 { "gnu", 0, 0, '9' }, 59 { "kazaa", 0, 0, 'a' }, 60 { "bit", 0, 0, 'b' }, 61 { "apple", 0, 0, 'c' }, 62 { "soul", 0, 0, 'd' }, 63 { "winmx", 0, 0, 'e' }, 64 { "ares", 0, 0, 'f' }, 65 { "mute", 0, 0, 'g' }, 66 { "waste", 0, 0, 'h' }, 67 { "xdcc", 0, 0, 'i' }, 68 { "debug", 0, 0, 'j' }, 69 {0} 70}; 71 72 73static void 74#ifdef _XTABLES_H 75init(struct xt_entry_match *m) 76#else 77init(struct ipt_entry_match *m, unsigned int *nfcache) 78#endif 79{ 80 struct ipt_p2p_info *info = (struct ipt_p2p_info *)m->data; 81 82#ifndef _XTABLES_H 83 *nfcache |= NFC_UNKNOWN; 84#endif 85 86 /*init the module with default values*/ 87 info->cmd = 0; 88 info->debug = 0; 89 90} 91 92 93static int 94parse(int c, char **argv, int invert, unsigned int *flags, 95#ifdef _XTABLES_H 96 const void *entry, struct xt_entry_match **match) 97#else 98 const struct ipt_entry *entry, unsigned int *nfcache, struct ipt_entry_match **match) 99#endif 100{ 101 struct ipt_p2p_info *info = (struct ipt_p2p_info *)(*match)->data; 102 103 switch (c) { 104 case '1': /*cmd: ipp2p*/ 105 if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) 106 exit_error(PARAMETER_PROBLEM, 107 "ipp2p: `--ipp2p' may only be " 108 "specified once!"); 109 110/* if ((*flags & SHORT_HAND_DATA) == SHORT_HAND_DATA) 111 exit_error(PARAMETER_PROBLEM, 112 "ipp2p: `--ipp2p-data' may only be " 113 "specified alone!"); 114*/ 115 116 if ((*flags) != 0) 117 exit_error(PARAMETER_PROBLEM, 118 "ipp2p: `--ipp2p' may only be " 119 "specified alone!"); 120 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 121 *flags += SHORT_HAND_IPP2P; 122 info->cmd = *flags; 123 break; 124 125 case '2': /*cmd: edk*/ 126 if ((*flags & IPP2P_EDK) == IPP2P_EDK) 127 exit_error(PARAMETER_PROBLEM, 128 "ipp2p: `--edk' may only be " 129 "specified once"); 130 if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) 131 exit_error(PARAMETER_PROBLEM, 132 "ipp2p: `--ipp2p' may only be " 133 "specified alone!"); 134/* if ((*flags & SHORT_HAND_DATA) == SHORT_HAND_DATA) 135 exit_error(PARAMETER_PROBLEM, 136 "ipp2p: `--ipp2p-data' may only be " 137 "specified alone!");*/ 138 if ((*flags & IPP2P_DATA_EDK) == IPP2P_DATA_EDK) 139 exit_error(PARAMETER_PROBLEM, 140 "ipp2p: use `--edk' OR `--edk-data' but not both of them!"); 141 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 142 *flags += IPP2P_EDK; 143 info->cmd = *flags; 144 break; 145 146 147 case '7': /*cmd: dc*/ 148 if ((*flags & IPP2P_DC) == IPP2P_DC) 149 exit_error(PARAMETER_PROBLEM, 150 "ipp2p: `--dc' may only be " 151 "specified once!"); 152 if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) 153 exit_error(PARAMETER_PROBLEM, 154 "ipp2p: `--ipp2p' may only be " 155 "specified alone!"); 156/* if ((*flags & SHORT_HAND_DATA) == SHORT_HAND_DATA) 157 exit_error(PARAMETER_PROBLEM, 158 "ipp2p: `--ipp2p-data' may only be " 159 "specified alone!");*/ 160 if ((*flags & IPP2P_DATA_DC) == IPP2P_DATA_DC) 161 exit_error(PARAMETER_PROBLEM, 162 "ipp2p: use `--dc' OR `--dc-data' but not both of them!"); 163 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 164 *flags += IPP2P_DC; 165 info->cmd = *flags; 166 break; 167 168 169 case '9': /*cmd: gnu*/ 170 if ((*flags & IPP2P_GNU) == IPP2P_GNU) 171 exit_error(PARAMETER_PROBLEM, 172 "ipp2p: `--gnu' may only be " 173 "specified once!"); 174/* if ((*flags & SHORT_HAND_DATA) == SHORT_HAND_DATA) 175 exit_error(PARAMETER_PROBLEM, 176 "ipp2p: `--ipp2p-data' may only be " 177 "specified alone!");*/ 178 if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) 179 exit_error(PARAMETER_PROBLEM, 180 "ipp2p: `--ipp2p' may only be " 181 "specified alone!"); 182 if ((*flags & IPP2P_DATA_GNU) == IPP2P_DATA_GNU) 183 exit_error(PARAMETER_PROBLEM, 184 "ipp2p: use `--gnu' OR `--gnu-data' but not both of them!"); 185 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 186 *flags += IPP2P_GNU; 187 info->cmd = *flags; 188 break; 189 190 case 'a': /*cmd: kazaa*/ 191 if ((*flags & IPP2P_KAZAA) == IPP2P_KAZAA) 192 exit_error(PARAMETER_PROBLEM, 193 "ipp2p: `--kazaa' may only be " 194 "specified once!"); 195/* if ((*flags & SHORT_HAND_DATA) == SHORT_HAND_DATA) 196 exit_error(PARAMETER_PROBLEM, 197 "ipp2p: `--ipp2p-data' may only be " 198 "specified alone!");*/ 199 if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) 200 exit_error(PARAMETER_PROBLEM, 201 "ipp2p: `--ipp2p' may only be " 202 "specified alone!"); 203 if ((*flags & IPP2P_DATA_KAZAA) == IPP2P_DATA_KAZAA) 204 exit_error(PARAMETER_PROBLEM, 205 "ipp2p: use `--kazaa' OR `--kazaa-data' but not both of them!"); 206 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 207 *flags += IPP2P_KAZAA; 208 info->cmd = *flags; 209 break; 210 211 case 'b': /*cmd: bit*/ 212 if ((*flags & IPP2P_BIT) == IPP2P_BIT) 213 exit_error(PARAMETER_PROBLEM, 214 "ipp2p: `--bit' may only be " 215 "specified once!"); 216 if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) 217 exit_error(PARAMETER_PROBLEM, 218 "ipp2p: `--ipp2p' may only be " 219 "specified alone!"); 220 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 221 *flags += IPP2P_BIT; 222 info->cmd = *flags; 223 break; 224 225 case 'c': /*cmd: apple*/ 226 if ((*flags & IPP2P_APPLE) == IPP2P_APPLE) 227 exit_error(PARAMETER_PROBLEM, 228 "ipp2p: `--apple' may only be " 229 "specified once!"); 230 if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) 231 exit_error(PARAMETER_PROBLEM, 232 "ipp2p: `--ipp2p' may only be " 233 "specified alone!"); 234 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 235 *flags += IPP2P_APPLE; 236 info->cmd = *flags; 237 break; 238 239 240 case 'd': /*cmd: soul*/ 241 if ((*flags & IPP2P_SOUL) == IPP2P_SOUL) 242 exit_error(PARAMETER_PROBLEM, 243 "ipp2p: `--soul' may only be " 244 "specified once!"); 245 if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) 246 exit_error(PARAMETER_PROBLEM, 247 "ipp2p: `--ipp2p' may only be " 248 "specified alone!"); 249 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 250 *flags += IPP2P_SOUL; 251 info->cmd = *flags; 252 break; 253 254 255 case 'e': /*cmd: winmx*/ 256 if ((*flags & IPP2P_WINMX) == IPP2P_WINMX) 257 exit_error(PARAMETER_PROBLEM, 258 "ipp2p: `--winmx' may only be " 259 "specified once!"); 260 if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) 261 exit_error(PARAMETER_PROBLEM, 262 "ipp2p: `--ipp2p' may only be " 263 "specified alone!"); 264 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 265 *flags += IPP2P_WINMX; 266 info->cmd = *flags; 267 break; 268 269 case 'f': /*cmd: ares*/ 270 if ((*flags & IPP2P_ARES) == IPP2P_ARES) 271 exit_error(PARAMETER_PROBLEM, 272 "ipp2p: `--ares' may only be " 273 "specified once!"); 274 if ((*flags & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) 275 exit_error(PARAMETER_PROBLEM, 276 "ipp2p: `--ipp2p' may only be " 277 "specified alone!"); 278 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 279 *flags += IPP2P_ARES; 280 info->cmd = *flags; 281 break; 282 283 case 'g': /*cmd: mute*/ 284 if ((*flags & IPP2P_MUTE) == IPP2P_MUTE) 285 exit_error(PARAMETER_PROBLEM, 286 "ipp2p: `--mute' may only be " 287 "specified once!"); 288 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 289 *flags += IPP2P_MUTE; 290 info->cmd = *flags; 291 break; 292 case 'h': /*cmd: waste*/ 293 if ((*flags & IPP2P_WASTE) == IPP2P_WASTE) 294 exit_error(PARAMETER_PROBLEM, 295 "ipp2p: `--waste' may only be " 296 "specified once!"); 297 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 298 *flags += IPP2P_WASTE; 299 info->cmd = *flags; 300 break; 301 case 'i': /*cmd: xdcc*/ 302 if ((*flags & IPP2P_XDCC) == IPP2P_XDCC) 303 exit_error(PARAMETER_PROBLEM, 304 "ipp2p: `--ares' may only be " 305 "specified once!"); 306 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 307 *flags += IPP2P_XDCC; 308 info->cmd = *flags; 309 break; 310 311 case 'j': /*cmd: debug*/ 312 if (invert) exit_error(PARAMETER_PROBLEM, "ipp2p: invert [!] is not allowed!"); 313 info->debug = 1; 314 break; 315 316 default: 317// exit_error(PARAMETER_PROBLEM, 318// "\nipp2p-parameter problem: for ipp2p usage type: iptables -m ipp2p --help\n"); 319 return 0; 320 } 321 return 1; 322} 323 324 325static void 326final_check(unsigned int flags) 327{ 328 if (!flags) 329 exit_error(PARAMETER_PROBLEM, 330 "\nipp2p-parameter problem: for ipp2p usage type: iptables -m ipp2p --help\n"); 331} 332 333static void 334#ifdef _XTABLES_H 335print(const void *ip, 336 const struct xt_entry_match *match, 337#else 338print(const struct ipt_ip *ip, 339 const struct ipt_entry_match *match, 340#endif 341 int numeric) 342{ 343 struct ipt_p2p_info *info = (struct ipt_p2p_info *)match->data; 344 345 printf("ipp2p v%s", IPP2P_VERSION); 346 if ((info->cmd & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) printf(" --ipp2p"); 347// if ((info->cmd & SHORT_HAND_DATA) == SHORT_HAND_DATA) printf(" --ipp2p-data"); 348 if ((info->cmd & IPP2P_KAZAA) == IPP2P_KAZAA) printf(" --kazaa"); 349// if ((info->cmd & IPP2P_DATA_KAZAA) == IPP2P_DATA_KAZAA) printf(" --kazaa-data"); 350// if ((info->cmd & IPP2P_DATA_GNU) == IPP2P_DATA_GNU) printf(" --gnu-data"); 351 if ((info->cmd & IPP2P_GNU) == IPP2P_GNU) printf(" --gnu"); 352 if ((info->cmd & IPP2P_EDK) == IPP2P_EDK) printf(" --edk"); 353// if ((info->cmd & IPP2P_DATA_EDK) == IPP2P_DATA_EDK) printf(" --edk-data"); 354// if ((info->cmd & IPP2P_DATA_DC) == IPP2P_DATA_DC) printf(" --dc-data"); 355 if ((info->cmd & IPP2P_DC) == IPP2P_DC) printf(" --dc"); 356 if ((info->cmd & IPP2P_BIT) == IPP2P_BIT) printf(" --bit"); 357 if ((info->cmd & IPP2P_APPLE) == IPP2P_APPLE) printf(" --apple"); 358 if ((info->cmd & IPP2P_SOUL) == IPP2P_SOUL) printf(" --soul"); 359 if ((info->cmd & IPP2P_WINMX) == IPP2P_WINMX) printf(" --winmx"); 360 if ((info->cmd & IPP2P_ARES) == IPP2P_ARES) printf(" --ares"); 361 if ((info->cmd & IPP2P_MUTE) == IPP2P_MUTE) printf(" --mute"); 362 if ((info->cmd & IPP2P_WASTE) == IPP2P_WASTE) printf(" --waste"); 363 if ((info->cmd & IPP2P_XDCC) == IPP2P_XDCC) printf(" --xdcc"); 364 if (info->debug != 0) printf(" --debug"); 365 printf(" "); 366} 367 368static void 369#ifdef _XTABLES_H 370save(const void *ip, 371 const struct xt_entry_match *match) 372#else 373save(const struct ipt_ip *ip, 374 const struct ipt_entry_match *match) 375#endif 376{ 377 struct ipt_p2p_info *info = (struct ipt_p2p_info *)match->data; 378 379 if ((info->cmd & SHORT_HAND_IPP2P) == SHORT_HAND_IPP2P) printf("--ipp2p "); 380// if ((info->cmd & SHORT_HAND_DATA) == SHORT_HAND_DATA) printf("--ipp2p-data "); 381 if ((info->cmd & IPP2P_KAZAA) == IPP2P_KAZAA) printf("--kazaa "); 382// if ((info->cmd & IPP2P_DATA_KAZAA) == IPP2P_DATA_KAZAA) printf("--kazaa-data "); 383// if ((info->cmd & IPP2P_DATA_GNU) == IPP2P_DATA_GNU) printf("--gnu-data "); 384 if ((info->cmd & IPP2P_GNU) == IPP2P_GNU) printf("--gnu "); 385 if ((info->cmd & IPP2P_EDK) == IPP2P_EDK) printf("--edk "); 386// if ((info->cmd & IPP2P_DATA_EDK) == IPP2P_DATA_EDK) printf("--edk-data "); 387// if ((info->cmd & IPP2P_DATA_DC) == IPP2P_DATA_DC) printf("--dc-data "); 388 if ((info->cmd & IPP2P_DC) == IPP2P_DC) printf("--dc "); 389 if ((info->cmd & IPP2P_BIT) == IPP2P_BIT) printf("--bit "); 390 if ((info->cmd & IPP2P_APPLE) == IPP2P_APPLE) printf("--apple "); 391 if ((info->cmd & IPP2P_SOUL) == IPP2P_SOUL) printf("--soul "); 392 if ((info->cmd & IPP2P_WINMX) == IPP2P_WINMX) printf("--winmx "); 393 if ((info->cmd & IPP2P_ARES) == IPP2P_ARES) printf("--ares "); 394 if ((info->cmd & IPP2P_MUTE) == IPP2P_MUTE) printf(" --mute"); 395 if ((info->cmd & IPP2P_WASTE) == IPP2P_WASTE) printf(" --waste"); 396 if ((info->cmd & IPP2P_XDCC) == IPP2P_XDCC) printf(" --xdcc"); 397 if (info->debug != 0) printf("--debug "); 398} 399 400 401static 402struct xtables_match ipp2p= 403{ 404 .next = NULL, 405 .name = "ipp2p", 406 .version = XTABLES_VERSION, 407 .size = IPT_ALIGN(sizeof(struct ipt_p2p_info)), 408 .userspacesize = IPT_ALIGN(sizeof(struct ipt_p2p_info)), 409 .help = &help, 410 .init = &init, 411 .parse = &parse, 412 .final_check = &final_check, 413 .print = &print, 414 .save = &save, 415 .extra_opts = opts 416}; 417 418 419 420void _init(void) 421{ 422 xtables_register_match(&ipp2p); 423} 424 425