"Fossies" - the Fresh Open Source Software Archive

Member "tcpdump-4.99.1/./print.c" (7 Jun 2021, 14152 Bytes) of package /linux/misc/tcpdump-4.99.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "print.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.99.0_vs_4.99.1.

    1 /*
    2  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
    3  *  The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that: (1) source code distributions
    7  * retain the above copyright notice and this paragraph in its entirety, (2)
    8  * distributions including binary code include the above copyright notice and
    9  * this paragraph in its entirety in the documentation or other materials
   10  * provided with the distribution, and (3) all advertising materials mentioning
   11  * features or use of this software display the following acknowledgement:
   12  * ``This product includes software developed by the University of California,
   13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
   14  * the University nor the names of its contributors may be used to endorse
   15  * or promote products derived from this software without specific prior
   16  * written permission.
   17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
   18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
   19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   20  *
   21  * Support for splitting captures into multiple files with a maximum
   22  * file size:
   23  *
   24  * Copyright (c) 2001
   25  *  Seth Webster <swebster@sst.ll.mit.edu>
   26  */
   27 
   28 #ifdef HAVE_CONFIG_H
   29 #include <config.h>
   30 #endif
   31 
   32 #include <stdlib.h>
   33 #include <string.h>
   34 #include <setjmp.h>
   35 
   36 #include "netdissect-stdinc.h"
   37 
   38 #include "netdissect.h"
   39 #include "addrtoname.h"
   40 #include "print.h"
   41 #include "netdissect-alloc.h"
   42 
   43 #include "pcap-missing.h"
   44 
   45 struct printer {
   46     if_printer f;
   47     int type;
   48 };
   49 
   50 static const struct printer printers[] = {
   51 #ifdef DLT_APPLE_IP_OVER_IEEE1394
   52     { ap1394_if_print,  DLT_APPLE_IP_OVER_IEEE1394 },
   53 #endif
   54     { arcnet_if_print,  DLT_ARCNET },
   55 #ifdef DLT_ARCNET_LINUX
   56     { arcnet_linux_if_print, DLT_ARCNET_LINUX },
   57 #endif
   58     { atm_if_print,     DLT_ATM_RFC1483 },
   59 #ifdef DLT_DSA_TAG_BRCM
   60     { brcm_tag_if_print,    DLT_DSA_TAG_BRCM },
   61 #endif
   62 #ifdef DLT_DSA_TAG_BRCM_PREPEND
   63     { brcm_tag_prepend_if_print, DLT_DSA_TAG_BRCM_PREPEND },
   64 #endif
   65 #ifdef DLT_BLUETOOTH_HCI_H4_WITH_PHDR
   66     { bt_if_print,      DLT_BLUETOOTH_HCI_H4_WITH_PHDR},
   67 #endif
   68 #ifdef DLT_C_HDLC
   69     { chdlc_if_print,   DLT_C_HDLC },
   70 #endif
   71 #ifdef DLT_HDLC
   72     { chdlc_if_print,   DLT_HDLC },
   73 #endif
   74 #ifdef DLT_ATM_CLIP
   75     { cip_if_print,     DLT_ATM_CLIP },
   76 #endif
   77 #ifdef DLT_CIP
   78     { cip_if_print,     DLT_CIP },
   79 #endif
   80 #ifdef DLT_DSA_TAG_DSA
   81     { dsa_if_print,     DLT_DSA_TAG_DSA },
   82 #endif
   83 #ifdef DLT_DSA_TAG_EDSA
   84     { edsa_if_print,    DLT_DSA_TAG_EDSA },
   85 #endif
   86 #ifdef DLT_ENC
   87     { enc_if_print,     DLT_ENC },
   88 #endif
   89     { ether_if_print,   DLT_EN10MB },
   90     { fddi_if_print,    DLT_FDDI },
   91 #ifdef DLT_FR
   92     { fr_if_print,      DLT_FR },
   93 #endif
   94 #ifdef DLT_FRELAY
   95     { fr_if_print,      DLT_FRELAY },
   96 #endif
   97 #ifdef DLT_IEEE802_11
   98     { ieee802_11_if_print,  DLT_IEEE802_11},
   99 #endif
  100 #ifdef DLT_IEEE802_11_RADIO_AVS
  101     { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS },
  102 #endif
  103 #ifdef DLT_IEEE802_11_RADIO
  104     { ieee802_11_radio_if_print,    DLT_IEEE802_11_RADIO },
  105 #endif
  106 #ifdef DLT_IEEE802_15_4
  107     { ieee802_15_4_if_print, DLT_IEEE802_15_4 },
  108 #endif
  109 #ifdef DLT_IEEE802_15_4_NOFCS
  110     { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS },
  111 #endif
  112 #ifdef DLT_IEEE802_15_4_TAP
  113     { ieee802_15_4_tap_if_print, DLT_IEEE802_15_4_TAP },
  114 #endif
  115 #ifdef DLT_IP_OVER_FC
  116     { ipfc_if_print,    DLT_IP_OVER_FC },
  117 #endif
  118 #ifdef DLT_IPNET
  119     { ipnet_if_print,   DLT_IPNET },
  120 #endif
  121 #ifdef DLT_IPOIB
  122     { ipoib_if_print,       DLT_IPOIB },
  123 #endif
  124 #ifdef DLT_JUNIPER_ATM1
  125     { juniper_atm1_if_print, DLT_JUNIPER_ATM1 },
  126 #endif
  127 #ifdef DLT_JUNIPER_ATM2
  128     { juniper_atm2_if_print, DLT_JUNIPER_ATM2 },
  129 #endif
  130 #ifdef DLT_JUNIPER_CHDLC
  131     { juniper_chdlc_if_print,   DLT_JUNIPER_CHDLC },
  132 #endif
  133 #ifdef DLT_JUNIPER_ES
  134     { juniper_es_if_print,  DLT_JUNIPER_ES },
  135 #endif
  136 #ifdef DLT_JUNIPER_ETHER
  137     { juniper_ether_if_print,   DLT_JUNIPER_ETHER },
  138 #endif
  139 #ifdef DLT_JUNIPER_FRELAY
  140     { juniper_frelay_if_print,  DLT_JUNIPER_FRELAY },
  141 #endif
  142 #ifdef DLT_JUNIPER_GGSN
  143     { juniper_ggsn_if_print, DLT_JUNIPER_GGSN },
  144 #endif
  145 #ifdef DLT_JUNIPER_MFR
  146     { juniper_mfr_if_print, DLT_JUNIPER_MFR },
  147 #endif
  148 #ifdef DLT_JUNIPER_MLFR
  149     { juniper_mlfr_if_print, DLT_JUNIPER_MLFR },
  150 #endif
  151 #ifdef DLT_JUNIPER_MLPPP
  152     { juniper_mlppp_if_print, DLT_JUNIPER_MLPPP },
  153 #endif
  154 #ifdef DLT_JUNIPER_MONITOR
  155     { juniper_monitor_if_print, DLT_JUNIPER_MONITOR },
  156 #endif
  157 #ifdef DLT_JUNIPER_PPP
  158     { juniper_ppp_if_print, DLT_JUNIPER_PPP },
  159 #endif
  160 #ifdef DLT_JUNIPER_PPPOE_ATM
  161     { juniper_pppoe_atm_if_print, DLT_JUNIPER_PPPOE_ATM },
  162 #endif
  163 #ifdef DLT_JUNIPER_PPPOE
  164     { juniper_pppoe_if_print, DLT_JUNIPER_PPPOE },
  165 #endif
  166 #ifdef DLT_JUNIPER_SERVICES
  167     { juniper_services_if_print, DLT_JUNIPER_SERVICES },
  168 #endif
  169 #ifdef DLT_LTALK
  170     { ltalk_if_print,   DLT_LTALK },
  171 #endif
  172 #ifdef DLT_MFR
  173     { mfr_if_print,     DLT_MFR },
  174 #endif
  175 #ifdef DLT_NETANALYZER
  176     { netanalyzer_if_print, DLT_NETANALYZER },
  177 #endif
  178 #ifdef DLT_NETANALYZER_TRANSPARENT
  179     { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT },
  180 #endif
  181 #ifdef DLT_NFLOG
  182     { nflog_if_print,   DLT_NFLOG},
  183 #endif
  184     { null_if_print,    DLT_NULL },
  185 #ifdef DLT_LOOP
  186     { null_if_print,    DLT_LOOP },
  187 #endif
  188 #if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H)
  189     { pflog_if_print,   DLT_PFLOG },
  190 #endif
  191 #ifdef DLT_PKTAP
  192     { pktap_if_print,   DLT_PKTAP },
  193 #endif
  194 #ifdef DLT_PPI
  195     { ppi_if_print,     DLT_PPI },
  196 #endif
  197 #ifdef DLT_PPP_BSDOS
  198     { ppp_bsdos_if_print,   DLT_PPP_BSDOS },
  199 #endif
  200 #ifdef DLT_PPP_SERIAL
  201     { ppp_hdlc_if_print,    DLT_PPP_SERIAL },
  202 #endif
  203     { ppp_if_print,     DLT_PPP },
  204 #ifdef DLT_PPP_PPPD
  205     { ppp_if_print,     DLT_PPP_PPPD },
  206 #endif
  207 #ifdef DLT_PPP_ETHER
  208     { pppoe_if_print,   DLT_PPP_ETHER },
  209 #endif
  210 #ifdef DLT_PRISM_HEADER
  211     { prism_if_print,   DLT_PRISM_HEADER },
  212 #endif
  213     { raw_if_print,     DLT_RAW },
  214 #ifdef DLT_IPV4
  215     { raw_if_print,     DLT_IPV4 },
  216 #endif
  217 #ifdef DLT_IPV6
  218     { raw_if_print,     DLT_IPV6 },
  219 #endif
  220 #ifdef DLT_SLIP_BSDOS
  221     { sl_bsdos_if_print,    DLT_SLIP_BSDOS },
  222 #endif
  223     { sl_if_print,      DLT_SLIP },
  224 #ifdef DLT_LINUX_SLL
  225     { sll_if_print,     DLT_LINUX_SLL },
  226 #endif
  227 #ifdef DLT_LINUX_SLL2
  228     { sll2_if_print,    DLT_LINUX_SLL2 },
  229 #endif
  230 #ifdef DLT_SUNATM
  231     { sunatm_if_print,  DLT_SUNATM },
  232 #endif
  233 #ifdef DLT_SYMANTEC_FIREWALL
  234     { symantec_if_print,    DLT_SYMANTEC_FIREWALL },
  235 #endif
  236     { token_if_print,   DLT_IEEE802 },
  237 #ifdef DLT_USB_LINUX
  238     { usb_linux_48_byte_if_print, DLT_USB_LINUX},
  239 #endif /* DLT_USB_LINUX */
  240 #ifdef DLT_USB_LINUX_MMAPPED
  241     { usb_linux_64_byte_if_print, DLT_USB_LINUX_MMAPPED},
  242 #endif /* DLT_USB_LINUX_MMAPPED */
  243 #ifdef DLT_VSOCK
  244     { vsock_if_print,   DLT_VSOCK },
  245 #endif
  246     { NULL,                 0 },
  247 };
  248 
  249 static void ndo_default_print(netdissect_options *ndo, const u_char *bp,
  250             u_int length);
  251 
  252 static void NORETURN ndo_error(netdissect_options *ndo,
  253              status_exit_codes_t status,
  254              FORMAT_STRING(const char *fmt), ...)
  255              PRINTFLIKE(3, 4);
  256 static void ndo_warning(netdissect_options *ndo,
  257             FORMAT_STRING(const char *fmt), ...)
  258             PRINTFLIKE(2, 3);
  259 
  260 static int  ndo_printf(netdissect_options *ndo,
  261              FORMAT_STRING(const char *fmt), ...)
  262              PRINTFLIKE(2, 3);
  263 
  264 void
  265 init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask)
  266 {
  267 
  268     init_addrtoname(ndo, localnet, mask);
  269     init_checksum();
  270 }
  271 
  272 if_printer
  273 lookup_printer(int type)
  274 {
  275     const struct printer *p;
  276 
  277     for (p = printers; p->f; ++p)
  278         if (type == p->type)
  279             return p->f;
  280 
  281 #if defined(DLT_USER2) && defined(DLT_PKTAP)
  282     /*
  283      * Apple incorrectly chose to use DLT_USER2 for their PKTAP
  284      * header.
  285      *
  286      * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin-
  287      * based OSes or the same value as LINKTYPE_PKTAP as it is on
  288      * other OSes, to LINKTYPE_PKTAP, so files written with
  289      * this version of libpcap for a DLT_PKTAP capture have a link-
  290      * layer header type of LINKTYPE_PKTAP.
  291      *
  292      * However, files written on OS X Mavericks for a DLT_PKTAP
  293      * capture have a link-layer header type of LINKTYPE_USER2.
  294      * If we don't have a printer for DLT_USER2, and type is
  295      * DLT_USER2, we look up the printer for DLT_PKTAP and use
  296      * that.
  297      */
  298     if (type == DLT_USER2) {
  299         for (p = printers; p->f; ++p)
  300             if (DLT_PKTAP == p->type)
  301                 return p->f;
  302     }
  303 #endif
  304 
  305     return NULL;
  306     /* NOTREACHED */
  307 }
  308 
  309 int
  310 has_printer(int type)
  311 {
  312     return (lookup_printer(type) != NULL);
  313 }
  314 
  315 if_printer
  316 get_if_printer(int type)
  317 {
  318     if_printer printer;
  319 
  320     printer = lookup_printer(type);
  321     if (printer == NULL)
  322         printer = unsupported_if_print;
  323     return printer;
  324 }
  325 
  326 void
  327 pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
  328             const u_char *sp, u_int packets_captured)
  329 {
  330     u_int hdrlen = 0;
  331     int invalid_header = 0;
  332 
  333     if (ndo->ndo_packet_number)
  334         ND_PRINT("%5u  ", packets_captured);
  335 
  336     /* Sanity checks on packet length / capture length */
  337     if (h->caplen == 0) {
  338         invalid_header = 1;
  339         ND_PRINT("[Invalid header: caplen==0");
  340     }
  341     if (h->len == 0) {
  342         if (!invalid_header) {
  343             invalid_header = 1;
  344             ND_PRINT("[Invalid header:");
  345         } else
  346             ND_PRINT(",");
  347         ND_PRINT(" len==0");
  348     } else if (h->len < h->caplen) {
  349         if (!invalid_header) {
  350             invalid_header = 1;
  351             ND_PRINT("[Invalid header:");
  352         } else
  353             ND_PRINT(",");
  354         ND_PRINT(" len(%u) < caplen(%u)", h->len, h->caplen);
  355     }
  356     if (h->caplen > MAXIMUM_SNAPLEN) {
  357         if (!invalid_header) {
  358             invalid_header = 1;
  359             ND_PRINT("[Invalid header:");
  360         } else
  361             ND_PRINT(",");
  362         ND_PRINT(" caplen(%u) > %u", h->caplen, MAXIMUM_SNAPLEN);
  363     }
  364     if (h->len > MAXIMUM_SNAPLEN) {
  365         if (!invalid_header) {
  366             invalid_header = 1;
  367             ND_PRINT("[Invalid header:");
  368         } else
  369             ND_PRINT(",");
  370         ND_PRINT(" len(%u) > %u", h->len, MAXIMUM_SNAPLEN);
  371     }
  372     if (invalid_header) {
  373         ND_PRINT("]\n");
  374         return;
  375     }
  376 
  377     /*
  378      * At this point:
  379      *   capture length != 0,
  380      *   packet length != 0,
  381      *   capture length <= MAXIMUM_SNAPLEN,
  382      *   packet length <= MAXIMUM_SNAPLEN,
  383      *   packet length >= capture length.
  384      *
  385      * Currently, there is no D-Bus printer, thus no need for
  386      * bigger lengths.
  387      */
  388 
  389     /*
  390      * The header /usr/include/pcap/pcap.h in OpenBSD declares h->ts as
  391      * struct bpf_timeval, not struct timeval. The former comes from
  392      * /usr/include/net/bpf.h and uses 32-bit unsigned types instead of
  393      * the types used in struct timeval.
  394      */
  395     struct timeval tvbuf;
  396     tvbuf.tv_sec = h->ts.tv_sec;
  397     tvbuf.tv_usec = h->ts.tv_usec;
  398     ts_print(ndo, &tvbuf);
  399 
  400     /*
  401      * Printers must check that they're not walking off the end of
  402      * the packet.
  403      * Rather than pass it all the way down, we set this member
  404      * of the netdissect_options structure.
  405      */
  406     ndo->ndo_snapend = sp + h->caplen;
  407 
  408     ndo->ndo_protocol = "";
  409     ndo->ndo_ll_hdr_len = 0;
  410     switch (setjmp(ndo->ndo_early_end)) {
  411     case 0:
  412         /* Print the packet. */
  413         (ndo->ndo_if_printer)(ndo, h, sp);
  414         break;
  415     case ND_TRUNCATED:
  416         /* A printer quit because the packet was truncated; report it */
  417         nd_print_trunc(ndo);
  418         /* Print the full packet */
  419         ndo->ndo_ll_hdr_len = 0;
  420         break;
  421     }
  422     hdrlen = ndo->ndo_ll_hdr_len;
  423 
  424     /*
  425      * Empty the stack of packet information, freeing all pushed buffers;
  426      * if we got here by a printer quitting, we need to release anything
  427      * that didn't get released because we longjmped out of the code
  428      * before it popped the packet information.
  429      */
  430     nd_pop_all_packet_info(ndo);
  431 
  432     /*
  433      * Restore the original snapend, as a printer might have
  434      * changed it.
  435      */
  436     ndo->ndo_snapend = sp + h->caplen;
  437     if (ndo->ndo_Xflag) {
  438         /*
  439          * Print the raw packet data in hex and ASCII.
  440          */
  441         if (ndo->ndo_Xflag > 1) {
  442             /*
  443              * Include the link-layer header.
  444              */
  445             hex_and_ascii_print(ndo, "\n\t", sp, h->caplen);
  446         } else {
  447             /*
  448              * Don't include the link-layer header - and if
  449              * we have nothing past the link-layer header,
  450              * print nothing.
  451              */
  452             if (h->caplen > hdrlen)
  453                 hex_and_ascii_print(ndo, "\n\t", sp + hdrlen,
  454                             h->caplen - hdrlen);
  455         }
  456     } else if (ndo->ndo_xflag) {
  457         /*
  458          * Print the raw packet data in hex.
  459          */
  460         if (ndo->ndo_xflag > 1) {
  461             /*
  462              * Include the link-layer header.
  463              */
  464             hex_print(ndo, "\n\t", sp, h->caplen);
  465         } else {
  466             /*
  467              * Don't include the link-layer header - and if
  468              * we have nothing past the link-layer header,
  469              * print nothing.
  470              */
  471             if (h->caplen > hdrlen)
  472                 hex_print(ndo, "\n\t", sp + hdrlen,
  473                       h->caplen - hdrlen);
  474         }
  475     } else if (ndo->ndo_Aflag) {
  476         /*
  477          * Print the raw packet data in ASCII.
  478          */
  479         if (ndo->ndo_Aflag > 1) {
  480             /*
  481              * Include the link-layer header.
  482              */
  483             ascii_print(ndo, sp, h->caplen);
  484         } else {
  485             /*
  486              * Don't include the link-layer header - and if
  487              * we have nothing past the link-layer header,
  488              * print nothing.
  489              */
  490             if (h->caplen > hdrlen)
  491                 ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen);
  492         }
  493     }
  494 
  495     ND_PRINT("\n");
  496     nd_free_all(ndo);
  497 }
  498 
  499 /*
  500  * By default, print the specified data out in hex and ASCII.
  501  */
  502 static void
  503 ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length)
  504 {
  505     hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */
  506 }
  507 
  508 /* VARARGS */
  509 static void
  510 ndo_error(netdissect_options *ndo, status_exit_codes_t status,
  511       const char *fmt, ...)
  512 {
  513     va_list ap;
  514 
  515     if (ndo->program_name)
  516         (void)fprintf(stderr, "%s: ", ndo->program_name);
  517     va_start(ap, fmt);
  518     (void)vfprintf(stderr, fmt, ap);
  519     va_end(ap);
  520     if (*fmt) {
  521         fmt += strlen(fmt);
  522         if (fmt[-1] != '\n')
  523             (void)fputc('\n', stderr);
  524     }
  525     nd_cleanup();
  526     exit(status);
  527     /* NOTREACHED */
  528 }
  529 
  530 /* VARARGS */
  531 static void
  532 ndo_warning(netdissect_options *ndo, const char *fmt, ...)
  533 {
  534     va_list ap;
  535 
  536     if (ndo->program_name)
  537         (void)fprintf(stderr, "%s: ", ndo->program_name);
  538     (void)fprintf(stderr, "WARNING: ");
  539     va_start(ap, fmt);
  540     (void)vfprintf(stderr, fmt, ap);
  541     va_end(ap);
  542     if (*fmt) {
  543         fmt += strlen(fmt);
  544         if (fmt[-1] != '\n')
  545             (void)fputc('\n', stderr);
  546     }
  547 }
  548 
  549 static int
  550 ndo_printf(netdissect_options *ndo, const char *fmt, ...)
  551 {
  552     va_list args;
  553     int ret;
  554 
  555     va_start(args, fmt);
  556     ret = vfprintf(stdout, fmt, args);
  557     va_end(args);
  558 
  559     if (ret < 0)
  560         ndo_error(ndo, S_ERR_ND_WRITE_FILE,
  561               "Unable to write output: %s", pcap_strerror(errno));
  562     return (ret);
  563 }
  564 
  565 void
  566 ndo_set_function_pointers(netdissect_options *ndo)
  567 {
  568     ndo->ndo_default_print=ndo_default_print;
  569     ndo->ndo_printf=ndo_printf;
  570     ndo->ndo_error=ndo_error;
  571     ndo->ndo_warning=ndo_warning;
  572 }