libnet_ptag_t libnet_build_bootpv4(u_char opcode, u_char htype, u_char hlen, u_char hopcount, u_long xid, u_short secs, u_short flags, u_long cip, u_long yip, u_long sip, u_long gip, u_char *chaddr, u_char *sname, u_char *file, u_char *payload, u_long payload_s, libnet_t *l, libnet_ptag_t ptag) { return (libnet_build_dhcpv4(opcode, htype, hlen, hopcount, xid, secs, flags, cip, yip, sip, gip, chaddr, sname, file, payload, payload_s, l, ptag)); }
libnet_ptag_t libnet_build_bootpv4(uint8_t opcode, uint8_t htype, uint8_t hlen, uint8_t hopcount, uint32_t xid, uint16_t secs, uint16_t flags, uint32_t cip, uint32_t yip, uint32_t sip, uint32_t gip, const uint8_t *chaddr, const char *sname, const char *file, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { return (libnet_build_dhcpv4(opcode, htype, hlen, hopcount, xid, secs, flags, cip, yip, sip, gip, chaddr, sname, file, payload, payload_s, l, ptag)); }
int main(int argc, char **argv) { int ch, dhcp_payload_len; unsigned char *dhcp_payload; libnet_ptag_t ptag_dhcpv4, ptag_udp, ptag_ipv4, ptag_ethernet; char *arg_secs, *arg_cip, *arg_chaddr, *arg_sip, *arg_ifname; char *arg_operation, *arg_timeout, *arg_xid, *arg_flags, *arg_yip; char *arg_gip, *arg_sname, *arg_fname, *arg_ether_dst, *stmp; char *arg_ipv4_src, *arg_ipv4_dst, *arg_ipv4_tos, *arg_ipv4_ttl; char *arg_reply_count; if (argc < 2) usage("too few arguments"); srandom(time(NULL)); arg_secs = arg_cip = arg_chaddr = arg_sip = arg_ifname = NULL; arg_operation = arg_timeout = arg_xid = arg_flags = arg_yip = NULL; arg_gip = arg_sname = arg_fname = arg_ether_dst = arg_reply_count = NULL; arg_ipv4_src = arg_ipv4_dst = arg_ipv4_tos = arg_ipv4_ttl = NULL; verbosity = 1; while ((ch = getopt(argc, argv, "s:c:h:i:o:t:x:f:y:g:S:A:B:O:X:v:F:T:L:Q:E:w:n:m")) != -1) { switch (ch) { case 's': arg_secs = optarg; break; case 'c': arg_cip = optarg; break; case 'h': arg_chaddr = optarg; break; case 'S': arg_sip = optarg; break; case 'i': arg_ifname = optarg; break; case 'o': arg_operation = optarg; break; case 't': arg_timeout = optarg; break; case 'x': arg_xid = optarg; break; case 'f': arg_flags = optarg; break; case 'y': arg_yip = optarg; break; case 'B': arg_fname = optarg; break; case 'A': arg_sname = optarg; break; case 'g': arg_gip = optarg; break; case 'F': arg_ipv4_src = optarg; break; case 'T': arg_ipv4_dst = optarg; break; case 'L': arg_ipv4_ttl = optarg; break; case 'Q': arg_ipv4_tos = optarg; break; case 'n': arg_reply_count = optarg; break; case 'E': arg_ether_dst = optarg; break; case 'v': verbosity = atoi(optarg); break; case 'm': no_double_options = 0; break; case 'O': add_option(optarg); break; case 'X': add_hexoption(optarg); break; case 'w': option_lookup(optarg); break; case '?': default: usage("unknown argument"); } } argc -= optind; argv += optind; /* Set some basic defaults */ set_defaults(); /* Make sure network interface was specified with -i option */ if (arg_ifname == NULL) { usage("Error: network interface (-i option) not specified."); } strncpy(ifname, arg_ifname, 99); /* Try to have pcap and libnet use the interface */ pcp = pcap_open_live(ifname, SNAPLEN, 1, 1, pcap_errbuf); if (pcp == NULL) { printf("pcap_open_live(%s) failed! Did you give the right interface name " "and are you root?\n", ifname); printf("pcap said: %s\n", pcap_errbuf); exit(1); } lnp = libnet_init(LIBNET_LINK, ifname, libnet_errbuf); if (lnp == NULL) { printf("libnet_init(%s) failed!\n", ifname); printf("libnet said: %s\n", libnet_errbuf); exit(1); } /* Set chaddr MAC address */ if (arg_chaddr != NULL) { int len = ETHER_ADDR_LEN; /*chaddr = libnet_hex_aton((int8_t *)arg_chaddr, &len);*/ chaddr = libnet_hex_aton(arg_chaddr, &len); if (chaddr == NULL) { if (verbosity > 0) printf("Invalid chaddr MAC address specified (%s)\n", arg_chaddr); exit(1); } } else { /* Try to retrieve MAC address using libnet */ chaddr = (u_int8_t *)libnet_get_hwaddr(lnp); if (chaddr == NULL) { if (verbosity > 1) { printf("Failed to retrieve MAC address for interface %s, using 0:0:0:0:0:0\n" "Libnet said: %s\n", ifname, libnet_errbuf); } memset(chaddr, 0, ETHER_ADDR_LEN); } } /* Set cip address */ if (arg_cip != NULL) { cip = inet_addr(arg_cip); if (cip == INADDR_NONE) { if (verbosity > 0) printf("Invalid cip address specified (%s)\n", arg_cip); exit(1); } cip = ntohl(cip); } else { /* Try to retrieve IP address using libnet */ cip = libnet_get_ipaddr4(lnp); if ((int)cip == -1) { if (verbosity > 1) { printf("Failed to retrieve IPv4 address for interface %s, using cip 0.0.0.0\n" "Libnet said: %s\n", ifname, libnet_errbuf); } cip = inet_addr("0.0.0.0"); } else cip = htonl(cip); } /**************************/ /* Set various parameters */ /**************************/ if (arg_operation != NULL) { if (option_added(LIBNET_DHCP_MESSAGETYPE) && no_double_options) { if (verbosity > 0) { printf("Error: DHCP messagetype specified twice (don't use -o option if\n" " you also intend to use -O to set option 53 (messagetype))\n"); } exit(1); } if (strcasecmp(arg_operation, "discover") == 0) { operation = LIBNET_DHCP_MSGDISCOVER; if (arg_timeout == NULL) timeout = 5; } else if (strcasecmp(arg_operation, "request") == 0) { operation = LIBNET_DHCP_MSGREQUEST; if (arg_timeout == NULL) timeout = 5; } else if (strcasecmp(arg_operation, "inform") == 0) { operation = LIBNET_DHCP_MSGINFORM; if (timeout == 0) timeout = 5; } else if (strcasecmp(arg_operation, "release") == 0) operation = LIBNET_DHCP_MSGRELEASE; else if (strcasecmp(arg_operation, "decline") == 0) operation = LIBNET_DHCP_MSGDECLINE; else { if (verbosity > 0) usage("Invalid DHCP operation type"); else exit(1); } /* Add MESSAGETYPE DHCP option */ num_options++; options = (struct dhcp_option *) realloc(options, num_options * sizeof(struct dhcp_option)); options[num_options-1].opnum = LIBNET_DHCP_MESSAGETYPE; options[num_options-1].oplen = 1; options[num_options-1].opdata[0] = operation; } else { /* no "-o operation" argument given */ if (option_added(LIBNET_DHCP_MESSAGETYPE) == 0) { /* Add MESSAGETYPE DHCP option */ num_options++; options = (struct dhcp_option *) realloc(options, num_options * sizeof(struct dhcp_option)); options[num_options-1].opnum = LIBNET_DHCP_MESSAGETYPE; options[num_options-1].oplen = 1; options[num_options-1].opdata[0] = operation; } } if (arg_secs != NULL) { unsigned long ultmp; ultmp = strtoul(arg_secs, &stmp, 0); if (*stmp != '\0' || ultmp > 65535) { if (verbosity > 0) printf("Error: secs must be 0-65535 (was: %s)\n", arg_secs); exit(1); } secs = (u_int16_t)ultmp; } if (arg_timeout != NULL) { timeout = strtoul(arg_timeout, &stmp, 0); if (*stmp != '\0') { if (verbosity > 0) printf("Error: timeout value must be 0 or a positive integer (was: %s)\n", arg_timeout); exit(1); } } if (arg_reply_count != NULL) { reply_count = strtoul(arg_reply_count, &stmp, 0); if (*stmp != '\0') { if (verbosity > 0) printf("Error: reply_count value must be 0 or a positive integer (was: %s)\n", arg_reply_count); exit(1); } } if (arg_xid != NULL) { xid = strtoul(arg_xid, &stmp, 0); if (*stmp != '\0') { if (verbosity > 0) printf("Error: xid value must be 0 or a positive integer (was: %s)\n", arg_xid); exit(1); } } if (arg_flags != NULL) { unsigned long ultmp; ultmp = strtoul(arg_flags, &stmp, 0); if (*stmp != '\0' || ultmp > 65535) { if (verbosity > 0) printf("Error: flags value must be 0-65535 (was: %s)\n", arg_flags); exit(1); } flags = (u_int16_t)ultmp; } if (arg_sip != NULL) { sip = inet_addr(arg_sip); if (sip == INADDR_NONE) { if (verbosity > 0) printf("Error: specified sip value is not a valid IPv4 address (was: %s)\n", arg_sip); exit(1); } } if (arg_yip != NULL) { yip = inet_addr(arg_yip); if (yip == INADDR_NONE) { if (verbosity > 0) printf("Error: specified yip value is not a valid IPv4 address (was: %s)\n", arg_yip); exit(1); } } if (arg_gip != NULL) { gip = inet_addr(arg_gip); if (gip == INADDR_NONE) { if (verbosity > 0) printf("Error: specified gip value is not a valid IPv4 address (was: %s)\n", arg_gip); exit(1); } } if (arg_fname != NULL) { fname = (char *)malloc(strlen(fname)+1); strcpy(fname, arg_fname); } if (arg_sname != NULL) { sname = (char *)malloc(strlen(sname)+1); strcpy(sname, arg_sname); } if (arg_ipv4_src != NULL) { ipv4_src = inet_addr(arg_ipv4_src); if (ipv4_src == INADDR_NONE) { if (verbosity > 0) printf("Error: specified ipv4_src value is not a valid IPv4 address (was: %s)\n", arg_ipv4_src); exit(1); } } if (arg_ipv4_dst != NULL) { ipv4_dst = inet_addr(arg_ipv4_dst); if (ipv4_dst == INADDR_NONE) { if (verbosity > 0) printf("Error: specified ipv4_dst value is not a valid IPv4 address (was: %s)\n", arg_ipv4_dst); exit(1); } } if (arg_ipv4_ttl != NULL) { unsigned long ultmp; ultmp = strtoul(arg_ipv4_ttl, &stmp, 0); if (*stmp != '\0' || ultmp > 255) { if (verbosity > 0) printf("Error: ipv4_ttl value must be 0-255 (was: %s)\n", arg_xid); exit(1); } ipv4_ttl = (u_int8_t)ultmp; } if (arg_ipv4_tos != NULL) { unsigned long ultmp; ultmp = strtoul(arg_ipv4_tos, &stmp, 0); if (*stmp != '\0' || ultmp > 255) { if (verbosity > 0) printf("Error: ipv4_tos value must be 0-255 (was: %s)\n", arg_ipv4_tos); exit(1); } ipv4_tos = (u_int8_t)ultmp; } if (arg_ether_dst != NULL) { int l = ETHER_ADDR_LEN; /*ether_dst = libnet_hex_aton((int8_t *)arg_ether_dst, &l);*/ ether_dst = libnet_hex_aton(arg_ether_dst, &l); if (ether_dst == NULL) { if (verbosity > 0) printf("Error: invalid ethernet destination MAC specified (was: %s)\n", arg_ether_dst); exit(1); } } /****************************** * Done setting parameters. * * Start building DHCP packet * ******************************/ libnet_clear_packet(lnp); /* Build DHCP payload (DHCP options section) */ dhcp_payload = build_payload(&dhcp_payload_len); /* Create DHCP message */ ptag_dhcpv4 = libnet_build_dhcpv4(LIBNET_DHCP_REQUEST, BOOTP_HTYPE_ETHER, ETHER_ADDR_LEN, BOOTP_HOPCOUNT, xid, secs, flags, cip, yip, sip, gip, chaddr, sname, fname, dhcp_payload, dhcp_payload_len, lnp, 0); if (ptag_dhcpv4 == -1) { printf("Failed to build bootp packet: %s\n", libnet_errbuf); exit(1); } /* libnet_ptag_t libnet_build_udp(u_int16_t sp, u_int16_t dp, u_int16_t len, u_int16_t sum, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag); */ /* Create UDP datagram */ ptag_udp = libnet_build_udp(UDP_SRCPORT, UDP_DSTPORT, dhcp_payload_len + LIBNET_DHCPV4_H + LIBNET_UDP_H, 0, NULL, 0, lnp, 0); if (ptag_udp == -1) { printf("Failed to build udp packet: %s\n", libnet_errbuf); exit(1); } /* libnet_ptag_t libnet_build_ipv4(u_int16_t len, u_int8_t tos, u_int16_t id, u_int16_t frag, u_int8_t ttl, u_int8_t prot, u_int16_t sum, u_int32_t src, u_int32_t dst, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag); */ /* Create IPv4 datagram */ ptag_ipv4 = libnet_build_ipv4(dhcp_payload_len + LIBNET_DHCPV4_H + LIBNET_UDP_H + LIBNET_IPV4_H, ipv4_tos, ipv4_id++, 0, ipv4_ttl, IPPROTO_UDP, 0, ipv4_src, ipv4_dst, NULL, 0, lnp, 0); if (ptag_ipv4 == -1) { printf("Failed to build ipv4 packet: %s\n", libnet_errbuf); exit(1); } /* Create ethernet packet */ ptag_ethernet = libnet_autobuild_ethernet(ether_dst, ETHERTYPE_IP, lnp); if (ptag_ethernet == -1) { printf("Failed to build ethernet packet: %s\n", libnet_errbuf); exit(1); } /* Write packet to network */ if (libnet_write(lnp) == -1) { printf("Failed to write ethernet packet to network: %s\n", libnet_errbuf); exit(1); } /* If we have to wait and listen for server replies, we use a timer and a signal handler to quit. We do this as libpcap doesn't support non-blocking packet capture on some (many?) platforms. We could have launched another thread also, but using timers and signals is simpler. */ if (timeout > 0) { struct itimerval itv; itv.it_interval.tv_sec = itv.it_value.tv_sec = timeout; itv.it_interval.tv_usec = itv.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itv, NULL); signal(SIGALRM, sighandler); pcap_loop(pcp, -1, pcap_callback, NULL); } libnet_destroy(lnp); pcap_close(pcp); exit(0); }
int main(int argc, char *argv[]) { char *intf; u_long src_ip, options_len, orig_len; int i; libnet_t *l; libnet_ptag_t t; libnet_ptag_t ip; libnet_ptag_t udp; libnet_ptag_t dhcp; struct libnet_ether_addr *ethaddr; struct libnet_stats ls; char errbuf[LIBNET_ERRBUF_SIZE]; u_char options_req[] = { LIBNET_DHCP_SUBNETMASK , LIBNET_DHCP_BROADCASTADDR , LIBNET_DHCP_TIMEOFFSET , LIBNET_DHCP_ROUTER , LIBNET_DHCP_DOMAINNAME , LIBNET_DHCP_DNS , LIBNET_DHCP_HOSTNAME }; u_char *options; u_char enet_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; u_char *tmp; // have to specify interface if (argc != 2) usage(argv[0]); intf = argv[1]; l = libnet_init( LIBNET_LINK, // injection type intf, // network interface errbuf); // errbuf if (!l) { fprintf(stderr, "libnet_init: %s", errbuf); exit(EXIT_FAILURE); } else { src_ip = libnet_get_ipaddr4(l);; if ((ethaddr = libnet_get_hwaddr(l)) == NULL) { fprintf(stderr, "libnet_get_hwaddr: %s\n", libnet_geterror(l)); exit(EXIT_FAILURE); } printf("ip addr : %s\n", libnet_addr2name4(src_ip, LIBNET_DONT_RESOLVE)); printf("eth addr : "); for (i = 0; i < 6; i++) { printf("%x", ethaddr->ether_addr_octet[i]); if (i != 5) { printf(":"); } } printf("\n"); // build options packet i = 0; options_len = 3; // update total payload size // we are a discover packet options = malloc(3); options[i++] = LIBNET_DHCP_MESSAGETYPE; // type options[i++] = 1; // len options[i++] = LIBNET_DHCP_MSGDISCOVER; // data orig_len = options_len; options_len += sizeof(options_req) + 2; // update total payload size // workaround for realloc on old machines // options = realloc(options, options_len); // resize options buffer tmp = malloc(options_len); memcpy(tmp, options, orig_len); free(options); options = tmp; // we are going to request some parameters options[i++] = LIBNET_DHCP_PARAMREQUEST; // type options[i++] = sizeof(options_req); // len memcpy(options + i, options_req, sizeof(options_req)); // data i += sizeof(options_req); // if we have an ip already, let's request it. if (src_ip) { orig_len = options_len; options_len += 2 + sizeof(src_ip); // workaround for realloc on old machines // options = realloc(options, options_len); tmp = malloc(options_len); memcpy(tmp, options, orig_len); free(options); options = tmp; options[i++] = LIBNET_DHCP_DISCOVERADDR; // type options[i++] = sizeof(src_ip); // len memcpy(options + i, (char *)&src_ip, sizeof(src_ip));// data i += sizeof(src_ip); } // end our options packet options[i] = LIBNET_DHCP_END; // make sure we are at least the minimum length, if not fill // this could go in libnet, but we will leave it in the app for now if (options_len + LIBNET_DHCPV4_H < LIBNET_BOOTP_MIN_LEN) { orig_len = options_len; options_len = LIBNET_BOOTP_MIN_LEN - LIBNET_DHCPV4_H; // workaround for realloc on old machines // options = realloc(options, options_len); tmp = malloc(options_len); memcpy(tmp, options, orig_len); free(options); options = tmp; memset(options + i, 0, options_len - i); } // the goodies are here dhcp = libnet_build_dhcpv4( LIBNET_DHCP_REQUEST, // opcode 1, // hardware type 6, // hardware address length 0, // hop count 0xdeadbeef, // transaction id 0, // seconds since bootstrap 0x8000, // flags 0, // client ip 0, // your ip 0, // server ip 0, // gateway ip ethaddr->ether_addr_octet, // client hardware addr NULL, // server host name NULL, // boot file options, // dhcp options stuck in payload since it is dynamic options_len, // length of options l, // libnet handle 0); // libnet id // wrap it udp = libnet_build_udp( 68, // source port 67, // destination port LIBNET_UDP_H + LIBNET_DHCPV4_H + options_len, // packet size 0, // checksum NULL, // payload 0, // payload size l, // libnet handle 0); // libnet id // hook me up with some ipv4 ip = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_DHCPV4_H + options_len, // length 0x10, // TOS 0, // IP ID 0, // IP Frag 16, // TTL IPPROTO_UDP, // protocol 0, // checksum src_ip, // src ip inet_addr("255.255.255.255"), // destination ip NULL, // payload 0, // payload size l, // libnet handle 0); // libnet id // we can just autobuild since we arent doing anything tricky t = libnet_autobuild_ethernet( enet_dst, // ethernet destination ETHERTYPE_IP, // protocol type l); // libnet handle // write to the wire if (libnet_write(l) == -1) { fprintf(stderr, " %s: libnet_write: %s\n", argv[0], strerror(errno)); exit(EXIT_FAILURE); } // fill and print stats libnet_stats(l, &ls); fprintf(stderr, "Packets sent: %ld\n" "Packet errors: %ld\n" "Bytes written: %ld\n", ls.packets_sent, ls.packet_errors, ls.bytes_written); libnet_destroy(l); // free mem free(options); exit(0); } exit(0); }
void configure_net_dhcp() { kprintf("k_network: configure_net_dhcp() - attempting DHCP configuration\n"); kprintf("k_network: configure_net_dhcp() - building DHCP request\n"); EFI_SIMPLE_NETWORK_MODE *m = simple_net->Mode; int i = 0; u_char options_req[] = { LIBNET_DHCP_SUBNETMASK, LIBNET_DHCP_BROADCASTADDR, LIBNET_DHCP_TIMEOFFSET, LIBNET_DHCP_ROUTER, LIBNET_DHCP_DOMAINNAME, LIBNET_DHCP_DNS, LIBNET_DHCP_HOSTNAME }; u_char *options; libnet_t *l; char* err_buf; l = libnet_init(LIBNET_NONE,NULL,err_buf); if(!l) { kprintf("libnet_init: %s\n", err_buf); } kprintf("k_network: configure_net_dhcp() - libnet setup\n"); u_long options_len = 3; libnet_ptag_t dhcp_packet; libnet_ptag_t udp_packet; libnet_ptag_t ip_packet; options = malloc(3); options[i++] = LIBNET_DHCP_MESSAGETYPE; options[i++] = 1; options[i++] = LIBNET_DHCP_MSGDISCOVER; u_long orig_len = options_len; options_len += sizeof(options_req) + 2; u_char *tmp = malloc(options_len); memcpy(tmp, options, orig_len); free(options); options = tmp; options[i++] = LIBNET_DHCP_PARAMREQUEST; options[i++] = sizeof(options_req); memcpy(options + i, options_req, sizeof(options_req)); i += sizeof(options_req); orig_len = options_len; options_len += 1; tmp = malloc(options_len); memcpy(tmp, options, orig_len); free(options); options = tmp; options[i++] = LIBNET_DHCP_END; if (options_len + LIBNET_DHCPV4_H < LIBNET_BOOTP_MIN_LEN) { orig_len = options_len; options_len = LIBNET_BOOTP_MIN_LEN - LIBNET_DHCPV4_H; tmp = malloc(options_len); memcpy(tmp, options, orig_len); free(options); options = tmp; memset(options + i, 0, options_len - i); } dhcp_packet = libnet_build_dhcpv4( LIBNET_DHCP_REQUEST, /* opcode */ 1, /* hardware type */ 6, /* hardware address length */ 0, /* hop count */ 0xdeadbeef, /* transaction id */ 0, /* seconds since bootstrap */ 0x8000, /* flags */ 0, /* client ip */ 0, /* your ip */ 0, /* server ip */ 0, /* gateway ip */ m->CurrentAddress.Addr, /* client hardware addr */ NULL, /* server host name */ NULL, /* boot file */ options, /* dhcp options in payload */ options_len, /* length of options */ l, /* libnet context */ 0); /* libnet ptag */ udp_packet = libnet_build_udp( 68, /* source port */ 67, /* destination port */ LIBNET_UDP_H + LIBNET_DHCPV4_H + options_len, /* packet size */ 0, /* checksum */ NULL, /* payload */ 0, /* payload size */ l, /* libnet context */ 0); /* libnet ptag */ ip_packet = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_DHCPV4_H + options_len, /* length */ 0x10, /* TOS */ 0, /* IP ID */ 0, /* IP Frag */ 16, /* TTL */ IPPROTO_UDP, /* protocol */ 0, /* checksum */ 0, /* src ip */ 0, /* destination ip */ NULL, /* payload */ 0, /* payload size */ l, /* libnet context */ 0); /* libnet ptag */ uint32_t pack_size=0; uint8_t *pack; /* char _tx_buf[4096]; void* buf = (void*)_tx_buf; memset(buf,0,4096); // UINTN pack_size = sizeof(struct dhcp_msg); UINTN pack_size=0; // EFI_PXE_BASE_CODE_DHCPV4_PACKET *dhcp_req = (EFI_PXE_BASE_CODE_DHCPV4_PACKET*)malloc(sizeof(EFI_PXE_BASE_CODE_DHCPV4_PACKET)); struct dhcp_msg *dhcp_req = (struct dhcp_msg*)(buf +(m->MediaHeaderSize)+ (sizeof(struct iphdr) + sizeof(struct udphdr))); uint64_t req_id = (uint64_t)rand(); int i=0; memset((void*)dhcp_req,0,pack_size); dhcp_req->op = 1; // request dhcp_req->htype = m->IfType; dhcp_req->hlen = m->HwAddressSize; dhcp_req->hops = 0; dhcp_req->xid = req_id; dhcp_req->secs = 0; dhcp_req->flags = 0x8000; for(i=0; i< m->HwAddressSize; i++) { dhcp_req->chaddr[i] = m->CurrentAddress.Addr[i]; } dhcp_req->cookie = 0x63825363; dhcp_req->options[0] = 53; dhcp_req->options[1] = 1; dhcp_req->options[2] = 1; kprintf("k_network: configure_net_dhcp() ID is %#llx\n",req_id); struct iphdr *iph = (struct iphdr *)(buf+(m->MediaHeaderSize)); struct udphdr *udph = (struct udphdr *) (buf + sizeof (struct iphdr)+(m->MediaHeaderSize)); memset((void*)iph,0,sizeof(struct iphdr)); // memset((void*)udph,0,sizeof(struct udph)); iph->ihl = 5; iph->version = 4; iph->tot_len = htons(sizeof(struct iphdr)); iph->protocol = IPPROTO_UDP; iph->ttl = 255; iph->saddr = INADDR_ANY; iph->daddr = INADDR_ANY; // iph->check = csum ((unsigned short *) buf, iph->tot_len); // udph->uh_ulen = sizeof(struct udphdr) + pack_size; // udph->uh_sum = csum((unsigned short*)(buf - sizeof(struct udphdr)),pack_size+sizeof(struct udphdr)); // udph->uh_sport = 68; // udph->uh_dport = 68;*/ EFI_MAC_ADDRESS anywhere; for(i=0; i< m->HwAddressSize; i++) { anywhere.Addr[i] = 255; } kprintf("k_network:configure_net_dhcp() - Transmitting request\n"); UINT16 ether_type = 0x800; // EFI_STATUS send_s = simple_net->Transmit(simple_net,0,tx_size,buf,NULL,&anywhere,ðer_type); EFI_STATUS send_s = simple_net->Transmit(simple_net,m->MediaHeaderSize,pack_size,(void*)pack,NULL,&anywhere,ðer_type); kprintf("k_network:configure_net_dhcp() - Waiting for transmission\n"); void* tx_buf=NULL; while(tx_buf==NULL && (send_s==0)) { tx_buf=NULL; send_s = simple_net->GetStatus(simple_net,0,&tx_buf); if(send_s != 0) kprintf("!\n"); } kprintf("k_network:configure_net_dhcp() - Transmitted, tx_buf at %#llx \n",tx_buf); }
static int dhcp_discovery(libnet_t *ln, uint8_t *enet_src, uint32_t dhcp_xid) { uint32_t options_len = 0; uint32_t options_ofs = 0; libnet_ptag_t eth; libnet_ptag_t ip; libnet_ptag_t udp; libnet_ptag_t dhcp; uint8_t enet_dst[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; uint8_t options_req[] = { LIBNET_DHCP_SUBNETMASK, LIBNET_DHCP_BROADCASTADDR, LIBNET_DHCP_ROUTER, LIBNET_DHCP_DOMAINNAME, LIBNET_DHCP_DNS, LIBNET_DHCP_HOSTNAME, LIBNET_DHCP_TIMEOFFSET }; /* build DHCP Discovery options packet */ options_len = 3; options = realloc(options, options_len); options[options_ofs++] = LIBNET_DHCP_MESSAGETYPE; options[options_ofs++] = 1; options[options_ofs++] = LIBNET_DHCP_MSGDISCOVER; /* we are going to request some parameters */ options_len += sizeof(options_req) + 2; options = realloc(options, options_len); options[options_ofs++] = LIBNET_DHCP_PARAMREQUEST; options[options_ofs++] = sizeof(options_req); memcpy(options + options_ofs, options_req, sizeof(options_req)); options_ofs += sizeof(options_req); /* gpxe client support */ if (gpxe) { options_len += 6; options = realloc(options, options_len); options[options_ofs++] = 0x4d; options[options_ofs++] = 0x4; options[options_ofs++] = 'g'; options[options_ofs++] = 'P'; options[options_ofs++] = 'X'; options[options_ofs++] = 'E'; } /* end our options packet */ options_len += 1; options = realloc(options, options_len); options[options_ofs++] = LIBNET_DHCP_END; if (options_len + LIBNET_DHCPV4_H < LIBNET_BOOTP_MIN_LEN) { options_len = LIBNET_BOOTP_MIN_LEN - LIBNET_DHCPV4_H; options = realloc(options, options_len); memset(options + options_ofs, 0, options_len - options_ofs); } dhcp = libnet_build_dhcpv4(LIBNET_DHCP_REQUEST, 1, 6, 0, dhcp_xid, 0, 0x8000, 0, 0, 0, 0, enet_src, NULL, NULL, options, options_len, ln, 0); udp = libnet_build_udp(68, 67, LIBNET_UDP_H + LIBNET_DHCPV4_H + options_len, 0, NULL, 0, ln, 0); ip = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_DHCPV4_H + options_len, 0x10, 0, 0, 16, IPPROTO_UDP, 0, 0, inet_addr("255.255.255.255"), NULL, 0, ln, 0); eth = libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, ln, 0); if (libnet_write(ln) == -1) { fprintf(stderr, "libnet_write: %s\n", strerror(errno)); exit(EXIT_FAILURE); } free(options); return 0; }