1 2#include <sys/cdefs.h> 3#ifndef lint 4__RCSID("$NetBSD: print-ipnet.c,v 1.5 2023/08/17 20:19:40 christos Exp $"); 5#endif 6 7/* \summary: Solaris DLT_IPNET printer */ 8 9#ifdef HAVE_CONFIG_H 10#include <config.h> 11#endif 12 13#include "netdissect-stdinc.h" 14 15#define ND_LONGJMP_FROM_TCHECK 16#include "netdissect.h" 17#include "extract.h" 18 19 20typedef struct ipnet_hdr { 21 nd_uint8_t iph_version; 22 nd_uint8_t iph_family; 23 nd_uint16_t iph_htype; 24 nd_uint32_t iph_pktlen; 25 nd_uint32_t iph_ifindex; 26 nd_uint32_t iph_grifindex; 27 nd_uint32_t iph_zsrc; 28 nd_uint32_t iph_zdst; 29} ipnet_hdr_t; 30 31#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */ 32#define IPH_AF_INET6 26 /* Matches Solaris's AF_INET6 */ 33 34#ifdef DLT_IPNET 35 36static const struct tok ipnet_values[] = { 37 { IPH_AF_INET, "IPv4" }, 38 { IPH_AF_INET6, "IPv6" }, 39 { 0, NULL } 40}; 41 42static void 43ipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length) 44{ 45 const ipnet_hdr_t *hdr; 46 hdr = (const ipnet_hdr_t *)bp; 47 48 ND_PRINT("%u > %u", GET_BE_U_4(hdr->iph_zsrc), 49 GET_BE_U_4(hdr->iph_zdst)); 50 51 if (!ndo->ndo_qflag) { 52 ND_PRINT(", family %s (%u)", 53 tok2str(ipnet_values, "Unknown", 54 GET_U_1(hdr->iph_family)), 55 GET_U_1(hdr->iph_family)); 56 } else { 57 ND_PRINT(", %s", 58 tok2str(ipnet_values, 59 "Unknown Ethertype (0x%04x)", 60 GET_U_1(hdr->iph_family))); 61 } 62 63 ND_PRINT(", length %u: ", length); 64} 65 66static void 67ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) 68{ 69 const ipnet_hdr_t *hdr; 70 71 ND_TCHECK_LEN(p, sizeof(ipnet_hdr_t)); 72 ndo->ndo_ll_hdr_len += sizeof(ipnet_hdr_t); 73 74 if (ndo->ndo_eflag) 75 ipnet_hdr_print(ndo, p, length); 76 77 length -= sizeof(ipnet_hdr_t); 78 caplen -= sizeof(ipnet_hdr_t); 79 hdr = (const ipnet_hdr_t *)p; 80 p += sizeof(ipnet_hdr_t); 81 82 switch (GET_U_1(hdr->iph_family)) { 83 84 case IPH_AF_INET: 85 ip_print(ndo, p, length); 86 break; 87 88 case IPH_AF_INET6: 89 ip6_print(ndo, p, length); 90 break; 91 92 default: 93 if (!ndo->ndo_eflag) 94 ipnet_hdr_print(ndo, (const u_char *)hdr, 95 length + sizeof(ipnet_hdr_t)); 96 97 if (!ndo->ndo_suppress_default_print) 98 ND_DEFAULTPRINT(p, caplen); 99 break; 100 } 101} 102 103/* 104 * This is the top level routine of the printer. 'p' points 105 * to the ether header of the packet, 'h->ts' is the timestamp, 106 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 107 * is the number of bytes actually captured. 108 */ 109void 110ipnet_if_print(netdissect_options *ndo, 111 const struct pcap_pkthdr *h, const u_char *p) 112{ 113 ndo->ndo_protocol = "ipnet"; 114 ipnet_print(ndo, p, h->len, h->caplen); 115} 116#endif /* DLT_IPNET */ 117