summaryrefslogtreecommitdiffstats
path: root/sbin/dhclient/packet.c
diff options
context:
space:
mode:
authorphilip <philip@FreeBSD.org>2009-10-21 23:50:35 +0000
committerphilip <philip@FreeBSD.org>2009-10-21 23:50:35 +0000
commita72663b23bf3cf6b649e0ef3794c893c317ed0bd (patch)
tree4932df0222a83ed26798bc6e55796c6d07fa1066 /sbin/dhclient/packet.c
parentec50bd2dc073063cd6fdb77344b2850072ce342c (diff)
downloadFreeBSD-src-a72663b23bf3cf6b649e0ef3794c893c317ed0bd.zip
FreeBSD-src-a72663b23bf3cf6b649e0ef3794c893c317ed0bd.tar.gz
Make dhclient use bootpc (68) as the source port for unicast DHCPREQUEST
packets instead of allowing the protocol stack to pick a random source port. This fixes the behaviour where dhclient would never transition from RENEWING to BOUND without going through REBINDING in networks which are paranoid about DHCP spoofing, such as most mainstream cable-broadband ISP networks. Reviewed by: brooks Obtained from: OpenBSD (partly - I'm not convinced their solution can work) MFC after: 1 week (pending re approval)
Diffstat (limited to 'sbin/dhclient/packet.c')
-rw-r--r--sbin/dhclient/packet.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/sbin/dhclient/packet.c b/sbin/dhclient/packet.c
index 484953c..2e90cc8 100644
--- a/sbin/dhclient/packet.c
+++ b/sbin/dhclient/packet.c
@@ -135,6 +135,17 @@ assemble_udp_ip_header(unsigned char *buf, int *bufix, u_int32_t from,
ip.ip_dst.s_addr = to;
ip.ip_sum = wrapsum(checksum((unsigned char *)&ip, sizeof(ip), 0));
+
+ /*
+ * While the BPF -- used for broadcasts -- expects a "true" IP header
+ * with all the bytes in network byte order, the raw socket interface
+ * which is used for unicasts expects the ip_len field to be in host
+ * byte order. In both cases, the checksum has to be correct, so this
+ * is as good a place as any to turn the bytes around again.
+ */
+ if (to != INADDR_BROADCAST)
+ ip.ip_len = ntohs(ip.ip_len);
+
memcpy(&buf[*bufix], &ip, sizeof(ip));
*bufix += sizeof(ip);
OpenPOWER on IntegriCloud