ring: use xzmalloc_aligned
[netsniff-ng.git] / trafgen_dump.c
blobff68e8b5d8897b3c00d23ad57631598b67967180
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Subject to the GPL, version 2.
4 */
6 #include <stdio.h>
7 #include <arpa/inet.h>
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__)
29 struct dump_ctx {
30 FILE *file;
33 static int proto_dump_eth(struct dump_ctx *ctx, struct proto_hdr *hdr)
35 uint8_t *mac;
37 HDR_START("eth");
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));
49 HDR_END();
50 return 0;
53 static int proto_dump_vlan(struct dump_ctx *ctx, struct proto_hdr *hdr)
55 HDR_START("vlan");
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));
62 HDR_END();
63 return 0;
66 static int proto_dump_arp(struct dump_ctx *ctx, struct proto_hdr *hdr)
68 char ip_str[INET_ADDRSTRLEN];
69 uint16_t oper;
70 uint8_t *mac;
71 uint32_t ip;
73 HDR_START("arp");
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");
97 else
98 FIELD_END("op=0x%x", oper);
100 HDR_END();
101 return 0;
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];
108 uint32_t ip;
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));
116 HDR_START("ip4");
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))
127 FIELD("mf");
128 if (proto_hdr_field_get_u16(hdr, IP4_DF))
129 FIELD("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);
137 HDR_END();
138 return 0;
141 static int proto_dump_udp(struct dump_ctx *ctx, struct proto_hdr *hdr)
143 HDR_START("udp");
145 FIELD_START("dp=%d", proto_hdr_field_get_u16(hdr, UDP_SPORT));
146 FIELD("sp=%d", proto_hdr_field_get_u16(hdr, UDP_DPORT));
147 FIELD("len=%d", proto_hdr_field_get_u16(hdr, UDP_LEN));
148 FIELD_END("csum=0x%x", proto_hdr_field_get_u16(hdr, UDP_CSUM));
150 HDR_END();
151 return 0;
154 static int proto_dump_tcp(struct dump_ctx *ctx, struct proto_hdr *hdr)
156 HDR_START("tcp");
158 FIELD_START("dp=%d", proto_hdr_field_get_u16(hdr, TCP_SPORT));
159 FIELD("sp=%d", proto_hdr_field_get_u16(hdr, TCP_DPORT));
160 FIELD("seq=0x%x", proto_hdr_field_get_u32(hdr, TCP_SEQ));
161 FIELD("ackseq=0x%x", proto_hdr_field_get_u32(hdr, TCP_ACK_SEQ));
162 FIELD("hlen=%d", proto_hdr_field_get_u16(hdr, TCP_DOFF));
163 if (proto_hdr_field_get_u16(hdr, TCP_CWR))
164 FIELD("cwr");
165 if (proto_hdr_field_get_u16(hdr, TCP_ECE))
166 FIELD("ecn");
167 if (proto_hdr_field_get_u16(hdr, TCP_URG))
168 FIELD("urg");
169 if (proto_hdr_field_get_u16(hdr, TCP_ACK))
170 FIELD("ack");
171 if (proto_hdr_field_get_u16(hdr, TCP_PSH))
172 FIELD("psh");
173 if (proto_hdr_field_get_u16(hdr, TCP_RST))
174 FIELD("rst");
175 if (proto_hdr_field_get_u16(hdr, TCP_SYN))
176 FIELD("syn");
177 if (proto_hdr_field_get_u16(hdr, TCP_FIN))
178 FIELD("fin");
179 FIELD("win=%d", proto_hdr_field_get_u16(hdr, TCP_WINDOW));
180 FIELD("csum=0x%x", proto_hdr_field_get_u16(hdr, TCP_CSUM));
181 FIELD_END("urgptr=0x%x", proto_hdr_field_get_u16(hdr, TCP_URG_PTR));
183 HDR_END();
184 return 0;
187 static int proto_dump_hdr(struct dump_ctx *ctx, struct proto_hdr *hdr)
189 switch (hdr->ops->id) {
190 case PROTO_ETH:
191 return proto_dump_eth(ctx, hdr);
192 case PROTO_VLAN:
193 return proto_dump_vlan(ctx, hdr);
194 case PROTO_ARP:
195 return proto_dump_arp(ctx, hdr);
196 case PROTO_IP4:
197 return proto_dump_ip4(ctx, hdr);
198 case PROTO_UDP:
199 return proto_dump_udp(ctx, hdr);
200 case PROTO_TCP:
201 return proto_dump_tcp(ctx, hdr);
202 default:
203 return -1;
207 int packet_dump_fd(struct packet *pkt, int fd)
209 struct proto_hdr *hdr;
210 enum proto_id pid;
211 struct dump_ctx _ctx;
212 struct dump_ctx *ctx = &_ctx;
213 size_t dump_len = 0;
214 uint32_t i;
216 _ctx.file = fdopen(fd, "w");
217 if (!_ctx.file)
218 return -1;
220 /* handle case if there is already proto headers */
221 if (pkt->headers_count == 0) {
222 hdr = proto_packet_apply(PROTO_ETH, pkt);
224 while ((pid = proto_hdr_get_next_proto(hdr)) != __PROTO_MAX) {
225 if (hdr->pkt_offset + hdr->len >= pkt->len)
226 break;
228 hdr = proto_packet_apply(pid, pkt);
232 PKT_START();
233 for (i = 0; i < pkt->headers_count; i++) {
234 hdr = pkt->headers[i];
236 if (proto_dump_hdr(ctx, hdr))
237 break;
239 dump_len += hdr->len;
242 /* print rest as a bytes */
243 if (dump_len < pkt->len) {
244 int j = 1;
246 DUMP(" ");
247 for (i = dump_len; i < pkt->len; ++i, ++j) {
248 if (j % 15 == 0)
249 DUMP("\n ");
250 DUMP("0x%02x,", pkt->payload[i]);
252 DUMP("\n");
254 PKT_END();
256 fflush(ctx->file);
257 return 0;