source:
freewrt/package/iptables/patches/02-layer7-1.5nbd.patch@
475ad56
| Last change on this file since 475ad56 was 475ad56, checked in by , 19 years ago | |
|---|---|
|
|
| File size: 11.5 KB | |
-
extensions/.layer7-test
diff -urN iptables.old/extensions/.layer7-test iptables.dev/extensions/.layer7-test
old new 1 #! /bin/sh 2 [ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_layer7.h ] && echo layer7 -
extensions/ipt_layer7.h
diff -urN iptables.old/extensions/ipt_layer7.h iptables.dev/extensions/ipt_layer7.h
old new 1 /* 2 By Matthew Strait <quadong@users.sf.net>, Dec 2003. 3 http://l7-filter.sf.net 4 5 This program is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License 7 as published by the Free Software Foundation; either version 8 2 of the License, or (at your option) any later version. 9 http://www.gnu.org/licenses/gpl.txt 10 */ 11 12 #ifndef _IPT_LAYER7_H 13 #define _IPT_LAYER7_H 14 15 #define MAX_PATTERN_LEN 8192 16 #define MAX_PROTOCOL_LEN 256 17 18 typedef char *(*proc_ipt_search) (char *, char, char *); 19 20 struct ipt_layer7_info { 21 char protocol[MAX_PROTOCOL_LEN]; 22 char invert:1; 23 char pattern[MAX_PATTERN_LEN]; 24 char pkt; 25 }; 26 27 #endif /* _IPT_LAYER7_H */ -
extensions/libipt_layer7.c
diff -urN iptables.old/extensions/libipt_layer7.c iptables.dev/extensions/libipt_layer7.c
old new 1 /* 2 Shared library add-on to iptables to add layer 7 matching support. 3 4 By Matthew Strait <quadong@users.sf.net>, Oct 2003. 5 6 http://l7-filter.sf.net 7 8 This program is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License 10 as published by the Free Software Foundation; either version 11 2 of the License, or (at your option) any later version. 12 http://www.gnu.org/licenses/gpl.txt 13 14 Based on libipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be> 15 */ 16 17 #define _GNU_SOURCE 18 #include <stdio.h> 19 #include <netdb.h> 20 #include <string.h> 21 #include <stdlib.h> 22 #include <getopt.h> 23 #include <ctype.h> 24 #include <dirent.h> 25 26 #include <iptables.h> 27 #include "ipt_layer7.h" 28 29 #define MAX_FN_LEN 256 30 31 static char l7dir[MAX_FN_LEN] = "\0"; 32 33 /* Function which prints out usage message. */ 34 static void help(void) 35 { 36 printf( 37 "LAYER7 match v%s options:\n" 38 "--l7dir <directory> : Look for patterns here instead of /etc/l7-protocols/\n" 39 " (--l7dir must be specified before --l7proto if used!)\n" 40 "--l7proto [!] <name> : Match the protocol defined in /etc/l7-protocols/name.pat\n" 41 "--l7pkt : Skip connection tracking and match individual packets\n", 42 IPTABLES_VERSION); 43 fputc('\n', stdout); 44 } 45 46 static struct option opts[] = { 47 { .name = "l7proto", .has_arg = 1, .flag = 0, .val = '1' }, 48 { .name = "l7dir", .has_arg = 1, .flag = 0, .val = '2' }, 49 { .name = "l7pkt", .has_arg = 0, .flag = 0, .val = '3' }, 50 { .name = 0 } 51 }; 52 53 /* reads filename, puts protocol info into layer7_protocol_info, number of protocols to numprotos */ 54 int parse_protocol_file(char * filename, const unsigned char * protoname, struct ipt_layer7_info *info) 55 { 56 FILE * f; 57 char * line = NULL; 58 size_t len = 0; 59 60 enum { protocol, pattern, done } datatype = protocol; 61 62 f = fopen(filename, "r"); 63 64 if(!f) 65 return 0; 66 67 while(getline(&line, &len, f) != -1) 68 { 69 if(strlen(line) < 2 || line[0] == '#') 70 continue; 71 72 /* strip the pesky newline... */ 73 if(line[strlen(line) - 1] == '\n') 74 line[strlen(line) - 1] = '\0'; 75 76 if(datatype == protocol) 77 { 78 if(strcmp(line, protoname)) 79 exit_error(OTHER_PROBLEM, 80 "Protocol name (%s) doesn't match file name (%s). Bailing out\n", 81 protoname, filename); 82 83 if(strlen(line) >= MAX_PROTOCOL_LEN) 84 exit_error(PARAMETER_PROBLEM, 85 "Protocol name in %s too long!", filename); 86 strncpy(info->protocol, line, MAX_PROTOCOL_LEN); 87 88 datatype = pattern; 89 } 90 else if(datatype == pattern) 91 { 92 if(strlen(line) >= MAX_PATTERN_LEN) 93 exit_error(PARAMETER_PROBLEM, "Pattern in %s too long!", filename); 94 strncpy(info->pattern, line, MAX_PATTERN_LEN); 95 96 datatype = done; 97 break; 98 } 99 else 100 exit_error(OTHER_PROBLEM, "Internal error"); 101 } 102 103 if(datatype != done) 104 exit_error(OTHER_PROBLEM, "Failed to get all needed data from %s", filename); 105 106 if(line) free(line); 107 fclose(f); 108 109 return 1; 110 111 /* 112 fprintf(stderr, "protocol: %s\npattern: %s\n\n", 113 info->protocol, 114 info->pattern); 115 */ 116 } 117 118 static int hex2dec(char c) 119 { 120 switch (c) 121 { 122 case '0' ... '9': 123 return c - '0'; 124 case 'a' ... 'f': 125 return c - 'a' + 10; 126 case 'A' ... 'F': 127 return c - 'A' + 10; 128 default: 129 exit_error(OTHER_PROBLEM, "hex2dec: bad value!\n"); 130 return 0; 131 } 132 } 133 134 /* takes a string with \xHH escapes and returns one with the characters 135 they stand for */ 136 static char * pre_process(char * s) 137 { 138 char * result = malloc(strlen(s) + 1); 139 int sindex = 0, rindex = 0; 140 while( sindex < strlen(s) ) 141 { 142 if( sindex + 3 < strlen(s) && 143 s[sindex] == '\\' && s[sindex+1] == 'x' && 144 isxdigit(s[sindex + 2]) && isxdigit(s[sindex + 3]) ) 145 { 146 /* carefully remember to call tolower here... */ 147 result[rindex] = tolower( hex2dec(s[sindex + 2])*16 + 148 hex2dec(s[sindex + 3] ) ); 149 sindex += 3; /* 4 total */ 150 } 151 else 152 result[rindex] = tolower(s[sindex]); 153 154 sindex++; 155 rindex++; 156 } 157 result[rindex] = '\0'; 158 159 return result; 160 } 161 162 #define MAX_SUBDIRS 128 163 char ** readl7dir(char * dirname) 164 { 165 DIR * scratchdir; 166 struct dirent ** namelist; 167 char ** subdirs = malloc(MAX_SUBDIRS * sizeof(char *)); 168 169 int n, d = 1; 170 subdirs[0] = ""; 171 172 n = scandir(dirname, &namelist, 0, alphasort); 173 174 if (n < 0) 175 { 176 perror("scandir"); 177 exit_error(OTHER_PROBLEM, "Couldn't open %s\n", dirname); 178 } 179 else 180 { 181 while(n--) 182 { 183 char fulldirname[MAX_FN_LEN]; 184 185 snprintf(fulldirname, MAX_FN_LEN, "%s/%s", dirname, namelist[n]->d_name); 186 187 if((scratchdir = opendir(fulldirname)) != NULL) 188 { 189 closedir(scratchdir); 190 191 if(!strcmp(namelist[n]->d_name, ".") || 192 !strcmp(namelist[n]->d_name, "..")) 193 /* do nothing */ ; 194 else 195 { 196 subdirs[d] = malloc(strlen(namelist[n]->d_name) + 1); 197 strcpy(subdirs[d], namelist[n]->d_name); 198 d++; 199 if(d >= MAX_SUBDIRS - 1) 200 { 201 fprintf(stderr, 202 "Too many subdirectories, skipping the rest!\n"); 203 break; 204 } 205 } 206 } 207 free(namelist[n]); 208 } 209 free(namelist); 210 } 211 212 subdirs[d] = NULL; 213 214 return subdirs; 215 } 216 217 static void 218 parse_layer7_protocol(const unsigned char *s, struct ipt_layer7_info *info) 219 { 220 char filename[MAX_FN_LEN]; 221 char * dir = NULL; 222 char ** subdirs; 223 int n = 0, done = 0; 224 225 if(strlen(l7dir) > 0) 226 dir = l7dir; 227 else 228 dir = "/etc/l7-protocols"; 229 230 subdirs = readl7dir(dir); 231 232 while(subdirs[n] != NULL) 233 { 234 int c = snprintf(filename, MAX_FN_LEN, "%s/%s/%s.pat", dir, subdirs[n], s); 235 236 //fprintf(stderr, "Trying to find pattern in %s ... ", filename); 237 238 if(c > MAX_FN_LEN) 239 { 240 exit_error(OTHER_PROBLEM, 241 "Filename beginning with %s is too long!\n", filename); 242 } 243 244 /* read in the pattern from the file */ 245 if(parse_protocol_file(filename, s, info)) 246 { 247 //fprintf(stderr, "found\n"); 248 done = 1; 249 break; 250 } 251 252 //fprintf(stderr, "not found\n"); 253 254 n++; 255 } 256 257 if(!done) 258 exit_error(OTHER_PROBLEM, 259 "Couldn't find a pattern definition file for %s.\n", s); 260 261 /* process \xHH escapes and tolower everything. (our regex lib has no 262 case insensitivity option.) */ 263 strncpy(info->pattern, pre_process(info->pattern), MAX_PATTERN_LEN); 264 } 265 266 /* Function which parses command options; returns true if it ate an option */ 267 static int parse(int c, char **argv, int invert, unsigned int *flags, 268 const struct ipt_entry *entry, unsigned int *nfcache, 269 struct ipt_entry_match **match) 270 { 271 struct ipt_layer7_info *layer7info = 272 (struct ipt_layer7_info *)(*match)->data; 273 274 switch (c) { 275 case '1': 276 check_inverse(optarg, &invert, &optind, 0); 277 parse_layer7_protocol(argv[optind-1], layer7info); 278 if (invert) 279 layer7info->invert = 1; 280 *flags = 1; 281 break; 282 283 case '2': 284 /* not going to use this, but maybe we need to strip a ! anyway (?) */ 285 check_inverse(optarg, &invert, &optind, 0); 286 287 if(strlen(argv[optind-1]) >= MAX_FN_LEN) 288 exit_error(PARAMETER_PROBLEM, "directory name too long\n"); 289 290 strncpy(l7dir, argv[optind-1], MAX_FN_LEN); 291 292 *flags = 1; 293 break; 294 case '3': 295 layer7info->pkt = 1; 296 break; 297 298 default: 299 return 0; 300 } 301 302 return 1; 303 } 304 305 /* Final check; must have specified --pattern. */ 306 static void final_check(unsigned int flags) 307 { 308 if (!flags) 309 exit_error(PARAMETER_PROBLEM, 310 "LAYER7 match: You must specify `--pattern'"); 311 } 312 313 static void print_protocol(char s[], int invert, int numeric) 314 { 315 fputs("l7proto ", stdout); 316 if (invert) fputc('!', stdout); 317 printf("%s ", s); 318 } 319 320 /* Prints out the matchinfo. */ 321 static void print(const struct ipt_ip *ip, 322 const struct ipt_entry_match *match, 323 int numeric) 324 { 325 printf("LAYER7 "); 326 327 print_protocol(((struct ipt_layer7_info *)match->data)->protocol, 328 ((struct ipt_layer7_info *)match->data)->invert, numeric); 329 330 if (((struct ipt_layer7_info *)match->data)->pkt) 331 printf("l7pkt "); 332 } 333 /* Saves the union ipt_matchinfo in parsable form to stdout. */ 334 static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) 335 { 336 const struct ipt_layer7_info *info = 337 (const struct ipt_layer7_info*) match->data; 338 339 printf("--l7proto %s%s ", (info->invert) ? "! ": "", info->protocol); 340 } 341 342 static struct iptables_match layer7 = { 343 .name = "layer7", 344 .version = IPTABLES_VERSION, 345 .size = IPT_ALIGN(sizeof(struct ipt_layer7_info)), 346 .userspacesize = IPT_ALIGN(sizeof(struct ipt_layer7_info)), 347 .help = &help, 348 .parse = &parse, 349 .final_check = &final_check, 350 .print = &print, 351 .save = &save, 352 .extra_opts = opts 353 }; 354 355 void _init(void) 356 { 357 register_match(&layer7); 358 } -
extensions/libipt_layer7.man
diff -urN iptables.old/extensions/libipt_layer7.man iptables.dev/extensions/libipt_layer7.man
old new 1 This module matches packets based on the application layer data of 2 their connections. It uses regular expression matching to compare 3 the application layer data to regular expressions found it the layer7 4 configuration files. This is an experimental module which can be found at 5 http://l7-filter.sf.net. It takes two options. 6 .TP 7 .BI "--l7proto " "\fIprotocol\fP" 8 Match the specified protocol. The protocol name must match a file 9 name in /etc/l7-protocols/ 10 .TP 11 .BI "--l7dir " "\fIdirectory\fP" 12 Use \fIdirectory\fP instead of /etc/l7-protocols/ 13
Note:
See TracBrowser
for help on using the repository browser.
