OpenWrt – Blame information for rev 2
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | pppd: Implement support for precompiled pcap filters |
2 | |||
3 | This patch implements support for precompiled pcap filters which is useful to |
||
4 | support dial-on-demand on memory constrained embedded devices without having |
||
5 | to link the full libpcap into pppd to generate the filters during runtime. |
||
6 | |||
7 | Two new options are introduced; "precompiled-pass-filter" specifies a pre- |
||
8 | compiled filter file containing rules to match packets which should be passed, |
||
9 | "precompiled-active-filter" specifies a filter file containing rules to match |
||
10 | packets which are treated as active. |
||
11 | |||
12 | Signed-off-by: Jo-Philipp Wich <jo@mein.io> |
||
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 | @@ -194,6 +197,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 | @@ -170,6 +171,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 | @@ -362,6 +370,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 | @@ -1511,6 +1527,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 */ |