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