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 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();
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
))
47 total_len
= proto_field_get_u16(hdr
, UDP_LEN
);
51 csum
= p4_csum((void *) proto_header_ptr(lower
), proto_header_ptr(hdr
),
52 total_len
, IPPROTO_UDP
);
55 csum
= p6_csum((void *) proto_header_ptr(lower
), proto_header_ptr(hdr
),
56 total_len
, IPPROTO_UDP
);
63 proto_field_set_be16(hdr
, UDP_CSUM
, bswap_16(csum
));
66 static struct proto_hdr udp_hdr
= {
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();
109 if (proto_field_is_set(hdr
, TCP_CSUM
))
115 total_len
= pkt
->len
- hdr
->pkt_offset
;
119 csum
= p4_csum((void *) proto_header_ptr(lower
), proto_header_ptr(hdr
),
120 total_len
, IPPROTO_TCP
);
123 csum
= p6_csum((void *) proto_header_ptr(lower
), proto_header_ptr(hdr
),
124 total_len
, IPPROTO_TCP
);
131 proto_field_set_be16(hdr
, TCP_CSUM
, bswap_16(csum
));
134 static struct proto_hdr tcp_hdr
= {
137 .header_init
= tcp_header_init
,
138 .packet_finish
= tcp_packet_finish
,
141 void protos_l4_init(void)
143 proto_header_register(&udp_hdr
);
144 proto_header_register(&tcp_hdr
);