117683Spst/* 239291Sfenner * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998 317683Spst * The Regents of the University of California. All rights reserved. 417683Spst * 517683Spst * Redistribution and use in source and binary forms, with or without 617683Spst * modification, are permitted provided that the following conditions 717683Spst * are met: 817683Spst * 1. Redistributions of source code must retain the above copyright 917683Spst * notice, this list of conditions and the following disclaimer. 1017683Spst * 2. Redistributions in binary form must reproduce the above copyright 1117683Spst * notice, this list of conditions and the following disclaimer in the 1217683Spst * documentation and/or other materials provided with the distribution. 1317683Spst * 3. All advertising materials mentioning features or use of this software 1417683Spst * must display the following acknowledgement: 1517683Spst * This product includes software developed by the Computer Systems 1617683Spst * Engineering Group at Lawrence Berkeley Laboratory. 1717683Spst * 4. Neither the name of the University nor of the Laboratory may be used 1817683Spst * to endorse or promote products derived from this software without 1917683Spst * specific prior written permission. 2017683Spst * 2117683Spst * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2217683Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2317683Spst * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2417683Spst * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2517683Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2617683Spst * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2717683Spst * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2817683Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2917683Spst * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3017683Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3117683Spst * SUCH DAMAGE. 3217683Spst */ 3317683Spst 3417683Spst#ifndef lint 35127664Sbmsstatic const char rcsid[] _U_ = 36214518Srpaulo "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.128 2008-12-23 20:13:29 guy Exp $ (LBL)"; 3717683Spst#endif 3817683Spst 3975107Sfenner#ifdef HAVE_CONFIG_H 4075107Sfenner#include "config.h" 4175107Sfenner#endif 4275107Sfenner 43127664Sbms#ifdef WIN32 44127664Sbms#include <pcap-stdinc.h> 45127664Sbms#else /* WIN32 */ 46214518Srpaulo#if HAVE_INTTYPES_H 47214518Srpaulo#include <inttypes.h> 48214518Srpaulo#elif HAVE_STDINT_H 49214518Srpaulo#include <stdint.h> 50214518Srpaulo#endif 51214518Srpaulo#ifdef HAVE_SYS_BITYPES_H 52214518Srpaulo#include <sys/bitypes.h> 53214518Srpaulo#endif 5417683Spst#include <sys/types.h> 55183102Scsjp#include <sys/mman.h> 56127664Sbms#endif /* WIN32 */ 5717683Spst 5817683Spst#include <stdio.h> 5917683Spst#include <stdlib.h> 6017683Spst#include <string.h> 61235426Sdelphij#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__MINGW32__) 6217683Spst#include <unistd.h> 63127664Sbms#endif 6498530Sfenner#include <fcntl.h> 6598530Sfenner#include <errno.h> 6617683Spst 6717683Spst#ifdef HAVE_OS_PROTO_H 6817683Spst#include "os-proto.h" 6917683Spst#endif 7017683Spst 71146768Ssam#ifdef MSDOS 72146768Ssam#include "pcap-dos.h" 73146768Ssam#endif 74146768Ssam 7517683Spst#include "pcap-int.h" 7617683Spst 77127664Sbms#ifdef HAVE_DAG_API 78251129Sdelphij#include "pcap-dag.h" 79251129Sdelphij#endif /* HAVE_DAG_API */ 80251129Sdelphij 81251129Sdelphij#ifdef HAVE_SEPTEL_API 82251129Sdelphij#include "pcap-septel.h" 83251129Sdelphij#endif /* HAVE_SEPTEL_API */ 84251129Sdelphij 85251129Sdelphij#ifdef HAVE_SNF_API 86251129Sdelphij#include "pcap-snf.h" 87251129Sdelphij#endif /* HAVE_SNF_API */ 88251129Sdelphij 89251129Sdelphij#ifdef PCAP_SUPPORT_USB 90251129Sdelphij#include "pcap-usb-linux.h" 91127664Sbms#endif 92127664Sbms 93251129Sdelphij#ifdef PCAP_SUPPORT_BT 94251129Sdelphij#include "pcap-bt-linux.h" 95251129Sdelphij#endif 96251129Sdelphij 97251129Sdelphij#ifdef PCAP_SUPPORT_CAN 98251129Sdelphij#include "pcap-can-linux.h" 99251129Sdelphij#endif 100251129Sdelphij 101251129Sdelphij#ifdef PCAP_SUPPORT_CANUSB 102251129Sdelphij#include "pcap-canusb-linux.h" 103251129Sdelphij#endif 104251129Sdelphij 105251129Sdelphij#ifdef PCAP_SUPPORT_NETFILTER 106251129Sdelphij#include "pcap-netfilter-linux.h" 107251129Sdelphij#endif 108251129Sdelphij 109190225Srpauloint 110190225Srpaulopcap_not_initialized(pcap_t *pcap) 111190225Srpaulo{ 112190225Srpaulo /* this means 'not initialized' */ 113235426Sdelphij return (PCAP_ERROR_NOT_ACTIVATED); 114190225Srpaulo} 115190225Srpaulo 116190225Srpaulo/* 117190225Srpaulo * Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't, 118190225Srpaulo * a PCAP_ERROR value on an error. 119190225Srpaulo */ 12017683Spstint 121190225Srpaulopcap_can_set_rfmon(pcap_t *p) 122190225Srpaulo{ 123190225Srpaulo return (p->can_set_rfmon_op(p)); 124190225Srpaulo} 125190225Srpaulo 126190225Srpaulo/* 127190225Srpaulo * For systems where rfmon mode is never supported. 128190225Srpaulo */ 129190225Srpaulostatic int 130190225Srpaulopcap_cant_set_rfmon(pcap_t *p _U_) 131190225Srpaulo{ 132190225Srpaulo return (0); 133190225Srpaulo} 134190225Srpaulo 135214518Srpaulo/* 136235426Sdelphij * Sets *tstamp_typesp to point to an array 1 or more supported time stamp 137235426Sdelphij * types; the return value is the number of supported time stamp types. 138235426Sdelphij * The list should be freed by a call to pcap_free_tstamp_types() when 139235426Sdelphij * you're done with it. 140235426Sdelphij * 141235426Sdelphij * A return value of 0 means "you don't get a choice of time stamp type", 142235426Sdelphij * in which case *tstamp_typesp is set to null. 143235426Sdelphij * 144235426Sdelphij * PCAP_ERROR is returned on error. 145235426Sdelphij */ 146235426Sdelphijint 147235426Sdelphijpcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp) 148235426Sdelphij{ 149235426Sdelphij if (p->tstamp_type_count == 0) { 150235426Sdelphij /* 151235426Sdelphij * We don't support multiple time stamp types. 152235426Sdelphij */ 153235426Sdelphij *tstamp_typesp = NULL; 154235426Sdelphij } else { 155235426Sdelphij *tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp), 156235426Sdelphij p->tstamp_type_count); 157235426Sdelphij if (*tstamp_typesp == NULL) { 158235426Sdelphij (void)snprintf(p->errbuf, sizeof(p->errbuf), 159235426Sdelphij "malloc: %s", pcap_strerror(errno)); 160235426Sdelphij return (PCAP_ERROR); 161235426Sdelphij } 162235426Sdelphij (void)memcpy(*tstamp_typesp, p->tstamp_type_list, 163235426Sdelphij sizeof(**tstamp_typesp) * p->tstamp_type_count); 164235426Sdelphij } 165235426Sdelphij return (p->tstamp_type_count); 166235426Sdelphij} 167235426Sdelphij 168235426Sdelphij/* 169235426Sdelphij * In Windows, you might have a library built with one version of the 170235426Sdelphij * C runtime library and an application built with another version of 171235426Sdelphij * the C runtime library, which means that the library might use one 172235426Sdelphij * version of malloc() and free() and the application might use another 173235426Sdelphij * version of malloc() and free(). If so, that means something 174235426Sdelphij * allocated by the library cannot be freed by the application, so we 175235426Sdelphij * need to have a pcap_free_tstamp_types() routine to free up the list 176235426Sdelphij * allocated by pcap_list_tstamp_types(), even though it's just a wrapper 177235426Sdelphij * around free(). 178235426Sdelphij */ 179235426Sdelphijvoid 180235426Sdelphijpcap_free_tstamp_types(int *tstamp_type_list) 181235426Sdelphij{ 182235426Sdelphij free(tstamp_type_list); 183235426Sdelphij} 184235426Sdelphij 185235426Sdelphij/* 186214518Srpaulo * Default one-shot callback; overridden for capture types where the 187214518Srpaulo * packet data cannot be guaranteed to be available after the callback 188214518Srpaulo * returns, so that a copy must be made. 189214518Srpaulo */ 190214518Srpaulostatic void 191214518Srpaulopcap_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *pkt) 192214518Srpaulo{ 193214518Srpaulo struct oneshot_userdata *sp = (struct oneshot_userdata *)user; 194214518Srpaulo 195214518Srpaulo *sp->hdr = *h; 196214518Srpaulo *sp->pkt = pkt; 197214518Srpaulo} 198214518Srpaulo 199214518Srpauloconst u_char * 200214518Srpaulopcap_next(pcap_t *p, struct pcap_pkthdr *h) 201214518Srpaulo{ 202214518Srpaulo struct oneshot_userdata s; 203214518Srpaulo const u_char *pkt; 204214518Srpaulo 205214518Srpaulo s.hdr = h; 206214518Srpaulo s.pkt = &pkt; 207214518Srpaulo s.pd = p; 208214518Srpaulo if (pcap_dispatch(p, 1, p->oneshot_callback, (u_char *)&s) <= 0) 209214518Srpaulo return (0); 210214518Srpaulo return (pkt); 211214518Srpaulo} 212214518Srpaulo 213214518Srpauloint 214214518Srpaulopcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, 215214518Srpaulo const u_char **pkt_data) 216214518Srpaulo{ 217214518Srpaulo struct oneshot_userdata s; 218214518Srpaulo 219214518Srpaulo s.hdr = &p->pcap_header; 220214518Srpaulo s.pkt = pkt_data; 221214518Srpaulo s.pd = p; 222214518Srpaulo 223214518Srpaulo /* Saves a pointer to the packet headers */ 224214518Srpaulo *pkt_header= &p->pcap_header; 225214518Srpaulo 226214518Srpaulo if (p->sf.rfile != NULL) { 227214518Srpaulo int status; 228214518Srpaulo 229214518Srpaulo /* We are on an offline capture */ 230235426Sdelphij status = pcap_offline_read(p, 1, p->oneshot_callback, 231235426Sdelphij (u_char *)&s); 232214518Srpaulo 233214518Srpaulo /* 234214518Srpaulo * Return codes for pcap_offline_read() are: 235214518Srpaulo * - 0: EOF 236214518Srpaulo * - -1: error 237214518Srpaulo * - >1: OK 238214518Srpaulo * The first one ('0') conflicts with the return code of 239214518Srpaulo * 0 from pcap_read() meaning "no packets arrived before 240214518Srpaulo * the timeout expired", so we map it to -2 so you can 241214518Srpaulo * distinguish between an EOF from a savefile and a 242214518Srpaulo * "no packets arrived before the timeout expired, try 243214518Srpaulo * again" from a live capture. 244214518Srpaulo */ 245214518Srpaulo if (status == 0) 246214518Srpaulo return (-2); 247214518Srpaulo else 248214518Srpaulo return (status); 249214518Srpaulo } 250214518Srpaulo 251214518Srpaulo /* 252214518Srpaulo * Return codes for pcap_read() are: 253214518Srpaulo * - 0: timeout 254214518Srpaulo * - -1: error 255214518Srpaulo * - -2: loop was broken out of with pcap_breakloop() 256214518Srpaulo * - >1: OK 257214518Srpaulo * The first one ('0') conflicts with the return code of 0 from 258214518Srpaulo * pcap_offline_read() meaning "end of file". 259214518Srpaulo */ 260235426Sdelphij return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s)); 261214518Srpaulo} 262214518Srpaulo 263251129Sdelphij#if defined(DAG_ONLY) 264251129Sdelphijint 265251129Sdelphijpcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 266251129Sdelphij{ 267251129Sdelphij return (dag_findalldevs(alldevsp, errbuf)); 268251129Sdelphij} 269251129Sdelphij 270251129Sdelphijpcap_t * 271251129Sdelphijpcap_create(const char *source, char *errbuf) 272251129Sdelphij{ 273251129Sdelphij return (dag_create(source, errbuf)); 274251129Sdelphij} 275251129Sdelphij#elif defined(SEPTEL_ONLY) 276251129Sdelphijint 277251129Sdelphijpcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 278251129Sdelphij{ 279251129Sdelphij return (septel_findalldevs(alldevsp, errbuf)); 280251129Sdelphij} 281251129Sdelphij 282251129Sdelphijpcap_t * 283251129Sdelphijpcap_create(const char *source, char *errbuf) 284251129Sdelphij{ 285251129Sdelphij return (septel_create(source, errbuf)); 286251129Sdelphij} 287251129Sdelphij#elif defined(SNF_ONLY) 288251129Sdelphijint 289251129Sdelphijpcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 290251129Sdelphij{ 291251129Sdelphij return (snf_findalldevs(alldevsp, errbuf)); 292251129Sdelphij} 293251129Sdelphij 294251129Sdelphijpcap_t * 295251129Sdelphijpcap_create(const char *source, char *errbuf) 296251129Sdelphij{ 297251129Sdelphij return (snf_create(source, errbuf)); 298251129Sdelphij} 299251129Sdelphij#else /* regular pcap */ 300251129Sdelphijstruct capture_source_type { 301251129Sdelphij int (*findalldevs_op)(pcap_if_t **, char *); 302251129Sdelphij pcap_t *(*create_op)(const char *, char *, int *); 303251129Sdelphij} capture_source_types[] = { 304251129Sdelphij#ifdef HAVE_DAG_API 305251129Sdelphij { dag_findalldevs, dag_create }, 306251129Sdelphij#endif 307251129Sdelphij#ifdef HAVE_SEPTEL_API 308251129Sdelphij { septel_findalldevs, septel_create }, 309251129Sdelphij#endif 310251129Sdelphij#ifdef HAVE_SNF_API 311251129Sdelphij { snf_findalldevs, snf_create }, 312251129Sdelphij#endif 313251129Sdelphij#ifdef PCAP_SUPPORT_BT 314251129Sdelphij { bt_findalldevs, bt_create }, 315251129Sdelphij#endif 316251129Sdelphij#if PCAP_SUPPORT_CANUSB 317251129Sdelphij { canusb_findalldevs, canusb_create }, 318251129Sdelphij#endif 319251129Sdelphij#ifdef PCAP_SUPPORT_CAN 320251129Sdelphij { can_findalldevs, can_create }, 321251129Sdelphij#endif 322251129Sdelphij#ifdef PCAP_SUPPORT_USB 323251129Sdelphij { usb_findalldevs, usb_create }, 324251129Sdelphij#endif 325251129Sdelphij#ifdef PCAP_SUPPORT_NETFILTER 326251129Sdelphij { netfilter_findalldevs, netfilter_create }, 327251129Sdelphij#endif 328251129Sdelphij { NULL, NULL } 329251129Sdelphij}; 330251129Sdelphij 331251129Sdelphij/* 332251129Sdelphij * Get a list of all capture sources that are up and that we can open. 333251129Sdelphij * Returns -1 on error, 0 otherwise. 334251129Sdelphij * The list, as returned through "alldevsp", may be null if no interfaces 335251129Sdelphij * were up and could be opened. 336251129Sdelphij */ 337251129Sdelphijint 338251129Sdelphijpcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 339251129Sdelphij{ 340251129Sdelphij size_t i; 341251129Sdelphij 342251129Sdelphij /* 343251129Sdelphij * Get the list of regular interfaces first. 344251129Sdelphij */ 345251129Sdelphij if (pcap_findalldevs_interfaces(alldevsp, errbuf) == -1) 346251129Sdelphij return (-1); /* failure */ 347251129Sdelphij 348251129Sdelphij /* 349251129Sdelphij * Add any interfaces that need a platform-specific mechanism 350251129Sdelphij * to find. 351251129Sdelphij */ 352251129Sdelphij if (pcap_platform_finddevs(alldevsp, errbuf) == -1) { 353251129Sdelphij /* 354251129Sdelphij * We had an error; free the list we've been 355251129Sdelphij * constructing. 356251129Sdelphij */ 357251129Sdelphij if (*alldevsp != NULL) { 358251129Sdelphij pcap_freealldevs(*alldevsp); 359251129Sdelphij *alldevsp = NULL; 360251129Sdelphij } 361251129Sdelphij return (-1); 362251129Sdelphij } 363251129Sdelphij 364251129Sdelphij /* 365251129Sdelphij * Ask each of the non-local-network-interface capture 366251129Sdelphij * source types what interfaces they have. 367251129Sdelphij */ 368251129Sdelphij for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) { 369251129Sdelphij if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) { 370251129Sdelphij /* 371251129Sdelphij * We had an error; free the list we've been 372251129Sdelphij * constructing. 373251129Sdelphij */ 374251129Sdelphij if (*alldevsp != NULL) { 375251129Sdelphij pcap_freealldevs(*alldevsp); 376251129Sdelphij *alldevsp = NULL; 377251129Sdelphij } 378251129Sdelphij return (-1); 379251129Sdelphij } 380251129Sdelphij } 381251129Sdelphij return (0); 382251129Sdelphij} 383251129Sdelphij 384251129Sdelphijpcap_t * 385251129Sdelphijpcap_create(const char *source, char *errbuf) 386251129Sdelphij{ 387251129Sdelphij size_t i; 388251129Sdelphij int is_theirs; 389251129Sdelphij pcap_t *p; 390251129Sdelphij 391251129Sdelphij /* 392251129Sdelphij * A null source name is equivalent to the "any" device - 393251129Sdelphij * which might not be supported on this platform, but 394251129Sdelphij * this means that you'll get a "not supported" error 395251129Sdelphij * rather than, say, a crash when we try to dereference 396251129Sdelphij * the null pointer. 397251129Sdelphij */ 398251129Sdelphij if (source == NULL) 399251129Sdelphij source = "any"; 400251129Sdelphij 401251129Sdelphij /* 402251129Sdelphij * Try each of the non-local-network-interface capture 403251129Sdelphij * source types until we find one that works for this 404251129Sdelphij * device or run out of types. 405251129Sdelphij */ 406251129Sdelphij for (i = 0; capture_source_types[i].create_op != NULL; i++) { 407251129Sdelphij is_theirs = 0; 408251129Sdelphij p = capture_source_types[i].create_op(source, errbuf, &is_theirs); 409251129Sdelphij if (is_theirs) { 410251129Sdelphij /* 411251129Sdelphij * The device name refers to a device of the 412251129Sdelphij * type in question; either it succeeded, 413251129Sdelphij * in which case p refers to a pcap_t to 414251129Sdelphij * later activate for the device, or it 415251129Sdelphij * failed, in which case p is null and we 416251129Sdelphij * should return that to report the failure 417251129Sdelphij * to create. 418251129Sdelphij */ 419251129Sdelphij return (p); 420251129Sdelphij } 421251129Sdelphij } 422251129Sdelphij 423251129Sdelphij /* 424251129Sdelphij * OK, try it as a regular network interface. 425251129Sdelphij */ 426251129Sdelphij return (pcap_create_interface(source, errbuf)); 427251129Sdelphij} 428251129Sdelphij#endif 429251129Sdelphij 430214518Srpaulostatic void 431214518Srpauloinitialize_ops(pcap_t *p) 432214518Srpaulo{ 433214518Srpaulo /* 434214518Srpaulo * Set operation pointers for operations that only work on 435214518Srpaulo * an activated pcap_t to point to a routine that returns 436214518Srpaulo * a "this isn't activated" error. 437214518Srpaulo */ 438214518Srpaulo p->read_op = (read_op_t)pcap_not_initialized; 439214518Srpaulo p->inject_op = (inject_op_t)pcap_not_initialized; 440214518Srpaulo p->setfilter_op = (setfilter_op_t)pcap_not_initialized; 441214518Srpaulo p->setdirection_op = (setdirection_op_t)pcap_not_initialized; 442214518Srpaulo p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized; 443214518Srpaulo p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized; 444214518Srpaulo p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized; 445214518Srpaulo p->stats_op = (stats_op_t)pcap_not_initialized; 446214518Srpaulo#ifdef WIN32 447214518Srpaulo p->setbuff_op = (setbuff_op_t)pcap_not_initialized; 448214518Srpaulo p->setmode_op = (setmode_op_t)pcap_not_initialized; 449214518Srpaulo p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized; 450214518Srpaulo#endif 451214518Srpaulo 452214518Srpaulo /* 453214518Srpaulo * Default cleanup operation - implementations can override 454214518Srpaulo * this, but should call pcap_cleanup_live_common() after 455214518Srpaulo * doing their own additional cleanup. 456214518Srpaulo */ 457214518Srpaulo p->cleanup_op = pcap_cleanup_live_common; 458214518Srpaulo 459214518Srpaulo /* 460214518Srpaulo * In most cases, the standard one-short callback can 461214518Srpaulo * be used for pcap_next()/pcap_next_ex(). 462214518Srpaulo */ 463214518Srpaulo p->oneshot_callback = pcap_oneshot; 464214518Srpaulo} 465214518Srpaulo 466190225Srpaulopcap_t * 467190225Srpaulopcap_create_common(const char *source, char *ebuf) 468190225Srpaulo{ 469190225Srpaulo pcap_t *p; 470190225Srpaulo 471190225Srpaulo p = malloc(sizeof(*p)); 472190225Srpaulo if (p == NULL) { 473190225Srpaulo snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 474190225Srpaulo pcap_strerror(errno)); 475190225Srpaulo return (NULL); 476190225Srpaulo } 477190225Srpaulo memset(p, 0, sizeof(*p)); 478190225Srpaulo#ifndef WIN32 479190225Srpaulo p->fd = -1; /* not opened yet */ 480214518Srpaulo p->selectable_fd = -1; 481214518Srpaulo p->send_fd = -1; 482190225Srpaulo#endif 483190225Srpaulo 484190225Srpaulo p->opt.source = strdup(source); 485190225Srpaulo if (p->opt.source == NULL) { 486190225Srpaulo snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 487190225Srpaulo pcap_strerror(errno)); 488190225Srpaulo free(p); 489190225Srpaulo return (NULL); 490190225Srpaulo } 491190225Srpaulo 492190225Srpaulo /* 493190225Srpaulo * Default to "can't set rfmon mode"; if it's supported by 494214518Srpaulo * a platform, the create routine that called us can set 495214518Srpaulo * the op to its routine to check whether a particular 496214518Srpaulo * device supports it. 497190225Srpaulo */ 498190225Srpaulo p->can_set_rfmon_op = pcap_cant_set_rfmon; 499190225Srpaulo 500214518Srpaulo initialize_ops(p); 501190225Srpaulo 502190225Srpaulo /* put in some defaults*/ 503190225Srpaulo pcap_set_timeout(p, 0); 504190225Srpaulo pcap_set_snaplen(p, 65535); /* max packet size */ 505190225Srpaulo p->opt.promisc = 0; 506190225Srpaulo p->opt.buffer_size = 0; 507235426Sdelphij p->opt.tstamp_type = -1; /* default to not setting time stamp type */ 508190225Srpaulo return (p); 509190225Srpaulo} 510190225Srpaulo 511190225Srpauloint 512190225Srpaulopcap_check_activated(pcap_t *p) 513190225Srpaulo{ 514190225Srpaulo if (p->activated) { 515190225Srpaulo snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform " 516190225Srpaulo " operation on activated capture"); 517235426Sdelphij return (-1); 518190225Srpaulo } 519235426Sdelphij return (0); 520190225Srpaulo} 521190225Srpaulo 522190225Srpauloint 523190225Srpaulopcap_set_snaplen(pcap_t *p, int snaplen) 524190225Srpaulo{ 525190225Srpaulo if (pcap_check_activated(p)) 526235426Sdelphij return (PCAP_ERROR_ACTIVATED); 527190225Srpaulo p->snapshot = snaplen; 528235426Sdelphij return (0); 529190225Srpaulo} 530190225Srpaulo 531190225Srpauloint 532190225Srpaulopcap_set_promisc(pcap_t *p, int promisc) 533190225Srpaulo{ 534190225Srpaulo if (pcap_check_activated(p)) 535235426Sdelphij return (PCAP_ERROR_ACTIVATED); 536190225Srpaulo p->opt.promisc = promisc; 537235426Sdelphij return (0); 538190225Srpaulo} 539190225Srpaulo 540190225Srpauloint 541190225Srpaulopcap_set_rfmon(pcap_t *p, int rfmon) 542190225Srpaulo{ 543190225Srpaulo if (pcap_check_activated(p)) 544235426Sdelphij return (PCAP_ERROR_ACTIVATED); 545190225Srpaulo p->opt.rfmon = rfmon; 546235426Sdelphij return (0); 547190225Srpaulo} 548190225Srpaulo 549190225Srpauloint 550190225Srpaulopcap_set_timeout(pcap_t *p, int timeout_ms) 551190225Srpaulo{ 552190225Srpaulo if (pcap_check_activated(p)) 553235426Sdelphij return (PCAP_ERROR_ACTIVATED); 554190225Srpaulo p->md.timeout = timeout_ms; 555235426Sdelphij return (0); 556190225Srpaulo} 557190225Srpaulo 558190225Srpauloint 559235426Sdelphijpcap_set_tstamp_type(pcap_t *p, int tstamp_type) 560235426Sdelphij{ 561235426Sdelphij int i; 562235426Sdelphij 563235426Sdelphij if (pcap_check_activated(p)) 564235426Sdelphij return (PCAP_ERROR_ACTIVATED); 565235426Sdelphij 566235426Sdelphij /* 567235426Sdelphij * If p->tstamp_type_count is 0, we don't support setting 568235426Sdelphij * the time stamp type at all. 569235426Sdelphij */ 570235426Sdelphij if (p->tstamp_type_count == 0) 571235426Sdelphij return (PCAP_ERROR_CANTSET_TSTAMP_TYPE); 572235426Sdelphij 573235426Sdelphij /* 574235426Sdelphij * Check whether we claim to support this type of time stamp. 575235426Sdelphij */ 576235426Sdelphij for (i = 0; i < p->tstamp_type_count; i++) { 577235426Sdelphij if (p->tstamp_type_list[i] == tstamp_type) { 578235426Sdelphij /* 579235426Sdelphij * Yes. 580235426Sdelphij */ 581235426Sdelphij p->opt.tstamp_type = tstamp_type; 582235426Sdelphij return (0); 583235426Sdelphij } 584235426Sdelphij } 585235426Sdelphij 586235426Sdelphij /* 587235426Sdelphij * No. We support setting the time stamp type, but not to this 588235426Sdelphij * particular value. 589235426Sdelphij */ 590235426Sdelphij return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP); 591235426Sdelphij} 592235426Sdelphij 593235426Sdelphijint 594190225Srpaulopcap_set_buffer_size(pcap_t *p, int buffer_size) 595190225Srpaulo{ 596190225Srpaulo if (pcap_check_activated(p)) 597235426Sdelphij return (PCAP_ERROR_ACTIVATED); 598190225Srpaulo p->opt.buffer_size = buffer_size; 599235426Sdelphij return (0); 600190225Srpaulo} 601190225Srpaulo 602190225Srpauloint 603190225Srpaulopcap_activate(pcap_t *p) 604190225Srpaulo{ 605190225Srpaulo int status; 606190225Srpaulo 607235426Sdelphij /* 608235426Sdelphij * Catch attempts to re-activate an already-activated 609235426Sdelphij * pcap_t; this should, for example, catch code that 610235426Sdelphij * calls pcap_open_live() followed by pcap_activate(), 611235426Sdelphij * as some code that showed up in a Stack Exchange 612235426Sdelphij * question did. 613235426Sdelphij */ 614235426Sdelphij if (pcap_check_activated(p)) 615235426Sdelphij return (PCAP_ERROR_ACTIVATED); 616190225Srpaulo status = p->activate_op(p); 617190225Srpaulo if (status >= 0) 618190225Srpaulo p->activated = 1; 619214518Srpaulo else { 620214518Srpaulo if (p->errbuf[0] == '\0') { 621214518Srpaulo /* 622214518Srpaulo * No error message supplied by the activate routine; 623214518Srpaulo * for the benefit of programs that don't specially 624214518Srpaulo * handle errors other than PCAP_ERROR, return the 625214518Srpaulo * error message corresponding to the status. 626214518Srpaulo */ 627214518Srpaulo snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", 628214518Srpaulo pcap_statustostr(status)); 629214518Srpaulo } 630214518Srpaulo 631214518Srpaulo /* 632214518Srpaulo * Undo any operation pointer setting, etc. done by 633214518Srpaulo * the activate operation. 634214518Srpaulo */ 635214518Srpaulo initialize_ops(p); 636214518Srpaulo } 637190225Srpaulo return (status); 638190225Srpaulo} 639190225Srpaulo 640190225Srpaulopcap_t * 641190225Srpaulopcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf) 642190225Srpaulo{ 643190225Srpaulo pcap_t *p; 644190225Srpaulo int status; 645190225Srpaulo 646190225Srpaulo p = pcap_create(source, errbuf); 647190225Srpaulo if (p == NULL) 648190225Srpaulo return (NULL); 649190225Srpaulo status = pcap_set_snaplen(p, snaplen); 650190225Srpaulo if (status < 0) 651190225Srpaulo goto fail; 652190225Srpaulo status = pcap_set_promisc(p, promisc); 653190225Srpaulo if (status < 0) 654190225Srpaulo goto fail; 655190225Srpaulo status = pcap_set_timeout(p, to_ms); 656190225Srpaulo if (status < 0) 657190225Srpaulo goto fail; 658190225Srpaulo /* 659190225Srpaulo * Mark this as opened with pcap_open_live(), so that, for 660190225Srpaulo * example, we show the full list of DLT_ values, rather 661190225Srpaulo * than just the ones that are compatible with capturing 662190225Srpaulo * when not in monitor mode. That allows existing applications 663190225Srpaulo * to work the way they used to work, but allows new applications 664190225Srpaulo * that know about the new open API to, for example, find out the 665190225Srpaulo * DLT_ values that they can select without changing whether 666190225Srpaulo * the adapter is in monitor mode or not. 667190225Srpaulo */ 668190225Srpaulo p->oldstyle = 1; 669190225Srpaulo status = pcap_activate(p); 670190225Srpaulo if (status < 0) 671190225Srpaulo goto fail; 672190225Srpaulo return (p); 673190225Srpaulofail: 674214518Srpaulo if (status == PCAP_ERROR) 675214518Srpaulo snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, 676214518Srpaulo p->errbuf); 677214518Srpaulo else if (status == PCAP_ERROR_NO_SUCH_DEVICE || 678235426Sdelphij status == PCAP_ERROR_PERM_DENIED || 679235426Sdelphij status == PCAP_ERROR_PROMISC_PERM_DENIED) 680214518Srpaulo snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source, 681214518Srpaulo pcap_statustostr(status), p->errbuf); 682190225Srpaulo else 683190225Srpaulo snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, 684190225Srpaulo pcap_statustostr(status)); 685190225Srpaulo pcap_close(p); 686190225Srpaulo return (NULL); 687190225Srpaulo} 688190225Srpaulo 689190225Srpauloint 69017683Spstpcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 69117683Spst{ 692235426Sdelphij return (p->read_op(p, cnt, callback, user)); 69317683Spst} 69417683Spst 695127664Sbms/* 696127664Sbms * XXX - is this necessary? 697127664Sbms */ 69817683Spstint 699127664Sbmspcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 700127664Sbms{ 701127664Sbms 702235426Sdelphij return (p->read_op(p, cnt, callback, user)); 703127664Sbms} 704127664Sbms 705127664Sbmsint 70617683Spstpcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 70717683Spst{ 70839291Sfenner register int n; 70939291Sfenner 71017683Spst for (;;) { 711127664Sbms if (p->sf.rfile != NULL) { 712127664Sbms /* 713127664Sbms * 0 means EOF, so don't loop if we get 0. 714127664Sbms */ 71539291Sfenner n = pcap_offline_read(p, cnt, callback, user); 716127664Sbms } else { 71739291Sfenner /* 71839291Sfenner * XXX keep reading until we get something 71939291Sfenner * (or an error occurs) 72039291Sfenner */ 72139291Sfenner do { 722127664Sbms n = p->read_op(p, cnt, callback, user); 72339291Sfenner } while (n == 0); 72439291Sfenner } 72517683Spst if (n <= 0) 72617683Spst return (n); 72717683Spst if (cnt > 0) { 72817683Spst cnt -= n; 72917683Spst if (cnt <= 0) 73017683Spst return (0); 73117683Spst } 73217683Spst } 73317683Spst} 73417683Spst 735127664Sbms/* 736127664Sbms * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate. 737127664Sbms */ 738127664Sbmsvoid 739127664Sbmspcap_breakloop(pcap_t *p) 740127664Sbms{ 741127664Sbms p->break_loop = 1; 742127664Sbms} 743127664Sbms 74417683Spstint 74517683Spstpcap_datalink(pcap_t *p) 74617683Spst{ 74717683Spst return (p->linktype); 74817683Spst} 74917683Spst 75017683Spstint 751190225Srpaulopcap_datalink_ext(pcap_t *p) 752190225Srpaulo{ 753190225Srpaulo return (p->linktype_ext); 754190225Srpaulo} 755190225Srpaulo 756190225Srpauloint 757109839Sfennerpcap_list_datalinks(pcap_t *p, int **dlt_buffer) 758109839Sfenner{ 759127664Sbms if (p->dlt_count == 0) { 760127664Sbms /* 761127664Sbms * We couldn't fetch the list of DLTs, which means 762127664Sbms * this platform doesn't support changing the 763127664Sbms * DLT for an interface. Return a list of DLTs 764127664Sbms * containing only the DLT this device supports. 765127664Sbms */ 766127664Sbms *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer)); 767127664Sbms if (*dlt_buffer == NULL) { 768127664Sbms (void)snprintf(p->errbuf, sizeof(p->errbuf), 769127664Sbms "malloc: %s", pcap_strerror(errno)); 770127664Sbms return (-1); 771127664Sbms } 772127664Sbms **dlt_buffer = p->linktype; 773127664Sbms return (1); 774127664Sbms } else { 775172677Smlaier *dlt_buffer = (int*)calloc(sizeof(**dlt_buffer), p->dlt_count); 776127664Sbms if (*dlt_buffer == NULL) { 777127664Sbms (void)snprintf(p->errbuf, sizeof(p->errbuf), 778127664Sbms "malloc: %s", pcap_strerror(errno)); 779127664Sbms return (-1); 780127664Sbms } 781127664Sbms (void)memcpy(*dlt_buffer, p->dlt_list, 782127664Sbms sizeof(**dlt_buffer) * p->dlt_count); 783127664Sbms return (p->dlt_count); 784109839Sfenner } 785127664Sbms} 786127664Sbms 787190225Srpaulo/* 788190225Srpaulo * In Windows, you might have a library built with one version of the 789190225Srpaulo * C runtime library and an application built with another version of 790190225Srpaulo * the C runtime library, which means that the library might use one 791190225Srpaulo * version of malloc() and free() and the application might use another 792190225Srpaulo * version of malloc() and free(). If so, that means something 793190225Srpaulo * allocated by the library cannot be freed by the application, so we 794190225Srpaulo * need to have a pcap_free_datalinks() routine to free up the list 795190225Srpaulo * allocated by pcap_list_datalinks(), even though it's just a wrapper 796190225Srpaulo * around free(). 797190225Srpaulo */ 798190225Srpaulovoid 799190225Srpaulopcap_free_datalinks(int *dlt_list) 800190225Srpaulo{ 801190225Srpaulo free(dlt_list); 802190225Srpaulo} 803190225Srpaulo 804127664Sbmsint 805127664Sbmspcap_set_datalink(pcap_t *p, int dlt) 806127664Sbms{ 807127664Sbms int i; 808127664Sbms const char *dlt_name; 809127664Sbms 810127664Sbms if (p->dlt_count == 0 || p->set_datalink_op == NULL) { 811127664Sbms /* 812127664Sbms * We couldn't fetch the list of DLTs, or we don't 813127664Sbms * have a "set datalink" operation, which means 814127664Sbms * this platform doesn't support changing the 815127664Sbms * DLT for an interface. Check whether the new 816127664Sbms * DLT is the one this interface supports. 817127664Sbms */ 818127664Sbms if (p->linktype != dlt) 819127664Sbms goto unsupported; 820127664Sbms 821127664Sbms /* 822127664Sbms * It is, so there's nothing we need to do here. 823127664Sbms */ 824127664Sbms return (0); 825109839Sfenner } 826127664Sbms for (i = 0; i < p->dlt_count; i++) 827127664Sbms if (p->dlt_list[i] == dlt) 828127664Sbms break; 829127664Sbms if (i >= p->dlt_count) 830127664Sbms goto unsupported; 831146768Ssam if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB && 832146768Ssam dlt == DLT_DOCSIS) { 833146768Ssam /* 834146768Ssam * This is presumably an Ethernet device, as the first 835146768Ssam * link-layer type it offers is DLT_EN10MB, and the only 836146768Ssam * other type it offers is DLT_DOCSIS. That means that 837146768Ssam * we can't tell the driver to supply DOCSIS link-layer 838146768Ssam * headers - we're just pretending that's what we're 839146768Ssam * getting, as, presumably, we're capturing on a dedicated 840146768Ssam * link to a Cisco Cable Modem Termination System, and 841146768Ssam * it's putting raw DOCSIS frames on the wire inside low-level 842146768Ssam * Ethernet framing. 843146768Ssam */ 844146768Ssam p->linktype = dlt; 845146768Ssam return (0); 846146768Ssam } 847127664Sbms if (p->set_datalink_op(p, dlt) == -1) 848127664Sbms return (-1); 849127664Sbms p->linktype = dlt; 850127664Sbms return (0); 851127664Sbms 852127664Sbmsunsupported: 853127664Sbms dlt_name = pcap_datalink_val_to_name(dlt); 854127664Sbms if (dlt_name != NULL) { 855127664Sbms (void) snprintf(p->errbuf, sizeof(p->errbuf), 856127664Sbms "%s is not one of the DLTs supported by this device", 857127664Sbms dlt_name); 858127664Sbms } else { 859127664Sbms (void) snprintf(p->errbuf, sizeof(p->errbuf), 860127664Sbms "DLT %d is not one of the DLTs supported by this device", 861127664Sbms dlt); 862127664Sbms } 863127664Sbms return (-1); 864109839Sfenner} 865109839Sfenner 866235426Sdelphij/* 867235426Sdelphij * This array is designed for mapping upper and lower case letter 868235426Sdelphij * together for a case independent comparison. The mappings are 869235426Sdelphij * based upon ascii character sequences. 870235426Sdelphij */ 871235426Sdelphijstatic const u_char charmap[] = { 872235426Sdelphij (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003', 873235426Sdelphij (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007', 874235426Sdelphij (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013', 875235426Sdelphij (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017', 876235426Sdelphij (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023', 877235426Sdelphij (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027', 878235426Sdelphij (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033', 879235426Sdelphij (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037', 880235426Sdelphij (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043', 881235426Sdelphij (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047', 882235426Sdelphij (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053', 883235426Sdelphij (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057', 884235426Sdelphij (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063', 885235426Sdelphij (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067', 886235426Sdelphij (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073', 887235426Sdelphij (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077', 888235426Sdelphij (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143', 889235426Sdelphij (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', 890235426Sdelphij (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', 891235426Sdelphij (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', 892235426Sdelphij (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', 893235426Sdelphij (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', 894235426Sdelphij (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133', 895235426Sdelphij (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137', 896235426Sdelphij (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143', 897235426Sdelphij (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', 898235426Sdelphij (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', 899235426Sdelphij (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', 900235426Sdelphij (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', 901235426Sdelphij (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', 902235426Sdelphij (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173', 903235426Sdelphij (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177', 904235426Sdelphij (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203', 905235426Sdelphij (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207', 906235426Sdelphij (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213', 907235426Sdelphij (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217', 908235426Sdelphij (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223', 909235426Sdelphij (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227', 910235426Sdelphij (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233', 911235426Sdelphij (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237', 912235426Sdelphij (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243', 913235426Sdelphij (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247', 914235426Sdelphij (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253', 915235426Sdelphij (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257', 916235426Sdelphij (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263', 917235426Sdelphij (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267', 918235426Sdelphij (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273', 919235426Sdelphij (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277', 920235426Sdelphij (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343', 921235426Sdelphij (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', 922235426Sdelphij (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', 923235426Sdelphij (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', 924235426Sdelphij (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', 925235426Sdelphij (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', 926235426Sdelphij (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333', 927235426Sdelphij (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337', 928235426Sdelphij (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343', 929235426Sdelphij (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', 930235426Sdelphij (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', 931235426Sdelphij (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', 932235426Sdelphij (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', 933235426Sdelphij (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', 934235426Sdelphij (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373', 935235426Sdelphij (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377', 936235426Sdelphij}; 937235426Sdelphij 938235426Sdelphijint 939235426Sdelphijpcap_strcasecmp(const char *s1, const char *s2) 940235426Sdelphij{ 941235426Sdelphij register const u_char *cm = charmap, 942235426Sdelphij *us1 = (const u_char *)s1, 943235426Sdelphij *us2 = (const u_char *)s2; 944235426Sdelphij 945235426Sdelphij while (cm[*us1] == cm[*us2++]) 946235426Sdelphij if (*us1++ == '\0') 947235426Sdelphij return(0); 948235426Sdelphij return (cm[*us1] - cm[*--us2]); 949235426Sdelphij} 950235426Sdelphij 951127664Sbmsstruct dlt_choice { 952127664Sbms const char *name; 953127664Sbms const char *description; 954127664Sbms int dlt; 955127664Sbms}; 956127664Sbms 957127664Sbms#define DLT_CHOICE(code, description) { #code, description, code } 958127664Sbms#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 } 959127664Sbms 960127664Sbmsstatic struct dlt_choice dlt_choices[] = { 961127664Sbms DLT_CHOICE(DLT_NULL, "BSD loopback"), 962127664Sbms DLT_CHOICE(DLT_EN10MB, "Ethernet"), 963127664Sbms DLT_CHOICE(DLT_IEEE802, "Token ring"), 964190225Srpaulo DLT_CHOICE(DLT_ARCNET, "BSD ARCNET"), 965127664Sbms DLT_CHOICE(DLT_SLIP, "SLIP"), 966127664Sbms DLT_CHOICE(DLT_PPP, "PPP"), 967127664Sbms DLT_CHOICE(DLT_FDDI, "FDDI"), 968147894Ssam DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"), 969127664Sbms DLT_CHOICE(DLT_RAW, "Raw IP"), 970127664Sbms DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"), 971127664Sbms DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"), 972127664Sbms DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"), 973127664Sbms DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"), 974127664Sbms DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"), 975190225Srpaulo DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"), 976127664Sbms DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"), 977127664Sbms DLT_CHOICE(DLT_IEEE802_11, "802.11"), 978127664Sbms DLT_CHOICE(DLT_FRELAY, "Frame Relay"), 979127664Sbms DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"), 980127664Sbms DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"), 981127664Sbms DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"), 982127664Sbms DLT_CHOICE(DLT_LTALK, "Localtalk"), 983127664Sbms DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"), 984241231Sdelphij DLT_CHOICE(DLT_PFSYNC, "Packet filter state syncing"), 985127664Sbms DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"), 986127664Sbms DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"), 987127664Sbms DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"), 988190225Srpaulo DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radiotap header"), 989190225Srpaulo DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"), 990190225Srpaulo DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"), 991190225Srpaulo DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"), 992190225Srpaulo DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"), 993190225Srpaulo DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"), 994190225Srpaulo DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"), 995190225Srpaulo DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"), 996190225Srpaulo DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"), 997190225Srpaulo DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"), 998127664Sbms DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"), 999190225Srpaulo DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"), 1000190225Srpaulo DLT_CHOICE(DLT_MTP2, "SS7 MTP2"), 1001190225Srpaulo DLT_CHOICE(DLT_MTP3, "SS7 MTP3"), 1002190225Srpaulo DLT_CHOICE(DLT_SCCP, "SS7 SCCP"), 1003146768Ssam DLT_CHOICE(DLT_DOCSIS, "DOCSIS"), 1004127664Sbms DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"), 1005127664Sbms DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"), 1006190225Srpaulo DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"), 1007172677Smlaier DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"), 1008172677Smlaier DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"), 1009172677Smlaier DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"), 1010172677Smlaier DLT_CHOICE(DLT_GPRS_LLC, "GPRS LLC"), 1011172677Smlaier DLT_CHOICE(DLT_GPF_T, "GPF-T"), 1012172677Smlaier DLT_CHOICE(DLT_GPF_F, "GPF-F"), 1013172677Smlaier DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"), 1014146768Ssam DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"), 1015146768Ssam DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"), 1016190225Srpaulo DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"), 1017172677Smlaier DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"), 1018172677Smlaier DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"), 1019172677Smlaier DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"), 1020172677Smlaier DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"), 1021172677Smlaier DLT_CHOICE(DLT_MFR, "FRF.16 Frame Relay"), 1022172677Smlaier DLT_CHOICE(DLT_JUNIPER_VP, "Juniper Voice PIC"), 1023172677Smlaier DLT_CHOICE(DLT_A429, "Arinc 429"), 1024172677Smlaier DLT_CHOICE(DLT_A653_ICM, "Arinc 653 Interpartition Communication"), 1025172677Smlaier DLT_CHOICE(DLT_USB, "USB"), 1026172677Smlaier DLT_CHOICE(DLT_BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"), 1027190225Srpaulo DLT_CHOICE(DLT_IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"), 1028190225Srpaulo DLT_CHOICE(DLT_USB_LINUX, "USB with Linux header"), 1029172677Smlaier DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"), 1030190225Srpaulo DLT_CHOICE(DLT_IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"), 1031190225Srpaulo DLT_CHOICE(DLT_PPI, "Per-Packet Information"), 1032190225Srpaulo DLT_CHOICE(DLT_IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"), 1033190225Srpaulo DLT_CHOICE(DLT_JUNIPER_ISM, "Juniper Integrated Service Module"), 1034235426Sdelphij DLT_CHOICE(DLT_IEEE802_15_4, "IEEE 802.15.4 with FCS"), 1035190225Srpaulo DLT_CHOICE(DLT_SITA, "SITA pseudo-header"), 1036190225Srpaulo DLT_CHOICE(DLT_ERF, "Endace ERF header"), 1037190225Srpaulo DLT_CHOICE(DLT_RAIF1, "Ethernet with u10 Networks pseudo-header"), 1038190225Srpaulo DLT_CHOICE(DLT_IPMB, "IPMB"), 1039190225Srpaulo DLT_CHOICE(DLT_JUNIPER_ST, "Juniper Secure Tunnel"), 1040190225Srpaulo DLT_CHOICE(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"), 1041190225Srpaulo DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"), 1042190225Srpaulo DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"), 1043214518Srpaulo DLT_CHOICE(DLT_MPLS, "MPLS with label as link-layer header"), 1044214518Srpaulo DLT_CHOICE(DLT_USB_LINUX_MMAPPED, "USB with padded Linux header"), 1045214518Srpaulo DLT_CHOICE(DLT_DECT, "DECT"), 1046214518Srpaulo DLT_CHOICE(DLT_AOS, "AOS Space Data Link protocol"), 1047214518Srpaulo DLT_CHOICE(DLT_WIHART, "Wireless HART"), 1048214518Srpaulo DLT_CHOICE(DLT_FC_2, "Fibre Channel FC-2"), 1049214518Srpaulo DLT_CHOICE(DLT_FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"), 1050214518Srpaulo DLT_CHOICE(DLT_IPNET, "Solaris ipnet"), 1051214518Srpaulo DLT_CHOICE(DLT_CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"), 1052214518Srpaulo DLT_CHOICE(DLT_IPV4, "Raw IPv4"), 1053214518Srpaulo DLT_CHOICE(DLT_IPV6, "Raw IPv6"), 1054235426Sdelphij DLT_CHOICE(DLT_IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"), 1055235426Sdelphij DLT_CHOICE(DLT_JUNIPER_VS, "Juniper Virtual Server"), 1056235426Sdelphij DLT_CHOICE(DLT_JUNIPER_SRX_E2E, "Juniper SRX E2E"), 1057235426Sdelphij DLT_CHOICE(DLT_JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"), 1058235426Sdelphij DLT_CHOICE(DLT_DVB_CI, "DVB-CI"), 1059235426Sdelphij DLT_CHOICE(DLT_JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"), 1060235426Sdelphij DLT_CHOICE(DLT_NFLOG, "Linux netfilter log messages"), 1061235426Sdelphij DLT_CHOICE(DLT_NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"), 1062235426Sdelphij DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"), 1063235426Sdelphij DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"), 1064127664Sbms DLT_CHOICE_SENTINEL 1065127664Sbms}; 1066127664Sbms 1067109839Sfennerint 1068127664Sbmspcap_datalink_name_to_val(const char *name) 1069127664Sbms{ 1070127664Sbms int i; 1071127664Sbms 1072127664Sbms for (i = 0; dlt_choices[i].name != NULL; i++) { 1073127664Sbms if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1, 1074127664Sbms name) == 0) 1075127664Sbms return (dlt_choices[i].dlt); 1076127664Sbms } 1077127664Sbms return (-1); 1078127664Sbms} 1079127664Sbms 1080127664Sbmsconst char * 1081127664Sbmspcap_datalink_val_to_name(int dlt) 1082127664Sbms{ 1083127664Sbms int i; 1084127664Sbms 1085127664Sbms for (i = 0; dlt_choices[i].name != NULL; i++) { 1086127664Sbms if (dlt_choices[i].dlt == dlt) 1087127664Sbms return (dlt_choices[i].name + sizeof("DLT_") - 1); 1088127664Sbms } 1089127664Sbms return (NULL); 1090127664Sbms} 1091127664Sbms 1092127664Sbmsconst char * 1093127664Sbmspcap_datalink_val_to_description(int dlt) 1094127664Sbms{ 1095127664Sbms int i; 1096127664Sbms 1097127664Sbms for (i = 0; dlt_choices[i].name != NULL; i++) { 1098127664Sbms if (dlt_choices[i].dlt == dlt) 1099127664Sbms return (dlt_choices[i].description); 1100127664Sbms } 1101127664Sbms return (NULL); 1102127664Sbms} 1103127664Sbms 1104235426Sdelphijstruct tstamp_type_choice { 1105235426Sdelphij const char *name; 1106235426Sdelphij const char *description; 1107235426Sdelphij int type; 1108235426Sdelphij}; 1109235426Sdelphij 1110235426Sdelphijstatic struct tstamp_type_choice tstamp_type_choices[] = { 1111235426Sdelphij { "host", "Host", PCAP_TSTAMP_HOST }, 1112235426Sdelphij { "host_lowprec", "Host, low precision", PCAP_TSTAMP_HOST_LOWPREC }, 1113235426Sdelphij { "host_hiprec", "Host, high precision", PCAP_TSTAMP_HOST_HIPREC }, 1114235426Sdelphij { "adapter", "Adapter", PCAP_TSTAMP_ADAPTER }, 1115235426Sdelphij { "adapter_unsynced", "Adapter, not synced with system time", PCAP_TSTAMP_ADAPTER_UNSYNCED }, 1116235426Sdelphij { NULL, NULL, 0 } 1117235426Sdelphij}; 1118235426Sdelphij 1119127664Sbmsint 1120235426Sdelphijpcap_tstamp_type_name_to_val(const char *name) 1121235426Sdelphij{ 1122235426Sdelphij int i; 1123235426Sdelphij 1124235426Sdelphij for (i = 0; tstamp_type_choices[i].name != NULL; i++) { 1125235426Sdelphij if (pcap_strcasecmp(tstamp_type_choices[i].name, name) == 0) 1126235426Sdelphij return (tstamp_type_choices[i].type); 1127235426Sdelphij } 1128235426Sdelphij return (PCAP_ERROR); 1129235426Sdelphij} 1130235426Sdelphij 1131235426Sdelphijconst char * 1132235426Sdelphijpcap_tstamp_type_val_to_name(int tstamp_type) 1133235426Sdelphij{ 1134235426Sdelphij int i; 1135235426Sdelphij 1136235426Sdelphij for (i = 0; tstamp_type_choices[i].name != NULL; i++) { 1137235426Sdelphij if (tstamp_type_choices[i].type == tstamp_type) 1138235426Sdelphij return (tstamp_type_choices[i].name); 1139235426Sdelphij } 1140235426Sdelphij return (NULL); 1141235426Sdelphij} 1142235426Sdelphij 1143235426Sdelphijconst char * 1144235426Sdelphijpcap_tstamp_type_val_to_description(int tstamp_type) 1145235426Sdelphij{ 1146235426Sdelphij int i; 1147235426Sdelphij 1148235426Sdelphij for (i = 0; tstamp_type_choices[i].name != NULL; i++) { 1149235426Sdelphij if (tstamp_type_choices[i].type == tstamp_type) 1150235426Sdelphij return (tstamp_type_choices[i].description); 1151235426Sdelphij } 1152235426Sdelphij return (NULL); 1153235426Sdelphij} 1154235426Sdelphij 1155235426Sdelphijint 115617683Spstpcap_snapshot(pcap_t *p) 115717683Spst{ 115817683Spst return (p->snapshot); 115917683Spst} 116017683Spst 116117683Spstint 116217683Spstpcap_is_swapped(pcap_t *p) 116317683Spst{ 116417683Spst return (p->sf.swapped); 116517683Spst} 116617683Spst 116717683Spstint 116817683Spstpcap_major_version(pcap_t *p) 116917683Spst{ 117017683Spst return (p->sf.version_major); 117117683Spst} 117217683Spst 117317683Spstint 117417683Spstpcap_minor_version(pcap_t *p) 117517683Spst{ 117617683Spst return (p->sf.version_minor); 117717683Spst} 117817683Spst 117917683SpstFILE * 118017683Spstpcap_file(pcap_t *p) 118117683Spst{ 118217683Spst return (p->sf.rfile); 118317683Spst} 118417683Spst 118517683Spstint 118617683Spstpcap_fileno(pcap_t *p) 118717683Spst{ 1188127664Sbms#ifndef WIN32 118917683Spst return (p->fd); 1190127664Sbms#else 1191127664Sbms if (p->adapter != NULL) 1192127664Sbms return ((int)(DWORD)p->adapter->hFile); 1193127664Sbms else 1194127664Sbms return (-1); 1195127664Sbms#endif 119617683Spst} 119717683Spst 1198146768Ssam#if !defined(WIN32) && !defined(MSDOS) 1199127664Sbmsint 1200127664Sbmspcap_get_selectable_fd(pcap_t *p) 1201127664Sbms{ 1202127664Sbms return (p->selectable_fd); 1203127664Sbms} 1204127664Sbms#endif 1205127664Sbms 120617683Spstvoid 120717683Spstpcap_perror(pcap_t *p, char *prefix) 120817683Spst{ 120917683Spst fprintf(stderr, "%s: %s\n", prefix, p->errbuf); 121017683Spst} 121117683Spst 121217683Spstchar * 121317683Spstpcap_geterr(pcap_t *p) 121417683Spst{ 121517683Spst return (p->errbuf); 121617683Spst} 121717683Spst 1218127664Sbmsint 1219127664Sbmspcap_getnonblock(pcap_t *p, char *errbuf) 1220127664Sbms{ 1221251129Sdelphij int ret; 1222251129Sdelphij 1223251129Sdelphij ret = p->getnonblock_op(p, errbuf); 1224251129Sdelphij if (ret == -1) { 1225251129Sdelphij /* 1226251129Sdelphij * In case somebody depended on the bug wherein 1227251129Sdelphij * the error message was put into p->errbuf 1228251129Sdelphij * by pcap_getnonblock_fd(). 1229251129Sdelphij */ 1230251129Sdelphij strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE); 1231251129Sdelphij } 1232251129Sdelphij return (ret); 1233127664Sbms} 1234127664Sbms 123517683Spst/* 1236127664Sbms * Get the current non-blocking mode setting, under the assumption that 1237127664Sbms * it's just the standard POSIX non-blocking flag. 1238127664Sbms * 1239127664Sbms * We don't look at "p->nonblock", in case somebody tweaked the FD 1240127664Sbms * directly. 124198530Sfenner */ 1242146768Ssam#if !defined(WIN32) && !defined(MSDOS) 124398530Sfennerint 1244127664Sbmspcap_getnonblock_fd(pcap_t *p, char *errbuf) 124598530Sfenner{ 124698530Sfenner int fdflags; 124798530Sfenner 124898530Sfenner fdflags = fcntl(p->fd, F_GETFL, 0); 124998530Sfenner if (fdflags == -1) { 1250251129Sdelphij snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", 125198530Sfenner pcap_strerror(errno)); 125298530Sfenner return (-1); 125398530Sfenner } 125498530Sfenner if (fdflags & O_NONBLOCK) 125598530Sfenner return (1); 125698530Sfenner else 125798530Sfenner return (0); 125898530Sfenner} 1259127664Sbms#endif 126098530Sfenner 126198530Sfennerint 126298530Sfennerpcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) 126398530Sfenner{ 1264251129Sdelphij int ret; 1265251129Sdelphij 1266251129Sdelphij ret = p->setnonblock_op(p, nonblock, errbuf); 1267251129Sdelphij if (ret == -1) { 1268251129Sdelphij /* 1269251129Sdelphij * In case somebody depended on the bug wherein 1270251129Sdelphij * the error message was put into p->errbuf 1271251129Sdelphij * by pcap_setnonblock_fd(). 1272251129Sdelphij */ 1273251129Sdelphij strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE); 1274251129Sdelphij } 1275251129Sdelphij return (ret); 1276127664Sbms} 1277127664Sbms 1278146768Ssam#if !defined(WIN32) && !defined(MSDOS) 1279127664Sbms/* 1280127664Sbms * Set non-blocking mode, under the assumption that it's just the 1281127664Sbms * standard POSIX non-blocking flag. (This can be called by the 1282127664Sbms * per-platform non-blocking-mode routine if that routine also 1283127664Sbms * needs to do some additional work.) 1284127664Sbms */ 1285127664Sbmsint 1286127664Sbmspcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf) 1287127664Sbms{ 128898530Sfenner int fdflags; 128998530Sfenner 129098530Sfenner fdflags = fcntl(p->fd, F_GETFL, 0); 129198530Sfenner if (fdflags == -1) { 1292251129Sdelphij snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", 129398530Sfenner pcap_strerror(errno)); 129498530Sfenner return (-1); 129598530Sfenner } 129698530Sfenner if (nonblock) 129798530Sfenner fdflags |= O_NONBLOCK; 129898530Sfenner else 129998530Sfenner fdflags &= ~O_NONBLOCK; 130098530Sfenner if (fcntl(p->fd, F_SETFL, fdflags) == -1) { 1301251129Sdelphij snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s", 130298530Sfenner pcap_strerror(errno)); 130398530Sfenner return (-1); 130498530Sfenner } 130598530Sfenner return (0); 130698530Sfenner} 1307127664Sbms#endif 130898530Sfenner 1309127664Sbms#ifdef WIN32 131098530Sfenner/* 1311127664Sbms * Generate a string for the last Win32-specific error (i.e. an error generated when 1312127664Sbms * calling a Win32 API). 1313127664Sbms * For errors occurred during standard C calls, we still use pcap_strerror() 1314127664Sbms */ 1315127664Sbmschar * 1316127664Sbmspcap_win32strerror(void) 1317127664Sbms{ 1318127664Sbms DWORD error; 1319127664Sbms static char errbuf[PCAP_ERRBUF_SIZE+1]; 1320127664Sbms int errlen; 1321146768Ssam char *p; 1322127664Sbms 1323127664Sbms error = GetLastError(); 1324127664Sbms FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, 1325127664Sbms PCAP_ERRBUF_SIZE, NULL); 1326127664Sbms 1327127664Sbms /* 1328127664Sbms * "FormatMessage()" "helpfully" sticks CR/LF at the end of the 1329127664Sbms * message. Get rid of it. 1330127664Sbms */ 1331127664Sbms errlen = strlen(errbuf); 1332127664Sbms if (errlen >= 2) { 1333127664Sbms errbuf[errlen - 1] = '\0'; 1334127664Sbms errbuf[errlen - 2] = '\0'; 1335127664Sbms } 1336146768Ssam p = strchr(errbuf, '\0'); 1337146768Ssam snprintf (p, sizeof(errbuf)-(p-errbuf), " (%lu)", error); 1338127664Sbms return (errbuf); 1339127664Sbms} 1340127664Sbms#endif 1341127664Sbms 1342127664Sbms/* 1343190225Srpaulo * Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values. 1344190225Srpaulo */ 1345190225Srpauloconst char * 1346190225Srpaulopcap_statustostr(int errnum) 1347190225Srpaulo{ 1348190225Srpaulo static char ebuf[15+10+1]; 1349190225Srpaulo 1350190225Srpaulo switch (errnum) { 1351190225Srpaulo 1352190225Srpaulo case PCAP_WARNING: 1353190225Srpaulo return("Generic warning"); 1354190225Srpaulo 1355235426Sdelphij case PCAP_WARNING_TSTAMP_TYPE_NOTSUP: 1356235426Sdelphij return ("That type of time stamp is not supported by that device"); 1357235426Sdelphij 1358190225Srpaulo case PCAP_WARNING_PROMISC_NOTSUP: 1359190225Srpaulo return ("That device doesn't support promiscuous mode"); 1360190225Srpaulo 1361190225Srpaulo case PCAP_ERROR: 1362190225Srpaulo return("Generic error"); 1363190225Srpaulo 1364190225Srpaulo case PCAP_ERROR_BREAK: 1365190225Srpaulo return("Loop terminated by pcap_breakloop"); 1366190225Srpaulo 1367190225Srpaulo case PCAP_ERROR_NOT_ACTIVATED: 1368190225Srpaulo return("The pcap_t has not been activated"); 1369190225Srpaulo 1370190225Srpaulo case PCAP_ERROR_ACTIVATED: 1371190225Srpaulo return ("The setting can't be changed after the pcap_t is activated"); 1372190225Srpaulo 1373190225Srpaulo case PCAP_ERROR_NO_SUCH_DEVICE: 1374190225Srpaulo return ("No such device exists"); 1375190225Srpaulo 1376190225Srpaulo case PCAP_ERROR_RFMON_NOTSUP: 1377190225Srpaulo return ("That device doesn't support monitor mode"); 1378190225Srpaulo 1379190225Srpaulo case PCAP_ERROR_NOT_RFMON: 1380190225Srpaulo return ("That operation is supported only in monitor mode"); 1381190225Srpaulo 1382190225Srpaulo case PCAP_ERROR_PERM_DENIED: 1383190225Srpaulo return ("You don't have permission to capture on that device"); 1384190225Srpaulo 1385190225Srpaulo case PCAP_ERROR_IFACE_NOT_UP: 1386190225Srpaulo return ("That device is not up"); 1387235426Sdelphij 1388235426Sdelphij case PCAP_ERROR_CANTSET_TSTAMP_TYPE: 1389235426Sdelphij return ("That device doesn't support setting the time stamp type"); 1390235426Sdelphij 1391235426Sdelphij case PCAP_ERROR_PROMISC_PERM_DENIED: 1392235426Sdelphij return ("You don't have permission to capture in promiscuous mode on that device"); 1393190225Srpaulo } 1394190225Srpaulo (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); 1395190225Srpaulo return(ebuf); 1396190225Srpaulo} 1397190225Srpaulo 1398190225Srpaulo/* 139917683Spst * Not all systems have strerror(). 140017683Spst */ 1401172677Smlaierconst char * 140217683Spstpcap_strerror(int errnum) 140317683Spst{ 140417683Spst#ifdef HAVE_STRERROR 140517683Spst return (strerror(errnum)); 140617683Spst#else 140717683Spst extern int sys_nerr; 140817683Spst extern const char *const sys_errlist[]; 1409190225Srpaulo static char ebuf[15+10+1]; 141017683Spst 141117683Spst if ((unsigned int)errnum < sys_nerr) 141217683Spst return ((char *)sys_errlist[errnum]); 141375107Sfenner (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); 141417683Spst return(ebuf); 141517683Spst#endif 141617683Spst} 141717683Spst 1418127664Sbmsint 1419127664Sbmspcap_setfilter(pcap_t *p, struct bpf_program *fp) 1420127664Sbms{ 1421235426Sdelphij return (p->setfilter_op(p, fp)); 1422127664Sbms} 1423127664Sbms 1424147894Ssam/* 1425147894Ssam * Set direction flag, which controls whether we accept only incoming 1426147894Ssam * packets, only outgoing packets, or both. 1427147894Ssam * Note that, depending on the platform, some or all direction arguments 1428147894Ssam * might not be supported. 1429147894Ssam */ 1430127664Sbmsint 1431162012Ssampcap_setdirection(pcap_t *p, pcap_direction_t d) 1432147894Ssam{ 1433147894Ssam if (p->setdirection_op == NULL) { 1434147894Ssam snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1435147894Ssam "Setting direction is not implemented on this platform"); 1436235426Sdelphij return (-1); 1437147894Ssam } else 1438235426Sdelphij return (p->setdirection_op(p, d)); 1439147894Ssam} 1440147894Ssam 1441147894Ssamint 1442127664Sbmspcap_stats(pcap_t *p, struct pcap_stat *ps) 1443127664Sbms{ 1444235426Sdelphij return (p->stats_op(p, ps)); 1445127664Sbms} 1446127664Sbms 1447127664Sbmsstatic int 1448146768Ssampcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_) 1449127664Sbms{ 1450127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1451127664Sbms "Statistics aren't available from a pcap_open_dead pcap_t"); 1452127664Sbms return (-1); 1453127664Sbms} 1454127664Sbms 1455190225Srpaulo#ifdef WIN32 1456190225Srpauloint 1457190225Srpaulopcap_setbuff(pcap_t *p, int dim) 1458146768Ssam{ 1459235426Sdelphij return (p->setbuff_op(p, dim)); 1460190225Srpaulo} 1461190225Srpaulo 1462190225Srpaulostatic int 1463190225Srpaulopcap_setbuff_dead(pcap_t *p, int dim) 1464190225Srpaulo{ 1465190225Srpaulo snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1466190225Srpaulo "The kernel buffer size cannot be set on a pcap_open_dead pcap_t"); 1467190225Srpaulo return (-1); 1468190225Srpaulo} 1469190225Srpaulo 1470190225Srpauloint 1471190225Srpaulopcap_setmode(pcap_t *p, int mode) 1472190225Srpaulo{ 1473235426Sdelphij return (p->setmode_op(p, mode)); 1474190225Srpaulo} 1475190225Srpaulo 1476190225Srpaulostatic int 1477190225Srpaulopcap_setmode_dead(pcap_t *p, int mode) 1478190225Srpaulo{ 1479190225Srpaulo snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1480190225Srpaulo "impossible to set mode on a pcap_open_dead pcap_t"); 1481190225Srpaulo return (-1); 1482190225Srpaulo} 1483190225Srpaulo 1484190225Srpauloint 1485190225Srpaulopcap_setmintocopy(pcap_t *p, int size) 1486190225Srpaulo{ 1487235426Sdelphij return (p->setmintocopy_op(p, size)); 1488190225Srpaulo} 1489190225Srpaulo 1490190225Srpaulostatic int 1491190225Srpaulopcap_setmintocopy_dead(pcap_t *p, int size) 1492190225Srpaulo{ 1493190225Srpaulo snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1494190225Srpaulo "The mintocopy parameter cannot be set on a pcap_open_dead pcap_t"); 1495190225Srpaulo return (-1); 1496190225Srpaulo} 1497190225Srpaulo#endif 1498190225Srpaulo 1499190225Srpaulo/* 1500190225Srpaulo * On some platforms, we need to clean up promiscuous or monitor mode 1501190225Srpaulo * when we close a device - and we want that to happen even if the 1502190225Srpaulo * application just exits without explicitl closing devices. 1503190225Srpaulo * On those platforms, we need to register a "close all the pcaps" 1504190225Srpaulo * routine to be called when we exit, and need to maintain a list of 1505190225Srpaulo * pcaps that need to be closed to clean up modes. 1506190225Srpaulo * 1507190225Srpaulo * XXX - not thread-safe. 1508190225Srpaulo */ 1509190225Srpaulo 1510190225Srpaulo/* 1511190225Srpaulo * List of pcaps on which we've done something that needs to be 1512190225Srpaulo * cleaned up. 1513190225Srpaulo * If there are any such pcaps, we arrange to call "pcap_close_all()" 1514190225Srpaulo * when we exit, and have it close all of them. 1515190225Srpaulo */ 1516190225Srpaulostatic struct pcap *pcaps_to_close; 1517190225Srpaulo 1518190225Srpaulo/* 1519190225Srpaulo * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to 1520190225Srpaulo * be called on exit. 1521190225Srpaulo */ 1522190225Srpaulostatic int did_atexit; 1523190225Srpaulo 1524190225Srpaulostatic void 1525190225Srpaulopcap_close_all(void) 1526190225Srpaulo{ 1527190225Srpaulo struct pcap *handle; 1528190225Srpaulo 1529190225Srpaulo while ((handle = pcaps_to_close) != NULL) 1530190225Srpaulo pcap_close(handle); 1531190225Srpaulo} 1532190225Srpaulo 1533190225Srpauloint 1534190225Srpaulopcap_do_addexit(pcap_t *p) 1535190225Srpaulo{ 1536183102Scsjp /* 1537190225Srpaulo * If we haven't already done so, arrange to have 1538190225Srpaulo * "pcap_close_all()" called when we exit. 1539183102Scsjp */ 1540190225Srpaulo if (!did_atexit) { 1541190225Srpaulo if (atexit(pcap_close_all) == -1) { 1542190225Srpaulo /* 1543190225Srpaulo * "atexit()" failed; let our caller know. 1544190225Srpaulo */ 1545190225Srpaulo strncpy(p->errbuf, "atexit failed", 1546190225Srpaulo PCAP_ERRBUF_SIZE); 1547190225Srpaulo return (0); 1548190225Srpaulo } 1549190225Srpaulo did_atexit = 1; 1550190225Srpaulo } 1551190225Srpaulo return (1); 1552190225Srpaulo} 1553190225Srpaulo 1554190225Srpaulovoid 1555190225Srpaulopcap_add_to_pcaps_to_close(pcap_t *p) 1556190225Srpaulo{ 1557190225Srpaulo p->md.next = pcaps_to_close; 1558190225Srpaulo pcaps_to_close = p; 1559190225Srpaulo} 1560190225Srpaulo 1561190225Srpaulovoid 1562190225Srpaulopcap_remove_from_pcaps_to_close(pcap_t *p) 1563190225Srpaulo{ 1564190225Srpaulo pcap_t *pc, *prevpc; 1565190225Srpaulo 1566190225Srpaulo for (pc = pcaps_to_close, prevpc = NULL; pc != NULL; 1567190225Srpaulo prevpc = pc, pc = pc->md.next) { 1568190225Srpaulo if (pc == p) { 1569190225Srpaulo /* 1570190225Srpaulo * Found it. Remove it from the list. 1571190225Srpaulo */ 1572190225Srpaulo if (prevpc == NULL) { 1573190225Srpaulo /* 1574190225Srpaulo * It was at the head of the list. 1575190225Srpaulo */ 1576190225Srpaulo pcaps_to_close = pc->md.next; 1577190225Srpaulo } else { 1578190225Srpaulo /* 1579190225Srpaulo * It was in the middle of the list. 1580190225Srpaulo */ 1581190225Srpaulo prevpc->md.next = pc->md.next; 1582190225Srpaulo } 1583190225Srpaulo break; 1584190225Srpaulo } 1585190225Srpaulo } 1586190225Srpaulo} 1587190225Srpaulo 1588190225Srpaulovoid 1589190225Srpaulopcap_cleanup_live_common(pcap_t *p) 1590190225Srpaulo{ 1591190225Srpaulo if (p->buffer != NULL) { 1592190225Srpaulo free(p->buffer); 1593183102Scsjp p->buffer = NULL; 1594190225Srpaulo } 1595190225Srpaulo if (p->dlt_list != NULL) { 1596190225Srpaulo free(p->dlt_list); 1597190225Srpaulo p->dlt_list = NULL; 1598190225Srpaulo p->dlt_count = 0; 1599190225Srpaulo } 1600235426Sdelphij if (p->tstamp_type_list != NULL) { 1601235426Sdelphij free(p->tstamp_type_list); 1602235426Sdelphij p->tstamp_type_list = NULL; 1603235426Sdelphij p->tstamp_type_count = 0; 1604235426Sdelphij } 1605190225Srpaulo pcap_freecode(&p->fcode); 1606146768Ssam#if !defined(WIN32) && !defined(MSDOS) 1607190225Srpaulo if (p->fd >= 0) { 1608146768Ssam close(p->fd); 1609190225Srpaulo p->fd = -1; 1610190225Srpaulo } 1611214518Srpaulo p->selectable_fd = -1; 1612214518Srpaulo p->send_fd = -1; 1613146768Ssam#endif 1614146768Ssam} 1615146768Ssam 1616127664Sbmsstatic void 1617190225Srpaulopcap_cleanup_dead(pcap_t *p _U_) 1618127664Sbms{ 1619127664Sbms /* Nothing to do. */ 1620127664Sbms} 1621127664Sbms 162275107Sfennerpcap_t * 162375107Sfennerpcap_open_dead(int linktype, int snaplen) 162475107Sfenner{ 162575107Sfenner pcap_t *p; 162675107Sfenner 162775107Sfenner p = malloc(sizeof(*p)); 162875107Sfenner if (p == NULL) 162975107Sfenner return NULL; 163075107Sfenner memset (p, 0, sizeof(*p)); 163175107Sfenner p->snapshot = snaplen; 163275107Sfenner p->linktype = linktype; 1633127664Sbms p->stats_op = pcap_stats_dead; 1634190225Srpaulo#ifdef WIN32 1635190225Srpaulo p->setbuff_op = pcap_setbuff_dead; 1636190225Srpaulo p->setmode_op = pcap_setmode_dead; 1637190225Srpaulo p->setmintocopy_op = pcap_setmintocopy_dead; 1638190225Srpaulo#endif 1639190225Srpaulo p->cleanup_op = pcap_cleanup_dead; 1640190225Srpaulo p->activated = 1; 1641235426Sdelphij return (p); 164275107Sfenner} 164375107Sfenner 1644146768Ssam/* 1645146768Ssam * API compatible with WinPcap's "send a packet" routine - returns -1 1646146768Ssam * on error, 0 otherwise. 1647146768Ssam * 1648146768Ssam * XXX - what if we get a short write? 1649146768Ssam */ 1650146768Ssamint 1651146768Ssampcap_sendpacket(pcap_t *p, const u_char *buf, int size) 1652146768Ssam{ 1653146768Ssam if (p->inject_op(p, buf, size) == -1) 1654146768Ssam return (-1); 1655146768Ssam return (0); 1656146768Ssam} 1657146768Ssam 1658146768Ssam/* 1659146768Ssam * API compatible with OpenBSD's "send a packet" routine - returns -1 on 1660146768Ssam * error, number of bytes written otherwise. 1661146768Ssam */ 1662146768Ssamint 1663146768Ssampcap_inject(pcap_t *p, const void *buf, size_t size) 1664146768Ssam{ 1665146768Ssam return (p->inject_op(p, buf, size)); 1666146768Ssam} 1667146768Ssam 166817683Spstvoid 166917683Spstpcap_close(pcap_t *p) 167017683Spst{ 1671190225Srpaulo if (p->opt.source != NULL) 1672190225Srpaulo free(p->opt.source); 1673190225Srpaulo p->cleanup_op(p); 167417683Spst free(p); 167517683Spst} 1676127664Sbms 1677127664Sbms/* 1678190225Srpaulo * Given a BPF program, a pcap_pkthdr structure for a packet, and the raw 1679190225Srpaulo * data for the packet, check whether the packet passes the filter. 1680190225Srpaulo * Returns the return value of the filter program, which will be zero if 1681190225Srpaulo * the packet doesn't pass and non-zero if the packet does pass. 1682190225Srpaulo */ 1683190225Srpauloint 1684251129Sdelphijpcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h, 1685190225Srpaulo const u_char *pkt) 1686190225Srpaulo{ 1687251129Sdelphij const struct bpf_insn *fcode = fp->bf_insns; 1688190225Srpaulo 1689190225Srpaulo if (fcode != NULL) 1690190225Srpaulo return (bpf_filter(fcode, pkt, h->len, h->caplen)); 1691190225Srpaulo else 1692190225Srpaulo return (0); 1693190225Srpaulo} 1694190225Srpaulo 1695190225Srpaulo/* 1696127664Sbms * We make the version string static, and return a pointer to it, rather 1697127664Sbms * than exporting the version string directly. On at least some UNIXes, 1698127664Sbms * if you import data from a shared library into an program, the data is 1699127664Sbms * bound into the program binary, so if the string in the version of the 1700127664Sbms * library with which the program was linked isn't the same as the 1701127664Sbms * string in the version of the library with which the program is being 1702127664Sbms * run, various undesirable things may happen (warnings, the string 1703127664Sbms * being the one from the version of the library with which the program 1704127664Sbms * was linked, or even weirder things, such as the string being the one 1705127664Sbms * from the library but being truncated). 1706127664Sbms */ 1707146768Ssam#ifdef HAVE_VERSION_H 1708146768Ssam#include "version.h" 1709146768Ssam#else 1710214518Srpaulostatic const char pcap_version_string[] = "libpcap version 1.x.y"; 1711146768Ssam#endif 1712146768Ssam 1713127664Sbms#ifdef WIN32 1714127664Sbms/* 1715127664Sbms * XXX - it'd be nice if we could somehow generate the WinPcap and libpcap 1716127664Sbms * version numbers when building WinPcap. (It'd be nice to do so for 1717127664Sbms * the packet.dll version number as well.) 1718127664Sbms */ 1719172677Smlaierstatic const char wpcap_version_string[] = "4.0"; 1720127664Sbmsstatic const char pcap_version_string_fmt[] = 1721146768Ssam "WinPcap version %s, based on %s"; 1722127664Sbmsstatic const char pcap_version_string_packet_dll_fmt[] = 1723146768Ssam "WinPcap version %s (packet.dll version %s), based on %s"; 1724146768Ssamstatic char *full_pcap_version_string; 1725127664Sbms 1726127664Sbmsconst char * 1727127664Sbmspcap_lib_version(void) 1728127664Sbms{ 1729127664Sbms char *packet_version_string; 1730146768Ssam size_t full_pcap_version_string_len; 1731127664Sbms 1732146768Ssam if (full_pcap_version_string == NULL) { 1733127664Sbms /* 1734127664Sbms * Generate the version string. 1735127664Sbms */ 1736127664Sbms packet_version_string = PacketGetVersion(); 1737127664Sbms if (strcmp(wpcap_version_string, packet_version_string) == 0) { 1738127664Sbms /* 1739127664Sbms * WinPcap version string and packet.dll version 1740127664Sbms * string are the same; just report the WinPcap 1741127664Sbms * version. 1742127664Sbms */ 1743146768Ssam full_pcap_version_string_len = 1744146768Ssam (sizeof pcap_version_string_fmt - 4) + 1745146768Ssam strlen(wpcap_version_string) + 1746146768Ssam strlen(pcap_version_string); 1747146768Ssam full_pcap_version_string = 1748146768Ssam malloc(full_pcap_version_string_len); 1749146768Ssam sprintf(full_pcap_version_string, 1750146768Ssam pcap_version_string_fmt, wpcap_version_string, 1751146768Ssam pcap_version_string); 1752127664Sbms } else { 1753127664Sbms /* 1754127664Sbms * WinPcap version string and packet.dll version 1755127664Sbms * string are different; that shouldn't be the 1756127664Sbms * case (the two libraries should come from the 1757127664Sbms * same version of WinPcap), so we report both 1758127664Sbms * versions. 1759127664Sbms */ 1760146768Ssam full_pcap_version_string_len = 1761146768Ssam (sizeof pcap_version_string_packet_dll_fmt - 6) + 1762127664Sbms strlen(wpcap_version_string) + 1763146768Ssam strlen(packet_version_string) + 1764146768Ssam strlen(pcap_version_string); 1765146768Ssam full_pcap_version_string = malloc(full_pcap_version_string_len); 1766146768Ssam 1767146768Ssam sprintf(full_pcap_version_string, 1768127664Sbms pcap_version_string_packet_dll_fmt, 1769146768Ssam wpcap_version_string, packet_version_string, 1770146768Ssam pcap_version_string); 1771127664Sbms } 1772127664Sbms } 1773146768Ssam return (full_pcap_version_string); 1774127664Sbms} 1775127664Sbms 1776146768Ssam#elif defined(MSDOS) 1777146768Ssam 1778146768Ssamstatic char *full_pcap_version_string; 1779146768Ssam 1780127664Sbmsconst char * 1781146768Ssampcap_lib_version (void) 1782146768Ssam{ 1783146768Ssam char *packet_version_string; 1784146768Ssam size_t full_pcap_version_string_len; 1785146768Ssam static char dospfx[] = "DOS-"; 1786146768Ssam 1787146768Ssam if (full_pcap_version_string == NULL) { 1788146768Ssam /* 1789146768Ssam * Generate the version string. 1790146768Ssam */ 1791146768Ssam full_pcap_version_string_len = 1792146768Ssam sizeof dospfx + strlen(pcap_version_string); 1793146768Ssam full_pcap_version_string = 1794146768Ssam malloc(full_pcap_version_string_len); 1795146768Ssam strcpy(full_pcap_version_string, dospfx); 1796146768Ssam strcat(full_pcap_version_string, pcap_version_string); 1797146768Ssam } 1798146768Ssam return (full_pcap_version_string); 1799146768Ssam} 1800146768Ssam 1801146768Ssam#else /* UN*X */ 1802146768Ssam 1803146768Ssamconst char * 1804127664Sbmspcap_lib_version(void) 1805127664Sbms{ 1806127664Sbms return (pcap_version_string); 1807127664Sbms} 1808127664Sbms#endif 1809