2 * netsniff-ng - the packet sniffing beast
3 * Subject to the GPL, version 2.
8 #include <netinet/in.h>
9 #include <net/ethernet.h>
11 #include "trafgen_l2.h"
12 #include "trafgen_l3.h"
13 #include "trafgen_l4.h"
14 #include "trafgen_proto.h"
15 #include "trafgen_dump.h"
17 #define DUMP(fmt, ...) fprintf((ctx)->file, fmt, ##__VA_ARGS__)
19 #define PKT_START() DUMP("{\n")
20 #define PKT_END() DUMP("}\n")
22 #define HDR_START(h) DUMP(" %s(", h)
23 #define HDR_END(h) DUMP(" ),\n")
25 #define FIELD_START(fmt, ...) DUMP(fmt",\n", ##__VA_ARGS__)
26 #define FIELD_END(fmt, ...) DUMP(" "fmt"\n", ##__VA_ARGS__)
27 #define FIELD(fmt, ...) DUMP(" "fmt",\n", ##__VA_ARGS__)
33 static int proto_dump_eth(struct dump_ctx
*ctx
, struct proto_hdr
*hdr
)
39 mac
= proto_hdr_field_get_bytes(hdr
, ETH_DST_ADDR
);
40 FIELD_START("da=%02x:%02x:%02x:%02x:%02x:%02x",
41 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5]);
43 mac
= proto_hdr_field_get_bytes(hdr
, ETH_SRC_ADDR
);
44 FIELD("sa=%02x:%02x:%02x:%02x:%02x:%02x",
45 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5]);
47 FIELD_END("type=0x%x", proto_hdr_field_get_u16(hdr
, ETH_TYPE
));
53 static int proto_dump_vlan(struct dump_ctx
*ctx
, struct proto_hdr
*hdr
)
57 FIELD_START("id=%d", proto_hdr_field_get_u16(hdr
, VLAN_VID
));
58 FIELD("pcp=%d", proto_hdr_field_get_u16(hdr
, VLAN_PCP
));
59 FIELD("dei=%d", proto_hdr_field_get_u16(hdr
, VLAN_DEI
));
60 FIELD_END("tpid=0x%x", proto_hdr_field_get_u16(hdr
, VLAN_TPID
));
66 static int proto_dump_arp(struct dump_ctx
*ctx
, struct proto_hdr
*hdr
)
68 char ip_str
[INET_ADDRSTRLEN
];
75 mac
= proto_hdr_field_get_bytes(hdr
, ARP_SHA
);
76 FIELD_START("smac=%02x:%02x:%02x:%02x:%02x:%02x",
77 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5]);
79 ip
= proto_hdr_field_get_be32(hdr
, ARP_SPA
);
80 inet_ntop(AF_INET
, &ip
, ip_str
, sizeof(ip_str
));
81 FIELD("sip=%s", ip_str
);
83 mac
= proto_hdr_field_get_bytes(hdr
, ARP_THA
);
84 FIELD("tmac=%02x:%02x:%02x:%02x:%02x:%02x",
85 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5]);
87 ip
= proto_hdr_field_get_be32(hdr
, ARP_TPA
);
88 inet_ntop(AF_INET
, &ip
, ip_str
, sizeof(ip_str
));
89 FIELD("tip=%s", ip_str
);
91 oper
= proto_hdr_field_get_u16(hdr
, ARP_OPER
);
93 if (oper
== ARPOP_REQUEST
)
94 FIELD_END("op=request");
95 else if (oper
== ARPOP_REPLY
)
96 FIELD_END("op=reply");
98 FIELD_END("op=0x%x", oper
);
104 static int proto_dump_ip4(struct dump_ctx
*ctx
, struct proto_hdr
*hdr
)
106 char ip_sa_str
[INET_ADDRSTRLEN
];
107 char ip_da_str
[INET_ADDRSTRLEN
];
110 ip
= proto_hdr_field_get_be32(hdr
, IP4_SADDR
);
111 inet_ntop(AF_INET
, &ip
, ip_sa_str
, sizeof(ip_sa_str
));
113 ip
= proto_hdr_field_get_be32(hdr
, IP4_DADDR
);
114 inet_ntop(AF_INET
, &ip
, ip_da_str
, sizeof(ip_da_str
));
118 FIELD_START("ver=0x%x", proto_hdr_field_get_u8(hdr
, IP4_VER
));
119 FIELD("ihl=0x%x", proto_hdr_field_get_u8(hdr
, IP4_IHL
));
120 FIELD("dscp=0x%x", proto_hdr_field_get_u8(hdr
, IP4_DSCP
));
121 FIELD("ecn=0x%x", proto_hdr_field_get_u8(hdr
, IP4_ECN
));
122 FIELD("tos=0x%x", proto_hdr_field_get_u8(hdr
, IP4_TOS
));
123 FIELD("len=%d", proto_hdr_field_get_u16(hdr
, IP4_LEN
));
124 FIELD("id=0x%x", proto_hdr_field_get_u16(hdr
, IP4_ID
));
125 FIELD("flags=0x%x", proto_hdr_field_get_u16(hdr
, IP4_FLAGS
));
126 if (proto_hdr_field_get_u16(hdr
, IP4_MF
))
128 if (proto_hdr_field_get_u16(hdr
, IP4_DF
))
130 FIELD("frag=0x%x", proto_hdr_field_get_u16(hdr
, IP4_FRAG_OFFS
));
131 FIELD("ttl=%d", proto_hdr_field_get_u8(hdr
, IP4_TTL
));
132 FIELD("proto=0x%x", proto_hdr_field_get_u8(hdr
, IP4_PROTO
));
133 FIELD("csum=0x%x", proto_hdr_field_get_u16(hdr
, IP4_CSUM
));
134 FIELD("sa=%s", ip_sa_str
);
135 FIELD_END("da=%s", ip_da_str
);
141 static int proto_dump_ip6(struct dump_ctx
*ctx
, struct proto_hdr
*hdr
)
143 char ip_sa_str
[INET6_ADDRSTRLEN
];
144 char ip_da_str
[INET6_ADDRSTRLEN
];
147 ip
= proto_hdr_field_get_bytes(hdr
, IP6_SADDR
);
148 inet_ntop(AF_INET6
, ip
, ip_sa_str
, sizeof(ip_sa_str
));
150 ip
= proto_hdr_field_get_bytes(hdr
, IP6_DADDR
);
151 inet_ntop(AF_INET6
, ip
, ip_da_str
, sizeof(ip_da_str
));
155 FIELD_START("ver=0x%x", proto_hdr_field_get_u32(hdr
, IP6_VER
));
156 FIELD("tc=0x%x", proto_hdr_field_get_u32(hdr
, IP6_CLASS
));
157 FIELD("fl=0x%x", proto_hdr_field_get_u32(hdr
, IP6_FLOW_LBL
));
158 FIELD("len=%d", proto_hdr_field_get_u16(hdr
, IP6_LEN
));
159 FIELD("nh=0x%x", proto_hdr_field_get_u8(hdr
, IP6_NEXT_HDR
));
160 FIELD("hl=%d", proto_hdr_field_get_u8(hdr
, IP6_HOP_LIMIT
));
161 FIELD("sa=%s", ip_sa_str
);
162 FIELD_END("da=%s", ip_da_str
);
168 static int proto_dump_udp(struct dump_ctx
*ctx
, struct proto_hdr
*hdr
)
172 FIELD_START("dp=%d", proto_hdr_field_get_u16(hdr
, UDP_SPORT
));
173 FIELD("sp=%d", proto_hdr_field_get_u16(hdr
, UDP_DPORT
));
174 FIELD("len=%d", proto_hdr_field_get_u16(hdr
, UDP_LEN
));
175 FIELD_END("csum=0x%x", proto_hdr_field_get_u16(hdr
, UDP_CSUM
));
181 static int proto_dump_tcp(struct dump_ctx
*ctx
, struct proto_hdr
*hdr
)
185 FIELD_START("dp=%d", proto_hdr_field_get_u16(hdr
, TCP_SPORT
));
186 FIELD("sp=%d", proto_hdr_field_get_u16(hdr
, TCP_DPORT
));
187 FIELD("seq=0x%x", proto_hdr_field_get_u32(hdr
, TCP_SEQ
));
188 FIELD("ackseq=0x%x", proto_hdr_field_get_u32(hdr
, TCP_ACK_SEQ
));
189 FIELD("hlen=%d", proto_hdr_field_get_u16(hdr
, TCP_DOFF
));
190 if (proto_hdr_field_get_u16(hdr
, TCP_CWR
))
192 if (proto_hdr_field_get_u16(hdr
, TCP_ECE
))
194 if (proto_hdr_field_get_u16(hdr
, TCP_URG
))
196 if (proto_hdr_field_get_u16(hdr
, TCP_ACK
))
198 if (proto_hdr_field_get_u16(hdr
, TCP_PSH
))
200 if (proto_hdr_field_get_u16(hdr
, TCP_RST
))
202 if (proto_hdr_field_get_u16(hdr
, TCP_SYN
))
204 if (proto_hdr_field_get_u16(hdr
, TCP_FIN
))
206 FIELD("win=%d", proto_hdr_field_get_u16(hdr
, TCP_WINDOW
));
207 FIELD("csum=0x%x", proto_hdr_field_get_u16(hdr
, TCP_CSUM
));
208 FIELD_END("urgptr=0x%x", proto_hdr_field_get_u16(hdr
, TCP_URG_PTR
));
214 static int proto_dump_hdr(struct dump_ctx
*ctx
, struct proto_hdr
*hdr
)
216 switch (hdr
->ops
->id
) {
218 return proto_dump_eth(ctx
, hdr
);
220 return proto_dump_vlan(ctx
, hdr
);
222 return proto_dump_arp(ctx
, hdr
);
224 return proto_dump_ip4(ctx
, hdr
);
226 return proto_dump_ip6(ctx
, hdr
);
228 return proto_dump_udp(ctx
, hdr
);
230 return proto_dump_tcp(ctx
, hdr
);
236 int packet_dump_fd(struct packet
*pkt
, int fd
)
238 struct proto_hdr
*hdr
;
240 struct dump_ctx _ctx
;
241 struct dump_ctx
*ctx
= &_ctx
;
245 _ctx
.file
= fdopen(fd
, "w");
249 /* handle case if there is already proto headers */
250 if (pkt
->headers_count
== 0) {
251 hdr
= proto_packet_apply(PROTO_ETH
, pkt
);
253 while ((pid
= proto_hdr_get_next_proto(hdr
)) != __PROTO_MAX
) {
254 if (hdr
->pkt_offset
+ hdr
->len
>= pkt
->len
)
257 hdr
= proto_packet_apply(pid
, pkt
);
262 for (i
= 0; i
< pkt
->headers_count
; i
++) {
263 hdr
= pkt
->headers
[i
];
265 if (proto_dump_hdr(ctx
, hdr
))
268 dump_len
+= hdr
->len
;
271 /* print rest as a bytes */
272 if (dump_len
< pkt
->len
) {
276 for (i
= dump_len
; i
< pkt
->len
; ++i
, ++j
) {
279 DUMP("0x%02x,", pkt
->payload
[i
]);