📄 dhcp-packet-build.c
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-packet-build.c,v 1.9 2003/06/26 23:56:42 actmodern Exp $ * * Copyright 2002 Thamer Alharbash <tmh@whitefang.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Packet building routines: * Utility routines wrapped around the packet objects. * */#define MODULE_NAME "dhcp-packet-build"#include "dhcp-local.h"#include "dhcp-limits.h"#include "dhcp-libutil.h"#include "dhcp-librawnet.h"/* constants we need. */static const eth_addr_t eth_null = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };static const eth_addr_t eth_broadcast = { {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} };static const uint32_t ip_addr_broadcast = 0xffffffff;/* * * * * * * * * * * * * * * * Packet writing routines. * * * * * * * * * * * * * * * */static void write_packet_dhcp(rawnet_t *net){ char *packet_ptr; /* Dump packet images for DHCP. */ packet_ptr = net->packet_data; memset(packet_ptr, 0, net->mtu); /* fixme: fix the default mtu issue! */ eth_write_packet_image(net->ether_p, packet_ptr); packet_ptr += ETH_HDR_LEN; ip_write_packet_image(net->ip_p, packet_ptr); packet_ptr += (ip_get_hl(net->ip_p)); udp_write_packet_image(net->udp_p, packet_ptr); packet_ptr += UDP_HDR_LEN; dhcp_write_packet_image(net->dhcp_p, packet_ptr); /* Run the IP checksum routine. */ ip_checksum((net->packet_data + ETH_HDR_LEN), (net->packet_len - ETH_HDR_LEN)); return;}static void write_packet_arp(rawnet_t *net){ char *packet_ptr; /* Dump packet images for ARP/UNARP. */ packet_ptr = net->packet_data; memset(packet_ptr, 0, net->mtu); /* fixme: fix the default mtu issue! */ eth_write_packet_image(net->ether_p, packet_ptr); packet_ptr += ETH_HDR_LEN; arp_write_packet_image(net->arp_p, packet_ptr); return;}static void write_packet_icmp(rawnet_t *net){ unsigned char *packet_ptr; /* Dump packet images for ICMP. */ packet_ptr = net->packet_data; memset(packet_ptr, 0, net->mtu); /* fixme: fix the default mtu issue! */ eth_write_packet_image(net->ether_p, packet_ptr); packet_ptr += ETH_HDR_LEN; ip_write_packet_image(net->ip_p, packet_ptr); packet_ptr += (ip_get_hl(net->ip_p)); icmp_write_packet_image(net->icmp_p, packet_ptr); ip_checksum((net->packet_data + ETH_HDR_LEN), (net->packet_len - ETH_HDR_LEN)); return;}static void write_packet(rawnet_t *net){ switch (net->type) { case RAWNET_DHCP: write_packet_dhcp(net); break; case RAWNET_ARP: write_packet_arp(net); break; case RAWNET_ICMP: write_packet_icmp(net); break; default: FATAL_MESSAGE ("warning: invalid packet type passed to write_packet() -- this is a bug report it please."); break; } return;}/* * * * * * * * * * * * * Ethernet Routines. * * * * * * * * * * * * */static void build_eth_proc(rawnet_t *net, eth_addr_t source_hw_addr, eth_addr_t dest_hw_addr, uint16_t type){ eth_set_dst_addr(net->ether_p, dest_hw_addr); eth_set_src_addr(net->ether_p, source_hw_addr); eth_set_type(net->ether_p, type); return;}/* build ethernet header with broadcast destination address. */static void build_eth_broadcast(rawnet_t *net, eth_addr_t source_hw_addr, uint16_t type){ build_eth_proc(net, source_hw_addr, eth_broadcast, type); return;}static void build_eth(rawnet_t *net, eth_addr_t source_hw_addr, eth_addr_t dest_hw_addr, uint16_t type){ build_eth_proc(net, source_hw_addr, dest_hw_addr, type); return;}/* * * * * * * * * * * * * ARP/UNARP Routines. * * * * * * * * * * * * *//* Build ARP packet: write out all the members. */static void build_arp(rawnet_t *net, uint16_t opcode, eth_addr_t sender_hw_addr, uint32_t sender_ip_addr, eth_addr_t target_hw_addr, uint32_t target_ip_addr, uint8_t hardware_len){ /* for unarp it's 0 */ arp_set_hardware_type(net->arp_p, ARP_HRD_ETH); arp_set_protocol_type(net->arp_p, ARP_PRO_IP); arp_set_hardware_len(net->arp_p, hardware_len); arp_set_protocol_len(net->arp_p, IP_ADDR_LEN); arp_set_op(net->arp_p, opcode); arp_set_sender_hardware_address(net->arp_p, sender_hw_addr); arp_set_sender_protocol_address(net->arp_p, sender_ip_addr); arp_set_target_hardware_address(net->arp_p, target_hw_addr); arp_set_target_protocol_address(net->arp_p, target_ip_addr); return;}/* Build ARP Proc: Do all the work for an arp packet. */static void build_arp_proc(rawnet_t *net, uint16_t opcode, eth_addr_t sender_hw_addr, uint32_t sender_ip_addr, eth_addr_t target_hw_addr, uint32_t target_ip_addr){ build_eth_broadcast(net, sender_hw_addr, ETH_TYPE_ARP); build_arp(net, opcode, sender_hw_addr, sender_ip_addr, target_hw_addr, target_ip_addr, ETH_ADDR_LEN); net->type = RAWNET_ARP; net->packet_len = ETH_HDR_LEN + ARP_ETHIP_LEN + ARP_HDR_LEN; write_packet(net); return;}/* Interface routines to ARP/UNARP building. *//* Build ARP reply. */void build_arp_reply(rawnet_t *net, uint32_t source_addr, uint32_t dest_addr, eth_addr_t source_hw_addr, eth_addr_t dest_hw_addr){ build_arp_proc(net, ARP_OP_REPLY, source_hw_addr, source_addr, dest_hw_addr, dest_addr); return;}/* Build ARP request. */void build_arp_request(rawnet_t *net, uint32_t source_addr, uint32_t dest_addr, eth_addr_t source_hw_addr){ build_arp_proc(net, ARP_OP_REQUEST, source_hw_addr, source_addr, eth_broadcast, dest_addr); return;}/* Build ARP reply with broadcast destination hardware address. */void build_arp_reply_broadcast(rawnet_t *net, uint32_t source_addr, eth_addr_t source_hw_addr){ build_arp_reply(net, source_addr, ip_addr_broadcast, source_hw_addr, eth_broadcast); return;}/* only one way to build unarp, so don't procify it. */void build_unarp(rawnet_t *net, uint32_t source_addr, eth_addr_t source_hw_addr){ build_eth_broadcast(net, source_hw_addr, ETH_TYPE_ARP); build_arp(net, ARP_OP_REPLY, source_hw_addr, 0, eth_broadcast, ip_addr_broadcast, ETH_ADDR_LEN); net->type = RAWNET_ARP; net->packet_len = ETH_HDR_LEN + ARP_ETHIP_LEN + ARP_HDR_LEN; write_packet(net); return;}/* * * * * * * * * * * * * * * * * Internet Protocol routines. * * * * * * * * * * * * * * * * */static void build_ip(rawnet_t *net, uint16_t ip_len, uint8_t protocol, ip_addr_t source_addr, ip_addr_t dest_addr){ ip_set_hl(net->ip_p, IP_HDR_LEN); ip_set_tos(net->ip_p, IP_TOS_DEFAULT); ip_set_len(net->ip_p, ip_len); ip_set_id(net->ip_p, IP_DF); ip_set_off(net->ip_p, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -