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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tcp.h Source File

tcp.h

Go to the documentation of this file.
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