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