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:48:59 2010 +0000
Revision:
8:1c1f6ce348c6
Parent:
6:66c4cd9073aa
Documentation

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