[GXemul-devel] patch for DHCP
Status: Alpha
Brought to you by:
gavare
From: George K. <xke...@ne...> - 2012-09-05 01:17:02
|
GXemul responds to DHCP requests, but the responses are not valid. Here is a patch so that NetBSD/pmax 5.1.2, running inside the emulator, can use dhcpcd to configure the network. First, this patch fixes the calculation for UDP checksums. I deleted "- 8". This is so dhcpcd no longer complains about "invalid UDP packet". Second, this patch adds these DHCP options: subnet mask, router, domain name server, server identifier. This is so dhcpcd does not "reject DHCP"; it seems that dhcpcd requires the option for server identifier. Where should I post the patch? Here to gxemul-devel, or elsewhere? --George Koehler Index: src/net/net_ip.cc =================================================================== --- src/net/net_ip.cc (revision 5802) +++ src/net/net_ip.cc (working copy) @@ -936,7 +936,7 @@ * * Handle an IPv4 DHCP broadcast packet, coming from the emulated NIC. * - * Read http://www.ietf.org/rfc/rfc2131.txt for details on DHCP. + * Read http://tools.ietf.org/html/rfc2131 for details on DHCP. * (And http://users.telenet.be/mydotcom/library/network/dhcp.htm.) */ static void net_ip_broadcast_dhcp(struct net *net, void *extra, @@ -947,7 +947,7 @@ */ #if 1 struct ethernet_packet_link *lp; - int i; + int i, reply_len; fatal("[ net: IPv4 DHCP: "); #if 1 @@ -1007,15 +1007,21 @@ */ fatal(" ]\n"); - lp = net_allocate_ethernet_packet_link(net, extra, len); + reply_len = 307; + lp = net_allocate_ethernet_packet_link(net, extra, reply_len); - /* Copy the old packet first: */ - memcpy(lp->data, packet, len); + /* From old packet, copy everything before options field: */ + memcpy(lp->data, packet, 278); /* We are sending to the client, from the gateway: */ memcpy(lp->data + 0, packet + 6, 6); memcpy(lp->data + 6, net->gateway_ethernet_addr, 6); + /* Set IP length: */ + lp->data[16] = (reply_len - 14) >> 8; + lp->data[17] = (reply_len - 14) & 0xff; + + /* Set IP addresses: */ memcpy(lp->data + 26, &net->gateway_ipv4_addr[0], 4); lp->data[30] = 0xff; lp->data[31] = 0xff; @@ -1026,6 +1032,10 @@ memcpy(lp->data + 34, packet + 36, 2); memcpy(lp->data + 36, packet + 34, 2); + /* Set UDP length: */ + lp->data[38] = (reply_len - 34) >> 8; + lp->data[39] = (reply_len - 34) & 0xff; + /* Client's (yiaddr) IPv4 address: */ lp->data[58] = 10; lp->data[59] = 0; @@ -1040,11 +1050,35 @@ snprintf((char *)lp->data + 70+16+64, 8, "gxemul"); + /* Options field at offset 278: */ + lp->data[278] = 99; + lp->data[279] = 130; + lp->data[280] = 83; + lp->data[281] = 99; + + /* DHCP options, http://tools.ietf.org/html/rfc1533 */ + lp->data[282] = 1; /* subnet mask */ + lp->data[283] = 4; + lp->data[284] = 255; + lp->data[285] = 0; + lp->data[286] = 0; + lp->data[287] = 0; + lp->data[288] = 3; /* router */ + lp->data[289] = 4; + memcpy(lp->data + 290, &net->gateway_ipv4_addr[0], 4); + lp->data[294] = 6; /* domain name server */ + lp->data[295] = 4; + memcpy(lp->data + 296, &net->gateway_ipv4_addr[0], 4); + lp->data[300] = 54; /* server identifier */ + lp->data[301] = 4; + memcpy(lp->data + 302, &net->gateway_ipv4_addr[0], 4); + lp->data[306] = 255; /* end */ + /* Recalculate IP header checksum: */ net_ip_checksum(lp->data + 14, 10, 20); /* ... and the UDP checksum: */ - net_ip_tcp_checksum(lp->data + 34, 6, len - 34 - 8, + net_ip_tcp_checksum(lp->data + 34, 6, reply_len - 34, lp->data + 26, lp->data + 30, 1); |