This is a low-level network debugging utility that utilizes raw packet i/o to construct and deconstruct tcp, udp, ipv4, arp, and icmp packets over ethernet.
ip.h
00001 #ifndef IP_H 00002 #define IP_H 00003 00004 #include "net.h" 00005 00006 /** 00007 \file ip.h 00008 \brief IP Packet header 00009 00010 This file contains the memory map and associated functions for IP packet header 00011 creation and deconstruction. 00012 */ 00013 00014 #define ETHERTYPE_IPV4 0x0800 00015 #define ETHERTYPE_IPV6 0x86DD 00016 00017 /// IP Address memory map 00018 typedef struct { 00019 unsigned char octet[4]; ///< Individual address octets 00020 } IP_Address; 00021 00022 /// IP Packet memory map 00023 typedef struct { 00024 /// 4 bits that contain the version, that specifies if it's an IPv4 or IPv6 packet, 00025 unsigned version:4; // Only 0x4 supported 00026 /// 4 bits that contain the Internet Header Length which is the length of the header in multiples of 4 bytes (eg. 5 means 20 bytes). 00027 unsigned header_bytes_div4:4; 00028 /// 8 bits that contain the Type of Service, also referred to as Quality of Service (QoS), which describes what priority the packet should have, 00029 unsigned tos:8; 00030 /// 16 bits that contain the total length of the IP packet (datagram) in bytes, 00031 u16 packet_bytes; 00032 /// 16 bits that contain an identification tag to help reconstruct the packet from several fragments, 00033 u16 fragment_id; 00034 /// 3 bits that contain a zero, a flag that says whether the packet is allowed to be fragmented or not (DF: Don't fragment), and a flag to state whether more fragments of a packet follow (MF: More Fragments) 00035 unsigned unused_0:1; 00036 unsigned dont_fragment:1; 00037 unsigned more_follow:1; 00038 /// 13 bits that contain the fragment offset, a field to identify position of fragment within original packet 00039 unsigned fragment_offset:13; ///< This and the ones above may not work properly due to endianness 00040 /// 8 bits that contain the Time to live (TTL) which is the number of hops (router, computer or device along a network) the packet is allowed to pass before it dies (for example, a packet with a TTL of 16 will be allowed to go across 16 routers to get to its destination before it is discarded), 00041 unsigned ttl:8; 00042 /// 8 bits that contain the protocol (TCP, UDP, ICMP, etc...) 00043 /// 0x01 ICMP 00044 /// 0x06 TCP 00045 /// 0x11 UDP 00046 unsigned protocol:8; 00047 /// 16 bits that contain the Header Checksum, a number used in error detection, 00048 u16 header_checksum; 00049 /// 32 bits that contain the source IP address, 00050 IP_Address source; 00051 /// 32 bits that contain the destination address. 00052 IP_Address destination; 00053 /// Zero-length field for memory mapping the packet data 00054 unsigned char data[]; 00055 } IP_PacketHeader; 00056 00057 /// Convert from wire to host or host to wire endianness 00058 inline void fix_endian_ip(IP_PacketHeader *packet) 00059 { 00060 packet->version ^= packet->header_bytes_div4; 00061 packet->header_bytes_div4 ^= packet->version; 00062 packet->version ^= packet->header_bytes_div4; 00063 fix_endian_u16(&packet->packet_bytes); 00064 fix_endian_u16(&packet->fragment_id); 00065 // Don't fix checksums; they are done bitwise 00066 } 00067 00068 /// Get a constant string of the given IP protocol (e.g. "ICMP", "TCP", "UDP") if known 00069 inline const char *ipproto2name(u8 proto) 00070 { 00071 switch (proto) 00072 { 00073 case 0x01: return "ICMP"; 00074 case 0x02: return "IGMP"; 00075 case 0x06: return "TCP"; 00076 case 0x11: return "UDP"; 00077 } 00078 return "<UNKNOWN>"; 00079 } 00080 00081 /// Print the IP packet 00082 inline void print_ip(IP_PacketHeader *packet) 00083 { 00084 main_log.printf("IPv%d Packet:", packet->version); 00085 if (packet->version != 4) 00086 { 00087 main_log.printf("Not an IPv4 packet (skipping)"); 00088 return; 00089 } 00090 00091 u8 *dst = packet->destination.octet; 00092 u8 *src = packet->source.octet; 00093 main_log.printf(" Source: IP - %03d.%03d.%03d.%03d", src[0], src[1], src[2], src[3]); 00094 main_log.printf(" Dest: IP - %03d.%03d.%03d.%03d", dst[0], dst[1], dst[2], dst[3]); 00095 main_log.printf(" TTL: %d", packet->ttl); 00096 main_log.printf(" Protocol: 0x%02X (%s)", packet->protocol, ipproto2name(packet->protocol)); 00097 main_log.printf(" ToS: 0x%02X", packet->tos); 00098 main_log.printf(" Header: %d bytes", packet->header_bytes_div4*4); 00099 main_log.printf(" Packet: %d bytes", packet->packet_bytes); 00100 main_log.printf(" Fragment: 0x%04X DF=%d MF=%d OFFSET=0x04X", packet->fragment_id, packet->dont_fragment, packet->more_follow, packet->fragment_offset); 00101 main_log.printf(" Checksum: 0x%04X", packet->header_checksum); 00102 } 00103 00104 /// Parse the string (in decimal triple-dot notation) into the IP address structure 00105 inline void str2ipaddr(const char *ip, IP_Address *addr) 00106 { 00107 static short a,b,c,d; 00108 sscanf(ip, "%3hd.%3hd.%3hd.%3hd", &a, &b, &c, &d); 00109 addr->octet[0] = a; 00110 addr->octet[1] = b; 00111 addr->octet[2] = c; 00112 addr->octet[3] = d; 00113 } 00114 00115 #endif
Generated on Tue Jul 12 2022 11:59:40 by 1.7.2