Hello, all:
I am executing ipconfig under a terminal and find one thing:
If I execute ipconfig the first time, it will get an ip address from
dhcp server, If I execute ipconfig the second time (or more times),
since my TP-LINK TL-R402M router will give an icmp(ping) packet before
DHCPOFFER,
the ipconfig will fail after it receive the packet and tries unpack
teh packet in packet_recv() since we have a packet form checking
there:
if (ntohs(ip->tot_len) > ret || ip->protocol != IPPROTO_UDP)
goto free_pkt;
ip config will fall in a loop and always got the icmp packet instead
of DHCPOFFER packet in this situation.
If I change the retrun value of packet_peek and make a packet form
checking in more early stage, I can avoiding ipconfig fall in a loop
with icmp packet, like this:
--- /work/atcs/os_pkg/klibc-git/klibc/usr/kinit/ipconfig.old/packet.c 2009-03-11
15:30:45.000000000 +0800
+++ packet.c 2009-03-11 17:39:56.000000000 +0800
@@ -176,6 +176,8 @@
*/
ret = recvfrom(pkt_fd, &iph, sizeof(struct iphdr),
MSG_PEEK, (struct sockaddr *)&sll, &sllen);
+
+
if (ret == -1)
return -1;
@@ -184,6 +186,10 @@
if (iph.ihl < 5 || iph.version != IPVERSION)
goto discard_pkt;
+
+ if (iph.protocol != IPPROTO_UDP)
+ goto discard_pkt;
+
*ifindex = sll.sll_ifindex;
@@ -191,7 +197,7 @@
discard_pkt:
packet_discard();
- return 0;
+ return -1;
}
void packet_discard(void)
This will make packet_peek return -1 if the packet is not what we
want. and affect the do_pkt_recv() process
static int do_pkt_recv(int pkt_fd, time_t now)
{
int ifindex, ret;
struct state *s;
ret = packet_peek(&ifindex);
if (ret < 0)
goto bail;
for (s = slist; s; s = s->next) {
if (s->dev->ifindex == ifindex) {
ret |= process_receive_event(s, now);
break;
}
}
bail:
return ret;
}
we will not do the above for loop since we don't want the received packet.
There are two questions:
1. Are you plan to make ipconfig work with network card which already
have an ip?
2. Is it safely to change the return value to -1 in discard_pkg lable
of packet_peek()?
Thank you very much.