xref: /dflybsd-src/contrib/tcpdump/print-ppi.c (revision 59c07fbdf8168fa08c76c515186d561b5a92690c)
127bfbee1SPeter Avalos /*
227bfbee1SPeter Avalos  * Oracle
327bfbee1SPeter Avalos  */
4411677aeSAaron LI 
5*ed775ee7SAntonio Huete Jimenez /* \summary: Per-Packet Information (DLT_PPI) printer */
6*ed775ee7SAntonio Huete Jimenez 
7*ed775ee7SAntonio Huete Jimenez /* Specification:
8*ed775ee7SAntonio Huete Jimenez  * Per-Packet Information Header Specification - Version 1.0.7
9*ed775ee7SAntonio Huete Jimenez  * https://web.archive.org/web/20160328114748/http://www.cacetech.com/documents/PPI%20Header%20format%201.0.7.pdf
10*ed775ee7SAntonio Huete Jimenez  */
11411677aeSAaron LI 
1227bfbee1SPeter Avalos #ifdef HAVE_CONFIG_H
13*ed775ee7SAntonio Huete Jimenez #include <config.h>
1427bfbee1SPeter Avalos #endif
1527bfbee1SPeter Avalos 
16*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
1727bfbee1SPeter Avalos 
1827bfbee1SPeter Avalos #include "netdissect.h"
1927bfbee1SPeter Avalos #include "extract.h"
20411677aeSAaron LI 
21*ed775ee7SAntonio Huete Jimenez 
22411677aeSAaron LI typedef struct ppi_header {
23*ed775ee7SAntonio Huete Jimenez 	nd_uint8_t	ppi_ver;	/* Version.  Currently 0 */
24*ed775ee7SAntonio Huete Jimenez 	nd_uint8_t	ppi_flags;	/* Flags. */
25*ed775ee7SAntonio Huete Jimenez 	nd_uint16_t	ppi_len;	/* Length of entire message, including
26*ed775ee7SAntonio Huete Jimenez 					 * this header and TLV payload. */
27*ed775ee7SAntonio Huete Jimenez 	nd_uint32_t	ppi_dlt;	/* Data Link Type of the captured
28*ed775ee7SAntonio Huete Jimenez 					 * packet data. */
29411677aeSAaron LI } ppi_header_t;
30411677aeSAaron LI 
31411677aeSAaron LI #define	PPI_HDRLEN	8
3227bfbee1SPeter Avalos 
3327bfbee1SPeter Avalos #ifdef DLT_PPI
3427bfbee1SPeter Avalos 
35*ed775ee7SAntonio Huete Jimenez static void
ppi_header_print(netdissect_options * ndo,const u_char * bp,u_int length)36411677aeSAaron LI ppi_header_print(netdissect_options *ndo, const u_char *bp, u_int length)
3727bfbee1SPeter Avalos {
3827bfbee1SPeter Avalos 	const ppi_header_t *hdr;
39411677aeSAaron LI 	uint16_t len;
40411677aeSAaron LI 	uint32_t dlt;
41411677aeSAaron LI 	const char *dltname;
4227bfbee1SPeter Avalos 
4327bfbee1SPeter Avalos 	hdr = (const ppi_header_t *)bp;
4427bfbee1SPeter Avalos 
45*ed775ee7SAntonio Huete Jimenez 	len = GET_LE_U_2(hdr->ppi_len);
46*ed775ee7SAntonio Huete Jimenez 	dlt = GET_LE_U_4(hdr->ppi_dlt);
47411677aeSAaron LI 	dltname = pcap_datalink_val_to_name(dlt);
4827bfbee1SPeter Avalos 
4927bfbee1SPeter Avalos 	if (!ndo->ndo_qflag) {
50*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("V.%u DLT %s (%u) len %u", GET_U_1(hdr->ppi_ver),
51411677aeSAaron LI 			  (dltname != NULL ? dltname : "UNKNOWN"), dlt,
52*ed775ee7SAntonio Huete Jimenez                           len);
5327bfbee1SPeter Avalos         } else {
54*ed775ee7SAntonio Huete Jimenez 		ND_PRINT("%s", (dltname != NULL ? dltname : "UNKNOWN"));
5527bfbee1SPeter Avalos         }
5627bfbee1SPeter Avalos 
57*ed775ee7SAntonio Huete Jimenez 	ND_PRINT(", length %u: ", length);
5827bfbee1SPeter Avalos }
5927bfbee1SPeter Avalos 
60*ed775ee7SAntonio Huete Jimenez /*
61*ed775ee7SAntonio Huete Jimenez  * This is the top level routine of the printer.  'p' points
62*ed775ee7SAntonio Huete Jimenez  * to the ether header of the packet, 'h->ts' is the timestamp,
63*ed775ee7SAntonio Huete Jimenez  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
64*ed775ee7SAntonio Huete Jimenez  * is the number of bytes actually captured.
65*ed775ee7SAntonio Huete Jimenez  */
66*ed775ee7SAntonio Huete Jimenez void
ppi_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)67*ed775ee7SAntonio Huete Jimenez ppi_if_print(netdissect_options *ndo,
6827bfbee1SPeter Avalos 	     const struct pcap_pkthdr *h, const u_char *p)
6927bfbee1SPeter Avalos {
7027bfbee1SPeter Avalos 	if_printer printer;
71411677aeSAaron LI 	const ppi_header_t *hdr;
7227bfbee1SPeter Avalos 	u_int caplen = h->caplen;
7327bfbee1SPeter Avalos 	u_int length = h->len;
74411677aeSAaron LI 	uint16_t len;
75411677aeSAaron LI 	uint32_t dlt;
76411677aeSAaron LI 	uint32_t hdrlen;
77411677aeSAaron LI 	struct pcap_pkthdr nhdr;
7827bfbee1SPeter Avalos 
79*ed775ee7SAntonio Huete Jimenez 	ndo->ndo_protocol = "ppi";
8027bfbee1SPeter Avalos 	if (caplen < sizeof(ppi_header_t)) {
81*ed775ee7SAntonio Huete Jimenez 		nd_print_trunc(ndo);
82*ed775ee7SAntonio Huete Jimenez 		ndo->ndo_ll_hdr_len += caplen;
83*ed775ee7SAntonio Huete Jimenez 		return;
8427bfbee1SPeter Avalos 	}
85411677aeSAaron LI 
86411677aeSAaron LI 	hdr = (const ppi_header_t *)p;
87*ed775ee7SAntonio Huete Jimenez 	len = GET_LE_U_2(hdr->ppi_len);
88*ed775ee7SAntonio Huete Jimenez 	if (len < sizeof(ppi_header_t) || len > 65532) {
89*ed775ee7SAntonio Huete Jimenez 		/* It MUST be between 8 and 65,532 inclusive (spec 3.1.3) */
90*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" [length %u < %zu or > 65532]", len,
91*ed775ee7SAntonio Huete Jimenez 			 sizeof(ppi_header_t));
92*ed775ee7SAntonio Huete Jimenez 		nd_print_invalid(ndo);
93*ed775ee7SAntonio Huete Jimenez 		ndo->ndo_ll_hdr_len += caplen;
94*ed775ee7SAntonio Huete Jimenez 		return;
95*ed775ee7SAntonio Huete Jimenez 	}
96411677aeSAaron LI 	if (caplen < len) {
97411677aeSAaron LI 		/*
98411677aeSAaron LI 		 * If we don't have the entire PPI header, don't
99411677aeSAaron LI 		 * bother.
100411677aeSAaron LI 		 */
101*ed775ee7SAntonio Huete Jimenez 		nd_print_trunc(ndo);
102*ed775ee7SAntonio Huete Jimenez 		ndo->ndo_ll_hdr_len += caplen;
103*ed775ee7SAntonio Huete Jimenez 		return;
104411677aeSAaron LI 	}
105*ed775ee7SAntonio Huete Jimenez 	dlt = GET_LE_U_4(hdr->ppi_dlt);
10627bfbee1SPeter Avalos 
10727bfbee1SPeter Avalos 	if (ndo->ndo_eflag)
10827bfbee1SPeter Avalos 		ppi_header_print(ndo, p, length);
10927bfbee1SPeter Avalos 
110411677aeSAaron LI 	length -= len;
111411677aeSAaron LI 	caplen -= len;
112411677aeSAaron LI 	p += len;
11327bfbee1SPeter Avalos 
114*ed775ee7SAntonio Huete Jimenez 	printer = lookup_printer(dlt);
115*ed775ee7SAntonio Huete Jimenez 	if (printer != NULL) {
116411677aeSAaron LI 		nhdr = *h;
117411677aeSAaron LI 		nhdr.caplen = caplen;
118411677aeSAaron LI 		nhdr.len = length;
119*ed775ee7SAntonio Huete Jimenez 		printer(ndo, &nhdr, p);
120*ed775ee7SAntonio Huete Jimenez 		hdrlen = ndo->ndo_ll_hdr_len;
12127bfbee1SPeter Avalos 	} else {
12227bfbee1SPeter Avalos 		if (!ndo->ndo_eflag)
123411677aeSAaron LI 			ppi_header_print(ndo, (const u_char *)hdr, length + len);
12427bfbee1SPeter Avalos 
12527bfbee1SPeter Avalos 		if (!ndo->ndo_suppress_default_print)
126411677aeSAaron LI 			ND_DEFAULTPRINT(p, caplen);
127411677aeSAaron LI 		hdrlen = 0;
12827bfbee1SPeter Avalos 	}
129*ed775ee7SAntonio Huete Jimenez 	ndo->ndo_ll_hdr_len += len + hdrlen;
13027bfbee1SPeter Avalos }
13127bfbee1SPeter Avalos #endif /* DLT_PPI */
132