xref: /netbsd-src/external/bsd/tcpdump/dist/print-ipnet.c (revision 26ba0b503b498a5194a71ac319838b7f5497f3fe)
1fdccd7e4Schristos 
2fdccd7e4Schristos #include <sys/cdefs.h>
3fdccd7e4Schristos #ifndef lint
4*26ba0b50Schristos __RCSID("$NetBSD: print-ipnet.c,v 1.6 2024/09/02 16:15:31 christos Exp $");
5fdccd7e4Schristos #endif
6fdccd7e4Schristos 
7dc860a36Sspz /* \summary: Solaris DLT_IPNET printer */
8dc860a36Sspz 
9c74ad251Schristos #include <config.h>
100f74e101Schristos 
11c74ad251Schristos #include "netdissect-stdinc.h"
120f74e101Schristos 
13c74ad251Schristos #define ND_LONGJMP_FROM_TCHECK
14784088dfSchristos #include "netdissect.h"
15817e9a7eSchristos #include "extract.h"
16817e9a7eSchristos 
17c47fd378Schristos 
18c47fd378Schristos typedef struct ipnet_hdr {
19817e9a7eSchristos 	nd_uint8_t	iph_version;
20817e9a7eSchristos 	nd_uint8_t	iph_family;
21817e9a7eSchristos 	nd_uint16_t	iph_htype;
22817e9a7eSchristos 	nd_uint32_t	iph_pktlen;
23817e9a7eSchristos 	nd_uint32_t	iph_ifindex;
24817e9a7eSchristos 	nd_uint32_t	iph_grifindex;
25817e9a7eSchristos 	nd_uint32_t	iph_zsrc;
26817e9a7eSchristos 	nd_uint32_t	iph_zdst;
27c47fd378Schristos } ipnet_hdr_t;
28c47fd378Schristos 
29c47fd378Schristos #define	IPH_AF_INET	2		/* Matches Solaris's AF_INET */
30c47fd378Schristos #define	IPH_AF_INET6	26		/* Matches Solaris's AF_INET6 */
310f74e101Schristos 
320f74e101Schristos #ifdef DLT_IPNET
330f74e101Schristos 
34026d7285Schristos static const struct tok ipnet_values[] = {
350f74e101Schristos 	{ IPH_AF_INET,		"IPv4" },
360f74e101Schristos 	{ IPH_AF_INET6,		"IPv6" },
370f74e101Schristos 	{ 0,			NULL }
380f74e101Schristos };
390f74e101Schristos 
40c74ad251Schristos static void
41c47fd378Schristos ipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length)
420f74e101Schristos {
430f74e101Schristos 	const ipnet_hdr_t *hdr;
440f74e101Schristos 	hdr = (const ipnet_hdr_t *)bp;
450f74e101Schristos 
46c74ad251Schristos 	ND_PRINT("%u > %u", GET_BE_U_4(hdr->iph_zsrc),
47c74ad251Schristos 		  GET_BE_U_4(hdr->iph_zdst));
480f74e101Schristos 
490f74e101Schristos 	if (!ndo->ndo_qflag) {
50c74ad251Schristos 		ND_PRINT(", family %s (%u)",
510f74e101Schristos                           tok2str(ipnet_values, "Unknown",
52c74ad251Schristos                                   GET_U_1(hdr->iph_family)),
53c74ad251Schristos                           GET_U_1(hdr->iph_family));
540f74e101Schristos         } else {
55c74ad251Schristos 		ND_PRINT(", %s",
560f74e101Schristos                           tok2str(ipnet_values,
570f74e101Schristos                                   "Unknown Ethertype (0x%04x)",
58c74ad251Schristos 				  GET_U_1(hdr->iph_family)));
590f74e101Schristos         }
600f74e101Schristos 
61c74ad251Schristos 	ND_PRINT(", length %u: ", length);
620f74e101Schristos }
630f74e101Schristos 
640f74e101Schristos static void
65c47fd378Schristos ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
660f74e101Schristos {
67784088dfSchristos 	const ipnet_hdr_t *hdr;
680f74e101Schristos 
69c74ad251Schristos 	ND_TCHECK_LEN(p, sizeof(ipnet_hdr_t));
70c74ad251Schristos 	ndo->ndo_ll_hdr_len += sizeof(ipnet_hdr_t);
710f74e101Schristos 
720f74e101Schristos 	if (ndo->ndo_eflag)
730f74e101Schristos 		ipnet_hdr_print(ndo, p, length);
740f74e101Schristos 
750f74e101Schristos 	length -= sizeof(ipnet_hdr_t);
760f74e101Schristos 	caplen -= sizeof(ipnet_hdr_t);
77784088dfSchristos 	hdr = (const ipnet_hdr_t *)p;
780f74e101Schristos 	p += sizeof(ipnet_hdr_t);
790f74e101Schristos 
80c74ad251Schristos 	switch (GET_U_1(hdr->iph_family)) {
810f74e101Schristos 
820f74e101Schristos 	case IPH_AF_INET:
830f74e101Schristos 	        ip_print(ndo, p, length);
840f74e101Schristos 		break;
850f74e101Schristos 
860f74e101Schristos 	case IPH_AF_INET6:
879546e36dSchristos 		ip6_print(ndo, p, length);
880f74e101Schristos 		break;
890f74e101Schristos 
900f74e101Schristos 	default:
910f74e101Schristos 		if (!ndo->ndo_eflag)
92784088dfSchristos 			ipnet_hdr_print(ndo, (const u_char *)hdr,
930f74e101Schristos 					length + sizeof(ipnet_hdr_t));
940f74e101Schristos 
950f74e101Schristos 		if (!ndo->ndo_suppress_default_print)
96c47fd378Schristos 			ND_DEFAULTPRINT(p, caplen);
970f74e101Schristos 		break;
980f74e101Schristos 	}
990f74e101Schristos }
1000f74e101Schristos 
1010f74e101Schristos /*
1020f74e101Schristos  * This is the top level routine of the printer.  'p' points
1030f74e101Schristos  * to the ether header of the packet, 'h->ts' is the timestamp,
1040f74e101Schristos  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1050f74e101Schristos  * is the number of bytes actually captured.
1060f74e101Schristos  */
107c74ad251Schristos void
108c47fd378Schristos ipnet_if_print(netdissect_options *ndo,
1090f74e101Schristos                const struct pcap_pkthdr *h, const u_char *p)
1100f74e101Schristos {
111c74ad251Schristos 	ndo->ndo_protocol = "ipnet";
1120f74e101Schristos 	ipnet_print(ndo, p, h->len, h->caplen);
1130f74e101Schristos }
1140f74e101Schristos #endif /* DLT_IPNET */
115