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