xref: /freebsd/contrib/tcpdump/print-ppi.c (revision 3340d77368116708ab5b5b95acf6c9c710528300)
1cac3dcd5SXin LI /*
2cac3dcd5SXin LI  * Oracle
3cac3dcd5SXin LI  */
4*3340d773SGleb Smirnoff 
5*3340d773SGleb Smirnoff /* \summary: Oracle DLT_PPI printer */
6*3340d773SGleb Smirnoff 
7cac3dcd5SXin LI #ifdef HAVE_CONFIG_H
8cac3dcd5SXin LI #include "config.h"
9cac3dcd5SXin LI #endif
10cac3dcd5SXin LI 
11*3340d773SGleb Smirnoff #include <netdissect-stdinc.h>
12cac3dcd5SXin LI 
13*3340d773SGleb Smirnoff #include "netdissect.h"
14cac3dcd5SXin LI #include "extract.h"
153c602fabSXin LI 
163c602fabSXin LI typedef struct ppi_header {
173c602fabSXin LI 	uint8_t		ppi_ver;
183c602fabSXin LI 	uint8_t		ppi_flags;
193c602fabSXin LI 	uint16_t	ppi_len;
203c602fabSXin LI 	uint32_t	ppi_dlt;
213c602fabSXin LI } ppi_header_t;
223c602fabSXin LI 
233c602fabSXin LI #define	PPI_HDRLEN	8
24cac3dcd5SXin LI 
25cac3dcd5SXin LI #ifdef DLT_PPI
26cac3dcd5SXin LI 
27cac3dcd5SXin LI static inline void
283c602fabSXin LI ppi_header_print(netdissect_options *ndo, const u_char *bp, u_int length)
29cac3dcd5SXin LI {
30cac3dcd5SXin LI 	const ppi_header_t *hdr;
313c602fabSXin LI 	uint16_t len;
328bdc5a62SPatrick Kelsey 	uint32_t dlt;
33*3340d773SGleb Smirnoff 	const char *dltname;
34cac3dcd5SXin LI 
35cac3dcd5SXin LI 	hdr = (const ppi_header_t *)bp;
36cac3dcd5SXin LI 
373c602fabSXin LI 	len = EXTRACT_LE_16BITS(&hdr->ppi_len);
383c602fabSXin LI 	dlt = EXTRACT_LE_32BITS(&hdr->ppi_dlt);
39*3340d773SGleb Smirnoff 	dltname = pcap_datalink_val_to_name(dlt);
40cac3dcd5SXin LI 
41cac3dcd5SXin LI 	if (!ndo->ndo_qflag) {
428bdc5a62SPatrick Kelsey 		ND_PRINT((ndo, "V.%d DLT %s (%d) len %d", hdr->ppi_ver,
43*3340d773SGleb Smirnoff 			  (dltname != NULL ? dltname : "UNKNOWN"), dlt,
44cac3dcd5SXin LI                           len));
45cac3dcd5SXin LI         } else {
46*3340d773SGleb Smirnoff 		ND_PRINT((ndo, "%s", (dltname != NULL ? dltname : "UNKNOWN")));
47cac3dcd5SXin LI         }
48cac3dcd5SXin LI 
49cac3dcd5SXin LI 	ND_PRINT((ndo, ", length %u: ", length));
50cac3dcd5SXin LI }
51cac3dcd5SXin LI 
52*3340d773SGleb Smirnoff static u_int
533c602fabSXin LI ppi_print(netdissect_options *ndo,
54cac3dcd5SXin LI                const struct pcap_pkthdr *h, const u_char *p)
55cac3dcd5SXin LI {
56cac3dcd5SXin LI 	if_printer printer;
57*3340d773SGleb Smirnoff 	const ppi_header_t *hdr;
58cac3dcd5SXin LI 	u_int caplen = h->caplen;
59cac3dcd5SXin LI 	u_int length = h->len;
608bdc5a62SPatrick Kelsey 	uint16_t len;
613c602fabSXin LI 	uint32_t dlt;
62*3340d773SGleb Smirnoff 	uint32_t hdrlen;
63*3340d773SGleb Smirnoff 	struct pcap_pkthdr nhdr;
64cac3dcd5SXin LI 
65cac3dcd5SXin LI 	if (caplen < sizeof(ppi_header_t)) {
66cac3dcd5SXin LI 		ND_PRINT((ndo, "[|ppi]"));
67*3340d773SGleb Smirnoff 		return (caplen);
68cac3dcd5SXin LI 	}
698bdc5a62SPatrick Kelsey 
70*3340d773SGleb Smirnoff 	hdr = (const ppi_header_t *)p;
718bdc5a62SPatrick Kelsey 	len = EXTRACT_LE_16BITS(&hdr->ppi_len);
72*3340d773SGleb Smirnoff 	if (caplen < len) {
73*3340d773SGleb Smirnoff 		/*
74*3340d773SGleb Smirnoff 		 * If we don't have the entire PPI header, don't
75*3340d773SGleb Smirnoff 		 * bother.
76*3340d773SGleb Smirnoff 		 */
77*3340d773SGleb Smirnoff 		ND_PRINT((ndo, "[|ppi]"));
78*3340d773SGleb Smirnoff 		return (caplen);
79*3340d773SGleb Smirnoff 	}
808bdc5a62SPatrick Kelsey 	if (len < sizeof(ppi_header_t)) {
818bdc5a62SPatrick Kelsey 		ND_PRINT((ndo, "[|ppi]"));
82*3340d773SGleb Smirnoff 		return (len);
838bdc5a62SPatrick Kelsey 	}
843c602fabSXin LI 	dlt = EXTRACT_LE_32BITS(&hdr->ppi_dlt);
85cac3dcd5SXin LI 
86cac3dcd5SXin LI 	if (ndo->ndo_eflag)
87cac3dcd5SXin LI 		ppi_header_print(ndo, p, length);
88cac3dcd5SXin LI 
898bdc5a62SPatrick Kelsey 	length -= len;
908bdc5a62SPatrick Kelsey 	caplen -= len;
918bdc5a62SPatrick Kelsey 	p += len;
92cac3dcd5SXin LI 
93cac3dcd5SXin LI 	if ((printer = lookup_printer(dlt)) != NULL) {
94*3340d773SGleb Smirnoff 		nhdr = *h;
95*3340d773SGleb Smirnoff 		nhdr.caplen = caplen;
96*3340d773SGleb Smirnoff 		nhdr.len = length;
97*3340d773SGleb Smirnoff 		hdrlen = printer(ndo, &nhdr, p);
98cac3dcd5SXin LI 	} else {
99cac3dcd5SXin LI 		if (!ndo->ndo_eflag)
100*3340d773SGleb Smirnoff 			ppi_header_print(ndo, (const u_char *)hdr, length + len);
101cac3dcd5SXin LI 
102cac3dcd5SXin LI 		if (!ndo->ndo_suppress_default_print)
1033c602fabSXin LI 			ND_DEFAULTPRINT(p, caplen);
104*3340d773SGleb Smirnoff 		hdrlen = 0;
105cac3dcd5SXin LI 	}
106*3340d773SGleb Smirnoff 	return (len + hdrlen);
107cac3dcd5SXin LI }
108cac3dcd5SXin LI 
109cac3dcd5SXin LI /*
110cac3dcd5SXin LI  * This is the top level routine of the printer.  'p' points
111cac3dcd5SXin LI  * to the ether header of the packet, 'h->ts' is the timestamp,
112cac3dcd5SXin LI  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
113cac3dcd5SXin LI  * is the number of bytes actually captured.
114cac3dcd5SXin LI  */
115cac3dcd5SXin LI u_int
1163c602fabSXin LI ppi_if_print(netdissect_options *ndo,
117cac3dcd5SXin LI                const struct pcap_pkthdr *h, const u_char *p)
118cac3dcd5SXin LI {
119*3340d773SGleb Smirnoff 	return (ppi_print(ndo, h, p));
120cac3dcd5SXin LI }
121cac3dcd5SXin LI 
122cac3dcd5SXin LI /*
123cac3dcd5SXin LI  * Local Variables:
124cac3dcd5SXin LI  * c-style: whitesmith
125cac3dcd5SXin LI  * c-basic-offset: 8
126cac3dcd5SXin LI  * End:
127cac3dcd5SXin LI  */
128cac3dcd5SXin LI 
129cac3dcd5SXin LI #endif /* DLT_PPI */
130