Skip to contentSkip to conversation

: CONFIG_IPPP_FILTER

RFC New Patrick McHardy 1 participant 2 messages Feb 10, 2003 – Feb 18, 2003 Documentation

lore
Share & tools
lore
#0 lore raw

RFC 1/1 : CONFIG_IPPP_FILTER

Hi,
this patch adds ippp filters to isdn similar to ppp filters. Also included is the required patch for ipppd. To compile ipppd add -DIPPP_FILTER to CFLAGS and -lpcap to LIBS.
Comments and suggestions are welcome.

Regards,
Patrick

Documentation/Configure.help +11 -0
diff -urN linux-2.4.20-clean/Documentation/Configure.help linux-2.4.20_ippp-filter/Documentation/Configure.help
@@ -20432,6 +20432,17 @@
   feature. See <file:Documentation/isdn/README.syncppp> and
   <file:Documentation/isdn/syncPPP.FAQ> for more information.
 
+PPP filtering for ISDN
+CONFIG_IPPP_FILTER
+  Say Y here if you want to be able to filter the packets passing over
+  IPPP interfaces.  This allows you to control which packets count as
+  activity (i.e. which packets will reset the idle timer or bring up
+  a demand-dialled link) and which packets are to be dropped entirely.
+  You need to say Y here if you wish to use the pass-filter and
+  active-filter options to ipppd.
+
+  If unsure, say N.
+
 Support generic MP (RFC 1717)
 CONFIG_ISDN_MPP
   With synchronous PPP enabled, it is possible to increase throughput
drivers/isdn/Config.in +1 -0
diff -urN linux-2.4.20-clean/drivers/isdn/Config.in linux-2.4.20_ippp-filter/drivers/isdn/Config.in
@@ -8,6 +8,7 @@
 if [ "$CONFIG_INET" != "n" ]; then
    bool '  Support synchronous PPP' CONFIG_ISDN_PPP
    if [ "$CONFIG_ISDN_PPP" != "n" ]; then
+      bool         '    PPP filtering for ISDN' CONFIG_IPPP_FILTER $CONFIG_FILTER
       bool         '    Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
       bool         '    Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
       dep_tristate '    Support BSD compression' CONFIG_ISDN_PPP_BSDCOMP $CONFIG_ISDN
drivers/isdn/isdn_net.c +11 -11
diff -urN linux-2.4.20-clean/drivers/isdn/isdn_net.c linux-2.4.20_ippp-filter/drivers/isdn/isdn_net.c
@@ -1296,6 +1296,16 @@
 						restore_flags(flags);
 						return 0;	/* STN (skb to nirvana) ;) */
 					}
+#ifdef CONFIG_IPPP_FILTER
+					if (isdn_ppp_autodial_filter(skb, lp)) {
+						isdn_ppp_free(lp);
+						isdn_net_unbind_channel(lp);
+						restore_flags(flags);
+						isdn_net_unreachable(ndev, skb, "dial rejected: packet filtered");
+						dev_kfree_skb(skb);
+						return 0;
+					}
+#endif
 					restore_flags(flags);
 					isdn_net_dial();	/* Initiate dialing */
 					netif_stop_queue(ndev);
@@ -1793,9 +1803,6 @@
 {
 	isdn_net_local *lp = (isdn_net_local *) ndev->priv;
 	isdn_net_local *olp = lp;	/* original 'lp' */
-#ifdef CONFIG_ISDN_PPP
-	int proto = PPP_PROTOCOL(skb->data);
-#endif
 #ifdef CONFIG_ISDN_X25
 	struct concap_proto *cprot = lp -> netdev -> cprot;
 #endif
@@ -1855,14 +1862,7 @@
 			break;
 #ifdef CONFIG_ISDN_PPP
 		case ISDN_NET_ENCAP_SYNCPPP:
-			/*
-			 * If encapsulation is syncppp, don't reset
-			 * huptimer on LCP packets.
-			 */
-			if (proto != PPP_LCP) {
-				olp->huptimer = 0;
-				lp->huptimer = 0;
-			}
+			/* huptimer is done in isdn_ppp_push_higher */
 			isdn_ppp_receive(lp->netdev, olp, skb);
 			return;
 #endif
drivers/isdn/isdn_ppp.c +153 -6

219 lines not on this page · raw message

drivers/isdn/isdn_ppp.h +1 -0
diff -urN linux-2.4.20-clean/drivers/isdn/isdn_ppp.h linux-2.4.20_ippp-filter/drivers/isdn/isdn_ppp.h
@@ -19,6 +19,7 @@
 extern void isdn_ppp_cleanup(void);
 extern int isdn_ppp_free(isdn_net_local *);
 extern int isdn_ppp_bind(isdn_net_local *);
+extern int isdn_ppp_autodial_filter(struct sk_buff *, isdn_net_local *);
 extern int isdn_ppp_xmit(struct sk_buff *, struct net_device *);
 extern void isdn_ppp_receive(isdn_net_dev *, isdn_net_local *, struct sk_buff *);
 extern int isdn_ppp_dev_ioctl(struct net_device *, struct ifreq *, int);
include/linux/isdn_ppp.h +7 -0
diff -urN linux-2.4.20-clean/include/linux/isdn_ppp.h linux-2.4.20_ippp-filter/include/linux/isdn_ppp.h
@@ -65,6 +65,9 @@
 
 #include <linux/config.h>
 
+#ifdef CONFIG_IPPP_FILTER
+#include <linux/filter.h>
+#endif
 
 #define DECOMP_ERR_NOMEM	(-10)
 
@@ -223,6 +226,10 @@
   unsigned char *cbuf;
   struct slcompress *slcomp;
 #endif
+#ifdef CONFIG_IPPP_FILTER
+  struct sock_fprog pass_filter;	/* filter for packets to pass */
+  struct sock_fprog active_filter;	/* filter for pkts to reset idle */
+#endif
   unsigned long debug;
   struct isdn_ppp_compressor *compressor,*decompressor;
   struct isdn_ppp_compressor *link_compressor,*link_decompressor;
ipppd/ipppd.h +8 -0
diff -urN isdn4k-utils-clean/ipppd/ipppd.h isdn4k-utils_ippp-filter/ipppd/ipppd.h
@@ -215,6 +215,11 @@
 #ifdef __linux__
 extern int      hostroute;      /* Add a route to the host at the other end? */
 #endif
+#ifdef IPPP_FILTER
+#include <net/bpf.h>
+extern struct   bpf_program pass_filter;   /* Filter for pkts to pass */
+extern struct   bpf_program active_filter; /* Filter for link-active pkts */
+#endif /* IPPP_FILTER */
 
 /*
  * Values for phase.
@@ -288,6 +293,9 @@
 void link_terminated(int);
 void link_down(int);
 void link_established(int unit);
+#ifdef IPPP_FILTER
+int set_filters(int, struct bpf_program *, struct bpf_program *);
+#endif /* IPPP_FILTER */
 int device_script(char *program,int in,int out);
 void check_auth_options(void);
 void setipdefault(void);
ipppd/ippp-filter-compat.h +11 -0
diff -urN isdn4k-utils-clean/ipppd/ippp-filter-compat.h isdn4k-utils_ippp-filter/ipppd/ippp-filter-compat.h
@@ -0,0 +1,11 @@
+#ifndef _IPPP_FILTER_COMPAT_H
+#define _IPPP_FILTER_COMPAT_T
+
+#ifndef PPPIOCSPASS
+#define PPPIOCSPASS	_IOW('t', 71, struct sock_fprog) /* set pass filter */
+#endif
+#ifndef PPPIOCSACTIVE
+#define PPPIOCSACTIVE	_IOW('t', 70, struct sock_fprog) /* set active filter */
+#endif
+                                                                                
+#endif /* _IPPP_FILTER_COMPAT_T */
ipppd/main.c +3 -0
diff -urN isdn4k-utils-clean/ipppd/main.c isdn4k-utils_ippp-filter/ipppd/main.c
@@ -564,6 +564,9 @@
 	lns[linkunit].upap_unit = lns[linkunit].chap_unit = lns[linkunit].lcp_unit;
 	upap[lns[linkunit].upap_unit].us_unit = chap[lns[linkunit].chap_unit].unit = linkunit;
 	lcp_lowerup(lns[linkunit].lcp_unit);
+#ifdef IPPP_FILTER
+	set_filters(linkunit, &pass_filter, &active_filter);
+#endif /* IPPP_FILTER */
 
 	return 0;
 }
ipppd/options.c +47 -1

75 lines not on this page · raw message

ipppd/sys-linux.c +40 -0
diff -urN isdn4k-utils-clean/ipppd/sys-linux.c isdn4k-utils_ippp-filter/ipppd/sys-linux.c
@@ -57,6 +57,7 @@
 #if defined __GLIBC__ && __GLIBC__ >= 2
 # include </usr/include/net/ppp_defs.h>
 # include </usr/include/net/if_ppp.h>
+# include "ippp-filter-compat.h"
 # include </usr/include/net/ethernet.h>
 # include "route.h"
 #else
@@ -70,6 +71,11 @@
 # include <netipx/ipx.h>
 #endif
 
+#ifdef IPPP_FILTER
+#include <net/bpf.h>
+#include <linux/filter.h>
+#endif /* IPPP_FILTER */
+
 #include "fsm.h"
 #include "ipppd.h"
 #include "ipcp.h"
@@ -515,6 +521,40 @@
 	return 1;
 }
 
+#ifdef IPPP_FILTER
+/*
+ * set_filters - set the active and pass filters in the kernel driver.
+ */
+int set_filters(int u, struct bpf_program *pass, struct bpf_program *active)
+{       
+        struct sock_fprog fp;
+
+	/*
+	 *  unfortunately there is no way of checking for kernel support. the
+	 *  driver just returns 0 for unsupported ioctls, which means without
+	 *  kernel support we won't even notice the error.
+	 */
+
+	if (pass) {
+		fp.len = pass->bf_len;
+		fp.filter = (struct sock_filter *) pass->bf_insns;
+		if (ioctl(lns[u].fd, PPPIOCSPASS, &fp) < 0) {
+			syslog(LOG_ERR, "Couldn't set pass-filter in kernel.");
+			return 0;
+		}
+	}
+	if (active) {
+		fp.len = active->bf_len;
+		fp.filter = (struct sock_filter *) active->bf_insns;
+		if (ioctl(lns[u].fd, PPPIOCSACTIVE, &fp) < 0) {
+			syslog(LOG_ERR, "Couldn't set active-filter in kernel.");
+	        	return 0;
+		}
+	}
+	return 1;
+}
+#endif /* IPPP_FILTER */
+
 /*
  * sifup - Config the interface up and enable IP packets to pass.
  */
#1 lore raw

RFC PATCH 1/1 : CONFIG_IPPP_FILTER

This patch adds ippp filters to isdn similar to ppp filters. Also included is the required patch for ipppd. You need to run autoconf in the ipppd subdir before compiling. ipppd support is enabled with --enable-ippp-filter.

Comments and suggestions are welcome.

Regards,
Patrick

Documentation/Configure.help +11 -0
diff -urN linux-2.4.20-clean/Documentation/Configure.help linux-2.4.20_ippp-filter/Documentation/Configure.help
@@ -20432,6 +20432,17 @@
   feature. See <file:Documentation/isdn/README.syncppp> and
   <file:Documentation/isdn/syncPPP.FAQ> for more information.
 
+PPP filtering for ISDN
+CONFIG_IPPP_FILTER
+  Say Y here if you want to be able to filter the packets passing over
+  IPPP interfaces.  This allows you to control which packets count as
+  activity (i.e. which packets will reset the idle timer or bring up
+  a demand-dialled link) and which packets are to be dropped entirely.
+  You need to say Y here if you wish to use the pass-filter and
+  active-filter options to ipppd.
+
+  If unsure, say N.
+
 Support generic MP (RFC 1717)
 CONFIG_ISDN_MPP
   With synchronous PPP enabled, it is possible to increase throughput
drivers/isdn/Config.in +1 -0
diff -urN linux-2.4.20-clean/drivers/isdn/Config.in linux-2.4.20_ippp-filter/drivers/isdn/Config.in
@@ -8,6 +8,7 @@
 if [ "$CONFIG_INET" != "n" ]; then
    bool '  Support synchronous PPP' CONFIG_ISDN_PPP
    if [ "$CONFIG_ISDN_PPP" != "n" ]; then
+      bool         '    PPP filtering for ISDN' CONFIG_IPPP_FILTER $CONFIG_FILTER
       bool         '    Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
       bool         '    Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
       dep_tristate '    Support BSD compression' CONFIG_ISDN_PPP_BSDCOMP $CONFIG_ISDN
drivers/isdn/isdn_net.c +11 -11
diff -urN linux-2.4.20-clean/drivers/isdn/isdn_net.c linux-2.4.20_ippp-filter/drivers/isdn/isdn_net.c
@@ -1296,6 +1296,16 @@
 						restore_flags(flags);
 						return 0;	/* STN (skb to nirvana) ;) */
 					}
+#ifdef CONFIG_IPPP_FILTER
+					if (isdn_ppp_autodial_filter(skb, lp)) {
+						isdn_ppp_free(lp);
+						isdn_net_unbind_channel(lp);
+						restore_flags(flags);
+						isdn_net_unreachable(ndev, skb, "dial rejected: packet filtered");
+						dev_kfree_skb(skb);
+						return 0;
+					}
+#endif
 					restore_flags(flags);
 					isdn_net_dial();	/* Initiate dialing */
 					netif_stop_queue(ndev);
@@ -1793,9 +1803,6 @@
 {
 	isdn_net_local *lp = (isdn_net_local *) ndev->priv;
 	isdn_net_local *olp = lp;	/* original 'lp' */
-#ifdef CONFIG_ISDN_PPP
-	int proto = PPP_PROTOCOL(skb->data);
-#endif
 #ifdef CONFIG_ISDN_X25
 	struct concap_proto *cprot = lp -> netdev -> cprot;
 #endif
@@ -1855,14 +1862,7 @@
 			break;
 #ifdef CONFIG_ISDN_PPP
 		case ISDN_NET_ENCAP_SYNCPPP:
-			/*
-			 * If encapsulation is syncppp, don't reset
-			 * huptimer on LCP packets.
-			 */
-			if (proto != PPP_LCP) {
-				olp->huptimer = 0;
-				lp->huptimer = 0;
-			}
+			/* huptimer is done in isdn_ppp_push_higher */
 			isdn_ppp_receive(lp->netdev, olp, skb);
 			return;
 #endif
drivers/isdn/isdn_ppp.c +153 -7

226 lines not on this page · raw message

drivers/isdn/isdn_ppp.h +1 -0
diff -urN linux-2.4.20-clean/drivers/isdn/isdn_ppp.h linux-2.4.20_ippp-filter/drivers/isdn/isdn_ppp.h
@@ -19,6 +19,7 @@
 extern void isdn_ppp_cleanup(void);
 extern int isdn_ppp_free(isdn_net_local *);
 extern int isdn_ppp_bind(isdn_net_local *);
+extern int isdn_ppp_autodial_filter(struct sk_buff *, isdn_net_local *);
 extern int isdn_ppp_xmit(struct sk_buff *, struct net_device *);
 extern void isdn_ppp_receive(isdn_net_dev *, isdn_net_local *, struct sk_buff *);
 extern int isdn_ppp_dev_ioctl(struct net_device *, struct ifreq *, int);
include/linux/isdn_ppp.h +7 -0
diff -urN linux-2.4.20-clean/include/linux/isdn_ppp.h linux-2.4.20_ippp-filter/include/linux/isdn_ppp.h
@@ -65,6 +65,9 @@
 
 #include <linux/config.h>
 
+#ifdef CONFIG_IPPP_FILTER
+#include <linux/filter.h>
+#endif
 
 #define DECOMP_ERR_NOMEM	(-10)
 
@@ -223,6 +226,10 @@
   unsigned char *cbuf;
   struct slcompress *slcomp;
 #endif
+#ifdef CONFIG_IPPP_FILTER
+  struct sock_fprog pass_filter;	/* filter for packets to pass */
+  struct sock_fprog active_filter;	/* filter for pkts to reset idle */
+#endif
   unsigned long debug;
   struct isdn_ppp_compressor *compressor,*decompressor;
   struct isdn_ppp_compressor *link_compressor,*link_decompressor;
ipppd/configure.in +7 -0
diff -urN isdn4k-utils-clean/ipppd/configure.in isdn4k-utils_ippp-filter/ipppd/configure.in
@@ -98,6 +98,12 @@
 	AC_DEFINE(CONFIG_IPPPD_DEBUGFLAGS,"-DDEBUGALL"),
 )
 
+AC_ARG_ENABLE(ippp-filter,
+	[  --enable-ippp-filter    Enable IPPP Filters (needs kernel supports) [no]],
+	CONFIG_IPPP_FILTER="1"
+	AC_DEFINE(CONFIG_IPPP_FILTER,"1"),
+)
+
 AC_SUBST(I4LVERSION)
 AC_SUBST(MANDATE)
 AC_SUBST(HAVE_LIBDES)
@@ -113,4 +119,5 @@
 AC_SUBST(RADIUS_CLIENT_CONFIG_FILE)
 AC_SUBST(CONFIG_RADIUS_WTMP_LOGGING)
 AC_SUBST(CONFIG_IPPPD_DEBUGFLAGS)
+AC_SUBST(CONFIG_IPPP_FILTER)
 AC_OUTPUT(Makefile ipppd.man pathnames.h)
ipppd/ipppd.h +8 -0
diff -urN isdn4k-utils-clean/ipppd/ipppd.h isdn4k-utils_ippp-filter/ipppd/ipppd.h
@@ -215,6 +215,11 @@
 #ifdef __linux__
 extern int      hostroute;      /* Add a route to the host at the other end? */
 #endif
+#ifdef IPPP_FILTER
+#include <net/bpf.h>
+extern struct   bpf_program pass_filter;   /* Filter for pkts to pass */
+extern struct   bpf_program active_filter; /* Filter for link-active pkts */
+#endif /* IPPP_FILTER */
 
 /*
  * Values for phase.
@@ -288,6 +293,9 @@
 void link_terminated(int);
 void link_down(int);
 void link_established(int unit);
+#ifdef IPPP_FILTER
+int set_filters(int, struct bpf_program *, struct bpf_program *);
+#endif /* IPPP_FILTER */
 int device_script(char *program,int in,int out);
 void check_auth_options(void);
 void setipdefault(void);
ipppd/ippp-filter-compat.h +11 -0
diff -urN isdn4k-utils-clean/ipppd/ippp-filter-compat.h isdn4k-utils_ippp-filter/ipppd/ippp-filter-compat.h
@@ -0,0 +1,11 @@
+#ifndef _IPPP_FILTER_COMPAT_H
+#define _IPPP_FILTER_COMPAT_T
+
+#ifndef PPPIOCSPASS
+#define PPPIOCSPASS	_IOW('t', 71, struct sock_fprog) /* set pass filter */
+#endif
+#ifndef PPPIOCSACTIVE
+#define PPPIOCSACTIVE	_IOW('t', 70, struct sock_fprog) /* set active filt */
+#endif
+                                                                                
+#endif /* _IPPP_FILTER_COMPAT_T */
ipppd/main.c +3 -0
diff -urN isdn4k-utils-clean/ipppd/main.c isdn4k-utils_ippp-filter/ipppd/main.c
@@ -564,6 +564,9 @@
 	lns[linkunit].upap_unit = lns[linkunit].chap_unit = lns[linkunit].lcp_unit;
 	upap[lns[linkunit].upap_unit].us_unit = chap[lns[linkunit].chap_unit].unit = linkunit;
 	lcp_lowerup(lns[linkunit].lcp_unit);
+#ifdef IPPP_FILTER
+	set_filters(linkunit, &pass_filter, &active_filter);
+#endif /* IPPP_FILTER */
 
 	return 0;
 }
ipppd/Makefile.in +5 -0
diff -urN isdn4k-utils-clean/ipppd/Makefile.in isdn4k-utils_ippp-filter/ipppd/Makefile.in
@@ -7,6 +7,7 @@
 HAVE_LIBCRYPT := @HAVE_LIBCRYPT@
 HAVE_SHADOW_H := @HAVE_SHADOW_H@
 HAVE_LZSCOMP_H:= @HAVE_LZSCOMP_H@
+IPPP_FILTER   := @CONFIG_IPPP_FILTER@
 SBINDIR       := @CONFIG_SBINDIR@
 MANDIR        := @CONFIG_MANDIR@
 CC            := @CC@
@@ -77,6 +78,10 @@
 LIBS        = -lcrypt -lutil
 endif
 
+ifeq ($(IPPP_FILTER),1)
+CFLAGS     += -DIPPP_FILTER
+LIBS       += -lpcap
+endif
 
 SOURCE = RELNOTES configure *.in $(PPPDSRCS) $(HEADERS) $(MANPAGES)
 
ipppd/options.c +47 -1

75 lines not on this page · raw message

ipppd/sys-linux.c +40 -0
diff -urN isdn4k-utils-clean/ipppd/sys-linux.c isdn4k-utils_ippp-filter/ipppd/sys-linux.c
@@ -57,6 +57,7 @@
 #if defined __GLIBC__ && __GLIBC__ >= 2
 # include </usr/include/net/ppp_defs.h>
 # include </usr/include/net/if_ppp.h>
+# include "ippp-filter-compat.h"
 # include </usr/include/net/ethernet.h>
 # include "route.h"
 #else
@@ -70,6 +71,11 @@
 # include <netipx/ipx.h>
 #endif
 
+#ifdef IPPP_FILTER
+#include <net/bpf.h>
+#include <linux/filter.h>
+#endif /* IPPP_FILTER */
+
 #include "fsm.h"
 #include "ipppd.h"
 #include "ipcp.h"
@@ -515,6 +521,40 @@
 	return 1;
 }
 
+#ifdef IPPP_FILTER
+/*
+ * set_filters - set the active and pass filters in the kernel driver.
+ */
+int set_filters(int u, struct bpf_program *pass, struct bpf_program *active)
+{       
+        struct sock_fprog fp;
+
+	/*
+	 *  unfortunately there is no way of checking for kernel support. the
+	 *  driver just returns 0 for unsupported ioctls, which means without
+	 *  kernel support we won't even notice the error.
+	 */
+
+	if (pass) {
+		fp.len = pass->bf_len;
+		fp.filter = (struct sock_filter *) pass->bf_insns;
+		if (ioctl(lns[u].fd, PPPIOCSPASS, &fp) < 0) {
+			syslog(LOG_ERR, "Couldn't set pass-filter in kernel.");
+			return 0;
+		}
+	}
+	if (active) {
+		fp.len = active->bf_len;
+		fp.filter = (struct sock_filter *) active->bf_insns;
+		if (ioctl(lns[u].fd, PPPIOCSACTIVE, &fp) < 0) {
+			syslog(LOG_ERR, "Couldn't set active-filter in kernel.");
+	        	return 0;
+		}
+	}
+	return 1;
+}
+#endif /* IPPP_FILTER */
+
 /*
  * sifup - Config the interface up and enable IP packets to pass.
  */