Home | History | Annotate | Download | only in tcpdump
      1 /* \summary: Solaris DLT_IPNET printer */
      2 
      3 #ifdef HAVE_CONFIG_H
      4 #include "config.h"
      5 #endif
      6 
      7 #include <netdissect-stdinc.h>
      8 
      9 #include "netdissect.h"
     10 
     11 typedef struct ipnet_hdr {
     12 	uint8_t		iph_version;
     13 	uint8_t		iph_family;
     14 	uint16_t	iph_htype;
     15 	uint32_t	iph_pktlen;
     16 	uint32_t	iph_ifindex;
     17 	uint32_t	iph_grifindex;
     18 	uint32_t	iph_zsrc;
     19 	uint32_t	iph_zdst;
     20 } ipnet_hdr_t;
     21 
     22 #define	IPH_AF_INET	2		/* Matches Solaris's AF_INET */
     23 #define	IPH_AF_INET6	26		/* Matches Solaris's AF_INET6 */
     24 
     25 #ifdef DLT_IPNET
     26 
     27 static const struct tok ipnet_values[] = {
     28 	{ IPH_AF_INET,		"IPv4" },
     29 	{ IPH_AF_INET6,		"IPv6" },
     30 	{ 0,			NULL }
     31 };
     32 
     33 static inline void
     34 ipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length)
     35 {
     36 	const ipnet_hdr_t *hdr;
     37 	hdr = (const ipnet_hdr_t *)bp;
     38 
     39 	ND_PRINT((ndo, "%d > %d", hdr->iph_zsrc, hdr->iph_zdst));
     40 
     41 	if (!ndo->ndo_qflag) {
     42 		ND_PRINT((ndo,", family %s (%d)",
     43                           tok2str(ipnet_values, "Unknown",
     44                                   hdr->iph_family),
     45                           hdr->iph_family));
     46         } else {
     47 		ND_PRINT((ndo,", %s",
     48                           tok2str(ipnet_values,
     49                                   "Unknown Ethertype (0x%04x)",
     50                                   hdr->iph_family)));
     51         }
     52 
     53 	ND_PRINT((ndo, ", length %u: ", length));
     54 }
     55 
     56 static void
     57 ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
     58 {
     59 	const ipnet_hdr_t *hdr;
     60 
     61 	if (caplen < sizeof(ipnet_hdr_t)) {
     62 		ND_PRINT((ndo, "[|ipnet]"));
     63 		return;
     64 	}
     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 (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 u_int
    102 ipnet_if_print(netdissect_options *ndo,
    103                const struct pcap_pkthdr *h, const u_char *p)
    104 {
    105 	ipnet_print(ndo, p, h->len, h->caplen);
    106 
    107 	return (sizeof(ipnet_hdr_t));
    108 }
    109 
    110 /*
    111  * Local Variables:
    112  * c-style: whitesmith
    113  * c-basic-offset: 8
    114  * End:
    115  */
    116 
    117 #endif /* DLT_IPNET */
    118