Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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 |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 29 | #include <config.h> |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 30 | #endif |
| 31 | |
| 32 | #include <stdlib.h> |
| 33 | #include <string.h> |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 34 | #include <setjmp.h> |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 35 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 36 | #include "netdissect-stdinc.h" |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 37 | |
| 38 | #include "netdissect.h" |
| 39 | #include "addrtoname.h" |
| 40 | #include "print.h" |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 41 | #include "netdissect-alloc.h" |
| 42 | |
| 43 | #include "pcap-missing.h" |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 44 | |
| 45 | struct printer { |
| 46 | if_printer f; |
| 47 | int type; |
| 48 | }; |
| 49 | |
| 50 | static const struct printer printers[] = { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 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 |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 89 | { ether_if_print, DLT_EN10MB }, |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 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 }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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 |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 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 }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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 |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 181 | #ifdef DLT_NFLOG |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 182 | { nflog_if_print, DLT_NFLOG}, |
| 183 | #endif |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 184 | { null_if_print, DLT_NULL }, |
| 185 | #ifdef DLT_LOOP |
| 186 | { null_if_print, DLT_LOOP }, |
| 187 | #endif |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 188 | #if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H) |
| 189 | { pflog_if_print, DLT_PFLOG }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 190 | #endif |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 191 | #ifdef DLT_PKTAP |
| 192 | { pktap_if_print, DLT_PKTAP }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 193 | #endif |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 194 | #ifdef DLT_PPI |
| 195 | { ppi_if_print, DLT_PPI }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 196 | #endif |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 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 }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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 |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 220 | #ifdef DLT_SLIP_BSDOS |
| 221 | { sl_bsdos_if_print, DLT_SLIP_BSDOS }, |
| 222 | #endif |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 223 | { sl_if_print, DLT_SLIP }, |
| 224 | #ifdef DLT_LINUX_SLL |
| 225 | { sll_if_print, DLT_LINUX_SLL }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 226 | #endif |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 227 | #ifdef DLT_LINUX_SLL2 |
| 228 | { sll2_if_print, DLT_LINUX_SLL2 }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 229 | #endif |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 230 | #ifdef DLT_SUNATM |
| 231 | { sunatm_if_print, DLT_SUNATM }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 232 | #endif |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 233 | #ifdef DLT_SYMANTEC_FIREWALL |
| 234 | { symantec_if_print, DLT_SYMANTEC_FIREWALL }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 235 | #endif |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 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 }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 245 | #endif |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 246 | { NULL, 0 }, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 247 | }; |
| 248 | |
| 249 | static void ndo_default_print(netdissect_options *ndo, const u_char *bp, |
| 250 | u_int length); |
| 251 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 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); |
Elliott Hughes | cec480a | 2017-12-19 16:54:57 -0800 | [diff] [blame] | 256 | static void ndo_warning(netdissect_options *ndo, |
| 257 | FORMAT_STRING(const char *fmt), ...) |
| 258 | PRINTFLIKE(2, 3); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 259 | |
Elliott Hughes | cec480a | 2017-12-19 16:54:57 -0800 | [diff] [blame] | 260 | static int ndo_printf(netdissect_options *ndo, |
| 261 | FORMAT_STRING(const char *fmt), ...) |
| 262 | PRINTFLIKE(2, 3); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 263 | |
| 264 | void |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 265 | init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 266 | { |
| 267 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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 |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 316 | get_if_printer(int type) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 317 | { |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 318 | if_printer printer; |
| 319 | |
| 320 | printer = lookup_printer(type); |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 321 | if (printer == NULL) |
| 322 | printer = unsupported_if_print; |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 323 | return printer; |
| 324 | } |
| 325 | |
| 326 | void |
| 327 | pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 328 | const u_char *sp, u_int packets_captured) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 329 | { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 330 | u_int hdrlen = 0; |
| 331 | int invalid_header = 0; |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 332 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 333 | if (ndo->ndo_packet_number) |
| 334 | ND_PRINT("%5u ", packets_captured); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 335 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 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 | } |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 376 | |
| 377 | /* |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 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. |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 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); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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, |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 454 | h->caplen - hdrlen); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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 | */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 464 | hex_print(ndo, "\n\t", sp, h->caplen); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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, |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 473 | h->caplen - hdrlen); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 495 | ND_PRINT("\n"); |
| 496 | nd_free_all(ndo); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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 |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 510 | ndo_error(netdissect_options *ndo, status_exit_codes_t status, |
| 511 | const char *fmt, ...) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 512 | { |
| 513 | va_list ap; |
| 514 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 515 | if (ndo->program_name) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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(); |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 526 | exit(status); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 527 | /* NOTREACHED */ |
| 528 | } |
| 529 | |
| 530 | /* VARARGS */ |
| 531 | static void |
| 532 | ndo_warning(netdissect_options *ndo, const char *fmt, ...) |
| 533 | { |
| 534 | va_list ap; |
| 535 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 536 | if (ndo->program_name) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 560 | ndo_error(ndo, S_ERR_ND_WRITE_FILE, |
| 561 | "Unable to write output: %s", pcap_strerror(errno)); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 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 | } |