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.
tcp.h
00001 #ifndef TCP_H 00002 #define TCP_H 00003 00004 #include "net.h" 00005 00006 /** 00007 \file tcp.h 00008 \brief TCP segment header 00009 00010 This file contains the memory map and associated functions for TCP segment header 00011 creation and deconstruction. 00012 */ 00013 00014 #define IPPROTO_TCP 0x06 00015 00016 /// TCP Segment memory map 00017 typedef struct { 00018 u16 source_port; ///< Source port (1-65535) 00019 u16 destination_port; ///< Destination port (1-65535) 00020 u32 sequence_number; ///< TCP Sequence number (initial one if SYN set) 00021 u32 acknowledge_number; ///< TCP Acknowledge number (valid if ACK set) 00022 00023 unsigned data_offset_bytes_div4:4; ///< Length of this header (20) divided by 4 (should be 5) 00024 unsigned unused_0:4; ///< Unused, should be zero 00025 00026 unsigned fin:1; ///< connection FINished (no more data from sender) 00027 unsigned syn:1; ///< SYNchronize sequence numbers 00028 unsigned rst:1; ///< ReSeT the connection 00029 unsigned psh:1; ///< PuSH to receiving application 00030 unsigned ack:1; ///< ACKnowledge fiend is significant 00031 unsigned urg:1; ///< URGent field is significant 00032 unsigned ece:1; ///< ECn Echo 00033 unsigned cwr:1; ///< Congestion Window Reduced 00034 00035 u16 window_size; ///< TCP Maxumum window size (8192 is good) 00036 u16 checksum; ///< TCP checksum (computed with pseudo header) 00037 u16 urgent_pointer; ///< Urgent pointer (valid if URG set) 00038 00039 /// Memory map for data if no options are set 00040 unsigned char data[]; 00041 } TCP_SegmentHeader; 00042 00043 /// Convert from wire to host or host to wire endianness 00044 inline void fix_endian_tcp(TCP_SegmentHeader *segment) 00045 { 00046 segment->unused_0 ^= segment->data_offset_bytes_div4; 00047 segment->data_offset_bytes_div4 ^= segment->unused_0; 00048 segment->unused_0 ^= segment->data_offset_bytes_div4; 00049 fix_endian_u16(&segment->source_port); 00050 fix_endian_u16(&segment->destination_port); 00051 fix_endian_u16(&segment->window_size); 00052 // No fixing checksums 00053 fix_endian_u16(&segment->urgent_pointer); 00054 fix_endian_u32(&segment->sequence_number); 00055 fix_endian_u32(&segment->acknowledge_number); 00056 } 00057 00058 /// Print the TCP segment header 00059 inline void print_tcp(TCP_SegmentHeader *segment) 00060 { 00061 main_log.printf("TCP Segment:"); 00062 main_log.printf(" Source: PORT %d", segment->source_port); 00063 main_log.printf(" Dest: PORT %d", segment->destination_port); 00064 main_log.printf(" TCP Seqno: 0x%08X", segment->sequence_number); 00065 main_log.printf(" TCP Ackno: 0x%08X", segment->acknowledge_number); 00066 main_log.printf(" Header: %d bytes", segment->data_offset_bytes_div4*4); 00067 if (segment->cwr) main_log.printf(" Flag: CWR"); 00068 if (segment->ece) main_log.printf(" Flag: ECE"); 00069 if (segment->urg) main_log.printf(" Flag: URG"); 00070 if (segment->ack) main_log.printf(" Flag: ACK"); 00071 if (segment->psh) main_log.printf(" Flag: PSH"); 00072 if (segment->rst) main_log.printf(" Flag: RST"); 00073 if (segment->syn) main_log.printf(" Flag: SYN"); 00074 if (segment->fin) main_log.printf(" Flag: FIN"); 00075 } 00076 00077 /// Compute the pseudo header checksum with the given source, destination, and length 00078 inline u16 pseudo_header_checksum(IP_Address source, IP_Address destination, u16 length) 00079 { 00080 struct { 00081 IP_Address src, dst; 00082 u8 zeros; 00083 u8 proto; 00084 u16 length; 00085 } pseudoheader = {source, destination, 0, IPPROTO_TCP, length}; 00086 fix_endian_u16(&pseudoheader.length); 00087 return checksum(&pseudoheader, sizeof(pseudoheader)); 00088 } 00089 00090 #endif
Generated on Tue Jul 12 2022 11:59:40 by 1.7.2