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