1235427Sdelphij/*
2235427Sdelphij * Oracle
3235427Sdelphij */
4235427Sdelphij#ifdef HAVE_CONFIG_H
5235427Sdelphij#include "config.h"
6235427Sdelphij#endif
7235427Sdelphij
8235427Sdelphij#include <tcpdump-stdinc.h>
9235427Sdelphij
10235427Sdelphij#include <stdio.h>
11235427Sdelphij#include <pcap.h>
12235427Sdelphij
13235427Sdelphij#include "netdissect.h"
14235427Sdelphij#include "interface.h"
15235427Sdelphij#include "extract.h"
16235427Sdelphij#include "ppi.h"
17235427Sdelphij
18235427Sdelphij#ifdef DLT_PPI
19235427Sdelphij
20235427Sdelphijstatic inline void
21235427Sdelphijppi_header_print(struct netdissect_options *ndo, const u_char *bp, u_int length)
22235427Sdelphij{
23235427Sdelphij	const ppi_header_t *hdr;
24235427Sdelphij	u_int32_t dlt;
25235427Sdelphij	u_int16_t len;
26235427Sdelphij
27235427Sdelphij	hdr = (const ppi_header_t *)bp;
28235427Sdelphij
29235427Sdelphij	len = EXTRACT_16BITS(&hdr->ppi_len);
30235427Sdelphij	dlt = EXTRACT_32BITS(&hdr->ppi_dlt);
31235427Sdelphij
32235427Sdelphij	if (!ndo->ndo_qflag) {
33235427Sdelphij		ND_PRINT((ndo,", V.%d DLT %s (%d) len %d", hdr->ppi_ver,
34235427Sdelphij			  pcap_datalink_val_to_name(dlt), dlt,
35235427Sdelphij                          len));
36235427Sdelphij        } else {
37235427Sdelphij		ND_PRINT((ndo,", %s", pcap_datalink_val_to_name(dlt)));
38235427Sdelphij        }
39235427Sdelphij
40235427Sdelphij	ND_PRINT((ndo, ", length %u: ", length));
41235427Sdelphij}
42235427Sdelphij
43235427Sdelphijstatic void
44235427Sdelphijppi_print(struct netdissect_options *ndo,
45235427Sdelphij               const struct pcap_pkthdr *h, const u_char *p)
46235427Sdelphij{
47235427Sdelphij	if_ndo_printer ndo_printer;
48235427Sdelphij        if_printer printer;
49235427Sdelphij	ppi_header_t *hdr;
50235427Sdelphij	u_int caplen = h->caplen;
51235427Sdelphij	u_int length = h->len;
52235427Sdelphij	u_int32_t dlt;
53235427Sdelphij
54235427Sdelphij	if (caplen < sizeof(ppi_header_t)) {
55235427Sdelphij		ND_PRINT((ndo, "[|ppi]"));
56235427Sdelphij		return;
57235427Sdelphij	}
58235427Sdelphij	hdr = (ppi_header_t *)p;
59235427Sdelphij	dlt = EXTRACT_32BITS(&hdr->ppi_dlt);
60235427Sdelphij
61235427Sdelphij	if (ndo->ndo_eflag)
62235427Sdelphij		ppi_header_print(ndo, p, length);
63235427Sdelphij
64235427Sdelphij	length -= sizeof(ppi_header_t);
65235427Sdelphij	caplen -= sizeof(ppi_header_t);
66235427Sdelphij	p += sizeof(ppi_header_t);
67235427Sdelphij
68235427Sdelphij	if ((printer = lookup_printer(dlt)) != NULL) {
69235427Sdelphij		printer(h, p);
70235427Sdelphij	} else if ((ndo_printer = lookup_ndo_printer(dlt)) != NULL) {
71235427Sdelphij		ndo_printer(ndo, h, p);
72235427Sdelphij	} else {
73235427Sdelphij		if (!ndo->ndo_eflag)
74235427Sdelphij			ppi_header_print(ndo, (u_char *)hdr,
75235427Sdelphij					length + sizeof(ppi_header_t));
76235427Sdelphij
77235427Sdelphij		if (!ndo->ndo_suppress_default_print)
78235427Sdelphij			ndo->ndo_default_print(ndo, p, caplen);
79235427Sdelphij	}
80235427Sdelphij}
81235427Sdelphij
82235427Sdelphij/*
83235427Sdelphij * This is the top level routine of the printer.  'p' points
84235427Sdelphij * to the ether header of the packet, 'h->ts' is the timestamp,
85235427Sdelphij * 'h->len' is the length of the packet off the wire, and 'h->caplen'
86235427Sdelphij * is the number of bytes actually captured.
87235427Sdelphij */
88235427Sdelphiju_int
89235427Sdelphijppi_if_print(struct netdissect_options *ndo,
90235427Sdelphij               const struct pcap_pkthdr *h, const u_char *p)
91235427Sdelphij{
92235427Sdelphij	ppi_print(ndo, h, p);
93235427Sdelphij
94235427Sdelphij	return (sizeof(ppi_header_t));
95235427Sdelphij}
96235427Sdelphij
97235427Sdelphij/*
98235427Sdelphij * Local Variables:
99235427Sdelphij * c-style: whitesmith
100235427Sdelphij * c-basic-offset: 8
101235427Sdelphij * End:
102235427Sdelphij */
103235427Sdelphij
104235427Sdelphij#endif /* DLT_PPI */
105