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
17static const struct tok ipnet_values[] = {
18	{ IPH_AF_INET,		"IPv4" },
19	{ IPH_AF_INET6,		"IPv6" },
20	{ 0,			NULL }
21};
22
23static inline void
24ipnet_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
46static void
47ipnet_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 */
93u_int
94ipnet_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