2 * netsniff-ng - the packet sniffing beast
3 * Subject to the GPL, version 2.
7 #include <netinet/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 struct proto_field tcp_fields
[] = {
25 { .id
= TCP_SPORT
, .len
= 2, .offset
= 0 },
26 { .id
= TCP_DPORT
, .len
= 2, .offset
= 2 },
27 { .id
= TCP_SEQ
, .len
= 4, .offset
= 4 },
28 { .id
= TCP_ACK_SEQ
, .len
= 4, .offset
= 8 },
29 { .id
= TCP_DOFF
, .len
= 2, .offset
= 12, .shift
= 12, .mask
= 0xf000 },
30 /* reserved (4 bits) */
31 { .id
= TCP_CWR
, .len
= 2, .offset
= 12, .shift
= 7, .mask
= 0x0080 },
32 { .id
= TCP_ECE
, .len
= 2, .offset
= 12, .shift
= 6, .mask
= 0x0040 },
33 { .id
= TCP_URG
, .len
= 2, .offset
= 12, .shift
= 5, .mask
= 0x0020 },
34 { .id
= TCP_ACK
, .len
= 2, .offset
= 12, .shift
= 4, .mask
= 0x0010 },
35 { .id
= TCP_PSH
, .len
= 2, .offset
= 12, .shift
= 3, .mask
= 0x0008 },
36 { .id
= TCP_RST
, .len
= 2, .offset
= 12, .shift
= 2, .mask
= 0x0004 },
37 { .id
= TCP_SYN
, .len
= 2, .offset
= 12, .shift
= 1, .mask
= 0x0002 },
38 { .id
= TCP_FIN
, .len
= 2, .offset
= 12, .shift
= 0, .mask
= 0x0001 },
39 { .id
= TCP_WINDOW
, .len
= 2, .offset
= 14 },
40 { .id
= TCP_CSUM
, .len
= 2, .offset
= 16 },
41 { .id
= TCP_URG_PTR
, .len
= 2, .offset
= 18 },
44 static void udp_header_init(struct proto_hdr
*hdr
)
46 proto_lower_default_add(hdr
, PROTO_IP4
);
48 proto_header_fields_add(hdr
, udp_fields
, array_size(udp_fields
));
51 static void udp_packet_finish(struct proto_hdr
*hdr
)
53 struct proto_hdr
*lower
= proto_lower_header(hdr
);
54 struct packet
*pkt
= current_packet();
58 total_len
= pkt
->len
- hdr
->pkt_offset
;
59 proto_field_set_default_be16(hdr
, UDP_LEN
, total_len
);
61 if (proto_field_is_set(hdr
, UDP_CSUM
))
64 if (!lower
|| lower
->id
!= PROTO_IP4
)
67 total_len
= proto_field_get_u16(hdr
, UDP_LEN
);
68 csum
= p4_csum((void *) proto_header_ptr(lower
), proto_header_ptr(hdr
),
69 total_len
, IPPROTO_UDP
);
71 proto_field_set_be16(hdr
, UDP_CSUM
, bswap_16(csum
));
74 static struct proto_hdr udp_hdr
= {
77 .header_init
= udp_header_init
,
78 .packet_finish
= udp_packet_finish
,
81 static void tcp_header_init(struct proto_hdr
*hdr
)
83 proto_lower_default_add(hdr
, PROTO_IP4
);
85 proto_header_fields_add(hdr
, tcp_fields
, array_size(tcp_fields
));
87 proto_field_set_default_be16(hdr
, TCP_DOFF
, 5);
90 static void tcp_packet_finish(struct proto_hdr
*hdr
)
92 struct proto_hdr
*lower
= proto_lower_header(hdr
);
93 struct packet
*pkt
= current_packet();
97 if (proto_field_is_set(hdr
, TCP_CSUM
))
100 if (!lower
|| lower
->id
!= PROTO_IP4
)
103 total_len
= pkt
->len
- hdr
->pkt_offset
;
104 csum
= p4_csum((void *) proto_header_ptr(lower
), proto_header_ptr(hdr
),
105 total_len
, IPPROTO_TCP
);
107 proto_field_set_be16(hdr
, TCP_CSUM
, bswap_16(csum
));
110 static struct proto_hdr tcp_hdr
= {
113 .header_init
= tcp_header_init
,
114 .packet_finish
= tcp_packet_finish
,
117 void protos_l4_init(void)
119 proto_header_register(&udp_hdr
);
120 proto_header_register(&tcp_hdr
);