Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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