def _build_dns_question(self): """Build DNS question""" host = self._host.decode("utf-8") host = host.split(".") # write out each section of host for i, _ in enumerate(host): # append the sz of the section self._pkt_buf.append(len(host[i])) # append the section data self._pkt_buf += host[i] # end of the name self._pkt_buf.append(0x00) # Type A record self._pkt_buf.append(htons(TYPE_A) & 0xFF) self._pkt_buf.append(htons(TYPE_A) >> 8) # Class IN self._pkt_buf.append(htons(CLASS_IN) & 0xFF) self._pkt_buf.append(htons(CLASS_IN) >> 8)
def send_dhcp_message(self, state, time_elapsed): """Assemble and send a DHCP message packet to a socket. :param int state: DHCP Message state. :param float time_elapsed: Number of seconds elapsed since renewal. """ # OP _BUFF[0] = DHCP_BOOT_REQUEST # HTYPE _BUFF[1] = DHCP_HTYPE10MB # HLEN _BUFF[2] = DHCP_HLENETHERNET # HOPS _BUFF[3] = DHCP_HOPS # Transaction ID (xid) self._initial_xid = htonl(self._transaction_id) self._initial_xid = self._initial_xid.to_bytes(4, 'l') _BUFF[4:7] = self._initial_xid # seconds elapsed _BUFF[8] = ((int(time_elapsed) & 0xff00) >> 8) _BUFF[9] = (int(time_elapsed) & 0x00ff) # flags flags = htons(0x8000) flags = flags.to_bytes(2, 'b') _BUFF[10] = flags[1] _BUFF[11] = flags[0] # NOTE: Skipping cidaddr/yiaddr/siaddr/giaddr # as they're already set to 0.0.0.0 # chaddr _BUFF[28:34] = self._mac_address # NOTE: 192 octets of 0's, BOOTP legacy # Magic Cookie _BUFF[236] = ((MAGIC_COOKIE >> 24)& 0xFF) _BUFF[237] = ((MAGIC_COOKIE >> 16)& 0xFF) _BUFF[238] = ((MAGIC_COOKIE >> 8)& 0xFF) _BUFF[239] = (MAGIC_COOKIE& 0xFF) # Option - DHCP Message Type _BUFF[240] = 53 _BUFF[241] = 0x01 _BUFF[242] = state # Option - Client Identifier _BUFF[243] = 61 # Length _BUFF[244] = 0x07 # HW Type - ETH _BUFF[245] = 0x01 # Client MAC Address for mac in range(0, len(self._mac_address)): _BUFF[246+mac] = self._mac_address[mac] # Option - Host Name _BUFF[252] = 12 _BUFF[253] = len(b"Wiznet") + 6 _BUFF[254:260] = b"WIZnet" for mac in range(0, 5): _BUFF[260+mac] = self._mac_address[mac] if state == DHCP_REQUEST: # Set the parsed local IP addr _BUFF[266] = 50 _BUFF[267] = 0x04 _BUFF[268:272] = self.local_ip # Set the parsed dhcp server ip addr _BUFF[272] = 54 _BUFF[273] = 0x04 _BUFF[274:278] = self.dhcp_server_ip _BUFF[278] = 55 _BUFF[279] = 0x06 # subnet mask _BUFF[280] = 1 # routers on subnet _BUFF[281] = 3 # DNS _BUFF[282] = 6 # domain name _BUFF[283] = 15 # renewal (T1) value _BUFF[284] = 58 # rebinding (T2) value _BUFF[285] = 59 _BUFF[286] = 255 # Send DHCP packet self._sock.send(_BUFF)
def send_dhcp_message(self, state, time_elapsed, renew=False): """Assemble and send a DHCP message packet to a socket. :param int state: DHCP Message state. :param float time_elapsed: Number of seconds elapsed since DHCP process started :param bool renew: Set True for renew and rebind """ _BUFF[:] = b"\x00" * len(_BUFF) # OP _BUFF[0] = DHCP_BOOT_REQUEST # HTYPE _BUFF[1] = DHCP_HTYPE10MB # HLEN _BUFF[2] = DHCP_HLENETHERNET # HOPS _BUFF[3] = DHCP_HOPS # Transaction ID (xid) self._initial_xid = htonl(self._transaction_id) self._initial_xid = self._initial_xid.to_bytes(4, "l") _BUFF[4:7] = self._initial_xid # seconds elapsed _BUFF[8] = (int(time_elapsed) & 0xFF00) >> 8 _BUFF[9] = int(time_elapsed) & 0x00FF # flags flags = htons(0x8000) flags = flags.to_bytes(2, "b") _BUFF[10] = flags[1] _BUFF[11] = flags[0] # NOTE: Skipping ciaddr/yiaddr/siaddr/giaddr # as they're already set to 0.0.0.0 # Except when renewing, then fill in ciaddr if renew: _BUFF[12:15] = bytes(self.local_ip) # chaddr _BUFF[28:34] = self._mac_address # NOTE: 192 octets of 0's, BOOTP legacy # Magic Cookie _BUFF[236] = (MAGIC_COOKIE >> 24) & 0xFF _BUFF[237] = (MAGIC_COOKIE >> 16) & 0xFF _BUFF[238] = (MAGIC_COOKIE >> 8) & 0xFF _BUFF[239] = MAGIC_COOKIE & 0xFF # Option - DHCP Message Type _BUFF[240] = 53 _BUFF[241] = 0x01 _BUFF[242] = state # Option - Client Identifier _BUFF[243] = 61 # Length _BUFF[244] = 0x07 # HW Type - ETH _BUFF[245] = 0x01 # Client MAC Address for mac, val in enumerate(self._mac_address): _BUFF[246 + mac] = val # Option - Host Name _BUFF[252] = 12 hostname_len = len(self._hostname) after_hostname = 254 + hostname_len _BUFF[253] = hostname_len _BUFF[254:after_hostname] = self._hostname if state == DHCP_REQUEST and not renew: # Set the parsed local IP addr _BUFF[after_hostname] = 50 _BUFF[after_hostname + 1] = 0x04 _BUFF[after_hostname + 2:after_hostname + 6] = bytes(self.local_ip) # Set the parsed dhcp server ip addr _BUFF[after_hostname + 6] = 54 _BUFF[after_hostname + 7] = 0x04 _BUFF[after_hostname + 8:after_hostname + 12] = bytes( self.dhcp_server_ip) _BUFF[after_hostname + 12] = 55 _BUFF[after_hostname + 13] = 0x06 # subnet mask _BUFF[after_hostname + 14] = 1 # routers on subnet _BUFF[after_hostname + 15] = 3 # DNS _BUFF[after_hostname + 16] = 6 # domain name _BUFF[after_hostname + 17] = 15 # renewal (T1) value _BUFF[after_hostname + 18] = 58 # rebinding (T2) value _BUFF[after_hostname + 19] = 59 _BUFF[after_hostname + 20] = 255 # Send DHCP packet self._sock.send(_BUFF)