Kyle Lemons / HvZServerLib

Dependencies:   NetServices

Dependents:   HvZ

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ip.h Source File

ip.h

Go to the documentation of this file.
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 /// Parse the string (in decimal triple-dot notation) into the IP address structure
00082 inline void str2ipaddr(const char *ip, IP_Address *addr)
00083 {
00084   static short a,b,c,d;
00085   sscanf(ip, "%3hd.%3hd.%3hd.%3hd", &a, &b, &c, &d);
00086   addr->octet[0] = a;
00087   addr->octet[1] = b;
00088   addr->octet[2] = c;
00089   addr->octet[3] = d;
00090 }
00091 
00092 #endif