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/tcp.h@2:e8e09adc41fc, 2010-10-12 (annotated)
- Committer:
- etherealflaim
- Date:
- Tue Oct 12 06:10:41 2010 +0000
- Revision:
- 2:e8e09adc41fc
- Parent:
- 0:d494b853ce97
- Child:
- 3:c32d9660b888
Finished documentation for net/ directory
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
etherealflaim | 0:d494b853ce97 | 1 | #ifndef TCP_H |
etherealflaim | 0:d494b853ce97 | 2 | #define TCP_H |
etherealflaim | 0:d494b853ce97 | 3 | |
etherealflaim | 0:d494b853ce97 | 4 | #include "net.h" |
etherealflaim | 0:d494b853ce97 | 5 | |
etherealflaim | 2:e8e09adc41fc | 6 | /// \file TCP Segment |
etherealflaim | 2:e8e09adc41fc | 7 | |
etherealflaim | 0:d494b853ce97 | 8 | #define IPPROTO_TCP 0x06 |
etherealflaim | 2:e8e09adc41fc | 9 | |
etherealflaim | 2:e8e09adc41fc | 10 | /// TCP Segment Memory Map |
etherealflaim | 0:d494b853ce97 | 11 | typedef struct { |
etherealflaim | 2:e8e09adc41fc | 12 | u16 source_port; ///< Source port (1-65535) |
etherealflaim | 2:e8e09adc41fc | 13 | u16 destination_port; ///< Destination port (1-65535) |
etherealflaim | 2:e8e09adc41fc | 14 | u32 sequence_number; ///< TCP Sequence number (initial one if SYN set) |
etherealflaim | 2:e8e09adc41fc | 15 | u32 acknowledge_number; ///< TCP Acknowledge number (valid if ACK set) |
etherealflaim | 0:d494b853ce97 | 16 | |
etherealflaim | 2:e8e09adc41fc | 17 | unsigned data_offset_bytes_div4:4; ///< Length of this header (20) divided by 4 (should be 5) |
etherealflaim | 2:e8e09adc41fc | 18 | unsigned unused_0:4; ///< Unused, should be zero |
etherealflaim | 0:d494b853ce97 | 19 | |
etherealflaim | 2:e8e09adc41fc | 20 | unsigned fin:1; ///< connection FINished (no more data from sender) |
etherealflaim | 2:e8e09adc41fc | 21 | unsigned syn:1; ///< SYNchronize sequence numbers |
etherealflaim | 2:e8e09adc41fc | 22 | unsigned rst:1; ///< ReSeT the connection |
etherealflaim | 2:e8e09adc41fc | 23 | unsigned psh:1; ///< PuSH to receiving application |
etherealflaim | 2:e8e09adc41fc | 24 | unsigned ack:1; ///< ACKnowledge fiend is significant |
etherealflaim | 2:e8e09adc41fc | 25 | unsigned urg:1; ///< URGent field is significant |
etherealflaim | 2:e8e09adc41fc | 26 | unsigned ece:1; ///< ECn Echo |
etherealflaim | 2:e8e09adc41fc | 27 | unsigned cwr:1; ///< Congestion Window Reduced |
etherealflaim | 0:d494b853ce97 | 28 | |
etherealflaim | 2:e8e09adc41fc | 29 | u16 window_size; ///< TCP Maxumum window size (8192 is good) |
etherealflaim | 2:e8e09adc41fc | 30 | u16 checksum; ///< TCP checksum (computed with pseudo header) |
etherealflaim | 2:e8e09adc41fc | 31 | u16 urgent_pointer; ///< Urgent pointer (valid if URG set) |
etherealflaim | 2:e8e09adc41fc | 32 | |
etherealflaim | 2:e8e09adc41fc | 33 | /// Memory map for data if no options are set |
etherealflaim | 0:d494b853ce97 | 34 | unsigned char data[]; |
etherealflaim | 0:d494b853ce97 | 35 | } TCP_SegmentHeader; |
etherealflaim | 0:d494b853ce97 | 36 | |
etherealflaim | 2:e8e09adc41fc | 37 | /// Convert from wire to host or host to wire endianness |
etherealflaim | 0:d494b853ce97 | 38 | inline void fix_endian_tcp(TCP_SegmentHeader *segment) |
etherealflaim | 0:d494b853ce97 | 39 | { |
etherealflaim | 0:d494b853ce97 | 40 | segment->unused_0 ^= segment->data_offset_bytes_div4; |
etherealflaim | 0:d494b853ce97 | 41 | segment->data_offset_bytes_div4 ^= segment->unused_0; |
etherealflaim | 0:d494b853ce97 | 42 | segment->unused_0 ^= segment->data_offset_bytes_div4; |
etherealflaim | 0:d494b853ce97 | 43 | fix_endian_u16(&segment->source_port); |
etherealflaim | 0:d494b853ce97 | 44 | fix_endian_u16(&segment->destination_port); |
etherealflaim | 0:d494b853ce97 | 45 | fix_endian_u16(&segment->window_size); |
etherealflaim | 0:d494b853ce97 | 46 | // No fixing checksums |
etherealflaim | 0:d494b853ce97 | 47 | fix_endian_u16(&segment->urgent_pointer); |
etherealflaim | 0:d494b853ce97 | 48 | fix_endian_u32(&segment->sequence_number); |
etherealflaim | 0:d494b853ce97 | 49 | fix_endian_u32(&segment->acknowledge_number); |
etherealflaim | 0:d494b853ce97 | 50 | } |
etherealflaim | 0:d494b853ce97 | 51 | |
etherealflaim | 2:e8e09adc41fc | 52 | /// Print the TCP segment header |
etherealflaim | 0:d494b853ce97 | 53 | inline void print_tcp(TCP_SegmentHeader *segment) |
etherealflaim | 0:d494b853ce97 | 54 | { |
etherealflaim | 0:d494b853ce97 | 55 | main_log.printf("TCP Segment:"); |
etherealflaim | 0:d494b853ce97 | 56 | main_log.printf(" Source: PORT %d", segment->source_port); |
etherealflaim | 0:d494b853ce97 | 57 | main_log.printf(" Dest: PORT %d", segment->destination_port); |
etherealflaim | 0:d494b853ce97 | 58 | main_log.printf(" TCP Seqno: 0x%08X", segment->sequence_number); |
etherealflaim | 0:d494b853ce97 | 59 | main_log.printf(" TCP Ackno: 0x%08X", segment->acknowledge_number); |
etherealflaim | 0:d494b853ce97 | 60 | main_log.printf(" Header: %d bytes", segment->data_offset_bytes_div4*4); |
etherealflaim | 0:d494b853ce97 | 61 | if (segment->cwr) main_log.printf(" Flag: CWR"); |
etherealflaim | 0:d494b853ce97 | 62 | if (segment->ece) main_log.printf(" Flag: ECE"); |
etherealflaim | 0:d494b853ce97 | 63 | if (segment->urg) main_log.printf(" Flag: URG"); |
etherealflaim | 0:d494b853ce97 | 64 | if (segment->ack) main_log.printf(" Flag: ACK"); |
etherealflaim | 0:d494b853ce97 | 65 | if (segment->psh) main_log.printf(" Flag: PSH"); |
etherealflaim | 0:d494b853ce97 | 66 | if (segment->rst) main_log.printf(" Flag: RST"); |
etherealflaim | 0:d494b853ce97 | 67 | if (segment->syn) main_log.printf(" Flag: SYN"); |
etherealflaim | 0:d494b853ce97 | 68 | if (segment->fin) main_log.printf(" Flag: FIN"); |
etherealflaim | 0:d494b853ce97 | 69 | } |
etherealflaim | 0:d494b853ce97 | 70 | |
etherealflaim | 2:e8e09adc41fc | 71 | /// Compute the pseudo header checksum with the given source, destination, and length |
etherealflaim | 0:d494b853ce97 | 72 | inline u16 pseudo_header_checksum(IP_Address source, IP_Address destination, u16 length) |
etherealflaim | 0:d494b853ce97 | 73 | { |
etherealflaim | 0:d494b853ce97 | 74 | struct { |
etherealflaim | 0:d494b853ce97 | 75 | IP_Address src, dst; |
etherealflaim | 0:d494b853ce97 | 76 | u8 zeros; |
etherealflaim | 0:d494b853ce97 | 77 | u8 proto; |
etherealflaim | 0:d494b853ce97 | 78 | u16 length; |
etherealflaim | 0:d494b853ce97 | 79 | } pseudoheader = {source, destination, 0, IPPROTO_TCP, length}; |
etherealflaim | 0:d494b853ce97 | 80 | fix_endian_u16(&pseudoheader.length); |
etherealflaim | 0:d494b853ce97 | 81 | return checksum(&pseudoheader, sizeof(pseudoheader)); |
etherealflaim | 0:d494b853ce97 | 82 | } |
etherealflaim | 0:d494b853ce97 | 83 | |
etherealflaim | 0:d494b853ce97 | 84 | #endif |