diff options
author | Julien BLACHE <julien-externe.blache@edf.fr> | 2010-08-10 15:37:10 +0200 |
---|---|---|
committer | maximilian attems <max@stro.at> | 2010-08-25 20:11:05 +0200 |
commit | b02b0f71aa7be125f0d64e44124d7f7ead0175b5 (patch) | |
tree | 724f0878fb9ebc30e4dea70289207533cb700dab | |
parent | 47da4f6ab856250854465f88edc6d76ca0ba017b (diff) | |
download | klibc-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.c | 2 | ||||
-rw-r--r-- | usr/kinit/ipconfig/dhcp_proto.c | 4 | ||||
-rw-r--r-- | usr/kinit/ipconfig/packet.c | 5 |
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; |