print-ppi.c revision 1.5
1/* 2 * Oracle 3 */ 4 5#include <sys/cdefs.h> 6#ifndef lint 7__RCSID("$NetBSD: print-ppi.c,v 1.5 2023/08/17 20:19:40 christos Exp $"); 8#endif 9 10/* \summary: Per-Packet Information (DLT_PPI) printer */ 11 12/* Specification: 13 * Per-Packet Information Header Specification - Version 1.0.7 14 * https://web.archive.org/web/20160328114748/http://www.cacetech.com/documents/PPI%20Header%20format%201.0.7.pdf 15 */ 16 17#ifdef HAVE_CONFIG_H 18#include <config.h> 19#endif 20 21#include "netdissect-stdinc.h" 22 23#include "netdissect.h" 24#include "extract.h" 25 26 27typedef struct ppi_header { 28 nd_uint8_t ppi_ver; /* Version. Currently 0 */ 29 nd_uint8_t ppi_flags; /* Flags. */ 30 nd_uint16_t ppi_len; /* Length of entire message, including 31 * this header and TLV payload. */ 32 nd_uint32_t ppi_dlt; /* Data Link Type of the captured 33 * packet data. */ 34} ppi_header_t; 35 36#define PPI_HDRLEN 8 37 38#ifdef DLT_PPI 39 40static void 41ppi_header_print(netdissect_options *ndo, const u_char *bp, u_int length) 42{ 43 const ppi_header_t *hdr; 44 uint16_t len; 45 uint32_t dlt; 46 const char *dltname; 47 48 hdr = (const ppi_header_t *)bp; 49 50 len = GET_LE_U_2(hdr->ppi_len); 51 dlt = GET_LE_U_4(hdr->ppi_dlt); 52 dltname = pcap_datalink_val_to_name(dlt); 53 54 if (!ndo->ndo_qflag) { 55 ND_PRINT("V.%u DLT %s (%u) len %u", GET_U_1(hdr->ppi_ver), 56 (dltname != NULL ? dltname : "UNKNOWN"), dlt, 57 len); 58 } else { 59 ND_PRINT("%s", (dltname != NULL ? dltname : "UNKNOWN")); 60 } 61 62 ND_PRINT(", length %u: ", length); 63} 64 65/* 66 * This is the top level routine of the printer. 'p' points 67 * to the ether header of the packet, 'h->ts' is the timestamp, 68 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 69 * is the number of bytes actually captured. 70 */ 71void 72ppi_if_print(netdissect_options *ndo, 73 const struct pcap_pkthdr *h, const u_char *p) 74{ 75 if_printer printer; 76 const ppi_header_t *hdr; 77 u_int caplen = h->caplen; 78 u_int length = h->len; 79 uint16_t len; 80 uint32_t dlt; 81 uint32_t hdrlen; 82 struct pcap_pkthdr nhdr; 83 84 ndo->ndo_protocol = "ppi"; 85 if (caplen < sizeof(ppi_header_t)) { 86 nd_print_trunc(ndo); 87 ndo->ndo_ll_hdr_len += caplen; 88 return; 89 } 90 91 hdr = (const ppi_header_t *)p; 92 len = GET_LE_U_2(hdr->ppi_len); 93 if (len < sizeof(ppi_header_t) || len > 65532) { 94 /* It MUST be between 8 and 65,532 inclusive (spec 3.1.3) */ 95 ND_PRINT(" [length %u < %zu or > 65532]", len, 96 sizeof(ppi_header_t)); 97 nd_print_invalid(ndo); 98 ndo->ndo_ll_hdr_len += caplen; 99 return; 100 } 101 if (caplen < len) { 102 /* 103 * If we don't have the entire PPI header, don't 104 * bother. 105 */ 106 nd_print_trunc(ndo); 107 ndo->ndo_ll_hdr_len += caplen; 108 return; 109 } 110 dlt = GET_LE_U_4(hdr->ppi_dlt); 111 112 if (ndo->ndo_eflag) 113 ppi_header_print(ndo, p, length); 114 115 length -= len; 116 caplen -= len; 117 p += len; 118 119 printer = lookup_printer(dlt); 120 if (printer != NULL) { 121 nhdr = *h; 122 nhdr.caplen = caplen; 123 nhdr.len = length; 124 printer(ndo, &nhdr, p); 125 hdrlen = ndo->ndo_ll_hdr_len; 126 } else { 127 if (!ndo->ndo_eflag) 128 ppi_header_print(ndo, (const u_char *)hdr, length + len); 129 130 if (!ndo->ndo_suppress_default_print) 131 ND_DEFAULTPRINT(p, caplen); 132 hdrlen = 0; 133 } 134 ndo->ndo_ll_hdr_len += len + hdrlen; 135} 136#endif /* DLT_PPI */ 137