print-ipnet.c revision 1.3
1
2#include <sys/cdefs.h>
3#ifndef lint
4__RCSID("$NetBSD: print-ipnet.c,v 1.3 2017/02/05 04:05:05 spz Exp $");
5#endif
6
7/* \summary: Solaris DLT_IPNET printer */
8
9#ifdef HAVE_CONFIG_H
10#include "config.h"
11#endif
12
13#include <netdissect-stdinc.h>
14
15#include "netdissect.h"
16
17typedef struct ipnet_hdr {
18	uint8_t		iph_version;
19	uint8_t		iph_family;
20	uint16_t	iph_htype;
21	uint32_t	iph_pktlen;
22	uint32_t	iph_ifindex;
23	uint32_t	iph_grifindex;
24	uint32_t	iph_zsrc;
25	uint32_t	iph_zdst;
26} ipnet_hdr_t;
27
28#define	IPH_AF_INET	2		/* Matches Solaris's AF_INET */
29#define	IPH_AF_INET6	26		/* Matches Solaris's AF_INET6 */
30
31#ifdef DLT_IPNET
32
33static const struct tok ipnet_values[] = {
34	{ IPH_AF_INET,		"IPv4" },
35	{ IPH_AF_INET6,		"IPv6" },
36	{ 0,			NULL }
37};
38
39static inline void
40ipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length)
41{
42	const ipnet_hdr_t *hdr;
43	hdr = (const ipnet_hdr_t *)bp;
44
45	ND_PRINT((ndo, "%d > %d", hdr->iph_zsrc, hdr->iph_zdst));
46
47	if (!ndo->ndo_qflag) {
48		ND_PRINT((ndo,", family %s (%d)",
49                          tok2str(ipnet_values, "Unknown",
50                                  hdr->iph_family),
51                          hdr->iph_family));
52        } else {
53		ND_PRINT((ndo,", %s",
54                          tok2str(ipnet_values,
55                                  "Unknown Ethertype (0x%04x)",
56                                  hdr->iph_family)));
57        }
58
59	ND_PRINT((ndo, ", length %u: ", length));
60}
61
62static void
63ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
64{
65	const ipnet_hdr_t *hdr;
66
67	if (caplen < sizeof(ipnet_hdr_t)) {
68		ND_PRINT((ndo, "[|ipnet]"));
69		return;
70	}
71
72	if (ndo->ndo_eflag)
73		ipnet_hdr_print(ndo, p, length);
74
75	length -= sizeof(ipnet_hdr_t);
76	caplen -= sizeof(ipnet_hdr_t);
77	hdr = (const ipnet_hdr_t *)p;
78	p += sizeof(ipnet_hdr_t);
79
80	switch (hdr->iph_family) {
81
82	case IPH_AF_INET:
83	        ip_print(ndo, p, length);
84		break;
85
86	case IPH_AF_INET6:
87		ip6_print(ndo, p, length);
88		break;
89
90	default:
91		if (!ndo->ndo_eflag)
92			ipnet_hdr_print(ndo, (const u_char *)hdr,
93					length + sizeof(ipnet_hdr_t));
94
95		if (!ndo->ndo_suppress_default_print)
96			ND_DEFAULTPRINT(p, caplen);
97		break;
98	}
99}
100
101/*
102 * This is the top level routine of the printer.  'p' points
103 * to the ether header of the packet, 'h->ts' is the timestamp,
104 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
105 * is the number of bytes actually captured.
106 */
107u_int
108ipnet_if_print(netdissect_options *ndo,
109               const struct pcap_pkthdr *h, const u_char *p)
110{
111	ipnet_print(ndo, p, h->len, h->caplen);
112
113	return (sizeof(ipnet_hdr_t));
114}
115
116/*
117 * Local Variables:
118 * c-style: whitesmith
119 * c-basic-offset: 8
120 * End:
121 */
122
123#endif /* DLT_IPNET */
124