diff -Naur linux-2.6.15.1.orig/include/linux/sysctl.h linux-2.6.15.1/include/linux/sysctl.h --- linux-2.6.15.1.orig/include/linux/sysctl.h 2006-01-15 07:16:02.000000000 +0100 +++ linux-2.6.15.1/include/linux/sysctl.h 2006-01-17 19:10:49.918063425 +0100 @@ -255,6 +255,7 @@ NET_CORE_DEV_WEIGHT=17, NET_CORE_SOMAXCONN=18, NET_CORE_BUDGET=19, + NET_CORE_CAPTURE_GROUP=99, }; /* /proc/sys/net/ethernet */ diff -Naur linux-2.6.15.1.orig/net/core/sysctl_net_core.c linux-2.6.15.1/net/core/sysctl_net_core.c --- linux-2.6.15.1.orig/net/core/sysctl_net_core.c 2006-01-15 07:16:02.000000000 +0100 +++ linux-2.6.15.1/net/core/sysctl_net_core.c 2006-01-17 19:14:56.572957650 +0100 @@ -21,6 +21,7 @@ extern __u32 sysctl_rmem_max; extern int sysctl_core_destroy_delay; +extern gid_t sysctl_capture_group; #ifdef CONFIG_NET_DIVERT extern char sysctl_divert_version[]; @@ -128,6 +129,14 @@ .mode = 0644, .proc_handler = &proc_dointvec }, + { + .ctl_name = NET_CORE_CAPTURE_GROUP, + .procname = "capture_group", + .data = &sysctl_capture_group, + .maxlen = sizeof(gid_t), + .mode = 0644, + .proc_handler = &proc_dointvec + }, { .ctl_name = 0 } }; diff -Naur linux-2.6.15.1.orig/net/packet/af_packet.c linux-2.6.15.1/net/packet/af_packet.c --- linux-2.6.15.1.orig/net/packet/af_packet.c 2006-01-15 07:16:02.000000000 +0100 +++ linux-2.6.15.1/net/packet/af_packet.c 2006-01-17 19:18:25.252060995 +0100 @@ -988,13 +988,17 @@ * Create a packet of type SOCK_PACKET. */ +/* If non-zero, id of group which is allowed to create SOCK_PACKETs. */ +gid_t sysctl_capture_group = 0; + static int packet_create(struct socket *sock, int protocol) { struct sock *sk; struct packet_sock *po; int err; - if (!capable(CAP_NET_RAW)) + if (! (capable(CAP_NET_RAW) || + (sysctl_capture_group != 0 && in_group_p(sysctl_capture_group)))) return -EPERM; if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW #ifdef CONFIG_SOCK_PACKET