Root/package/network/services/ppp/patches/310-precompile_filter.patch

1pppd: Implement support for precompiled pcap filters
2
3This patch implements support for precompiled pcap filters which is useful to
4support dial-on-demand on memory constrained embedded devices without having
5to link the full libpcap into pppd to generate the filters during runtime.
6
7Two new options are introduced; "precompiled-pass-filter" specifies a pre-
8compiled filter file containing rules to match packets which should be passed,
9"precompiled-active-filter" specifies a filter file containing rules to match
10packets which are treated as active.
11
12Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
13
14--- a/pppd/Makefile.linux
15+++ b/pppd/Makefile.linux
16@@ -50,6 +50,9 @@ MPPE=y
17 # and that the kernel driver support PPP packet filtering.
18 #FILTER=y
19 
20+# Support for precompiled filters
21+PRECOMPILED_FILTER=y
22+
23 # Uncomment the next line to enable multilink PPP (enabled by default)
24 # Linux distributions: Please leave multilink ENABLED in your builds
25 # of pppd!
26@@ -175,6 +178,14 @@ CFLAGS += -DPPP_FILTER -I$(STAGING_DIR)
27 endif
28 endif
29 
30+ifdef PRECOMPILED_FILTER
31+PPPDSRCS += pcap_pcc.c
32+HEADERS += pcap_pcc.h
33+PPPDOBJS += pcap_pcc.o
34+LIBS += $(STAGING_DIR)/usr/lib/libpcap.a
35+CFLAGS += -DPPP_FILTER -DPPP_PRECOMPILED_FILTER -I$(STAGING_DIR)/usr/include
36+endif
37+
38 ifdef HAVE_INET6
39      PPPDSRCS += ipv6cp.c eui64.c
40      HEADERS += ipv6cp.h eui64.h
41--- a/pppd/options.c
42+++ b/pppd/options.c
43@@ -57,6 +57,7 @@
44 
45 #ifdef PPP_FILTER
46 #include <pcap.h>
47+#include <pcap-bpf.h>
48 /*
49  * There have been 3 or 4 different names for this in libpcap CVS, but
50  * this seems to be what they have settled on...
51@@ -162,6 +163,13 @@ static int setlogfile __P((char **));
52 static int loadplugin __P((char **));
53 #endif
54 
55+#ifdef PPP_PRECOMPILED_FILTER
56+#include "pcap_pcc.h"
57+static int setprecompiledpassfilter __P((char **));
58+static int setprecompiledactivefilter __P((char **));
59+#undef PPP_FILTER
60+#endif
61+
62 #ifdef PPP_FILTER
63 static int setpassfilter __P((char **));
64 static int setactivefilter __P((char **));
65@@ -326,6 +334,14 @@ option_t general_options[] = {
66       "set filter for active pkts", OPT_PRIO },
67 #endif
68 
69+#ifdef PPP_PRECOMPILED_FILTER
70+ { "precompiled-pass-filter", 1, setprecompiledpassfilter,
71+ "set precompiled filter for packets to pass", OPT_PRIO },
72+
73+ { "precompiled-active-filter", 1, setprecompiledactivefilter,
74+ "set precompiled filter for active pkts", OPT_PRIO },
75+#endif
76+
77 #ifdef MAXOCTETS
78     { "maxoctets", o_int, &maxoctets,
79       "Set connection traffic limit",
80@@ -1472,6 +1488,29 @@ callfile(argv)
81     return ok;
82 }
83 
84+#ifdef PPP_PRECOMPILED_FILTER
85+/*
86+ * setprecompiledpassfilter - Set the pass filter for packets using a
87+ * precompiled expression
88+ */
89+static int
90+setprecompiledpassfilter(argv)
91+ char **argv;
92+{
93+ return pcap_pre_compiled (*argv, &pass_filter);
94+}
95+
96+/*
97+ * setactivefilter - Set the active filter for packets
98+ */
99+static int
100+setprecompiledactivefilter(argv)
101+ char **argv;
102+{
103+ return pcap_pre_compiled (*argv, &active_filter);
104+}
105+#endif
106+
107 #ifdef PPP_FILTER
108 /*
109  * setpassfilter - Set the pass filter for packets
110--- /dev/null
111+++ b/pppd/pcap_pcc.c
112@@ -0,0 +1,74 @@
113+#include <pcap.h>
114+#include <pcap-bpf.h>
115+#include <stdio.h>
116+#include <stdlib.h>
117+#include <string.h>
118+#include <errno.h>
119+#include "pppd.h"
120+
121+int pcap_pre_compiled (char * fname, struct bpf_program *p)
122+{
123+ char buf[128];
124+ int line = 0, size = 0, index=0, ret=1;
125+ FILE *f = fopen (fname, "r");
126+ if (!f)
127+ {
128+ option_error("error opening precompiled active-filter '%s': %s",
129+ fname, strerror (errno));
130+ return 0;
131+ }
132+ while (fgets (buf, 127, f))
133+ {
134+ line++;
135+ if (*buf == '#')
136+ continue;
137+ if (size)
138+ {
139+ /*
140+ struct bpf_insn {
141+ u_short code;
142+ u_char jt;
143+ u_char jf;
144+ bpf_int32 k;
145+ }
146+ */
147+ struct bpf_insn * insn = & p->bf_insns[index];
148+ unsigned code, jt, jf, k;
149+ if (sscanf (buf, "%u %u %u %u", &code, &jt, &jf, &k) != 4)
150+ {
151+ goto err;
152+ }
153+ insn->code = code;
154+ insn->jt = jt;
155+ insn->jf = jf;
156+ insn->k = k;
157+ index++;
158+ }
159+ else
160+ {
161+ if (sscanf (buf, "%u", &size) != 1)
162+ {
163+ goto err;
164+ }
165+ p->bf_len = size;
166+ p->bf_insns = (struct bpf_insn *)
167+ malloc (size * sizeof (struct bpf_insn));
168+ }
169+ }
170+ if (size != index)
171+ {
172+ option_error("error in precompiled active-filter,"
173+ " expected %d expressions, got %dn",
174+ size, index);
175+ ret = 0;
176+ }
177+ fclose(f);
178+ return ret;
179+
180+err:
181+ option_error("error in precompiled active-filter"
182+ " expression line %s:%d (wrong size)\n",
183+ fname, line);
184+ fclose (f);
185+ return 0;
186+}
187--- /dev/null
188+++ b/pppd/pcap_pcc.h
189@@ -0,0 +1,7 @@
190+#ifndef PCAP_PCC_H
191+#define PCAP_PCC_H
192+
193+#include <pcap.h>
194+
195+int pcap_pre_compiled (char * fname, struct bpf_program *p);
196+#endif /* PCAP_PCC_H */
197

Archive Download this file



interactive