1 #ifndef __PRETTYPACKET_H__
2 #define __PRETTYPACKET_H__
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <arpa/inet.h>
9 #include "hexstring.h"
10
11 /**
12 * Default terminal rows
13 */
14 static const int rows = 24;
15
16 /**
17 * Default terminal columns
18 */
19 static const int cols = 80;
20
21 /**
22 * Example ARP packet
23 */
24 static const uint8_t arp_packet[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xAA\x00\x04\x00\x0A\x04\x08\x06\x00\x01\x08\x00\x06\x04\x00\x01\xAA\x00\x04\x00\x0A\x04\xC0\xA8\x01\x09\x00\x00\x00\x00\x00\x00\xC0\xA8\x01\x04";
25
26 /**
27 * Example TCP packet
28 */
29 static const uint8_t tcp_packet[] = "\x1C\xAF\xF7\x6B\x0E\x4D\xAA\x00\x04\x00\x0A\x04\x08\x00\x45\x00\x00\x34\x5A\xAE\x40\x00\x40\x06\x5E\x67\xC0\xA8\x01\x09\x58\xBF\x67\x3E\x9B\x44\x00\x50\x8E\xB5\xC6\xAC\x15\x93\x47\x9E\x80\x10\x00\x58\xA5\xA0\x00\x00\x01\x01\x08\x0A\x00\x09\xC3\xB2\x42\x5B\xFA\xD6";
30
31 /**
32 * Example of IPv6 TCP packet
33 */
34 static const uint8_t ipv6_tcp_packet[] = "\xc5\x00\x00\x00\x82\xc4\x00\x12\x1e\xf2\x61\x3d\x86\xdd\x60\x0A\x0B\x0C\x00\x20\x06\xf6\x24\x02\xf0\x00\x00\x01\x8e\x01\x00\x00\x00\x00\x00\x00\x55\x55\x26\x07\xfc\xd0\x01\x00\x23\x00\x00\x00\x00\x00\xb1\x08\x2a\x6b\x9b\x44\x00\x50\x8e\xb5\xc6\xac\x15\x93\x47\x9e\x80\x10\x00\x58\x0d\xa9\x00\x00\x01\x01\x08\x0a\x00\x09\xc3\xb2\x42\x5b\xfa\xd6";
35
36 /**
37 * Example ICMP packet
38 */
39 static const uint8_t icmp_packet[] = "\x1C\xAF\xF7\x6B\x0E\x4D\xAA\x00\x04\x00\x0A\x04\x08\x00\x45\x00\x00\x54\x00\x00\x40\x00\x40\x01\x54\x4E\xC0\xA8\x01\x09\xC0\xA8\x64\x01\x08\x00\x34\x98\xD7\x10\x00\x01\x5B\x68\x98\x4C\x00\x00\x00\x00\x2D\xCE\x0C\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37";
40
41 /**
42 * Example of ICMPv6 packet
43 */
44 static const uint8_t ipv6_icmp_packet[] = "\x33\x33\x00\x00\x00\x16\x08\x00\x27\xd4\x10\xbb\x86\xdd\x60\x00\x00\x00\x00\x38\x00\x01\xfe\x80\x00\x00\x00\x00\x00\x00\x0a\x00\x27\xff\xfe\xd4\x10\xbb\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x3a\x00\x05\x02\x00\x00\x01\x00\x8f\x00\x2b\x5a\x00\x00\x00\x02\x04\x00\x00\x00\xff\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x03\x04\x00\x00\x00\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02";
45
46 /**
47 * Example UDP packet
48 */
49 static const uint8_t udp_packet[] = "\x1C\xAF\xF7\x6B\x0E\x4D\xAA\x00\x04\x00\x0A\x04\x08\x00\x45\x00\x00\x3C\x9B\x23\x00\x00\x40\x11\x70\xBC\xC0\xA8\x01\x09\xD0\x43\xDC\xDC\x91\x02\x00\x35\x00\x28\x6F\x0B\xAE\x9C\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\x77\x77\x77\x06\x67\x6F\x6F\x67\x6C\x65\x03\x63\x6F\x6D\x00\x00\x01\x00\x01";
50
51 /**
52 * Example IGMP packet
53 */
54 static const uint8_t igmp_packet[] = "\x1C\xAF\xF7\x6B\x0E\x4D\xAA\x00\x04\x00\x0A\x04\x08\x00\x45\x00\x00\x1C\x00\x00\x40\x00\x40\x02\x54\x4E\xC0\xA8\x01\x09\xC0\xA8\x64\x01\x11\xFF\x0D\xFF\xE0\x00\x00\x01";
55
56 /**
57 * Example of IPv6 in IPv4 encapsulation
58 */
59 static const uint8_t ipv6_in_ipv4_packet[] = "\x00\x90\x1a\x41\x65\x41\x00\x16\xcf\x41\x9c\x20\x08\x00\x45\x00\x00\x50\x93\x5a\x00\x00\x80\x29\x67\xc6\x46\x37\xd5\xd3\xc0\x58\x63\x01\x60\x00\x00\x00\x00\x14\x06\x80\x20\x02\x46\x37\xd5\xd3\x00\x00\x00\x00\x00\x00\x46\x37\xd5\xd3\x20\x01\x48\x60\x00\x00\x20\x01\x00\x00\x00\x00\x00\x00\x00\x68\x05\x07\x00\x50\x22\xec\x58\x2e\x3a\xc0\x18\xc5\x50\x10\x42\x48\xb8\xb3\x00\x00";
60
61 /**
62 * Example Spanning Tree Protocol (STP) packet
63 */
64 static const uint8_t stp_packet[]="\x01\x80\xc2\x00\x00\x00\x00\x1c\x0e\x87\x85\x04\x00\x26\x42\x42\x03\x00\x00\x00\x00\x00\x80\x64\x00\x1c\x0e\x87\x78\x00\x00\x00\x00\x04\x80\x64\x00\x1c\x0e\x87\x85\x00\x80\x04\x01\x00\x14\x00\x02\x00\x0f\x00";
65
66 // functions that need prototypes
67 void layer_2_dispatcher(const uint8_t *, int, uint64_t);
68 void layer_3_dispatcher(const uint8_t *, int, uint64_t);
69 void layer_4_dispatcher(const uint8_t *, int, uint64_t);
70
71 /**
72 * Extract protocol number (8bit version)
73 *
74 * @param packet_buffer raw packet captured from the network
75 * @param counter protocol number offset
76 * @return protocol number in host format
77 */
protocol_8bit_extract(const uint8_t * packet_buffer,int counter)78 static uint8_t protocol_8bit_extract(const uint8_t *packet_buffer, int counter) {
79 return *(packet_buffer + counter);
80 }
81
82 /**
83 * Extract protocol number (16bit version)
84 *
85 * @param packet_buffer raw packet captured from the network
86 * @param counter protocol number offset
87 * @return protocol number in host format
88 */
protocol_16bit_extract(const uint8_t * packet_buffer,int counter)89 static uint16_t protocol_16bit_extract(const uint8_t *packet_buffer, int counter) {
90 return ntohs(*((uint16_t *)(packet_buffer + counter)));
91 }
92
93 /**
94 * Extract protocol type from ethernet Destination MAC Address (48bit)
95 * @param packet_buffer raw packet captured from the network
96 * @param counter protocol number offset
97 * @return protocol number in host format
98 */
protocol_48bit_extract(const uint8_t * packet_buffer,int counter)99 static uint64_t protocol_48bit_extract(const uint8_t *packet_buffer, int counter) {
100 uint64_t value = 0;
101
102 int i;
103 for(i=0; i < 6; i++) {
104 uint8_t byte = *((uint8_t *)(packet_buffer + counter + i));
105
106 value = byte + (value * 256);
107 }
108
109 return value;
110 }
111
112 /**
113 * Diplay a single field of an header
114 *
115 * @param packet_buffer raw packet captured from the network, starting at the part to process
116 * @param field_size size in bytes of the field to print
117 * @param counter read bytes counter
118 * @param field_text description of the field
119 */
field_print(const uint8_t * packet_buffer,int field_size,int * counter,const char * field_text)120 static void field_print (const uint8_t *packet_buffer, int field_size, int *counter, const char *field_text) {
121
122 char *tmp_hexstr = raw_to_hexstr(packet_buffer + *counter, field_size);
123 *counter += field_size;
124
125 printf(" %-24s %s\n", tmp_hexstr, field_text);
126
127 free(tmp_hexstr);
128 }
129
130 /**
131 * Print the payload part of the packet
132 *
133 * @param packet_buffer raw packet captured from the network, starting at the part to process
134 * @param size packet_buffer size
135 */
payload_print(const uint8_t * packet_buffer,int size)136 void payload_print (const uint8_t *packet_buffer, int size) {
137
138 if (size < 1) {
139 return;
140 }
141
142 puts("\nPayload or Trailer:");
143
144 int bytes_per_row = cols / BYTE_MULT;
145
146 int i, j=0;
147
148 // new line
149 while (j < size) {
150
151 // bytes in the line
152 for (i = 0; (i < bytes_per_row) && (j < size); i++, j++) { // columns
153 char str[BYTE_MULT];
154
155 hex_to_str(packet_buffer[j], str);
156
157 printf(" %s", str);
158 }
159
160 puts("");
161 }
162
163 }
164
165 /**
166 * Print the TCP header of the packet
167 *
168 * @param packet_buffer raw packet captured from the network, starting at the part to process
169 * @param size packet_buffer size
170 */
tcp_print(const uint8_t * packet_buffer,int size)171 void tcp_print (const uint8_t *packet_buffer, int size) {
172 int counter = 0;
173
174 puts("\nTCP Header:");
175
176 if (size < 8) {
177 puts (" invalid header size");
178 return;
179 }
180
181 // print header fields
182 field_print(packet_buffer, 2, &counter, "Source port");
183 field_print(packet_buffer, 2, &counter, "Destination port");
184 field_print(packet_buffer, 4, &counter, "Sequence number");
185 field_print(packet_buffer, 4, &counter, "Acknowledgement number");
186 field_print(packet_buffer, 1, &counter, "Header length");
187 field_print(packet_buffer, 1, &counter, "Flags");
188 field_print(packet_buffer, 2, &counter, "Window");
189 field_print(packet_buffer, 2, &counter, "Checksum");
190 field_print(packet_buffer, 2, &counter, "Urgent pointer");
191
192 // print remaining payload
193 payload_print(packet_buffer + counter, size - counter);
194 }
195
196 /**
197 * Print the UDP header of the packet
198 *
199 * @param packet_buffer raw packet captured from the network, starting at the part to process
200 * @param size packet_buffer size
201 */
udp_print(const uint8_t * packet_buffer,int size)202 void udp_print (const uint8_t *packet_buffer, int size) {
203 int counter = 0;
204
205 puts("\nUDP Header:");
206
207 if (size < 8) {
208 puts (" invalid header size");
209 return;
210 }
211
212 // print header fields
213 field_print(packet_buffer, 2, &counter, "Source port");
214 field_print(packet_buffer, 2, &counter, "Destination port");
215 field_print(packet_buffer, 2, &counter, "Length");
216 field_print(packet_buffer, 2, &counter, "Checksum");
217
218 // print remaining payload
219 payload_print(packet_buffer + counter, size - counter);
220 }
221
222 /**
223 * Print the ICMP header of the packet
224 *
225 * @param packet_buffer raw packet captured from the network, starting at the part to process
226 * @param size packet_buffer size
227 */
icmp_print(const uint8_t * packet_buffer,int size)228 void icmp_print (const uint8_t *packet_buffer, int size) {
229 int counter = 0;
230
231 puts("\nICMP Header:");
232
233 if (size < 8) {
234 puts (" invalid header size");
235 return;
236 }
237
238 // print header fields
239 field_print(packet_buffer, 1, &counter, "Type");
240 field_print(packet_buffer, 1, &counter, "Code");
241 field_print(packet_buffer, 2, &counter, "Checksum");
242 field_print(packet_buffer, 2, &counter, "ID");
243 field_print(packet_buffer, 2, &counter, "Sequence number");
244
245 // print remaining payload
246 payload_print(packet_buffer + counter, size - counter);
247 }
248
249 /**
250 * Print the ICMPv6 header of the packet
251 *
252 * @param packet_buffer raw packet captured from the network, starting at the part to process
253 * @param size packet_buffer size
254 */
icmp6_print(const uint8_t * packet_buffer,int size)255 void icmp6_print (const uint8_t *packet_buffer, int size) {
256 int counter = 0;
257
258 puts("\nICMPv6 Header:");
259
260 if (size < 8) {
261 puts (" invalid header size");
262 return;
263 }
264
265 // print header fields
266 field_print(packet_buffer, 1, &counter, "Type");
267 field_print(packet_buffer, 1, &counter, "Code");
268 field_print(packet_buffer, 2, &counter, "Checksum");
269
270 // print remaining payload
271 payload_print(packet_buffer + counter, size - counter);
272 }
273
274 /**
275 * Print the IGMP header of the packet
276 *
277 * @param packet_buffer raw packet captured from the network, starting at the part to process
278 * @param size packet_buffer size
279 */
igmp_print(const uint8_t * packet_buffer,int size)280 void igmp_print (const uint8_t *packet_buffer, int size) {
281 int counter = 0;
282
283 puts("\nIGMP Header:");
284
285 if (size < 8) {
286 puts (" invalid header size");
287 return;
288 }
289
290 // print header fields
291 field_print(packet_buffer, 1, &counter, "Type");
292 field_print(packet_buffer, 1, &counter, "Max response time");
293 field_print(packet_buffer, 2, &counter, "Checksum");
294 field_print(packet_buffer, 4, &counter, "Group address");
295
296 // print remaining payload
297 payload_print(packet_buffer + counter, size - counter);
298 }
299
300 /**
301 * Print the IPv4 header of the packet
302 *
303 * @param packet_buffer raw packet captured from the network, starting at the part to process
304 * @param size packet_buffer size
305 */
ip_print(const uint8_t * packet_buffer,int size)306 void ip_print (const uint8_t *packet_buffer, int size) {
307 int counter = 0;
308
309 puts("\nIPv4 Header:");
310
311 if (size < 20) {
312 puts (" invalid header size");
313 return;
314 }
315
316 // print header fields
317 field_print(packet_buffer, 1, &counter, "Version / Header length");
318 field_print(packet_buffer, 1, &counter, "ToS / DFS");
319 field_print(packet_buffer, 2, &counter, "Total length");
320 field_print(packet_buffer, 2, &counter, "ID");
321 field_print(packet_buffer, 2, &counter, "Flags / Fragment offset");
322 field_print(packet_buffer, 1, &counter, "TTL");
323
324 int next_protocol = protocol_8bit_extract(packet_buffer, counter);
325 field_print(packet_buffer, 1, &counter, "Protocol");
326
327 field_print(packet_buffer, 2, &counter, "Checksum");
328 field_print(packet_buffer, 4, &counter, "Source address");
329 field_print(packet_buffer, 4, &counter, "Destination address");
330
331 // go up to the next layer
332 layer_4_dispatcher(packet_buffer + counter, size - counter, next_protocol);
333 }
334
335 /**
336 * Print the IPv6 header of the packet
337 *
338 * @param packet_buffer raw packet captured from the network, starting at the part to process
339 * @param size packet_buffer size
340 */
ipv6_print(const uint8_t * packet_buffer,int size)341 void ipv6_print (const uint8_t *packet_buffer, int size) {
342
343 int next_protocol = 0, eh_size = 0;
344 int counter = 0;
345
346 puts("\nIPv6 Header:");
347
348 if (size < 40) {
349 puts (" invalid header size");
350 return;
351 }
352
353 uint8_t buffer[8] = { 0 };
354 int counter_tmp = 0;
355
356 // print header fields
357
358 buffer[0] = *(packet_buffer + counter) >> 4;
359 counter_tmp = 0;
360 field_print(buffer, 1, &counter_tmp, "Version");
361
362 buffer[0] = (*(packet_buffer + counter) << 4) | (*(packet_buffer + counter + 1) >> 4);
363 counter_tmp = 0;
364 field_print(buffer, 1, &counter_tmp, "Traffic class");
365
366 buffer[0] = *(packet_buffer + counter + 1) & 0x0F;
367 buffer[1] = *(packet_buffer + counter + 2);
368 buffer[2] = *(packet_buffer + counter + 3);
369 counter_tmp = 0;
370 field_print(buffer, 3, &counter_tmp, "Flow label");
371
372 counter += 4;
373
374 field_print(packet_buffer, 2, &counter, "Payload length");
375
376 next_protocol = protocol_8bit_extract(packet_buffer, counter);
377 field_print(packet_buffer, 1, &counter, "Next header");
378
379 field_print(packet_buffer, 1, &counter, "Hop limit");
380
381 field_print(packet_buffer, 8, &counter, "Source address");
382 field_print(packet_buffer, 8, &counter, "(...)");
383
384 field_print(packet_buffer, 8, &counter, "Destination address");
385 field_print(packet_buffer, 8, &counter, "(...)");
386
387 // print ipv6 extension headers
388 while (1) {
389 switch (next_protocol) {
390
391 case 0: // hop-by-hop options
392 puts("\nIPv6 Hop-by-Hop Options:");
393 goto EXTENSION_HEADER_FIELDS;
394
395 case 43: // routing options
396 puts("\nIPv6 Routing Routing:");
397 goto EXTENSION_HEADER_FIELDS;
398
399 case 44: // fragment options
400 puts("\nIPv6 Fragment Options:");
401 goto EXTENSION_HEADER_FIELDS;
402
403 case 50: // encapsulating security payload
404 puts("\nIPv6 Encapsulating Security Payload:");
405 goto EXTENSION_HEADER_FIELDS;
406
407 case 51: // authentication header
408 puts("\nIPv6 Authentication Header:");
409 goto EXTENSION_HEADER_FIELDS;
410
411 case 60: // destination options
412 puts("\nIPv6 Destination Options:");
413 goto EXTENSION_HEADER_FIELDS;
414
415 case 135: // mobility options
416 puts("\nIPv6 Mobility Options:");
417
418 EXTENSION_HEADER_FIELDS:
419
420 if (size - counter < 8) {
421 puts (" invalid header size");
422 return;
423 }
424
425 next_protocol = protocol_8bit_extract(packet_buffer, counter);
426 field_print(packet_buffer, 1, &counter, "Next header");
427
428 eh_size = protocol_8bit_extract(packet_buffer, counter);
429 eh_size = eh_size * 8;
430 field_print(packet_buffer, 1, &counter, "Extension Header Length");
431
432 field_print(packet_buffer, 6, &counter, "Options");
433
434 if (size - counter < eh_size) {
435 puts (" invalid header size");
436 return;
437 }
438
439 int i;
440 for(i = 0; i < (eh_size/8); i++) {
441 field_print(packet_buffer, 8, &counter, i ? "(...)" : "Extension Header Data");
442 }
443
444 break;
445
446 default: // go up to the next layer
447 layer_4_dispatcher(packet_buffer + counter, size - counter, next_protocol);
448 return;
449
450 }
451 }
452
453 }
454
455 /**
456 * Print the ARP header of the packet
457 *
458 * @param packet_buffer raw packet captured from the network, starting at the part to process
459 * @param size packet_buffer size
460 */
arp_print(const uint8_t * packet_buffer,int size)461 void arp_print (const uint8_t *packet_buffer, int size) {
462 int counter = 0;
463
464 puts("\nARP Header:");
465
466 if (size < 28) {
467 puts (" invalid header size");
468 return;
469 }
470
471 // print header fields
472 field_print(packet_buffer, 2, &counter, "Hardware type");
473 field_print(packet_buffer, 2, &counter, "Protocol type");
474
475 int hs = *(packet_buffer + counter);
476 field_print(packet_buffer, 1, &counter, "Hardware size");
477
478 int ps = *(packet_buffer + counter);
479 field_print(packet_buffer, 1, &counter, "Protocol size");
480
481 field_print(packet_buffer, 2, &counter, "Opcode");
482
483 field_print(packet_buffer, hs, &counter, "Sender hardware address");
484 field_print(packet_buffer, ps, &counter, "Sender protocol address");
485 field_print(packet_buffer, hs, &counter, "Target hardware address");
486 field_print(packet_buffer, ps, &counter, "Target protocol address");
487
488 // print remaining payload
489 payload_print(packet_buffer + counter, size - counter);
490 }
491
492 /**
493 * Print the ETHERNET header of the packet
494 *
495 * @param packet_buffer raw packet captured from the network, starting at the part to process
496 * @param size packet_buffer size
497 */
ethernet_print(const uint8_t * packet_buffer,int size)498 void ethernet_print (const uint8_t *packet_buffer, int size) {
499 int counter = 0;
500
501 puts("\nEthernet Header:");
502
503 if (size < 14) {
504 puts (" invalid header size");
505 return;
506 }
507
508 // print header fields
509 uint64_t dst_mac = protocol_48bit_extract(packet_buffer, counter);
510 field_print(packet_buffer, 6, &counter, "Destination hardware address");
511 field_print(packet_buffer, 6, &counter, "Source hardware address");
512
513 int next_protocol = protocol_16bit_extract(packet_buffer, counter);
514 field_print(packet_buffer, 2, &counter, "Lenght/Type");
515
516 /*
517 * if the last field value is less or equal to 1500 is a lenght
518 * otherwise is a protocol type (check IEEE 802.3 documentation...)
519 */
520
521 if (next_protocol > 1500) {
522
523 // go up to the next layer
524 layer_3_dispatcher(packet_buffer + counter, size - counter, next_protocol);
525
526 } else {
527
528 // remain on the same layer
529 layer_2_dispatcher(packet_buffer + counter, size - counter, dst_mac);
530
531 }
532 }
533
534 /**
535 * Print the ISL header of the packet
536 *
537 * @param packet_buffer raw packet captured from the network, starting at the part to process
538 * @param size packet_buffer size
539 */
isl_print(const uint8_t * packet_buffer,int size)540 void isl_print (const uint8_t *packet_buffer, int size) {
541 int counter = 0;
542
543 puts("\nISL Header:");
544
545 if (size < 30) {
546 puts (" invalid header size");
547 return;
548 }
549
550 // print header fields
551 field_print(packet_buffer, 5, &counter, "Destination");
552
553
554 int next_protocol = protocol_8bit_extract(packet_buffer, counter);
555 next_protocol >>= 4;
556
557 field_print(packet_buffer, 1, &counter, "Type/User");
558 field_print(packet_buffer, 6, &counter, "Source");
559 field_print(packet_buffer, 2, &counter, "Length");
560 field_print(packet_buffer, 1, &counter, "DSAP");
561 field_print(packet_buffer, 1, &counter, "SSAP");
562 field_print(packet_buffer, 1, &counter, "Control");
563 field_print(packet_buffer, 3, &counter, "HSA");
564 field_print(packet_buffer, 2, &counter, "Vlan ID/BPDU");
565 field_print(packet_buffer, 2, &counter, "Index");
566 field_print(packet_buffer, 2, &counter, "RES");
567
568 /*
569 * Note: we subtrack 4 to the size of the packet to exclude
570 * the final frame check sequence
571 */
572
573 if (next_protocol == 0) {
574
575 // go up to the next layer
576 ethernet_print(packet_buffer + counter, size - counter - 4);
577
578 } else {
579
580 // go up to the next layer
581 payload_print(packet_buffer + counter, size - counter - 4);
582
583 }
584
585 counter = size - 4;
586
587 puts("\nISL Header (end):");
588
589 field_print(packet_buffer, 4, &counter, "Frame check seq.");
590 }
591
592 /**
593 * Print the DTP header of the packet
594 *
595 * @param packet_buffer raw packet captured from the network, starting at the part to process
596 * @param size packet_buffer size
597 */
dtp_print(const uint8_t * packet_buffer,int size)598 void dtp_print (const uint8_t *packet_buffer, int size) {
599 int counter = 0;
600
601 puts("\nDinamic Trunking Protocol Header:");
602
603 if (size < 29) {
604 puts (" invalid header size");
605 return;
606 }
607
608 // print header fields
609 field_print(packet_buffer, 1, &counter, "Version");
610 field_print(packet_buffer, 8, &counter, "Domain");
611
612 field_print(packet_buffer, 5, &counter, "Status");
613 field_print(packet_buffer, 5, &counter, "DTP Type");
614
615 field_print(packet_buffer, 8, &counter, "Neighbor");
616 field_print(packet_buffer, 2, &counter, ""); // splitted since too long...
617
618 // print remaining payload
619 payload_print(packet_buffer + counter, size - counter);
620 }
621
622 /**
623 * Print the STP header of the packet
624 *
625 * @param packet_buffer raw packet captured from the network, starting at the part to process
626 * @param size packet_buffer size
627 */
stp_print(const uint8_t * packet_buffer,int size)628 void stp_print (const uint8_t *packet_buffer, int size) {
629 int counter = 0;
630
631 puts("\nSpanning Tree Protocol Header:");
632
633 if (size < 35) {
634 puts (" invalid header size");
635 return;
636 }
637
638 // print header fields
639 field_print(packet_buffer, 2, &counter, "Protocol Identifier");
640 field_print(packet_buffer, 1, &counter, "Protocol Version Identifier");
641
642 field_print(packet_buffer, 1, &counter, "BPDU Type");
643 field_print(packet_buffer, 1, &counter, "BPDU Flags");
644
645 field_print(packet_buffer, 2, &counter, "Root Priority/System ID Extension");
646 field_print(packet_buffer, 6, &counter, "Root System ID");
647
648 field_print(packet_buffer, 4, &counter, "Root Path Cost");
649
650 field_print(packet_buffer, 2, &counter, "Bridge Priority/System ID Extension");
651 field_print(packet_buffer, 6, &counter, "Bridge System ID");
652
653 field_print(packet_buffer, 2, &counter, "Port Identifier");
654 field_print(packet_buffer, 2, &counter, "Message Age");
655 field_print(packet_buffer, 2, &counter, "Max Age");
656 field_print(packet_buffer, 2, &counter, "Hello Time");
657 field_print(packet_buffer, 2, &counter, "Forward Delay");
658
659 // print remaining payload
660 payload_print(packet_buffer + counter, size - counter);
661 }
662
663 /**
664 * Print the LLC header of the packet
665 *
666 * @param packet_buffer raw packet captured from the network, starting at the part to process
667 * @param size packet_buffer size
668 */
llc_print(const uint8_t * packet_buffer,int size)669 void llc_print (const uint8_t *packet_buffer, int size) {
670 int counter = 0;
671
672 puts("\nLogical-Link Control Header:");
673
674 if (size < 3) {
675 puts (" invalid header size");
676 return;
677 }
678
679 // print header fields
680 int dsap = protocol_8bit_extract(packet_buffer, counter);
681 field_print(packet_buffer, 1, &counter, "DSAP");
682
683 int ssap = protocol_8bit_extract(packet_buffer, counter);
684 field_print(packet_buffer, 1, &counter, "SSAP");
685
686 field_print(packet_buffer, 1, &counter, "Control field");
687
688 if (dsap == 0x42 && ssap == 0x42) {
689
690 // spanning tree protocol
691 stp_print(packet_buffer + counter, size - counter);
692
693 } else if (dsap == 0xaa && ssap == 0xaa) {
694
695 if (size < 8) {
696 puts (" invalid header size");
697 return;
698 }
699
700 // continue printing LLC fields
701 field_print(packet_buffer, 3, &counter, "Organization code");
702
703 int pid = protocol_16bit_extract(packet_buffer, counter);
704 field_print(packet_buffer, 2, &counter, "PID");
705
706 if (pid == 0x2004) {
707
708 // dinamic trunking protocol
709 dtp_print(packet_buffer + counter, size - counter);
710
711 } else {
712
713 // print remaining payload
714 payload_print(packet_buffer + counter, size - counter);
715
716 }
717
718 }
719
720 }
721
722 /**
723 * Determine the packet type and call the appropriate function to disassemble it.
724 * Operates on layer 2 (OSI model) packet's headers.
725 *
726 * @param packet_buffer raw packet captured from the network, starting at layer 2
727 * @param size packet_buffer size
728 * @param protocol protocol number
729 */
layer_2_dispatcher(const uint8_t * packet_buffer,int size,uint64_t protocol)730 void layer_2_dispatcher (const uint8_t *packet_buffer, int size, uint64_t protocol) {
731
732 uint64_t llc1 = 0x0180C20000LLU, llc2 = 0x01000CCCCCCCLLU;
733
734 if (size < 1) {
735 return;
736 }
737
738 if (memcmp(packet_buffer, "\x01\x00\x0C\x00\x00", 5)==0 ||
739 memcmp(packet_buffer, "\x03\x00\x0c\x00\x00", 5)==0 ) {
740
741 isl_print(packet_buffer, size);
742
743 } else if ((protocol / 256) == llc1) {
744
745 llc_print(packet_buffer, size); // spanning tree
746
747 } else if (protocol == llc2) {
748
749 llc_print(packet_buffer, size);
750
751 } else {
752
753 ethernet_print(packet_buffer, size);
754
755 }
756
757 }
758
759 /**
760 * Determine the packet type and call the appropriate function to disassemble it.
761 * Operates on layer 3 (OSI model) packet's headers.
762 *
763 * @param packet_buffer raw packet captured from the network, starting at layer 3
764 * @param size packet_buffer size
765 * @param protocol protocol number
766 */
layer_3_dispatcher(const uint8_t * packet_buffer,int size,uint64_t protocol)767 void layer_3_dispatcher (const uint8_t *packet_buffer, int size, uint64_t protocol) {
768
769 if (size < 1) {
770 return;
771 }
772
773 /*
774 * if the last field value (of an ethernet header) is less or equal to 1500
775 * then is a lenght otherwise is a protocol type (check IEEE 802.3 documentation...)
776 */
777
778 if (protocol <= 0xffff) { // check if it's a 16bit field
779 // (i.e. last ethernet field was a protocol)
780 switch (protocol) {
781
782 case 0x0800: ip_print(packet_buffer, size); break;
783 case 0x0806: arp_print(packet_buffer, size); break;
784 case 0x86dd: ipv6_print(packet_buffer, size); break;
785
786 default: payload_print(packet_buffer, size);
787
788 }
789
790 } else {
791 payload_print(packet_buffer, size);
792 }
793
794 }
795
796 /**
797 * Determine the packet type and call the appropriate function to disassemble it.
798 * Operates on layer 4 (OSI model) packet's headers.
799 *
800 * @param packet_buffer raw packet captured from the network, starting at layer 4
801 * @param size packet_buffer size
802 * @param protocol protocol number
803 */
layer_4_dispatcher(const uint8_t * packet_buffer,int size,uint64_t protocol)804 void layer_4_dispatcher (const uint8_t *packet_buffer, int size, uint64_t protocol) {
805
806 if (size < 1) {
807 return;
808 }
809
810 switch (protocol) {
811 case 0x01: icmp_print(packet_buffer, size); break;
812 case 0x02: igmp_print(packet_buffer, size); break;
813 case 0x04: ip_print(packet_buffer, size); break;
814 case 0x06: tcp_print(packet_buffer, size); break;
815 case 0x11: udp_print(packet_buffer, size); break;
816 case 0x29: ipv6_print(packet_buffer, size); break;
817 case 0x3A: icmp6_print(packet_buffer, size); break;
818 default: payload_print(packet_buffer, size);
819 }
820
821 }
822
823
824 #endif /* __PRETTYPACKET_H__ */
825
826