flowtop: Remove unused parameters from draw_help() and draw_footer()
[netsniff-ng.git] / trafgen_l4.c
blob886e2b2acf1b28253a8113722584ea18fb5e7849
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Subject to the GPL, version 2.
4 */
6 #include <stdbool.h>
7 #include <netinet/in.h>
9 #include "die.h"
10 #include "csum.h"
11 #include "built_in.h"
12 #include "trafgen_l3.h"
13 #include "trafgen_l4.h"
14 #include "trafgen_conf.h"
15 #include "trafgen_proto.h"
17 static struct proto_field udp_fields[] = {
18 { .id = UDP_SPORT, .len = 2, .offset = 0 },
19 { .id = UDP_DPORT, .len = 2, .offset = 2 },
20 { .id = UDP_LEN, .len = 2, .offset = 4 },
21 { .id = UDP_CSUM, .len = 2, .offset = 6 },
24 static void udp_header_init(struct proto_hdr *hdr)
26 proto_lower_default_add(hdr, PROTO_IP4);
28 proto_header_fields_add(hdr, udp_fields, array_size(udp_fields));
31 static void udp_packet_finish(struct proto_hdr *hdr)
33 struct proto_hdr *lower = proto_lower_header(hdr);
34 struct packet *pkt = current_packet();
35 uint16_t total_len;
36 uint16_t csum;
38 total_len = pkt->len - hdr->pkt_offset;
39 proto_field_set_default_be16(hdr, UDP_LEN, total_len);
41 if (proto_field_is_set(hdr, UDP_CSUM))
42 return;
44 if (!lower)
45 return;
47 total_len = proto_field_get_u16(hdr, UDP_LEN);
49 switch (lower->id) {
50 case PROTO_IP4:
51 csum = p4_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr),
52 total_len, IPPROTO_UDP);
53 break;
54 case PROTO_IP6:
55 csum = p6_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr),
56 total_len, IPPROTO_UDP);
57 break;
58 default:
59 csum = 0;
60 break;
63 proto_field_set_be16(hdr, UDP_CSUM, bswap_16(csum));
66 static struct proto_hdr udp_hdr = {
67 .id = PROTO_UDP,
68 .layer = PROTO_L4,
69 .header_init = udp_header_init,
70 .packet_finish = udp_packet_finish,
73 static struct proto_field tcp_fields[] = {
74 { .id = TCP_SPORT, .len = 2, .offset = 0 },
75 { .id = TCP_DPORT, .len = 2, .offset = 2 },
76 { .id = TCP_SEQ, .len = 4, .offset = 4 },
77 { .id = TCP_ACK_SEQ, .len = 4, .offset = 8 },
78 { .id = TCP_DOFF, .len = 2, .offset = 12, .shift = 12, .mask = 0xf000 },
79 /* reserved (4 bits) */
80 { .id = TCP_CWR, .len = 2, .offset = 12, .shift = 7, .mask = 0x0080 },
81 { .id = TCP_ECE, .len = 2, .offset = 12, .shift = 6, .mask = 0x0040 },
82 { .id = TCP_URG, .len = 2, .offset = 12, .shift = 5, .mask = 0x0020 },
83 { .id = TCP_ACK, .len = 2, .offset = 12, .shift = 4, .mask = 0x0010 },
84 { .id = TCP_PSH, .len = 2, .offset = 12, .shift = 3, .mask = 0x0008 },
85 { .id = TCP_RST, .len = 2, .offset = 12, .shift = 2, .mask = 0x0004 },
86 { .id = TCP_SYN, .len = 2, .offset = 12, .shift = 1, .mask = 0x0002 },
87 { .id = TCP_FIN, .len = 2, .offset = 12, .shift = 0, .mask = 0x0001 },
88 { .id = TCP_WINDOW, .len = 2, .offset = 14 },
89 { .id = TCP_CSUM, .len = 2, .offset = 16 },
90 { .id = TCP_URG_PTR, .len = 2, .offset = 18 },
93 static void tcp_header_init(struct proto_hdr *hdr)
95 proto_lower_default_add(hdr, PROTO_IP4);
97 proto_header_fields_add(hdr, tcp_fields, array_size(tcp_fields));
99 proto_field_set_default_be16(hdr, TCP_DOFF, 5);
102 static void tcp_packet_finish(struct proto_hdr *hdr)
104 struct proto_hdr *lower = proto_lower_header(hdr);
105 struct packet *pkt = current_packet();
106 uint16_t total_len;
107 uint16_t csum;
109 if (proto_field_is_set(hdr, TCP_CSUM))
110 return;
112 if (!lower)
113 return;
115 total_len = pkt->len - hdr->pkt_offset;
117 switch (lower->id) {
118 case PROTO_IP4:
119 csum = p4_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr),
120 total_len, IPPROTO_TCP);
121 break;
122 case PROTO_IP6:
123 csum = p6_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr),
124 total_len, IPPROTO_TCP);
125 break;
126 default:
127 csum = 0;
128 break;
131 proto_field_set_be16(hdr, TCP_CSUM, bswap_16(csum));
134 static struct proto_hdr tcp_hdr = {
135 .id = PROTO_TCP,
136 .layer = PROTO_L4,
137 .header_init = tcp_header_init,
138 .packet_finish = tcp_packet_finish,
141 static struct proto_field icmpv6_fields[] = {
142 { .id = ICMPV6_TYPE, .len = 1, .offset = 0 },
143 { .id = ICMPV6_CODE, .len = 1, .offset = 1 },
144 { .id = ICMPV6_CSUM, .len = 2, .offset = 2 }
147 static void icmpv6_header_init(struct proto_hdr *hdr)
149 proto_lower_default_add(hdr, PROTO_IP6);
151 proto_header_fields_add(hdr, icmpv6_fields, array_size(icmpv6_fields));
154 static void icmpv6_packet_finish(struct proto_hdr *hdr)
156 struct proto_hdr *lower = proto_lower_header(hdr);
157 struct packet *pkt = current_packet();
158 uint16_t total_len;
159 uint16_t csum;
161 if (proto_field_is_set(hdr, ICMPV6_CSUM))
162 return;
164 if (!lower)
165 return;
167 total_len = pkt->len - hdr->pkt_offset;
169 switch (lower->id) {
170 case PROTO_IP6:
171 csum = p6_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr),
172 total_len, IPPROTO_ICMPV6);
173 break;
174 default:
175 csum = 0;
176 break;
179 proto_field_set_be16(hdr, ICMPV6_CSUM, bswap_16(csum));
182 static struct proto_hdr icmpv6_hdr = {
183 .id = PROTO_ICMP6,
184 .layer = PROTO_L4,
185 .header_init = icmpv6_header_init,
186 .packet_finish = icmpv6_packet_finish,
189 void protos_l4_init(void)
191 proto_header_register(&udp_hdr);
192 proto_header_register(&tcp_hdr);
193 proto_header_register(&icmpv6_hdr);