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.
Revision 2:e8e09adc41fc, committed 2010-10-12
- Comitter:
- etherealflaim
- Date:
- Tue Oct 12 06:10:41 2010 +0000
- Parent:
- 1:63d4ff534d65
- Child:
- 3:c32d9660b888
- Commit message:
- Finished documentation for net/ directory
Changed in this revision
--- a/net/arp.h Tue Oct 12 05:54:52 2010 +0000 +++ b/net/arp.h Tue Oct 12 06:10:41 2010 +0000 @@ -5,7 +5,6 @@ /// \file ARP packet -/// Ethertype Constant for ARP #define ETHERTYPE_ARP 0x0806 /// ARP Packet @@ -22,6 +21,7 @@ u8 target_protocol_address[4]; ///< Announce - Same as TPA } ARP_Packet; +/// Convert from wire to host or host to wire endianness inline void fix_endian_arp(ARP_Packet *packet) { fix_endian_u16(&packet->hardware_type); @@ -29,6 +29,7 @@ fix_endian_u16(&packet->operation); } +/// Print the ARP packet inline void print_arp(ARP_Packet *packet) { main_log.printf("ARP Packet:");
--- a/net/ethernet.h Tue Oct 12 05:54:52 2010 +0000 +++ b/net/ethernet.h Tue Oct 12 06:10:41 2010 +0000 @@ -3,27 +3,33 @@ #include "net.h" +/// \file Ethernet frames + +/// Ethernet MAC address typedef struct { - unsigned char octet[6]; + unsigned char octet[6]; ///< Individual octsts of the MAC address } Ethernet_MAC; +/// Memory map for Ethernet Frame Header (according to the Ethernet II Framing Standard) typedef struct { - // In the Ethernet II Framing Standard: - // Destination MAC address (6 octets) + /// Destination MAC address (6 octets) Ethernet_MAC destination; - // Source MAC address (6 octets) + /// Source MAC address (6 octets) Ethernet_MAC source; // (optional) VLAN Tag (unsupported) - // Ethernet type or length (only <0x600 or 0x0800 IPv4 supported) + /// Ethernet type or length (only <0x600 or 0x0800 IPv4 supported) u16 ethertype; + /// Payload (used for memory mapping; has zero size) unsigned char payload[]; } Ethernet_FrameHeader; +/// Convert from wire to host or host to wire endian-ness inline void fix_endian_ethernet(Ethernet_FrameHeader *header) { fix_endian_u16(&header->ethertype); } +/// Print out an ethernet packet inline void print_ethernet(Ethernet_FrameHeader *frame) { main_log.printf("Ethernet frame:");
--- a/net/icmp.h Tue Oct 12 05:54:52 2010 +0000 +++ b/net/icmp.h Tue Oct 12 06:10:41 2010 +0000 @@ -3,18 +3,23 @@ #include "net.h" +/// \file ICMP Packet + #define ICMP_ECHO_REPLY 0x00 #define ICMP_ECHO_REQUEST 0x08 #define IPPROTO_ICMP 0x01 + +/// Memory map of ICMP packet typedef struct { - u8 type; // type of ICMP message - u8 code; // code number associated with certain message types + u8 type; ///< type of ICMP message + u8 code; ///< code number associated with certain message types u16 checksum; - u16 id; // ID value, returned in ECHO REPLY - u16 sequence; // Sequence value to be returned with ECHO REPLY - u8 data[]; + u16 id; ///< ID value, returned in ECHO REPLY + u16 sequence; ///< Sequence value to be returned with ECHO REPLY + u8 data[]; ///< Data memory map } ICMP_Packet; +/// Convert from wire to host or host to wire endianness inline void fix_endian_icmp(ICMP_Packet *segment) { fix_endian_u16(&segment->checksum); @@ -22,6 +27,7 @@ fix_endian_u16(&segment->sequence); } +/// Print the ICMP packet inline void print_icmp(ICMP_Packet *segment) { main_log.printf("ICMP Packet:");
--- a/net/ip.h Tue Oct 12 05:54:52 2010 +0000 +++ b/net/ip.h Tue Oct 12 06:10:41 2010 +0000 @@ -3,51 +3,52 @@ #include "net.h" +/// \file IP Packet + #define ETHERTYPE_IPV4 0x0800 #define ETHERTYPE_IPV6 0x86DD -/************** IPv4 ***************/ - +/// IP Address memory map typedef struct { - unsigned char octet[4]; + unsigned char octet[4]; ///< Individual address octets } IP_Address; -// 0x0800 +/// Memory map of IP Packet - Some may not work (see comments) 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, + /// 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). + /// 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, + /// 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, + /// 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, + /// 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) + /// 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 + /// 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), + /// 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 + /// 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, + /// 16 bits that contain the Header Checksum, a number used in error detection, u16 header_checksum; - // 32 bits that contain the source IP address, + /// 32 bits that contain the source IP address, IP_Address source; - // 32 bits that contain the destination address. + /// 32 bits that contain the destination address. IP_Address destination; - // Other flags are unsupported + /// 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; @@ -58,6 +59,7 @@ // 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) @@ -70,6 +72,7 @@ return "<UNKNOWN>"; } +/// Print the IP packet inline void print_ip(IP_PacketHeader *packet) { main_log.printf("IPv%d Packet:", packet->version); @@ -92,6 +95,7 @@ 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;
--- a/net/net.h Tue Oct 12 05:54:52 2010 +0000 +++ b/net/net.h Tue Oct 12 06:10:41 2010 +0000 @@ -6,7 +6,11 @@ #include "ctype.h" -// General networking checksum +/// \file Overall networking header - Includes all other net/ headers + +/// General networking checksum - Used for IP, TCP, UDP, ICMP, etc. +/// Computes the one's complement of the one's complement sum of all of the given bytes except for the memory +/// at skip_byte for skip_count bytes (e.g. the checksum). Optionally resumes computation from the (given) last checksum. inline u16 checksum(void *_mem, unsigned int bytes, void *skip_byte = NULL, unsigned int skip_count = 0, u16 last = 0) { u32 sum = 0; @@ -39,7 +43,7 @@ return (u16)(sum); } -// Generic u16 endian swapping +/// Generic u16 endian swapping inline void fix_endian_u16(u16 *p) { char *bytes = (char*)p; @@ -48,7 +52,7 @@ bytes[0] ^= bytes[1]; } -// Generic u32 endian swapping +/// Generic u32 endian swapping inline void fix_endian_u32(u32 *p) { char *bytes = (char*)p; @@ -65,7 +69,7 @@ /* Printing character */ #define PCHAR(x) (isprint(x)?(x):'.') -/* Hex dump a word-aligned number of bytes (may misbehave if length is not a multiple of 32 bits */ +/// Hex dump a word-aligned number of bytes (will print extra bytes if length is not a multiple of 32 bits) inline void hex_dump(void *base, unsigned int length) { char line[/*indent*/ 2 + /*0x*/ 2 + /*addr*/ 8 + /* : */ 3 + /*4xXXXX */ 4*5 + /*: */ 2 + /*8x.*/ 8 + /*\0*/ 1];
--- a/net/tcp.h Tue Oct 12 05:54:52 2010 +0000 +++ b/net/tcp.h Tue Oct 12 06:10:41 2010 +0000 @@ -3,32 +3,38 @@ #include "net.h" +/// \file TCP Segment + #define IPPROTO_TCP 0x06 + +/// TCP Segment Memory Map typedef struct { - u16 source_port; - u16 destination_port; - u32 sequence_number; - u32 acknowledge_number; + u16 source_port; ///< Source port (1-65535) + u16 destination_port; ///< Destination port (1-65535) + u32 sequence_number; ///< TCP Sequence number (initial one if SYN set) + u32 acknowledge_number; ///< TCP Acknowledge number (valid if ACK set) - unsigned data_offset_bytes_div4:4; - unsigned unused_0:4; + unsigned data_offset_bytes_div4:4; ///< Length of this header (20) divided by 4 (should be 5) + unsigned unused_0:4; ///< Unused, should be zero - unsigned fin:1; // connection FINished (no more data from sender) - unsigned syn:1; // SYNchronize sequence numbers - unsigned rst:1; // ReSeT the connection - unsigned psh:1; // PuSH to receiving application - unsigned ack:1; // ACKnowledge fiend is significant - unsigned urg:1; // URGent field is significant - unsigned ece:1; // ECn Echo - unsigned cwr:1; // Congestion Window Reduced + unsigned fin:1; ///< connection FINished (no more data from sender) + unsigned syn:1; ///< SYNchronize sequence numbers + unsigned rst:1; ///< ReSeT the connection + unsigned psh:1; ///< PuSH to receiving application + unsigned ack:1; ///< ACKnowledge fiend is significant + unsigned urg:1; ///< URGent field is significant + unsigned ece:1; ///< ECn Echo + unsigned cwr:1; ///< Congestion Window Reduced - u16 window_size; - u16 checksum; - u16 urgent_pointer; - // Options (unsupported) + u16 window_size; ///< TCP Maxumum window size (8192 is good) + u16 checksum; ///< TCP checksum (computed with pseudo header) + u16 urgent_pointer; ///< Urgent pointer (valid if URG set) + + /// Memory map for data if no options are set unsigned char data[]; } TCP_SegmentHeader; +/// Convert from wire to host or host to wire endianness inline void fix_endian_tcp(TCP_SegmentHeader *segment) { segment->unused_0 ^= segment->data_offset_bytes_div4; @@ -43,6 +49,7 @@ fix_endian_u32(&segment->acknowledge_number); } +/// Print the TCP segment header inline void print_tcp(TCP_SegmentHeader *segment) { main_log.printf("TCP Segment:"); @@ -61,6 +68,7 @@ if (segment->fin) main_log.printf(" Flag: FIN"); } +/// Compute the pseudo header checksum with the given source, destination, and length inline u16 pseudo_header_checksum(IP_Address source, IP_Address destination, u16 length) { struct {
--- a/net/udp.h Tue Oct 12 05:54:52 2010 +0000 +++ b/net/udp.h Tue Oct 12 06:10:41 2010 +0000 @@ -3,7 +3,11 @@ #include "net.h" +/// \file UDP packet + #define IPPROTO_UDP 0x11 + +/// UDP Packet memory map typedef struct { u16 source_port; u16 destination_port; @@ -12,6 +16,7 @@ u8 data[]; } UDP_Packet; +/// Convert from wire to host or host to wire endianness inline void fix_endian_udp(UDP_Packet *segment) { fix_endian_u16(&segment->source_port); @@ -19,6 +24,7 @@ fix_endian_u16(&segment->length); } +/// Print the UDP packet inline void print_udp(UDP_Packet *segment) { main_log.printf("UDP Packet:");