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

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?

UserRevisionLine numberNew 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