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.
net/tcp.h@0:d494b853ce97, 2010-10-12 (annotated)
- 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?
User | Revision | Line number | New 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 |