📄 dhcp-packet-build.c
字号:
ip_set_ttl(net->ip_p, IP_TTL_MAX); ip_set_proto(net->ip_p, protocol); /* Do checksum later. */ ip_set_src_addr(net->ip_p, source_addr); ip_set_dst_addr(net->ip_p, dest_addr); return;}static void build_ip_broadcast(rawnet_t *net, uint16_t ip_len, uint8_t protocol, ip_addr_t source_addr){ build_ip(net, ip_len, protocol, source_addr, ip_addr_broadcast); return;}/* * * * * * * * * * * UDP routines. * * * * * * * * * * */static void build_udp(rawnet_t *net, uint16_t udp_len){ udp_set_src_port(net->udp_p, net->src_port); udp_set_dst_port(net->udp_p, net->dst_port); udp_set_len(net->udp_p, udp_len); /* libdnet sets this properly for us. */ udp_set_cksum(net->udp_p, 0); return;}/* * * * * * * * * * * DHCP routines. * * * * * * * * * * */static void build_dhcp_proc(rawnet_t *net, uint32_t xid, uint16_t secs, eth_addr_t client_hw_addr, uint32_t ciaddr, uint32_t yiaddr, uint32_t siaddr, uint32_t giaddr, list_t *options, unsigned char broadcast, unsigned char bootp_type){ dhcp_set_op(net->dhcp_p, bootp_type); dhcp_set_htype(net->dhcp_p, rawnet_get_datalink_type(net)); dhcp_set_hlen(net->dhcp_p, ETH_ADDR_LEN); dhcp_set_hops(net->dhcp_p, 0); dhcp_set_xid(net->dhcp_p, xid); dhcp_set_secs(net->dhcp_p, secs); if(broadcast) dhcp_set_flag_broadcast(net->dhcp_p); else dhcp_unset_flag_broadcast(net->dhcp_p); dhcp_set_ciaddr(net->dhcp_p, ciaddr); dhcp_set_yiaddr(net->dhcp_p, yiaddr); dhcp_set_siaddr(net->dhcp_p, siaddr); dhcp_set_giaddr(net->dhcp_p, giaddr); dhcp_clear_chaddr(net->dhcp_p); dhcp_set_chaddr(net->dhcp_p, client_hw_addr.data, ETH_ADDR_LEN); dhcp_clear_sname(net->dhcp_p); dhcp_clear_filename(net->dhcp_p); dhcp_set_magic_cookie(net->dhcp_p); dhcp_set_options(net->dhcp_p, options); return;}static void build_dhcp(rawnet_t *net, uint32_t xid, time_t secs, uint32_t ciaddr, uint32_t yiaddr, uint32_t siaddr, uint32_t giaddr, ip_addr_t server_ip_addr, eth_addr_t server_hw_addr, unsigned char broadcast, list_t *options, unsigned char bootp_type){ uint16_t ip_len, udp_len; int total_len; dhcp_purge(net->dhcp_p); /* clear up old options. */ /* Calculate the total length of the packet * including IP header but not datalink header. * This goes into ip_len */ ip_len = IP_HDR_LEN + /* IP Header length. */ UDP_HDR_LEN + /* UDP Header length. */ DHCP_FIXEDHDR_LEN + /* DHCP fixed header. */ 4 + /* magic cookie length. */ dhcp_get_options_len(options); /* options length. */ udp_len = ip_len - IP_HDR_LEN; total_len = ip_len + ETH_HDR_LEN; /* It is possible that we exceeded MTU. * * On smaller MTUs (once we configure it and not * hardcode it) it may be possible. So keep * this check in. XXX -- fixme: check for * UDP size, and overload DHCP when it * goes over that size. * */ if(total_len > net->mtu) FATAL_MESSAGE ("Outgoing DHCP packet too large. I'm currently not implementing this properly so I'll have to exit!"); if(broadcast) build_eth_broadcast(net, net->chw_addr, ETH_TYPE_IP); else build_eth(net, net->chw_addr, server_hw_addr, ETH_TYPE_IP); if(broadcast) build_ip_broadcast(net, ip_len, IP_PROTO_UDP, 0); else build_ip(net, ip_len, IP_PROTO_UDP, net->cip_addr, server_ip_addr); build_udp(net, udp_len); build_dhcp_proc(net, xid, secs, net->chw_addr, ciaddr, yiaddr, siaddr, giaddr, options, broadcast, bootp_type); /* Write packet. */ net->type = RAWNET_DHCP; net->packet_len = total_len; write_packet(net); return;}/* Create a dhcp discover message. */void build_dhcp_discover(rawnet_t *net, uint32_t xid, time_t secs, list_t *options){ build_dhcp(net, xid, secs, 0, 0, 0, 0, 0, eth_null, 1, options, DHCP_BOOTP_REQUEST);}/* Create dhcp request message: unicast */void build_dhcp_request_unicast(rawnet_t *net, uint32_t xid, time_t secs, list_t *options, ip_addr_t cip_addr, ip_addr_t sip_addr, ip_addr_t gip_addr, eth_addr_t shw_addr){ build_dhcp(net, xid, secs, cip_addr, 0, sip_addr, gip_addr, sip_addr, shw_addr, 0, options, DHCP_BOOTP_REQUEST);}/* Create dhcp request message: broadcast */void build_dhcp_request_broadcast(rawnet_t *net, uint32_t xid, time_t secs, ip_addr_t cip_addr, ip_addr_t sip_addr, list_t *options){ build_dhcp(net, xid, secs, cip_addr, 0, sip_addr, 0, ip_addr_broadcast, eth_broadcast, 0, options, DHCP_BOOTP_REQUEST);}/* Create dhcp release message. */void build_dhcp_release(rawnet_t *net, uint32_t xid, list_t *options, ip_addr_t cip_addr, ip_addr_t sip_addr, eth_addr_t shw_addr){ build_dhcp(net, xid, 0, cip_addr, 0, sip_addr, 0, sip_addr, shw_addr, 0, options, DHCP_BOOTP_REQUEST);}void build_dhcp_decline(rawnet_t *net, uint32_t xid, time_t secs, list_t *options){ build_dhcp(net, xid, secs, 0, 0, 0, 0, ip_addr_broadcast, eth_broadcast, 0, options, DHCP_BOOTP_REQUEST);}/* * * * * * * * * * * ICMP routines. * * * * * * * * * * *//* Create icmp packet: procify this so we can use it for all other icmp building. */static void build_icmp_header_proc(rawnet_t *net, uint8_t icmp_type, uint8_t icmp_code){ icmp_set_type(net->icmp_p, icmp_type); icmp_set_code(net->icmp_p, icmp_code); icmp_clear_cksum(net->icmp_p); return;}/* Create icmp mask reply/request packet: procify this to act as * a subroutine for the icmp mask interface routines. */static void build_icmp_mask_proc(rawnet_t *net, uint8_t icmp_type, uint32_t icmp_id, uint32_t icmp_seq, uint32_t mask){ build_icmp_header_proc(net, icmp_type, 0); icmp_mask_set_seq(net->icmp_p, icmp_id); icmp_mask_set_seq(net->icmp_p, icmp_seq); icmp_mask_set_mask(net->icmp_p, mask); return;}/* build icmp mask request packet. */void build_icmp_mask_request(rawnet_t *net, uint32_t id, uint32_t seq){ int ip_len = ICMP_HDR_LEN + 12 + IP_HDR_LEN; /* 12 bytes for the mask request. */ build_eth_broadcast(net, net->chw_addr, ETH_TYPE_IP); build_ip_broadcast(net, ip_len, IP_PROTO_ICMP, 0); build_icmp_mask_proc(net, ICMP_MASK, id, seq, 0); net->type = RAWNET_ICMP; net->packet_len = ETH_HDR_LEN + ip_len; write_packet(net);}/* build icmp mask reply packet. */void build_icmp_mask_reply(rawnet_t *net, uint32_t id, uint32_t seq, uint32_t subnet_mask){ int ip_len = IP_HDR_LEN + ICMP_HDR_LEN + 12; /* 12 bytes for the mask reply. */ build_eth_broadcast(net, net->chw_addr, ETH_TYPE_IP); build_ip_broadcast(net, ip_len, IP_PROTO_ICMP, 0); build_icmp_mask_proc(net, ICMP_MASK, id, seq, subnet_mask); net->type = RAWNET_ICMP; net->packet_len = ETH_HDR_LEN + ip_len; write_packet(net);}static void build_icmp_echo_request_proc(rawnet_t *net, uint16_t id, uint16_t seq){ icmp_echo_set_id(net->icmp_p, id); icmp_echo_set_seq(net->icmp_p, seq); return;}/* build icmp echo request. */void build_icmp_echo_request(rawnet_t *net, ip_addr_t source_addr, ip_addr_t dest_addr, eth_addr_t source_mac, eth_addr_t dest_mac, uint16_t id, uint16_t seq){ int ip_len = IP_HDR_LEN + ICMP_HDR_LEN + 4; /* 4 bytes for vanilla icmp echo request packet. */ build_eth(net, source_mac, dest_mac, ETH_TYPE_IP); build_ip(net, ip_len, IP_PROTO_ICMP, source_addr, dest_addr); build_icmp_header_proc(net, ICMP_ECHO, 0); build_icmp_echo_request_proc(net, id, seq); net->type = RAWNET_ICMP; net->packet_len = ETH_HDR_LEN + ip_len; write_packet(net);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -