static void dhcp_send_request_packet(struct bootp *bp_offer) { struct bootp *bp; int extlen; IPaddr_t OfferedIP; unsigned char *payload = net_udp_get_payload(dhcp_con); debug("%s: Sending DHCPREQUEST\n", __func__); bp = (struct bootp *)payload; bp->bp_op = OP_BOOTREQUEST; bp->bp_htype = HWT_ETHER; bp->bp_hlen = HWL_ETHER; bp->bp_hops = 0; /* FIXME what is this? */ // bp->bp_secs = htons(get_timer(0) / CFG_HZ); net_copy_ip(&bp->bp_ciaddr, &bp_offer->bp_ciaddr); /* both in network byte order */ net_copy_ip(&bp->bp_yiaddr, &bp_offer->bp_yiaddr); net_copy_ip(&bp->bp_siaddr, &bp_offer->bp_siaddr); /* * RFC3046 requires Relay Agents to discard packets with * nonzero and offered giaddr */ net_write_ip(&bp->bp_giaddr, 0); memcpy(bp->bp_chaddr, dhcp_con->et->et_src, 6); /* * ID is the id of the OFFER packet */ net_copy_uint32(&bp->bp_id, &bp_offer->bp_id); /* * Copy options from OFFER packet if present */ net_copy_ip(&OfferedIP, &bp->bp_yiaddr); extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_REQUEST, net_dhcp_server_ip, OfferedIP); debug("Transmitting DHCPREQUEST packet\n"); net_udp_send(dhcp_con, sizeof(*bp) + extlen); }
static int bootp_request(void) { struct bootp *bp; int ext_len; int ret; unsigned char *payload = net_udp_get_payload(dhcp_con); const char *bfile; dhcp_state = INIT; debug("BOOTP broadcast\n"); bp = (struct bootp *)payload; bp->bp_op = OP_BOOTREQUEST; bp->bp_htype = HWT_ETHER; bp->bp_hlen = HWL_ETHER; bp->bp_hops = 0; bp->bp_secs = htons(get_time_ns() >> 30); net_write_ip(&bp->bp_ciaddr, 0); net_write_ip(&bp->bp_yiaddr, 0); net_write_ip(&bp->bp_siaddr, 0); net_write_ip(&bp->bp_giaddr, 0); memcpy(bp->bp_chaddr, dhcp_con->et->et_src, 6); bfile = getenv("bootfile"); if (bfile) safe_strncpy (bp->bp_file, bfile, sizeof(bp->bp_file)); /* Request additional information from the BOOTP/DHCP server */ ext_len = dhcp_extended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0); Bootp_id = (uint32_t)get_time_ns(); net_copy_uint32(&bp->bp_id, &Bootp_id); dhcp_state = SELECTING; ret = net_udp_send(dhcp_con, sizeof(*bp) + ext_len); return ret; }
static void copy_uint32_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen) { net_copy_uint32(opt->data, (uint32_t *)popt); };
static void dhcp_options_process(unsigned char *popt, struct bootp *bp) { unsigned char *end = popt + sizeof(*bp) + OPT_SIZE; int oplen; IPaddr_t ip; char str[256]; while (popt < end && *popt != 0xff) { oplen = *(popt + 1); switch (*popt) { case 1: ip = net_read_ip(popt + 2); net_set_netmask(ip); break; case 3: ip = net_read_ip(popt + 2); net_set_gateway(ip); break; case 6: ip = net_read_ip(popt + 2); setenv_ip("nameserver", ip); break; case 12: memcpy(str, popt + 2, oplen); str[oplen] = 0; setenv("hostname", str); break; case 15: memcpy(str, popt + 2, oplen); str[oplen] = 0; setenv("domainname", str); break; case 17: memcpy(str, popt + 2, oplen); str[oplen] = 0; setenv("rootpath", str); break; case 51: net_copy_uint32 (&dhcp_leasetime, (uint32_t *)(popt + 2)); break; case 53: /* Ignore Message Type Option */ break; case 54: net_copy_ip(&net_dhcp_server_ip, (popt + 2)); break; case 58: /* Ignore Renewal Time Option */ break; case 59: /* Ignore Rebinding Time Option */ break; case 66: /* Ignore TFTP server name */ break; case 67: /* vendor opt bootfile */ /* * I can't use dhcp_vendorex_proc here because I need * to write into the bootp packet - even then I had to * pass the bootp packet pointer into here as the * second arg */ memcpy(str, popt + 2, oplen); str[oplen] = 0; if (bp->bp_file[0] == '\0') { /* * only use vendor boot file if we didn't * receive a boot file in the main non-vendor * part of the packet - god only knows why * some vendors chose not to use this perfectly * good spot to store the boot file (join on * Tru64 Unix) it seems mind bogglingly crazy * to me */ printf("*** WARNING: using vendor " "optional boot file\n"); setenv("bootfile", str); } break; default: #ifdef CONFIG_BOOTP_VENDOREX if (dhcp_vendorex_proc (popt)) break; #endif debug("*** Unhandled DHCP Option in OFFER/ACK: %d\n", *popt); break; } popt += oplen + 2; /* Process next option */ } }