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.

Dependencies:   mbed

Revision:
0:d494b853ce97
Child:
2:e8e09adc41fc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/net/ip.h	Tue Oct 12 05:32:59 2010 +0000
@@ -0,0 +1,105 @@
+#ifndef IP_H
+#define IP_H
+
+#include "net.h"
+
+#define ETHERTYPE_IPV4 0x0800
+#define ETHERTYPE_IPV6 0x86DD
+
+/************** IPv4 ***************/
+
+typedef struct {
+  unsigned char octet[4];
+} IP_Address;
+
+// 0x0800
+typedef struct {
+  // IP packets are composed of a header and payload. The IPv4 packet header consists of:
+  // 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;
+  // Other flags are unsupported
+  unsigned char data[];
+} IP_PacketHeader;
+
+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
+}
+
+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>";
+}
+
+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);
+}
+
+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
\ No newline at end of file