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 05:32:59 2010 +0000
Revision:
0:d494b853ce97
Child:
2:e8e09adc41fc
Initial Publish - Slightly unfinished, but usable

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 0:d494b853ce97 6 #define IPPROTO_TCP 0x06
etherealflaim 0:d494b853ce97 7 typedef struct {
etherealflaim 0:d494b853ce97 8 u16 source_port;
etherealflaim 0:d494b853ce97 9 u16 destination_port;
etherealflaim 0:d494b853ce97 10 u32 sequence_number;
etherealflaim 0:d494b853ce97 11 u32 acknowledge_number;
etherealflaim 0:d494b853ce97 12
etherealflaim 0:d494b853ce97 13 unsigned data_offset_bytes_div4:4;
etherealflaim 0:d494b853ce97 14 unsigned unused_0:4;
etherealflaim 0:d494b853ce97 15
etherealflaim 0:d494b853ce97 16 unsigned fin:1; // connection FINished (no more data from sender)
etherealflaim 0:d494b853ce97 17 unsigned syn:1; // SYNchronize sequence numbers
etherealflaim 0:d494b853ce97 18 unsigned rst:1; // ReSeT the connection
etherealflaim 0:d494b853ce97 19 unsigned psh:1; // PuSH to receiving application
etherealflaim 0:d494b853ce97 20 unsigned ack:1; // ACKnowledge fiend is significant
etherealflaim 0:d494b853ce97 21 unsigned urg:1; // URGent field is significant
etherealflaim 0:d494b853ce97 22 unsigned ece:1; // ECn Echo
etherealflaim 0:d494b853ce97 23 unsigned cwr:1; // Congestion Window Reduced
etherealflaim 0:d494b853ce97 24
etherealflaim 0:d494b853ce97 25 u16 window_size;
etherealflaim 0:d494b853ce97 26 u16 checksum;
etherealflaim 0:d494b853ce97 27 u16 urgent_pointer;
etherealflaim 0:d494b853ce97 28 // Options (unsupported)
etherealflaim 0:d494b853ce97 29 unsigned char data[];
etherealflaim 0:d494b853ce97 30 } TCP_SegmentHeader;
etherealflaim 0:d494b853ce97 31
etherealflaim 0:d494b853ce97 32 inline void fix_endian_tcp(TCP_SegmentHeader *segment)
etherealflaim 0:d494b853ce97 33 {
etherealflaim 0:d494b853ce97 34 segment->unused_0 ^= segment->data_offset_bytes_div4;
etherealflaim 0:d494b853ce97 35 segment->data_offset_bytes_div4 ^= segment->unused_0;
etherealflaim 0:d494b853ce97 36 segment->unused_0 ^= segment->data_offset_bytes_div4;
etherealflaim 0:d494b853ce97 37 fix_endian_u16(&segment->source_port);
etherealflaim 0:d494b853ce97 38 fix_endian_u16(&segment->destination_port);
etherealflaim 0:d494b853ce97 39 fix_endian_u16(&segment->window_size);
etherealflaim 0:d494b853ce97 40 // No fixing checksums
etherealflaim 0:d494b853ce97 41 fix_endian_u16(&segment->urgent_pointer);
etherealflaim 0:d494b853ce97 42 fix_endian_u32(&segment->sequence_number);
etherealflaim 0:d494b853ce97 43 fix_endian_u32(&segment->acknowledge_number);
etherealflaim 0:d494b853ce97 44 }
etherealflaim 0:d494b853ce97 45
etherealflaim 0:d494b853ce97 46 inline void print_tcp(TCP_SegmentHeader *segment)
etherealflaim 0:d494b853ce97 47 {
etherealflaim 0:d494b853ce97 48 main_log.printf("TCP Segment:");
etherealflaim 0:d494b853ce97 49 main_log.printf(" Source: PORT %d", segment->source_port);
etherealflaim 0:d494b853ce97 50 main_log.printf(" Dest: PORT %d", segment->destination_port);
etherealflaim 0:d494b853ce97 51 main_log.printf(" TCP Seqno: 0x%08X", segment->sequence_number);
etherealflaim 0:d494b853ce97 52 main_log.printf(" TCP Ackno: 0x%08X", segment->acknowledge_number);
etherealflaim 0:d494b853ce97 53 main_log.printf(" Header: %d bytes", segment->data_offset_bytes_div4*4);
etherealflaim 0:d494b853ce97 54 if (segment->cwr) main_log.printf(" Flag: CWR");
etherealflaim 0:d494b853ce97 55 if (segment->ece) main_log.printf(" Flag: ECE");
etherealflaim 0:d494b853ce97 56 if (segment->urg) main_log.printf(" Flag: URG");
etherealflaim 0:d494b853ce97 57 if (segment->ack) main_log.printf(" Flag: ACK");
etherealflaim 0:d494b853ce97 58 if (segment->psh) main_log.printf(" Flag: PSH");
etherealflaim 0:d494b853ce97 59 if (segment->rst) main_log.printf(" Flag: RST");
etherealflaim 0:d494b853ce97 60 if (segment->syn) main_log.printf(" Flag: SYN");
etherealflaim 0:d494b853ce97 61 if (segment->fin) main_log.printf(" Flag: FIN");
etherealflaim 0:d494b853ce97 62 }
etherealflaim 0:d494b853ce97 63
etherealflaim 0:d494b853ce97 64 inline u16 pseudo_header_checksum(IP_Address source, IP_Address destination, u16 length)
etherealflaim 0:d494b853ce97 65 {
etherealflaim 0:d494b853ce97 66 struct {
etherealflaim 0:d494b853ce97 67 IP_Address src, dst;
etherealflaim 0:d494b853ce97 68 u8 zeros;
etherealflaim 0:d494b853ce97 69 u8 proto;
etherealflaim 0:d494b853ce97 70 u16 length;
etherealflaim 0:d494b853ce97 71 } pseudoheader = {source, destination, 0, IPPROTO_TCP, length};
etherealflaim 0:d494b853ce97 72 fix_endian_u16(&pseudoheader.length);
etherealflaim 0:d494b853ce97 73 return checksum(&pseudoheader, sizeof(pseudoheader));
etherealflaim 0:d494b853ce97 74 }
etherealflaim 0:d494b853ce97 75
etherealflaim 0:d494b853ce97 76 #endif