]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print.c
CI: Add warning exemptions for Sun C (suncc-5.14) on Solaris 10
[tcpdump] / print.c
diff --git a/print.c b/print.c
index 7ab74727b6eeaaea7c9d53c4418d35b820285dcf..f67597e3a51a3aaeeb1d1e4cd1f1c851ef7463eb 100644 (file)
--- a/print.c
+++ b/print.c
  *     Seth Webster <[email protected]>
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
 #include <stdlib.h>
 #include <string.h>
+#include <setjmp.h>
 
 #include "netdissect-stdinc.h"
 
 #include "netdissect.h"
 #include "addrtoname.h"
 #include "print.h"
+#include "netdissect-alloc.h"
 
 struct printer {
        if_printer f;
@@ -44,69 +44,22 @@ struct printer {
 };
 
 static const struct printer printers[] = {
-       { ether_if_print,       DLT_EN10MB },
-#ifdef DLT_IPNET
-       { ipnet_if_print,       DLT_IPNET },
-#endif
-#ifdef DLT_IEEE802_15_4
-       { ieee802_15_4_if_print, DLT_IEEE802_15_4 },
-#endif
-#ifdef DLT_IEEE802_15_4_NOFCS
-       { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS },
-#endif
-#ifdef DLT_PPI
-       { ppi_if_print,         DLT_PPI },
-#endif
-#ifdef DLT_NETANALYZER
-       { netanalyzer_if_print, DLT_NETANALYZER },
-#endif
-#ifdef DLT_NETANALYZER_TRANSPARENT
-       { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT },
-#endif
-#if defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H)
-       { nflog_if_print,       DLT_NFLOG},
-#endif
-#ifdef DLT_CIP
-       { cip_if_print,         DLT_CIP },
-#endif
-#ifdef DLT_ATM_CLIP
-       { cip_if_print,         DLT_ATM_CLIP },
-#endif
-#ifdef DLT_IP_OVER_FC
-       { ipfc_if_print,        DLT_IP_OVER_FC },
-#endif
-       { null_if_print,        DLT_NULL },
-#ifdef DLT_LOOP
-       { null_if_print,        DLT_LOOP },
-#endif
 #ifdef DLT_APPLE_IP_OVER_IEEE1394
        { ap1394_if_print,      DLT_APPLE_IP_OVER_IEEE1394 },
-#endif
-#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H)
-       { bt_if_print,          DLT_BLUETOOTH_HCI_H4_WITH_PHDR},
-#endif
-#ifdef DLT_LANE8023
-       { lane_if_print,        DLT_LANE8023 },
 #endif
        { arcnet_if_print,      DLT_ARCNET },
 #ifdef DLT_ARCNET_LINUX
        { arcnet_linux_if_print, DLT_ARCNET_LINUX },
 #endif
-       { raw_if_print,         DLT_RAW },
-#ifdef DLT_IPV4
-       { raw_if_print,         DLT_IPV4 },
+       { atm_if_print,         DLT_ATM_RFC1483 },
+#ifdef DLT_DSA_TAG_BRCM
+       { brcm_tag_if_print,    DLT_DSA_TAG_BRCM },
 #endif
-#ifdef DLT_IPV6
-       { raw_if_print,         DLT_IPV6 },
+#ifdef DLT_DSA_TAG_BRCM_PREPEND
+       { brcm_tag_prepend_if_print, DLT_DSA_TAG_BRCM_PREPEND },
 #endif
-#ifdef DLT_USB_LINUX
-       { usb_linux_48_byte_if_print, DLT_USB_LINUX},
-#endif /* DLT_USB_LINUX */
-#ifdef DLT_USB_LINUX_MMAPPED
-       { usb_linux_64_byte_if_print, DLT_USB_LINUX_MMAPPED},
-#endif /* DLT_USB_LINUX_MMAPPED */
-#ifdef DLT_SYMANTEC_FIREWALL
-       { symantec_if_print,    DLT_SYMANTEC_FIREWALL },
+#ifdef DLT_BLUETOOTH_HCI_H4_WITH_PHDR
+       { bt_if_print,          DLT_BLUETOOTH_HCI_H4_WITH_PHDR},
 #endif
 #ifdef DLT_C_HDLC
        { chdlc_if_print,       DLT_C_HDLC },
@@ -114,39 +67,55 @@ static const struct printer printers[] = {
 #ifdef DLT_HDLC
        { chdlc_if_print,       DLT_HDLC },
 #endif
-#ifdef DLT_PPP_ETHER
-       { pppoe_if_print,       DLT_PPP_ETHER },
+#ifdef DLT_ATM_CLIP
+       { cip_if_print,         DLT_ATM_CLIP },
 #endif
-#if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H)
-       { pflog_if_print,       DLT_PFLOG },
+#ifdef DLT_CIP
+       { cip_if_print,         DLT_CIP },
 #endif
-       { token_if_print,       DLT_IEEE802 },
-       { fddi_if_print,        DLT_FDDI },
-#ifdef DLT_LINUX_SLL
-       { sll_if_print,         DLT_LINUX_SLL },
+#ifdef DLT_DSA_TAG_DSA
+       { dsa_if_print,         DLT_DSA_TAG_DSA },
+#endif
+#ifdef DLT_DSA_TAG_EDSA
+       { edsa_if_print,        DLT_DSA_TAG_EDSA },
+#endif
+#ifdef DLT_ENC
+       { enc_if_print,         DLT_ENC },
 #endif
+       { ether_if_print,       DLT_EN10MB },
+       { fddi_if_print,        DLT_FDDI },
 #ifdef DLT_FR
        { fr_if_print,          DLT_FR },
 #endif
 #ifdef DLT_FRELAY
        { fr_if_print,          DLT_FRELAY },
 #endif
-#ifdef DLT_MFR
-       { mfr_if_print,         DLT_MFR },
+#ifdef DLT_IEEE802_11
+       { ieee802_11_if_print,  DLT_IEEE802_11},
 #endif
-       { atm_if_print,         DLT_ATM_RFC1483 },
-#ifdef DLT_SUNATM
-       { sunatm_if_print,      DLT_SUNATM },
+#ifdef DLT_IEEE802_11_RADIO_AVS
+       { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS },
 #endif
-#ifdef DLT_ENC
-       { enc_if_print,         DLT_ENC },
+#ifdef DLT_IEEE802_11_RADIO
+       { ieee802_11_radio_if_print,    DLT_IEEE802_11_RADIO },
 #endif
-       { sl_if_print,          DLT_SLIP },
-#ifdef DLT_SLIP_BSDOS
-       { sl_bsdos_if_print,    DLT_SLIP_BSDOS },
+#ifdef DLT_IEEE802_15_4
+       { ieee802_15_4_if_print, DLT_IEEE802_15_4 },
 #endif
-#ifdef DLT_LTALK
-       { ltalk_if_print,       DLT_LTALK },
+#ifdef DLT_IEEE802_15_4_NOFCS
+       { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS },
+#endif
+#ifdef DLT_IEEE802_15_4_TAP
+       { ieee802_15_4_tap_if_print, DLT_IEEE802_15_4_TAP },
+#endif
+#ifdef DLT_IP_OVER_FC
+       { ipfc_if_print,        DLT_IP_OVER_FC },
+#endif
+#ifdef DLT_IPNET
+       { ipnet_if_print,       DLT_IPNET },
+#endif
+#ifdef DLT_IPOIB
+       { ipoib_if_print,       DLT_IPOIB },
 #endif
 #ifdef DLT_JUNIPER_ATM1
        { juniper_atm1_if_print, DLT_JUNIPER_ATM1 },
@@ -154,6 +123,21 @@ static const struct printer printers[] = {
 #ifdef DLT_JUNIPER_ATM2
        { juniper_atm2_if_print, DLT_JUNIPER_ATM2 },
 #endif
+#ifdef DLT_JUNIPER_CHDLC
+       { juniper_chdlc_if_print,       DLT_JUNIPER_CHDLC },
+#endif
+#ifdef DLT_JUNIPER_ES
+       { juniper_es_if_print,  DLT_JUNIPER_ES },
+#endif
+#ifdef DLT_JUNIPER_ETHER
+       { juniper_ether_if_print,       DLT_JUNIPER_ETHER },
+#endif
+#ifdef DLT_JUNIPER_FRELAY
+       { juniper_frelay_if_print,      DLT_JUNIPER_FRELAY },
+#endif
+#ifdef DLT_JUNIPER_GGSN
+       { juniper_ggsn_if_print, DLT_JUNIPER_GGSN },
+#endif
 #ifdef DLT_JUNIPER_MFR
        { juniper_mfr_if_print, DLT_JUNIPER_MFR },
 #endif
@@ -163,86 +147,103 @@ static const struct printer printers[] = {
 #ifdef DLT_JUNIPER_MLPPP
        { juniper_mlppp_if_print, DLT_JUNIPER_MLPPP },
 #endif
-#ifdef DLT_JUNIPER_PPPOE
-       { juniper_pppoe_if_print, DLT_JUNIPER_PPPOE },
+#ifdef DLT_JUNIPER_MONITOR
+       { juniper_monitor_if_print, DLT_JUNIPER_MONITOR },
+#endif
+#ifdef DLT_JUNIPER_PPP
+       { juniper_ppp_if_print, DLT_JUNIPER_PPP },
 #endif
 #ifdef DLT_JUNIPER_PPPOE_ATM
        { juniper_pppoe_atm_if_print, DLT_JUNIPER_PPPOE_ATM },
 #endif
-#ifdef DLT_JUNIPER_GGSN
-       { juniper_ggsn_if_print, DLT_JUNIPER_GGSN },
-#endif
-#ifdef DLT_JUNIPER_ES
-       { juniper_es_if_print,  DLT_JUNIPER_ES },
-#endif
-#ifdef DLT_JUNIPER_MONITOR
-       { juniper_monitor_if_print, DLT_JUNIPER_MONITOR },
+#ifdef DLT_JUNIPER_PPPOE
+       { juniper_pppoe_if_print, DLT_JUNIPER_PPPOE },
 #endif
 #ifdef DLT_JUNIPER_SERVICES
        { juniper_services_if_print, DLT_JUNIPER_SERVICES },
 #endif
-#ifdef DLT_JUNIPER_ETHER
-       { juniper_ether_if_print,       DLT_JUNIPER_ETHER },
+#ifdef DLT_LTALK
+       { ltalk_if_print,       DLT_LTALK },
 #endif
-#ifdef DLT_JUNIPER_PPP
-       { juniper_ppp_if_print, DLT_JUNIPER_PPP },
+#ifdef DLT_MFR
+       { mfr_if_print,         DLT_MFR },
 #endif
-#ifdef DLT_JUNIPER_FRELAY
-       { juniper_frelay_if_print,      DLT_JUNIPER_FRELAY },
+#ifdef DLT_NETANALYZER
+       { netanalyzer_if_print, DLT_NETANALYZER },
 #endif
-#ifdef DLT_JUNIPER_CHDLC
-       { juniper_chdlc_if_print,       DLT_JUNIPER_CHDLC },
+#ifdef DLT_NETANALYZER_TRANSPARENT
+       { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT },
+#endif
+#ifdef DLT_NFLOG
+       { nflog_if_print,       DLT_NFLOG},
+#endif
+       { null_if_print,        DLT_NULL },
+#ifdef DLT_LOOP
+       { null_if_print,        DLT_LOOP },
+#endif
+#ifdef DLT_PFLOG
+       { pflog_if_print,       DLT_PFLOG },
 #endif
 #ifdef DLT_PKTAP
        { pktap_if_print,       DLT_PKTAP },
 #endif
-#ifdef DLT_IEEE802_11_RADIO
-       { ieee802_11_radio_if_print,    DLT_IEEE802_11_RADIO },
+#ifdef DLT_PPI
+       { ppi_if_print,         DLT_PPI },
 #endif
-#ifdef DLT_IEEE802_11
-       { ieee802_11_if_print,  DLT_IEEE802_11},
+#ifdef DLT_PPP_SERIAL
+       { ppp_hdlc_if_print,    DLT_PPP_SERIAL },
 #endif
-#ifdef DLT_IEEE802_11_RADIO_AVS
-       { ieee802_11_radio_avs_if_print,        DLT_IEEE802_11_RADIO_AVS },
+       { ppp_if_print,         DLT_PPP },
+#ifdef DLT_PPP_PPPD
+       { ppp_if_print,         DLT_PPP_PPPD },
+#endif
+#ifdef DLT_PPP_ETHER
+       { pppoe_if_print,       DLT_PPP_ETHER },
 #endif
 #ifdef DLT_PRISM_HEADER
        { prism_if_print,       DLT_PRISM_HEADER },
 #endif
-       { ppp_if_print,         DLT_PPP },
-#ifdef DLT_PPP_WITHDIRECTION
-       { ppp_if_print,         DLT_PPP_WITHDIRECTION },
+       { raw_if_print,         DLT_RAW },
+#ifdef DLT_IPV4
+       { raw_if_print,         DLT_IPV4 },
 #endif
-#ifdef DLT_PPP_BSDOS
-       { ppp_bsdos_if_print,   DLT_PPP_BSDOS },
+#ifdef DLT_IPV6
+       { raw_if_print,         DLT_IPV6 },
 #endif
-#ifdef DLT_PPP_SERIAL
-       { ppp_hdlc_if_print,    DLT_PPP_SERIAL },
+#ifdef DLT_SLIP_BSDOS
+       { sl_bsdos_if_print,    DLT_SLIP_BSDOS },
+#endif
+       { sl_if_print,          DLT_SLIP },
+#ifdef DLT_LINUX_SLL
+       { sll_if_print,         DLT_LINUX_SLL },
+#endif
+#ifdef DLT_LINUX_SLL2
+       { sll2_if_print,        DLT_LINUX_SLL2 },
 #endif
-       { NULL,                 0 },
+#ifdef DLT_SUNATM
+       { sunatm_if_print,      DLT_SUNATM },
+#endif
+#ifdef DLT_SYMANTEC_FIREWALL
+       { symantec_if_print,    DLT_SYMANTEC_FIREWALL },
+#endif
+       { token_if_print,       DLT_IEEE802 },
+#ifdef DLT_USB_LINUX
+       { usb_linux_48_byte_if_print, DLT_USB_LINUX},
+#endif /* DLT_USB_LINUX */
+#ifdef DLT_USB_LINUX_MMAPPED
+       { usb_linux_64_byte_if_print, DLT_USB_LINUX_MMAPPED},
+#endif /* DLT_USB_LINUX_MMAPPED */
+#ifdef DLT_VSOCK
+       { vsock_if_print,       DLT_VSOCK },
+#endif
+       { NULL,                 0 },
 };
 
-static void    ndo_default_print(netdissect_options *ndo, const u_char *bp,
-                   u_int length);
-
-static void NORETURN ndo_error(netdissect_options *ndo,
-                    FORMAT_STRING(const char *fmt), ...)
-                    PRINTFLIKE(2, 3);
-static void    ndo_warning(netdissect_options *ndo,
-                   FORMAT_STRING(const char *fmt), ...)
-                   PRINTFLIKE(2, 3);
-
-static int     ndo_printf(netdissect_options *ndo,
-                    FORMAT_STRING(const char *fmt), ...)
-                    PRINTFLIKE(2, 3);
-
+// Both localnet and mask are in network byte order.
 void
-init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask,
-    uint32_t timezone_offset)
+init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask)
 {
-
-       thiszone = timezone_offset;
        init_addrtoname(ndo, localnet, mask);
-       init_checksum();
 }
 
 if_printer
@@ -289,61 +290,105 @@ has_printer(int type)
 }
 
 if_printer
-get_if_printer(netdissect_options *ndo, int type)
+get_if_printer(int type)
 {
-       const char *dltname;
        if_printer printer;
 
        printer = lookup_printer(type);
-       if (printer == NULL) {
-               dltname = pcap_datalink_val_to_name(type);
-               if (dltname != NULL)
-                       (*ndo->ndo_error)(ndo,
-                                         "packet printing is not supported for link type %s: use -w",
-                                         dltname);
-               else
-                       (*ndo->ndo_error)(ndo,
-                                         "packet printing is not supported for link type %d: use -w", type);
-       }
+       if (printer == NULL)
+               printer = unsupported_if_print;
        return printer;
 }
 
+#ifdef ENABLE_INSTRUMENT_FUNCTIONS
+extern int profile_func_level;
+static int pretty_print_packet_level = -1;
+#endif
+
 void
 pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
-    const u_char *sp, u_int packets_captured)
+                   const u_char *sp, u_int packets_captured)
 {
-       u_int hdrlen;
+       u_int hdrlen = 0;
+       int invalid_header = 0;
 
-       if(ndo->ndo_packet_number)
+       if (ndo->ndo_print_sampling && packets_captured % ndo->ndo_print_sampling != 0)
+               return;
+
+#ifdef ENABLE_INSTRUMENT_FUNCTIONS
+       if (pretty_print_packet_level == -1)
+               pretty_print_packet_level = profile_func_level;
+#endif
+
+       if (ndo->ndo_packet_number)
                ND_PRINT("%5u  ", packets_captured);
 
+       if (ndo->ndo_lengths)
+               ND_PRINT("caplen %u len %u ", h->caplen, h->len);
+
        /* Sanity checks on packet length / capture length */
-       ndo->ndo_invalid_header = 0;
-       if(h->caplen == 0) {
-               ndo->ndo_invalid_header = 1;
+       if (h->caplen == 0) {
+               invalid_header = 1;
                ND_PRINT("[Invalid header: caplen==0");
        }
        if (h->len == 0) {
-               if (!ndo->ndo_invalid_header) {
-                       ndo->ndo_invalid_header = 1;
+               if (!invalid_header) {
+                       invalid_header = 1;
                        ND_PRINT("[Invalid header:");
                } else
                        ND_PRINT(",");
                ND_PRINT(" len==0");
        } else if (h->len < h->caplen) {
-               if (!ndo->ndo_invalid_header) {
-                       ndo->ndo_invalid_header = 1;
+               if (!invalid_header) {
+                       invalid_header = 1;
                        ND_PRINT("[Invalid header:");
                } else
                        ND_PRINT(",");
                ND_PRINT(" len(%u) < caplen(%u)", h->len, h->caplen);
        }
-       if (ndo->ndo_invalid_header) {
+       if (h->caplen > MAXIMUM_SNAPLEN) {
+               if (!invalid_header) {
+                       invalid_header = 1;
+                       ND_PRINT("[Invalid header:");
+               } else
+                       ND_PRINT(",");
+               ND_PRINT(" caplen(%u) > %u", h->caplen, MAXIMUM_SNAPLEN);
+       }
+       if (h->len > MAXIMUM_SNAPLEN) {
+               if (!invalid_header) {
+                       invalid_header = 1;
+                       ND_PRINT("[Invalid header:");
+               } else
+                       ND_PRINT(",");
+               ND_PRINT(" len(%u) > %u", h->len, MAXIMUM_SNAPLEN);
+       }
+       if (invalid_header) {
                ND_PRINT("]\n");
                return;
        }
 
-       ts_print(ndo, &h->ts);
+       /*
+        * At this point:
+        *   capture length != 0,
+        *   packet length != 0,
+        *   capture length <= MAXIMUM_SNAPLEN,
+        *   packet length <= MAXIMUM_SNAPLEN,
+        *   packet length >= capture length.
+        *
+        * Currently, there is no D-Bus printer, thus no need for
+        * bigger lengths.
+        */
+
+       /*
+        * The header /usr/include/pcap/pcap.h in OpenBSD declares h->ts as
+        * struct bpf_timeval, not struct timeval. The former comes from
+        * /usr/include/net/bpf.h and uses 32-bit unsigned types instead of
+        * the types used in struct timeval.
+        */
+       struct timeval tvbuf;
+       tvbuf.tv_sec = h->ts.tv_sec;
+       tvbuf.tv_usec = h->ts.tv_usec;
+       ts_print(ndo, &tvbuf);
 
        /*
         * Printers must check that they're not walking off the end of
@@ -352,14 +397,45 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
         * of the netdissect_options structure.
         */
        ndo->ndo_snapend = sp + h->caplen;
+       ndo->ndo_packetp = sp;
+
+       ndo->ndo_protocol = "";
+       ndo->ndo_ll_hdr_len = 0;
+       switch (setjmp(ndo->ndo_early_end)) {
+       case 0:
+               /* Print the packet. */
+               (ndo->ndo_if_printer)(ndo, h, sp);
+               break;
+       case ND_TRUNCATED:
+               /* A printer quit because the packet was truncated; report it */
+               nd_print_trunc(ndo);
+               /* Print the full packet */
+               ndo->ndo_ll_hdr_len = 0;
+#ifdef ENABLE_INSTRUMENT_FUNCTIONS
+               /* truncation => reassignment */
+               profile_func_level = pretty_print_packet_level;
+#endif
+               break;
+       }
+       hdrlen = ndo->ndo_ll_hdr_len;
 
-        hdrlen = (ndo->ndo_if_printer)(ndo, h, sp);
+       /*
+        * Empty the stack of packet information, freeing all pushed buffers;
+        * if we got here by a printer quitting, we need to release anything
+        * that didn't get released because we longjmped out of the code
+        * before it popped the packet information.
+        */
+       nd_pop_all_packet_info(ndo);
 
        /*
-        * Restore the original snapend, as a printer might have
-        * changed it.
+        * Restore the originals snapend and packetp, as a printer
+        * might have changed them.
+        *
+        * XXX - nd_pop_all_packet_info() should have restored the
+        * original values, but, just in case....
         */
        ndo->ndo_snapend = sp + h->caplen;
+       ndo->ndo_packetp = sp;
        if (ndo->ndo_Xflag) {
                /*
                 * Print the raw packet data in hex and ASCII.
@@ -377,7 +453,7 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
                         */
                        if (h->caplen > hdrlen)
                                hex_and_ascii_print(ndo, "\n\t", sp + hdrlen,
-                                   h->caplen - hdrlen);
+                                                   h->caplen - hdrlen);
                }
        } else if (ndo->ndo_xflag) {
                /*
@@ -387,7 +463,7 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
                        /*
                         * Include the link-layer header.
                         */
-                        hex_print(ndo, "\n\t", sp, h->caplen);
+                       hex_print(ndo, "\n\t", sp, h->caplen);
                } else {
                        /*
                         * Don't include the link-layer header - and if
@@ -396,7 +472,7 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
                         */
                        if (h->caplen > hdrlen)
                                hex_print(ndo, "\n\t", sp + hdrlen,
-                                          h->caplen - hdrlen);
+                                         h->caplen - hdrlen);
                }
        } else if (ndo->ndo_Aflag) {
                /*
@@ -419,6 +495,7 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
        }
 
        ND_PRINT("\n");
+       nd_free_all(ndo);
 }
 
 /*
@@ -431,12 +508,13 @@ ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length)
 }
 
 /* VARARGS */
-static void
-ndo_error(netdissect_options *ndo, const char *fmt, ...)
+static void NORETURN PRINTFLIKE(3, 4)
+ndo_error(netdissect_options *ndo, status_exit_codes_t status,
+          FORMAT_STRING(const char *fmt), ...)
 {
        va_list ap;
 
-       if(ndo->program_name)
+       if (ndo->program_name)
                (void)fprintf(stderr, "%s: ", ndo->program_name);
        va_start(ap, fmt);
        (void)vfprintf(stderr, fmt, ap);
@@ -447,17 +525,17 @@ ndo_error(netdissect_options *ndo, const char *fmt, ...)
                        (void)fputc('\n', stderr);
        }
        nd_cleanup();
-       exit(1);
+       exit(status);
        /* NOTREACHED */
 }
 
 /* VARARGS */
-static void
-ndo_warning(netdissect_options *ndo, const char *fmt, ...)
+static void PRINTFLIKE(2, 3)
+ndo_warning(netdissect_options *ndo, FORMAT_STRING(const char *fmt), ...)
 {
        va_list ap;
 
-       if(ndo->program_name)
+       if (ndo->program_name)
                (void)fprintf(stderr, "%s: ", ndo->program_name);
        (void)fprintf(stderr, "WARNING: ");
        va_start(ap, fmt);
@@ -470,8 +548,9 @@ ndo_warning(netdissect_options *ndo, const char *fmt, ...)
        }
 }
 
-static int
-ndo_printf(netdissect_options *ndo, const char *fmt, ...)
+/* VARARGS */
+static int PRINTFLIKE(2, 3)
+ndo_printf(netdissect_options *ndo, FORMAT_STRING(const char *fmt), ...)
 {
        va_list args;
        int ret;
@@ -481,7 +560,8 @@ ndo_printf(netdissect_options *ndo, const char *fmt, ...)
        va_end(args);
 
        if (ret < 0)
-               ndo_error(ndo, "Unable to write output: %s", pcap_strerror(errno));
+               ndo_error(ndo, S_ERR_ND_WRITE_FILE,
+                         "Unable to write output: %s", pcap_strerror(errno));
        return (ret);
 }
 
@@ -493,9 +573,3 @@ ndo_set_function_pointers(netdissect_options *ndo)
        ndo->ndo_error=ndo_error;
        ndo->ndo_warning=ndo_warning;
 }
-/*
- * Local Variables:
- * c-style: whitesmith
- * c-basic-offset: 8
- * End:
- */