]> The Tcpdump Group git mirrors - tcpdump/blob - print-ipnet.c
updated print-ipnet.c to use netdissect options structure
[tcpdump] / print-ipnet.c
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 "addrtoname.h"
12 #include "ipnet.h"
13
14 #ifdef DLT_IPNET
15
16 int ipnet_encap_print(netdissect_options *,u_short, const u_char *, u_int, u_int);
17
18 const struct tok ipnet_values[] = {
19 { IPH_AF_INET, "IPv4" },
20 { IPH_AF_INET6, "IPv6" },
21 { 0, NULL }
22 };
23
24 static inline void
25 ipnet_hdr_print(struct netdissect_options *ndo, const u_char *bp, u_int length)
26 {
27 const ipnet_hdr_t *hdr;
28 hdr = (const ipnet_hdr_t *)bp;
29
30 ND_PRINT((ndo, "%d > %d", hdr->iph_zsrc, hdr->iph_zdst));
31
32 if (!ndo->ndo_qflag) {
33 ND_PRINT((ndo,", family %s (%d)",
34 tok2str(ipnet_values, "Unknown",
35 hdr->iph_family),
36 hdr->iph_family));
37 } else {
38 ND_PRINT((ndo,", %s",
39 tok2str(ipnet_values,
40 "Unknown Ethertype (0x%04x)",
41 hdr->iph_family)));
42 }
43
44 ND_PRINT((ndo, ", length %u: ", length));
45 }
46
47 void
48 ipnet_print(struct netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
49 {
50 ipnet_hdr_t *hdr;
51
52 if (caplen < sizeof(ipnet_hdr_t)) {
53 ND_PRINT((ndo, "[|ipnet]"));
54 return;
55 }
56
57 if (ndo->ndo_eflag)
58 ipnet_hdr_print(ndo, p, length);
59
60 length -= sizeof(ipnet_hdr_t);
61 caplen -= sizeof(ipnet_hdr_t);
62 hdr = (ipnet_hdr_t *)p;
63 p += sizeof(ipnet_hdr_t);
64
65 if (ipnet_encap_print(ndo, hdr->iph_family, p, length, caplen) == 0) {
66 if (!ndo->ndo_eflag)
67 ipnet_hdr_print(ndo, (u_char *)hdr,
68 length + sizeof(ipnet_hdr_t));
69
70 if (!ndo->ndo_suppress_default_print)
71 ndo->ndo_default_print(ndo, p, caplen);
72 }
73 }
74
75 /*
76 * This is the top level routine of the printer. 'p' points
77 * to the ether header of the packet, 'h->ts' is the timestamp,
78 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
79 * is the number of bytes actually captured.
80 */
81 u_int
82 ipnet_if_print(struct netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
83 {
84 ipnet_print(ndo, p, h->len, h->caplen);
85
86 return (sizeof(ipnet_hdr_t));
87 }
88
89 /*
90 * Prints the packet encapsulated in an Ethernet data segment
91 * (or an equivalent encapsulation), given the Ethernet type code.
92 *
93 * Returns non-zero if it can do so, zero if the ethertype is unknown.
94 *
95 * The Ethernet type code is passed through a pointer; if it was
96 * ETHERTYPE_8021Q, it gets updated to be the Ethernet type of
97 * the 802.1Q payload, for the benefit of lower layers that might
98 * want to know what it is.
99 */
100
101 int
102 ipnet_encap_print(struct netdissect_options *ndo, u_short family, const u_char *p,
103 u_int length, u_int caplen)
104 {
105 recurse:
106
107 switch (family) {
108
109 case IPH_AF_INET:
110 ip_print(ndo, p, length);
111 return (1);
112
113 #ifdef INET6
114 case IPH_AF_INET6:
115 ip6_print(p, length);
116 return (1);
117 #endif /*INET6*/
118
119 default:
120 return(0);
121 }
122 }
123
124
125 /*
126 * Local Variables:
127 * c-style: whitesmith
128 * c-basic-offset: 8
129 * End:
130 */
131
132 #endif /* DLT_IPNET */