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.
Diff: net/tcp.h
- Revision:
- 0:d494b853ce97
- Child:
- 2:e8e09adc41fc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/net/tcp.h Tue Oct 12 05:32:59 2010 +0000 @@ -0,0 +1,76 @@ +#ifndef TCP_H +#define TCP_H + +#include "net.h" + +#define IPPROTO_TCP 0x06 +typedef struct { + u16 source_port; + u16 destination_port; + u32 sequence_number; + u32 acknowledge_number; + + unsigned data_offset_bytes_div4:4; + unsigned unused_0:4; + + 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; + u16 checksum; + u16 urgent_pointer; + // Options (unsupported) + unsigned char data[]; +} TCP_SegmentHeader; + +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); +} + +inline void print_tcp(TCP_SegmentHeader *segment) +{ + main_log.printf("TCP Segment:"); + main_log.printf(" Source: PORT %d", segment->source_port); + main_log.printf(" Dest: PORT %d", segment->destination_port); + main_log.printf(" TCP Seqno: 0x%08X", segment->sequence_number); + main_log.printf(" TCP Ackno: 0x%08X", segment->acknowledge_number); + main_log.printf(" Header: %d bytes", segment->data_offset_bytes_div4*4); + if (segment->cwr) main_log.printf(" Flag: CWR"); + if (segment->ece) main_log.printf(" Flag: ECE"); + if (segment->urg) main_log.printf(" Flag: URG"); + if (segment->ack) main_log.printf(" Flag: ACK"); + if (segment->psh) main_log.printf(" Flag: PSH"); + if (segment->rst) main_log.printf(" Flag: RST"); + if (segment->syn) main_log.printf(" Flag: SYN"); + if (segment->fin) main_log.printf(" Flag: FIN"); +} + +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