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