docs: added project to PROJECTS file
[netsniff-ng.git] / src / proto_tcp.h
blob8ab45274539b3e73adfd02200c730dccba31665f
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
5 * Subject to the GPL, version 2.
6 */
8 #ifndef TCP_H
9 #define TCP_H
11 #include <stdio.h>
12 #include <stdint.h>
13 #include <netinet/in.h> /* for ntohs() */
15 #include "proto_struct.h"
16 #include "dissector_eth.h"
18 struct tcphdr {
19 uint16_t source;
20 uint16_t dest;
21 uint32_t seq;
22 uint32_t ack_seq;
23 #if defined(__LITTLE_ENDIAN_BITFIELD)
24 __extension__ uint16_t res1:4,
25 doff:4,
26 fin:1,
27 syn:1,
28 rst:1,
29 psh:1,
30 ack:1,
31 urg:1,
32 ece:1,
33 cwr:1;
34 #elif defined(__BIG_ENDIAN_BITFIELD)
35 __extension__ uint16_t doff:4,
36 res1:4,
37 cwr:1,
38 ece:1,
39 urg:1,
40 ack:1,
41 psh:1,
42 rst:1,
43 syn:1,
44 fin:1;
45 #else
46 # error "Adjust your <asm/byteorder.h> defines"
47 #endif
48 uint16_t window;
49 uint16_t check;
50 uint16_t urg_ptr;
51 } __attribute__((packed));
53 static inline uint16_t tcp_port(uint16_t src, uint16_t dst)
55 char *tmp1, *tmp2;
57 src = ntohs(src);
58 dst = ntohs(dst);
60 /* XXX: Is there a better way to determine? */
61 if (src < dst && src < 1024) {
62 return src;
63 } else if (dst < src && dst < 1024) {
64 return dst;
65 } else {
66 tmp1 = lookup_port_tcp(src);
67 tmp2 = lookup_port_tcp(dst);
68 if (tmp1 && !tmp2) {
69 return src;
70 } else if (!tmp1 && tmp2) {
71 return dst;
72 } else {
73 if (src < dst)
74 return src;
75 else
76 return dst;
81 static inline void tcp(uint8_t *packet, size_t len)
83 struct tcphdr *tcp = (struct tcphdr *) packet;
85 if (len < sizeof(struct tcphdr))
86 return;
88 tprintf(" [ TCP ");
89 tprintf("Port (%u => %u, %s%s%s), ",
90 ntohs(tcp->source), ntohs(tcp->dest),
91 colorize_start(bold),
92 lookup_port_tcp(tcp_port(tcp->source, tcp->dest)),
93 colorize_end());
94 tprintf("SN (0x%x), ", ntohl(tcp->seq));
95 tprintf("AN (0x%x), ", ntohl(tcp->ack_seq));
96 tprintf("DataOff (%u), ", tcp->doff);
97 tprintf("Res (%u), ", tcp->res1);
98 tprintf("Flags (");
99 if (tcp->fin)
100 tprintf("FIN ");
101 if (tcp->syn)
102 tprintf("SYN ");
103 if (tcp->rst)
104 tprintf("RST ");
105 if (tcp->psh)
106 tprintf("PSH ");
107 if (tcp->ack)
108 tprintf("ACK ");
109 if (tcp->urg)
110 tprintf("URG ");
111 if (tcp->ece)
112 tprintf("ECE ");
113 if (tcp->cwr)
114 tprintf("CWR ");
115 tprintf("), ");
116 tprintf("Window (%u), ", ntohs(tcp->window));
117 tprintf("CSum (0x%.4x), ", ntohs(tcp->check));
118 tprintf("UrgPtr (%u)", ntohs(tcp->urg_ptr));
119 tprintf(" ]\n");
122 static inline void tcp_less(uint8_t *packet, size_t len)
124 struct tcphdr *tcp = (struct tcphdr *) packet;
126 if (len < sizeof(struct tcphdr))
127 return;
129 tprintf(" TCP %s%s%s %u/%u F%s",
130 colorize_start(bold),
131 lookup_port_tcp(tcp_port(tcp->source, tcp->dest)),
132 colorize_end(), ntohs(tcp->source), ntohs(tcp->dest),
133 colorize_start(bold));
134 if (tcp->fin)
135 tprintf(" FIN");
136 if (tcp->syn)
137 tprintf(" SYN");
138 if (tcp->rst)
139 tprintf(" RST");
140 if (tcp->psh)
141 tprintf(" PSH");
142 if (tcp->ack)
143 tprintf(" ACK");
144 if (tcp->urg)
145 tprintf(" URG");
146 if (tcp->ece)
147 tprintf(" ECE");
148 if (tcp->cwr)
149 tprintf(" CWR");
150 tprintf("%s Win %u S/A 0x%x/0x%x", colorize_end(),
151 ntohs(tcp->window), ntohl(tcp->seq), ntohl(tcp->ack_seq));
154 static inline void tcp_next(uint8_t *packet, size_t len,
155 struct hash_table **table,
156 unsigned int *key, size_t *off)
158 struct tcphdr *tcp = (struct tcphdr *) packet;
160 if (len < sizeof(struct tcphdr))
161 goto invalid;
163 (*off) = sizeof(struct tcphdr);
164 (*key) = tcp_port(tcp->source, tcp->dest);
165 (*table) = &eth_lay4;
167 return;
168 invalid:
169 (*off) = 0;
170 (*key) = 0;
171 (*table) = NULL;
174 struct protocol tcp_ops = {
175 .key = 0x06,
176 .offset = sizeof(struct tcphdr),
177 .print_full = tcp,
178 .print_less = tcp_less,
179 .print_pay_ascii = empty,
180 .print_pay_hex = empty,
181 .print_pay_none = tcp,
182 .print_all_cstyle = __hex2,
183 .print_all_hex = __hex,
184 .proto_next = tcp_next,
187 #endif /* TCP_H */