proto_ipv4: don't trim length of pkt_buff
[netsniff-ng.git] / src / proto_tcp.c
blob0c92d40c2a92bff00eb2dfb01c9279b68fbfb43b
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 #include <stdio.h>
9 #include <stdint.h>
10 #include <endian.h>
11 #include <netinet/in.h> /* for ntohs() */
12 #include <asm/byteorder.h>
14 #include "proto.h"
15 #include "protos.h"
16 #include "dissector_eth.h"
17 #include "built_in.h"
18 #include "pkt_buff.h"
20 struct tcphdr {
21 uint16_t source;
22 uint16_t dest;
23 uint32_t seq;
24 uint32_t ack_seq;
25 #if defined(__LITTLE_ENDIAN_BITFIELD)
26 __extension__ uint16_t res1:4,
27 doff:4,
28 fin:1,
29 syn:1,
30 rst:1,
31 psh:1,
32 ack:1,
33 urg:1,
34 ece:1,
35 cwr:1;
36 #elif defined(__BIG_ENDIAN_BITFIELD)
37 __extension__ uint16_t doff:4,
38 res1:4,
39 cwr:1,
40 ece:1,
41 urg:1,
42 ack:1,
43 psh:1,
44 rst:1,
45 syn:1,
46 fin:1;
47 #else
48 # error "Adjust your <asm/byteorder.h> defines"
49 #endif
50 uint16_t window;
51 uint16_t check;
52 uint16_t urg_ptr;
53 } __attribute__((packed));
55 static uint16_t tcp_port(uint16_t src, uint16_t dst)
57 char *tmp1, *tmp2;
59 src = ntohs(src);
60 dst = ntohs(dst);
62 /* XXX: Is there a better way to determine? */
63 if (src < dst && src < 1024) {
64 return src;
65 } else if (dst < src && dst < 1024) {
66 return dst;
67 } else {
68 tmp1 = lookup_port_tcp(src);
69 tmp2 = lookup_port_tcp(dst);
70 if (tmp1 && !tmp2) {
71 return src;
72 } else if (!tmp1 && tmp2) {
73 return dst;
74 } else {
75 if (src < dst)
76 return src;
77 else
78 return dst;
83 static void tcp(struct pkt_buff *pkt)
85 struct tcphdr *tcp = (struct tcphdr *) pkt_pull(pkt, sizeof(*tcp));
87 if (tcp == NULL)
88 return;
90 tprintf(" [ TCP ");
91 tprintf("Port (%u => %u, %s%s%s), ",
92 ntohs(tcp->source), ntohs(tcp->dest),
93 colorize_start(bold),
94 lookup_port_tcp(tcp_port(tcp->source, tcp->dest)),
95 colorize_end());
96 tprintf("SN (0x%x), ", ntohl(tcp->seq));
97 tprintf("AN (0x%x), ", ntohl(tcp->ack_seq));
98 tprintf("DataOff (%u), ", tcp->doff);
99 tprintf("Res (%u), ", tcp->res1);
100 tprintf("Flags (");
101 if (tcp->fin)
102 tprintf("FIN ");
103 if (tcp->syn)
104 tprintf("SYN ");
105 if (tcp->rst)
106 tprintf("RST ");
107 if (tcp->psh)
108 tprintf("PSH ");
109 if (tcp->ack)
110 tprintf("ACK ");
111 if (tcp->urg)
112 tprintf("URG ");
113 if (tcp->ece)
114 tprintf("ECE ");
115 if (tcp->cwr)
116 tprintf("CWR ");
117 tprintf("), ");
118 tprintf("Window (%u), ", ntohs(tcp->window));
119 tprintf("CSum (0x%.4x), ", ntohs(tcp->check));
120 tprintf("UrgPtr (%u)", ntohs(tcp->urg_ptr));
121 tprintf(" ]\n");
123 pkt_set_proto(pkt, &eth_lay4, tcp_port(tcp->source, tcp->dest));
126 static void tcp_less(struct pkt_buff *pkt)
128 struct tcphdr *tcp = (struct tcphdr *) pkt_pull(pkt, sizeof(*tcp));
130 if (tcp == NULL)
131 return;
133 tprintf(" TCP %s%s%s %u/%u F%s",
134 colorize_start(bold),
135 lookup_port_tcp(tcp_port(tcp->source, tcp->dest)),
136 colorize_end(), ntohs(tcp->source), ntohs(tcp->dest),
137 colorize_start(bold));
138 if (tcp->fin)
139 tprintf(" FIN");
140 if (tcp->syn)
141 tprintf(" SYN");
142 if (tcp->rst)
143 tprintf(" RST");
144 if (tcp->psh)
145 tprintf(" PSH");
146 if (tcp->ack)
147 tprintf(" ACK");
148 if (tcp->urg)
149 tprintf(" URG");
150 if (tcp->ece)
151 tprintf(" ECE");
152 if (tcp->cwr)
153 tprintf(" CWR");
154 tprintf("%s Win %u S/A 0x%x/0x%x", colorize_end(),
155 ntohs(tcp->window), ntohl(tcp->seq), ntohl(tcp->ack_seq));
157 pkt_set_proto(pkt, &eth_lay4, tcp_port(tcp->source, tcp->dest));
160 struct protocol tcp_ops = {
161 .key = 0x06,
162 .print_full = tcp,
163 .print_less = tcp_less,
166 EXPORT_SYMBOL(tcp_ops);