1 2 #include <sys/cdefs.h> 3 #ifndef lint 4 __RCSID("$NetBSD: print-ipnet.c,v 1.4 2019/10/01 16:06:16 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 #include "netdissect.h" 16 #include "extract.h" 17 18 static const char tstr[] = "[|ipnet]"; 19 20 typedef 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 36 static const struct tok ipnet_values[] = { 37 { IPH_AF_INET, "IPv4" }, 38 { IPH_AF_INET6, "IPv6" }, 39 { 0, NULL } 40 }; 41 42 static inline void 43 ipnet_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_TCHECK(*hdr); 49 ND_PRINT((ndo, "%d > %d", EXTRACT_32BITS(hdr->iph_zsrc), 50 EXTRACT_32BITS(hdr->iph_zdst))); 51 52 if (!ndo->ndo_qflag) { 53 ND_PRINT((ndo,", family %s (%d)", 54 tok2str(ipnet_values, "Unknown", 55 EXTRACT_8BITS(&hdr->iph_family)), 56 EXTRACT_8BITS(&hdr->iph_family))); 57 } else { 58 ND_PRINT((ndo,", %s", 59 tok2str(ipnet_values, 60 "Unknown Ethertype (0x%04x)", 61 EXTRACT_8BITS(&hdr->iph_family)))); 62 } 63 64 ND_PRINT((ndo, ", length %u: ", length)); 65 return; 66 trunc: 67 ND_PRINT((ndo, " %s", tstr)); 68 } 69 70 static void 71 ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) 72 { 73 const ipnet_hdr_t *hdr; 74 75 if (caplen < sizeof(ipnet_hdr_t)) 76 goto trunc; 77 78 if (ndo->ndo_eflag) 79 ipnet_hdr_print(ndo, p, length); 80 81 length -= sizeof(ipnet_hdr_t); 82 caplen -= sizeof(ipnet_hdr_t); 83 hdr = (const ipnet_hdr_t *)p; 84 p += sizeof(ipnet_hdr_t); 85 86 ND_TCHECK2(hdr->iph_family, 1); 87 switch (EXTRACT_8BITS(&hdr->iph_family)) { 88 89 case IPH_AF_INET: 90 ip_print(ndo, p, length); 91 break; 92 93 case IPH_AF_INET6: 94 ip6_print(ndo, p, length); 95 break; 96 97 default: 98 if (!ndo->ndo_eflag) 99 ipnet_hdr_print(ndo, (const u_char *)hdr, 100 length + sizeof(ipnet_hdr_t)); 101 102 if (!ndo->ndo_suppress_default_print) 103 ND_DEFAULTPRINT(p, caplen); 104 break; 105 } 106 return; 107 trunc: 108 ND_PRINT((ndo, " %s", tstr)); 109 } 110 111 /* 112 * This is the top level routine of the printer. 'p' points 113 * to the ether header of the packet, 'h->ts' is the timestamp, 114 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 115 * is the number of bytes actually captured. 116 */ 117 u_int 118 ipnet_if_print(netdissect_options *ndo, 119 const struct pcap_pkthdr *h, const u_char *p) 120 { 121 ipnet_print(ndo, p, h->len, h->caplen); 122 123 return (sizeof(ipnet_hdr_t)); 124 } 125 126 /* 127 * Local Variables: 128 * c-style: whitesmith 129 * c-basic-offset: 8 130 * End: 131 */ 132 133 #endif /* DLT_IPNET */ 134