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.
net/ip.h
- Committer:
- etherealflaim
- Date:
- 2010-10-12
- Revision:
- 8:1c1f6ce348c6
- Parent:
- 6:66c4cd9073aa
File content as of revision 8:1c1f6ce348c6:
#ifndef IP_H #define IP_H #include "net.h" /** \file ip.h \brief IP Packet header This file contains the memory map and associated functions for IP packet header creation and deconstruction. */ #define ETHERTYPE_IPV4 0x0800 #define ETHERTYPE_IPV6 0x86DD /// IP Address memory map typedef struct { unsigned char octet[4]; ///< Individual address octets } IP_Address; /// IP Packet memory map typedef struct { /// 4 bits that contain the version, that specifies if it's an IPv4 or IPv6 packet, unsigned version:4; // Only 0x4 supported /// 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). unsigned header_bytes_div4:4; /// 8 bits that contain the Type of Service, also referred to as Quality of Service (QoS), which describes what priority the packet should have, unsigned tos:8; /// 16 bits that contain the total length of the IP packet (datagram) in bytes, u16 packet_bytes; /// 16 bits that contain an identification tag to help reconstruct the packet from several fragments, u16 fragment_id; /// 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) unsigned unused_0:1; unsigned dont_fragment:1; unsigned more_follow:1; /// 13 bits that contain the fragment offset, a field to identify position of fragment within original packet unsigned fragment_offset:13; ///< This and the ones above may not work properly due to endianness /// 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), unsigned ttl:8; /// 8 bits that contain the protocol (TCP, UDP, ICMP, etc...) /// 0x01 ICMP /// 0x06 TCP /// 0x11 UDP unsigned protocol:8; /// 16 bits that contain the Header Checksum, a number used in error detection, u16 header_checksum; /// 32 bits that contain the source IP address, IP_Address source; /// 32 bits that contain the destination address. IP_Address destination; /// Zero-length field for memory mapping the packet data unsigned char data[]; } IP_PacketHeader; /// Convert from wire to host or host to wire endianness inline void fix_endian_ip(IP_PacketHeader *packet) { packet->version ^= packet->header_bytes_div4; packet->header_bytes_div4 ^= packet->version; packet->version ^= packet->header_bytes_div4; fix_endian_u16(&packet->packet_bytes); fix_endian_u16(&packet->fragment_id); // Don't fix checksums; they are done bitwise } /// Get a constant string of the given IP protocol (e.g. "ICMP", "TCP", "UDP") if known inline const char *ipproto2name(u8 proto) { switch (proto) { case 0x01: return "ICMP"; case 0x02: return "IGMP"; case 0x06: return "TCP"; case 0x11: return "UDP"; } return "<UNKNOWN>"; } /// Print the IP packet inline void print_ip(IP_PacketHeader *packet) { main_log.printf("IPv%d Packet:", packet->version); if (packet->version != 4) { main_log.printf("Not an IPv4 packet (skipping)"); return; } u8 *dst = packet->destination.octet; u8 *src = packet->source.octet; main_log.printf(" Source: IP - %03d.%03d.%03d.%03d", src[0], src[1], src[2], src[3]); main_log.printf(" Dest: IP - %03d.%03d.%03d.%03d", dst[0], dst[1], dst[2], dst[3]); main_log.printf(" TTL: %d", packet->ttl); main_log.printf(" Protocol: 0x%02X (%s)", packet->protocol, ipproto2name(packet->protocol)); main_log.printf(" ToS: 0x%02X", packet->tos); main_log.printf(" Header: %d bytes", packet->header_bytes_div4*4); main_log.printf(" Packet: %d bytes", packet->packet_bytes); main_log.printf(" Fragment: 0x%04X DF=%d MF=%d OFFSET=0x04X", packet->fragment_id, packet->dont_fragment, packet->more_follow, packet->fragment_offset); main_log.printf(" Checksum: 0x%04X", packet->header_checksum); } /// Parse the string (in decimal triple-dot notation) into the IP address structure inline void str2ipaddr(const char *ip, IP_Address *addr) { static short a,b,c,d; sscanf(ip, "%3hd.%3hd.%3hd.%3hd", &a, &b, &c, &d); addr->octet[0] = a; addr->octet[1] = b; addr->octet[2] = c; addr->octet[3] = d; } #endif