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