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