When creating a packet socket, it is possible to defer receiving any
packets on that socket by giving socket(2) 0 for the protocol:
fd = socket(PF_PACKET, SOCK_RAW, 0);
That socket can later set which protocol it will receive with bind(2):
struct sockaddr_ll sl;
memset(&sl, 0, sizeof(sl));
sl.sll_family = AF_PACKET;
sl.sll_protocol = htons(ETH_P_ALL);
sl.sll_ifindex = idx;
bind(sd, (struct sockaddr*)&sl, sizeof(sl));
Repeated calls to bind(2) can change the protocol, but cannot set it
back to zero to put the socket in its initial state. The patch below
fixes this.
The last hunk is the important one, and I don't understand why the ?: is
there. Can someone tell me the reason to disallow a 0 protocol here? I
couldn't find one, and running with this patch doesn't seem to affect
any of my pcap-based applications.
diff -ur linux-2.4.17/net/packet/af_packet.c
linux.bindfix/net/packet/af_packet.c
--- linux-2.4.17/net/packet/af_packet.c Tue Feb 12 13:13:30 2002
+++ linux.bindfix/net/packet/af_packet.c Tue Feb 19 19:20:56 2002
@@ -835,25 +835,19 @@
sk->protinfo.af_packet->running = 0;
}
+ if (protocol == 0)
+ goto out_unlock;
+
sk->num = protocol;
sk->protinfo.af_packet->prot_hook.type = protocol;
sk->protinfo.af_packet->prot_hook.dev = dev;
sk->protinfo.af_packet->ifindex = dev ? dev->ifindex : 0;
- if (protocol == 0)
- goto out_unlock;
-
- if (dev) {
- if (dev->flags&IFF_UP) {
- dev_add_pack(&sk->protinfo.af_packet->prot_hook);
- sock_hold(sk);
- sk->protinfo.af_packet->running = 1;
- } else {
- sk->err = ENETDOWN;
- if (!sk->dead)
- sk->error_report(sk);
- }
+ if (dev && !(dev->flags&IFF_UP)) {
+ sk->err = ENETDOWN;
+ if (!sk->dead)
+ sk->error_report(sk);
} else {
dev_add_pack(&sk->protinfo.af_packet->prot_hook);
sock_hold(sk);
@@ -920,7 +914,7 @@
if (dev == NULL)
goto out;
}
- err = packet_do_bind(sk, dev, sll->sll_protocol ? : sk->num);
+ err = packet_do_bind(sk, dev, sll->sll_protocol);
if (dev)
dev_put(dev);
--
Jason Lunz Trellis Network Security
j@xxxxxxxxxxxxxx http://www.trellisinc.com/
|