aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlrich Dangel <uli@spamt.net>2011-03-28 18:59:34 +0200
committermaximilian attems <max@stro.at>2011-03-29 14:51:27 +0200
commit92823d1a78a8a6f3e7a7cc36f949ca6379c4e77c (patch)
treea481f1248ae9131d5beddd316c2a36ef4af9746b
parente90552b6d78dd4d090d014024da00723e179df30 (diff)
downloadklibc-92823d1a78a8a6f3e7a7cc36f949ca6379c4e77c.tar.gz
[klibc] ipconfig: Only peek and discard packets from specified device.
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@spamt.net> 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.c2
-rw-r--r--usr/kinit/ipconfig/main.c16
-rw-r--r--usr/kinit/ipconfig/packet.c16
-rw-r--r--usr/kinit/ipconfig/packet.h6
5 files changed, 20 insertions, 22 deletions
diff --git a/usr/kinit/ipconfig/bootp_proto.c b/usr/kinit/ipconfig/bootp_proto.c
index baf9d3e8ef5c8..f2cc90c85e2c1 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 fc0494d3b4e8e..993db520aa55d 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 d501bec0cebcc..1e48083e21ff7 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 84267b7db8f01..993a2fa1bb127 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 627d282aad8ae..524f3937b172f 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 */