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