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