James Sayer
/
smart2
test icmp
Fork of ethspam by
Diff: net/tcp.h
- Revision:
- 1:feaa107f56b3
diff -r 852db76de235 -r feaa107f56b3 net/tcp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/net/tcp.h Fri Apr 24 03:11:02 2015 +0000 @@ -0,0 +1,90 @@ +#ifndef TCP_H +#define TCP_H + +#include "net.h" + +/** + \file tcp.h + \brief TCP segment header + + This file contains the memory map and associated functions for TCP segment header + creation and deconstruction. +*/ + +#define IPPROTO_TCP 0x06 + +/// TCP Segment memory map +typedef struct { + u16 source_port; ///< Source port (1-65535) + u16 destination_port; ///< Destination port (1-65535) + u32 sequence_number; ///< TCP Sequence number (initial one if SYN set) + u32 acknowledge_number; ///< TCP Acknowledge number (valid if ACK set) + + unsigned data_offset_bytes_div4:4; ///< Length of this header (20) divided by 4 (should be 5) + unsigned unused_0:4; ///< Unused, should be zero + + unsigned fin:1; ///< connection FINished (no more data from sender) + unsigned syn:1; ///< SYNchronize sequence numbers + unsigned rst:1; ///< ReSeT the connection + unsigned psh:1; ///< PuSH to receiving application + unsigned ack:1; ///< ACKnowledge fiend is significant + unsigned urg:1; ///< URGent field is significant + unsigned ece:1; ///< ECn Echo + unsigned cwr:1; ///< Congestion Window Reduced + + u16 window_size; ///< TCP Maxumum window size (8192 is good) + u16 checksum; ///< TCP checksum (computed with pseudo header) + u16 urgent_pointer; ///< Urgent pointer (valid if URG set) + + /// Memory map for data if no options are set + unsigned char data[]; +} TCP_SegmentHeader; + +/// Convert from wire to host or host to wire endianness +inline void fix_endian_tcp(TCP_SegmentHeader *segment) +{ + segment->unused_0 ^= segment->data_offset_bytes_div4; + segment->data_offset_bytes_div4 ^= segment->unused_0; + segment->unused_0 ^= segment->data_offset_bytes_div4; + fix_endian_u16(&segment->source_port); + fix_endian_u16(&segment->destination_port); + fix_endian_u16(&segment->window_size); + // No fixing checksums + fix_endian_u16(&segment->urgent_pointer); + fix_endian_u32(&segment->sequence_number); + fix_endian_u32(&segment->acknowledge_number); +} + +/// Print the TCP segment header +inline void print_tcp(TCP_SegmentHeader *segment) +{ + printf("TCP Segment: \n"); + printf(" Source: PORT %d \n", segment->source_port); + printf(" Dest: PORT %d \n", segment->destination_port); + printf(" TCP Seqno: 0x%08X \n", segment->sequence_number); + printf(" TCP Ackno: 0x%08X \n", segment->acknowledge_number); + printf(" Header: %d bytes \n", segment->data_offset_bytes_div4*4); + if (segment->cwr) printf(" Flag: CWR \n"); + if (segment->ece) printf(" Flag: ECE \n"); + if (segment->urg) printf(" Flag: URG \n"); + if (segment->ack) printf(" Flag: ACK \n"); + if (segment->psh) printf(" Flag: PSH \n"); + if (segment->rst) printf(" Flag: RST \n"); + if (segment->syn) printf(" Flag: SYN \n"); + if (segment->fin) printf(" Flag: FIN \n"); +} + +/// Compute the pseudo header checksum with the given source, destination, and length +inline u16 pseudo_header_checksum(IP_Address source, IP_Address destination, u16 length) +{ + struct { + IP_Address src, dst; + u8 zeros; + u8 proto; + u16 length; + } pseudoheader = {source, destination, 0, IPPROTO_TCP, length}; + fix_endian_u16(&pseudoheader.length); + return checksum(&pseudoheader, sizeof(pseudoheader)); +} + +#endif \ No newline at end of file