DHCP由BOOTP协议发展而来,而后者基于UDP、IP协议,这使得使用socket发送DHCP报文成为可能。本文示例构造了DHCP Discovery报文并调用socket接口发送,值得注意的是,由于DHCP要求发送者ip是0.0.0.0,所以必须使用raw socket进行发送(本文没有示例),更进一步的,用户层代码Linux、macOS系统可以使用libpcap,Windows系统可以使用Windivert、Winpcap/Npcap进行发送。
builder<dhcp_hdr, char[64]> packet;
auto dhcp = packet.get<dhcp_hdr>();
dopt opts[] = {
packet.get<dhcp_opt>(3),
packet.get<dhcp_opt>(9),
packet.get<dhcp_opt>(6),
packet.get<dhcp_opt>(8), // host name
packet.get<dhcp_opt>(10),
packet.get<dhcp_opt>(15)
};
auto optend = packet.get(1);
auto padcalc = calculator<>();
auto padding = packet.get( BOOTP_MIN_LEN - packet.length());
dhcp->opcode = DHCP_REQUEST;
dhcp->htype = ARPHRD_ETHER;
dhcp->hlen = ETHER_ADDR_LEN;
dhcp->hops = 0;
dhcp->xid = 0; // TODO: Transaction ID
dhcp->secs = 0;
dhcp->flags = 0; // UNICAST
dhcp->cip = IP_THIS_ADDR;
dhcp->yip = IP_THIS_ADDR;
dhcp->sip = IP_THIS_ADDR;
dhcp->gip = IP_THIS_ADDR;
memcpy(dhcp->chaddr, ETHER_SELF_MAC, ETHER_ADDR_LEN);
memset(&dhcp->chaddr[ETHER_ADDR_LEN], 0, sizeof(dhcp_hdr::chaddr) - ETHER_ADDR_LEN);
memset(dhcp->sname, 0, sizeof(dhcp_hdr::sname));
memset(dhcp->file, 0, sizeof(dhcp_hdr::file));
dhcp->magic = BOOTP_RMAGIC;
opts[0]->kind = DHCP_MESSAGETYPE;
opts[0]->len = 1;
opts[0]->val[0] = DHCP_MSGDISCOVER;
opts[1]->kind = DHCP_CLIENTID;
opts[1]->len = 7;
opts[1]->val[0] = ARPHRD_ETHER; // hardware address
memcpy(&opts[1]->val[1], ETHER_SELF_MAC, ETHER_ADDR_LEN);
opts[2]->kind = DHCP_DISCOVERADDR;
opts[2]->len = IPV4_ADDR_LEN;
memcpy(opts[2]->val, "\x00\x00\x00\x00", opts[2]->len);
opts[3]->kind = DHCP_HOSTNAME;
opts[3]->len = sizeof("Huawei") - 1;
memcpy(opts[3]->val, "Huawei", opts[3]->len);
opts[4]->kind = DHCP_CLASSSID;
opts[4]->len = sizeof("MSFT 5.0") - 1;
memcpy(opts[4]->val, "MSFT 5.0", opts[4]->len);
opts[5]->kind = DHCP_PARAMREQUEST;
opts[5]->len = 13;
opts[5]->val[0] = DHCP_SUBNETMASK;
opts[5]->val[1] = DHCP_ROUTER;
opts[5]->val[2] = DHCP_DNS;
opts[5]->val[3] = DHCP_DOMAINNAME;
opts[5]->val[4] = DHCP_DOROUTEDISC;
opts[5]->val[5] = DHCP_STATICROUTE;
opts[5]->val[6] = DHCP_VENDSPECIFIC;
opts[5]->val[7] = DHCP_NBNS;
opts[5]->val[8] = DHCP_NBTCPIP;
opts[5]->val[9] = DHCP_NBTCPSCOPE;
opts[5]->val[10] = DHCP_CLSTATICROUTE;
opts[5]->val[11] = DHCP_MSCLSTATICROUTE;
opts[5]->val[12] = DHCP_PRIAUTODISCOVERY;
optend[0] = DHCP_END;
ManagedObject<Sockets> sock = new Sockets(IPPROTO_UDP, SOCK_DGRAM);
sock->SetOption(SO_BROADCAST, 1);
sock->SendTo(packet.first<void>(), packet.length<int>(), IP_BCAST_ADDR, DHCP_BOOTPS_RPORT);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)