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