1*3340d773SGleb Smirnoff /* 2*3340d773SGleb Smirnoff * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 3*3340d773SGleb Smirnoff * The Regents of the University of California. All rights reserved. 4*3340d773SGleb Smirnoff * 5*3340d773SGleb Smirnoff * Redistribution and use in source and binary forms, with or without 6*3340d773SGleb Smirnoff * modification, are permitted provided that: (1) source code distributions 7*3340d773SGleb Smirnoff * retain the above copyright notice and this paragraph in its entirety, (2) 8*3340d773SGleb Smirnoff * distributions including binary code include the above copyright notice and 9*3340d773SGleb Smirnoff * this paragraph in its entirety in the documentation or other materials 10*3340d773SGleb Smirnoff * provided with the distribution, and (3) all advertising materials mentioning 11*3340d773SGleb Smirnoff * features or use of this software display the following acknowledgement: 12*3340d773SGleb Smirnoff * ``This product includes software developed by the University of California, 13*3340d773SGleb Smirnoff * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14*3340d773SGleb Smirnoff * the University nor the names of its contributors may be used to endorse 15*3340d773SGleb Smirnoff * or promote products derived from this software without specific prior 16*3340d773SGleb Smirnoff * written permission. 17*3340d773SGleb Smirnoff * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18*3340d773SGleb Smirnoff * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19*3340d773SGleb Smirnoff * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20*3340d773SGleb Smirnoff * 21*3340d773SGleb Smirnoff * Support for splitting captures into multiple files with a maximum 22*3340d773SGleb Smirnoff * file size: 23*3340d773SGleb Smirnoff * 24*3340d773SGleb Smirnoff * Copyright (c) 2001 25*3340d773SGleb Smirnoff * Seth Webster <swebster@sst.ll.mit.edu> 26*3340d773SGleb Smirnoff */ 27*3340d773SGleb Smirnoff 28*3340d773SGleb Smirnoff #ifdef HAVE_CONFIG_H 29*3340d773SGleb Smirnoff #include "config.h" 30*3340d773SGleb Smirnoff #endif 31*3340d773SGleb Smirnoff 32*3340d773SGleb Smirnoff #include <stdlib.h> 33*3340d773SGleb Smirnoff #include <string.h> 34*3340d773SGleb Smirnoff 35*3340d773SGleb Smirnoff #include <netdissect-stdinc.h> 36*3340d773SGleb Smirnoff 37*3340d773SGleb Smirnoff #include "netdissect.h" 38*3340d773SGleb Smirnoff #include "addrtoname.h" 39*3340d773SGleb Smirnoff #include "print.h" 40*3340d773SGleb Smirnoff 41*3340d773SGleb Smirnoff struct printer { 42*3340d773SGleb Smirnoff if_printer f; 43*3340d773SGleb Smirnoff int type; 44*3340d773SGleb Smirnoff }; 45*3340d773SGleb Smirnoff 46*3340d773SGleb Smirnoff static const struct printer printers[] = { 47*3340d773SGleb Smirnoff { ether_if_print, DLT_EN10MB }, 48*3340d773SGleb Smirnoff #ifdef DLT_IPNET 49*3340d773SGleb Smirnoff { ipnet_if_print, DLT_IPNET }, 50*3340d773SGleb Smirnoff #endif 51*3340d773SGleb Smirnoff #ifdef DLT_IEEE802_15_4 52*3340d773SGleb Smirnoff { ieee802_15_4_if_print, DLT_IEEE802_15_4 }, 53*3340d773SGleb Smirnoff #endif 54*3340d773SGleb Smirnoff #ifdef DLT_IEEE802_15_4_NOFCS 55*3340d773SGleb Smirnoff { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS }, 56*3340d773SGleb Smirnoff #endif 57*3340d773SGleb Smirnoff #ifdef DLT_PPI 58*3340d773SGleb Smirnoff { ppi_if_print, DLT_PPI }, 59*3340d773SGleb Smirnoff #endif 60*3340d773SGleb Smirnoff #ifdef DLT_NETANALYZER 61*3340d773SGleb Smirnoff { netanalyzer_if_print, DLT_NETANALYZER }, 62*3340d773SGleb Smirnoff #endif 63*3340d773SGleb Smirnoff #ifdef DLT_NETANALYZER_TRANSPARENT 64*3340d773SGleb Smirnoff { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT }, 65*3340d773SGleb Smirnoff #endif 66*3340d773SGleb Smirnoff #if defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H) 67*3340d773SGleb Smirnoff { nflog_if_print, DLT_NFLOG}, 68*3340d773SGleb Smirnoff #endif 69*3340d773SGleb Smirnoff #ifdef DLT_CIP 70*3340d773SGleb Smirnoff { cip_if_print, DLT_CIP }, 71*3340d773SGleb Smirnoff #endif 72*3340d773SGleb Smirnoff #ifdef DLT_ATM_CLIP 73*3340d773SGleb Smirnoff { cip_if_print, DLT_ATM_CLIP }, 74*3340d773SGleb Smirnoff #endif 75*3340d773SGleb Smirnoff #ifdef DLT_IP_OVER_FC 76*3340d773SGleb Smirnoff { ipfc_if_print, DLT_IP_OVER_FC }, 77*3340d773SGleb Smirnoff #endif 78*3340d773SGleb Smirnoff { null_if_print, DLT_NULL }, 79*3340d773SGleb Smirnoff #ifdef DLT_LOOP 80*3340d773SGleb Smirnoff { null_if_print, DLT_LOOP }, 81*3340d773SGleb Smirnoff #endif 82*3340d773SGleb Smirnoff #ifdef DLT_APPLE_IP_OVER_IEEE1394 83*3340d773SGleb Smirnoff { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, 84*3340d773SGleb Smirnoff #endif 85*3340d773SGleb Smirnoff #if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) 86*3340d773SGleb Smirnoff { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, 87*3340d773SGleb Smirnoff #endif 88*3340d773SGleb Smirnoff #ifdef DLT_LANE8023 89*3340d773SGleb Smirnoff { lane_if_print, DLT_LANE8023 }, 90*3340d773SGleb Smirnoff #endif 91*3340d773SGleb Smirnoff { arcnet_if_print, DLT_ARCNET }, 92*3340d773SGleb Smirnoff #ifdef DLT_ARCNET_LINUX 93*3340d773SGleb Smirnoff { arcnet_linux_if_print, DLT_ARCNET_LINUX }, 94*3340d773SGleb Smirnoff #endif 95*3340d773SGleb Smirnoff { raw_if_print, DLT_RAW }, 96*3340d773SGleb Smirnoff #ifdef DLT_IPV4 97*3340d773SGleb Smirnoff { raw_if_print, DLT_IPV4 }, 98*3340d773SGleb Smirnoff #endif 99*3340d773SGleb Smirnoff #ifdef DLT_IPV6 100*3340d773SGleb Smirnoff { raw_if_print, DLT_IPV6 }, 101*3340d773SGleb Smirnoff #endif 102*3340d773SGleb Smirnoff #ifdef HAVE_PCAP_USB_H 103*3340d773SGleb Smirnoff #ifdef DLT_USB_LINUX 104*3340d773SGleb Smirnoff { usb_linux_48_byte_print, DLT_USB_LINUX}, 105*3340d773SGleb Smirnoff #endif /* DLT_USB_LINUX */ 106*3340d773SGleb Smirnoff #ifdef DLT_USB_LINUX_MMAPPED 107*3340d773SGleb Smirnoff { usb_linux_64_byte_print, DLT_USB_LINUX_MMAPPED}, 108*3340d773SGleb Smirnoff #endif /* DLT_USB_LINUX_MMAPPED */ 109*3340d773SGleb Smirnoff #endif /* HAVE_PCAP_USB_H */ 110*3340d773SGleb Smirnoff #ifdef DLT_SYMANTEC_FIREWALL 111*3340d773SGleb Smirnoff { symantec_if_print, DLT_SYMANTEC_FIREWALL }, 112*3340d773SGleb Smirnoff #endif 113*3340d773SGleb Smirnoff #ifdef DLT_C_HDLC 114*3340d773SGleb Smirnoff { chdlc_if_print, DLT_C_HDLC }, 115*3340d773SGleb Smirnoff #endif 116*3340d773SGleb Smirnoff #ifdef DLT_HDLC 117*3340d773SGleb Smirnoff { chdlc_if_print, DLT_HDLC }, 118*3340d773SGleb Smirnoff #endif 119*3340d773SGleb Smirnoff #ifdef DLT_PPP_ETHER 120*3340d773SGleb Smirnoff { pppoe_if_print, DLT_PPP_ETHER }, 121*3340d773SGleb Smirnoff #endif 122*3340d773SGleb Smirnoff #if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H) 123*3340d773SGleb Smirnoff { pflog_if_print, DLT_PFLOG }, 124*3340d773SGleb Smirnoff #endif 125*3340d773SGleb Smirnoff { token_if_print, DLT_IEEE802 }, 126*3340d773SGleb Smirnoff { fddi_if_print, DLT_FDDI }, 127*3340d773SGleb Smirnoff #ifdef DLT_LINUX_SLL 128*3340d773SGleb Smirnoff { sll_if_print, DLT_LINUX_SLL }, 129*3340d773SGleb Smirnoff #endif 130*3340d773SGleb Smirnoff #ifdef DLT_FR 131*3340d773SGleb Smirnoff { fr_if_print, DLT_FR }, 132*3340d773SGleb Smirnoff #endif 133*3340d773SGleb Smirnoff #ifdef DLT_FRELAY 134*3340d773SGleb Smirnoff { fr_if_print, DLT_FRELAY }, 135*3340d773SGleb Smirnoff #endif 136*3340d773SGleb Smirnoff #ifdef DLT_MFR 137*3340d773SGleb Smirnoff { mfr_if_print, DLT_MFR }, 138*3340d773SGleb Smirnoff #endif 139*3340d773SGleb Smirnoff { atm_if_print, DLT_ATM_RFC1483 }, 140*3340d773SGleb Smirnoff #ifdef DLT_SUNATM 141*3340d773SGleb Smirnoff { sunatm_if_print, DLT_SUNATM }, 142*3340d773SGleb Smirnoff #endif 143*3340d773SGleb Smirnoff #ifdef DLT_ENC 144*3340d773SGleb Smirnoff { enc_if_print, DLT_ENC }, 145*3340d773SGleb Smirnoff #endif 146*3340d773SGleb Smirnoff { sl_if_print, DLT_SLIP }, 147*3340d773SGleb Smirnoff #ifdef DLT_SLIP_BSDOS 148*3340d773SGleb Smirnoff { sl_bsdos_if_print, DLT_SLIP_BSDOS }, 149*3340d773SGleb Smirnoff #endif 150*3340d773SGleb Smirnoff #ifdef DLT_LTALK 151*3340d773SGleb Smirnoff { ltalk_if_print, DLT_LTALK }, 152*3340d773SGleb Smirnoff #endif 153*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_ATM1 154*3340d773SGleb Smirnoff { juniper_atm1_print, DLT_JUNIPER_ATM1 }, 155*3340d773SGleb Smirnoff #endif 156*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_ATM2 157*3340d773SGleb Smirnoff { juniper_atm2_print, DLT_JUNIPER_ATM2 }, 158*3340d773SGleb Smirnoff #endif 159*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_MFR 160*3340d773SGleb Smirnoff { juniper_mfr_print, DLT_JUNIPER_MFR }, 161*3340d773SGleb Smirnoff #endif 162*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_MLFR 163*3340d773SGleb Smirnoff { juniper_mlfr_print, DLT_JUNIPER_MLFR }, 164*3340d773SGleb Smirnoff #endif 165*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_MLPPP 166*3340d773SGleb Smirnoff { juniper_mlppp_print, DLT_JUNIPER_MLPPP }, 167*3340d773SGleb Smirnoff #endif 168*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_PPPOE 169*3340d773SGleb Smirnoff { juniper_pppoe_print, DLT_JUNIPER_PPPOE }, 170*3340d773SGleb Smirnoff #endif 171*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_PPPOE_ATM 172*3340d773SGleb Smirnoff { juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM }, 173*3340d773SGleb Smirnoff #endif 174*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_GGSN 175*3340d773SGleb Smirnoff { juniper_ggsn_print, DLT_JUNIPER_GGSN }, 176*3340d773SGleb Smirnoff #endif 177*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_ES 178*3340d773SGleb Smirnoff { juniper_es_print, DLT_JUNIPER_ES }, 179*3340d773SGleb Smirnoff #endif 180*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_MONITOR 181*3340d773SGleb Smirnoff { juniper_monitor_print, DLT_JUNIPER_MONITOR }, 182*3340d773SGleb Smirnoff #endif 183*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_SERVICES 184*3340d773SGleb Smirnoff { juniper_services_print, DLT_JUNIPER_SERVICES }, 185*3340d773SGleb Smirnoff #endif 186*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_ETHER 187*3340d773SGleb Smirnoff { juniper_ether_print, DLT_JUNIPER_ETHER }, 188*3340d773SGleb Smirnoff #endif 189*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_PPP 190*3340d773SGleb Smirnoff { juniper_ppp_print, DLT_JUNIPER_PPP }, 191*3340d773SGleb Smirnoff #endif 192*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_FRELAY 193*3340d773SGleb Smirnoff { juniper_frelay_print, DLT_JUNIPER_FRELAY }, 194*3340d773SGleb Smirnoff #endif 195*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_CHDLC 196*3340d773SGleb Smirnoff { juniper_chdlc_print, DLT_JUNIPER_CHDLC }, 197*3340d773SGleb Smirnoff #endif 198*3340d773SGleb Smirnoff #ifdef DLT_PKTAP 199*3340d773SGleb Smirnoff { pktap_if_print, DLT_PKTAP }, 200*3340d773SGleb Smirnoff #endif 201*3340d773SGleb Smirnoff #ifdef DLT_IEEE802_11_RADIO 202*3340d773SGleb Smirnoff { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, 203*3340d773SGleb Smirnoff #endif 204*3340d773SGleb Smirnoff #ifdef DLT_IEEE802_11 205*3340d773SGleb Smirnoff { ieee802_11_if_print, DLT_IEEE802_11}, 206*3340d773SGleb Smirnoff #endif 207*3340d773SGleb Smirnoff #ifdef DLT_IEEE802_11_RADIO_AVS 208*3340d773SGleb Smirnoff { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, 209*3340d773SGleb Smirnoff #endif 210*3340d773SGleb Smirnoff #ifdef DLT_PRISM_HEADER 211*3340d773SGleb Smirnoff { prism_if_print, DLT_PRISM_HEADER }, 212*3340d773SGleb Smirnoff #endif 213*3340d773SGleb Smirnoff { ppp_if_print, DLT_PPP }, 214*3340d773SGleb Smirnoff #ifdef DLT_PPP_WITHDIRECTION 215*3340d773SGleb Smirnoff { ppp_if_print, DLT_PPP_WITHDIRECTION }, 216*3340d773SGleb Smirnoff #endif 217*3340d773SGleb Smirnoff #ifdef DLT_PPP_BSDOS 218*3340d773SGleb Smirnoff { ppp_bsdos_if_print, DLT_PPP_BSDOS }, 219*3340d773SGleb Smirnoff #endif 220*3340d773SGleb Smirnoff #ifdef DLT_PPP_SERIAL 221*3340d773SGleb Smirnoff { ppp_hdlc_if_print, DLT_PPP_SERIAL }, 222*3340d773SGleb Smirnoff #endif 223*3340d773SGleb Smirnoff { NULL, 0 }, 224*3340d773SGleb Smirnoff }; 225*3340d773SGleb Smirnoff 226*3340d773SGleb Smirnoff static void ndo_default_print(netdissect_options *ndo, const u_char *bp, 227*3340d773SGleb Smirnoff u_int length); 228*3340d773SGleb Smirnoff 229*3340d773SGleb Smirnoff static void ndo_error(netdissect_options *ndo, const char *fmt, ...) 230*3340d773SGleb Smirnoff __attribute__((noreturn)) 231*3340d773SGleb Smirnoff #ifdef __ATTRIBUTE___FORMAT_OK 232*3340d773SGleb Smirnoff __attribute__((format (printf, 2, 3))) 233*3340d773SGleb Smirnoff #endif /* __ATTRIBUTE___FORMAT_OK */ 234*3340d773SGleb Smirnoff ; 235*3340d773SGleb Smirnoff static void ndo_warning(netdissect_options *ndo, const char *fmt, ...) 236*3340d773SGleb Smirnoff #ifdef __ATTRIBUTE___FORMAT_OK 237*3340d773SGleb Smirnoff __attribute__((format (printf, 2, 3))) 238*3340d773SGleb Smirnoff #endif /* __ATTRIBUTE___FORMAT_OK */ 239*3340d773SGleb Smirnoff ; 240*3340d773SGleb Smirnoff 241*3340d773SGleb Smirnoff static int ndo_printf(netdissect_options *ndo, const char *fmt, ...) 242*3340d773SGleb Smirnoff #ifdef __ATTRIBUTE___FORMAT_OK 243*3340d773SGleb Smirnoff __attribute ((format (printf, 2, 3))) 244*3340d773SGleb Smirnoff #endif /* __ATTRIBUTE___FORMAT_OK */ 245*3340d773SGleb Smirnoff ; 246*3340d773SGleb Smirnoff 247*3340d773SGleb Smirnoff void 248*3340d773SGleb Smirnoff init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask, 249*3340d773SGleb Smirnoff uint32_t timezone_offset) 250*3340d773SGleb Smirnoff { 251*3340d773SGleb Smirnoff 252*3340d773SGleb Smirnoff thiszone = timezone_offset; 253*3340d773SGleb Smirnoff init_addrtoname(ndo, localnet, mask); 254*3340d773SGleb Smirnoff init_checksum(); 255*3340d773SGleb Smirnoff } 256*3340d773SGleb Smirnoff 257*3340d773SGleb Smirnoff if_printer 258*3340d773SGleb Smirnoff lookup_printer(int type) 259*3340d773SGleb Smirnoff { 260*3340d773SGleb Smirnoff const struct printer *p; 261*3340d773SGleb Smirnoff 262*3340d773SGleb Smirnoff for (p = printers; p->f; ++p) 263*3340d773SGleb Smirnoff if (type == p->type) 264*3340d773SGleb Smirnoff return p->f; 265*3340d773SGleb Smirnoff 266*3340d773SGleb Smirnoff #if defined(DLT_USER2) && defined(DLT_PKTAP) 267*3340d773SGleb Smirnoff /* 268*3340d773SGleb Smirnoff * Apple incorrectly chose to use DLT_USER2 for their PKTAP 269*3340d773SGleb Smirnoff * header. 270*3340d773SGleb Smirnoff * 271*3340d773SGleb Smirnoff * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin- 272*3340d773SGleb Smirnoff * based OSes or the same value as LINKTYPE_PKTAP as it is on 273*3340d773SGleb Smirnoff * other OSes, to LINKTYPE_PKTAP, so files written with 274*3340d773SGleb Smirnoff * this version of libpcap for a DLT_PKTAP capture have a link- 275*3340d773SGleb Smirnoff * layer header type of LINKTYPE_PKTAP. 276*3340d773SGleb Smirnoff * 277*3340d773SGleb Smirnoff * However, files written on OS X Mavericks for a DLT_PKTAP 278*3340d773SGleb Smirnoff * capture have a link-layer header type of LINKTYPE_USER2. 279*3340d773SGleb Smirnoff * If we don't have a printer for DLT_USER2, and type is 280*3340d773SGleb Smirnoff * DLT_USER2, we look up the printer for DLT_PKTAP and use 281*3340d773SGleb Smirnoff * that. 282*3340d773SGleb Smirnoff */ 283*3340d773SGleb Smirnoff if (type == DLT_USER2) { 284*3340d773SGleb Smirnoff for (p = printers; p->f; ++p) 285*3340d773SGleb Smirnoff if (DLT_PKTAP == p->type) 286*3340d773SGleb Smirnoff return p->f; 287*3340d773SGleb Smirnoff } 288*3340d773SGleb Smirnoff #endif 289*3340d773SGleb Smirnoff 290*3340d773SGleb Smirnoff return NULL; 291*3340d773SGleb Smirnoff /* NOTREACHED */ 292*3340d773SGleb Smirnoff } 293*3340d773SGleb Smirnoff 294*3340d773SGleb Smirnoff int 295*3340d773SGleb Smirnoff has_printer(int type) 296*3340d773SGleb Smirnoff { 297*3340d773SGleb Smirnoff return (lookup_printer(type) != NULL); 298*3340d773SGleb Smirnoff } 299*3340d773SGleb Smirnoff 300*3340d773SGleb Smirnoff if_printer 301*3340d773SGleb Smirnoff get_if_printer(netdissect_options *ndo, int type) 302*3340d773SGleb Smirnoff { 303*3340d773SGleb Smirnoff const char *dltname; 304*3340d773SGleb Smirnoff if_printer printer; 305*3340d773SGleb Smirnoff 306*3340d773SGleb Smirnoff printer = lookup_printer(type); 307*3340d773SGleb Smirnoff if (printer == NULL) { 308*3340d773SGleb Smirnoff dltname = pcap_datalink_val_to_name(type); 309*3340d773SGleb Smirnoff if (dltname != NULL) 310*3340d773SGleb Smirnoff (*ndo->ndo_error)(ndo, 311*3340d773SGleb Smirnoff "packet printing is not supported for link type %s: use -w", 312*3340d773SGleb Smirnoff dltname); 313*3340d773SGleb Smirnoff else 314*3340d773SGleb Smirnoff (*ndo->ndo_error)(ndo, 315*3340d773SGleb Smirnoff "packet printing is not supported for link type %d: use -w", type); 316*3340d773SGleb Smirnoff } 317*3340d773SGleb Smirnoff return printer; 318*3340d773SGleb Smirnoff } 319*3340d773SGleb Smirnoff 320*3340d773SGleb Smirnoff void 321*3340d773SGleb Smirnoff pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, 322*3340d773SGleb Smirnoff const u_char *sp, u_int packets_captured) 323*3340d773SGleb Smirnoff { 324*3340d773SGleb Smirnoff u_int hdrlen; 325*3340d773SGleb Smirnoff 326*3340d773SGleb Smirnoff if(ndo->ndo_packet_number) 327*3340d773SGleb Smirnoff ND_PRINT((ndo, "%5u ", packets_captured)); 328*3340d773SGleb Smirnoff 329*3340d773SGleb Smirnoff ts_print(ndo, &h->ts); 330*3340d773SGleb Smirnoff 331*3340d773SGleb Smirnoff /* 332*3340d773SGleb Smirnoff * Some printers want to check that they're not walking off the 333*3340d773SGleb Smirnoff * end of the packet. 334*3340d773SGleb Smirnoff * Rather than pass it all the way down, we set this member 335*3340d773SGleb Smirnoff * of the netdissect_options structure. 336*3340d773SGleb Smirnoff */ 337*3340d773SGleb Smirnoff ndo->ndo_snapend = sp + h->caplen; 338*3340d773SGleb Smirnoff 339*3340d773SGleb Smirnoff hdrlen = (ndo->ndo_if_printer)(ndo, h, sp); 340*3340d773SGleb Smirnoff 341*3340d773SGleb Smirnoff /* 342*3340d773SGleb Smirnoff * Restore the original snapend, as a printer might have 343*3340d773SGleb Smirnoff * changed it. 344*3340d773SGleb Smirnoff */ 345*3340d773SGleb Smirnoff ndo->ndo_snapend = sp + h->caplen; 346*3340d773SGleb Smirnoff if (ndo->ndo_Xflag) { 347*3340d773SGleb Smirnoff /* 348*3340d773SGleb Smirnoff * Print the raw packet data in hex and ASCII. 349*3340d773SGleb Smirnoff */ 350*3340d773SGleb Smirnoff if (ndo->ndo_Xflag > 1) { 351*3340d773SGleb Smirnoff /* 352*3340d773SGleb Smirnoff * Include the link-layer header. 353*3340d773SGleb Smirnoff */ 354*3340d773SGleb Smirnoff hex_and_ascii_print(ndo, "\n\t", sp, h->caplen); 355*3340d773SGleb Smirnoff } else { 356*3340d773SGleb Smirnoff /* 357*3340d773SGleb Smirnoff * Don't include the link-layer header - and if 358*3340d773SGleb Smirnoff * we have nothing past the link-layer header, 359*3340d773SGleb Smirnoff * print nothing. 360*3340d773SGleb Smirnoff */ 361*3340d773SGleb Smirnoff if (h->caplen > hdrlen) 362*3340d773SGleb Smirnoff hex_and_ascii_print(ndo, "\n\t", sp + hdrlen, 363*3340d773SGleb Smirnoff h->caplen - hdrlen); 364*3340d773SGleb Smirnoff } 365*3340d773SGleb Smirnoff } else if (ndo->ndo_xflag) { 366*3340d773SGleb Smirnoff /* 367*3340d773SGleb Smirnoff * Print the raw packet data in hex. 368*3340d773SGleb Smirnoff */ 369*3340d773SGleb Smirnoff if (ndo->ndo_xflag > 1) { 370*3340d773SGleb Smirnoff /* 371*3340d773SGleb Smirnoff * Include the link-layer header. 372*3340d773SGleb Smirnoff */ 373*3340d773SGleb Smirnoff hex_print(ndo, "\n\t", sp, h->caplen); 374*3340d773SGleb Smirnoff } else { 375*3340d773SGleb Smirnoff /* 376*3340d773SGleb Smirnoff * Don't include the link-layer header - and if 377*3340d773SGleb Smirnoff * we have nothing past the link-layer header, 378*3340d773SGleb Smirnoff * print nothing. 379*3340d773SGleb Smirnoff */ 380*3340d773SGleb Smirnoff if (h->caplen > hdrlen) 381*3340d773SGleb Smirnoff hex_print(ndo, "\n\t", sp + hdrlen, 382*3340d773SGleb Smirnoff h->caplen - hdrlen); 383*3340d773SGleb Smirnoff } 384*3340d773SGleb Smirnoff } else if (ndo->ndo_Aflag) { 385*3340d773SGleb Smirnoff /* 386*3340d773SGleb Smirnoff * Print the raw packet data in ASCII. 387*3340d773SGleb Smirnoff */ 388*3340d773SGleb Smirnoff if (ndo->ndo_Aflag > 1) { 389*3340d773SGleb Smirnoff /* 390*3340d773SGleb Smirnoff * Include the link-layer header. 391*3340d773SGleb Smirnoff */ 392*3340d773SGleb Smirnoff ascii_print(ndo, sp, h->caplen); 393*3340d773SGleb Smirnoff } else { 394*3340d773SGleb Smirnoff /* 395*3340d773SGleb Smirnoff * Don't include the link-layer header - and if 396*3340d773SGleb Smirnoff * we have nothing past the link-layer header, 397*3340d773SGleb Smirnoff * print nothing. 398*3340d773SGleb Smirnoff */ 399*3340d773SGleb Smirnoff if (h->caplen > hdrlen) 400*3340d773SGleb Smirnoff ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen); 401*3340d773SGleb Smirnoff } 402*3340d773SGleb Smirnoff } 403*3340d773SGleb Smirnoff 404*3340d773SGleb Smirnoff ND_PRINT((ndo, "\n")); 405*3340d773SGleb Smirnoff } 406*3340d773SGleb Smirnoff 407*3340d773SGleb Smirnoff /* 408*3340d773SGleb Smirnoff * By default, print the specified data out in hex and ASCII. 409*3340d773SGleb Smirnoff */ 410*3340d773SGleb Smirnoff static void 411*3340d773SGleb Smirnoff ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length) 412*3340d773SGleb Smirnoff { 413*3340d773SGleb Smirnoff hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */ 414*3340d773SGleb Smirnoff } 415*3340d773SGleb Smirnoff 416*3340d773SGleb Smirnoff /* VARARGS */ 417*3340d773SGleb Smirnoff static void 418*3340d773SGleb Smirnoff ndo_error(netdissect_options *ndo, const char *fmt, ...) 419*3340d773SGleb Smirnoff { 420*3340d773SGleb Smirnoff va_list ap; 421*3340d773SGleb Smirnoff 422*3340d773SGleb Smirnoff if(ndo->program_name) 423*3340d773SGleb Smirnoff (void)fprintf(stderr, "%s: ", ndo->program_name); 424*3340d773SGleb Smirnoff va_start(ap, fmt); 425*3340d773SGleb Smirnoff (void)vfprintf(stderr, fmt, ap); 426*3340d773SGleb Smirnoff va_end(ap); 427*3340d773SGleb Smirnoff if (*fmt) { 428*3340d773SGleb Smirnoff fmt += strlen(fmt); 429*3340d773SGleb Smirnoff if (fmt[-1] != '\n') 430*3340d773SGleb Smirnoff (void)fputc('\n', stderr); 431*3340d773SGleb Smirnoff } 432*3340d773SGleb Smirnoff nd_cleanup(); 433*3340d773SGleb Smirnoff exit(1); 434*3340d773SGleb Smirnoff /* NOTREACHED */ 435*3340d773SGleb Smirnoff } 436*3340d773SGleb Smirnoff 437*3340d773SGleb Smirnoff /* VARARGS */ 438*3340d773SGleb Smirnoff static void 439*3340d773SGleb Smirnoff ndo_warning(netdissect_options *ndo, const char *fmt, ...) 440*3340d773SGleb Smirnoff { 441*3340d773SGleb Smirnoff va_list ap; 442*3340d773SGleb Smirnoff 443*3340d773SGleb Smirnoff if(ndo->program_name) 444*3340d773SGleb Smirnoff (void)fprintf(stderr, "%s: ", ndo->program_name); 445*3340d773SGleb Smirnoff (void)fprintf(stderr, "WARNING: "); 446*3340d773SGleb Smirnoff va_start(ap, fmt); 447*3340d773SGleb Smirnoff (void)vfprintf(stderr, fmt, ap); 448*3340d773SGleb Smirnoff va_end(ap); 449*3340d773SGleb Smirnoff if (*fmt) { 450*3340d773SGleb Smirnoff fmt += strlen(fmt); 451*3340d773SGleb Smirnoff if (fmt[-1] != '\n') 452*3340d773SGleb Smirnoff (void)fputc('\n', stderr); 453*3340d773SGleb Smirnoff } 454*3340d773SGleb Smirnoff } 455*3340d773SGleb Smirnoff 456*3340d773SGleb Smirnoff static int 457*3340d773SGleb Smirnoff ndo_printf(netdissect_options *ndo, const char *fmt, ...) 458*3340d773SGleb Smirnoff { 459*3340d773SGleb Smirnoff va_list args; 460*3340d773SGleb Smirnoff int ret; 461*3340d773SGleb Smirnoff 462*3340d773SGleb Smirnoff va_start(args, fmt); 463*3340d773SGleb Smirnoff ret = vfprintf(stdout, fmt, args); 464*3340d773SGleb Smirnoff va_end(args); 465*3340d773SGleb Smirnoff 466*3340d773SGleb Smirnoff if (ret < 0) 467*3340d773SGleb Smirnoff ndo_error(ndo, "Unable to write output: %s", pcap_strerror(errno)); 468*3340d773SGleb Smirnoff return (ret); 469*3340d773SGleb Smirnoff } 470*3340d773SGleb Smirnoff 471*3340d773SGleb Smirnoff void 472*3340d773SGleb Smirnoff ndo_set_function_pointers(netdissect_options *ndo) 473*3340d773SGleb Smirnoff { 474*3340d773SGleb Smirnoff ndo->ndo_default_print=ndo_default_print; 475*3340d773SGleb Smirnoff ndo->ndo_printf=ndo_printf; 476*3340d773SGleb Smirnoff ndo->ndo_error=ndo_error; 477*3340d773SGleb Smirnoff ndo->ndo_warning=ndo_warning; 478*3340d773SGleb Smirnoff } 479*3340d773SGleb Smirnoff /* 480*3340d773SGleb Smirnoff * Local Variables: 481*3340d773SGleb Smirnoff * c-style: whitesmith 482*3340d773SGleb Smirnoff * c-basic-offset: 8 483*3340d773SGleb Smirnoff * End: 484*3340d773SGleb Smirnoff */ 485