static void show_dlts_and_exit(const char *device, pcap_t *pd) { int n_dlts; int *dlts = 0; const char *dlt_name; n_dlts = pcap_list_datalinks(pd, &dlts); if (n_dlts < 0) error("%s", pcap_geterr(pd)); else if (n_dlts == 0 || !dlts) error("No data link types."); /* * If the interface is known to support monitor mode, indicate * whether these are the data link types available when not in * monitor mode, if -I wasn't specified, or when in monitor mode, * when -I was specified (the link-layer types available in * monitor mode might be different from the ones available when * not in monitor mode). */ if (supports_monitor_mode) (void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n", device, Iflag ? "when in monitor mode" : "when not in monitor mode"); else (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n", device); while (--n_dlts >= 0) { dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); if (dlt_name != NULL) { (void) fprintf(stderr, " %s (%s)", dlt_name, pcap_datalink_val_to_description(dlts[n_dlts])); /* * OK, does tcpdump handle that type? */ if (lookup_printer(dlts[n_dlts]) == NULL && lookup_ndo_printer(dlts[n_dlts]) == NULL) (void) fprintf(stderr, " (printing not supported)"); putchar('\n'); } else { (void) fprintf(stderr, " DLT %d (printing not supported)\n", dlts[n_dlts]); } } free(dlts); exit(0); }
/* * This is the top level routine of the printer. 'p' points * to the ether header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ u_int pktap_if_print(struct netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { uint32_t dlt, hdrlen, rectype; u_int caplen = h->caplen; u_int length = h->len; if_ndo_printer ndo_printer; if_printer printer; pktap_header_t *hdr; if (caplen < sizeof(pktap_header_t) || length < sizeof(pktap_header_t)) { ND_PRINT((ndo, "[|pktap]")); return (0); } hdr = (pktap_header_t *)p; dlt = EXTRACT_LE_32BITS(&hdr->pkt_dlt); hdrlen = EXTRACT_LE_32BITS(&hdr->pkt_len); if (hdrlen < sizeof(pktap_header_t)) { /* * Claimed header length < structure length. * XXX - does this just mean some fields aren't * being supplied, or is it truly an error (i.e., * is the length supplied so that the header can * be expanded in the future)? */ ND_PRINT((ndo, "[|pktap]")); return (0); } if (caplen < hdrlen || length < hdrlen) { ND_PRINT((ndo, "[|pktap]")); return (hdrlen); } if (ndo->ndo_eflag) pktap_header_print(ndo, p, length); length -= hdrlen; caplen -= hdrlen; p += hdrlen; rectype = EXTRACT_LE_32BITS(&hdr->pkt_rectype); switch (rectype) { case PKT_REC_NONE: ND_PRINT((ndo, "no data")); break; case PKT_REC_PACKET: if ((printer = lookup_printer(dlt)) != NULL) { printer(h, p); } else if ((ndo_printer = lookup_ndo_printer(dlt)) != NULL) { ndo_printer(ndo, h, p); } else { if (!ndo->ndo_eflag) pktap_header_print(ndo, (u_char *)hdr, length + hdrlen); if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); } break; } return (hdrlen); }