packages: sort network related packages into package/network/
[openwrt/staging/dedeckeh.git] / package / network / services / ppp / patches / 310-precompile_filter.patch
diff --git a/package/network/services/ppp/patches/310-precompile_filter.patch b/package/network/services/ppp/patches/310-precompile_filter.patch
new file mode 100644 (file)
index 0000000..87b9687
--- /dev/null
@@ -0,0 +1,196 @@
+pppd: Implement support for precompiled pcap filters
+
+This patch implements support for precompiled pcap filters which is useful to
+support dial-on-demand on memory constrained embedded devices without having
+to link the full libpcap into pppd to generate the filters during runtime.
+
+Two new options are introduced; "precompiled-pass-filter" specifies a pre-
+compiled filter file containing rules to match packets which should be passed,
+"precompiled-active-filter" specifies a filter file containing rules to match
+packets which are treated as active.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+
+--- a/pppd/Makefile.linux
++++ b/pppd/Makefile.linux
+@@ -50,6 +50,9 @@ MPPE=y
+ # and that the kernel driver support PPP packet filtering.
+ #FILTER=y
++# Support for precompiled filters
++PRECOMPILED_FILTER=y
++
+ # Uncomment the next line to enable multilink PPP (enabled by default)
+ # Linux distributions: Please leave multilink ENABLED in your builds
+ # of pppd!
+@@ -175,6 +178,14 @@ CFLAGS  += -DPPP_FILTER -I$(STAGING_DIR)
+ endif
+ endif
++ifdef PRECOMPILED_FILTER
++PPPDSRCS += pcap_pcc.c
++HEADERS  += pcap_pcc.h
++PPPDOBJS += pcap_pcc.o
++LIBS  += $(STAGING_DIR)/usr/lib/libpcap.a
++CFLAGS        += -DPPP_FILTER -DPPP_PRECOMPILED_FILTER -I$(STAGING_DIR)/usr/include
++endif
++
+ ifdef HAVE_INET6
+      PPPDSRCS += ipv6cp.c eui64.c
+      HEADERS  += ipv6cp.h eui64.h
+--- a/pppd/options.c
++++ b/pppd/options.c
+@@ -57,6 +57,7 @@
+ #ifdef PPP_FILTER
+ #include <pcap.h>
++#include <pcap-bpf.h>
+ /*
+  * There have been 3 or 4 different names for this in libpcap CVS, but
+  * this seems to be what they have settled on...
+@@ -162,6 +163,13 @@ static int setlogfile __P((char **));
+ static int loadplugin __P((char **));
+ #endif
++#ifdef PPP_PRECOMPILED_FILTER
++#include "pcap_pcc.h"
++static int setprecompiledpassfilter __P((char **));
++static int setprecompiledactivefilter __P((char **));
++#undef PPP_FILTER
++#endif
++
+ #ifdef PPP_FILTER
+ static int setpassfilter __P((char **));
+ static int setactivefilter __P((char **));
+@@ -326,6 +334,14 @@ option_t general_options[] = {
+       "set filter for active pkts", OPT_PRIO },
+ #endif
++#ifdef PPP_PRECOMPILED_FILTER
++    { "precompiled-pass-filter", 1, setprecompiledpassfilter,
++      "set precompiled filter for packets to pass", OPT_PRIO },
++
++    { "precompiled-active-filter", 1, setprecompiledactivefilter,
++      "set precompiled filter for active pkts", OPT_PRIO },
++#endif
++
+ #ifdef MAXOCTETS
+     { "maxoctets", o_int, &maxoctets,
+       "Set connection traffic limit",
+@@ -1472,6 +1488,29 @@ callfile(argv)
+     return ok;
+ }
++#ifdef PPP_PRECOMPILED_FILTER
++/*
++ * setprecompiledpassfilter - Set the pass filter for packets using a
++ * precompiled expression
++ */
++static int
++setprecompiledpassfilter(argv)
++    char **argv;
++{
++    return pcap_pre_compiled (*argv, &pass_filter);
++}
++
++/*
++ * setactivefilter - Set the active filter for packets
++ */
++static int
++setprecompiledactivefilter(argv)
++    char **argv;
++{
++    return pcap_pre_compiled (*argv, &active_filter);
++}
++#endif
++
+ #ifdef PPP_FILTER
+ /*
+  * setpassfilter - Set the pass filter for packets
+--- /dev/null
++++ b/pppd/pcap_pcc.c
+@@ -0,0 +1,74 @@
++#include <pcap.h>
++#include <pcap-bpf.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include "pppd.h"
++
++int pcap_pre_compiled (char * fname, struct bpf_program *p)
++{
++    char buf[128];
++    int line = 0, size = 0, index=0, ret=1;
++    FILE *f = fopen (fname, "r");
++    if (!f)
++    {
++       option_error("error opening precompiled active-filter '%s': %s",
++                    fname, strerror (errno));
++       return 0;
++    }
++    while (fgets (buf, 127, f))
++    {
++       line++;
++       if (*buf == '#')
++           continue;
++       if (size)
++       {
++           /*
++             struct bpf_insn {
++             u_short   code;
++             u_char    jt;
++             u_char    jf;
++             bpf_int32 k;
++             }
++           */
++           struct bpf_insn * insn = & p->bf_insns[index];
++           unsigned code, jt, jf, k;
++           if (sscanf (buf, "%u %u %u %u", &code, &jt, &jf, &k) != 4)
++           {
++               goto err;
++           }
++           insn->code = code;
++           insn->jt = jt;
++           insn->jf = jf;
++           insn->k  = k;
++           index++;
++       }
++       else
++       {
++           if (sscanf (buf, "%u", &size) != 1)
++           {
++               goto err;
++           }
++           p->bf_len = size;
++           p->bf_insns = (struct bpf_insn *) 
++               malloc (size * sizeof (struct bpf_insn));
++       }
++    } 
++    if (size != index)
++    {
++       option_error("error in precompiled active-filter,"
++                    " expected %d expressions, got %dn",
++                    size, index);
++       ret = 0;
++    }
++    fclose(f);
++    return ret;
++
++err:
++  option_error("error in precompiled active-filter"
++              " expression line %s:%d (wrong size)\n", 
++              fname, line);
++  fclose (f);
++  return 0;
++}
+--- /dev/null
++++ b/pppd/pcap_pcc.h
+@@ -0,0 +1,7 @@
++#ifndef PCAP_PCC_H
++#define PCAP_PCC_H
++
++#include <pcap.h>
++
++int pcap_pre_compiled (char * fname, struct bpf_program *p);
++#endif /* PCAP_PCC_H */