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