18cf6c252SPaul Traina /* 2a4b5b39fSBill Fenner * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998 38cf6c252SPaul Traina * The Regents of the University of California. All rights reserved. 48cf6c252SPaul Traina * 58cf6c252SPaul Traina * Redistribution and use in source and binary forms, with or without 68cf6c252SPaul Traina * modification, are permitted provided that the following conditions 78cf6c252SPaul Traina * are met: 88cf6c252SPaul Traina * 1. Redistributions of source code must retain the above copyright 98cf6c252SPaul Traina * notice, this list of conditions and the following disclaimer. 108cf6c252SPaul Traina * 2. Redistributions in binary form must reproduce the above copyright 118cf6c252SPaul Traina * notice, this list of conditions and the following disclaimer in the 128cf6c252SPaul Traina * documentation and/or other materials provided with the distribution. 138cf6c252SPaul Traina * 3. All advertising materials mentioning features or use of this software 148cf6c252SPaul Traina * must display the following acknowledgement: 158cf6c252SPaul Traina * This product includes software developed by the Computer Systems 168cf6c252SPaul Traina * Engineering Group at Lawrence Berkeley Laboratory. 178cf6c252SPaul Traina * 4. Neither the name of the University nor of the Laboratory may be used 188cf6c252SPaul Traina * to endorse or promote products derived from this software without 198cf6c252SPaul Traina * specific prior written permission. 208cf6c252SPaul Traina * 218cf6c252SPaul Traina * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 228cf6c252SPaul Traina * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 238cf6c252SPaul Traina * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 248cf6c252SPaul Traina * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 258cf6c252SPaul Traina * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 268cf6c252SPaul Traina * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 278cf6c252SPaul Traina * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 288cf6c252SPaul Traina * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 298cf6c252SPaul Traina * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 308cf6c252SPaul Traina * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 318cf6c252SPaul Traina * SUCH DAMAGE. 328cf6c252SPaul Traina */ 338cf6c252SPaul Traina 34dc2c7305SBill Fenner #ifdef HAVE_CONFIG_H 35b00ab754SHans Petter Selasky #include <config.h> 368cf6c252SPaul Traina #endif 378cf6c252SPaul Traina 38b00ab754SHans Petter Selasky #include <pcap-types.h> 39b00ab754SHans Petter Selasky #ifndef _WIN32 40b00ab754SHans Petter Selasky #include <sys/param.h> 41b00ab754SHans Petter Selasky #ifndef MSDOS 42b00ab754SHans Petter Selasky #include <sys/file.h> 43a0ee43a1SRui Paulo #endif 44b00ab754SHans Petter Selasky #include <sys/ioctl.h> 45b00ab754SHans Petter Selasky #include <sys/socket.h> 46b00ab754SHans Petter Selasky #ifdef HAVE_SYS_SOCKIO_H 47b00ab754SHans Petter Selasky #include <sys/sockio.h> 48a0ee43a1SRui Paulo #endif 49b00ab754SHans Petter Selasky 50b00ab754SHans Petter Selasky struct mbuf; /* Squelch compiler warnings on some platforms for */ 51b00ab754SHans Petter Selasky struct rtentry; /* declarations in <net/if.h> */ 52b00ab754SHans Petter Selasky #include <net/if.h> 53b00ab754SHans Petter Selasky #include <netinet/in.h> 54ada6f083SXin LI #endif /* _WIN32 */ 558cf6c252SPaul Traina 56b00ab754SHans Petter Selasky #include <ctype.h> 578cf6c252SPaul Traina #include <stdio.h> 588cf6c252SPaul Traina #include <stdlib.h> 598cf6c252SPaul Traina #include <string.h> 60d1e87331SXin LI #if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__MINGW32__) 618cf6c252SPaul Traina #include <unistd.h> 62feb4ecdbSBruce M Simpson #endif 630a94d38fSBill Fenner #include <fcntl.h> 640a94d38fSBill Fenner #include <errno.h> 65b00ab754SHans Petter Selasky #ifdef HAVE_LIMITS_H 66b00ab754SHans Petter Selasky #include <limits.h> 67b00ab754SHans Petter Selasky #else 68b00ab754SHans Petter Selasky #define INT_MAX 2147483647 69b00ab754SHans Petter Selasky #endif 708cf6c252SPaul Traina 718cf6c252SPaul Traina #ifdef HAVE_OS_PROTO_H 728cf6c252SPaul Traina #include "os-proto.h" 738cf6c252SPaul Traina #endif 748cf6c252SPaul Traina 7504fb2745SSam Leffler #ifdef MSDOS 7604fb2745SSam Leffler #include "pcap-dos.h" 7704fb2745SSam Leffler #endif 7804fb2745SSam Leffler 798cf6c252SPaul Traina #include "pcap-int.h" 808cf6c252SPaul Traina 81b00ab754SHans Petter Selasky #include "optimize.h" 82b00ab754SHans Petter Selasky 83feb4ecdbSBruce M Simpson #ifdef HAVE_DAG_API 84edc89b24SXin LI #include "pcap-dag.h" 85edc89b24SXin LI #endif /* HAVE_DAG_API */ 86edc89b24SXin LI 87edc89b24SXin LI #ifdef HAVE_SEPTEL_API 88edc89b24SXin LI #include "pcap-septel.h" 89edc89b24SXin LI #endif /* HAVE_SEPTEL_API */ 90edc89b24SXin LI 91edc89b24SXin LI #ifdef HAVE_SNF_API 92edc89b24SXin LI #include "pcap-snf.h" 93edc89b24SXin LI #endif /* HAVE_SNF_API */ 94edc89b24SXin LI 95ada6f083SXin LI #ifdef HAVE_TC_API 96ada6f083SXin LI #include "pcap-tc.h" 97ada6f083SXin LI #endif /* HAVE_TC_API */ 98ada6f083SXin LI 99edc89b24SXin LI #ifdef PCAP_SUPPORT_USB 100edc89b24SXin LI #include "pcap-usb-linux.h" 101edc89b24SXin LI #endif 102edc89b24SXin LI 103edc89b24SXin LI #ifdef PCAP_SUPPORT_BT 104edc89b24SXin LI #include "pcap-bt-linux.h" 105edc89b24SXin LI #endif 106edc89b24SXin LI 107681ed54cSXin LI #ifdef PCAP_SUPPORT_BT_MONITOR 108681ed54cSXin LI #include "pcap-bt-monitor-linux.h" 109681ed54cSXin LI #endif 110681ed54cSXin LI 111edc89b24SXin LI #ifdef PCAP_SUPPORT_NETFILTER 112edc89b24SXin LI #include "pcap-netfilter-linux.h" 113feb4ecdbSBruce M Simpson #endif 114feb4ecdbSBruce M Simpson 11586f82ef9SLuigi Rizzo #ifdef PCAP_SUPPORT_NETMAP 116b00ab754SHans Petter Selasky #include "pcap-netmap.h" 11786f82ef9SLuigi Rizzo #endif 11886f82ef9SLuigi Rizzo 119681ed54cSXin LI #ifdef PCAP_SUPPORT_DBUS 120681ed54cSXin LI #include "pcap-dbus.h" 121681ed54cSXin LI #endif 122681ed54cSXin LI 123b00ab754SHans Petter Selasky #ifdef PCAP_SUPPORT_RDMASNIFF 124b00ab754SHans Petter Selasky #include "pcap-rdmasniff.h" 125b00ab754SHans Petter Selasky #endif 126b00ab754SHans Petter Selasky 127b00ab754SHans Petter Selasky #ifdef _WIN32 128b00ab754SHans Petter Selasky /* 129b00ab754SHans Petter Selasky * DllMain(), required when built as a Windows DLL. 130b00ab754SHans Petter Selasky */ 131b00ab754SHans Petter Selasky BOOL WINAPI DllMain( 132b00ab754SHans Petter Selasky HANDLE hinstDLL, 133b00ab754SHans Petter Selasky DWORD dwReason, 134b00ab754SHans Petter Selasky LPVOID lpvReserved 135b00ab754SHans Petter Selasky ) 136b00ab754SHans Petter Selasky { 137b00ab754SHans Petter Selasky return (TRUE); 138b00ab754SHans Petter Selasky } 139b00ab754SHans Petter Selasky 140b00ab754SHans Petter Selasky /* 141b00ab754SHans Petter Selasky * Start WinSock. 142*57e22627SCy Schubert * Exported in case some applications using WinPcap/Npcap called it, 143b00ab754SHans Petter Selasky * even though it wasn't exported. 144b00ab754SHans Petter Selasky */ 145b00ab754SHans Petter Selasky int 146b00ab754SHans Petter Selasky wsockinit(void) 147b00ab754SHans Petter Selasky { 148b00ab754SHans Petter Selasky WORD wVersionRequested; 149b00ab754SHans Petter Selasky WSADATA wsaData; 150b00ab754SHans Petter Selasky static int err = -1; 151b00ab754SHans Petter Selasky static int done = 0; 152b00ab754SHans Petter Selasky 153b00ab754SHans Petter Selasky if (done) 154b00ab754SHans Petter Selasky return (err); 155b00ab754SHans Petter Selasky 156b00ab754SHans Petter Selasky wVersionRequested = MAKEWORD( 1, 1); 157b00ab754SHans Petter Selasky err = WSAStartup( wVersionRequested, &wsaData ); 158b00ab754SHans Petter Selasky atexit ((void(*)(void))WSACleanup); 159b00ab754SHans Petter Selasky done = 1; 160b00ab754SHans Petter Selasky 161b00ab754SHans Petter Selasky if ( err != 0 ) 162b00ab754SHans Petter Selasky err = -1; 163b00ab754SHans Petter Selasky return (err); 164b00ab754SHans Petter Selasky } 165b00ab754SHans Petter Selasky 166b00ab754SHans Petter Selasky /* 167b00ab754SHans Petter Selasky * This is the exported function; new programs should call this. 168b00ab754SHans Petter Selasky */ 169b00ab754SHans Petter Selasky int 170b00ab754SHans Petter Selasky pcap_wsockinit(void) 171b00ab754SHans Petter Selasky { 172b00ab754SHans Petter Selasky return (wsockinit()); 173b00ab754SHans Petter Selasky } 174b00ab754SHans Petter Selasky #endif /* _WIN32 */ 175b00ab754SHans Petter Selasky 176b00ab754SHans Petter Selasky /* 177b00ab754SHans Petter Selasky * String containing the library version. 178b00ab754SHans Petter Selasky * Not explicitly exported via a header file - the right API to use 179b00ab754SHans Petter Selasky * is pcap_lib_version() - but some programs included it, so we 180b00ab754SHans Petter Selasky * provide it. 181b00ab754SHans Petter Selasky * 182b00ab754SHans Petter Selasky * We declare it here, right before defining it, to squelch any 183b00ab754SHans Petter Selasky * warnings we might get from compilers about the lack of a 184b00ab754SHans Petter Selasky * declaration. 185b00ab754SHans Petter Selasky */ 186b00ab754SHans Petter Selasky PCAP_API char pcap_version[]; 187b00ab754SHans Petter Selasky PCAP_API_DEF char pcap_version[] = PACKAGE_VERSION; 188b00ab754SHans Petter Selasky 189*57e22627SCy Schubert static void 190*57e22627SCy Schubert pcap_set_not_initialized_message(pcap_t *pcap) 191a8e07101SRui Paulo { 192b00ab754SHans Petter Selasky if (pcap->activated) { 193b00ab754SHans Petter Selasky /* A module probably forgot to set the function pointer */ 194b00ab754SHans Petter Selasky (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), 195b00ab754SHans Petter Selasky "This operation isn't properly handled by that device"); 196*57e22627SCy Schubert return; 197b00ab754SHans Petter Selasky } 198ada6f083SXin LI /* in case the caller doesn't check for PCAP_ERROR_NOT_ACTIVATED */ 199ada6f083SXin LI (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), 200ada6f083SXin LI "This handle hasn't been activated yet"); 201*57e22627SCy Schubert } 202*57e22627SCy Schubert 203*57e22627SCy Schubert static int 204*57e22627SCy Schubert pcap_read_not_initialized(pcap_t *pcap, int cnt _U_, pcap_handler callback _U_, 205*57e22627SCy Schubert u_char *user _U_) 206*57e22627SCy Schubert { 207*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 208*57e22627SCy Schubert /* this means 'not initialized' */ 209*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 210*57e22627SCy Schubert } 211*57e22627SCy Schubert 212*57e22627SCy Schubert static int 213*57e22627SCy Schubert pcap_inject_not_initialized(pcap_t *pcap, const void * buf _U_, size_t size _U_) 214*57e22627SCy Schubert { 215*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 216*57e22627SCy Schubert /* this means 'not initialized' */ 217*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 218*57e22627SCy Schubert } 219*57e22627SCy Schubert 220*57e22627SCy Schubert static int 221*57e22627SCy Schubert pcap_setfilter_not_initialized(pcap_t *pcap, struct bpf_program *fp _U_) 222*57e22627SCy Schubert { 223*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 224*57e22627SCy Schubert /* this means 'not initialized' */ 225*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 226*57e22627SCy Schubert } 227*57e22627SCy Schubert 228*57e22627SCy Schubert static int 229*57e22627SCy Schubert pcap_setdirection_not_initialized(pcap_t *pcap, pcap_direction_t d _U_) 230*57e22627SCy Schubert { 231*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 232*57e22627SCy Schubert /* this means 'not initialized' */ 233*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 234*57e22627SCy Schubert } 235*57e22627SCy Schubert 236*57e22627SCy Schubert static int 237*57e22627SCy Schubert pcap_set_datalink_not_initialized(pcap_t *pcap, int dlt _U_) 238*57e22627SCy Schubert { 239*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 240*57e22627SCy Schubert /* this means 'not initialized' */ 241*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 242*57e22627SCy Schubert } 243*57e22627SCy Schubert 244*57e22627SCy Schubert static int 245*57e22627SCy Schubert pcap_getnonblock_not_initialized(pcap_t *pcap) 246*57e22627SCy Schubert { 247*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 248*57e22627SCy Schubert /* this means 'not initialized' */ 249*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 250*57e22627SCy Schubert } 251*57e22627SCy Schubert 252*57e22627SCy Schubert static int 253*57e22627SCy Schubert pcap_stats_not_initialized(pcap_t *pcap, struct pcap_stat *ps _U_) 254*57e22627SCy Schubert { 255*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 256a8e07101SRui Paulo /* this means 'not initialized' */ 257d1e87331SXin LI return (PCAP_ERROR_NOT_ACTIVATED); 258a8e07101SRui Paulo } 259a8e07101SRui Paulo 260ada6f083SXin LI #ifdef _WIN32 261*57e22627SCy Schubert struct pcap_stat * 262*57e22627SCy Schubert pcap_stats_ex_not_initialized(pcap_t *pcap, int *pcap_stat_size _U_) 263681ed54cSXin LI { 264*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 265b00ab754SHans Petter Selasky return (NULL); 266b00ab754SHans Petter Selasky } 267*57e22627SCy Schubert 268*57e22627SCy Schubert static int 269*57e22627SCy Schubert pcap_setbuff_not_initialized(pcap_t *pcap, int dim _U_) 270*57e22627SCy Schubert { 271*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 272*57e22627SCy Schubert /* this means 'not initialized' */ 273*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 274*57e22627SCy Schubert } 275*57e22627SCy Schubert 276*57e22627SCy Schubert static int 277*57e22627SCy Schubert pcap_setmode_not_initialized(pcap_t *pcap, int mode _U_) 278*57e22627SCy Schubert { 279*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 280*57e22627SCy Schubert /* this means 'not initialized' */ 281*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 282*57e22627SCy Schubert } 283*57e22627SCy Schubert 284*57e22627SCy Schubert static int 285*57e22627SCy Schubert pcap_setmintocopy_not_initialized(pcap_t *pcap, int size _U_) 286*57e22627SCy Schubert { 287*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 288*57e22627SCy Schubert /* this means 'not initialized' */ 289*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 290ada6f083SXin LI } 291ada6f083SXin LI 292ada6f083SXin LI static HANDLE 293ada6f083SXin LI pcap_getevent_not_initialized(pcap_t *pcap) 294ada6f083SXin LI { 295*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 296b00ab754SHans Petter Selasky return (INVALID_HANDLE_VALUE); 297b00ab754SHans Petter Selasky } 298*57e22627SCy Schubert 299*57e22627SCy Schubert static int 300*57e22627SCy Schubert pcap_oid_get_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_, 301*57e22627SCy Schubert void *data _U_, size_t *lenp _U_) 302*57e22627SCy Schubert { 303*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 304*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 305*57e22627SCy Schubert } 306*57e22627SCy Schubert 307*57e22627SCy Schubert static int 308*57e22627SCy Schubert pcap_oid_set_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_, 309*57e22627SCy Schubert const void *data _U_, size_t *lenp _U_) 310*57e22627SCy Schubert { 311*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 312*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 313ada6f083SXin LI } 314ada6f083SXin LI 315ada6f083SXin LI static u_int 316ada6f083SXin LI pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, int sync) 317ada6f083SXin LI { 318*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 319b00ab754SHans Petter Selasky return (0); 320b00ab754SHans Petter Selasky } 321*57e22627SCy Schubert 322*57e22627SCy Schubert static int 323*57e22627SCy Schubert pcap_setuserbuffer_not_initialized(pcap_t *pcap, int size _U_) 324*57e22627SCy Schubert { 325*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 326*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 327*57e22627SCy Schubert } 328*57e22627SCy Schubert 329*57e22627SCy Schubert static int 330*57e22627SCy Schubert pcap_live_dump_not_initialized(pcap_t *pcap, char *filename _U_, int maxsize _U_, 331*57e22627SCy Schubert int maxpacks _U_) 332*57e22627SCy Schubert { 333*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 334*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 335*57e22627SCy Schubert } 336*57e22627SCy Schubert 337*57e22627SCy Schubert static int 338*57e22627SCy Schubert pcap_live_dump_ended_not_initialized(pcap_t *pcap, int sync _U_) 339*57e22627SCy Schubert { 340*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 341*57e22627SCy Schubert return (PCAP_ERROR_NOT_ACTIVATED); 342ada6f083SXin LI } 343ada6f083SXin LI 344ada6f083SXin LI static PAirpcapHandle 345ada6f083SXin LI pcap_get_airpcap_handle_not_initialized(pcap_t *pcap) 346ada6f083SXin LI { 347*57e22627SCy Schubert pcap_set_not_initialized_message(pcap); 348681ed54cSXin LI return (NULL); 349681ed54cSXin LI } 350681ed54cSXin LI #endif 351681ed54cSXin LI 352a8e07101SRui Paulo /* 353a8e07101SRui Paulo * Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't, 354a8e07101SRui Paulo * a PCAP_ERROR value on an error. 355a8e07101SRui Paulo */ 356a8e07101SRui Paulo int 357a8e07101SRui Paulo pcap_can_set_rfmon(pcap_t *p) 358a8e07101SRui Paulo { 359a8e07101SRui Paulo return (p->can_set_rfmon_op(p)); 360a8e07101SRui Paulo } 361a8e07101SRui Paulo 362a8e07101SRui Paulo /* 363a8e07101SRui Paulo * For systems where rfmon mode is never supported. 364a8e07101SRui Paulo */ 365a8e07101SRui Paulo static int 366a8e07101SRui Paulo pcap_cant_set_rfmon(pcap_t *p _U_) 367a8e07101SRui Paulo { 368a8e07101SRui Paulo return (0); 369a8e07101SRui Paulo } 370a8e07101SRui Paulo 371a8e07101SRui Paulo /* 372d1e87331SXin LI * Sets *tstamp_typesp to point to an array 1 or more supported time stamp 373d1e87331SXin LI * types; the return value is the number of supported time stamp types. 374d1e87331SXin LI * The list should be freed by a call to pcap_free_tstamp_types() when 375d1e87331SXin LI * you're done with it. 376d1e87331SXin LI * 377d1e87331SXin LI * A return value of 0 means "you don't get a choice of time stamp type", 378d1e87331SXin LI * in which case *tstamp_typesp is set to null. 379d1e87331SXin LI * 380d1e87331SXin LI * PCAP_ERROR is returned on error. 381d1e87331SXin LI */ 382d1e87331SXin LI int 383d1e87331SXin LI pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp) 384d1e87331SXin LI { 385d1e87331SXin LI if (p->tstamp_type_count == 0) { 386d1e87331SXin LI /* 387d1e87331SXin LI * We don't support multiple time stamp types. 388*57e22627SCy Schubert * That means the only type we support is PCAP_TSTAMP_HOST; 389*57e22627SCy Schubert * set up a list containing only that type. 390d1e87331SXin LI */ 391*57e22627SCy Schubert *tstamp_typesp = (int*)malloc(sizeof(**tstamp_typesp)); 392*57e22627SCy Schubert if (*tstamp_typesp == NULL) { 393*57e22627SCy Schubert pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 394*57e22627SCy Schubert errno, "malloc"); 395*57e22627SCy Schubert return (PCAP_ERROR); 396*57e22627SCy Schubert } 397*57e22627SCy Schubert **tstamp_typesp = PCAP_TSTAMP_HOST; 398*57e22627SCy Schubert return (1); 399d1e87331SXin LI } else { 400d1e87331SXin LI *tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp), 401d1e87331SXin LI p->tstamp_type_count); 402d1e87331SXin LI if (*tstamp_typesp == NULL) { 403b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 404b00ab754SHans Petter Selasky errno, "malloc"); 405d1e87331SXin LI return (PCAP_ERROR); 406d1e87331SXin LI } 407d1e87331SXin LI (void)memcpy(*tstamp_typesp, p->tstamp_type_list, 408d1e87331SXin LI sizeof(**tstamp_typesp) * p->tstamp_type_count); 409d1e87331SXin LI return (p->tstamp_type_count); 410d1e87331SXin LI } 411*57e22627SCy Schubert } 412d1e87331SXin LI 413d1e87331SXin LI /* 414d1e87331SXin LI * In Windows, you might have a library built with one version of the 415d1e87331SXin LI * C runtime library and an application built with another version of 416d1e87331SXin LI * the C runtime library, which means that the library might use one 417d1e87331SXin LI * version of malloc() and free() and the application might use another 418d1e87331SXin LI * version of malloc() and free(). If so, that means something 419d1e87331SXin LI * allocated by the library cannot be freed by the application, so we 420d1e87331SXin LI * need to have a pcap_free_tstamp_types() routine to free up the list 421d1e87331SXin LI * allocated by pcap_list_tstamp_types(), even though it's just a wrapper 422d1e87331SXin LI * around free(). 423d1e87331SXin LI */ 424d1e87331SXin LI void 425d1e87331SXin LI pcap_free_tstamp_types(int *tstamp_type_list) 426d1e87331SXin LI { 427d1e87331SXin LI free(tstamp_type_list); 428d1e87331SXin LI } 429d1e87331SXin LI 430d1e87331SXin LI /* 431a0ee43a1SRui Paulo * Default one-shot callback; overridden for capture types where the 432a0ee43a1SRui Paulo * packet data cannot be guaranteed to be available after the callback 433a0ee43a1SRui Paulo * returns, so that a copy must be made. 434a8e07101SRui Paulo */ 435681ed54cSXin LI void 436a0ee43a1SRui Paulo pcap_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *pkt) 437a0ee43a1SRui Paulo { 438a0ee43a1SRui Paulo struct oneshot_userdata *sp = (struct oneshot_userdata *)user; 439a0ee43a1SRui Paulo 440a0ee43a1SRui Paulo *sp->hdr = *h; 441a0ee43a1SRui Paulo *sp->pkt = pkt; 442a0ee43a1SRui Paulo } 443a0ee43a1SRui Paulo 444a0ee43a1SRui Paulo const u_char * 445a0ee43a1SRui Paulo pcap_next(pcap_t *p, struct pcap_pkthdr *h) 446a0ee43a1SRui Paulo { 447a0ee43a1SRui Paulo struct oneshot_userdata s; 448a0ee43a1SRui Paulo const u_char *pkt; 449a0ee43a1SRui Paulo 450a0ee43a1SRui Paulo s.hdr = h; 451a0ee43a1SRui Paulo s.pkt = &pkt; 452a0ee43a1SRui Paulo s.pd = p; 453a0ee43a1SRui Paulo if (pcap_dispatch(p, 1, p->oneshot_callback, (u_char *)&s) <= 0) 454a0ee43a1SRui Paulo return (0); 455a0ee43a1SRui Paulo return (pkt); 456a0ee43a1SRui Paulo } 457a0ee43a1SRui Paulo 458a0ee43a1SRui Paulo int 459a0ee43a1SRui Paulo pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, 460a0ee43a1SRui Paulo const u_char **pkt_data) 461a0ee43a1SRui Paulo { 462a0ee43a1SRui Paulo struct oneshot_userdata s; 463a0ee43a1SRui Paulo 464a0ee43a1SRui Paulo s.hdr = &p->pcap_header; 465a0ee43a1SRui Paulo s.pkt = pkt_data; 466a0ee43a1SRui Paulo s.pd = p; 467a0ee43a1SRui Paulo 468a0ee43a1SRui Paulo /* Saves a pointer to the packet headers */ 469a0ee43a1SRui Paulo *pkt_header= &p->pcap_header; 470a0ee43a1SRui Paulo 471681ed54cSXin LI if (p->rfile != NULL) { 472a0ee43a1SRui Paulo int status; 473a0ee43a1SRui Paulo 474a0ee43a1SRui Paulo /* We are on an offline capture */ 475d1e87331SXin LI status = pcap_offline_read(p, 1, p->oneshot_callback, 476d1e87331SXin LI (u_char *)&s); 477a8e07101SRui Paulo 478a8e07101SRui Paulo /* 479a0ee43a1SRui Paulo * Return codes for pcap_offline_read() are: 480a0ee43a1SRui Paulo * - 0: EOF 481a0ee43a1SRui Paulo * - -1: error 482a0ee43a1SRui Paulo * - >1: OK 483a0ee43a1SRui Paulo * The first one ('0') conflicts with the return code of 484a0ee43a1SRui Paulo * 0 from pcap_read() meaning "no packets arrived before 485a0ee43a1SRui Paulo * the timeout expired", so we map it to -2 so you can 486a0ee43a1SRui Paulo * distinguish between an EOF from a savefile and a 487a0ee43a1SRui Paulo * "no packets arrived before the timeout expired, try 488a0ee43a1SRui Paulo * again" from a live capture. 489a0ee43a1SRui Paulo */ 490a0ee43a1SRui Paulo if (status == 0) 491a0ee43a1SRui Paulo return (-2); 492a0ee43a1SRui Paulo else 493a0ee43a1SRui Paulo return (status); 494a0ee43a1SRui Paulo } 495a0ee43a1SRui Paulo 496a0ee43a1SRui Paulo /* 497a0ee43a1SRui Paulo * Return codes for pcap_read() are: 498a0ee43a1SRui Paulo * - 0: timeout 499a0ee43a1SRui Paulo * - -1: error 500a0ee43a1SRui Paulo * - -2: loop was broken out of with pcap_breakloop() 501a0ee43a1SRui Paulo * - >1: OK 502a0ee43a1SRui Paulo * The first one ('0') conflicts with the return code of 0 from 503a0ee43a1SRui Paulo * pcap_offline_read() meaning "end of file". 504a0ee43a1SRui Paulo */ 505d1e87331SXin LI return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s)); 506a0ee43a1SRui Paulo } 507a0ee43a1SRui Paulo 508b00ab754SHans Petter Selasky /* 509b00ab754SHans Petter Selasky * Implementation of a pcap_if_list_t. 510b00ab754SHans Petter Selasky */ 511b00ab754SHans Petter Selasky struct pcap_if_list { 512b00ab754SHans Petter Selasky pcap_if_t *beginning; 513b00ab754SHans Petter Selasky }; 514b00ab754SHans Petter Selasky 515ada6f083SXin LI static struct capture_source_type { 516b00ab754SHans Petter Selasky int (*findalldevs_op)(pcap_if_list_t *, char *); 517edc89b24SXin LI pcap_t *(*create_op)(const char *, char *, int *); 518edc89b24SXin LI } capture_source_types[] = { 519edc89b24SXin LI #ifdef HAVE_DAG_API 520edc89b24SXin LI { dag_findalldevs, dag_create }, 521edc89b24SXin LI #endif 522edc89b24SXin LI #ifdef HAVE_SEPTEL_API 523edc89b24SXin LI { septel_findalldevs, septel_create }, 524edc89b24SXin LI #endif 525edc89b24SXin LI #ifdef HAVE_SNF_API 526edc89b24SXin LI { snf_findalldevs, snf_create }, 527edc89b24SXin LI #endif 528ada6f083SXin LI #ifdef HAVE_TC_API 529ada6f083SXin LI { TcFindAllDevs, TcCreate }, 530ada6f083SXin LI #endif 531edc89b24SXin LI #ifdef PCAP_SUPPORT_BT 532edc89b24SXin LI { bt_findalldevs, bt_create }, 533edc89b24SXin LI #endif 534681ed54cSXin LI #ifdef PCAP_SUPPORT_BT_MONITOR 535681ed54cSXin LI { bt_monitor_findalldevs, bt_monitor_create }, 536681ed54cSXin LI #endif 537edc89b24SXin LI #ifdef PCAP_SUPPORT_USB 538edc89b24SXin LI { usb_findalldevs, usb_create }, 539edc89b24SXin LI #endif 540edc89b24SXin LI #ifdef PCAP_SUPPORT_NETFILTER 541edc89b24SXin LI { netfilter_findalldevs, netfilter_create }, 542edc89b24SXin LI #endif 543b00ab754SHans Petter Selasky #ifdef PCAP_SUPPORT_NETMAP 544b00ab754SHans Petter Selasky { pcap_netmap_findalldevs, pcap_netmap_create }, 545b00ab754SHans Petter Selasky #endif 546681ed54cSXin LI #ifdef PCAP_SUPPORT_DBUS 547681ed54cSXin LI { dbus_findalldevs, dbus_create }, 548681ed54cSXin LI #endif 549b00ab754SHans Petter Selasky #ifdef PCAP_SUPPORT_RDMASNIFF 550b00ab754SHans Petter Selasky { rdmasniff_findalldevs, rdmasniff_create }, 551b00ab754SHans Petter Selasky #endif 552edc89b24SXin LI { NULL, NULL } 553edc89b24SXin LI }; 554edc89b24SXin LI 555edc89b24SXin LI /* 556edc89b24SXin LI * Get a list of all capture sources that are up and that we can open. 557edc89b24SXin LI * Returns -1 on error, 0 otherwise. 558edc89b24SXin LI * The list, as returned through "alldevsp", may be null if no interfaces 559edc89b24SXin LI * were up and could be opened. 560edc89b24SXin LI */ 561edc89b24SXin LI int 562edc89b24SXin LI pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 563edc89b24SXin LI { 564edc89b24SXin LI size_t i; 565b00ab754SHans Petter Selasky pcap_if_list_t devlist; 566edc89b24SXin LI 567edc89b24SXin LI /* 568ada6f083SXin LI * Find all the local network interfaces on which we 569ada6f083SXin LI * can capture. 570edc89b24SXin LI */ 571b00ab754SHans Petter Selasky devlist.beginning = NULL; 572b00ab754SHans Petter Selasky if (pcap_platform_finddevs(&devlist, errbuf) == -1) { 573b00ab754SHans Petter Selasky /* 574b00ab754SHans Petter Selasky * Failed - free all of the entries we were given 575b00ab754SHans Petter Selasky * before we failed. 576b00ab754SHans Petter Selasky */ 577b00ab754SHans Petter Selasky if (devlist.beginning != NULL) 578b00ab754SHans Petter Selasky pcap_freealldevs(devlist.beginning); 579b00ab754SHans Petter Selasky *alldevsp = NULL; 580edc89b24SXin LI return (-1); 581b00ab754SHans Petter Selasky } 582edc89b24SXin LI 583edc89b24SXin LI /* 584edc89b24SXin LI * Ask each of the non-local-network-interface capture 585edc89b24SXin LI * source types what interfaces they have. 586edc89b24SXin LI */ 587edc89b24SXin LI for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) { 588b00ab754SHans Petter Selasky if (capture_source_types[i].findalldevs_op(&devlist, errbuf) == -1) { 589edc89b24SXin LI /* 590edc89b24SXin LI * We had an error; free the list we've been 591edc89b24SXin LI * constructing. 592edc89b24SXin LI */ 593b00ab754SHans Petter Selasky if (devlist.beginning != NULL) 594b00ab754SHans Petter Selasky pcap_freealldevs(devlist.beginning); 595edc89b24SXin LI *alldevsp = NULL; 596edc89b24SXin LI return (-1); 597edc89b24SXin LI } 598edc89b24SXin LI } 599681ed54cSXin LI 600b00ab754SHans Petter Selasky /* 601b00ab754SHans Petter Selasky * Return the first entry of the list of all devices. 602b00ab754SHans Petter Selasky */ 603b00ab754SHans Petter Selasky *alldevsp = devlist.beginning; 604edc89b24SXin LI return (0); 605edc89b24SXin LI } 606edc89b24SXin LI 607b00ab754SHans Petter Selasky static struct sockaddr * 608b00ab754SHans Petter Selasky dup_sockaddr(struct sockaddr *sa, size_t sa_length) 609b00ab754SHans Petter Selasky { 610b00ab754SHans Petter Selasky struct sockaddr *newsa; 611b00ab754SHans Petter Selasky 612b00ab754SHans Petter Selasky if ((newsa = malloc(sa_length)) == NULL) 613b00ab754SHans Petter Selasky return (NULL); 614b00ab754SHans Petter Selasky return (memcpy(newsa, sa, sa_length)); 615b00ab754SHans Petter Selasky } 616b00ab754SHans Petter Selasky 617b00ab754SHans Petter Selasky /* 618b00ab754SHans Petter Selasky * Construct a "figure of merit" for an interface, for use when sorting 619b00ab754SHans Petter Selasky * the list of interfaces, in which interfaces that are up are superior 620b00ab754SHans Petter Selasky * to interfaces that aren't up, interfaces that are up and running are 621b00ab754SHans Petter Selasky * superior to interfaces that are up but not running, and non-loopback 622b00ab754SHans Petter Selasky * interfaces that are up and running are superior to loopback interfaces, 623b00ab754SHans Petter Selasky * and interfaces with the same flags have a figure of merit that's higher 624b00ab754SHans Petter Selasky * the lower the instance number. 625b00ab754SHans Petter Selasky * 626b00ab754SHans Petter Selasky * The goal is to try to put the interfaces most likely to be useful for 627b00ab754SHans Petter Selasky * capture at the beginning of the list. 628b00ab754SHans Petter Selasky * 629b00ab754SHans Petter Selasky * The figure of merit, which is lower the "better" the interface is, 630b00ab754SHans Petter Selasky * has the uppermost bit set if the interface isn't running, the bit 631b00ab754SHans Petter Selasky * below that set if the interface isn't up, the bit below that set 632b00ab754SHans Petter Selasky * if the interface is a loopback interface, and the interface index 633b00ab754SHans Petter Selasky * in the 29 bits below that. (Yes, we assume u_int is 32 bits.) 634b00ab754SHans Petter Selasky */ 635b00ab754SHans Petter Selasky static u_int 636b00ab754SHans Petter Selasky get_figure_of_merit(pcap_if_t *dev) 637b00ab754SHans Petter Selasky { 638b00ab754SHans Petter Selasky const char *cp; 639b00ab754SHans Petter Selasky u_int n; 640b00ab754SHans Petter Selasky 641b00ab754SHans Petter Selasky if (strcmp(dev->name, "any") == 0) { 642b00ab754SHans Petter Selasky /* 643b00ab754SHans Petter Selasky * Give the "any" device an artificially high instance 644b00ab754SHans Petter Selasky * number, so it shows up after all other non-loopback 645b00ab754SHans Petter Selasky * interfaces. 646b00ab754SHans Petter Selasky */ 647b00ab754SHans Petter Selasky n = 0x1FFFFFFF; /* 29 all-1 bits */ 648b00ab754SHans Petter Selasky } else { 649b00ab754SHans Petter Selasky /* 650b00ab754SHans Petter Selasky * A number at the end of the device name string is 651b00ab754SHans Petter Selasky * assumed to be an instance number. Add 1 to the 652b00ab754SHans Petter Selasky * instance number, and use 0 for "no instance 653b00ab754SHans Petter Selasky * number", so we don't put "no instance number" 654b00ab754SHans Petter Selasky * devices and "instance 0" devices together. 655b00ab754SHans Petter Selasky */ 656b00ab754SHans Petter Selasky cp = dev->name + strlen(dev->name) - 1; 657b00ab754SHans Petter Selasky while (cp-1 >= dev->name && *(cp-1) >= '0' && *(cp-1) <= '9') 658b00ab754SHans Petter Selasky cp--; 659b00ab754SHans Petter Selasky if (*cp >= '0' && *cp <= '9') 660b00ab754SHans Petter Selasky n = atoi(cp) + 1; 661b00ab754SHans Petter Selasky else 662b00ab754SHans Petter Selasky n = 0; 663b00ab754SHans Petter Selasky } 664b00ab754SHans Petter Selasky if (!(dev->flags & PCAP_IF_RUNNING)) 665b00ab754SHans Petter Selasky n |= 0x80000000; 666b00ab754SHans Petter Selasky if (!(dev->flags & PCAP_IF_UP)) 667b00ab754SHans Petter Selasky n |= 0x40000000; 668b00ab754SHans Petter Selasky 669b00ab754SHans Petter Selasky /* 670b00ab754SHans Petter Selasky * Give non-wireless interfaces that aren't disconnected a better 671b00ab754SHans Petter Selasky * figure of merit than interfaces that are disconnected, as 672b00ab754SHans Petter Selasky * "disconnected" should indicate that the interface isn't 673b00ab754SHans Petter Selasky * plugged into a network and thus won't give you any traffic. 674b00ab754SHans Petter Selasky * 675b00ab754SHans Petter Selasky * For wireless interfaces, it means "associated with a network", 676b00ab754SHans Petter Selasky * which we presume not to necessarily prevent capture, as you 677b00ab754SHans Petter Selasky * might run the adapter in some flavor of monitor mode. 678b00ab754SHans Petter Selasky */ 679b00ab754SHans Petter Selasky if (!(dev->flags & PCAP_IF_WIRELESS) && 680b00ab754SHans Petter Selasky (dev->flags & PCAP_IF_CONNECTION_STATUS) == PCAP_IF_CONNECTION_STATUS_DISCONNECTED) 681b00ab754SHans Petter Selasky n |= 0x20000000; 682b00ab754SHans Petter Selasky 683b00ab754SHans Petter Selasky /* 684b00ab754SHans Petter Selasky * Sort loopback devices after non-loopback devices, *except* for 685b00ab754SHans Petter Selasky * disconnected devices. 686b00ab754SHans Petter Selasky */ 687b00ab754SHans Petter Selasky if (dev->flags & PCAP_IF_LOOPBACK) 688b00ab754SHans Petter Selasky n |= 0x10000000; 689b00ab754SHans Petter Selasky 690b00ab754SHans Petter Selasky return (n); 691b00ab754SHans Petter Selasky } 692b00ab754SHans Petter Selasky 693b00ab754SHans Petter Selasky #ifndef _WIN32 694b00ab754SHans Petter Selasky /* 695b00ab754SHans Petter Selasky * Try to get a description for a given device. 696b00ab754SHans Petter Selasky * Returns a mallocated description if it could and NULL if it couldn't. 697b00ab754SHans Petter Selasky * 698b00ab754SHans Petter Selasky * XXX - on FreeBSDs that support it, should it get the sysctl named 699b00ab754SHans Petter Selasky * "dev.{adapter family name}.{adapter unit}.%desc" to get a description 700b00ab754SHans Petter Selasky * of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800" 701b00ab754SHans Petter Selasky * with my Cisco 350 card, so the name isn't entirely descriptive. The 702b00ab754SHans Petter Selasky * "dev.an.0.%pnpinfo" has a better description, although one might argue 703b00ab754SHans Petter Selasky * that the problem is really a driver bug - if it can find out that it's 704b00ab754SHans Petter Selasky * a Cisco 340 or 350, rather than an old Aironet card, it should use 705b00ab754SHans Petter Selasky * that in the description. 706b00ab754SHans Petter Selasky * 707b00ab754SHans Petter Selasky * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD 708b00ab754SHans Petter Selasky * and OpenBSD let you get a description, but it's not generated by the OS, 709b00ab754SHans Petter Selasky * it's set with another ioctl that ifconfig supports; we use that to get 710b00ab754SHans Petter Selasky * a description in FreeBSD and OpenBSD, but if there is no such 711b00ab754SHans Petter Selasky * description available, it still might be nice to get some description 712b00ab754SHans Petter Selasky * string based on the device type or something such as that. 713b00ab754SHans Petter Selasky * 714b00ab754SHans Petter Selasky * In macOS, the System Configuration framework can apparently return 715b00ab754SHans Petter Selasky * names in 10.4 and later. 716b00ab754SHans Petter Selasky * 717b00ab754SHans Petter Selasky * It also appears that freedesktop.org's HAL offers an "info.product" 718b00ab754SHans Petter Selasky * string, but the HAL specification says it "should not be used in any 719b00ab754SHans Petter Selasky * UI" and "subsystem/capability specific properties" should be used 720b00ab754SHans Petter Selasky * instead and, in any case, I think HAL is being deprecated in 721b00ab754SHans Petter Selasky * favor of other stuff such as DeviceKit. DeviceKit doesn't appear 722b00ab754SHans Petter Selasky * to have any obvious product information for devices, but maybe 723b00ab754SHans Petter Selasky * I haven't looked hard enough. 724b00ab754SHans Petter Selasky * 725b00ab754SHans Petter Selasky * Using the System Configuration framework, or HAL, or DeviceKit, or 726b00ab754SHans Petter Selasky * whatever, would require that libpcap applications be linked with 727b00ab754SHans Petter Selasky * the frameworks/libraries in question. That shouldn't be a problem 728b00ab754SHans Petter Selasky * for programs linking with the shared version of libpcap (unless 729b00ab754SHans Petter Selasky * you're running on AIX - which I think is the only UN*X that doesn't 730b00ab754SHans Petter Selasky * support linking a shared library with other libraries on which it 731b00ab754SHans Petter Selasky * depends, and having an executable linked only with the first shared 732b00ab754SHans Petter Selasky * library automatically pick up the other libraries when started - 733b00ab754SHans Petter Selasky * and using HAL or whatever). Programs linked with the static 734b00ab754SHans Petter Selasky * version of libpcap would have to use pcap-config with the --static 735b00ab754SHans Petter Selasky * flag in order to get the right linker flags in order to pick up 736b00ab754SHans Petter Selasky * the additional libraries/frameworks; those programs need that anyway 737b00ab754SHans Petter Selasky * for libpcap 1.1 and beyond on Linux, as, by default, it requires 738b00ab754SHans Petter Selasky * -lnl. 739b00ab754SHans Petter Selasky * 740b00ab754SHans Petter Selasky * Do any other UN*Xes, or desktop environments support getting a 741b00ab754SHans Petter Selasky * description? 742b00ab754SHans Petter Selasky */ 743b00ab754SHans Petter Selasky static char * 744b00ab754SHans Petter Selasky #ifdef SIOCGIFDESCR 745b00ab754SHans Petter Selasky get_if_description(const char *name) 746b00ab754SHans Petter Selasky { 747b00ab754SHans Petter Selasky char *description = NULL; 748b00ab754SHans Petter Selasky int s; 749b00ab754SHans Petter Selasky struct ifreq ifrdesc; 750b00ab754SHans Petter Selasky #ifndef IFDESCRSIZE 751b00ab754SHans Petter Selasky size_t descrlen = 64; 752b00ab754SHans Petter Selasky #else 753b00ab754SHans Petter Selasky size_t descrlen = IFDESCRSIZE; 754b00ab754SHans Petter Selasky #endif /* IFDESCRSIZE */ 755b00ab754SHans Petter Selasky 756b00ab754SHans Petter Selasky /* 757b00ab754SHans Petter Selasky * Get the description for the interface. 758b00ab754SHans Petter Selasky */ 759b00ab754SHans Petter Selasky memset(&ifrdesc, 0, sizeof ifrdesc); 760*57e22627SCy Schubert pcap_strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name); 761b00ab754SHans Petter Selasky s = socket(AF_INET, SOCK_DGRAM, 0); 762b00ab754SHans Petter Selasky if (s >= 0) { 763b00ab754SHans Petter Selasky #ifdef __FreeBSD__ 764b00ab754SHans Petter Selasky /* 765b00ab754SHans Petter Selasky * On FreeBSD, if the buffer isn't big enough for the 766b00ab754SHans Petter Selasky * description, the ioctl succeeds, but the description 767b00ab754SHans Petter Selasky * isn't copied, ifr_buffer.length is set to the description 768b00ab754SHans Petter Selasky * length, and ifr_buffer.buffer is set to NULL. 769b00ab754SHans Petter Selasky */ 770b00ab754SHans Petter Selasky for (;;) { 771b00ab754SHans Petter Selasky free(description); 772b00ab754SHans Petter Selasky if ((description = malloc(descrlen)) != NULL) { 773b00ab754SHans Petter Selasky ifrdesc.ifr_buffer.buffer = description; 774b00ab754SHans Petter Selasky ifrdesc.ifr_buffer.length = descrlen; 775b00ab754SHans Petter Selasky if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) { 776b00ab754SHans Petter Selasky if (ifrdesc.ifr_buffer.buffer == 777b00ab754SHans Petter Selasky description) 778b00ab754SHans Petter Selasky break; 779b00ab754SHans Petter Selasky else 780b00ab754SHans Petter Selasky descrlen = ifrdesc.ifr_buffer.length; 781b00ab754SHans Petter Selasky } else { 782b00ab754SHans Petter Selasky /* 783b00ab754SHans Petter Selasky * Failed to get interface description. 784b00ab754SHans Petter Selasky */ 785b00ab754SHans Petter Selasky free(description); 786b00ab754SHans Petter Selasky description = NULL; 787b00ab754SHans Petter Selasky break; 788b00ab754SHans Petter Selasky } 789b00ab754SHans Petter Selasky } else 790b00ab754SHans Petter Selasky break; 791b00ab754SHans Petter Selasky } 792b00ab754SHans Petter Selasky #else /* __FreeBSD__ */ 793b00ab754SHans Petter Selasky /* 794b00ab754SHans Petter Selasky * The only other OS that currently supports 795b00ab754SHans Petter Selasky * SIOCGIFDESCR is OpenBSD, and it has no way 796b00ab754SHans Petter Selasky * to get the description length - it's clamped 797b00ab754SHans Petter Selasky * to a maximum of IFDESCRSIZE. 798b00ab754SHans Petter Selasky */ 799b00ab754SHans Petter Selasky if ((description = malloc(descrlen)) != NULL) { 800b00ab754SHans Petter Selasky ifrdesc.ifr_data = (caddr_t)description; 801b00ab754SHans Petter Selasky if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) { 802b00ab754SHans Petter Selasky /* 803b00ab754SHans Petter Selasky * Failed to get interface description. 804b00ab754SHans Petter Selasky */ 805b00ab754SHans Petter Selasky free(description); 806b00ab754SHans Petter Selasky description = NULL; 807b00ab754SHans Petter Selasky } 808b00ab754SHans Petter Selasky } 809b00ab754SHans Petter Selasky #endif /* __FreeBSD__ */ 810b00ab754SHans Petter Selasky close(s); 811*57e22627SCy Schubert if (description != NULL && description[0] == '\0') { 812b00ab754SHans Petter Selasky /* 813b00ab754SHans Petter Selasky * Description is empty, so discard it. 814b00ab754SHans Petter Selasky */ 815b00ab754SHans Petter Selasky free(description); 816b00ab754SHans Petter Selasky description = NULL; 817b00ab754SHans Petter Selasky } 818b00ab754SHans Petter Selasky } 819b00ab754SHans Petter Selasky 820b00ab754SHans Petter Selasky #ifdef __FreeBSD__ 821b00ab754SHans Petter Selasky /* 822b00ab754SHans Petter Selasky * For FreeBSD, if we didn't get a description, and this is 823b00ab754SHans Petter Selasky * a device with a name of the form usbusN, label it as a USB 824b00ab754SHans Petter Selasky * bus. 825b00ab754SHans Petter Selasky */ 826b00ab754SHans Petter Selasky if (description == NULL) { 827b00ab754SHans Petter Selasky if (strncmp(name, "usbus", 5) == 0) { 828b00ab754SHans Petter Selasky /* 829b00ab754SHans Petter Selasky * OK, it begins with "usbus". 830b00ab754SHans Petter Selasky */ 831b00ab754SHans Petter Selasky long busnum; 832b00ab754SHans Petter Selasky char *p; 833b00ab754SHans Petter Selasky 834b00ab754SHans Petter Selasky errno = 0; 835b00ab754SHans Petter Selasky busnum = strtol(name + 5, &p, 10); 836b00ab754SHans Petter Selasky if (errno == 0 && p != name + 5 && *p == '\0' && 837b00ab754SHans Petter Selasky busnum >= 0 && busnum <= INT_MAX) { 838b00ab754SHans Petter Selasky /* 839b00ab754SHans Petter Selasky * OK, it's a valid number that's not 840b00ab754SHans Petter Selasky * bigger than INT_MAX. Construct 841b00ab754SHans Petter Selasky * a description from it. 842*57e22627SCy Schubert * (If that fails, we don't worry about 843*57e22627SCy Schubert * it, we just return NULL.) 844b00ab754SHans Petter Selasky */ 845*57e22627SCy Schubert if (pcap_asprintf(&description, 846*57e22627SCy Schubert "USB bus number %ld", busnum) == -1) { 847*57e22627SCy Schubert /* Failed. */ 848*57e22627SCy Schubert description = NULL; 849b00ab754SHans Petter Selasky } 850b00ab754SHans Petter Selasky } 851b00ab754SHans Petter Selasky } 852b00ab754SHans Petter Selasky } 853b00ab754SHans Petter Selasky #endif 854b00ab754SHans Petter Selasky return (description); 855b00ab754SHans Petter Selasky #else /* SIOCGIFDESCR */ 856b00ab754SHans Petter Selasky get_if_description(const char *name _U_) 857b00ab754SHans Petter Selasky { 858b00ab754SHans Petter Selasky return (NULL); 859b00ab754SHans Petter Selasky #endif /* SIOCGIFDESCR */ 860b00ab754SHans Petter Selasky } 861b00ab754SHans Petter Selasky 862b00ab754SHans Petter Selasky /* 863b00ab754SHans Petter Selasky * Look for a given device in the specified list of devices. 864b00ab754SHans Petter Selasky * 865b00ab754SHans Petter Selasky * If we find it, return a pointer to its entry. 866b00ab754SHans Petter Selasky * 867b00ab754SHans Petter Selasky * If we don't find it, attempt to add an entry for it, with the specified 868b00ab754SHans Petter Selasky * IFF_ flags and description, and, if that succeeds, return a pointer to 869b00ab754SHans Petter Selasky * the new entry, otherwise return NULL and set errbuf to an error message. 870b00ab754SHans Petter Selasky */ 871b00ab754SHans Petter Selasky pcap_if_t * 872b00ab754SHans Petter Selasky find_or_add_if(pcap_if_list_t *devlistp, const char *name, 873b00ab754SHans Petter Selasky bpf_u_int32 if_flags, get_if_flags_func get_flags_func, char *errbuf) 874b00ab754SHans Petter Selasky { 875b00ab754SHans Petter Selasky bpf_u_int32 pcap_flags; 876b00ab754SHans Petter Selasky 877b00ab754SHans Petter Selasky /* 878b00ab754SHans Petter Selasky * Convert IFF_ flags to pcap flags. 879b00ab754SHans Petter Selasky */ 880b00ab754SHans Petter Selasky pcap_flags = 0; 881b00ab754SHans Petter Selasky #ifdef IFF_LOOPBACK 882b00ab754SHans Petter Selasky if (if_flags & IFF_LOOPBACK) 883b00ab754SHans Petter Selasky pcap_flags |= PCAP_IF_LOOPBACK; 884b00ab754SHans Petter Selasky #else 885b00ab754SHans Petter Selasky /* 886b00ab754SHans Petter Selasky * We don't have IFF_LOOPBACK, so look at the device name to 887b00ab754SHans Petter Selasky * see if it looks like a loopback device. 888b00ab754SHans Petter Selasky */ 889b00ab754SHans Petter Selasky if (name[0] == 'l' && name[1] == 'o' && 890b00ab754SHans Petter Selasky (isdigit((unsigned char)(name[2])) || name[2] == '\0') 891b00ab754SHans Petter Selasky pcap_flags |= PCAP_IF_LOOPBACK; 892b00ab754SHans Petter Selasky #endif 893b00ab754SHans Petter Selasky #ifdef IFF_UP 894b00ab754SHans Petter Selasky if (if_flags & IFF_UP) 895b00ab754SHans Petter Selasky pcap_flags |= PCAP_IF_UP; 896b00ab754SHans Petter Selasky #endif 897b00ab754SHans Petter Selasky #ifdef IFF_RUNNING 898b00ab754SHans Petter Selasky if (if_flags & IFF_RUNNING) 899b00ab754SHans Petter Selasky pcap_flags |= PCAP_IF_RUNNING; 900b00ab754SHans Petter Selasky #endif 901b00ab754SHans Petter Selasky 902b00ab754SHans Petter Selasky /* 903b00ab754SHans Petter Selasky * Attempt to find an entry for this device; if we don't find one, 904b00ab754SHans Petter Selasky * attempt to add one. 905b00ab754SHans Petter Selasky */ 906b00ab754SHans Petter Selasky return (find_or_add_dev(devlistp, name, pcap_flags, 907b00ab754SHans Petter Selasky get_flags_func, get_if_description(name), errbuf)); 908b00ab754SHans Petter Selasky } 909b00ab754SHans Petter Selasky 910b00ab754SHans Petter Selasky /* 911b00ab754SHans Petter Selasky * Look for a given device in the specified list of devices. 912b00ab754SHans Petter Selasky * 913b00ab754SHans Petter Selasky * If we find it, then, if the specified address isn't null, add it to 914b00ab754SHans Petter Selasky * the list of addresses for the device and return 0. 915b00ab754SHans Petter Selasky * 916b00ab754SHans Petter Selasky * If we don't find it, attempt to add an entry for it, with the specified 917b00ab754SHans Petter Selasky * IFF_ flags and description, and, if that succeeds, add the specified 918b00ab754SHans Petter Selasky * address to its list of addresses if that address is non-null, and 919b00ab754SHans Petter Selasky * return 0, otherwise return -1 and set errbuf to an error message. 920b00ab754SHans Petter Selasky * 921b00ab754SHans Petter Selasky * (We can get called with a null address because we might get a list 922b00ab754SHans Petter Selasky * of interface name/address combinations from the underlying OS, with 923b00ab754SHans Petter Selasky * the address being absent in some cases, rather than a list of 924b00ab754SHans Petter Selasky * interfaces with each interface having a list of addresses, so this 925b00ab754SHans Petter Selasky * call may be the only call made to add to the list, and we want to 926b00ab754SHans Petter Selasky * add interfaces even if they have no addresses.) 927b00ab754SHans Petter Selasky */ 928b00ab754SHans Petter Selasky int 929b00ab754SHans Petter Selasky add_addr_to_if(pcap_if_list_t *devlistp, const char *name, 930b00ab754SHans Petter Selasky bpf_u_int32 if_flags, get_if_flags_func get_flags_func, 931b00ab754SHans Petter Selasky struct sockaddr *addr, size_t addr_size, 932b00ab754SHans Petter Selasky struct sockaddr *netmask, size_t netmask_size, 933b00ab754SHans Petter Selasky struct sockaddr *broadaddr, size_t broadaddr_size, 934b00ab754SHans Petter Selasky struct sockaddr *dstaddr, size_t dstaddr_size, 935b00ab754SHans Petter Selasky char *errbuf) 936b00ab754SHans Petter Selasky { 937b00ab754SHans Petter Selasky pcap_if_t *curdev; 938b00ab754SHans Petter Selasky 939b00ab754SHans Petter Selasky /* 940b00ab754SHans Petter Selasky * Check whether the device exists and, if not, add it. 941b00ab754SHans Petter Selasky */ 942b00ab754SHans Petter Selasky curdev = find_or_add_if(devlistp, name, if_flags, get_flags_func, 943b00ab754SHans Petter Selasky errbuf); 944b00ab754SHans Petter Selasky if (curdev == NULL) { 945b00ab754SHans Petter Selasky /* 946b00ab754SHans Petter Selasky * Error - give up. 947b00ab754SHans Petter Selasky */ 948b00ab754SHans Petter Selasky return (-1); 949b00ab754SHans Petter Selasky } 950b00ab754SHans Petter Selasky 951b00ab754SHans Petter Selasky if (addr == NULL) { 952b00ab754SHans Petter Selasky /* 953b00ab754SHans Petter Selasky * There's no address to add; this entry just meant 954b00ab754SHans Petter Selasky * "here's a new interface". 955b00ab754SHans Petter Selasky */ 956b00ab754SHans Petter Selasky return (0); 957b00ab754SHans Petter Selasky } 958b00ab754SHans Petter Selasky 959b00ab754SHans Petter Selasky /* 960b00ab754SHans Petter Selasky * "curdev" is an entry for this interface, and we have an 961b00ab754SHans Petter Selasky * address for it; add an entry for that address to the 962b00ab754SHans Petter Selasky * interface's list of addresses. 963b00ab754SHans Petter Selasky */ 964b00ab754SHans Petter Selasky return (add_addr_to_dev(curdev, addr, addr_size, netmask, 965b00ab754SHans Petter Selasky netmask_size, broadaddr, broadaddr_size, dstaddr, 966b00ab754SHans Petter Selasky dstaddr_size, errbuf)); 967b00ab754SHans Petter Selasky } 968b00ab754SHans Petter Selasky #endif /* _WIN32 */ 969b00ab754SHans Petter Selasky 970b00ab754SHans Petter Selasky /* 971b00ab754SHans Petter Selasky * Add an entry to the list of addresses for an interface. 972b00ab754SHans Petter Selasky * "curdev" is the entry for that interface. 973b00ab754SHans Petter Selasky */ 974b00ab754SHans Petter Selasky int 975b00ab754SHans Petter Selasky add_addr_to_dev(pcap_if_t *curdev, 976b00ab754SHans Petter Selasky struct sockaddr *addr, size_t addr_size, 977b00ab754SHans Petter Selasky struct sockaddr *netmask, size_t netmask_size, 978b00ab754SHans Petter Selasky struct sockaddr *broadaddr, size_t broadaddr_size, 979b00ab754SHans Petter Selasky struct sockaddr *dstaddr, size_t dstaddr_size, 980b00ab754SHans Petter Selasky char *errbuf) 981b00ab754SHans Petter Selasky { 982b00ab754SHans Petter Selasky pcap_addr_t *curaddr, *prevaddr, *nextaddr; 983b00ab754SHans Petter Selasky 984b00ab754SHans Petter Selasky /* 985b00ab754SHans Petter Selasky * Allocate the new entry and fill it in. 986b00ab754SHans Petter Selasky */ 987b00ab754SHans Petter Selasky curaddr = (pcap_addr_t *)malloc(sizeof(pcap_addr_t)); 988b00ab754SHans Petter Selasky if (curaddr == NULL) { 989b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 990b00ab754SHans Petter Selasky errno, "malloc"); 991b00ab754SHans Petter Selasky return (-1); 992b00ab754SHans Petter Selasky } 993b00ab754SHans Petter Selasky 994b00ab754SHans Petter Selasky curaddr->next = NULL; 995b00ab754SHans Petter Selasky if (addr != NULL && addr_size != 0) { 996b00ab754SHans Petter Selasky curaddr->addr = (struct sockaddr *)dup_sockaddr(addr, addr_size); 997b00ab754SHans Petter Selasky if (curaddr->addr == NULL) { 998b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 999b00ab754SHans Petter Selasky errno, "malloc"); 1000b00ab754SHans Petter Selasky free(curaddr); 1001b00ab754SHans Petter Selasky return (-1); 1002b00ab754SHans Petter Selasky } 1003b00ab754SHans Petter Selasky } else 1004b00ab754SHans Petter Selasky curaddr->addr = NULL; 1005b00ab754SHans Petter Selasky 1006b00ab754SHans Petter Selasky if (netmask != NULL && netmask_size != 0) { 1007b00ab754SHans Petter Selasky curaddr->netmask = (struct sockaddr *)dup_sockaddr(netmask, netmask_size); 1008b00ab754SHans Petter Selasky if (curaddr->netmask == NULL) { 1009b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1010b00ab754SHans Petter Selasky errno, "malloc"); 1011b00ab754SHans Petter Selasky if (curaddr->addr != NULL) 1012b00ab754SHans Petter Selasky free(curaddr->addr); 1013b00ab754SHans Petter Selasky free(curaddr); 1014b00ab754SHans Petter Selasky return (-1); 1015b00ab754SHans Petter Selasky } 1016b00ab754SHans Petter Selasky } else 1017b00ab754SHans Petter Selasky curaddr->netmask = NULL; 1018b00ab754SHans Petter Selasky 1019b00ab754SHans Petter Selasky if (broadaddr != NULL && broadaddr_size != 0) { 1020b00ab754SHans Petter Selasky curaddr->broadaddr = (struct sockaddr *)dup_sockaddr(broadaddr, broadaddr_size); 1021b00ab754SHans Petter Selasky if (curaddr->broadaddr == NULL) { 1022b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1023b00ab754SHans Petter Selasky errno, "malloc"); 1024b00ab754SHans Petter Selasky if (curaddr->netmask != NULL) 1025b00ab754SHans Petter Selasky free(curaddr->netmask); 1026b00ab754SHans Petter Selasky if (curaddr->addr != NULL) 1027b00ab754SHans Petter Selasky free(curaddr->addr); 1028b00ab754SHans Petter Selasky free(curaddr); 1029b00ab754SHans Petter Selasky return (-1); 1030b00ab754SHans Petter Selasky } 1031b00ab754SHans Petter Selasky } else 1032b00ab754SHans Petter Selasky curaddr->broadaddr = NULL; 1033b00ab754SHans Petter Selasky 1034b00ab754SHans Petter Selasky if (dstaddr != NULL && dstaddr_size != 0) { 1035b00ab754SHans Petter Selasky curaddr->dstaddr = (struct sockaddr *)dup_sockaddr(dstaddr, dstaddr_size); 1036b00ab754SHans Petter Selasky if (curaddr->dstaddr == NULL) { 1037b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1038b00ab754SHans Petter Selasky errno, "malloc"); 1039b00ab754SHans Petter Selasky if (curaddr->broadaddr != NULL) 1040b00ab754SHans Petter Selasky free(curaddr->broadaddr); 1041b00ab754SHans Petter Selasky if (curaddr->netmask != NULL) 1042b00ab754SHans Petter Selasky free(curaddr->netmask); 1043b00ab754SHans Petter Selasky if (curaddr->addr != NULL) 1044b00ab754SHans Petter Selasky free(curaddr->addr); 1045b00ab754SHans Petter Selasky free(curaddr); 1046b00ab754SHans Petter Selasky return (-1); 1047b00ab754SHans Petter Selasky } 1048b00ab754SHans Petter Selasky } else 1049b00ab754SHans Petter Selasky curaddr->dstaddr = NULL; 1050b00ab754SHans Petter Selasky 1051b00ab754SHans Petter Selasky /* 1052b00ab754SHans Petter Selasky * Find the end of the list of addresses. 1053b00ab754SHans Petter Selasky */ 1054b00ab754SHans Petter Selasky for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { 1055b00ab754SHans Petter Selasky nextaddr = prevaddr->next; 1056b00ab754SHans Petter Selasky if (nextaddr == NULL) { 1057b00ab754SHans Petter Selasky /* 1058b00ab754SHans Petter Selasky * This is the end of the list. 1059b00ab754SHans Petter Selasky */ 1060b00ab754SHans Petter Selasky break; 1061b00ab754SHans Petter Selasky } 1062b00ab754SHans Petter Selasky } 1063b00ab754SHans Petter Selasky 1064b00ab754SHans Petter Selasky if (prevaddr == NULL) { 1065b00ab754SHans Petter Selasky /* 1066b00ab754SHans Petter Selasky * The list was empty; this is the first member. 1067b00ab754SHans Petter Selasky */ 1068b00ab754SHans Petter Selasky curdev->addresses = curaddr; 1069b00ab754SHans Petter Selasky } else { 1070b00ab754SHans Petter Selasky /* 1071b00ab754SHans Petter Selasky * "prevaddr" is the last member of the list; append 1072b00ab754SHans Petter Selasky * this member to it. 1073b00ab754SHans Petter Selasky */ 1074b00ab754SHans Petter Selasky prevaddr->next = curaddr; 1075b00ab754SHans Petter Selasky } 1076b00ab754SHans Petter Selasky 1077b00ab754SHans Petter Selasky return (0); 1078b00ab754SHans Petter Selasky } 1079b00ab754SHans Petter Selasky 1080b00ab754SHans Petter Selasky /* 1081b00ab754SHans Petter Selasky * Look for a given device in the specified list of devices. 1082b00ab754SHans Petter Selasky * 1083b00ab754SHans Petter Selasky * If we find it, return 0 and set *curdev_ret to point to it. 1084b00ab754SHans Petter Selasky * 1085b00ab754SHans Petter Selasky * If we don't find it, attempt to add an entry for it, with the specified 1086b00ab754SHans Petter Selasky * flags and description, and, if that succeeds, return 0, otherwise 1087b00ab754SHans Petter Selasky * return -1 and set errbuf to an error message. 1088b00ab754SHans Petter Selasky */ 1089b00ab754SHans Petter Selasky pcap_if_t * 1090b00ab754SHans Petter Selasky find_or_add_dev(pcap_if_list_t *devlistp, const char *name, bpf_u_int32 flags, 1091b00ab754SHans Petter Selasky get_if_flags_func get_flags_func, const char *description, char *errbuf) 1092b00ab754SHans Petter Selasky { 1093b00ab754SHans Petter Selasky pcap_if_t *curdev; 1094b00ab754SHans Petter Selasky 1095b00ab754SHans Petter Selasky /* 1096b00ab754SHans Petter Selasky * Is there already an entry in the list for this device? 1097b00ab754SHans Petter Selasky */ 1098b00ab754SHans Petter Selasky curdev = find_dev(devlistp, name); 1099b00ab754SHans Petter Selasky if (curdev != NULL) { 1100b00ab754SHans Petter Selasky /* 1101b00ab754SHans Petter Selasky * Yes, return it. 1102b00ab754SHans Petter Selasky */ 1103b00ab754SHans Petter Selasky return (curdev); 1104b00ab754SHans Petter Selasky } 1105b00ab754SHans Petter Selasky 1106b00ab754SHans Petter Selasky /* 1107b00ab754SHans Petter Selasky * No, we didn't find it. 1108b00ab754SHans Petter Selasky */ 1109b00ab754SHans Petter Selasky 1110b00ab754SHans Petter Selasky /* 1111b00ab754SHans Petter Selasky * Try to get additional flags for the device. 1112b00ab754SHans Petter Selasky */ 1113b00ab754SHans Petter Selasky if ((*get_flags_func)(name, &flags, errbuf) == -1) { 1114b00ab754SHans Petter Selasky /* 1115b00ab754SHans Petter Selasky * Failed. 1116b00ab754SHans Petter Selasky */ 1117b00ab754SHans Petter Selasky return (NULL); 1118b00ab754SHans Petter Selasky } 1119b00ab754SHans Petter Selasky 1120b00ab754SHans Petter Selasky /* 1121b00ab754SHans Petter Selasky * Now, try to add it to the list of devices. 1122b00ab754SHans Petter Selasky */ 1123b00ab754SHans Petter Selasky return (add_dev(devlistp, name, flags, description, errbuf)); 1124b00ab754SHans Petter Selasky } 1125b00ab754SHans Petter Selasky 1126b00ab754SHans Petter Selasky /* 1127b00ab754SHans Petter Selasky * Look for a given device in the specified list of devices, and return 1128b00ab754SHans Petter Selasky * the entry for it if we find it or NULL if we don't. 1129b00ab754SHans Petter Selasky */ 1130b00ab754SHans Petter Selasky pcap_if_t * 1131b00ab754SHans Petter Selasky find_dev(pcap_if_list_t *devlistp, const char *name) 1132b00ab754SHans Petter Selasky { 1133b00ab754SHans Petter Selasky pcap_if_t *curdev; 1134b00ab754SHans Petter Selasky 1135b00ab754SHans Petter Selasky /* 1136b00ab754SHans Petter Selasky * Is there an entry in the list for this device? 1137b00ab754SHans Petter Selasky */ 1138b00ab754SHans Petter Selasky for (curdev = devlistp->beginning; curdev != NULL; 1139b00ab754SHans Petter Selasky curdev = curdev->next) { 1140b00ab754SHans Petter Selasky if (strcmp(name, curdev->name) == 0) { 1141b00ab754SHans Petter Selasky /* 1142b00ab754SHans Petter Selasky * We found it, so, yes, there is. No need to 1143b00ab754SHans Petter Selasky * add it. Provide the entry we found to our 1144b00ab754SHans Petter Selasky * caller. 1145b00ab754SHans Petter Selasky */ 1146b00ab754SHans Petter Selasky return (curdev); 1147b00ab754SHans Petter Selasky } 1148b00ab754SHans Petter Selasky } 1149b00ab754SHans Petter Selasky 1150b00ab754SHans Petter Selasky /* 1151b00ab754SHans Petter Selasky * No. 1152b00ab754SHans Petter Selasky */ 1153b00ab754SHans Petter Selasky return (NULL); 1154b00ab754SHans Petter Selasky } 1155b00ab754SHans Petter Selasky 1156b00ab754SHans Petter Selasky /* 1157b00ab754SHans Petter Selasky * Attempt to add an entry for a device, with the specified flags 1158b00ab754SHans Petter Selasky * and description, and, if that succeeds, return 0 and return a pointer 1159b00ab754SHans Petter Selasky * to the new entry, otherwise return NULL and set errbuf to an error 1160b00ab754SHans Petter Selasky * message. 1161b00ab754SHans Petter Selasky * 1162b00ab754SHans Petter Selasky * If we weren't given a description, try to get one. 1163b00ab754SHans Petter Selasky */ 1164b00ab754SHans Petter Selasky pcap_if_t * 1165b00ab754SHans Petter Selasky add_dev(pcap_if_list_t *devlistp, const char *name, bpf_u_int32 flags, 1166b00ab754SHans Petter Selasky const char *description, char *errbuf) 1167b00ab754SHans Petter Selasky { 1168b00ab754SHans Petter Selasky pcap_if_t *curdev, *prevdev, *nextdev; 1169b00ab754SHans Petter Selasky u_int this_figure_of_merit, nextdev_figure_of_merit; 1170b00ab754SHans Petter Selasky 1171b00ab754SHans Petter Selasky curdev = malloc(sizeof(pcap_if_t)); 1172b00ab754SHans Petter Selasky if (curdev == NULL) { 1173b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1174b00ab754SHans Petter Selasky errno, "malloc"); 1175b00ab754SHans Petter Selasky return (NULL); 1176b00ab754SHans Petter Selasky } 1177b00ab754SHans Petter Selasky 1178b00ab754SHans Petter Selasky /* 1179b00ab754SHans Petter Selasky * Fill in the entry. 1180b00ab754SHans Petter Selasky */ 1181b00ab754SHans Petter Selasky curdev->next = NULL; 1182b00ab754SHans Petter Selasky curdev->name = strdup(name); 1183b00ab754SHans Petter Selasky if (curdev->name == NULL) { 1184b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1185b00ab754SHans Petter Selasky errno, "malloc"); 1186b00ab754SHans Petter Selasky free(curdev); 1187b00ab754SHans Petter Selasky return (NULL); 1188b00ab754SHans Petter Selasky } 1189b00ab754SHans Petter Selasky if (description == NULL) { 1190b00ab754SHans Petter Selasky /* 1191b00ab754SHans Petter Selasky * We weren't handed a description for the interface. 1192b00ab754SHans Petter Selasky */ 1193b00ab754SHans Petter Selasky curdev->description = NULL; 1194b00ab754SHans Petter Selasky } else { 1195b00ab754SHans Petter Selasky /* 1196b00ab754SHans Petter Selasky * We were handed a description; make a copy. 1197b00ab754SHans Petter Selasky */ 1198b00ab754SHans Petter Selasky curdev->description = strdup(description); 1199b00ab754SHans Petter Selasky if (curdev->description == NULL) { 1200b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1201b00ab754SHans Petter Selasky errno, "malloc"); 1202b00ab754SHans Petter Selasky free(curdev->name); 1203b00ab754SHans Petter Selasky free(curdev); 1204b00ab754SHans Petter Selasky return (NULL); 1205b00ab754SHans Petter Selasky } 1206b00ab754SHans Petter Selasky } 1207b00ab754SHans Petter Selasky curdev->addresses = NULL; /* list starts out as empty */ 1208b00ab754SHans Petter Selasky curdev->flags = flags; 1209b00ab754SHans Petter Selasky 1210b00ab754SHans Petter Selasky /* 1211b00ab754SHans Petter Selasky * Add it to the list, in the appropriate location. 1212b00ab754SHans Petter Selasky * First, get the "figure of merit" for this interface. 1213b00ab754SHans Petter Selasky */ 1214b00ab754SHans Petter Selasky this_figure_of_merit = get_figure_of_merit(curdev); 1215b00ab754SHans Petter Selasky 1216b00ab754SHans Petter Selasky /* 1217b00ab754SHans Petter Selasky * Now look for the last interface with an figure of merit 1218b00ab754SHans Petter Selasky * less than or equal to the new interface's figure of merit. 1219b00ab754SHans Petter Selasky * 1220b00ab754SHans Petter Selasky * We start with "prevdev" being NULL, meaning we're before 1221b00ab754SHans Petter Selasky * the first element in the list. 1222b00ab754SHans Petter Selasky */ 1223b00ab754SHans Petter Selasky prevdev = NULL; 1224b00ab754SHans Petter Selasky for (;;) { 1225b00ab754SHans Petter Selasky /* 1226b00ab754SHans Petter Selasky * Get the interface after this one. 1227b00ab754SHans Petter Selasky */ 1228b00ab754SHans Petter Selasky if (prevdev == NULL) { 1229b00ab754SHans Petter Selasky /* 1230b00ab754SHans Petter Selasky * The next element is the first element. 1231b00ab754SHans Petter Selasky */ 1232b00ab754SHans Petter Selasky nextdev = devlistp->beginning; 1233b00ab754SHans Petter Selasky } else 1234b00ab754SHans Petter Selasky nextdev = prevdev->next; 1235b00ab754SHans Petter Selasky 1236b00ab754SHans Petter Selasky /* 1237b00ab754SHans Petter Selasky * Are we at the end of the list? 1238b00ab754SHans Petter Selasky */ 1239b00ab754SHans Petter Selasky if (nextdev == NULL) { 1240b00ab754SHans Petter Selasky /* 1241b00ab754SHans Petter Selasky * Yes - we have to put the new entry after "prevdev". 1242b00ab754SHans Petter Selasky */ 1243b00ab754SHans Petter Selasky break; 1244b00ab754SHans Petter Selasky } 1245b00ab754SHans Petter Selasky 1246b00ab754SHans Petter Selasky /* 1247b00ab754SHans Petter Selasky * Is the new interface's figure of merit less 1248b00ab754SHans Petter Selasky * than the next interface's figure of merit, 1249b00ab754SHans Petter Selasky * meaning that the new interface is better 1250b00ab754SHans Petter Selasky * than the next interface? 1251b00ab754SHans Petter Selasky */ 1252b00ab754SHans Petter Selasky nextdev_figure_of_merit = get_figure_of_merit(nextdev); 1253b00ab754SHans Petter Selasky if (this_figure_of_merit < nextdev_figure_of_merit) { 1254b00ab754SHans Petter Selasky /* 1255b00ab754SHans Petter Selasky * Yes - we should put the new entry 1256b00ab754SHans Petter Selasky * before "nextdev", i.e. after "prevdev". 1257b00ab754SHans Petter Selasky */ 1258b00ab754SHans Petter Selasky break; 1259b00ab754SHans Petter Selasky } 1260b00ab754SHans Petter Selasky 1261b00ab754SHans Petter Selasky prevdev = nextdev; 1262b00ab754SHans Petter Selasky } 1263b00ab754SHans Petter Selasky 1264b00ab754SHans Petter Selasky /* 1265b00ab754SHans Petter Selasky * Insert before "nextdev". 1266b00ab754SHans Petter Selasky */ 1267b00ab754SHans Petter Selasky curdev->next = nextdev; 1268b00ab754SHans Petter Selasky 1269b00ab754SHans Petter Selasky /* 1270b00ab754SHans Petter Selasky * Insert after "prevdev" - unless "prevdev" is null, 1271b00ab754SHans Petter Selasky * in which case this is the first interface. 1272b00ab754SHans Petter Selasky */ 1273b00ab754SHans Petter Selasky if (prevdev == NULL) { 1274b00ab754SHans Petter Selasky /* 1275b00ab754SHans Petter Selasky * This is the first interface. Make it 1276b00ab754SHans Petter Selasky * the first element in the list of devices. 1277b00ab754SHans Petter Selasky */ 1278b00ab754SHans Petter Selasky devlistp->beginning = curdev; 1279b00ab754SHans Petter Selasky } else 1280b00ab754SHans Petter Selasky prevdev->next = curdev; 1281b00ab754SHans Petter Selasky return (curdev); 1282b00ab754SHans Petter Selasky } 1283b00ab754SHans Petter Selasky 1284b00ab754SHans Petter Selasky /* 1285b00ab754SHans Petter Selasky * Free a list of interfaces. 1286b00ab754SHans Petter Selasky */ 1287b00ab754SHans Petter Selasky void 1288b00ab754SHans Petter Selasky pcap_freealldevs(pcap_if_t *alldevs) 1289b00ab754SHans Petter Selasky { 1290b00ab754SHans Petter Selasky pcap_if_t *curdev, *nextdev; 1291b00ab754SHans Petter Selasky pcap_addr_t *curaddr, *nextaddr; 1292b00ab754SHans Petter Selasky 1293b00ab754SHans Petter Selasky for (curdev = alldevs; curdev != NULL; curdev = nextdev) { 1294b00ab754SHans Petter Selasky nextdev = curdev->next; 1295b00ab754SHans Petter Selasky 1296b00ab754SHans Petter Selasky /* 1297b00ab754SHans Petter Selasky * Free all addresses. 1298b00ab754SHans Petter Selasky */ 1299b00ab754SHans Petter Selasky for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) { 1300b00ab754SHans Petter Selasky nextaddr = curaddr->next; 1301b00ab754SHans Petter Selasky if (curaddr->addr) 1302b00ab754SHans Petter Selasky free(curaddr->addr); 1303b00ab754SHans Petter Selasky if (curaddr->netmask) 1304b00ab754SHans Petter Selasky free(curaddr->netmask); 1305b00ab754SHans Petter Selasky if (curaddr->broadaddr) 1306b00ab754SHans Petter Selasky free(curaddr->broadaddr); 1307b00ab754SHans Petter Selasky if (curaddr->dstaddr) 1308b00ab754SHans Petter Selasky free(curaddr->dstaddr); 1309b00ab754SHans Petter Selasky free(curaddr); 1310b00ab754SHans Petter Selasky } 1311b00ab754SHans Petter Selasky 1312b00ab754SHans Petter Selasky /* 1313b00ab754SHans Petter Selasky * Free the name string. 1314b00ab754SHans Petter Selasky */ 1315b00ab754SHans Petter Selasky free(curdev->name); 1316b00ab754SHans Petter Selasky 1317b00ab754SHans Petter Selasky /* 1318b00ab754SHans Petter Selasky * Free the description string, if any. 1319b00ab754SHans Petter Selasky */ 1320b00ab754SHans Petter Selasky if (curdev->description != NULL) 1321b00ab754SHans Petter Selasky free(curdev->description); 1322b00ab754SHans Petter Selasky 1323b00ab754SHans Petter Selasky /* 1324b00ab754SHans Petter Selasky * Free the interface. 1325b00ab754SHans Petter Selasky */ 1326b00ab754SHans Petter Selasky free(curdev); 1327b00ab754SHans Petter Selasky } 1328b00ab754SHans Petter Selasky } 1329b00ab754SHans Petter Selasky 1330b00ab754SHans Petter Selasky /* 1331b00ab754SHans Petter Selasky * pcap-npf.c has its own pcap_lookupdev(), for compatibility reasons, as 1332b00ab754SHans Petter Selasky * it actually returns the names of all interfaces, with a NUL separator 1333b00ab754SHans Petter Selasky * between them; some callers may depend on that. 1334b00ab754SHans Petter Selasky * 1335b00ab754SHans Petter Selasky * MS-DOS has its own pcap_lookupdev(), but that might be useful only 1336b00ab754SHans Petter Selasky * as an optimization. 1337b00ab754SHans Petter Selasky * 1338b00ab754SHans Petter Selasky * In all other cases, we just use pcap_findalldevs() to get a list of 1339b00ab754SHans Petter Selasky * devices, and pick from that list. 1340b00ab754SHans Petter Selasky */ 1341b00ab754SHans Petter Selasky #if !defined(HAVE_PACKET32) && !defined(MSDOS) 1342b00ab754SHans Petter Selasky /* 1343b00ab754SHans Petter Selasky * Return the name of a network interface attached to the system, or NULL 1344b00ab754SHans Petter Selasky * if none can be found. The interface must be configured up; the 1345b00ab754SHans Petter Selasky * lowest unit number is preferred; loopback is ignored. 1346b00ab754SHans Petter Selasky */ 1347b00ab754SHans Petter Selasky char * 1348b00ab754SHans Petter Selasky pcap_lookupdev(char *errbuf) 1349b00ab754SHans Petter Selasky { 1350b00ab754SHans Petter Selasky pcap_if_t *alldevs; 1351b00ab754SHans Petter Selasky #ifdef _WIN32 1352b00ab754SHans Petter Selasky /* 1353b00ab754SHans Petter Selasky * Windows - use the same size as the old WinPcap 3.1 code. 1354b00ab754SHans Petter Selasky * XXX - this is probably bigger than it needs to be. 1355b00ab754SHans Petter Selasky */ 1356b00ab754SHans Petter Selasky #define IF_NAMESIZE 8192 1357b00ab754SHans Petter Selasky #else 1358b00ab754SHans Petter Selasky /* 1359b00ab754SHans Petter Selasky * UN*X - use the system's interface name size. 1360b00ab754SHans Petter Selasky * XXX - that might not be large enough for capture devices 1361b00ab754SHans Petter Selasky * that aren't regular network interfaces. 1362b00ab754SHans Petter Selasky */ 1363b00ab754SHans Petter Selasky /* for old BSD systems, including bsdi3 */ 1364b00ab754SHans Petter Selasky #ifndef IF_NAMESIZE 1365b00ab754SHans Petter Selasky #define IF_NAMESIZE IFNAMSIZ 1366b00ab754SHans Petter Selasky #endif 1367b00ab754SHans Petter Selasky #endif 1368b00ab754SHans Petter Selasky static char device[IF_NAMESIZE + 1]; 1369b00ab754SHans Petter Selasky char *ret; 1370b00ab754SHans Petter Selasky 1371b00ab754SHans Petter Selasky if (pcap_findalldevs(&alldevs, errbuf) == -1) 1372b00ab754SHans Petter Selasky return (NULL); 1373b00ab754SHans Petter Selasky 1374b00ab754SHans Petter Selasky if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) { 1375b00ab754SHans Petter Selasky /* 1376b00ab754SHans Petter Selasky * There are no devices on the list, or the first device 1377b00ab754SHans Petter Selasky * on the list is a loopback device, which means there 1378b00ab754SHans Petter Selasky * are no non-loopback devices on the list. This means 1379b00ab754SHans Petter Selasky * we can't return any device. 1380b00ab754SHans Petter Selasky * 1381b00ab754SHans Petter Selasky * XXX - why not return a loopback device? If we can't 1382b00ab754SHans Petter Selasky * capture on it, it won't be on the list, and if it's 1383b00ab754SHans Petter Selasky * on the list, there aren't any non-loopback devices, 1384b00ab754SHans Petter Selasky * so why not just supply it as the default device? 1385b00ab754SHans Petter Selasky */ 1386*57e22627SCy Schubert (void)pcap_strlcpy(errbuf, "no suitable device found", 1387b00ab754SHans Petter Selasky PCAP_ERRBUF_SIZE); 1388b00ab754SHans Petter Selasky ret = NULL; 1389b00ab754SHans Petter Selasky } else { 1390b00ab754SHans Petter Selasky /* 1391b00ab754SHans Petter Selasky * Return the name of the first device on the list. 1392b00ab754SHans Petter Selasky */ 1393*57e22627SCy Schubert (void)pcap_strlcpy(device, alldevs->name, sizeof(device)); 1394b00ab754SHans Petter Selasky ret = device; 1395b00ab754SHans Petter Selasky } 1396b00ab754SHans Petter Selasky 1397b00ab754SHans Petter Selasky pcap_freealldevs(alldevs); 1398b00ab754SHans Petter Selasky return (ret); 1399b00ab754SHans Petter Selasky } 1400b00ab754SHans Petter Selasky #endif /* !defined(HAVE_PACKET32) && !defined(MSDOS) */ 1401b00ab754SHans Petter Selasky 1402b00ab754SHans Petter Selasky #if !defined(_WIN32) && !defined(MSDOS) 1403b00ab754SHans Petter Selasky /* 1404b00ab754SHans Petter Selasky * We don't just fetch the entire list of devices, search for the 1405b00ab754SHans Petter Selasky * particular device, and use its first IPv4 address, as that's too 1406b00ab754SHans Petter Selasky * much work to get just one device's netmask. 1407b00ab754SHans Petter Selasky * 1408b00ab754SHans Petter Selasky * If we had an API to get attributes for a given device, we could 1409b00ab754SHans Petter Selasky * use that. 1410b00ab754SHans Petter Selasky */ 1411b00ab754SHans Petter Selasky int 1412b00ab754SHans Petter Selasky pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, 1413b00ab754SHans Petter Selasky char *errbuf) 1414b00ab754SHans Petter Selasky { 1415b00ab754SHans Petter Selasky register int fd; 1416b00ab754SHans Petter Selasky register struct sockaddr_in *sin4; 1417b00ab754SHans Petter Selasky struct ifreq ifr; 1418b00ab754SHans Petter Selasky 1419b00ab754SHans Petter Selasky /* 1420b00ab754SHans Petter Selasky * The pseudo-device "any" listens on all interfaces and therefore 1421b00ab754SHans Petter Selasky * has the network address and -mask "0.0.0.0" therefore catching 1422b00ab754SHans Petter Selasky * all traffic. Using NULL for the interface is the same as "any". 1423b00ab754SHans Petter Selasky */ 1424b00ab754SHans Petter Selasky if (!device || strcmp(device, "any") == 0 1425b00ab754SHans Petter Selasky #ifdef HAVE_DAG_API 1426b00ab754SHans Petter Selasky || strstr(device, "dag") != NULL 1427b00ab754SHans Petter Selasky #endif 1428b00ab754SHans Petter Selasky #ifdef HAVE_SEPTEL_API 1429b00ab754SHans Petter Selasky || strstr(device, "septel") != NULL 1430b00ab754SHans Petter Selasky #endif 1431b00ab754SHans Petter Selasky #ifdef PCAP_SUPPORT_BT 1432b00ab754SHans Petter Selasky || strstr(device, "bluetooth") != NULL 1433b00ab754SHans Petter Selasky #endif 1434b00ab754SHans Petter Selasky #ifdef PCAP_SUPPORT_USB 1435b00ab754SHans Petter Selasky || strstr(device, "usbmon") != NULL 1436b00ab754SHans Petter Selasky #endif 1437b00ab754SHans Petter Selasky #ifdef HAVE_SNF_API 1438b00ab754SHans Petter Selasky || strstr(device, "snf") != NULL 1439b00ab754SHans Petter Selasky #endif 1440b00ab754SHans Petter Selasky #ifdef PCAP_SUPPORT_NETMAP 1441b00ab754SHans Petter Selasky || strncmp(device, "netmap:", 7) == 0 1442b00ab754SHans Petter Selasky || strncmp(device, "vale", 4) == 0 1443b00ab754SHans Petter Selasky #endif 1444b00ab754SHans Petter Selasky ) { 1445b00ab754SHans Petter Selasky *netp = *maskp = 0; 1446b00ab754SHans Petter Selasky return 0; 1447b00ab754SHans Petter Selasky } 1448b00ab754SHans Petter Selasky 1449b00ab754SHans Petter Selasky fd = socket(AF_INET, SOCK_DGRAM, 0); 1450b00ab754SHans Petter Selasky if (fd < 0) { 1451b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1452b00ab754SHans Petter Selasky errno, "socket"); 1453b00ab754SHans Petter Selasky return (-1); 1454b00ab754SHans Petter Selasky } 1455b00ab754SHans Petter Selasky memset(&ifr, 0, sizeof(ifr)); 1456b00ab754SHans Petter Selasky #ifdef linux 1457b00ab754SHans Petter Selasky /* XXX Work around Linux kernel bug */ 1458b00ab754SHans Petter Selasky ifr.ifr_addr.sa_family = AF_INET; 1459b00ab754SHans Petter Selasky #endif 1460*57e22627SCy Schubert (void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 1461b00ab754SHans Petter Selasky if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { 1462b00ab754SHans Petter Selasky if (errno == EADDRNOTAVAIL) { 1463b00ab754SHans Petter Selasky (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 1464b00ab754SHans Petter Selasky "%s: no IPv4 address assigned", device); 1465b00ab754SHans Petter Selasky } else { 1466b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1467b00ab754SHans Petter Selasky errno, "SIOCGIFADDR: %s", device); 1468b00ab754SHans Petter Selasky } 1469b00ab754SHans Petter Selasky (void)close(fd); 1470b00ab754SHans Petter Selasky return (-1); 1471b00ab754SHans Petter Selasky } 1472b00ab754SHans Petter Selasky sin4 = (struct sockaddr_in *)&ifr.ifr_addr; 1473b00ab754SHans Petter Selasky *netp = sin4->sin_addr.s_addr; 1474b00ab754SHans Petter Selasky memset(&ifr, 0, sizeof(ifr)); 1475b00ab754SHans Petter Selasky #ifdef linux 1476b00ab754SHans Petter Selasky /* XXX Work around Linux kernel bug */ 1477b00ab754SHans Petter Selasky ifr.ifr_addr.sa_family = AF_INET; 1478b00ab754SHans Petter Selasky #endif 1479*57e22627SCy Schubert (void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 1480b00ab754SHans Petter Selasky if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) { 1481b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1482b00ab754SHans Petter Selasky errno, "SIOCGIFNETMASK: %s", device); 1483b00ab754SHans Petter Selasky (void)close(fd); 1484b00ab754SHans Petter Selasky return (-1); 1485b00ab754SHans Petter Selasky } 1486b00ab754SHans Petter Selasky (void)close(fd); 1487b00ab754SHans Petter Selasky *maskp = sin4->sin_addr.s_addr; 1488b00ab754SHans Petter Selasky if (*maskp == 0) { 1489b00ab754SHans Petter Selasky if (IN_CLASSA(*netp)) 1490b00ab754SHans Petter Selasky *maskp = IN_CLASSA_NET; 1491b00ab754SHans Petter Selasky else if (IN_CLASSB(*netp)) 1492b00ab754SHans Petter Selasky *maskp = IN_CLASSB_NET; 1493b00ab754SHans Petter Selasky else if (IN_CLASSC(*netp)) 1494b00ab754SHans Petter Selasky *maskp = IN_CLASSC_NET; 1495b00ab754SHans Petter Selasky else { 1496b00ab754SHans Petter Selasky (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 1497b00ab754SHans Petter Selasky "inet class for 0x%x unknown", *netp); 1498b00ab754SHans Petter Selasky return (-1); 1499b00ab754SHans Petter Selasky } 1500b00ab754SHans Petter Selasky } 1501b00ab754SHans Petter Selasky *netp &= *maskp; 1502b00ab754SHans Petter Selasky return (0); 1503b00ab754SHans Petter Selasky } 1504b00ab754SHans Petter Selasky #endif /* !defined(_WIN32) && !defined(MSDOS) */ 1505b00ab754SHans Petter Selasky 1506b00ab754SHans Petter Selasky #ifdef ENABLE_REMOTE 1507b00ab754SHans Petter Selasky #include "pcap-rpcap.h" 1508b00ab754SHans Petter Selasky 1509b00ab754SHans Petter Selasky /* 1510b00ab754SHans Petter Selasky * Extract a substring from a string. 1511b00ab754SHans Petter Selasky */ 1512b00ab754SHans Petter Selasky static char * 1513b00ab754SHans Petter Selasky get_substring(const char *p, size_t len, char *ebuf) 1514b00ab754SHans Petter Selasky { 1515b00ab754SHans Petter Selasky char *token; 1516b00ab754SHans Petter Selasky 1517b00ab754SHans Petter Selasky token = malloc(len + 1); 1518b00ab754SHans Petter Selasky if (token == NULL) { 1519b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1520b00ab754SHans Petter Selasky errno, "malloc"); 1521b00ab754SHans Petter Selasky return (NULL); 1522b00ab754SHans Petter Selasky } 1523b00ab754SHans Petter Selasky memcpy(token, p, len); 1524b00ab754SHans Petter Selasky token[len] = '\0'; 1525b00ab754SHans Petter Selasky return (token); 1526b00ab754SHans Petter Selasky } 1527b00ab754SHans Petter Selasky 1528b00ab754SHans Petter Selasky /* 1529b00ab754SHans Petter Selasky * Parse a capture source that might be a URL. 1530b00ab754SHans Petter Selasky * 1531b00ab754SHans Petter Selasky * If the source is not a URL, *schemep, *userinfop, *hostp, and *portp 1532b00ab754SHans Petter Selasky * are set to NULL, *pathp is set to point to the source, and 0 is 1533b00ab754SHans Petter Selasky * returned. 1534b00ab754SHans Petter Selasky * 1535b00ab754SHans Petter Selasky * If source is a URL, and the URL refers to a local device (a special 1536b00ab754SHans Petter Selasky * case of rpcap:), *schemep, *userinfop, *hostp, and *portp are set 1537b00ab754SHans Petter Selasky * to NULL, *pathp is set to point to the device name, and 0 is returned. 1538b00ab754SHans Petter Selasky * 1539b00ab754SHans Petter Selasky * If source is a URL, and it's not a special case that refers to a local 1540b00ab754SHans Petter Selasky * device, and the parse succeeds: 1541b00ab754SHans Petter Selasky * 1542b00ab754SHans Petter Selasky * *schemep is set to point to an allocated string containing the scheme; 1543b00ab754SHans Petter Selasky * 1544b00ab754SHans Petter Selasky * if user information is present in the URL, *userinfop is set to point 1545b00ab754SHans Petter Selasky * to an allocated string containing the user information, otherwise 1546b00ab754SHans Petter Selasky * it's set to NULL; 1547b00ab754SHans Petter Selasky * 1548b00ab754SHans Petter Selasky * if host information is present in the URL, *hostp is set to point 1549b00ab754SHans Petter Selasky * to an allocated string containing the host information, otherwise 1550b00ab754SHans Petter Selasky * it's set to NULL; 1551b00ab754SHans Petter Selasky * 1552b00ab754SHans Petter Selasky * if a port number is present in the URL, *portp is set to point 1553b00ab754SHans Petter Selasky * to an allocated string containing the port number, otherwise 1554b00ab754SHans Petter Selasky * it's set to NULL; 1555b00ab754SHans Petter Selasky * 1556b00ab754SHans Petter Selasky * *pathp is set to point to an allocated string containing the 1557b00ab754SHans Petter Selasky * path; 1558b00ab754SHans Petter Selasky * 1559b00ab754SHans Petter Selasky * and 0 is returned. 1560b00ab754SHans Petter Selasky * 1561b00ab754SHans Petter Selasky * If the parse fails, ebuf is set to an error string, and -1 is returned. 1562b00ab754SHans Petter Selasky */ 1563b00ab754SHans Petter Selasky static int 1564b00ab754SHans Petter Selasky pcap_parse_source(const char *source, char **schemep, char **userinfop, 1565b00ab754SHans Petter Selasky char **hostp, char **portp, char **pathp, char *ebuf) 1566b00ab754SHans Petter Selasky { 1567b00ab754SHans Petter Selasky char *colonp; 1568b00ab754SHans Petter Selasky size_t scheme_len; 1569b00ab754SHans Petter Selasky char *scheme; 1570b00ab754SHans Petter Selasky const char *endp; 1571b00ab754SHans Petter Selasky size_t authority_len; 1572b00ab754SHans Petter Selasky char *authority; 1573b00ab754SHans Petter Selasky char *parsep, *atsignp, *bracketp; 1574b00ab754SHans Petter Selasky char *userinfo, *host, *port, *path; 1575b00ab754SHans Petter Selasky 1576b00ab754SHans Petter Selasky /* 1577b00ab754SHans Petter Selasky * Start out returning nothing. 1578b00ab754SHans Petter Selasky */ 1579b00ab754SHans Petter Selasky *schemep = NULL; 1580b00ab754SHans Petter Selasky *userinfop = NULL; 1581b00ab754SHans Petter Selasky *hostp = NULL; 1582b00ab754SHans Petter Selasky *portp = NULL; 1583b00ab754SHans Petter Selasky *pathp = NULL; 1584b00ab754SHans Petter Selasky 1585b00ab754SHans Petter Selasky /* 1586b00ab754SHans Petter Selasky * RFC 3986 says: 1587b00ab754SHans Petter Selasky * 1588b00ab754SHans Petter Selasky * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 1589b00ab754SHans Petter Selasky * 1590b00ab754SHans Petter Selasky * hier-part = "//" authority path-abempty 1591b00ab754SHans Petter Selasky * / path-absolute 1592b00ab754SHans Petter Selasky * / path-rootless 1593b00ab754SHans Petter Selasky * / path-empty 1594b00ab754SHans Petter Selasky * 1595b00ab754SHans Petter Selasky * authority = [ userinfo "@" ] host [ ":" port ] 1596b00ab754SHans Petter Selasky * 1597b00ab754SHans Petter Selasky * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) 1598b00ab754SHans Petter Selasky * 1599b00ab754SHans Petter Selasky * Step 1: look for the ":" at the end of the scheme. 1600b00ab754SHans Petter Selasky * A colon in the source is *NOT* sufficient to indicate that 1601b00ab754SHans Petter Selasky * this is a URL, as interface names on some platforms might 1602b00ab754SHans Petter Selasky * include colons (e.g., I think some Solaris interfaces 1603b00ab754SHans Petter Selasky * might). 1604b00ab754SHans Petter Selasky */ 1605b00ab754SHans Petter Selasky colonp = strchr(source, ':'); 1606b00ab754SHans Petter Selasky if (colonp == NULL) { 1607b00ab754SHans Petter Selasky /* 1608b00ab754SHans Petter Selasky * The source is the device to open. 1609b00ab754SHans Petter Selasky * Return a NULL pointer for the scheme, user information, 1610b00ab754SHans Petter Selasky * host, and port, and return the device as the path. 1611b00ab754SHans Petter Selasky */ 1612b00ab754SHans Petter Selasky *pathp = strdup(source); 1613b00ab754SHans Petter Selasky if (*pathp == NULL) { 1614b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1615b00ab754SHans Petter Selasky errno, "malloc"); 1616b00ab754SHans Petter Selasky return (-1); 1617b00ab754SHans Petter Selasky } 1618b00ab754SHans Petter Selasky return (0); 1619b00ab754SHans Petter Selasky } 1620b00ab754SHans Petter Selasky 1621b00ab754SHans Petter Selasky /* 1622b00ab754SHans Petter Selasky * All schemes must have "//" after them, i.e. we only support 1623b00ab754SHans Petter Selasky * hier-part = "//" authority path-abempty, not 1624b00ab754SHans Petter Selasky * hier-part = path-absolute 1625b00ab754SHans Petter Selasky * hier-part = path-rootless 1626b00ab754SHans Petter Selasky * hier-part = path-empty 1627b00ab754SHans Petter Selasky * 1628b00ab754SHans Petter Selasky * We need that in order to distinguish between a local device 1629b00ab754SHans Petter Selasky * name that happens to contain a colon and a URI. 1630b00ab754SHans Petter Selasky */ 1631b00ab754SHans Petter Selasky if (strncmp(colonp + 1, "//", 2) != 0) { 1632b00ab754SHans Petter Selasky /* 1633b00ab754SHans Petter Selasky * The source is the device to open. 1634b00ab754SHans Petter Selasky * Return a NULL pointer for the scheme, user information, 1635b00ab754SHans Petter Selasky * host, and port, and return the device as the path. 1636b00ab754SHans Petter Selasky */ 1637b00ab754SHans Petter Selasky *pathp = strdup(source); 1638b00ab754SHans Petter Selasky if (*pathp == NULL) { 1639b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1640b00ab754SHans Petter Selasky errno, "malloc"); 1641b00ab754SHans Petter Selasky return (-1); 1642b00ab754SHans Petter Selasky } 1643b00ab754SHans Petter Selasky return (0); 1644b00ab754SHans Petter Selasky } 1645b00ab754SHans Petter Selasky 1646b00ab754SHans Petter Selasky /* 1647b00ab754SHans Petter Selasky * XXX - check whether the purported scheme could be a scheme? 1648b00ab754SHans Petter Selasky */ 1649b00ab754SHans Petter Selasky 1650b00ab754SHans Petter Selasky /* 1651b00ab754SHans Petter Selasky * OK, this looks like a URL. 1652b00ab754SHans Petter Selasky * Get the scheme. 1653b00ab754SHans Petter Selasky */ 1654b00ab754SHans Petter Selasky scheme_len = colonp - source; 1655b00ab754SHans Petter Selasky scheme = malloc(scheme_len + 1); 1656b00ab754SHans Petter Selasky if (scheme == NULL) { 1657b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1658b00ab754SHans Petter Selasky errno, "malloc"); 1659b00ab754SHans Petter Selasky return (-1); 1660b00ab754SHans Petter Selasky } 1661b00ab754SHans Petter Selasky memcpy(scheme, source, scheme_len); 1662b00ab754SHans Petter Selasky scheme[scheme_len] = '\0'; 1663b00ab754SHans Petter Selasky 1664b00ab754SHans Petter Selasky /* 1665b00ab754SHans Petter Selasky * Treat file: specially - take everything after file:// as 1666b00ab754SHans Petter Selasky * the pathname. 1667b00ab754SHans Petter Selasky */ 1668b00ab754SHans Petter Selasky if (pcap_strcasecmp(scheme, "file") == 0) { 1669b00ab754SHans Petter Selasky *pathp = strdup(colonp + 3); 1670b00ab754SHans Petter Selasky if (*pathp == NULL) { 1671b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1672b00ab754SHans Petter Selasky errno, "malloc"); 1673*57e22627SCy Schubert free(scheme); 1674b00ab754SHans Petter Selasky return (-1); 1675b00ab754SHans Petter Selasky } 1676*57e22627SCy Schubert *schemep = scheme; 1677b00ab754SHans Petter Selasky return (0); 1678b00ab754SHans Petter Selasky } 1679b00ab754SHans Petter Selasky 1680b00ab754SHans Petter Selasky /* 1681b00ab754SHans Petter Selasky * The WinPcap documentation says you can specify a local 1682b00ab754SHans Petter Selasky * interface with "rpcap://{device}"; we special-case 1683b00ab754SHans Petter Selasky * that here. If the scheme is "rpcap", and there are 1684b00ab754SHans Petter Selasky * no slashes past the "//", we just return the device. 1685b00ab754SHans Petter Selasky * 1686b00ab754SHans Petter Selasky * XXX - %-escaping? 1687b00ab754SHans Petter Selasky */ 1688b00ab754SHans Petter Selasky if (pcap_strcasecmp(scheme, "rpcap") == 0 && 1689b00ab754SHans Petter Selasky strchr(colonp + 3, '/') == NULL) { 1690b00ab754SHans Petter Selasky /* 1691b00ab754SHans Petter Selasky * Local device. 1692b00ab754SHans Petter Selasky * 1693b00ab754SHans Petter Selasky * Return a NULL pointer for the scheme, user information, 1694b00ab754SHans Petter Selasky * host, and port, and return the device as the path. 1695b00ab754SHans Petter Selasky */ 1696b00ab754SHans Petter Selasky free(scheme); 1697b00ab754SHans Petter Selasky *pathp = strdup(colonp + 3); 1698b00ab754SHans Petter Selasky if (*pathp == NULL) { 1699b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1700b00ab754SHans Petter Selasky errno, "malloc"); 1701b00ab754SHans Petter Selasky return (-1); 1702b00ab754SHans Petter Selasky } 1703b00ab754SHans Petter Selasky return (0); 1704b00ab754SHans Petter Selasky } 1705b00ab754SHans Petter Selasky 1706b00ab754SHans Petter Selasky /* 1707b00ab754SHans Petter Selasky * OK, now start parsing the authority. 1708b00ab754SHans Petter Selasky * Get token, terminated with / or terminated at the end of 1709b00ab754SHans Petter Selasky * the string. 1710b00ab754SHans Petter Selasky */ 1711b00ab754SHans Petter Selasky authority_len = strcspn(colonp + 3, "/"); 1712b00ab754SHans Petter Selasky authority = get_substring(colonp + 3, authority_len, ebuf); 1713b00ab754SHans Petter Selasky if (authority == NULL) { 1714b00ab754SHans Petter Selasky /* 1715b00ab754SHans Petter Selasky * Error. 1716b00ab754SHans Petter Selasky */ 1717b00ab754SHans Petter Selasky free(scheme); 1718b00ab754SHans Petter Selasky return (-1); 1719b00ab754SHans Petter Selasky } 1720b00ab754SHans Petter Selasky endp = colonp + 3 + authority_len; 1721b00ab754SHans Petter Selasky 1722b00ab754SHans Petter Selasky /* 1723b00ab754SHans Petter Selasky * Now carve the authority field into its components. 1724b00ab754SHans Petter Selasky */ 1725b00ab754SHans Petter Selasky parsep = authority; 1726b00ab754SHans Petter Selasky 1727b00ab754SHans Petter Selasky /* 1728b00ab754SHans Petter Selasky * Is there a userinfo field? 1729b00ab754SHans Petter Selasky */ 1730b00ab754SHans Petter Selasky atsignp = strchr(parsep, '@'); 1731b00ab754SHans Petter Selasky if (atsignp != NULL) { 1732b00ab754SHans Petter Selasky /* 1733b00ab754SHans Petter Selasky * Yes. 1734b00ab754SHans Petter Selasky */ 1735b00ab754SHans Petter Selasky size_t userinfo_len; 1736b00ab754SHans Petter Selasky 1737b00ab754SHans Petter Selasky userinfo_len = atsignp - parsep; 1738b00ab754SHans Petter Selasky userinfo = get_substring(parsep, userinfo_len, ebuf); 1739b00ab754SHans Petter Selasky if (userinfo == NULL) { 1740b00ab754SHans Petter Selasky /* 1741b00ab754SHans Petter Selasky * Error. 1742b00ab754SHans Petter Selasky */ 1743b00ab754SHans Petter Selasky free(authority); 1744b00ab754SHans Petter Selasky free(scheme); 1745b00ab754SHans Petter Selasky return (-1); 1746b00ab754SHans Petter Selasky } 1747b00ab754SHans Petter Selasky parsep = atsignp + 1; 1748b00ab754SHans Petter Selasky } else { 1749b00ab754SHans Petter Selasky /* 1750b00ab754SHans Petter Selasky * No. 1751b00ab754SHans Petter Selasky */ 1752b00ab754SHans Petter Selasky userinfo = NULL; 1753b00ab754SHans Petter Selasky } 1754b00ab754SHans Petter Selasky 1755b00ab754SHans Petter Selasky /* 1756b00ab754SHans Petter Selasky * Is there a host field? 1757b00ab754SHans Petter Selasky */ 1758b00ab754SHans Petter Selasky if (*parsep == '\0') { 1759b00ab754SHans Petter Selasky /* 1760b00ab754SHans Petter Selasky * No; there's no host field or port field. 1761b00ab754SHans Petter Selasky */ 1762b00ab754SHans Petter Selasky host = NULL; 1763b00ab754SHans Petter Selasky port = NULL; 1764b00ab754SHans Petter Selasky } else { 1765b00ab754SHans Petter Selasky /* 1766b00ab754SHans Petter Selasky * Yes. 1767b00ab754SHans Petter Selasky */ 1768b00ab754SHans Petter Selasky size_t host_len; 1769b00ab754SHans Petter Selasky 1770b00ab754SHans Petter Selasky /* 1771b00ab754SHans Petter Selasky * Is it an IP-literal? 1772b00ab754SHans Petter Selasky */ 1773b00ab754SHans Petter Selasky if (*parsep == '[') { 1774b00ab754SHans Petter Selasky /* 1775b00ab754SHans Petter Selasky * Yes. 1776b00ab754SHans Petter Selasky * Treat verything up to the closing square 1777b00ab754SHans Petter Selasky * bracket as the IP-Literal; we don't worry 1778b00ab754SHans Petter Selasky * about whether it's a valid IPv6address or 1779*57e22627SCy Schubert * IPvFuture (or an IPv4address, for that 1780*57e22627SCy Schubert * matter, just in case we get handed a 1781*57e22627SCy Schubert * URL with an IPv4 IP-Literal, of the sort 1782*57e22627SCy Schubert * that pcap_createsrcstr() used to generate, 1783*57e22627SCy Schubert * and that pcap_parsesrcstr(), in the original 1784*57e22627SCy Schubert * WinPcap code, accepted). 1785b00ab754SHans Petter Selasky */ 1786b00ab754SHans Petter Selasky bracketp = strchr(parsep, ']'); 1787b00ab754SHans Petter Selasky if (bracketp == NULL) { 1788b00ab754SHans Petter Selasky /* 1789b00ab754SHans Petter Selasky * There's no closing square bracket. 1790b00ab754SHans Petter Selasky */ 1791b00ab754SHans Petter Selasky pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1792b00ab754SHans Petter Selasky "IP-literal in URL doesn't end with ]"); 1793b00ab754SHans Petter Selasky free(userinfo); 1794b00ab754SHans Petter Selasky free(authority); 1795b00ab754SHans Petter Selasky free(scheme); 1796b00ab754SHans Petter Selasky return (-1); 1797b00ab754SHans Petter Selasky } 1798b00ab754SHans Petter Selasky if (*(bracketp + 1) != '\0' && 1799b00ab754SHans Petter Selasky *(bracketp + 1) != ':') { 1800b00ab754SHans Petter Selasky /* 1801b00ab754SHans Petter Selasky * There's extra crud after the 1802b00ab754SHans Petter Selasky * closing square bracketn. 1803b00ab754SHans Petter Selasky */ 1804b00ab754SHans Petter Selasky pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 1805b00ab754SHans Petter Selasky "Extra text after IP-literal in URL"); 1806b00ab754SHans Petter Selasky free(userinfo); 1807b00ab754SHans Petter Selasky free(authority); 1808b00ab754SHans Petter Selasky free(scheme); 1809b00ab754SHans Petter Selasky return (-1); 1810b00ab754SHans Petter Selasky } 1811b00ab754SHans Petter Selasky host_len = (bracketp - 1) - parsep; 1812b00ab754SHans Petter Selasky host = get_substring(parsep + 1, host_len, ebuf); 1813b00ab754SHans Petter Selasky if (host == NULL) { 1814b00ab754SHans Petter Selasky /* 1815b00ab754SHans Petter Selasky * Error. 1816b00ab754SHans Petter Selasky */ 1817b00ab754SHans Petter Selasky free(userinfo); 1818b00ab754SHans Petter Selasky free(authority); 1819b00ab754SHans Petter Selasky free(scheme); 1820b00ab754SHans Petter Selasky return (-1); 1821b00ab754SHans Petter Selasky } 1822b00ab754SHans Petter Selasky parsep = bracketp + 1; 1823b00ab754SHans Petter Selasky } else { 1824b00ab754SHans Petter Selasky /* 1825b00ab754SHans Petter Selasky * No. 1826b00ab754SHans Petter Selasky * Treat everything up to a : or the end of 1827b00ab754SHans Petter Selasky * the string as the host. 1828b00ab754SHans Petter Selasky */ 1829b00ab754SHans Petter Selasky host_len = strcspn(parsep, ":"); 1830b00ab754SHans Petter Selasky host = get_substring(parsep, host_len, ebuf); 1831b00ab754SHans Petter Selasky if (host == NULL) { 1832b00ab754SHans Petter Selasky /* 1833b00ab754SHans Petter Selasky * Error. 1834b00ab754SHans Petter Selasky */ 1835b00ab754SHans Petter Selasky free(userinfo); 1836b00ab754SHans Petter Selasky free(authority); 1837b00ab754SHans Petter Selasky free(scheme); 1838b00ab754SHans Petter Selasky return (-1); 1839b00ab754SHans Petter Selasky } 1840b00ab754SHans Petter Selasky parsep = parsep + host_len; 1841b00ab754SHans Petter Selasky } 1842b00ab754SHans Petter Selasky 1843b00ab754SHans Petter Selasky /* 1844b00ab754SHans Petter Selasky * Is there a port field? 1845b00ab754SHans Petter Selasky */ 1846b00ab754SHans Petter Selasky if (*parsep == ':') { 1847b00ab754SHans Petter Selasky /* 1848b00ab754SHans Petter Selasky * Yes. It's the rest of the authority field. 1849b00ab754SHans Petter Selasky */ 1850b00ab754SHans Petter Selasky size_t port_len; 1851b00ab754SHans Petter Selasky 1852b00ab754SHans Petter Selasky parsep++; 1853b00ab754SHans Petter Selasky port_len = strlen(parsep); 1854b00ab754SHans Petter Selasky port = get_substring(parsep, port_len, ebuf); 1855b00ab754SHans Petter Selasky if (port == NULL) { 1856b00ab754SHans Petter Selasky /* 1857b00ab754SHans Petter Selasky * Error. 1858b00ab754SHans Petter Selasky */ 1859b00ab754SHans Petter Selasky free(host); 1860b00ab754SHans Petter Selasky free(userinfo); 1861b00ab754SHans Petter Selasky free(authority); 1862b00ab754SHans Petter Selasky free(scheme); 1863b00ab754SHans Petter Selasky return (-1); 1864b00ab754SHans Petter Selasky } 1865b00ab754SHans Petter Selasky } else { 1866b00ab754SHans Petter Selasky /* 1867b00ab754SHans Petter Selasky * No. 1868b00ab754SHans Petter Selasky */ 1869b00ab754SHans Petter Selasky port = NULL; 1870b00ab754SHans Petter Selasky } 1871b00ab754SHans Petter Selasky } 1872b00ab754SHans Petter Selasky free(authority); 1873b00ab754SHans Petter Selasky 1874b00ab754SHans Petter Selasky /* 1875b00ab754SHans Petter Selasky * Everything else is the path. Strip off the leading /. 1876b00ab754SHans Petter Selasky */ 1877b00ab754SHans Petter Selasky if (*endp == '\0') 1878b00ab754SHans Petter Selasky path = strdup(""); 1879b00ab754SHans Petter Selasky else 1880b00ab754SHans Petter Selasky path = strdup(endp + 1); 1881b00ab754SHans Petter Selasky if (path == NULL) { 1882b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1883b00ab754SHans Petter Selasky errno, "malloc"); 1884b00ab754SHans Petter Selasky free(port); 1885b00ab754SHans Petter Selasky free(host); 1886b00ab754SHans Petter Selasky free(userinfo); 1887b00ab754SHans Petter Selasky free(scheme); 1888b00ab754SHans Petter Selasky return (-1); 1889b00ab754SHans Petter Selasky } 1890b00ab754SHans Petter Selasky *schemep = scheme; 1891b00ab754SHans Petter Selasky *userinfop = userinfo; 1892b00ab754SHans Petter Selasky *hostp = host; 1893b00ab754SHans Petter Selasky *portp = port; 1894b00ab754SHans Petter Selasky *pathp = path; 1895b00ab754SHans Petter Selasky return (0); 1896b00ab754SHans Petter Selasky } 1897b00ab754SHans Petter Selasky 1898b00ab754SHans Petter Selasky int 1899b00ab754SHans Petter Selasky pcap_createsrcstr(char *source, int type, const char *host, const char *port, 1900b00ab754SHans Petter Selasky const char *name, char *errbuf) 1901b00ab754SHans Petter Selasky { 1902b00ab754SHans Petter Selasky switch (type) { 1903b00ab754SHans Petter Selasky 1904b00ab754SHans Petter Selasky case PCAP_SRC_FILE: 1905*57e22627SCy Schubert pcap_strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE); 1906b00ab754SHans Petter Selasky if (name != NULL && *name != '\0') { 1907*57e22627SCy Schubert pcap_strlcat(source, name, PCAP_BUF_SIZE); 1908b00ab754SHans Petter Selasky return (0); 1909b00ab754SHans Petter Selasky } else { 1910b00ab754SHans Petter Selasky pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 1911b00ab754SHans Petter Selasky "The file name cannot be NULL."); 1912b00ab754SHans Petter Selasky return (-1); 1913b00ab754SHans Petter Selasky } 1914b00ab754SHans Petter Selasky 1915b00ab754SHans Petter Selasky case PCAP_SRC_IFREMOTE: 1916*57e22627SCy Schubert pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE); 1917b00ab754SHans Petter Selasky if (host != NULL && *host != '\0') { 1918b00ab754SHans Petter Selasky if (strchr(host, ':') != NULL) { 1919b00ab754SHans Petter Selasky /* 1920b00ab754SHans Petter Selasky * The host name contains a colon, so it's 1921b00ab754SHans Petter Selasky * probably an IPv6 address, and needs to 1922b00ab754SHans Petter Selasky * be included in square brackets. 1923b00ab754SHans Petter Selasky */ 1924*57e22627SCy Schubert pcap_strlcat(source, "[", PCAP_BUF_SIZE); 1925*57e22627SCy Schubert pcap_strlcat(source, host, PCAP_BUF_SIZE); 1926*57e22627SCy Schubert pcap_strlcat(source, "]", PCAP_BUF_SIZE); 1927b00ab754SHans Petter Selasky } else 1928*57e22627SCy Schubert pcap_strlcat(source, host, PCAP_BUF_SIZE); 1929b00ab754SHans Petter Selasky 1930b00ab754SHans Petter Selasky if (port != NULL && *port != '\0') { 1931*57e22627SCy Schubert pcap_strlcat(source, ":", PCAP_BUF_SIZE); 1932*57e22627SCy Schubert pcap_strlcat(source, port, PCAP_BUF_SIZE); 1933b00ab754SHans Petter Selasky } 1934b00ab754SHans Petter Selasky 1935*57e22627SCy Schubert pcap_strlcat(source, "/", PCAP_BUF_SIZE); 1936b00ab754SHans Petter Selasky } else { 1937b00ab754SHans Petter Selasky pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 1938b00ab754SHans Petter Selasky "The host name cannot be NULL."); 1939b00ab754SHans Petter Selasky return (-1); 1940b00ab754SHans Petter Selasky } 1941b00ab754SHans Petter Selasky 1942b00ab754SHans Petter Selasky if (name != NULL && *name != '\0') 1943*57e22627SCy Schubert pcap_strlcat(source, name, PCAP_BUF_SIZE); 1944b00ab754SHans Petter Selasky 1945b00ab754SHans Petter Selasky return (0); 1946b00ab754SHans Petter Selasky 1947b00ab754SHans Petter Selasky case PCAP_SRC_IFLOCAL: 1948*57e22627SCy Schubert pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE); 1949b00ab754SHans Petter Selasky 1950b00ab754SHans Petter Selasky if (name != NULL && *name != '\0') 1951*57e22627SCy Schubert pcap_strlcat(source, name, PCAP_BUF_SIZE); 1952b00ab754SHans Petter Selasky 1953b00ab754SHans Petter Selasky return (0); 1954b00ab754SHans Petter Selasky 1955b00ab754SHans Petter Selasky default: 1956b00ab754SHans Petter Selasky pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 1957b00ab754SHans Petter Selasky "The interface type is not valid."); 1958b00ab754SHans Petter Selasky return (-1); 1959b00ab754SHans Petter Selasky } 1960b00ab754SHans Petter Selasky } 1961b00ab754SHans Petter Selasky 1962b00ab754SHans Petter Selasky int 1963b00ab754SHans Petter Selasky pcap_parsesrcstr(const char *source, int *type, char *host, char *port, 1964b00ab754SHans Petter Selasky char *name, char *errbuf) 1965b00ab754SHans Petter Selasky { 1966b00ab754SHans Petter Selasky char *scheme, *tmpuserinfo, *tmphost, *tmpport, *tmppath; 1967b00ab754SHans Petter Selasky 1968b00ab754SHans Petter Selasky /* Initialization stuff */ 1969b00ab754SHans Petter Selasky if (host) 1970b00ab754SHans Petter Selasky *host = '\0'; 1971b00ab754SHans Petter Selasky if (port) 1972b00ab754SHans Petter Selasky *port = '\0'; 1973b00ab754SHans Petter Selasky if (name) 1974b00ab754SHans Petter Selasky *name = '\0'; 1975b00ab754SHans Petter Selasky 1976b00ab754SHans Petter Selasky /* Parse the source string */ 1977b00ab754SHans Petter Selasky if (pcap_parse_source(source, &scheme, &tmpuserinfo, &tmphost, 1978b00ab754SHans Petter Selasky &tmpport, &tmppath, errbuf) == -1) { 1979b00ab754SHans Petter Selasky /* 1980b00ab754SHans Petter Selasky * Fail. 1981b00ab754SHans Petter Selasky */ 1982b00ab754SHans Petter Selasky return (-1); 1983b00ab754SHans Petter Selasky } 1984b00ab754SHans Petter Selasky 1985b00ab754SHans Petter Selasky if (scheme == NULL) { 1986b00ab754SHans Petter Selasky /* 1987b00ab754SHans Petter Selasky * Local device. 1988b00ab754SHans Petter Selasky */ 1989b00ab754SHans Petter Selasky if (name && tmppath) 1990*57e22627SCy Schubert pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE); 1991b00ab754SHans Petter Selasky if (type) 1992b00ab754SHans Petter Selasky *type = PCAP_SRC_IFLOCAL; 1993b00ab754SHans Petter Selasky free(tmppath); 1994b00ab754SHans Petter Selasky free(tmpport); 1995b00ab754SHans Petter Selasky free(tmphost); 1996b00ab754SHans Petter Selasky free(tmpuserinfo); 1997b00ab754SHans Petter Selasky return (0); 1998b00ab754SHans Petter Selasky } 1999b00ab754SHans Petter Selasky 2000b00ab754SHans Petter Selasky if (strcmp(scheme, "rpcap") == 0) { 2001b00ab754SHans Petter Selasky /* 2002b00ab754SHans Petter Selasky * rpcap:// 2003b00ab754SHans Petter Selasky * 2004b00ab754SHans Petter Selasky * pcap_parse_source() has already handled the case of 2005b00ab754SHans Petter Selasky * rpcap://device 2006b00ab754SHans Petter Selasky */ 2007b00ab754SHans Petter Selasky if (host && tmphost) { 2008b00ab754SHans Petter Selasky if (tmpuserinfo) 2009b00ab754SHans Petter Selasky pcap_snprintf(host, PCAP_BUF_SIZE, "%s@%s", 2010b00ab754SHans Petter Selasky tmpuserinfo, tmphost); 2011b00ab754SHans Petter Selasky else 2012*57e22627SCy Schubert pcap_strlcpy(host, tmphost, PCAP_BUF_SIZE); 2013b00ab754SHans Petter Selasky } 2014b00ab754SHans Petter Selasky if (port && tmpport) 2015*57e22627SCy Schubert pcap_strlcpy(port, tmpport, PCAP_BUF_SIZE); 2016b00ab754SHans Petter Selasky if (name && tmppath) 2017*57e22627SCy Schubert pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE); 2018b00ab754SHans Petter Selasky if (type) 2019b00ab754SHans Petter Selasky *type = PCAP_SRC_IFREMOTE; 2020b00ab754SHans Petter Selasky free(tmppath); 2021b00ab754SHans Petter Selasky free(tmpport); 2022b00ab754SHans Petter Selasky free(tmphost); 2023b00ab754SHans Petter Selasky free(tmpuserinfo); 2024b00ab754SHans Petter Selasky free(scheme); 2025b00ab754SHans Petter Selasky return (0); 2026b00ab754SHans Petter Selasky } 2027b00ab754SHans Petter Selasky 2028b00ab754SHans Petter Selasky if (strcmp(scheme, "file") == 0) { 2029b00ab754SHans Petter Selasky /* 2030b00ab754SHans Petter Selasky * file:// 2031b00ab754SHans Petter Selasky */ 2032b00ab754SHans Petter Selasky if (name && tmppath) 2033*57e22627SCy Schubert pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE); 2034b00ab754SHans Petter Selasky if (type) 2035b00ab754SHans Petter Selasky *type = PCAP_SRC_FILE; 2036b00ab754SHans Petter Selasky free(tmppath); 2037b00ab754SHans Petter Selasky free(tmpport); 2038b00ab754SHans Petter Selasky free(tmphost); 2039b00ab754SHans Petter Selasky free(tmpuserinfo); 2040b00ab754SHans Petter Selasky free(scheme); 2041b00ab754SHans Petter Selasky return (0); 2042b00ab754SHans Petter Selasky } 2043b00ab754SHans Petter Selasky 2044b00ab754SHans Petter Selasky /* 2045b00ab754SHans Petter Selasky * Neither rpcap: nor file:; just treat the entire string 2046b00ab754SHans Petter Selasky * as a local device. 2047b00ab754SHans Petter Selasky */ 2048b00ab754SHans Petter Selasky if (name) 2049*57e22627SCy Schubert pcap_strlcpy(name, source, PCAP_BUF_SIZE); 2050b00ab754SHans Petter Selasky if (type) 2051b00ab754SHans Petter Selasky *type = PCAP_SRC_IFLOCAL; 2052b00ab754SHans Petter Selasky free(tmppath); 2053b00ab754SHans Petter Selasky free(tmpport); 2054b00ab754SHans Petter Selasky free(tmphost); 2055b00ab754SHans Petter Selasky free(tmpuserinfo); 2056b00ab754SHans Petter Selasky free(scheme); 2057b00ab754SHans Petter Selasky return (0); 2058b00ab754SHans Petter Selasky } 2059b00ab754SHans Petter Selasky #endif 2060b00ab754SHans Petter Selasky 2061edc89b24SXin LI pcap_t * 2062ada6f083SXin LI pcap_create(const char *device, char *errbuf) 2063edc89b24SXin LI { 2064edc89b24SXin LI size_t i; 2065edc89b24SXin LI int is_theirs; 2066edc89b24SXin LI pcap_t *p; 2067ada6f083SXin LI char *device_str; 2068edc89b24SXin LI 2069edc89b24SXin LI /* 2070ada6f083SXin LI * A null device name is equivalent to the "any" device - 2071edc89b24SXin LI * which might not be supported on this platform, but 2072edc89b24SXin LI * this means that you'll get a "not supported" error 2073edc89b24SXin LI * rather than, say, a crash when we try to dereference 2074edc89b24SXin LI * the null pointer. 2075edc89b24SXin LI */ 2076ada6f083SXin LI if (device == NULL) 2077ada6f083SXin LI device_str = strdup("any"); 2078ada6f083SXin LI else { 2079ada6f083SXin LI #ifdef _WIN32 2080ada6f083SXin LI /* 2081*57e22627SCy Schubert * On Windows, for backwards compatibility reasons, 2082*57e22627SCy Schubert * pcap_lookupdev() returns a pointer to a sequence of 2083*57e22627SCy Schubert * pairs of UTF-16LE device names and local code page 2084*57e22627SCy Schubert * description strings. 2085ada6f083SXin LI * 2086*57e22627SCy Schubert * This means that if a program uses pcap_lookupdev() 2087*57e22627SCy Schubert * to get a default device, and hands that to an API 2088*57e22627SCy Schubert * that opens devices, we'll get handed a UTF-16LE 2089*57e22627SCy Schubert * string, not a string in the local code page. 2090*57e22627SCy Schubert * 2091*57e22627SCy Schubert * To work around that, we check whether the string 2092*57e22627SCy Schubert * looks as if it might be a UTF-16LE strinh and, if 2093*57e22627SCy Schubert * so, convert it back to the local code page's 2094*57e22627SCy Schubert * extended ASCII. 2095*57e22627SCy Schubert * 2096*57e22627SCy Schubert * XXX - you *cannot* reliably detect whether a 2097*57e22627SCy Schubert * string is UTF-16LE or not; "a" could either 2098*57e22627SCy Schubert * be a one-character ASCII string or the first 2099*57e22627SCy Schubert * character of a UTF-16LE string. This particular 2100*57e22627SCy Schubert * version of this heuristic dates back to WinPcap 2101*57e22627SCy Schubert * 4.1.1; PacketOpenAdapter() does uses the same 2102*57e22627SCy Schubert * heuristic, with the exact same vulnerability. 2103ada6f083SXin LI */ 2104ada6f083SXin LI if (device[0] != '\0' && device[1] == '\0') { 2105ada6f083SXin LI size_t length; 2106ada6f083SXin LI 2107ada6f083SXin LI length = wcslen((wchar_t *)device); 2108ada6f083SXin LI device_str = (char *)malloc(length + 1); 2109ada6f083SXin LI if (device_str == NULL) { 2110b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, 2111b00ab754SHans Petter Selasky PCAP_ERRBUF_SIZE, errno, 2112b00ab754SHans Petter Selasky "malloc"); 2113ada6f083SXin LI return (NULL); 2114ada6f083SXin LI } 2115ada6f083SXin LI 2116ada6f083SXin LI pcap_snprintf(device_str, length + 1, "%ws", 2117ada6f083SXin LI (const wchar_t *)device); 2118ada6f083SXin LI } else 2119ada6f083SXin LI #endif 2120ada6f083SXin LI device_str = strdup(device); 2121ada6f083SXin LI } 2122ada6f083SXin LI if (device_str == NULL) { 2123b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 2124b00ab754SHans Petter Selasky errno, "malloc"); 2125ada6f083SXin LI return (NULL); 2126ada6f083SXin LI } 2127edc89b24SXin LI 2128edc89b24SXin LI /* 2129edc89b24SXin LI * Try each of the non-local-network-interface capture 2130edc89b24SXin LI * source types until we find one that works for this 2131edc89b24SXin LI * device or run out of types. 2132edc89b24SXin LI */ 2133edc89b24SXin LI for (i = 0; capture_source_types[i].create_op != NULL; i++) { 2134edc89b24SXin LI is_theirs = 0; 2135ada6f083SXin LI p = capture_source_types[i].create_op(device_str, errbuf, 2136ada6f083SXin LI &is_theirs); 2137edc89b24SXin LI if (is_theirs) { 2138edc89b24SXin LI /* 2139edc89b24SXin LI * The device name refers to a device of the 2140edc89b24SXin LI * type in question; either it succeeded, 2141edc89b24SXin LI * in which case p refers to a pcap_t to 2142edc89b24SXin LI * later activate for the device, or it 2143edc89b24SXin LI * failed, in which case p is null and we 2144edc89b24SXin LI * should return that to report the failure 2145edc89b24SXin LI * to create. 2146edc89b24SXin LI */ 2147ada6f083SXin LI if (p == NULL) { 2148ada6f083SXin LI /* 2149ada6f083SXin LI * We assume the caller filled in errbuf. 2150ada6f083SXin LI */ 2151ada6f083SXin LI free(device_str); 2152ada6f083SXin LI return (NULL); 2153ada6f083SXin LI } 2154ada6f083SXin LI p->opt.device = device_str; 2155edc89b24SXin LI return (p); 2156edc89b24SXin LI } 2157edc89b24SXin LI } 2158edc89b24SXin LI 2159edc89b24SXin LI /* 2160edc89b24SXin LI * OK, try it as a regular network interface. 2161edc89b24SXin LI */ 2162ada6f083SXin LI p = pcap_create_interface(device_str, errbuf); 2163ada6f083SXin LI if (p == NULL) { 2164ada6f083SXin LI /* 2165ada6f083SXin LI * We assume the caller filled in errbuf. 2166ada6f083SXin LI */ 2167ada6f083SXin LI free(device_str); 2168ada6f083SXin LI return (NULL); 2169edc89b24SXin LI } 2170ada6f083SXin LI p->opt.device = device_str; 2171ada6f083SXin LI return (p); 2172ada6f083SXin LI } 2173edc89b24SXin LI 2174b00ab754SHans Petter Selasky /* 2175b00ab754SHans Petter Selasky * Set nonblocking mode on an unactivated pcap_t; this sets a flag 2176b00ab754SHans Petter Selasky * checked by pcap_activate(), which sets the mode after calling 2177b00ab754SHans Petter Selasky * the activate routine. 2178b00ab754SHans Petter Selasky */ 2179b00ab754SHans Petter Selasky static int 2180b00ab754SHans Petter Selasky pcap_setnonblock_unactivated(pcap_t *p, int nonblock) 2181b00ab754SHans Petter Selasky { 2182b00ab754SHans Petter Selasky p->opt.nonblock = nonblock; 2183b00ab754SHans Petter Selasky return (0); 2184b00ab754SHans Petter Selasky } 2185b00ab754SHans Petter Selasky 2186a0ee43a1SRui Paulo static void 2187a0ee43a1SRui Paulo initialize_ops(pcap_t *p) 2188a0ee43a1SRui Paulo { 2189a0ee43a1SRui Paulo /* 2190a0ee43a1SRui Paulo * Set operation pointers for operations that only work on 2191a0ee43a1SRui Paulo * an activated pcap_t to point to a routine that returns 2192a0ee43a1SRui Paulo * a "this isn't activated" error. 2193a8e07101SRui Paulo */ 2194*57e22627SCy Schubert p->read_op = pcap_read_not_initialized; 2195*57e22627SCy Schubert p->inject_op = pcap_inject_not_initialized; 2196*57e22627SCy Schubert p->setfilter_op = pcap_setfilter_not_initialized; 2197*57e22627SCy Schubert p->setdirection_op = pcap_setdirection_not_initialized; 2198*57e22627SCy Schubert p->set_datalink_op = pcap_set_datalink_not_initialized; 2199*57e22627SCy Schubert p->getnonblock_op = pcap_getnonblock_not_initialized; 2200*57e22627SCy Schubert p->stats_op = pcap_stats_not_initialized; 2201ada6f083SXin LI #ifdef _WIN32 2202*57e22627SCy Schubert p->stats_ex_op = pcap_stats_ex_not_initialized; 2203*57e22627SCy Schubert p->setbuff_op = pcap_setbuff_not_initialized; 2204*57e22627SCy Schubert p->setmode_op = pcap_setmode_not_initialized; 2205*57e22627SCy Schubert p->setmintocopy_op = pcap_setmintocopy_not_initialized; 2206ada6f083SXin LI p->getevent_op = pcap_getevent_not_initialized; 2207*57e22627SCy Schubert p->oid_get_request_op = pcap_oid_get_request_not_initialized; 2208*57e22627SCy Schubert p->oid_set_request_op = pcap_oid_set_request_not_initialized; 2209ada6f083SXin LI p->sendqueue_transmit_op = pcap_sendqueue_transmit_not_initialized; 2210*57e22627SCy Schubert p->setuserbuffer_op = pcap_setuserbuffer_not_initialized; 2211*57e22627SCy Schubert p->live_dump_op = pcap_live_dump_not_initialized; 2212*57e22627SCy Schubert p->live_dump_ended_op = pcap_live_dump_ended_not_initialized; 2213ada6f083SXin LI p->get_airpcap_handle_op = pcap_get_airpcap_handle_not_initialized; 2214a8e07101SRui Paulo #endif 2215a0ee43a1SRui Paulo 2216a0ee43a1SRui Paulo /* 2217a0ee43a1SRui Paulo * Default cleanup operation - implementations can override 2218a0ee43a1SRui Paulo * this, but should call pcap_cleanup_live_common() after 2219a0ee43a1SRui Paulo * doing their own additional cleanup. 2220a0ee43a1SRui Paulo */ 2221a8e07101SRui Paulo p->cleanup_op = pcap_cleanup_live_common; 2222a8e07101SRui Paulo 2223a0ee43a1SRui Paulo /* 2224681ed54cSXin LI * In most cases, the standard one-shot callback can 2225a0ee43a1SRui Paulo * be used for pcap_next()/pcap_next_ex(). 2226a0ee43a1SRui Paulo */ 2227a0ee43a1SRui Paulo p->oneshot_callback = pcap_oneshot; 2228a0ee43a1SRui Paulo } 2229a0ee43a1SRui Paulo 2230681ed54cSXin LI static pcap_t * 2231681ed54cSXin LI pcap_alloc_pcap_t(char *ebuf, size_t size) 2232a0ee43a1SRui Paulo { 2233681ed54cSXin LI char *chunk; 2234a0ee43a1SRui Paulo pcap_t *p; 2235a0ee43a1SRui Paulo 2236681ed54cSXin LI /* 2237681ed54cSXin LI * Allocate a chunk of memory big enough for a pcap_t 2238681ed54cSXin LI * plus a structure following it of size "size". The 2239681ed54cSXin LI * structure following it is a private data structure 2240681ed54cSXin LI * for the routines that handle this pcap_t. 2241*57e22627SCy Schubert * 2242*57e22627SCy Schubert * The structure following it must be aligned on 2243*57e22627SCy Schubert * the appropriate alignment boundary for this platform. 2244*57e22627SCy Schubert * We align on an 8-byte boundary as that's probably what 2245*57e22627SCy Schubert * at least some platforms do, even with 32-bit integers, 2246*57e22627SCy Schubert * and because we can't be sure that some values won't 2247*57e22627SCy Schubert * require 8-byte alignment even on platforms with 32-bit 2248*57e22627SCy Schubert * integers. 2249681ed54cSXin LI */ 2250*57e22627SCy Schubert #define PCAP_T_ALIGNED_SIZE ((sizeof(pcap_t) + 7U) & ~0x7U) 2251*57e22627SCy Schubert chunk = malloc(PCAP_T_ALIGNED_SIZE + size); 2252681ed54cSXin LI if (chunk == NULL) { 2253b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 2254b00ab754SHans Petter Selasky errno, "malloc"); 2255a0ee43a1SRui Paulo return (NULL); 2256a0ee43a1SRui Paulo } 2257*57e22627SCy Schubert memset(chunk, 0, PCAP_T_ALIGNED_SIZE + size); 2258681ed54cSXin LI 2259681ed54cSXin LI /* 2260681ed54cSXin LI * Get a pointer to the pcap_t at the beginning. 2261681ed54cSXin LI */ 2262681ed54cSXin LI p = (pcap_t *)chunk; 2263681ed54cSXin LI 2264b00ab754SHans Petter Selasky #ifdef _WIN32 2265b00ab754SHans Petter Selasky p->handle = INVALID_HANDLE_VALUE; /* not opened yet */ 2266b00ab754SHans Petter Selasky #else /* _WIN32 */ 2267a0ee43a1SRui Paulo p->fd = -1; /* not opened yet */ 2268b00ab754SHans Petter Selasky #ifndef MSDOS 2269a0ee43a1SRui Paulo p->selectable_fd = -1; 2270b00ab754SHans Petter Selasky p->required_select_timeout = NULL; 2271b00ab754SHans Petter Selasky #endif /* MSDOS */ 2272b00ab754SHans Petter Selasky #endif /* _WIN32 */ 2273a0ee43a1SRui Paulo 2274681ed54cSXin LI if (size == 0) { 2275681ed54cSXin LI /* No private data was requested. */ 2276681ed54cSXin LI p->priv = NULL; 2277681ed54cSXin LI } else { 2278681ed54cSXin LI /* 2279681ed54cSXin LI * Set the pointer to the private data; that's the structure 2280681ed54cSXin LI * of size "size" following the pcap_t. 2281681ed54cSXin LI */ 2282*57e22627SCy Schubert p->priv = (void *)(chunk + PCAP_T_ALIGNED_SIZE); 2283681ed54cSXin LI } 2284681ed54cSXin LI 2285681ed54cSXin LI return (p); 2286681ed54cSXin LI } 2287681ed54cSXin LI 2288681ed54cSXin LI pcap_t * 2289ada6f083SXin LI pcap_create_common(char *ebuf, size_t size) 2290681ed54cSXin LI { 2291681ed54cSXin LI pcap_t *p; 2292681ed54cSXin LI 2293681ed54cSXin LI p = pcap_alloc_pcap_t(ebuf, size); 2294681ed54cSXin LI if (p == NULL) 2295681ed54cSXin LI return (NULL); 2296681ed54cSXin LI 2297a0ee43a1SRui Paulo /* 2298a0ee43a1SRui Paulo * Default to "can't set rfmon mode"; if it's supported by 2299a0ee43a1SRui Paulo * a platform, the create routine that called us can set 2300a0ee43a1SRui Paulo * the op to its routine to check whether a particular 2301a0ee43a1SRui Paulo * device supports it. 2302a0ee43a1SRui Paulo */ 2303a0ee43a1SRui Paulo p->can_set_rfmon_op = pcap_cant_set_rfmon; 2304a0ee43a1SRui Paulo 2305b00ab754SHans Petter Selasky /* 2306b00ab754SHans Petter Selasky * If pcap_setnonblock() is called on a not-yet-activated 2307b00ab754SHans Petter Selasky * pcap_t, default to setting a flag and turning 2308b00ab754SHans Petter Selasky * on non-blocking mode when activated. 2309b00ab754SHans Petter Selasky */ 2310b00ab754SHans Petter Selasky p->setnonblock_op = pcap_setnonblock_unactivated; 2311b00ab754SHans Petter Selasky 2312a0ee43a1SRui Paulo initialize_ops(p); 2313a0ee43a1SRui Paulo 2314a8e07101SRui Paulo /* put in some defaults*/ 2315b00ab754SHans Petter Selasky p->snapshot = 0; /* max packet size unspecified */ 2316681ed54cSXin LI p->opt.timeout = 0; /* no timeout specified */ 2317681ed54cSXin LI p->opt.buffer_size = 0; /* use the platform's default */ 2318a8e07101SRui Paulo p->opt.promisc = 0; 2319681ed54cSXin LI p->opt.rfmon = 0; 2320681ed54cSXin LI p->opt.immediate = 0; 2321d1e87331SXin LI p->opt.tstamp_type = -1; /* default to not setting time stamp type */ 2322681ed54cSXin LI p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO; 2323b00ab754SHans Petter Selasky /* 2324b00ab754SHans Petter Selasky * Platform-dependent options. 2325b00ab754SHans Petter Selasky */ 2326b00ab754SHans Petter Selasky #ifdef __linux__ 2327b00ab754SHans Petter Selasky p->opt.protocol = 0; 2328b00ab754SHans Petter Selasky #endif 2329b00ab754SHans Petter Selasky #ifdef _WIN32 2330b00ab754SHans Petter Selasky p->opt.nocapture_local = 0; 2331b00ab754SHans Petter Selasky #endif 2332ada6f083SXin LI 2333ada6f083SXin LI /* 2334ada6f083SXin LI * Start out with no BPF code generation flags set. 2335ada6f083SXin LI */ 2336ada6f083SXin LI p->bpf_codegen_flags = 0; 2337ada6f083SXin LI 2338a8e07101SRui Paulo return (p); 2339a8e07101SRui Paulo } 2340a8e07101SRui Paulo 2341a8e07101SRui Paulo int 2342a8e07101SRui Paulo pcap_check_activated(pcap_t *p) 2343a8e07101SRui Paulo { 2344a8e07101SRui Paulo if (p->activated) { 2345ada6f083SXin LI pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform " 2346a8e07101SRui Paulo " operation on activated capture"); 2347d1e87331SXin LI return (-1); 2348a8e07101SRui Paulo } 2349d1e87331SXin LI return (0); 2350a8e07101SRui Paulo } 2351a8e07101SRui Paulo 2352a8e07101SRui Paulo int 2353a8e07101SRui Paulo pcap_set_snaplen(pcap_t *p, int snaplen) 2354a8e07101SRui Paulo { 2355a8e07101SRui Paulo if (pcap_check_activated(p)) 2356d1e87331SXin LI return (PCAP_ERROR_ACTIVATED); 2357a8e07101SRui Paulo p->snapshot = snaplen; 2358d1e87331SXin LI return (0); 2359a8e07101SRui Paulo } 2360a8e07101SRui Paulo 2361a8e07101SRui Paulo int 2362a8e07101SRui Paulo pcap_set_promisc(pcap_t *p, int promisc) 2363a8e07101SRui Paulo { 2364a8e07101SRui Paulo if (pcap_check_activated(p)) 2365d1e87331SXin LI return (PCAP_ERROR_ACTIVATED); 2366a8e07101SRui Paulo p->opt.promisc = promisc; 2367d1e87331SXin LI return (0); 2368a8e07101SRui Paulo } 2369a8e07101SRui Paulo 2370a8e07101SRui Paulo int 2371a8e07101SRui Paulo pcap_set_rfmon(pcap_t *p, int rfmon) 2372a8e07101SRui Paulo { 2373a8e07101SRui Paulo if (pcap_check_activated(p)) 2374d1e87331SXin LI return (PCAP_ERROR_ACTIVATED); 2375a8e07101SRui Paulo p->opt.rfmon = rfmon; 2376d1e87331SXin LI return (0); 2377a8e07101SRui Paulo } 2378a8e07101SRui Paulo 2379a8e07101SRui Paulo int 2380a8e07101SRui Paulo pcap_set_timeout(pcap_t *p, int timeout_ms) 2381a8e07101SRui Paulo { 2382a8e07101SRui Paulo if (pcap_check_activated(p)) 2383d1e87331SXin LI return (PCAP_ERROR_ACTIVATED); 2384681ed54cSXin LI p->opt.timeout = timeout_ms; 2385d1e87331SXin LI return (0); 2386d1e87331SXin LI } 2387d1e87331SXin LI 2388d1e87331SXin LI int 2389d1e87331SXin LI pcap_set_tstamp_type(pcap_t *p, int tstamp_type) 2390d1e87331SXin LI { 2391d1e87331SXin LI int i; 2392d1e87331SXin LI 2393d1e87331SXin LI if (pcap_check_activated(p)) 2394d1e87331SXin LI return (PCAP_ERROR_ACTIVATED); 2395d1e87331SXin LI 2396d1e87331SXin LI /* 2397ada6f083SXin LI * The argument should have been u_int, but that's too late 2398ada6f083SXin LI * to change now - it's an API. 2399ada6f083SXin LI */ 2400ada6f083SXin LI if (tstamp_type < 0) 2401ada6f083SXin LI return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP); 2402ada6f083SXin LI 2403ada6f083SXin LI /* 2404681ed54cSXin LI * If p->tstamp_type_count is 0, we only support PCAP_TSTAMP_HOST; 2405681ed54cSXin LI * the default time stamp type is PCAP_TSTAMP_HOST. 2406d1e87331SXin LI */ 2407681ed54cSXin LI if (p->tstamp_type_count == 0) { 2408681ed54cSXin LI if (tstamp_type == PCAP_TSTAMP_HOST) { 2409681ed54cSXin LI p->opt.tstamp_type = tstamp_type; 2410681ed54cSXin LI return (0); 2411681ed54cSXin LI } 2412681ed54cSXin LI } else { 2413d1e87331SXin LI /* 2414d1e87331SXin LI * Check whether we claim to support this type of time stamp. 2415d1e87331SXin LI */ 2416d1e87331SXin LI for (i = 0; i < p->tstamp_type_count; i++) { 2417ada6f083SXin LI if (p->tstamp_type_list[i] == (u_int)tstamp_type) { 2418d1e87331SXin LI /* 2419d1e87331SXin LI * Yes. 2420d1e87331SXin LI */ 2421d1e87331SXin LI p->opt.tstamp_type = tstamp_type; 2422d1e87331SXin LI return (0); 2423d1e87331SXin LI } 2424d1e87331SXin LI } 2425681ed54cSXin LI } 2426d1e87331SXin LI 2427d1e87331SXin LI /* 2428681ed54cSXin LI * We don't support this type of time stamp. 2429d1e87331SXin LI */ 2430d1e87331SXin LI return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP); 2431a8e07101SRui Paulo } 2432a8e07101SRui Paulo 2433a8e07101SRui Paulo int 2434681ed54cSXin LI pcap_set_immediate_mode(pcap_t *p, int immediate) 2435681ed54cSXin LI { 2436681ed54cSXin LI if (pcap_check_activated(p)) 2437681ed54cSXin LI return (PCAP_ERROR_ACTIVATED); 2438681ed54cSXin LI p->opt.immediate = immediate; 2439681ed54cSXin LI return (0); 2440681ed54cSXin LI } 2441681ed54cSXin LI 2442681ed54cSXin LI int 2443a8e07101SRui Paulo pcap_set_buffer_size(pcap_t *p, int buffer_size) 2444a8e07101SRui Paulo { 2445a8e07101SRui Paulo if (pcap_check_activated(p)) 2446d1e87331SXin LI return (PCAP_ERROR_ACTIVATED); 2447ada6f083SXin LI if (buffer_size <= 0) { 2448ada6f083SXin LI /* 2449ada6f083SXin LI * Silently ignore invalid values. 2450ada6f083SXin LI */ 2451ada6f083SXin LI return (0); 2452ada6f083SXin LI } 2453a8e07101SRui Paulo p->opt.buffer_size = buffer_size; 2454d1e87331SXin LI return (0); 2455a8e07101SRui Paulo } 2456a8e07101SRui Paulo 2457a8e07101SRui Paulo int 2458681ed54cSXin LI pcap_set_tstamp_precision(pcap_t *p, int tstamp_precision) 2459681ed54cSXin LI { 2460681ed54cSXin LI int i; 2461681ed54cSXin LI 2462681ed54cSXin LI if (pcap_check_activated(p)) 2463681ed54cSXin LI return (PCAP_ERROR_ACTIVATED); 2464681ed54cSXin LI 2465681ed54cSXin LI /* 2466ada6f083SXin LI * The argument should have been u_int, but that's too late 2467ada6f083SXin LI * to change now - it's an API. 2468ada6f083SXin LI */ 2469ada6f083SXin LI if (tstamp_precision < 0) 2470ada6f083SXin LI return (PCAP_ERROR_TSTAMP_PRECISION_NOTSUP); 2471ada6f083SXin LI 2472ada6f083SXin LI /* 2473681ed54cSXin LI * If p->tstamp_precision_count is 0, we only support setting 2474681ed54cSXin LI * the time stamp precision to microsecond precision; every 2475681ed54cSXin LI * pcap module *MUST* support microsecond precision, even if 2476681ed54cSXin LI * it does so by converting the native precision to 2477681ed54cSXin LI * microseconds. 2478681ed54cSXin LI */ 2479681ed54cSXin LI if (p->tstamp_precision_count == 0) { 2480681ed54cSXin LI if (tstamp_precision == PCAP_TSTAMP_PRECISION_MICRO) { 2481681ed54cSXin LI p->opt.tstamp_precision = tstamp_precision; 2482681ed54cSXin LI return (0); 2483681ed54cSXin LI } 2484681ed54cSXin LI } else { 2485681ed54cSXin LI /* 2486681ed54cSXin LI * Check whether we claim to support this precision of 2487681ed54cSXin LI * time stamp. 2488681ed54cSXin LI */ 2489681ed54cSXin LI for (i = 0; i < p->tstamp_precision_count; i++) { 2490ada6f083SXin LI if (p->tstamp_precision_list[i] == (u_int)tstamp_precision) { 2491681ed54cSXin LI /* 2492681ed54cSXin LI * Yes. 2493681ed54cSXin LI */ 2494681ed54cSXin LI p->opt.tstamp_precision = tstamp_precision; 2495681ed54cSXin LI return (0); 2496681ed54cSXin LI } 2497681ed54cSXin LI } 2498681ed54cSXin LI } 2499681ed54cSXin LI 2500681ed54cSXin LI /* 2501681ed54cSXin LI * We don't support this time stamp precision. 2502681ed54cSXin LI */ 2503681ed54cSXin LI return (PCAP_ERROR_TSTAMP_PRECISION_NOTSUP); 2504681ed54cSXin LI } 2505681ed54cSXin LI 2506681ed54cSXin LI int 2507681ed54cSXin LI pcap_get_tstamp_precision(pcap_t *p) 2508681ed54cSXin LI { 2509681ed54cSXin LI return (p->opt.tstamp_precision); 2510681ed54cSXin LI } 2511681ed54cSXin LI 2512681ed54cSXin LI int 2513a8e07101SRui Paulo pcap_activate(pcap_t *p) 2514a8e07101SRui Paulo { 2515a8e07101SRui Paulo int status; 2516a8e07101SRui Paulo 2517d1e87331SXin LI /* 2518d1e87331SXin LI * Catch attempts to re-activate an already-activated 2519d1e87331SXin LI * pcap_t; this should, for example, catch code that 2520d1e87331SXin LI * calls pcap_open_live() followed by pcap_activate(), 2521d1e87331SXin LI * as some code that showed up in a Stack Exchange 2522d1e87331SXin LI * question did. 2523d1e87331SXin LI */ 2524d1e87331SXin LI if (pcap_check_activated(p)) 2525d1e87331SXin LI return (PCAP_ERROR_ACTIVATED); 2526a8e07101SRui Paulo status = p->activate_op(p); 2527b00ab754SHans Petter Selasky if (status >= 0) { 2528b00ab754SHans Petter Selasky /* 2529b00ab754SHans Petter Selasky * If somebody requested non-blocking mode before 2530b00ab754SHans Petter Selasky * calling pcap_activate(), turn it on now. 2531b00ab754SHans Petter Selasky */ 2532b00ab754SHans Petter Selasky if (p->opt.nonblock) { 2533b00ab754SHans Petter Selasky status = p->setnonblock_op(p, 1); 2534b00ab754SHans Petter Selasky if (status < 0) { 2535b00ab754SHans Petter Selasky /* 2536b00ab754SHans Petter Selasky * Failed. Undo everything done by 2537b00ab754SHans Petter Selasky * the activate operation. 2538b00ab754SHans Petter Selasky */ 2539b00ab754SHans Petter Selasky p->cleanup_op(p); 2540b00ab754SHans Petter Selasky initialize_ops(p); 2541b00ab754SHans Petter Selasky return (status); 2542b00ab754SHans Petter Selasky } 2543b00ab754SHans Petter Selasky } 2544a8e07101SRui Paulo p->activated = 1; 2545b00ab754SHans Petter Selasky } else { 2546a0ee43a1SRui Paulo if (p->errbuf[0] == '\0') { 2547a0ee43a1SRui Paulo /* 2548a0ee43a1SRui Paulo * No error message supplied by the activate routine; 2549a0ee43a1SRui Paulo * for the benefit of programs that don't specially 2550a0ee43a1SRui Paulo * handle errors other than PCAP_ERROR, return the 2551a0ee43a1SRui Paulo * error message corresponding to the status. 2552a0ee43a1SRui Paulo */ 2553ada6f083SXin LI pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", 2554a0ee43a1SRui Paulo pcap_statustostr(status)); 2555a0ee43a1SRui Paulo } 2556a0ee43a1SRui Paulo 2557a0ee43a1SRui Paulo /* 2558a0ee43a1SRui Paulo * Undo any operation pointer setting, etc. done by 2559a0ee43a1SRui Paulo * the activate operation. 2560a0ee43a1SRui Paulo */ 2561a0ee43a1SRui Paulo initialize_ops(p); 2562a0ee43a1SRui Paulo } 2563a8e07101SRui Paulo return (status); 2564a8e07101SRui Paulo } 2565a8e07101SRui Paulo 2566a8e07101SRui Paulo pcap_t * 2567ada6f083SXin LI pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf) 2568a8e07101SRui Paulo { 2569a8e07101SRui Paulo pcap_t *p; 2570a8e07101SRui Paulo int status; 2571b00ab754SHans Petter Selasky #ifdef ENABLE_REMOTE 2572b00ab754SHans Petter Selasky char host[PCAP_BUF_SIZE + 1]; 2573b00ab754SHans Petter Selasky char port[PCAP_BUF_SIZE + 1]; 2574b00ab754SHans Petter Selasky char name[PCAP_BUF_SIZE + 1]; 2575b00ab754SHans Petter Selasky int srctype; 2576b00ab754SHans Petter Selasky 2577b00ab754SHans Petter Selasky /* 2578*57e22627SCy Schubert * A null device name is equivalent to the "any" device - 2579*57e22627SCy Schubert * which might not be supported on this platform, but 2580*57e22627SCy Schubert * this means that you'll get a "not supported" error 2581*57e22627SCy Schubert * rather than, say, a crash when we try to dereference 2582*57e22627SCy Schubert * the null pointer. 2583*57e22627SCy Schubert */ 2584*57e22627SCy Schubert if (device == NULL) 2585*57e22627SCy Schubert device = "any"; 2586*57e22627SCy Schubert 2587*57e22627SCy Schubert /* 2588b00ab754SHans Petter Selasky * Retrofit - we have to make older applications compatible with 2589b00ab754SHans Petter Selasky * remote capture. 2590b00ab754SHans Petter Selasky * So we're calling pcap_open_remote() from here; this is a very 2591b00ab754SHans Petter Selasky * dirty hack. 2592b00ab754SHans Petter Selasky * Obviously, we cannot exploit all the new features; for instance, 2593b00ab754SHans Petter Selasky * we cannot send authentication, we cannot use a UDP data connection, 2594b00ab754SHans Petter Selasky * and so on. 2595b00ab754SHans Petter Selasky */ 2596b00ab754SHans Petter Selasky if (pcap_parsesrcstr(device, &srctype, host, port, name, errbuf)) 2597b00ab754SHans Petter Selasky return (NULL); 2598b00ab754SHans Petter Selasky 2599b00ab754SHans Petter Selasky if (srctype == PCAP_SRC_IFREMOTE) { 2600b00ab754SHans Petter Selasky /* 2601b00ab754SHans Petter Selasky * Although we already have host, port and iface, we prefer 2602b00ab754SHans Petter Selasky * to pass only 'device' to pcap_open_rpcap(), so that it has 2603b00ab754SHans Petter Selasky * to call pcap_parsesrcstr() again. 2604b00ab754SHans Petter Selasky * This is less optimized, but much clearer. 2605b00ab754SHans Petter Selasky */ 2606b00ab754SHans Petter Selasky return (pcap_open_rpcap(device, snaplen, 2607b00ab754SHans Petter Selasky promisc ? PCAP_OPENFLAG_PROMISCUOUS : 0, to_ms, 2608b00ab754SHans Petter Selasky NULL, errbuf)); 2609b00ab754SHans Petter Selasky } 2610b00ab754SHans Petter Selasky if (srctype == PCAP_SRC_FILE) { 2611b00ab754SHans Petter Selasky pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown URL scheme \"file\""); 2612b00ab754SHans Petter Selasky return (NULL); 2613b00ab754SHans Petter Selasky } 2614b00ab754SHans Petter Selasky if (srctype == PCAP_SRC_IFLOCAL) { 2615b00ab754SHans Petter Selasky /* 2616b00ab754SHans Petter Selasky * If it starts with rpcap://, that refers to a local device 2617b00ab754SHans Petter Selasky * (no host part in the URL). Remove the rpcap://, and 2618b00ab754SHans Petter Selasky * fall through to the regular open path. 2619b00ab754SHans Petter Selasky */ 2620b00ab754SHans Petter Selasky if (strncmp(device, PCAP_SRC_IF_STRING, strlen(PCAP_SRC_IF_STRING)) == 0) { 2621b00ab754SHans Petter Selasky size_t len = strlen(device) - strlen(PCAP_SRC_IF_STRING) + 1; 2622b00ab754SHans Petter Selasky 2623b00ab754SHans Petter Selasky if (len > 0) 2624b00ab754SHans Petter Selasky device += strlen(PCAP_SRC_IF_STRING); 2625b00ab754SHans Petter Selasky } 2626b00ab754SHans Petter Selasky } 2627b00ab754SHans Petter Selasky #endif /* ENABLE_REMOTE */ 2628a8e07101SRui Paulo 2629ada6f083SXin LI p = pcap_create(device, errbuf); 2630a8e07101SRui Paulo if (p == NULL) 2631a8e07101SRui Paulo return (NULL); 2632a8e07101SRui Paulo status = pcap_set_snaplen(p, snaplen); 2633a8e07101SRui Paulo if (status < 0) 2634a8e07101SRui Paulo goto fail; 2635a8e07101SRui Paulo status = pcap_set_promisc(p, promisc); 2636a8e07101SRui Paulo if (status < 0) 2637a8e07101SRui Paulo goto fail; 2638a8e07101SRui Paulo status = pcap_set_timeout(p, to_ms); 2639a8e07101SRui Paulo if (status < 0) 2640a8e07101SRui Paulo goto fail; 2641a8e07101SRui Paulo /* 2642a8e07101SRui Paulo * Mark this as opened with pcap_open_live(), so that, for 2643a8e07101SRui Paulo * example, we show the full list of DLT_ values, rather 2644a8e07101SRui Paulo * than just the ones that are compatible with capturing 2645a8e07101SRui Paulo * when not in monitor mode. That allows existing applications 2646a8e07101SRui Paulo * to work the way they used to work, but allows new applications 2647a8e07101SRui Paulo * that know about the new open API to, for example, find out the 2648a8e07101SRui Paulo * DLT_ values that they can select without changing whether 2649a8e07101SRui Paulo * the adapter is in monitor mode or not. 2650a8e07101SRui Paulo */ 2651a8e07101SRui Paulo p->oldstyle = 1; 2652a8e07101SRui Paulo status = pcap_activate(p); 2653a8e07101SRui Paulo if (status < 0) 2654a8e07101SRui Paulo goto fail; 2655a8e07101SRui Paulo return (p); 2656a8e07101SRui Paulo fail: 2657a0ee43a1SRui Paulo if (status == PCAP_ERROR) 2658*57e22627SCy Schubert pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %.*s", device, 2659*57e22627SCy Schubert PCAP_ERRBUF_SIZE - 3, p->errbuf); 2660a0ee43a1SRui Paulo else if (status == PCAP_ERROR_NO_SUCH_DEVICE || 2661d1e87331SXin LI status == PCAP_ERROR_PERM_DENIED || 2662d1e87331SXin LI status == PCAP_ERROR_PROMISC_PERM_DENIED) 2663*57e22627SCy Schubert pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%.*s)", device, 2664*57e22627SCy Schubert pcap_statustostr(status), PCAP_ERRBUF_SIZE - 6, p->errbuf); 2665a8e07101SRui Paulo else 2666ada6f083SXin LI pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device, 2667a8e07101SRui Paulo pcap_statustostr(status)); 2668a8e07101SRui Paulo pcap_close(p); 2669a8e07101SRui Paulo return (NULL); 2670a8e07101SRui Paulo } 2671a8e07101SRui Paulo 2672681ed54cSXin LI pcap_t * 2673681ed54cSXin LI pcap_open_offline_common(char *ebuf, size_t size) 2674681ed54cSXin LI { 2675681ed54cSXin LI pcap_t *p; 2676681ed54cSXin LI 2677681ed54cSXin LI p = pcap_alloc_pcap_t(ebuf, size); 2678681ed54cSXin LI if (p == NULL) 2679681ed54cSXin LI return (NULL); 2680681ed54cSXin LI 2681681ed54cSXin LI p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO; 2682681ed54cSXin LI 2683681ed54cSXin LI return (p); 2684681ed54cSXin LI } 2685681ed54cSXin LI 2686a8e07101SRui Paulo int 26878cf6c252SPaul Traina pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 26888cf6c252SPaul Traina { 2689d1e87331SXin LI return (p->read_op(p, cnt, callback, user)); 2690feb4ecdbSBruce M Simpson } 2691feb4ecdbSBruce M Simpson 26928cf6c252SPaul Traina int 26938cf6c252SPaul Traina pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 26948cf6c252SPaul Traina { 2695a4b5b39fSBill Fenner register int n; 2696a4b5b39fSBill Fenner 26978cf6c252SPaul Traina for (;;) { 2698681ed54cSXin LI if (p->rfile != NULL) { 2699feb4ecdbSBruce M Simpson /* 2700feb4ecdbSBruce M Simpson * 0 means EOF, so don't loop if we get 0. 2701feb4ecdbSBruce M Simpson */ 2702a4b5b39fSBill Fenner n = pcap_offline_read(p, cnt, callback, user); 2703feb4ecdbSBruce M Simpson } else { 2704a4b5b39fSBill Fenner /* 2705a4b5b39fSBill Fenner * XXX keep reading until we get something 2706a4b5b39fSBill Fenner * (or an error occurs) 2707a4b5b39fSBill Fenner */ 2708a4b5b39fSBill Fenner do { 2709feb4ecdbSBruce M Simpson n = p->read_op(p, cnt, callback, user); 2710a4b5b39fSBill Fenner } while (n == 0); 2711a4b5b39fSBill Fenner } 27128cf6c252SPaul Traina if (n <= 0) 27138cf6c252SPaul Traina return (n); 2714681ed54cSXin LI if (!PACKET_COUNT_IS_UNLIMITED(cnt)) { 27158cf6c252SPaul Traina cnt -= n; 27168cf6c252SPaul Traina if (cnt <= 0) 27178cf6c252SPaul Traina return (0); 27188cf6c252SPaul Traina } 27198cf6c252SPaul Traina } 27208cf6c252SPaul Traina } 27218cf6c252SPaul Traina 2722feb4ecdbSBruce M Simpson /* 2723feb4ecdbSBruce M Simpson * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate. 2724feb4ecdbSBruce M Simpson */ 2725feb4ecdbSBruce M Simpson void 2726feb4ecdbSBruce M Simpson pcap_breakloop(pcap_t *p) 2727feb4ecdbSBruce M Simpson { 2728feb4ecdbSBruce M Simpson p->break_loop = 1; 2729feb4ecdbSBruce M Simpson } 2730feb4ecdbSBruce M Simpson 27318cf6c252SPaul Traina int 27328cf6c252SPaul Traina pcap_datalink(pcap_t *p) 27338cf6c252SPaul Traina { 2734681ed54cSXin LI if (!p->activated) 2735681ed54cSXin LI return (PCAP_ERROR_NOT_ACTIVATED); 27368cf6c252SPaul Traina return (p->linktype); 27378cf6c252SPaul Traina } 27388cf6c252SPaul Traina 27398cf6c252SPaul Traina int 2740a8e07101SRui Paulo pcap_datalink_ext(pcap_t *p) 2741a8e07101SRui Paulo { 2742681ed54cSXin LI if (!p->activated) 2743681ed54cSXin LI return (PCAP_ERROR_NOT_ACTIVATED); 2744a8e07101SRui Paulo return (p->linktype_ext); 2745a8e07101SRui Paulo } 2746a8e07101SRui Paulo 2747a8e07101SRui Paulo int 274809f33d61SBill Fenner pcap_list_datalinks(pcap_t *p, int **dlt_buffer) 274909f33d61SBill Fenner { 2750681ed54cSXin LI if (!p->activated) 2751681ed54cSXin LI return (PCAP_ERROR_NOT_ACTIVATED); 2752feb4ecdbSBruce M Simpson if (p->dlt_count == 0) { 2753feb4ecdbSBruce M Simpson /* 2754feb4ecdbSBruce M Simpson * We couldn't fetch the list of DLTs, which means 2755feb4ecdbSBruce M Simpson * this platform doesn't support changing the 2756feb4ecdbSBruce M Simpson * DLT for an interface. Return a list of DLTs 2757feb4ecdbSBruce M Simpson * containing only the DLT this device supports. 2758feb4ecdbSBruce M Simpson */ 2759feb4ecdbSBruce M Simpson *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer)); 2760feb4ecdbSBruce M Simpson if (*dlt_buffer == NULL) { 2761b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 2762b00ab754SHans Petter Selasky errno, "malloc"); 2763681ed54cSXin LI return (PCAP_ERROR); 276409f33d61SBill Fenner } 2765feb4ecdbSBruce M Simpson **dlt_buffer = p->linktype; 2766feb4ecdbSBruce M Simpson return (1); 2767feb4ecdbSBruce M Simpson } else { 2768ef96d74fSMax Laier *dlt_buffer = (int*)calloc(sizeof(**dlt_buffer), p->dlt_count); 276909f33d61SBill Fenner if (*dlt_buffer == NULL) { 2770b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 2771b00ab754SHans Petter Selasky errno, "malloc"); 2772681ed54cSXin LI return (PCAP_ERROR); 277309f33d61SBill Fenner } 277409f33d61SBill Fenner (void)memcpy(*dlt_buffer, p->dlt_list, 277509f33d61SBill Fenner sizeof(**dlt_buffer) * p->dlt_count); 277609f33d61SBill Fenner return (p->dlt_count); 277709f33d61SBill Fenner } 2778feb4ecdbSBruce M Simpson } 2779feb4ecdbSBruce M Simpson 2780a8e07101SRui Paulo /* 2781a8e07101SRui Paulo * In Windows, you might have a library built with one version of the 2782a8e07101SRui Paulo * C runtime library and an application built with another version of 2783a8e07101SRui Paulo * the C runtime library, which means that the library might use one 2784a8e07101SRui Paulo * version of malloc() and free() and the application might use another 2785a8e07101SRui Paulo * version of malloc() and free(). If so, that means something 2786a8e07101SRui Paulo * allocated by the library cannot be freed by the application, so we 2787a8e07101SRui Paulo * need to have a pcap_free_datalinks() routine to free up the list 2788a8e07101SRui Paulo * allocated by pcap_list_datalinks(), even though it's just a wrapper 2789a8e07101SRui Paulo * around free(). 2790a8e07101SRui Paulo */ 2791a8e07101SRui Paulo void 2792a8e07101SRui Paulo pcap_free_datalinks(int *dlt_list) 2793a8e07101SRui Paulo { 2794a8e07101SRui Paulo free(dlt_list); 2795a8e07101SRui Paulo } 2796a8e07101SRui Paulo 2797feb4ecdbSBruce M Simpson int 2798feb4ecdbSBruce M Simpson pcap_set_datalink(pcap_t *p, int dlt) 2799feb4ecdbSBruce M Simpson { 2800feb4ecdbSBruce M Simpson int i; 2801feb4ecdbSBruce M Simpson const char *dlt_name; 2802feb4ecdbSBruce M Simpson 2803ada6f083SXin LI if (dlt < 0) 2804ada6f083SXin LI goto unsupported; 2805ada6f083SXin LI 2806feb4ecdbSBruce M Simpson if (p->dlt_count == 0 || p->set_datalink_op == NULL) { 2807feb4ecdbSBruce M Simpson /* 2808feb4ecdbSBruce M Simpson * We couldn't fetch the list of DLTs, or we don't 2809feb4ecdbSBruce M Simpson * have a "set datalink" operation, which means 2810feb4ecdbSBruce M Simpson * this platform doesn't support changing the 2811feb4ecdbSBruce M Simpson * DLT for an interface. Check whether the new 2812feb4ecdbSBruce M Simpson * DLT is the one this interface supports. 2813feb4ecdbSBruce M Simpson */ 2814feb4ecdbSBruce M Simpson if (p->linktype != dlt) 2815feb4ecdbSBruce M Simpson goto unsupported; 2816feb4ecdbSBruce M Simpson 2817feb4ecdbSBruce M Simpson /* 2818feb4ecdbSBruce M Simpson * It is, so there's nothing we need to do here. 2819feb4ecdbSBruce M Simpson */ 2820feb4ecdbSBruce M Simpson return (0); 2821feb4ecdbSBruce M Simpson } 2822feb4ecdbSBruce M Simpson for (i = 0; i < p->dlt_count; i++) 2823ada6f083SXin LI if (p->dlt_list[i] == (u_int)dlt) 2824feb4ecdbSBruce M Simpson break; 2825feb4ecdbSBruce M Simpson if (i >= p->dlt_count) 2826feb4ecdbSBruce M Simpson goto unsupported; 282704fb2745SSam Leffler if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB && 282804fb2745SSam Leffler dlt == DLT_DOCSIS) { 282904fb2745SSam Leffler /* 283004fb2745SSam Leffler * This is presumably an Ethernet device, as the first 283104fb2745SSam Leffler * link-layer type it offers is DLT_EN10MB, and the only 283204fb2745SSam Leffler * other type it offers is DLT_DOCSIS. That means that 283304fb2745SSam Leffler * we can't tell the driver to supply DOCSIS link-layer 283404fb2745SSam Leffler * headers - we're just pretending that's what we're 283504fb2745SSam Leffler * getting, as, presumably, we're capturing on a dedicated 283604fb2745SSam Leffler * link to a Cisco Cable Modem Termination System, and 283704fb2745SSam Leffler * it's putting raw DOCSIS frames on the wire inside low-level 283804fb2745SSam Leffler * Ethernet framing. 283904fb2745SSam Leffler */ 284004fb2745SSam Leffler p->linktype = dlt; 284104fb2745SSam Leffler return (0); 284204fb2745SSam Leffler } 2843feb4ecdbSBruce M Simpson if (p->set_datalink_op(p, dlt) == -1) 2844feb4ecdbSBruce M Simpson return (-1); 2845feb4ecdbSBruce M Simpson p->linktype = dlt; 2846feb4ecdbSBruce M Simpson return (0); 2847feb4ecdbSBruce M Simpson 2848feb4ecdbSBruce M Simpson unsupported: 2849feb4ecdbSBruce M Simpson dlt_name = pcap_datalink_val_to_name(dlt); 2850feb4ecdbSBruce M Simpson if (dlt_name != NULL) { 2851ada6f083SXin LI (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf), 2852feb4ecdbSBruce M Simpson "%s is not one of the DLTs supported by this device", 2853feb4ecdbSBruce M Simpson dlt_name); 2854feb4ecdbSBruce M Simpson } else { 2855ada6f083SXin LI (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf), 2856feb4ecdbSBruce M Simpson "DLT %d is not one of the DLTs supported by this device", 2857feb4ecdbSBruce M Simpson dlt); 2858feb4ecdbSBruce M Simpson } 2859feb4ecdbSBruce M Simpson return (-1); 2860feb4ecdbSBruce M Simpson } 2861feb4ecdbSBruce M Simpson 2862feb4ecdbSBruce M Simpson /* 2863feb4ecdbSBruce M Simpson * This array is designed for mapping upper and lower case letter 2864feb4ecdbSBruce M Simpson * together for a case independent comparison. The mappings are 2865feb4ecdbSBruce M Simpson * based upon ascii character sequences. 2866feb4ecdbSBruce M Simpson */ 2867feb4ecdbSBruce M Simpson static const u_char charmap[] = { 2868feb4ecdbSBruce M Simpson (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003', 2869feb4ecdbSBruce M Simpson (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007', 2870feb4ecdbSBruce M Simpson (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013', 2871feb4ecdbSBruce M Simpson (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017', 2872feb4ecdbSBruce M Simpson (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023', 2873feb4ecdbSBruce M Simpson (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027', 2874feb4ecdbSBruce M Simpson (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033', 2875feb4ecdbSBruce M Simpson (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037', 2876feb4ecdbSBruce M Simpson (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043', 2877feb4ecdbSBruce M Simpson (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047', 2878feb4ecdbSBruce M Simpson (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053', 2879feb4ecdbSBruce M Simpson (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057', 2880feb4ecdbSBruce M Simpson (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063', 2881feb4ecdbSBruce M Simpson (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067', 2882feb4ecdbSBruce M Simpson (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073', 2883feb4ecdbSBruce M Simpson (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077', 2884feb4ecdbSBruce M Simpson (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143', 2885feb4ecdbSBruce M Simpson (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', 2886feb4ecdbSBruce M Simpson (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', 2887feb4ecdbSBruce M Simpson (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', 2888feb4ecdbSBruce M Simpson (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', 2889feb4ecdbSBruce M Simpson (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', 2890feb4ecdbSBruce M Simpson (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133', 2891feb4ecdbSBruce M Simpson (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137', 2892feb4ecdbSBruce M Simpson (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143', 2893feb4ecdbSBruce M Simpson (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', 2894feb4ecdbSBruce M Simpson (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', 2895feb4ecdbSBruce M Simpson (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', 2896feb4ecdbSBruce M Simpson (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', 2897feb4ecdbSBruce M Simpson (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', 2898feb4ecdbSBruce M Simpson (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173', 2899feb4ecdbSBruce M Simpson (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177', 2900feb4ecdbSBruce M Simpson (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203', 2901feb4ecdbSBruce M Simpson (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207', 2902feb4ecdbSBruce M Simpson (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213', 2903feb4ecdbSBruce M Simpson (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217', 2904feb4ecdbSBruce M Simpson (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223', 2905feb4ecdbSBruce M Simpson (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227', 2906feb4ecdbSBruce M Simpson (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233', 2907feb4ecdbSBruce M Simpson (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237', 2908feb4ecdbSBruce M Simpson (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243', 2909feb4ecdbSBruce M Simpson (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247', 2910feb4ecdbSBruce M Simpson (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253', 2911feb4ecdbSBruce M Simpson (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257', 2912feb4ecdbSBruce M Simpson (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263', 2913feb4ecdbSBruce M Simpson (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267', 2914feb4ecdbSBruce M Simpson (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273', 2915feb4ecdbSBruce M Simpson (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277', 2916feb4ecdbSBruce M Simpson (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343', 2917feb4ecdbSBruce M Simpson (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', 2918feb4ecdbSBruce M Simpson (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', 2919feb4ecdbSBruce M Simpson (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', 2920feb4ecdbSBruce M Simpson (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', 2921feb4ecdbSBruce M Simpson (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', 2922feb4ecdbSBruce M Simpson (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333', 2923feb4ecdbSBruce M Simpson (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337', 2924feb4ecdbSBruce M Simpson (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343', 2925feb4ecdbSBruce M Simpson (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', 2926feb4ecdbSBruce M Simpson (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', 2927feb4ecdbSBruce M Simpson (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', 2928feb4ecdbSBruce M Simpson (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', 2929feb4ecdbSBruce M Simpson (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', 2930feb4ecdbSBruce M Simpson (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373', 2931feb4ecdbSBruce M Simpson (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377', 2932feb4ecdbSBruce M Simpson }; 2933feb4ecdbSBruce M Simpson 2934feb4ecdbSBruce M Simpson int 2935feb4ecdbSBruce M Simpson pcap_strcasecmp(const char *s1, const char *s2) 2936feb4ecdbSBruce M Simpson { 2937feb4ecdbSBruce M Simpson register const u_char *cm = charmap, 2938ef96d74fSMax Laier *us1 = (const u_char *)s1, 2939ef96d74fSMax Laier *us2 = (const u_char *)s2; 2940feb4ecdbSBruce M Simpson 2941feb4ecdbSBruce M Simpson while (cm[*us1] == cm[*us2++]) 2942feb4ecdbSBruce M Simpson if (*us1++ == '\0') 2943feb4ecdbSBruce M Simpson return(0); 2944feb4ecdbSBruce M Simpson return (cm[*us1] - cm[*--us2]); 2945feb4ecdbSBruce M Simpson } 2946feb4ecdbSBruce M Simpson 2947d1e87331SXin LI struct dlt_choice { 2948d1e87331SXin LI const char *name; 2949d1e87331SXin LI const char *description; 2950d1e87331SXin LI int dlt; 2951d1e87331SXin LI }; 2952d1e87331SXin LI 2953ada6f083SXin LI #define DLT_CHOICE(code, description) { #code, description, DLT_ ## code } 2954d1e87331SXin LI #define DLT_CHOICE_SENTINEL { NULL, NULL, 0 } 2955d1e87331SXin LI 2956d1e87331SXin LI static struct dlt_choice dlt_choices[] = { 2957ada6f083SXin LI DLT_CHOICE(NULL, "BSD loopback"), 2958ada6f083SXin LI DLT_CHOICE(EN10MB, "Ethernet"), 2959ada6f083SXin LI DLT_CHOICE(IEEE802, "Token ring"), 2960ada6f083SXin LI DLT_CHOICE(ARCNET, "BSD ARCNET"), 2961ada6f083SXin LI DLT_CHOICE(SLIP, "SLIP"), 2962ada6f083SXin LI DLT_CHOICE(PPP, "PPP"), 2963ada6f083SXin LI DLT_CHOICE(FDDI, "FDDI"), 2964ada6f083SXin LI DLT_CHOICE(ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"), 2965ada6f083SXin LI DLT_CHOICE(RAW, "Raw IP"), 2966ada6f083SXin LI DLT_CHOICE(SLIP_BSDOS, "BSD/OS SLIP"), 2967ada6f083SXin LI DLT_CHOICE(PPP_BSDOS, "BSD/OS PPP"), 2968ada6f083SXin LI DLT_CHOICE(ATM_CLIP, "Linux Classical IP-over-ATM"), 2969ada6f083SXin LI DLT_CHOICE(PPP_SERIAL, "PPP over serial"), 2970ada6f083SXin LI DLT_CHOICE(PPP_ETHER, "PPPoE"), 2971ada6f083SXin LI DLT_CHOICE(SYMANTEC_FIREWALL, "Symantec Firewall"), 2972ada6f083SXin LI DLT_CHOICE(C_HDLC, "Cisco HDLC"), 2973ada6f083SXin LI DLT_CHOICE(IEEE802_11, "802.11"), 2974ada6f083SXin LI DLT_CHOICE(FRELAY, "Frame Relay"), 2975ada6f083SXin LI DLT_CHOICE(LOOP, "OpenBSD loopback"), 2976ada6f083SXin LI DLT_CHOICE(ENC, "OpenBSD encapsulated IP"), 2977*57e22627SCy Schubert DLT_CHOICE(LINUX_SLL, "Linux cooked v1"), 2978ada6f083SXin LI DLT_CHOICE(LTALK, "Localtalk"), 2979ada6f083SXin LI DLT_CHOICE(PFLOG, "OpenBSD pflog file"), 2980ada6f083SXin LI DLT_CHOICE(PFSYNC, "Packet filter state syncing"), 2981ada6f083SXin LI DLT_CHOICE(PRISM_HEADER, "802.11 plus Prism header"), 2982ada6f083SXin LI DLT_CHOICE(IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"), 2983ada6f083SXin LI DLT_CHOICE(SUNATM, "Sun raw ATM"), 2984ada6f083SXin LI DLT_CHOICE(IEEE802_11_RADIO, "802.11 plus radiotap header"), 2985ada6f083SXin LI DLT_CHOICE(ARCNET_LINUX, "Linux ARCNET"), 2986ada6f083SXin LI DLT_CHOICE(JUNIPER_MLPPP, "Juniper Multi-Link PPP"), 2987ada6f083SXin LI DLT_CHOICE(JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"), 2988ada6f083SXin LI DLT_CHOICE(JUNIPER_ES, "Juniper Encryption Services PIC"), 2989ada6f083SXin LI DLT_CHOICE(JUNIPER_GGSN, "Juniper GGSN PIC"), 2990ada6f083SXin LI DLT_CHOICE(JUNIPER_MFR, "Juniper FRF.16 Frame Relay"), 2991ada6f083SXin LI DLT_CHOICE(JUNIPER_ATM2, "Juniper ATM2 PIC"), 2992ada6f083SXin LI DLT_CHOICE(JUNIPER_SERVICES, "Juniper Advanced Services PIC"), 2993ada6f083SXin LI DLT_CHOICE(JUNIPER_ATM1, "Juniper ATM1 PIC"), 2994ada6f083SXin LI DLT_CHOICE(APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"), 2995ada6f083SXin LI DLT_CHOICE(MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"), 2996ada6f083SXin LI DLT_CHOICE(MTP2, "SS7 MTP2"), 2997ada6f083SXin LI DLT_CHOICE(MTP3, "SS7 MTP3"), 2998ada6f083SXin LI DLT_CHOICE(SCCP, "SS7 SCCP"), 2999ada6f083SXin LI DLT_CHOICE(DOCSIS, "DOCSIS"), 3000ada6f083SXin LI DLT_CHOICE(LINUX_IRDA, "Linux IrDA"), 3001ada6f083SXin LI DLT_CHOICE(IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"), 3002ada6f083SXin LI DLT_CHOICE(JUNIPER_MONITOR, "Juniper Passive Monitor PIC"), 3003ada6f083SXin LI DLT_CHOICE(BACNET_MS_TP, "BACnet MS/TP"), 3004ada6f083SXin LI DLT_CHOICE(PPP_PPPD, "PPP for pppd, with direction flag"), 3005ada6f083SXin LI DLT_CHOICE(JUNIPER_PPPOE, "Juniper PPPoE"), 3006ada6f083SXin LI DLT_CHOICE(JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"), 3007ada6f083SXin LI DLT_CHOICE(GPRS_LLC, "GPRS LLC"), 3008ada6f083SXin LI DLT_CHOICE(GPF_T, "GPF-T"), 3009ada6f083SXin LI DLT_CHOICE(GPF_F, "GPF-F"), 3010ada6f083SXin LI DLT_CHOICE(JUNIPER_PIC_PEER, "Juniper PIC Peer"), 3011ada6f083SXin LI DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"), 3012ada6f083SXin LI DLT_CHOICE(ERF_POS, "Packet-over-SONET with Endace ERF header"), 3013ada6f083SXin LI DLT_CHOICE(LINUX_LAPD, "Linux vISDN LAPD"), 3014ada6f083SXin LI DLT_CHOICE(JUNIPER_ETHER, "Juniper Ethernet"), 3015ada6f083SXin LI DLT_CHOICE(JUNIPER_PPP, "Juniper PPP"), 3016ada6f083SXin LI DLT_CHOICE(JUNIPER_FRELAY, "Juniper Frame Relay"), 3017ada6f083SXin LI DLT_CHOICE(JUNIPER_CHDLC, "Juniper C-HDLC"), 3018ada6f083SXin LI DLT_CHOICE(MFR, "FRF.16 Frame Relay"), 3019ada6f083SXin LI DLT_CHOICE(JUNIPER_VP, "Juniper Voice PIC"), 3020ada6f083SXin LI DLT_CHOICE(A429, "Arinc 429"), 3021ada6f083SXin LI DLT_CHOICE(A653_ICM, "Arinc 653 Interpartition Communication"), 3022ada6f083SXin LI DLT_CHOICE(USB_FREEBSD, "USB with FreeBSD header"), 3023ada6f083SXin LI DLT_CHOICE(BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"), 3024ada6f083SXin LI DLT_CHOICE(IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"), 3025ada6f083SXin LI DLT_CHOICE(USB_LINUX, "USB with Linux header"), 3026ada6f083SXin LI DLT_CHOICE(CAN20B, "Controller Area Network (CAN) v. 2.0B"), 3027ada6f083SXin LI DLT_CHOICE(IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"), 3028ada6f083SXin LI DLT_CHOICE(PPI, "Per-Packet Information"), 3029ada6f083SXin LI DLT_CHOICE(IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"), 3030ada6f083SXin LI DLT_CHOICE(JUNIPER_ISM, "Juniper Integrated Service Module"), 3031ada6f083SXin LI DLT_CHOICE(IEEE802_15_4, "IEEE 802.15.4 with FCS"), 3032ada6f083SXin LI DLT_CHOICE(SITA, "SITA pseudo-header"), 3033ada6f083SXin LI DLT_CHOICE(ERF, "Endace ERF header"), 3034ada6f083SXin LI DLT_CHOICE(RAIF1, "Ethernet with u10 Networks pseudo-header"), 3035*57e22627SCy Schubert DLT_CHOICE(IPMB_KONTRON, "IPMB with Kontron pseudo-header"), 3036ada6f083SXin LI DLT_CHOICE(JUNIPER_ST, "Juniper Secure Tunnel"), 3037ada6f083SXin LI DLT_CHOICE(BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"), 3038ada6f083SXin LI DLT_CHOICE(AX25_KISS, "AX.25 with KISS header"), 3039*57e22627SCy Schubert DLT_CHOICE(IPMB_LINUX, "IPMB with Linux/Pigeon Point pseudo-header"), 3040ada6f083SXin LI DLT_CHOICE(IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"), 3041ada6f083SXin LI DLT_CHOICE(MPLS, "MPLS with label as link-layer header"), 3042ada6f083SXin LI DLT_CHOICE(LINUX_EVDEV, "Linux evdev events"), 3043ada6f083SXin LI DLT_CHOICE(USB_LINUX_MMAPPED, "USB with padded Linux header"), 3044ada6f083SXin LI DLT_CHOICE(DECT, "DECT"), 3045ada6f083SXin LI DLT_CHOICE(AOS, "AOS Space Data Link protocol"), 3046ada6f083SXin LI DLT_CHOICE(WIHART, "Wireless HART"), 3047ada6f083SXin LI DLT_CHOICE(FC_2, "Fibre Channel FC-2"), 3048ada6f083SXin LI DLT_CHOICE(FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"), 3049ada6f083SXin LI DLT_CHOICE(IPNET, "Solaris ipnet"), 3050ada6f083SXin LI DLT_CHOICE(CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"), 3051ada6f083SXin LI DLT_CHOICE(IPV4, "Raw IPv4"), 3052ada6f083SXin LI DLT_CHOICE(IPV6, "Raw IPv6"), 3053ada6f083SXin LI DLT_CHOICE(IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"), 3054ada6f083SXin LI DLT_CHOICE(DBUS, "D-Bus"), 3055ada6f083SXin LI DLT_CHOICE(JUNIPER_VS, "Juniper Virtual Server"), 3056ada6f083SXin LI DLT_CHOICE(JUNIPER_SRX_E2E, "Juniper SRX E2E"), 3057ada6f083SXin LI DLT_CHOICE(JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"), 3058ada6f083SXin LI DLT_CHOICE(DVB_CI, "DVB-CI"), 3059ada6f083SXin LI DLT_CHOICE(MUX27010, "MUX27010"), 3060ada6f083SXin LI DLT_CHOICE(STANAG_5066_D_PDU, "STANAG 5066 D_PDUs"), 3061ada6f083SXin LI DLT_CHOICE(JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"), 3062ada6f083SXin LI DLT_CHOICE(NFLOG, "Linux netfilter log messages"), 3063ada6f083SXin LI DLT_CHOICE(NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"), 3064ada6f083SXin LI DLT_CHOICE(NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"), 3065ada6f083SXin LI DLT_CHOICE(IPOIB, "RFC 4391 IP-over-Infiniband"), 3066ada6f083SXin LI DLT_CHOICE(MPEG_2_TS, "MPEG-2 transport stream"), 3067ada6f083SXin LI DLT_CHOICE(NG40, "ng40 protocol tester Iub/Iur"), 3068ada6f083SXin LI DLT_CHOICE(NFC_LLCP, "NFC LLCP PDUs with pseudo-header"), 3069ada6f083SXin LI DLT_CHOICE(INFINIBAND, "InfiniBand"), 3070ada6f083SXin LI DLT_CHOICE(SCTP, "SCTP"), 3071ada6f083SXin LI DLT_CHOICE(USBPCAP, "USB with USBPcap header"), 3072ada6f083SXin LI DLT_CHOICE(RTAC_SERIAL, "Schweitzer Engineering Laboratories RTAC packets"), 3073ada6f083SXin LI DLT_CHOICE(BLUETOOTH_LE_LL, "Bluetooth Low Energy air interface"), 3074ada6f083SXin LI DLT_CHOICE(NETLINK, "Linux netlink"), 3075ada6f083SXin LI DLT_CHOICE(BLUETOOTH_LINUX_MONITOR, "Bluetooth Linux Monitor"), 3076ada6f083SXin LI DLT_CHOICE(BLUETOOTH_BREDR_BB, "Bluetooth Basic Rate/Enhanced Data Rate baseband packets"), 3077ada6f083SXin LI DLT_CHOICE(BLUETOOTH_LE_LL_WITH_PHDR, "Bluetooth Low Energy air interface with pseudo-header"), 3078ada6f083SXin LI DLT_CHOICE(PROFIBUS_DL, "PROFIBUS data link layer"), 3079ada6f083SXin LI DLT_CHOICE(PKTAP, "Apple DLT_PKTAP"), 3080ada6f083SXin LI DLT_CHOICE(EPON, "Ethernet with 802.3 Clause 65 EPON preamble"), 3081ada6f083SXin LI DLT_CHOICE(IPMI_HPM_2, "IPMI trace packets"), 3082ada6f083SXin LI DLT_CHOICE(ZWAVE_R1_R2, "Z-Wave RF profile R1 and R2 packets"), 3083ada6f083SXin LI DLT_CHOICE(ZWAVE_R3, "Z-Wave RF profile R3 packets"), 3084ada6f083SXin LI DLT_CHOICE(WATTSTOPPER_DLM, "WattStopper Digital Lighting Management (DLM) and Legrand Nitoo Open protocol"), 3085ada6f083SXin LI DLT_CHOICE(ISO_14443, "ISO 14443 messages"), 3086ada6f083SXin LI DLT_CHOICE(RDS, "IEC 62106 Radio Data System groups"), 3087b00ab754SHans Petter Selasky DLT_CHOICE(USB_DARWIN, "USB with Darwin header"), 3088b00ab754SHans Petter Selasky DLT_CHOICE(OPENFLOW, "OpenBSD DLT_OPENFLOW"), 3089b00ab754SHans Petter Selasky DLT_CHOICE(SDLC, "IBM SDLC frames"), 3090b00ab754SHans Petter Selasky DLT_CHOICE(TI_LLN_SNIFFER, "TI LLN sniffer frames"), 3091b00ab754SHans Petter Selasky DLT_CHOICE(VSOCK, "Linux vsock"), 3092b00ab754SHans Petter Selasky DLT_CHOICE(NORDIC_BLE, "Nordic Semiconductor Bluetooth LE sniffer frames"), 3093b00ab754SHans Petter Selasky DLT_CHOICE(DOCSIS31_XRA31, "Excentis XRA-31 DOCSIS 3.1 RF sniffer frames"), 3094b00ab754SHans Petter Selasky DLT_CHOICE(ETHERNET_MPACKET, "802.3br mPackets"), 3095b00ab754SHans Petter Selasky DLT_CHOICE(DISPLAYPORT_AUX, "DisplayPort AUX channel monitoring data"), 3096*57e22627SCy Schubert DLT_CHOICE(LINUX_SLL2, "Linux cooked v2"), 3097d1e87331SXin LI DLT_CHOICE_SENTINEL 3098d1e87331SXin LI }; 3099d1e87331SXin LI 3100feb4ecdbSBruce M Simpson int 3101feb4ecdbSBruce M Simpson pcap_datalink_name_to_val(const char *name) 3102feb4ecdbSBruce M Simpson { 3103feb4ecdbSBruce M Simpson int i; 3104feb4ecdbSBruce M Simpson 3105feb4ecdbSBruce M Simpson for (i = 0; dlt_choices[i].name != NULL; i++) { 3106ada6f083SXin LI if (pcap_strcasecmp(dlt_choices[i].name, name) == 0) 3107feb4ecdbSBruce M Simpson return (dlt_choices[i].dlt); 3108feb4ecdbSBruce M Simpson } 3109feb4ecdbSBruce M Simpson return (-1); 3110feb4ecdbSBruce M Simpson } 3111feb4ecdbSBruce M Simpson 3112feb4ecdbSBruce M Simpson const char * 3113feb4ecdbSBruce M Simpson pcap_datalink_val_to_name(int dlt) 3114feb4ecdbSBruce M Simpson { 3115feb4ecdbSBruce M Simpson int i; 3116feb4ecdbSBruce M Simpson 3117feb4ecdbSBruce M Simpson for (i = 0; dlt_choices[i].name != NULL; i++) { 3118feb4ecdbSBruce M Simpson if (dlt_choices[i].dlt == dlt) 3119ada6f083SXin LI return (dlt_choices[i].name); 3120feb4ecdbSBruce M Simpson } 3121feb4ecdbSBruce M Simpson return (NULL); 3122feb4ecdbSBruce M Simpson } 3123feb4ecdbSBruce M Simpson 3124feb4ecdbSBruce M Simpson const char * 3125feb4ecdbSBruce M Simpson pcap_datalink_val_to_description(int dlt) 3126feb4ecdbSBruce M Simpson { 3127feb4ecdbSBruce M Simpson int i; 3128feb4ecdbSBruce M Simpson 3129feb4ecdbSBruce M Simpson for (i = 0; dlt_choices[i].name != NULL; i++) { 3130feb4ecdbSBruce M Simpson if (dlt_choices[i].dlt == dlt) 3131feb4ecdbSBruce M Simpson return (dlt_choices[i].description); 3132feb4ecdbSBruce M Simpson } 3133feb4ecdbSBruce M Simpson return (NULL); 3134feb4ecdbSBruce M Simpson } 313509f33d61SBill Fenner 3136*57e22627SCy Schubert const char * 3137*57e22627SCy Schubert pcap_datalink_val_to_description_or_dlt(int dlt) 3138*57e22627SCy Schubert { 3139*57e22627SCy Schubert static char unkbuf[40]; 3140*57e22627SCy Schubert const char *description; 3141*57e22627SCy Schubert 3142*57e22627SCy Schubert description = pcap_datalink_val_to_description(dlt); 3143*57e22627SCy Schubert if (description != NULL) { 3144*57e22627SCy Schubert return description; 3145*57e22627SCy Schubert } else { 3146*57e22627SCy Schubert (void)pcap_snprintf(unkbuf, sizeof(unkbuf), "DLT %u", dlt); 3147*57e22627SCy Schubert return unkbuf; 3148*57e22627SCy Schubert } 3149*57e22627SCy Schubert } 3150*57e22627SCy Schubert 3151d1e87331SXin LI struct tstamp_type_choice { 3152d1e87331SXin LI const char *name; 3153d1e87331SXin LI const char *description; 3154d1e87331SXin LI int type; 3155d1e87331SXin LI }; 3156d1e87331SXin LI 3157d1e87331SXin LI static struct tstamp_type_choice tstamp_type_choices[] = { 3158d1e87331SXin LI { "host", "Host", PCAP_TSTAMP_HOST }, 3159d1e87331SXin LI { "host_lowprec", "Host, low precision", PCAP_TSTAMP_HOST_LOWPREC }, 3160d1e87331SXin LI { "host_hiprec", "Host, high precision", PCAP_TSTAMP_HOST_HIPREC }, 3161d1e87331SXin LI { "adapter", "Adapter", PCAP_TSTAMP_ADAPTER }, 3162d1e87331SXin LI { "adapter_unsynced", "Adapter, not synced with system time", PCAP_TSTAMP_ADAPTER_UNSYNCED }, 3163d1e87331SXin LI { NULL, NULL, 0 } 3164d1e87331SXin LI }; 3165d1e87331SXin LI 3166d1e87331SXin LI int 3167d1e87331SXin LI pcap_tstamp_type_name_to_val(const char *name) 3168d1e87331SXin LI { 3169d1e87331SXin LI int i; 3170d1e87331SXin LI 3171d1e87331SXin LI for (i = 0; tstamp_type_choices[i].name != NULL; i++) { 3172d1e87331SXin LI if (pcap_strcasecmp(tstamp_type_choices[i].name, name) == 0) 3173d1e87331SXin LI return (tstamp_type_choices[i].type); 3174d1e87331SXin LI } 3175d1e87331SXin LI return (PCAP_ERROR); 3176d1e87331SXin LI } 3177d1e87331SXin LI 3178d1e87331SXin LI const char * 3179d1e87331SXin LI pcap_tstamp_type_val_to_name(int tstamp_type) 3180d1e87331SXin LI { 3181d1e87331SXin LI int i; 3182d1e87331SXin LI 3183d1e87331SXin LI for (i = 0; tstamp_type_choices[i].name != NULL; i++) { 3184d1e87331SXin LI if (tstamp_type_choices[i].type == tstamp_type) 3185d1e87331SXin LI return (tstamp_type_choices[i].name); 3186d1e87331SXin LI } 3187d1e87331SXin LI return (NULL); 3188d1e87331SXin LI } 3189d1e87331SXin LI 3190d1e87331SXin LI const char * 3191d1e87331SXin LI pcap_tstamp_type_val_to_description(int tstamp_type) 3192d1e87331SXin LI { 3193d1e87331SXin LI int i; 3194d1e87331SXin LI 3195d1e87331SXin LI for (i = 0; tstamp_type_choices[i].name != NULL; i++) { 3196d1e87331SXin LI if (tstamp_type_choices[i].type == tstamp_type) 3197d1e87331SXin LI return (tstamp_type_choices[i].description); 3198d1e87331SXin LI } 3199d1e87331SXin LI return (NULL); 3200d1e87331SXin LI } 3201d1e87331SXin LI 320209f33d61SBill Fenner int 32038cf6c252SPaul Traina pcap_snapshot(pcap_t *p) 32048cf6c252SPaul Traina { 3205681ed54cSXin LI if (!p->activated) 3206681ed54cSXin LI return (PCAP_ERROR_NOT_ACTIVATED); 32078cf6c252SPaul Traina return (p->snapshot); 32088cf6c252SPaul Traina } 32098cf6c252SPaul Traina 32108cf6c252SPaul Traina int 32118cf6c252SPaul Traina pcap_is_swapped(pcap_t *p) 32128cf6c252SPaul Traina { 3213681ed54cSXin LI if (!p->activated) 3214681ed54cSXin LI return (PCAP_ERROR_NOT_ACTIVATED); 3215681ed54cSXin LI return (p->swapped); 32168cf6c252SPaul Traina } 32178cf6c252SPaul Traina 32188cf6c252SPaul Traina int 32198cf6c252SPaul Traina pcap_major_version(pcap_t *p) 32208cf6c252SPaul Traina { 3221681ed54cSXin LI if (!p->activated) 3222681ed54cSXin LI return (PCAP_ERROR_NOT_ACTIVATED); 3223681ed54cSXin LI return (p->version_major); 32248cf6c252SPaul Traina } 32258cf6c252SPaul Traina 32268cf6c252SPaul Traina int 32278cf6c252SPaul Traina pcap_minor_version(pcap_t *p) 32288cf6c252SPaul Traina { 3229681ed54cSXin LI if (!p->activated) 3230681ed54cSXin LI return (PCAP_ERROR_NOT_ACTIVATED); 3231681ed54cSXin LI return (p->version_minor); 32328cf6c252SPaul Traina } 32338cf6c252SPaul Traina 3234b00ab754SHans Petter Selasky int 3235b00ab754SHans Petter Selasky pcap_bufsize(pcap_t *p) 3236b00ab754SHans Petter Selasky { 3237b00ab754SHans Petter Selasky if (!p->activated) 3238b00ab754SHans Petter Selasky return (PCAP_ERROR_NOT_ACTIVATED); 3239b00ab754SHans Petter Selasky return (p->bufsize); 3240b00ab754SHans Petter Selasky } 3241b00ab754SHans Petter Selasky 32428cf6c252SPaul Traina FILE * 32438cf6c252SPaul Traina pcap_file(pcap_t *p) 32448cf6c252SPaul Traina { 3245681ed54cSXin LI return (p->rfile); 32468cf6c252SPaul Traina } 32478cf6c252SPaul Traina 32488cf6c252SPaul Traina int 32498cf6c252SPaul Traina pcap_fileno(pcap_t *p) 32508cf6c252SPaul Traina { 3251ada6f083SXin LI #ifndef _WIN32 32528cf6c252SPaul Traina return (p->fd); 3253feb4ecdbSBruce M Simpson #else 3254b00ab754SHans Petter Selasky if (p->handle != INVALID_HANDLE_VALUE) 3255b00ab754SHans Petter Selasky return ((int)(DWORD)p->handle); 3256feb4ecdbSBruce M Simpson else 3257681ed54cSXin LI return (PCAP_ERROR); 3258feb4ecdbSBruce M Simpson #endif 32598cf6c252SPaul Traina } 32608cf6c252SPaul Traina 3261ada6f083SXin LI #if !defined(_WIN32) && !defined(MSDOS) 3262feb4ecdbSBruce M Simpson int 3263feb4ecdbSBruce M Simpson pcap_get_selectable_fd(pcap_t *p) 3264feb4ecdbSBruce M Simpson { 3265feb4ecdbSBruce M Simpson return (p->selectable_fd); 3266feb4ecdbSBruce M Simpson } 3267b00ab754SHans Petter Selasky 3268b00ab754SHans Petter Selasky struct timeval * 3269b00ab754SHans Petter Selasky pcap_get_required_select_timeout(pcap_t *p) 3270b00ab754SHans Petter Selasky { 3271b00ab754SHans Petter Selasky return (p->required_select_timeout); 3272b00ab754SHans Petter Selasky } 3273feb4ecdbSBruce M Simpson #endif 3274feb4ecdbSBruce M Simpson 32758cf6c252SPaul Traina void 3276ada6f083SXin LI pcap_perror(pcap_t *p, const char *prefix) 32778cf6c252SPaul Traina { 32788cf6c252SPaul Traina fprintf(stderr, "%s: %s\n", prefix, p->errbuf); 32798cf6c252SPaul Traina } 32808cf6c252SPaul Traina 32818cf6c252SPaul Traina char * 32828cf6c252SPaul Traina pcap_geterr(pcap_t *p) 32838cf6c252SPaul Traina { 32848cf6c252SPaul Traina return (p->errbuf); 32858cf6c252SPaul Traina } 32868cf6c252SPaul Traina 32870a94d38fSBill Fenner int 32880a94d38fSBill Fenner pcap_getnonblock(pcap_t *p, char *errbuf) 32890a94d38fSBill Fenner { 3290edc89b24SXin LI int ret; 3291edc89b24SXin LI 3292b00ab754SHans Petter Selasky ret = p->getnonblock_op(p); 3293edc89b24SXin LI if (ret == -1) { 3294edc89b24SXin LI /* 3295b00ab754SHans Petter Selasky * The get nonblock operation sets p->errbuf; this 3296b00ab754SHans Petter Selasky * function *shouldn't* have had a separate errbuf 3297b00ab754SHans Petter Selasky * argument, as it didn't need one, but I goofed 3298b00ab754SHans Petter Selasky * when adding it. 3299b00ab754SHans Petter Selasky * 3300b00ab754SHans Petter Selasky * We copy the error message to errbuf, so callers 3301b00ab754SHans Petter Selasky * can find it in either place. 3302edc89b24SXin LI */ 3303*57e22627SCy Schubert pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE); 3304edc89b24SXin LI } 3305edc89b24SXin LI return (ret); 3306feb4ecdbSBruce M Simpson } 3307feb4ecdbSBruce M Simpson 3308feb4ecdbSBruce M Simpson /* 3309feb4ecdbSBruce M Simpson * Get the current non-blocking mode setting, under the assumption that 3310feb4ecdbSBruce M Simpson * it's just the standard POSIX non-blocking flag. 3311feb4ecdbSBruce M Simpson */ 3312ada6f083SXin LI #if !defined(_WIN32) && !defined(MSDOS) 3313feb4ecdbSBruce M Simpson int 3314b00ab754SHans Petter Selasky pcap_getnonblock_fd(pcap_t *p) 3315feb4ecdbSBruce M Simpson { 33160a94d38fSBill Fenner int fdflags; 33170a94d38fSBill Fenner 33180a94d38fSBill Fenner fdflags = fcntl(p->fd, F_GETFL, 0); 33190a94d38fSBill Fenner if (fdflags == -1) { 3320b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 3321b00ab754SHans Petter Selasky errno, "F_GETFL"); 33220a94d38fSBill Fenner return (-1); 33230a94d38fSBill Fenner } 33240a94d38fSBill Fenner if (fdflags & O_NONBLOCK) 33250a94d38fSBill Fenner return (1); 33260a94d38fSBill Fenner else 33270a94d38fSBill Fenner return (0); 33280a94d38fSBill Fenner } 3329feb4ecdbSBruce M Simpson #endif 33300a94d38fSBill Fenner 33310a94d38fSBill Fenner int 33320a94d38fSBill Fenner pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) 33330a94d38fSBill Fenner { 3334edc89b24SXin LI int ret; 3335edc89b24SXin LI 3336b00ab754SHans Petter Selasky ret = p->setnonblock_op(p, nonblock); 3337edc89b24SXin LI if (ret == -1) { 3338edc89b24SXin LI /* 3339b00ab754SHans Petter Selasky * The set nonblock operation sets p->errbuf; this 3340b00ab754SHans Petter Selasky * function *shouldn't* have had a separate errbuf 3341b00ab754SHans Petter Selasky * argument, as it didn't need one, but I goofed 3342b00ab754SHans Petter Selasky * when adding it. 3343b00ab754SHans Petter Selasky * 3344b00ab754SHans Petter Selasky * We copy the error message to errbuf, so callers 3345b00ab754SHans Petter Selasky * can find it in either place. 3346edc89b24SXin LI */ 3347*57e22627SCy Schubert pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE); 3348edc89b24SXin LI } 3349edc89b24SXin LI return (ret); 3350feb4ecdbSBruce M Simpson } 3351feb4ecdbSBruce M Simpson 3352ada6f083SXin LI #if !defined(_WIN32) && !defined(MSDOS) 3353feb4ecdbSBruce M Simpson /* 3354feb4ecdbSBruce M Simpson * Set non-blocking mode, under the assumption that it's just the 3355feb4ecdbSBruce M Simpson * standard POSIX non-blocking flag. (This can be called by the 3356feb4ecdbSBruce M Simpson * per-platform non-blocking-mode routine if that routine also 3357feb4ecdbSBruce M Simpson * needs to do some additional work.) 3358feb4ecdbSBruce M Simpson */ 3359feb4ecdbSBruce M Simpson int 3360b00ab754SHans Petter Selasky pcap_setnonblock_fd(pcap_t *p, int nonblock) 3361feb4ecdbSBruce M Simpson { 33620a94d38fSBill Fenner int fdflags; 33630a94d38fSBill Fenner 33640a94d38fSBill Fenner fdflags = fcntl(p->fd, F_GETFL, 0); 33650a94d38fSBill Fenner if (fdflags == -1) { 3366b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 3367b00ab754SHans Petter Selasky errno, "F_GETFL"); 33680a94d38fSBill Fenner return (-1); 33690a94d38fSBill Fenner } 33700a94d38fSBill Fenner if (nonblock) 33710a94d38fSBill Fenner fdflags |= O_NONBLOCK; 33720a94d38fSBill Fenner else 33730a94d38fSBill Fenner fdflags &= ~O_NONBLOCK; 33740a94d38fSBill Fenner if (fcntl(p->fd, F_SETFL, fdflags) == -1) { 3375b00ab754SHans Petter Selasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 3376b00ab754SHans Petter Selasky errno, "F_SETFL"); 33770a94d38fSBill Fenner return (-1); 33780a94d38fSBill Fenner } 33790a94d38fSBill Fenner return (0); 33800a94d38fSBill Fenner } 3381feb4ecdbSBruce M Simpson #endif 3382feb4ecdbSBruce M Simpson 33830a94d38fSBill Fenner /* 3384a8e07101SRui Paulo * Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values. 3385a8e07101SRui Paulo */ 3386a8e07101SRui Paulo const char * 3387a8e07101SRui Paulo pcap_statustostr(int errnum) 3388a8e07101SRui Paulo { 3389a8e07101SRui Paulo static char ebuf[15+10+1]; 3390a8e07101SRui Paulo 3391a8e07101SRui Paulo switch (errnum) { 3392a8e07101SRui Paulo 3393a8e07101SRui Paulo case PCAP_WARNING: 3394a8e07101SRui Paulo return("Generic warning"); 3395a8e07101SRui Paulo 3396d1e87331SXin LI case PCAP_WARNING_TSTAMP_TYPE_NOTSUP: 3397d1e87331SXin LI return ("That type of time stamp is not supported by that device"); 3398d1e87331SXin LI 3399a8e07101SRui Paulo case PCAP_WARNING_PROMISC_NOTSUP: 3400a8e07101SRui Paulo return ("That device doesn't support promiscuous mode"); 3401a8e07101SRui Paulo 3402a8e07101SRui Paulo case PCAP_ERROR: 3403a8e07101SRui Paulo return("Generic error"); 3404a8e07101SRui Paulo 3405a8e07101SRui Paulo case PCAP_ERROR_BREAK: 3406a8e07101SRui Paulo return("Loop terminated by pcap_breakloop"); 3407a8e07101SRui Paulo 3408a8e07101SRui Paulo case PCAP_ERROR_NOT_ACTIVATED: 3409a8e07101SRui Paulo return("The pcap_t has not been activated"); 3410a8e07101SRui Paulo 3411a8e07101SRui Paulo case PCAP_ERROR_ACTIVATED: 3412a8e07101SRui Paulo return ("The setting can't be changed after the pcap_t is activated"); 3413a8e07101SRui Paulo 3414a8e07101SRui Paulo case PCAP_ERROR_NO_SUCH_DEVICE: 3415a8e07101SRui Paulo return ("No such device exists"); 3416a8e07101SRui Paulo 3417a8e07101SRui Paulo case PCAP_ERROR_RFMON_NOTSUP: 3418a8e07101SRui Paulo return ("That device doesn't support monitor mode"); 3419a8e07101SRui Paulo 3420a8e07101SRui Paulo case PCAP_ERROR_NOT_RFMON: 3421a8e07101SRui Paulo return ("That operation is supported only in monitor mode"); 3422a8e07101SRui Paulo 3423a8e07101SRui Paulo case PCAP_ERROR_PERM_DENIED: 3424a8e07101SRui Paulo return ("You don't have permission to capture on that device"); 3425a8e07101SRui Paulo 3426a8e07101SRui Paulo case PCAP_ERROR_IFACE_NOT_UP: 3427a8e07101SRui Paulo return ("That device is not up"); 3428d1e87331SXin LI 3429d1e87331SXin LI case PCAP_ERROR_CANTSET_TSTAMP_TYPE: 3430d1e87331SXin LI return ("That device doesn't support setting the time stamp type"); 3431d1e87331SXin LI 3432d1e87331SXin LI case PCAP_ERROR_PROMISC_PERM_DENIED: 3433d1e87331SXin LI return ("You don't have permission to capture in promiscuous mode on that device"); 3434681ed54cSXin LI 3435681ed54cSXin LI case PCAP_ERROR_TSTAMP_PRECISION_NOTSUP: 3436681ed54cSXin LI return ("That device doesn't support that time stamp precision"); 3437a8e07101SRui Paulo } 3438ada6f083SXin LI (void)pcap_snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); 3439a8e07101SRui Paulo return(ebuf); 3440a8e07101SRui Paulo } 3441a8e07101SRui Paulo 3442a8e07101SRui Paulo /* 34438cf6c252SPaul Traina * Not all systems have strerror(). 34448cf6c252SPaul Traina */ 3445ef96d74fSMax Laier const char * 34468cf6c252SPaul Traina pcap_strerror(int errnum) 34478cf6c252SPaul Traina { 34488cf6c252SPaul Traina #ifdef HAVE_STRERROR 3449ada6f083SXin LI #ifdef _WIN32 3450ada6f083SXin LI static char errbuf[PCAP_ERRBUF_SIZE]; 3451b00ab754SHans Petter Selasky errno_t err = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum); 3452b00ab754SHans Petter Selasky 3453b00ab754SHans Petter Selasky if (err != 0) /* err = 0 if successful */ 3454*57e22627SCy Schubert pcap_strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE); 3455ada6f083SXin LI return (errbuf); 3456ada6f083SXin LI #else 34578cf6c252SPaul Traina return (strerror(errnum)); 3458ada6f083SXin LI #endif /* _WIN32 */ 34598cf6c252SPaul Traina #else 34608cf6c252SPaul Traina extern int sys_nerr; 34618cf6c252SPaul Traina extern const char *const sys_errlist[]; 3462ada6f083SXin LI static char errbuf[PCAP_ERRBUF_SIZE]; 34638cf6c252SPaul Traina 34648cf6c252SPaul Traina if ((unsigned int)errnum < sys_nerr) 34658cf6c252SPaul Traina return ((char *)sys_errlist[errnum]); 3466ada6f083SXin LI (void)pcap_snprintf(errbuf, sizeof errbuf, "Unknown error: %d", errnum); 3467ada6f083SXin LI return (errbuf); 34688cf6c252SPaul Traina #endif 34698cf6c252SPaul Traina } 34708cf6c252SPaul Traina 3471feb4ecdbSBruce M Simpson int 3472feb4ecdbSBruce M Simpson pcap_setfilter(pcap_t *p, struct bpf_program *fp) 3473feb4ecdbSBruce M Simpson { 3474d1e87331SXin LI return (p->setfilter_op(p, fp)); 3475feb4ecdbSBruce M Simpson } 3476feb4ecdbSBruce M Simpson 3477ee2dd488SSam Leffler /* 3478ee2dd488SSam Leffler * Set direction flag, which controls whether we accept only incoming 3479ee2dd488SSam Leffler * packets, only outgoing packets, or both. 3480ee2dd488SSam Leffler * Note that, depending on the platform, some or all direction arguments 3481ee2dd488SSam Leffler * might not be supported. 3482ee2dd488SSam Leffler */ 3483ee2dd488SSam Leffler int 34845d18909fSSam Leffler pcap_setdirection(pcap_t *p, pcap_direction_t d) 3485ee2dd488SSam Leffler { 3486ee2dd488SSam Leffler if (p->setdirection_op == NULL) { 3487ada6f083SXin LI pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3488ee2dd488SSam Leffler "Setting direction is not implemented on this platform"); 3489d1e87331SXin LI return (-1); 3490ee2dd488SSam Leffler } else 3491d1e87331SXin LI return (p->setdirection_op(p, d)); 3492ee2dd488SSam Leffler } 3493ee2dd488SSam Leffler 3494feb4ecdbSBruce M Simpson int 3495feb4ecdbSBruce M Simpson pcap_stats(pcap_t *p, struct pcap_stat *ps) 3496feb4ecdbSBruce M Simpson { 3497d1e87331SXin LI return (p->stats_op(p, ps)); 3498feb4ecdbSBruce M Simpson } 3499feb4ecdbSBruce M Simpson 3500ada6f083SXin LI #ifdef _WIN32 3501ada6f083SXin LI struct pcap_stat * 3502ada6f083SXin LI pcap_stats_ex(pcap_t *p, int *pcap_stat_size) 3503ada6f083SXin LI { 3504ada6f083SXin LI return (p->stats_ex_op(p, pcap_stat_size)); 3505ada6f083SXin LI } 3506ada6f083SXin LI 3507a8e07101SRui Paulo int 3508a8e07101SRui Paulo pcap_setbuff(pcap_t *p, int dim) 350904fb2745SSam Leffler { 3510d1e87331SXin LI return (p->setbuff_op(p, dim)); 3511a8e07101SRui Paulo } 3512a8e07101SRui Paulo 3513a8e07101SRui Paulo int 3514a8e07101SRui Paulo pcap_setmode(pcap_t *p, int mode) 3515a8e07101SRui Paulo { 3516d1e87331SXin LI return (p->setmode_op(p, mode)); 3517a8e07101SRui Paulo } 3518a8e07101SRui Paulo 3519a8e07101SRui Paulo int 3520a8e07101SRui Paulo pcap_setmintocopy(pcap_t *p, int size) 3521a8e07101SRui Paulo { 3522d1e87331SXin LI return (p->setmintocopy_op(p, size)); 3523a8e07101SRui Paulo } 3524a8e07101SRui Paulo 3525ada6f083SXin LI HANDLE 3526ada6f083SXin LI pcap_getevent(pcap_t *p) 3527ada6f083SXin LI { 3528ada6f083SXin LI return (p->getevent_op(p)); 3529ada6f083SXin LI } 3530ada6f083SXin LI 3531ada6f083SXin LI int 3532ada6f083SXin LI pcap_oid_get_request(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp) 3533ada6f083SXin LI { 3534ada6f083SXin LI return (p->oid_get_request_op(p, oid, data, lenp)); 3535ada6f083SXin LI } 3536ada6f083SXin LI 3537ada6f083SXin LI int 3538ada6f083SXin LI pcap_oid_set_request(pcap_t *p, bpf_u_int32 oid, const void *data, size_t *lenp) 3539ada6f083SXin LI { 3540ada6f083SXin LI return (p->oid_set_request_op(p, oid, data, lenp)); 3541ada6f083SXin LI } 3542ada6f083SXin LI 3543ada6f083SXin LI pcap_send_queue * 3544ada6f083SXin LI pcap_sendqueue_alloc(u_int memsize) 3545ada6f083SXin LI { 3546ada6f083SXin LI pcap_send_queue *tqueue; 3547ada6f083SXin LI 3548ada6f083SXin LI /* Allocate the queue */ 3549ada6f083SXin LI tqueue = (pcap_send_queue *)malloc(sizeof(pcap_send_queue)); 3550ada6f083SXin LI if (tqueue == NULL){ 3551ada6f083SXin LI return (NULL); 3552ada6f083SXin LI } 3553ada6f083SXin LI 3554ada6f083SXin LI /* Allocate the buffer */ 3555ada6f083SXin LI tqueue->buffer = (char *)malloc(memsize); 3556ada6f083SXin LI if (tqueue->buffer == NULL) { 3557ada6f083SXin LI free(tqueue); 3558ada6f083SXin LI return (NULL); 3559ada6f083SXin LI } 3560ada6f083SXin LI 3561ada6f083SXin LI tqueue->maxlen = memsize; 3562ada6f083SXin LI tqueue->len = 0; 3563ada6f083SXin LI 3564ada6f083SXin LI return (tqueue); 3565ada6f083SXin LI } 3566ada6f083SXin LI 3567ada6f083SXin LI void 3568ada6f083SXin LI pcap_sendqueue_destroy(pcap_send_queue *queue) 3569ada6f083SXin LI { 3570ada6f083SXin LI free(queue->buffer); 3571ada6f083SXin LI free(queue); 3572ada6f083SXin LI } 3573ada6f083SXin LI 3574ada6f083SXin LI int 3575ada6f083SXin LI pcap_sendqueue_queue(pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) 3576ada6f083SXin LI { 3577ada6f083SXin LI if (queue->len + sizeof(struct pcap_pkthdr) + pkt_header->caplen > queue->maxlen){ 3578ada6f083SXin LI return (-1); 3579ada6f083SXin LI } 3580ada6f083SXin LI 3581ada6f083SXin LI /* Copy the pcap_pkthdr header*/ 3582ada6f083SXin LI memcpy(queue->buffer + queue->len, pkt_header, sizeof(struct pcap_pkthdr)); 3583ada6f083SXin LI queue->len += sizeof(struct pcap_pkthdr); 3584ada6f083SXin LI 3585ada6f083SXin LI /* copy the packet */ 3586ada6f083SXin LI memcpy(queue->buffer + queue->len, pkt_data, pkt_header->caplen); 3587ada6f083SXin LI queue->len += pkt_header->caplen; 3588ada6f083SXin LI 3589ada6f083SXin LI return (0); 3590ada6f083SXin LI } 3591ada6f083SXin LI 3592ada6f083SXin LI u_int 3593ada6f083SXin LI pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue, int sync) 3594ada6f083SXin LI { 3595ada6f083SXin LI return (p->sendqueue_transmit_op(p, queue, sync)); 3596ada6f083SXin LI } 3597ada6f083SXin LI 3598ada6f083SXin LI int 3599ada6f083SXin LI pcap_setuserbuffer(pcap_t *p, int size) 3600ada6f083SXin LI { 3601ada6f083SXin LI return (p->setuserbuffer_op(p, size)); 3602ada6f083SXin LI } 3603ada6f083SXin LI 3604ada6f083SXin LI int 3605ada6f083SXin LI pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks) 3606ada6f083SXin LI { 3607ada6f083SXin LI return (p->live_dump_op(p, filename, maxsize, maxpacks)); 3608ada6f083SXin LI } 3609ada6f083SXin LI 3610ada6f083SXin LI int 3611ada6f083SXin LI pcap_live_dump_ended(pcap_t *p, int sync) 3612ada6f083SXin LI { 3613ada6f083SXin LI return (p->live_dump_ended_op(p, sync)); 3614ada6f083SXin LI } 3615ada6f083SXin LI 3616ada6f083SXin LI PAirpcapHandle 3617ada6f083SXin LI pcap_get_airpcap_handle(pcap_t *p) 3618ada6f083SXin LI { 3619ada6f083SXin LI PAirpcapHandle handle; 3620ada6f083SXin LI 3621ada6f083SXin LI handle = p->get_airpcap_handle_op(p); 3622ada6f083SXin LI if (handle == NULL) { 3623ada6f083SXin LI (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf), 3624ada6f083SXin LI "This isn't an AirPcap device"); 3625ada6f083SXin LI } 3626ada6f083SXin LI return (handle); 3627ada6f083SXin LI } 3628154bbe41SChristian S.J. Peron #endif 3629a8e07101SRui Paulo 3630a8e07101SRui Paulo /* 3631a8e07101SRui Paulo * On some platforms, we need to clean up promiscuous or monitor mode 3632a8e07101SRui Paulo * when we close a device - and we want that to happen even if the 3633a8e07101SRui Paulo * application just exits without explicitl closing devices. 3634a8e07101SRui Paulo * On those platforms, we need to register a "close all the pcaps" 3635a8e07101SRui Paulo * routine to be called when we exit, and need to maintain a list of 3636a8e07101SRui Paulo * pcaps that need to be closed to clean up modes. 3637a8e07101SRui Paulo * 3638a8e07101SRui Paulo * XXX - not thread-safe. 3639a8e07101SRui Paulo */ 3640a8e07101SRui Paulo 3641a8e07101SRui Paulo /* 3642a8e07101SRui Paulo * List of pcaps on which we've done something that needs to be 3643a8e07101SRui Paulo * cleaned up. 3644a8e07101SRui Paulo * If there are any such pcaps, we arrange to call "pcap_close_all()" 3645a8e07101SRui Paulo * when we exit, and have it close all of them. 3646a8e07101SRui Paulo */ 3647a8e07101SRui Paulo static struct pcap *pcaps_to_close; 3648a8e07101SRui Paulo 3649a8e07101SRui Paulo /* 3650a8e07101SRui Paulo * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to 3651a8e07101SRui Paulo * be called on exit. 3652a8e07101SRui Paulo */ 3653a8e07101SRui Paulo static int did_atexit; 3654a8e07101SRui Paulo 3655a8e07101SRui Paulo static void 3656a8e07101SRui Paulo pcap_close_all(void) 3657a8e07101SRui Paulo { 3658a8e07101SRui Paulo struct pcap *handle; 3659a8e07101SRui Paulo 3660a8e07101SRui Paulo while ((handle = pcaps_to_close) != NULL) 3661a8e07101SRui Paulo pcap_close(handle); 3662a8e07101SRui Paulo } 3663a8e07101SRui Paulo 3664a8e07101SRui Paulo int 3665a8e07101SRui Paulo pcap_do_addexit(pcap_t *p) 3666a8e07101SRui Paulo { 3667a8e07101SRui Paulo /* 3668a8e07101SRui Paulo * If we haven't already done so, arrange to have 3669a8e07101SRui Paulo * "pcap_close_all()" called when we exit. 3670a8e07101SRui Paulo */ 3671a8e07101SRui Paulo if (!did_atexit) { 3672ada6f083SXin LI if (atexit(pcap_close_all) != 0) { 3673a8e07101SRui Paulo /* 3674a8e07101SRui Paulo * "atexit()" failed; let our caller know. 3675a8e07101SRui Paulo */ 3676*57e22627SCy Schubert pcap_strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE); 3677a8e07101SRui Paulo return (0); 3678a8e07101SRui Paulo } 3679a8e07101SRui Paulo did_atexit = 1; 3680a8e07101SRui Paulo } 3681a8e07101SRui Paulo return (1); 3682a8e07101SRui Paulo } 3683a8e07101SRui Paulo 3684a8e07101SRui Paulo void 3685a8e07101SRui Paulo pcap_add_to_pcaps_to_close(pcap_t *p) 3686a8e07101SRui Paulo { 3687681ed54cSXin LI p->next = pcaps_to_close; 3688a8e07101SRui Paulo pcaps_to_close = p; 3689a8e07101SRui Paulo } 3690a8e07101SRui Paulo 3691a8e07101SRui Paulo void 3692a8e07101SRui Paulo pcap_remove_from_pcaps_to_close(pcap_t *p) 3693a8e07101SRui Paulo { 3694a8e07101SRui Paulo pcap_t *pc, *prevpc; 3695a8e07101SRui Paulo 3696a8e07101SRui Paulo for (pc = pcaps_to_close, prevpc = NULL; pc != NULL; 3697681ed54cSXin LI prevpc = pc, pc = pc->next) { 3698a8e07101SRui Paulo if (pc == p) { 3699a8e07101SRui Paulo /* 3700a8e07101SRui Paulo * Found it. Remove it from the list. 3701a8e07101SRui Paulo */ 3702a8e07101SRui Paulo if (prevpc == NULL) { 3703a8e07101SRui Paulo /* 3704a8e07101SRui Paulo * It was at the head of the list. 3705a8e07101SRui Paulo */ 3706681ed54cSXin LI pcaps_to_close = pc->next; 3707a8e07101SRui Paulo } else { 3708a8e07101SRui Paulo /* 3709a8e07101SRui Paulo * It was in the middle of the list. 3710a8e07101SRui Paulo */ 3711681ed54cSXin LI prevpc->next = pc->next; 3712a8e07101SRui Paulo } 3713a8e07101SRui Paulo break; 3714a8e07101SRui Paulo } 3715a8e07101SRui Paulo } 3716a8e07101SRui Paulo } 3717a8e07101SRui Paulo 3718a8e07101SRui Paulo void 3719a8e07101SRui Paulo pcap_cleanup_live_common(pcap_t *p) 3720a8e07101SRui Paulo { 3721a8e07101SRui Paulo if (p->buffer != NULL) { 372204fb2745SSam Leffler free(p->buffer); 3723a8e07101SRui Paulo p->buffer = NULL; 3724a8e07101SRui Paulo } 3725a8e07101SRui Paulo if (p->dlt_list != NULL) { 3726a8e07101SRui Paulo free(p->dlt_list); 3727a8e07101SRui Paulo p->dlt_list = NULL; 3728a8e07101SRui Paulo p->dlt_count = 0; 3729a8e07101SRui Paulo } 3730d1e87331SXin LI if (p->tstamp_type_list != NULL) { 3731d1e87331SXin LI free(p->tstamp_type_list); 3732d1e87331SXin LI p->tstamp_type_list = NULL; 3733d1e87331SXin LI p->tstamp_type_count = 0; 3734d1e87331SXin LI } 3735681ed54cSXin LI if (p->tstamp_precision_list != NULL) { 3736681ed54cSXin LI free(p->tstamp_precision_list); 3737681ed54cSXin LI p->tstamp_precision_list = NULL; 3738681ed54cSXin LI p->tstamp_precision_count = 0; 3739681ed54cSXin LI } 3740a8e07101SRui Paulo pcap_freecode(&p->fcode); 3741ada6f083SXin LI #if !defined(_WIN32) && !defined(MSDOS) 3742a8e07101SRui Paulo if (p->fd >= 0) { 374304fb2745SSam Leffler close(p->fd); 3744a8e07101SRui Paulo p->fd = -1; 3745a8e07101SRui Paulo } 3746a0ee43a1SRui Paulo p->selectable_fd = -1; 374704fb2745SSam Leffler #endif 374804fb2745SSam Leffler } 374904fb2745SSam Leffler 375004fb2745SSam Leffler /* 375104fb2745SSam Leffler * API compatible with WinPcap's "send a packet" routine - returns -1 375204fb2745SSam Leffler * on error, 0 otherwise. 375304fb2745SSam Leffler * 375404fb2745SSam Leffler * XXX - what if we get a short write? 375504fb2745SSam Leffler */ 375604fb2745SSam Leffler int 375704fb2745SSam Leffler pcap_sendpacket(pcap_t *p, const u_char *buf, int size) 375804fb2745SSam Leffler { 375904fb2745SSam Leffler if (p->inject_op(p, buf, size) == -1) 376004fb2745SSam Leffler return (-1); 376104fb2745SSam Leffler return (0); 376204fb2745SSam Leffler } 376304fb2745SSam Leffler 376404fb2745SSam Leffler /* 376504fb2745SSam Leffler * API compatible with OpenBSD's "send a packet" routine - returns -1 on 376604fb2745SSam Leffler * error, number of bytes written otherwise. 376704fb2745SSam Leffler */ 376804fb2745SSam Leffler int 376904fb2745SSam Leffler pcap_inject(pcap_t *p, const void *buf, size_t size) 377004fb2745SSam Leffler { 377104fb2745SSam Leffler return (p->inject_op(p, buf, size)); 377204fb2745SSam Leffler } 377304fb2745SSam Leffler 37748cf6c252SPaul Traina void 37758cf6c252SPaul Traina pcap_close(pcap_t *p) 37768cf6c252SPaul Traina { 3777ada6f083SXin LI if (p->opt.device != NULL) 3778ada6f083SXin LI free(p->opt.device); 3779a8e07101SRui Paulo p->cleanup_op(p); 37808cf6c252SPaul Traina free(p); 37818cf6c252SPaul Traina } 3782feb4ecdbSBruce M Simpson 3783feb4ecdbSBruce M Simpson /* 3784a8e07101SRui Paulo * Given a BPF program, a pcap_pkthdr structure for a packet, and the raw 3785a8e07101SRui Paulo * data for the packet, check whether the packet passes the filter. 3786a8e07101SRui Paulo * Returns the return value of the filter program, which will be zero if 3787a8e07101SRui Paulo * the packet doesn't pass and non-zero if the packet does pass. 3788a8e07101SRui Paulo */ 3789a8e07101SRui Paulo int 3790edc89b24SXin LI pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h, 3791a8e07101SRui Paulo const u_char *pkt) 3792a8e07101SRui Paulo { 3793edc89b24SXin LI const struct bpf_insn *fcode = fp->bf_insns; 3794a8e07101SRui Paulo 3795a8e07101SRui Paulo if (fcode != NULL) 3796a8e07101SRui Paulo return (bpf_filter(fcode, pkt, h->len, h->caplen)); 3797a8e07101SRui Paulo else 3798a8e07101SRui Paulo return (0); 3799a8e07101SRui Paulo } 3800a8e07101SRui Paulo 3801b00ab754SHans Petter Selasky static int 3802b00ab754SHans Petter Selasky pcap_can_set_rfmon_dead(pcap_t *p) 3803b00ab754SHans Petter Selasky { 3804b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3805b00ab754SHans Petter Selasky "Rfmon mode doesn't apply on a pcap_open_dead pcap_t"); 3806b00ab754SHans Petter Selasky return (PCAP_ERROR); 3807b00ab754SHans Petter Selasky } 3808b00ab754SHans Petter Selasky 3809b00ab754SHans Petter Selasky static int 3810b00ab754SHans Petter Selasky pcap_read_dead(pcap_t *p, int cnt _U_, pcap_handler callback _U_, 3811b00ab754SHans Petter Selasky u_char *user _U_) 3812b00ab754SHans Petter Selasky { 3813b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3814b00ab754SHans Petter Selasky "Packets aren't available from a pcap_open_dead pcap_t"); 3815b00ab754SHans Petter Selasky return (-1); 3816b00ab754SHans Petter Selasky } 3817b00ab754SHans Petter Selasky 3818b00ab754SHans Petter Selasky static int 3819b00ab754SHans Petter Selasky pcap_inject_dead(pcap_t *p, const void *buf _U_, size_t size _U_) 3820b00ab754SHans Petter Selasky { 3821b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3822b00ab754SHans Petter Selasky "Packets can't be sent on a pcap_open_dead pcap_t"); 3823b00ab754SHans Petter Selasky return (-1); 3824b00ab754SHans Petter Selasky } 3825b00ab754SHans Petter Selasky 3826b00ab754SHans Petter Selasky static int 3827b00ab754SHans Petter Selasky pcap_setfilter_dead(pcap_t *p, struct bpf_program *fp _U_) 3828b00ab754SHans Petter Selasky { 3829b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3830b00ab754SHans Petter Selasky "A filter cannot be set on a pcap_open_dead pcap_t"); 3831b00ab754SHans Petter Selasky return (-1); 3832b00ab754SHans Petter Selasky } 3833b00ab754SHans Petter Selasky 3834b00ab754SHans Petter Selasky static int 3835b00ab754SHans Petter Selasky pcap_setdirection_dead(pcap_t *p, pcap_direction_t d _U_) 3836b00ab754SHans Petter Selasky { 3837b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3838b00ab754SHans Petter Selasky "The packet direction cannot be set on a pcap_open_dead pcap_t"); 3839b00ab754SHans Petter Selasky return (-1); 3840b00ab754SHans Petter Selasky } 3841b00ab754SHans Petter Selasky 3842b00ab754SHans Petter Selasky static int 3843b00ab754SHans Petter Selasky pcap_set_datalink_dead(pcap_t *p, int dlt _U_) 3844b00ab754SHans Petter Selasky { 3845b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3846b00ab754SHans Petter Selasky "The link-layer header type cannot be set on a pcap_open_dead pcap_t"); 3847b00ab754SHans Petter Selasky return (-1); 3848b00ab754SHans Petter Selasky } 3849b00ab754SHans Petter Selasky 3850b00ab754SHans Petter Selasky static int 3851b00ab754SHans Petter Selasky pcap_getnonblock_dead(pcap_t *p) 3852b00ab754SHans Petter Selasky { 3853b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3854b00ab754SHans Petter Selasky "A pcap_open_dead pcap_t does not have a non-blocking mode setting"); 3855b00ab754SHans Petter Selasky return (-1); 3856b00ab754SHans Petter Selasky } 3857b00ab754SHans Petter Selasky 3858b00ab754SHans Petter Selasky static int 3859b00ab754SHans Petter Selasky pcap_setnonblock_dead(pcap_t *p, int nonblock _U_) 3860b00ab754SHans Petter Selasky { 3861b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3862b00ab754SHans Petter Selasky "A pcap_open_dead pcap_t does not have a non-blocking mode setting"); 3863b00ab754SHans Petter Selasky return (-1); 3864b00ab754SHans Petter Selasky } 3865b00ab754SHans Petter Selasky 3866b00ab754SHans Petter Selasky static int 3867b00ab754SHans Petter Selasky pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_) 3868b00ab754SHans Petter Selasky { 3869b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3870b00ab754SHans Petter Selasky "Statistics aren't available from a pcap_open_dead pcap_t"); 3871b00ab754SHans Petter Selasky return (-1); 3872b00ab754SHans Petter Selasky } 387304fb2745SSam Leffler 3874ada6f083SXin LI #ifdef _WIN32 3875b00ab754SHans Petter Selasky struct pcap_stat * 3876b00ab754SHans Petter Selasky pcap_stats_ex_dead(pcap_t *p, int *pcap_stat_size _U_) 3877feb4ecdbSBruce M Simpson { 3878b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3879b00ab754SHans Petter Selasky "Statistics aren't available from a pcap_open_dead pcap_t"); 3880681ed54cSXin LI return (NULL); 3881feb4ecdbSBruce M Simpson } 388204fb2745SSam Leffler 3883b00ab754SHans Petter Selasky static int 3884b00ab754SHans Petter Selasky pcap_setbuff_dead(pcap_t *p, int dim) 3885ada6f083SXin LI { 3886b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3887b00ab754SHans Petter Selasky "The kernel buffer size cannot be set on a pcap_open_dead pcap_t"); 3888b00ab754SHans Petter Selasky return (-1); 3889ada6f083SXin LI } 3890ada6f083SXin LI 3891b00ab754SHans Petter Selasky static int 3892b00ab754SHans Petter Selasky pcap_setmode_dead(pcap_t *p, int mode) 389304fb2745SSam Leffler { 3894b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3895b00ab754SHans Petter Selasky "impossible to set mode on a pcap_open_dead pcap_t"); 3896b00ab754SHans Petter Selasky return (-1); 389704fb2745SSam Leffler } 389804fb2745SSam Leffler 3899b00ab754SHans Petter Selasky static int 3900b00ab754SHans Petter Selasky pcap_setmintocopy_dead(pcap_t *p, int size) 3901feb4ecdbSBruce M Simpson { 3902b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3903b00ab754SHans Petter Selasky "The mintocopy parameter cannot be set on a pcap_open_dead pcap_t"); 3904b00ab754SHans Petter Selasky return (-1); 3905feb4ecdbSBruce M Simpson } 3906b00ab754SHans Petter Selasky 3907b00ab754SHans Petter Selasky static HANDLE 3908b00ab754SHans Petter Selasky pcap_getevent_dead(pcap_t *p) 3909b00ab754SHans Petter Selasky { 3910b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3911b00ab754SHans Petter Selasky "A pcap_open_dead pcap_t has no event handle"); 3912b00ab754SHans Petter Selasky return (INVALID_HANDLE_VALUE); 3913b00ab754SHans Petter Selasky } 3914b00ab754SHans Petter Selasky 3915b00ab754SHans Petter Selasky static int 3916b00ab754SHans Petter Selasky pcap_oid_get_request_dead(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, 3917b00ab754SHans Petter Selasky size_t *lenp _U_) 3918b00ab754SHans Petter Selasky { 3919b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3920b00ab754SHans Petter Selasky "An OID get request cannot be performed on a pcap_open_dead pcap_t"); 3921b00ab754SHans Petter Selasky return (PCAP_ERROR); 3922b00ab754SHans Petter Selasky } 3923b00ab754SHans Petter Selasky 3924b00ab754SHans Petter Selasky static int 3925b00ab754SHans Petter Selasky pcap_oid_set_request_dead(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_, 3926b00ab754SHans Petter Selasky size_t *lenp _U_) 3927b00ab754SHans Petter Selasky { 3928b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3929b00ab754SHans Petter Selasky "An OID set request cannot be performed on a pcap_open_dead pcap_t"); 3930b00ab754SHans Petter Selasky return (PCAP_ERROR); 3931b00ab754SHans Petter Selasky } 3932b00ab754SHans Petter Selasky 3933b00ab754SHans Petter Selasky static u_int 3934b00ab754SHans Petter Selasky pcap_sendqueue_transmit_dead(pcap_t *p, pcap_send_queue *queue, int sync) 3935b00ab754SHans Petter Selasky { 3936b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3937b00ab754SHans Petter Selasky "Packets cannot be transmitted on a pcap_open_dead pcap_t"); 3938b00ab754SHans Petter Selasky return (0); 3939b00ab754SHans Petter Selasky } 3940b00ab754SHans Petter Selasky 3941b00ab754SHans Petter Selasky static int 3942b00ab754SHans Petter Selasky pcap_setuserbuffer_dead(pcap_t *p, int size) 3943b00ab754SHans Petter Selasky { 3944b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3945b00ab754SHans Petter Selasky "The user buffer cannot be set on a pcap_open_dead pcap_t"); 3946b00ab754SHans Petter Selasky return (-1); 3947b00ab754SHans Petter Selasky } 3948b00ab754SHans Petter Selasky 3949b00ab754SHans Petter Selasky static int 3950b00ab754SHans Petter Selasky pcap_live_dump_dead(pcap_t *p, char *filename, int maxsize, int maxpacks) 3951b00ab754SHans Petter Selasky { 3952b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3953b00ab754SHans Petter Selasky "Live packet dumping cannot be performed on a pcap_open_dead pcap_t"); 3954b00ab754SHans Petter Selasky return (-1); 3955b00ab754SHans Petter Selasky } 3956b00ab754SHans Petter Selasky 3957b00ab754SHans Petter Selasky static int 3958b00ab754SHans Petter Selasky pcap_live_dump_ended_dead(pcap_t *p, int sync) 3959b00ab754SHans Petter Selasky { 3960b00ab754SHans Petter Selasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 3961b00ab754SHans Petter Selasky "Live packet dumping cannot be performed on a pcap_open_dead pcap_t"); 3962b00ab754SHans Petter Selasky return (-1); 3963b00ab754SHans Petter Selasky } 3964b00ab754SHans Petter Selasky 3965b00ab754SHans Petter Selasky static PAirpcapHandle 3966b00ab754SHans Petter Selasky pcap_get_airpcap_handle_dead(pcap_t *p) 3967b00ab754SHans Petter Selasky { 3968b00ab754SHans Petter Selasky return (NULL); 3969b00ab754SHans Petter Selasky } 3970b00ab754SHans Petter Selasky #endif /* _WIN32 */ 3971b00ab754SHans Petter Selasky 3972b00ab754SHans Petter Selasky static void 3973b00ab754SHans Petter Selasky pcap_cleanup_dead(pcap_t *p _U_) 3974b00ab754SHans Petter Selasky { 3975b00ab754SHans Petter Selasky /* Nothing to do. */ 3976b00ab754SHans Petter Selasky } 3977b00ab754SHans Petter Selasky 3978b00ab754SHans Petter Selasky pcap_t * 3979b00ab754SHans Petter Selasky pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, u_int precision) 3980b00ab754SHans Petter Selasky { 3981b00ab754SHans Petter Selasky pcap_t *p; 3982b00ab754SHans Petter Selasky 3983b00ab754SHans Petter Selasky switch (precision) { 3984b00ab754SHans Petter Selasky 3985b00ab754SHans Petter Selasky case PCAP_TSTAMP_PRECISION_MICRO: 3986b00ab754SHans Petter Selasky case PCAP_TSTAMP_PRECISION_NANO: 3987b00ab754SHans Petter Selasky break; 3988b00ab754SHans Petter Selasky 3989b00ab754SHans Petter Selasky default: 3990b00ab754SHans Petter Selasky /* 3991b00ab754SHans Petter Selasky * This doesn't really matter, but we don't have any way 3992b00ab754SHans Petter Selasky * to report particular errors, so the only failure we 3993b00ab754SHans Petter Selasky * should have is a memory allocation failure. Just 3994b00ab754SHans Petter Selasky * pick microsecond precision. 3995b00ab754SHans Petter Selasky */ 3996b00ab754SHans Petter Selasky precision = PCAP_TSTAMP_PRECISION_MICRO; 3997b00ab754SHans Petter Selasky break; 3998b00ab754SHans Petter Selasky } 3999b00ab754SHans Petter Selasky p = malloc(sizeof(*p)); 4000b00ab754SHans Petter Selasky if (p == NULL) 4001b00ab754SHans Petter Selasky return NULL; 4002b00ab754SHans Petter Selasky memset (p, 0, sizeof(*p)); 4003b00ab754SHans Petter Selasky p->snapshot = snaplen; 4004b00ab754SHans Petter Selasky p->linktype = linktype; 4005b00ab754SHans Petter Selasky p->opt.tstamp_precision = precision; 4006b00ab754SHans Petter Selasky p->can_set_rfmon_op = pcap_can_set_rfmon_dead; 4007b00ab754SHans Petter Selasky p->read_op = pcap_read_dead; 4008b00ab754SHans Petter Selasky p->inject_op = pcap_inject_dead; 4009b00ab754SHans Petter Selasky p->setfilter_op = pcap_setfilter_dead; 4010b00ab754SHans Petter Selasky p->setdirection_op = pcap_setdirection_dead; 4011b00ab754SHans Petter Selasky p->set_datalink_op = pcap_set_datalink_dead; 4012b00ab754SHans Petter Selasky p->getnonblock_op = pcap_getnonblock_dead; 4013b00ab754SHans Petter Selasky p->setnonblock_op = pcap_setnonblock_dead; 4014b00ab754SHans Petter Selasky p->stats_op = pcap_stats_dead; 4015b00ab754SHans Petter Selasky #ifdef _WIN32 4016b00ab754SHans Petter Selasky p->stats_ex_op = pcap_stats_ex_dead; 4017b00ab754SHans Petter Selasky p->setbuff_op = pcap_setbuff_dead; 4018b00ab754SHans Petter Selasky p->setmode_op = pcap_setmode_dead; 4019b00ab754SHans Petter Selasky p->setmintocopy_op = pcap_setmintocopy_dead; 4020b00ab754SHans Petter Selasky p->getevent_op = pcap_getevent_dead; 4021b00ab754SHans Petter Selasky p->oid_get_request_op = pcap_oid_get_request_dead; 4022b00ab754SHans Petter Selasky p->oid_set_request_op = pcap_oid_set_request_dead; 4023b00ab754SHans Petter Selasky p->sendqueue_transmit_op = pcap_sendqueue_transmit_dead; 4024b00ab754SHans Petter Selasky p->setuserbuffer_op = pcap_setuserbuffer_dead; 4025b00ab754SHans Petter Selasky p->live_dump_op = pcap_live_dump_dead; 4026b00ab754SHans Petter Selasky p->live_dump_ended_op = pcap_live_dump_ended_dead; 4027b00ab754SHans Petter Selasky p->get_airpcap_handle_op = pcap_get_airpcap_handle_dead; 4028feb4ecdbSBruce M Simpson #endif 4029b00ab754SHans Petter Selasky p->cleanup_op = pcap_cleanup_dead; 4030b00ab754SHans Petter Selasky 4031b00ab754SHans Petter Selasky /* 4032b00ab754SHans Petter Selasky * A "dead" pcap_t never requires special BPF code generation. 4033b00ab754SHans Petter Selasky */ 4034b00ab754SHans Petter Selasky p->bpf_codegen_flags = 0; 4035b00ab754SHans Petter Selasky 4036b00ab754SHans Petter Selasky p->activated = 1; 4037b00ab754SHans Petter Selasky return (p); 4038b00ab754SHans Petter Selasky } 4039b00ab754SHans Petter Selasky 4040b00ab754SHans Petter Selasky pcap_t * 4041b00ab754SHans Petter Selasky pcap_open_dead(int linktype, int snaplen) 4042b00ab754SHans Petter Selasky { 4043b00ab754SHans Petter Selasky return (pcap_open_dead_with_tstamp_precision(linktype, snaplen, 4044b00ab754SHans Petter Selasky PCAP_TSTAMP_PRECISION_MICRO)); 4045b00ab754SHans Petter Selasky } 4046ada6f083SXin LI 4047ada6f083SXin LI #ifdef YYDEBUG 4048ada6f083SXin LI /* 4049ada6f083SXin LI * Set the internal "debug printout" flag for the filter expression parser. 4050ada6f083SXin LI * The code to print that stuff is present only if YYDEBUG is defined, so 4051ada6f083SXin LI * the flag, and the routine to set it, are defined only if YYDEBUG is 4052ada6f083SXin LI * defined. 4053ada6f083SXin LI * 4054ada6f083SXin LI * This is intended for libpcap developers, not for general use. 4055ada6f083SXin LI * If you want to set these in a program, you'll have to declare this 4056ada6f083SXin LI * routine yourself, with the appropriate DLL import attribute on Windows; 4057ada6f083SXin LI * it's not declared in any header file, and won't be declared in any 4058ada6f083SXin LI * header file provided by libpcap. 4059ada6f083SXin LI */ 4060ada6f083SXin LI PCAP_API void pcap_set_parser_debug(int value); 4061ada6f083SXin LI 4062ada6f083SXin LI PCAP_API_DEF void 4063ada6f083SXin LI pcap_set_parser_debug(int value) 4064ada6f083SXin LI { 4065ada6f083SXin LI pcap_debug = value; 4066ada6f083SXin LI } 4067ada6f083SXin LI #endif 4068