1313537Sglebius/* \summary: Solaris DLT_IPNET printer */
2313537Sglebius
3214456Srpaulo#ifdef HAVE_CONFIG_H
4214456Srpaulo#include "config.h"
5214456Srpaulo#endif
6214456Srpaulo
7313537Sglebius#include <netdissect-stdinc.h>
8214456Srpaulo
9313537Sglebius#include "netdissect.h"
10356341Scy#include "extract.h"
11214456Srpaulo
12356341Scystatic const char tstr[] = "[|ipnet]";
13356341Scy
14276788Sdelphijtypedef struct ipnet_hdr {
15356341Scy	nd_uint8_t	iph_version;
16356341Scy	nd_uint8_t	iph_family;
17356341Scy	nd_uint16_t	iph_htype;
18356341Scy	nd_uint32_t	iph_pktlen;
19356341Scy	nd_uint32_t	iph_ifindex;
20356341Scy	nd_uint32_t	iph_grifindex;
21356341Scy	nd_uint32_t	iph_zsrc;
22356341Scy	nd_uint32_t	iph_zdst;
23276788Sdelphij} ipnet_hdr_t;
24276788Sdelphij
25276788Sdelphij#define	IPH_AF_INET	2		/* Matches Solaris's AF_INET */
26276788Sdelphij#define	IPH_AF_INET6	26		/* Matches Solaris's AF_INET6 */
27276788Sdelphij
28214456Srpaulo#ifdef DLT_IPNET
29214456Srpaulo
30276788Sdelphijstatic const struct tok ipnet_values[] = {
31214456Srpaulo	{ IPH_AF_INET,		"IPv4" },
32214456Srpaulo	{ IPH_AF_INET6,		"IPv6" },
33214456Srpaulo	{ 0,			NULL }
34214456Srpaulo};
35214456Srpaulo
36214456Srpaulostatic inline void
37276788Sdelphijipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length)
38214456Srpaulo{
39214456Srpaulo	const ipnet_hdr_t *hdr;
40214456Srpaulo	hdr = (const ipnet_hdr_t *)bp;
41214456Srpaulo
42356341Scy	ND_TCHECK(*hdr);
43356341Scy	ND_PRINT((ndo, "%d > %d", EXTRACT_32BITS(hdr->iph_zsrc),
44356341Scy		  EXTRACT_32BITS(hdr->iph_zdst)));
45214456Srpaulo
46214456Srpaulo	if (!ndo->ndo_qflag) {
47214456Srpaulo		ND_PRINT((ndo,", family %s (%d)",
48214456Srpaulo                          tok2str(ipnet_values, "Unknown",
49356341Scy                                  EXTRACT_8BITS(&hdr->iph_family)),
50356341Scy                          EXTRACT_8BITS(&hdr->iph_family)));
51214456Srpaulo        } else {
52214456Srpaulo		ND_PRINT((ndo,", %s",
53214456Srpaulo                          tok2str(ipnet_values,
54214456Srpaulo                                  "Unknown Ethertype (0x%04x)",
55356341Scy				  EXTRACT_8BITS(&hdr->iph_family))));
56214456Srpaulo        }
57214456Srpaulo
58214456Srpaulo	ND_PRINT((ndo, ", length %u: ", length));
59356341Scy	return;
60356341Scytrunc:
61356341Scy	ND_PRINT((ndo, " %s", tstr));
62214456Srpaulo}
63214456Srpaulo
64214456Srpaulostatic void
65276788Sdelphijipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
66214456Srpaulo{
67313537Sglebius	const ipnet_hdr_t *hdr;
68214456Srpaulo
69356341Scy	if (caplen < sizeof(ipnet_hdr_t))
70356341Scy		goto trunc;
71214456Srpaulo
72214456Srpaulo	if (ndo->ndo_eflag)
73214456Srpaulo		ipnet_hdr_print(ndo, p, length);
74214456Srpaulo
75214456Srpaulo	length -= sizeof(ipnet_hdr_t);
76214456Srpaulo	caplen -= sizeof(ipnet_hdr_t);
77313537Sglebius	hdr = (const ipnet_hdr_t *)p;
78214456Srpaulo	p += sizeof(ipnet_hdr_t);
79214456Srpaulo
80356341Scy	ND_TCHECK2(hdr->iph_family, 1);
81356341Scy	switch (EXTRACT_8BITS(&hdr->iph_family)) {
82214456Srpaulo
83214456Srpaulo	case IPH_AF_INET:
84214456Srpaulo	        ip_print(ndo, p, length);
85214456Srpaulo		break;
86214456Srpaulo
87214456Srpaulo	case IPH_AF_INET6:
88235530Sdelphij		ip6_print(ndo, p, length);
89214456Srpaulo		break;
90214456Srpaulo
91214456Srpaulo	default:
92214456Srpaulo		if (!ndo->ndo_eflag)
93313537Sglebius			ipnet_hdr_print(ndo, (const u_char *)hdr,
94214456Srpaulo					length + sizeof(ipnet_hdr_t));
95214456Srpaulo
96214456Srpaulo		if (!ndo->ndo_suppress_default_print)
97276788Sdelphij			ND_DEFAULTPRINT(p, caplen);
98214456Srpaulo		break;
99214456Srpaulo	}
100356341Scy	return;
101356341Scytrunc:
102356341Scy	ND_PRINT((ndo, " %s", tstr));
103214456Srpaulo}
104214456Srpaulo
105214456Srpaulo/*
106214456Srpaulo * This is the top level routine of the printer.  'p' points
107214456Srpaulo * to the ether header of the packet, 'h->ts' is the timestamp,
108214456Srpaulo * 'h->len' is the length of the packet off the wire, and 'h->caplen'
109214456Srpaulo * is the number of bytes actually captured.
110214456Srpaulo */
111214456Srpaulou_int
112276788Sdelphijipnet_if_print(netdissect_options *ndo,
113214456Srpaulo               const struct pcap_pkthdr *h, const u_char *p)
114214456Srpaulo{
115214456Srpaulo	ipnet_print(ndo, p, h->len, h->caplen);
116214456Srpaulo
117214456Srpaulo	return (sizeof(ipnet_hdr_t));
118214456Srpaulo}
119214456Srpaulo
120214456Srpaulo/*
121214456Srpaulo * Local Variables:
122214456Srpaulo * c-style: whitesmith
123214456Srpaulo * c-basic-offset: 8
124214456Srpaulo * End:
125214456Srpaulo */
126214456Srpaulo
127214456Srpaulo#endif /* DLT_IPNET */
128