aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien BLACHE <julien-externe.blache@edf.fr>2010-08-10 15:37:10 +0200
committermaximilian attems <max@stro.at>2010-08-25 20:11:05 +0200
commitb02b0f71aa7be125f0d64e44124d7f7ead0175b5 (patch)
tree724f0878fb9ebc30e4dea70289207533cb700dab
parent47da4f6ab856250854465f88edc6d76ca0ba017b (diff)
downloadklibc-b02b0f71aa7be125f0d64e44124d7f7ead0175b5.tar.gz
[klibc] ipconfig: differentiate between error and non-DHCP/BOOTP traffic in packet_recv()
Commit 4efbcf90f60e27febe883ef052454d8cfded5c15 badly broke ipconfig by turning packet_recv() into an all-or-nothing function. Before this commit, packet_recv() did distinguish between a DHCP/BOOTP packet that's of interest, random UDP packets we don't care about and errors. After the patch, either a packet is a DHCP/BOOTP packet or packet_recv() exits with an error. This breaks ipconfig on big, noisy LANs where random UDP traffic can arrive before the DHCP reply and throw the device into DEVST_ERROR state. This fixes http://bugs.debian.org/552554 Tested-by: Michael Prokop <mika@debian.org> Signed-off-by: maximilian attems <max@stro.at>
-rw-r--r--usr/kinit/ipconfig/bootp_proto.c2
-rw-r--r--usr/kinit/ipconfig/dhcp_proto.c4
-rw-r--r--usr/kinit/ipconfig/packet.c5
3 files changed, 6 insertions, 5 deletions
diff --git a/usr/kinit/ipconfig/bootp_proto.c b/usr/kinit/ipconfig/bootp_proto.c
index 42dfad3cda620..baf9d3e8ef5c8 100644
--- a/usr/kinit/ipconfig/bootp_proto.c
+++ b/usr/kinit/ipconfig/bootp_proto.c
@@ -171,7 +171,7 @@ int bootp_recv_reply(struct netdev *dev)
ret = packet_recv(iov, 3);
if (ret <= 0)
- return -1;
+ return ret;
if (ret < sizeof(struct bootp_hdr) ||
bootp.op != BOOTP_REPLY || /* RFC951 7.5 */
diff --git a/usr/kinit/ipconfig/dhcp_proto.c b/usr/kinit/ipconfig/dhcp_proto.c
index 2a2651a1abd90..fc0494d3b4e8e 100644
--- a/usr/kinit/ipconfig/dhcp_proto.c
+++ b/usr/kinit/ipconfig/dhcp_proto.c
@@ -148,8 +148,8 @@ static int dhcp_recv(struct netdev *dev)
int ret;
ret = packet_recv(iov, 3);
- if (ret == 0)
- return -1;
+ if (ret <= 0)
+ return ret;
dprintf("\n dhcp xid %08x ", dev->bootp.xid);
diff --git a/usr/kinit/ipconfig/packet.c b/usr/kinit/ipconfig/packet.c
index d24245761a3f0..84267b7db8f01 100644
--- a/usr/kinit/ipconfig/packet.c
+++ b/usr/kinit/ipconfig/packet.c
@@ -215,7 +215,8 @@ void packet_discard(void)
* Receive a bootp packet. The options are listed in iov[1...iov_len].
* iov[0] must point to the bootp packet header.
* Returns:
- * 0 = Error, try again later
+ * -1 = Error, try again later
+* 0 = Discarded packet (non-DHCP/BOOTP traffic)
* >0 = Size of packet
*/
int packet_recv(struct iovec *iov, int iov_len)
@@ -236,7 +237,7 @@ int packet_recv(struct iovec *iov, int iov_len)
ret = recvfrom(pkt_fd, &iph, sizeof(struct iphdr),
MSG_PEEK, NULL, NULL);
if (ret == -1)
- return 0;
+ return -1;
if (iph.ihl < 5 || iph.version != IPVERSION)
goto discard_pkt;