[klibc] [PATCH 1/3] Only peek and discard packets from specified device.

Ulrich Dangel uli at spamt.net
Mon Mar 28 09:59:34 PDT 2011


This patch fixes a bug on systems with multiple connected network devices.
As packet_peek uses all devices to receive data instead of a specific
device. As the return value was never reset it was possible that packets
from other devices were returned by packet_peek. That means that the
ifindex did not match any ifindex of the specified devices the packet was
never removed and packets for the correct device were never processed.

This patch enhance packet_peek and packet_discard to only work on packages
for the specified device instead of all packets.

Signed-off-by: Ulrich Dangel <uli at spamt.net>
---
 usr/kinit/ipconfig/bootp_proto.c |    2 +-
 usr/kinit/ipconfig/dhcp_proto.c  |    2 +-
 usr/kinit/ipconfig/main.c        |   16 ++++++----------
 usr/kinit/ipconfig/packet.c      |   16 +++++++++-------
 usr/kinit/ipconfig/packet.h      |    6 +++---
 5 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/usr/kinit/ipconfig/bootp_proto.c b/usr/kinit/ipconfig/bootp_proto.c
index baf9d3e..f2cc90c 100644
--- a/usr/kinit/ipconfig/bootp_proto.c
+++ b/usr/kinit/ipconfig/bootp_proto.c
@@ -169,7 +169,7 @@ int bootp_recv_reply(struct netdev *dev)
 	};
 	int ret;
 
-	ret = packet_recv(iov, 3);
+	ret = packet_recv(dev, iov, 3);
 	if (ret <= 0)
 		return ret;
 
diff --git a/usr/kinit/ipconfig/dhcp_proto.c b/usr/kinit/ipconfig/dhcp_proto.c
index fc0494d..993db52 100644
--- a/usr/kinit/ipconfig/dhcp_proto.c
+++ b/usr/kinit/ipconfig/dhcp_proto.c
@@ -147,7 +147,7 @@ static int dhcp_recv(struct netdev *dev)
 	};
 	int ret;
 
-	ret = packet_recv(iov, 3);
+	ret = packet_recv(dev, iov, 3);
 	if (ret <= 0)
 		return ret;
 
diff --git a/usr/kinit/ipconfig/main.c b/usr/kinit/ipconfig/main.c
index d501bec..1e48083 100644
--- a/usr/kinit/ipconfig/main.c
+++ b/usr/kinit/ipconfig/main.c
@@ -304,23 +304,19 @@ struct netdev *ifaces;
  */
 static int do_pkt_recv(int pkt_fd, time_t now)
 {
-	int ifindex, ret;
+	int ret = 0;
 	struct state *s;
 
-	ret = packet_peek(&ifindex);
-	if (ret == 0)
-		return ret;
-
 	for (s = slist; s; s = s->next) {
-		if (s->dev->ifindex == ifindex) {
+		ret = packet_peek(s->dev);
+		if (ret) {
 			ret = process_receive_event(s, now);
+			if (ret == 0) {
+				packet_discard(s->dev);
+			}
 			break;
 		}
 	}
-
-	if (ret == 0)
-		packet_discard();
-
 	return ret;
 }
 
diff --git a/usr/kinit/ipconfig/packet.c b/usr/kinit/ipconfig/packet.c
index 84267b7..993a2fa 100644
--- a/usr/kinit/ipconfig/packet.c
+++ b/usr/kinit/ipconfig/packet.c
@@ -167,17 +167,18 @@ int packet_send(struct netdev *dev, struct iovec *iov, int iov_len)
 }
 
 /*
- * Fetches a bootp packet, but doesn't remove it.
+ * Fetches a bootp packet from specified device, but doesn't remove it.
  * Returns:
  *  0 = Error
  * >0 = A packet of size "ret" is available for interface ifindex
  */
-int packet_peek(int *ifindex)
+int packet_peek(struct netdev *dev)
 {
 	struct sockaddr_ll sll;
 	struct iphdr iph;
 	int ret, sllen = sizeof(struct sockaddr_ll);
 
+	sll.sll_ifindex = dev->ifindex;
 	/*
 	 * Peek at the IP header.
 	 */
@@ -192,21 +193,22 @@ int packet_peek(int *ifindex)
 	if (iph.ihl < 5 || iph.version != IPVERSION)
 		goto discard_pkt;
 
-	*ifindex = sll.sll_ifindex;
 
 	return ret;
 
 discard_pkt:
-	packet_discard();
+	packet_discard(dev);
 	return 0;
 }
 
-void packet_discard(void)
+void packet_discard(struct netdev *dev)
 {
 	struct iphdr iph;
 	struct sockaddr_ll sll;
 	socklen_t sllen = sizeof(sll);
 
+	sll.sll_ifindex = dev->ifindex;
+
 	recvfrom(pkt_fd, &iph, sizeof(iph), 0,
 		 (struct sockaddr *)&sll, &sllen);
 }
@@ -219,7 +221,7 @@ void packet_discard(void)
 *   0 = Discarded packet (non-DHCP/BOOTP traffic)
  * >0 = Size of packet
  */
-int packet_recv(struct iovec *iov, int iov_len)
+int packet_recv(struct netdev* dev, struct iovec *iov, int iov_len)
 {
 	struct iphdr *ip, iph;
 	struct udphdr *udp;
@@ -293,6 +295,6 @@ free_pkt:
 
 discard_pkt:
 	dprintf("discarded\n");
-	packet_discard();
+	packet_discard(dev);
 	return 0;
 }
diff --git a/usr/kinit/ipconfig/packet.h b/usr/kinit/ipconfig/packet.h
index 627d282..524f393 100644
--- a/usr/kinit/ipconfig/packet.h
+++ b/usr/kinit/ipconfig/packet.h
@@ -6,8 +6,8 @@ struct iovec;
 int packet_open(void);
 void packet_close(void);
 int packet_send(struct netdev *dev, struct iovec *iov, int iov_len);
-int packet_peek(int *ifindex);
-void packet_discard(void);
-int packet_recv(struct iovec *iov, int iov_len);
+int packet_peek(struct netdev *dev);
+void packet_discard(struct netdev *dev);
+int packet_recv(struct netdev *dev, struct iovec *iov, int iov_len);
 
 #endif /* IPCONFIG_PACKET_H */
-- 
1.7.1



More information about the klibc mailing list