ppp: bump to 2.4.6
[openwrt/svn-archive/archive.git] / package / network / services / ppp / patches / 310-precompile_filter.patch
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 <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 @@ -183,6 +186,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 @@ -165,6 +166,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 @@ -344,6 +352,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 @@ -1488,6 +1504,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 */