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