117683Spst/* 239291Sfenner * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998 317683Spst * The Regents of the University of California. All rights reserved. 417683Spst * 517683Spst * Redistribution and use in source and binary forms, with or without 617683Spst * modification, are permitted provided that the following conditions 717683Spst * are met: 817683Spst * 1. Redistributions of source code must retain the above copyright 917683Spst * notice, this list of conditions and the following disclaimer. 1017683Spst * 2. Redistributions in binary form must reproduce the above copyright 1117683Spst * notice, this list of conditions and the following disclaimer in the 1217683Spst * documentation and/or other materials provided with the distribution. 1317683Spst * 3. All advertising materials mentioning features or use of this software 1417683Spst * must display the following acknowledgement: 1517683Spst * This product includes software developed by the Computer Systems 1617683Spst * Engineering Group at Lawrence Berkeley Laboratory. 1717683Spst * 4. Neither the name of the University nor of the Laboratory may be used 1817683Spst * to endorse or promote products derived from this software without 1917683Spst * specific prior written permission. 2017683Spst * 2117683Spst * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2217683Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2317683Spst * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2417683Spst * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2517683Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2617683Spst * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2717683Spst * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2817683Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2917683Spst * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3017683Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3117683Spst * SUCH DAMAGE. 3217683Spst */ 3317683Spst 3417683Spst#ifndef lint 35127664Sbmsstatic const char rcsid[] _U_ = 36214518Srpaulo "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.128 2008-12-23 20:13:29 guy Exp $ (LBL)"; 3717683Spst#endif 3817683Spst 3975107Sfenner#ifdef HAVE_CONFIG_H 4075107Sfenner#include "config.h" 4175107Sfenner#endif 4275107Sfenner 43127664Sbms#ifdef WIN32 44127664Sbms#include <pcap-stdinc.h> 45127664Sbms#else /* WIN32 */ 46214518Srpaulo#if HAVE_INTTYPES_H 47214518Srpaulo#include <inttypes.h> 48214518Srpaulo#elif HAVE_STDINT_H 49214518Srpaulo#include <stdint.h> 50214518Srpaulo#endif 51214518Srpaulo#ifdef HAVE_SYS_BITYPES_H 52214518Srpaulo#include <sys/bitypes.h> 53214518Srpaulo#endif 5417683Spst#include <sys/types.h> 55183102Scsjp#include <sys/mman.h> 56127664Sbms#endif /* WIN32 */ 5717683Spst 5817683Spst#include <stdio.h> 5917683Spst#include <stdlib.h> 6017683Spst#include <string.h> 61235426Sdelphij#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__MINGW32__) 6217683Spst#include <unistd.h> 63127664Sbms#endif 6498530Sfenner#include <fcntl.h> 6598530Sfenner#include <errno.h> 6617683Spst 6717683Spst#ifdef HAVE_OS_PROTO_H 6817683Spst#include "os-proto.h" 6917683Spst#endif 7017683Spst 71146768Ssam#ifdef MSDOS 72146768Ssam#include "pcap-dos.h" 73146768Ssam#endif 74146768Ssam 7517683Spst#include "pcap-int.h" 7617683Spst 77127664Sbms#ifdef HAVE_DAG_API 78251129Sdelphij#include "pcap-dag.h" 79251129Sdelphij#endif /* HAVE_DAG_API */ 80251129Sdelphij 81251129Sdelphij#ifdef HAVE_SEPTEL_API 82251129Sdelphij#include "pcap-septel.h" 83251129Sdelphij#endif /* HAVE_SEPTEL_API */ 84251129Sdelphij 85251129Sdelphij#ifdef HAVE_SNF_API 86251129Sdelphij#include "pcap-snf.h" 87251129Sdelphij#endif /* HAVE_SNF_API */ 88251129Sdelphij 89251129Sdelphij#ifdef PCAP_SUPPORT_USB 90251129Sdelphij#include "pcap-usb-linux.h" 91127664Sbms#endif 92127664Sbms 93251129Sdelphij#ifdef PCAP_SUPPORT_BT 94251129Sdelphij#include "pcap-bt-linux.h" 95251129Sdelphij#endif 96251129Sdelphij 97251129Sdelphij#ifdef PCAP_SUPPORT_CAN 98251129Sdelphij#include "pcap-can-linux.h" 99251129Sdelphij#endif 100251129Sdelphij 101251129Sdelphij#ifdef PCAP_SUPPORT_CANUSB 102251129Sdelphij#include "pcap-canusb-linux.h" 103251129Sdelphij#endif 104251129Sdelphij 105251129Sdelphij#ifdef PCAP_SUPPORT_NETFILTER 106251129Sdelphij#include "pcap-netfilter-linux.h" 107251129Sdelphij#endif 108251129Sdelphij 109277722Sluigi#ifdef PCAP_SUPPORT_NETMAP 110277722Sluigipcap_t* pcap_netmap_create(const char *device, char *ebuf, int *is_ours); 111277722Sluigi#endif 112277722Sluigi 113190225Srpauloint 114190225Srpaulopcap_not_initialized(pcap_t *pcap) 115190225Srpaulo{ 116190225Srpaulo /* this means 'not initialized' */ 117235426Sdelphij return (PCAP_ERROR_NOT_ACTIVATED); 118190225Srpaulo} 119190225Srpaulo 120190225Srpaulo/* 121190225Srpaulo * Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't, 122190225Srpaulo * a PCAP_ERROR value on an error. 123190225Srpaulo */ 12417683Spstint 125190225Srpaulopcap_can_set_rfmon(pcap_t *p) 126190225Srpaulo{ 127190225Srpaulo return (p->can_set_rfmon_op(p)); 128190225Srpaulo} 129190225Srpaulo 130190225Srpaulo/* 131190225Srpaulo * For systems where rfmon mode is never supported. 132190225Srpaulo */ 133190225Srpaulostatic int 134190225Srpaulopcap_cant_set_rfmon(pcap_t *p _U_) 135190225Srpaulo{ 136190225Srpaulo return (0); 137190225Srpaulo} 138190225Srpaulo 139214518Srpaulo/* 140235426Sdelphij * Sets *tstamp_typesp to point to an array 1 or more supported time stamp 141235426Sdelphij * types; the return value is the number of supported time stamp types. 142235426Sdelphij * The list should be freed by a call to pcap_free_tstamp_types() when 143235426Sdelphij * you're done with it. 144235426Sdelphij * 145235426Sdelphij * A return value of 0 means "you don't get a choice of time stamp type", 146235426Sdelphij * in which case *tstamp_typesp is set to null. 147235426Sdelphij * 148235426Sdelphij * PCAP_ERROR is returned on error. 149235426Sdelphij */ 150235426Sdelphijint 151235426Sdelphijpcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp) 152235426Sdelphij{ 153235426Sdelphij if (p->tstamp_type_count == 0) { 154235426Sdelphij /* 155235426Sdelphij * We don't support multiple time stamp types. 156235426Sdelphij */ 157235426Sdelphij *tstamp_typesp = NULL; 158235426Sdelphij } else { 159235426Sdelphij *tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp), 160235426Sdelphij p->tstamp_type_count); 161235426Sdelphij if (*tstamp_typesp == NULL) { 162235426Sdelphij (void)snprintf(p->errbuf, sizeof(p->errbuf), 163235426Sdelphij "malloc: %s", pcap_strerror(errno)); 164235426Sdelphij return (PCAP_ERROR); 165235426Sdelphij } 166235426Sdelphij (void)memcpy(*tstamp_typesp, p->tstamp_type_list, 167235426Sdelphij sizeof(**tstamp_typesp) * p->tstamp_type_count); 168235426Sdelphij } 169235426Sdelphij return (p->tstamp_type_count); 170235426Sdelphij} 171235426Sdelphij 172235426Sdelphij/* 173235426Sdelphij * In Windows, you might have a library built with one version of the 174235426Sdelphij * C runtime library and an application built with another version of 175235426Sdelphij * the C runtime library, which means that the library might use one 176235426Sdelphij * version of malloc() and free() and the application might use another 177235426Sdelphij * version of malloc() and free(). If so, that means something 178235426Sdelphij * allocated by the library cannot be freed by the application, so we 179235426Sdelphij * need to have a pcap_free_tstamp_types() routine to free up the list 180235426Sdelphij * allocated by pcap_list_tstamp_types(), even though it's just a wrapper 181235426Sdelphij * around free(). 182235426Sdelphij */ 183235426Sdelphijvoid 184235426Sdelphijpcap_free_tstamp_types(int *tstamp_type_list) 185235426Sdelphij{ 186235426Sdelphij free(tstamp_type_list); 187235426Sdelphij} 188235426Sdelphij 189235426Sdelphij/* 190214518Srpaulo * Default one-shot callback; overridden for capture types where the 191214518Srpaulo * packet data cannot be guaranteed to be available after the callback 192214518Srpaulo * returns, so that a copy must be made. 193214518Srpaulo */ 194214518Srpaulostatic void 195214518Srpaulopcap_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *pkt) 196214518Srpaulo{ 197214518Srpaulo struct oneshot_userdata *sp = (struct oneshot_userdata *)user; 198214518Srpaulo 199214518Srpaulo *sp->hdr = *h; 200214518Srpaulo *sp->pkt = pkt; 201214518Srpaulo} 202214518Srpaulo 203214518Srpauloconst u_char * 204214518Srpaulopcap_next(pcap_t *p, struct pcap_pkthdr *h) 205214518Srpaulo{ 206214518Srpaulo struct oneshot_userdata s; 207214518Srpaulo const u_char *pkt; 208214518Srpaulo 209214518Srpaulo s.hdr = h; 210214518Srpaulo s.pkt = &pkt; 211214518Srpaulo s.pd = p; 212214518Srpaulo if (pcap_dispatch(p, 1, p->oneshot_callback, (u_char *)&s) <= 0) 213214518Srpaulo return (0); 214214518Srpaulo return (pkt); 215214518Srpaulo} 216214518Srpaulo 217214518Srpauloint 218214518Srpaulopcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, 219214518Srpaulo const u_char **pkt_data) 220214518Srpaulo{ 221214518Srpaulo struct oneshot_userdata s; 222214518Srpaulo 223214518Srpaulo s.hdr = &p->pcap_header; 224214518Srpaulo s.pkt = pkt_data; 225214518Srpaulo s.pd = p; 226214518Srpaulo 227214518Srpaulo /* Saves a pointer to the packet headers */ 228214518Srpaulo *pkt_header= &p->pcap_header; 229214518Srpaulo 230214518Srpaulo if (p->sf.rfile != NULL) { 231214518Srpaulo int status; 232214518Srpaulo 233214518Srpaulo /* We are on an offline capture */ 234235426Sdelphij status = pcap_offline_read(p, 1, p->oneshot_callback, 235235426Sdelphij (u_char *)&s); 236214518Srpaulo 237214518Srpaulo /* 238214518Srpaulo * Return codes for pcap_offline_read() are: 239214518Srpaulo * - 0: EOF 240214518Srpaulo * - -1: error 241214518Srpaulo * - >1: OK 242214518Srpaulo * The first one ('0') conflicts with the return code of 243214518Srpaulo * 0 from pcap_read() meaning "no packets arrived before 244214518Srpaulo * the timeout expired", so we map it to -2 so you can 245214518Srpaulo * distinguish between an EOF from a savefile and a 246214518Srpaulo * "no packets arrived before the timeout expired, try 247214518Srpaulo * again" from a live capture. 248214518Srpaulo */ 249214518Srpaulo if (status == 0) 250214518Srpaulo return (-2); 251214518Srpaulo else 252214518Srpaulo return (status); 253214518Srpaulo } 254214518Srpaulo 255214518Srpaulo /* 256214518Srpaulo * Return codes for pcap_read() are: 257214518Srpaulo * - 0: timeout 258214518Srpaulo * - -1: error 259214518Srpaulo * - -2: loop was broken out of with pcap_breakloop() 260214518Srpaulo * - >1: OK 261214518Srpaulo * The first one ('0') conflicts with the return code of 0 from 262214518Srpaulo * pcap_offline_read() meaning "end of file". 263214518Srpaulo */ 264235426Sdelphij return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s)); 265214518Srpaulo} 266214518Srpaulo 267251129Sdelphij#if defined(DAG_ONLY) 268251129Sdelphijint 269251129Sdelphijpcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 270251129Sdelphij{ 271251129Sdelphij return (dag_findalldevs(alldevsp, errbuf)); 272251129Sdelphij} 273251129Sdelphij 274251129Sdelphijpcap_t * 275251129Sdelphijpcap_create(const char *source, char *errbuf) 276251129Sdelphij{ 277251129Sdelphij return (dag_create(source, errbuf)); 278251129Sdelphij} 279251129Sdelphij#elif defined(SEPTEL_ONLY) 280251129Sdelphijint 281251129Sdelphijpcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 282251129Sdelphij{ 283251129Sdelphij return (septel_findalldevs(alldevsp, errbuf)); 284251129Sdelphij} 285251129Sdelphij 286251129Sdelphijpcap_t * 287251129Sdelphijpcap_create(const char *source, char *errbuf) 288251129Sdelphij{ 289251129Sdelphij return (septel_create(source, errbuf)); 290251129Sdelphij} 291251129Sdelphij#elif defined(SNF_ONLY) 292251129Sdelphijint 293251129Sdelphijpcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 294251129Sdelphij{ 295251129Sdelphij return (snf_findalldevs(alldevsp, errbuf)); 296251129Sdelphij} 297251129Sdelphij 298251129Sdelphijpcap_t * 299251129Sdelphijpcap_create(const char *source, char *errbuf) 300251129Sdelphij{ 301251129Sdelphij return (snf_create(source, errbuf)); 302251129Sdelphij} 303251129Sdelphij#else /* regular pcap */ 304251129Sdelphijstruct capture_source_type { 305251129Sdelphij int (*findalldevs_op)(pcap_if_t **, char *); 306251129Sdelphij pcap_t *(*create_op)(const char *, char *, int *); 307251129Sdelphij} capture_source_types[] = { 308277722Sluigi#ifdef PCAP_SUPPORT_NETMAP 309277722Sluigi { NULL, pcap_netmap_create }, 310277722Sluigi#endif 311251129Sdelphij#ifdef HAVE_DAG_API 312251129Sdelphij { dag_findalldevs, dag_create }, 313251129Sdelphij#endif 314251129Sdelphij#ifdef HAVE_SEPTEL_API 315251129Sdelphij { septel_findalldevs, septel_create }, 316251129Sdelphij#endif 317251129Sdelphij#ifdef HAVE_SNF_API 318251129Sdelphij { snf_findalldevs, snf_create }, 319251129Sdelphij#endif 320251129Sdelphij#ifdef PCAP_SUPPORT_BT 321251129Sdelphij { bt_findalldevs, bt_create }, 322251129Sdelphij#endif 323251129Sdelphij#if PCAP_SUPPORT_CANUSB 324251129Sdelphij { canusb_findalldevs, canusb_create }, 325251129Sdelphij#endif 326251129Sdelphij#ifdef PCAP_SUPPORT_CAN 327251129Sdelphij { can_findalldevs, can_create }, 328251129Sdelphij#endif 329251129Sdelphij#ifdef PCAP_SUPPORT_USB 330251129Sdelphij { usb_findalldevs, usb_create }, 331251129Sdelphij#endif 332251129Sdelphij#ifdef PCAP_SUPPORT_NETFILTER 333251129Sdelphij { netfilter_findalldevs, netfilter_create }, 334251129Sdelphij#endif 335251129Sdelphij { NULL, NULL } 336251129Sdelphij}; 337251129Sdelphij 338251129Sdelphij/* 339251129Sdelphij * Get a list of all capture sources that are up and that we can open. 340251129Sdelphij * Returns -1 on error, 0 otherwise. 341251129Sdelphij * The list, as returned through "alldevsp", may be null if no interfaces 342251129Sdelphij * were up and could be opened. 343251129Sdelphij */ 344251129Sdelphijint 345251129Sdelphijpcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 346251129Sdelphij{ 347251129Sdelphij size_t i; 348251129Sdelphij 349251129Sdelphij /* 350251129Sdelphij * Get the list of regular interfaces first. 351251129Sdelphij */ 352251129Sdelphij if (pcap_findalldevs_interfaces(alldevsp, errbuf) == -1) 353251129Sdelphij return (-1); /* failure */ 354251129Sdelphij 355251129Sdelphij /* 356251129Sdelphij * Add any interfaces that need a platform-specific mechanism 357251129Sdelphij * to find. 358251129Sdelphij */ 359251129Sdelphij if (pcap_platform_finddevs(alldevsp, errbuf) == -1) { 360251129Sdelphij /* 361251129Sdelphij * We had an error; free the list we've been 362251129Sdelphij * constructing. 363251129Sdelphij */ 364251129Sdelphij if (*alldevsp != NULL) { 365251129Sdelphij pcap_freealldevs(*alldevsp); 366251129Sdelphij *alldevsp = NULL; 367251129Sdelphij } 368251129Sdelphij return (-1); 369251129Sdelphij } 370251129Sdelphij 371251129Sdelphij /* 372251129Sdelphij * Ask each of the non-local-network-interface capture 373251129Sdelphij * source types what interfaces they have. 374251129Sdelphij */ 375251129Sdelphij for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) { 376251129Sdelphij if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) { 377251129Sdelphij /* 378251129Sdelphij * We had an error; free the list we've been 379251129Sdelphij * constructing. 380251129Sdelphij */ 381251129Sdelphij if (*alldevsp != NULL) { 382251129Sdelphij pcap_freealldevs(*alldevsp); 383251129Sdelphij *alldevsp = NULL; 384251129Sdelphij } 385251129Sdelphij return (-1); 386251129Sdelphij } 387251129Sdelphij } 388251129Sdelphij return (0); 389251129Sdelphij} 390251129Sdelphij 391251129Sdelphijpcap_t * 392251129Sdelphijpcap_create(const char *source, char *errbuf) 393251129Sdelphij{ 394251129Sdelphij size_t i; 395251129Sdelphij int is_theirs; 396251129Sdelphij pcap_t *p; 397251129Sdelphij 398251129Sdelphij /* 399251129Sdelphij * A null source name is equivalent to the "any" device - 400251129Sdelphij * which might not be supported on this platform, but 401251129Sdelphij * this means that you'll get a "not supported" error 402251129Sdelphij * rather than, say, a crash when we try to dereference 403251129Sdelphij * the null pointer. 404251129Sdelphij */ 405251129Sdelphij if (source == NULL) 406251129Sdelphij source = "any"; 407251129Sdelphij 408251129Sdelphij /* 409251129Sdelphij * Try each of the non-local-network-interface capture 410251129Sdelphij * source types until we find one that works for this 411251129Sdelphij * device or run out of types. 412251129Sdelphij */ 413251129Sdelphij for (i = 0; capture_source_types[i].create_op != NULL; i++) { 414251129Sdelphij is_theirs = 0; 415251129Sdelphij p = capture_source_types[i].create_op(source, errbuf, &is_theirs); 416251129Sdelphij if (is_theirs) { 417251129Sdelphij /* 418251129Sdelphij * The device name refers to a device of the 419251129Sdelphij * type in question; either it succeeded, 420251129Sdelphij * in which case p refers to a pcap_t to 421251129Sdelphij * later activate for the device, or it 422251129Sdelphij * failed, in which case p is null and we 423251129Sdelphij * should return that to report the failure 424251129Sdelphij * to create. 425251129Sdelphij */ 426251129Sdelphij return (p); 427251129Sdelphij } 428251129Sdelphij } 429251129Sdelphij 430251129Sdelphij /* 431251129Sdelphij * OK, try it as a regular network interface. 432251129Sdelphij */ 433251129Sdelphij return (pcap_create_interface(source, errbuf)); 434251129Sdelphij} 435251129Sdelphij#endif 436251129Sdelphij 437214518Srpaulostatic void 438214518Srpauloinitialize_ops(pcap_t *p) 439214518Srpaulo{ 440214518Srpaulo /* 441214518Srpaulo * Set operation pointers for operations that only work on 442214518Srpaulo * an activated pcap_t to point to a routine that returns 443214518Srpaulo * a "this isn't activated" error. 444214518Srpaulo */ 445214518Srpaulo p->read_op = (read_op_t)pcap_not_initialized; 446214518Srpaulo p->inject_op = (inject_op_t)pcap_not_initialized; 447214518Srpaulo p->setfilter_op = (setfilter_op_t)pcap_not_initialized; 448214518Srpaulo p->setdirection_op = (setdirection_op_t)pcap_not_initialized; 449214518Srpaulo p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized; 450214518Srpaulo p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized; 451214518Srpaulo p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized; 452214518Srpaulo p->stats_op = (stats_op_t)pcap_not_initialized; 453214518Srpaulo#ifdef WIN32 454214518Srpaulo p->setbuff_op = (setbuff_op_t)pcap_not_initialized; 455214518Srpaulo p->setmode_op = (setmode_op_t)pcap_not_initialized; 456214518Srpaulo p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized; 457214518Srpaulo#endif 458214518Srpaulo 459214518Srpaulo /* 460214518Srpaulo * Default cleanup operation - implementations can override 461214518Srpaulo * this, but should call pcap_cleanup_live_common() after 462214518Srpaulo * doing their own additional cleanup. 463214518Srpaulo */ 464214518Srpaulo p->cleanup_op = pcap_cleanup_live_common; 465214518Srpaulo 466214518Srpaulo /* 467214518Srpaulo * In most cases, the standard one-short callback can 468214518Srpaulo * be used for pcap_next()/pcap_next_ex(). 469214518Srpaulo */ 470214518Srpaulo p->oneshot_callback = pcap_oneshot; 471214518Srpaulo} 472214518Srpaulo 473190225Srpaulopcap_t * 474190225Srpaulopcap_create_common(const char *source, char *ebuf) 475190225Srpaulo{ 476190225Srpaulo pcap_t *p; 477190225Srpaulo 478190225Srpaulo p = malloc(sizeof(*p)); 479190225Srpaulo if (p == NULL) { 480190225Srpaulo snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 481190225Srpaulo pcap_strerror(errno)); 482190225Srpaulo return (NULL); 483190225Srpaulo } 484190225Srpaulo memset(p, 0, sizeof(*p)); 485190225Srpaulo#ifndef WIN32 486190225Srpaulo p->fd = -1; /* not opened yet */ 487214518Srpaulo p->selectable_fd = -1; 488214518Srpaulo p->send_fd = -1; 489190225Srpaulo#endif 490190225Srpaulo 491190225Srpaulo p->opt.source = strdup(source); 492190225Srpaulo if (p->opt.source == NULL) { 493190225Srpaulo snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 494190225Srpaulo pcap_strerror(errno)); 495190225Srpaulo free(p); 496190225Srpaulo return (NULL); 497190225Srpaulo } 498190225Srpaulo 499190225Srpaulo /* 500190225Srpaulo * Default to "can't set rfmon mode"; if it's supported by 501214518Srpaulo * a platform, the create routine that called us can set 502214518Srpaulo * the op to its routine to check whether a particular 503214518Srpaulo * device supports it. 504190225Srpaulo */ 505190225Srpaulo p->can_set_rfmon_op = pcap_cant_set_rfmon; 506190225Srpaulo 507214518Srpaulo initialize_ops(p); 508190225Srpaulo 509190225Srpaulo /* put in some defaults*/ 510190225Srpaulo pcap_set_timeout(p, 0); 511190225Srpaulo pcap_set_snaplen(p, 65535); /* max packet size */ 512190225Srpaulo p->opt.promisc = 0; 513190225Srpaulo p->opt.buffer_size = 0; 514235426Sdelphij p->opt.tstamp_type = -1; /* default to not setting time stamp type */ 515190225Srpaulo return (p); 516190225Srpaulo} 517190225Srpaulo 518190225Srpauloint 519190225Srpaulopcap_check_activated(pcap_t *p) 520190225Srpaulo{ 521190225Srpaulo if (p->activated) { 522190225Srpaulo snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform " 523190225Srpaulo " operation on activated capture"); 524235426Sdelphij return (-1); 525190225Srpaulo } 526235426Sdelphij return (0); 527190225Srpaulo} 528190225Srpaulo 529190225Srpauloint 530190225Srpaulopcap_set_snaplen(pcap_t *p, int snaplen) 531190225Srpaulo{ 532190225Srpaulo if (pcap_check_activated(p)) 533235426Sdelphij return (PCAP_ERROR_ACTIVATED); 534190225Srpaulo p->snapshot = snaplen; 535235426Sdelphij return (0); 536190225Srpaulo} 537190225Srpaulo 538190225Srpauloint 539190225Srpaulopcap_set_promisc(pcap_t *p, int promisc) 540190225Srpaulo{ 541190225Srpaulo if (pcap_check_activated(p)) 542235426Sdelphij return (PCAP_ERROR_ACTIVATED); 543190225Srpaulo p->opt.promisc = promisc; 544235426Sdelphij return (0); 545190225Srpaulo} 546190225Srpaulo 547190225Srpauloint 548190225Srpaulopcap_set_rfmon(pcap_t *p, int rfmon) 549190225Srpaulo{ 550190225Srpaulo if (pcap_check_activated(p)) 551235426Sdelphij return (PCAP_ERROR_ACTIVATED); 552190225Srpaulo p->opt.rfmon = rfmon; 553235426Sdelphij return (0); 554190225Srpaulo} 555190225Srpaulo 556190225Srpauloint 557190225Srpaulopcap_set_timeout(pcap_t *p, int timeout_ms) 558190225Srpaulo{ 559190225Srpaulo if (pcap_check_activated(p)) 560235426Sdelphij return (PCAP_ERROR_ACTIVATED); 561190225Srpaulo p->md.timeout = timeout_ms; 562235426Sdelphij return (0); 563190225Srpaulo} 564190225Srpaulo 565190225Srpauloint 566235426Sdelphijpcap_set_tstamp_type(pcap_t *p, int tstamp_type) 567235426Sdelphij{ 568235426Sdelphij int i; 569235426Sdelphij 570235426Sdelphij if (pcap_check_activated(p)) 571235426Sdelphij return (PCAP_ERROR_ACTIVATED); 572235426Sdelphij 573235426Sdelphij /* 574235426Sdelphij * If p->tstamp_type_count is 0, we don't support setting 575235426Sdelphij * the time stamp type at all. 576235426Sdelphij */ 577235426Sdelphij if (p->tstamp_type_count == 0) 578235426Sdelphij return (PCAP_ERROR_CANTSET_TSTAMP_TYPE); 579235426Sdelphij 580235426Sdelphij /* 581235426Sdelphij * Check whether we claim to support this type of time stamp. 582235426Sdelphij */ 583235426Sdelphij for (i = 0; i < p->tstamp_type_count; i++) { 584235426Sdelphij if (p->tstamp_type_list[i] == tstamp_type) { 585235426Sdelphij /* 586235426Sdelphij * Yes. 587235426Sdelphij */ 588235426Sdelphij p->opt.tstamp_type = tstamp_type; 589235426Sdelphij return (0); 590235426Sdelphij } 591235426Sdelphij } 592235426Sdelphij 593235426Sdelphij /* 594235426Sdelphij * No. We support setting the time stamp type, but not to this 595235426Sdelphij * particular value. 596235426Sdelphij */ 597235426Sdelphij return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP); 598235426Sdelphij} 599235426Sdelphij 600235426Sdelphijint 601190225Srpaulopcap_set_buffer_size(pcap_t *p, int buffer_size) 602190225Srpaulo{ 603190225Srpaulo if (pcap_check_activated(p)) 604235426Sdelphij return (PCAP_ERROR_ACTIVATED); 605190225Srpaulo p->opt.buffer_size = buffer_size; 606235426Sdelphij return (0); 607190225Srpaulo} 608190225Srpaulo 609190225Srpauloint 610190225Srpaulopcap_activate(pcap_t *p) 611190225Srpaulo{ 612190225Srpaulo int status; 613190225Srpaulo 614235426Sdelphij /* 615235426Sdelphij * Catch attempts to re-activate an already-activated 616235426Sdelphij * pcap_t; this should, for example, catch code that 617235426Sdelphij * calls pcap_open_live() followed by pcap_activate(), 618235426Sdelphij * as some code that showed up in a Stack Exchange 619235426Sdelphij * question did. 620235426Sdelphij */ 621235426Sdelphij if (pcap_check_activated(p)) 622235426Sdelphij return (PCAP_ERROR_ACTIVATED); 623190225Srpaulo status = p->activate_op(p); 624190225Srpaulo if (status >= 0) 625190225Srpaulo p->activated = 1; 626214518Srpaulo else { 627214518Srpaulo if (p->errbuf[0] == '\0') { 628214518Srpaulo /* 629214518Srpaulo * No error message supplied by the activate routine; 630214518Srpaulo * for the benefit of programs that don't specially 631214518Srpaulo * handle errors other than PCAP_ERROR, return the 632214518Srpaulo * error message corresponding to the status. 633214518Srpaulo */ 634214518Srpaulo snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", 635214518Srpaulo pcap_statustostr(status)); 636214518Srpaulo } 637214518Srpaulo 638214518Srpaulo /* 639214518Srpaulo * Undo any operation pointer setting, etc. done by 640214518Srpaulo * the activate operation. 641214518Srpaulo */ 642214518Srpaulo initialize_ops(p); 643214518Srpaulo } 644190225Srpaulo return (status); 645190225Srpaulo} 646190225Srpaulo 647190225Srpaulopcap_t * 648190225Srpaulopcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf) 649190225Srpaulo{ 650190225Srpaulo pcap_t *p; 651190225Srpaulo int status; 652190225Srpaulo 653190225Srpaulo p = pcap_create(source, errbuf); 654190225Srpaulo if (p == NULL) 655190225Srpaulo return (NULL); 656190225Srpaulo status = pcap_set_snaplen(p, snaplen); 657190225Srpaulo if (status < 0) 658190225Srpaulo goto fail; 659190225Srpaulo status = pcap_set_promisc(p, promisc); 660190225Srpaulo if (status < 0) 661190225Srpaulo goto fail; 662190225Srpaulo status = pcap_set_timeout(p, to_ms); 663190225Srpaulo if (status < 0) 664190225Srpaulo goto fail; 665190225Srpaulo /* 666190225Srpaulo * Mark this as opened with pcap_open_live(), so that, for 667190225Srpaulo * example, we show the full list of DLT_ values, rather 668190225Srpaulo * than just the ones that are compatible with capturing 669190225Srpaulo * when not in monitor mode. That allows existing applications 670190225Srpaulo * to work the way they used to work, but allows new applications 671190225Srpaulo * that know about the new open API to, for example, find out the 672190225Srpaulo * DLT_ values that they can select without changing whether 673190225Srpaulo * the adapter is in monitor mode or not. 674190225Srpaulo */ 675190225Srpaulo p->oldstyle = 1; 676190225Srpaulo status = pcap_activate(p); 677190225Srpaulo if (status < 0) 678190225Srpaulo goto fail; 679190225Srpaulo return (p); 680190225Srpaulofail: 681214518Srpaulo if (status == PCAP_ERROR) 682214518Srpaulo snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, 683214518Srpaulo p->errbuf); 684214518Srpaulo else if (status == PCAP_ERROR_NO_SUCH_DEVICE || 685235426Sdelphij status == PCAP_ERROR_PERM_DENIED || 686235426Sdelphij status == PCAP_ERROR_PROMISC_PERM_DENIED) 687214518Srpaulo snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source, 688214518Srpaulo pcap_statustostr(status), p->errbuf); 689190225Srpaulo else 690190225Srpaulo snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, 691190225Srpaulo pcap_statustostr(status)); 692190225Srpaulo pcap_close(p); 693190225Srpaulo return (NULL); 694190225Srpaulo} 695190225Srpaulo 696190225Srpauloint 69717683Spstpcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 69817683Spst{ 699235426Sdelphij return (p->read_op(p, cnt, callback, user)); 70017683Spst} 70117683Spst 702127664Sbms/* 703127664Sbms * XXX - is this necessary? 704127664Sbms */ 70517683Spstint 706127664Sbmspcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 707127664Sbms{ 708127664Sbms 709235426Sdelphij return (p->read_op(p, cnt, callback, user)); 710127664Sbms} 711127664Sbms 712127664Sbmsint 71317683Spstpcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 71417683Spst{ 71539291Sfenner register int n; 71639291Sfenner 71717683Spst for (;;) { 718127664Sbms if (p->sf.rfile != NULL) { 719127664Sbms /* 720127664Sbms * 0 means EOF, so don't loop if we get 0. 721127664Sbms */ 72239291Sfenner n = pcap_offline_read(p, cnt, callback, user); 723127664Sbms } else { 72439291Sfenner /* 72539291Sfenner * XXX keep reading until we get something 72639291Sfenner * (or an error occurs) 72739291Sfenner */ 72839291Sfenner do { 729127664Sbms n = p->read_op(p, cnt, callback, user); 73039291Sfenner } while (n == 0); 73139291Sfenner } 73217683Spst if (n <= 0) 73317683Spst return (n); 73417683Spst if (cnt > 0) { 73517683Spst cnt -= n; 73617683Spst if (cnt <= 0) 73717683Spst return (0); 73817683Spst } 73917683Spst } 74017683Spst} 74117683Spst 742127664Sbms/* 743127664Sbms * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate. 744127664Sbms */ 745127664Sbmsvoid 746127664Sbmspcap_breakloop(pcap_t *p) 747127664Sbms{ 748127664Sbms p->break_loop = 1; 749127664Sbms} 750127664Sbms 75117683Spstint 75217683Spstpcap_datalink(pcap_t *p) 75317683Spst{ 75417683Spst return (p->linktype); 75517683Spst} 75617683Spst 75717683Spstint 758190225Srpaulopcap_datalink_ext(pcap_t *p) 759190225Srpaulo{ 760190225Srpaulo return (p->linktype_ext); 761190225Srpaulo} 762190225Srpaulo 763190225Srpauloint 764109839Sfennerpcap_list_datalinks(pcap_t *p, int **dlt_buffer) 765109839Sfenner{ 766127664Sbms if (p->dlt_count == 0) { 767127664Sbms /* 768127664Sbms * We couldn't fetch the list of DLTs, which means 769127664Sbms * this platform doesn't support changing the 770127664Sbms * DLT for an interface. Return a list of DLTs 771127664Sbms * containing only the DLT this device supports. 772127664Sbms */ 773127664Sbms *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer)); 774127664Sbms if (*dlt_buffer == NULL) { 775127664Sbms (void)snprintf(p->errbuf, sizeof(p->errbuf), 776127664Sbms "malloc: %s", pcap_strerror(errno)); 777127664Sbms return (-1); 778127664Sbms } 779127664Sbms **dlt_buffer = p->linktype; 780127664Sbms return (1); 781127664Sbms } else { 782172677Smlaier *dlt_buffer = (int*)calloc(sizeof(**dlt_buffer), p->dlt_count); 783127664Sbms if (*dlt_buffer == NULL) { 784127664Sbms (void)snprintf(p->errbuf, sizeof(p->errbuf), 785127664Sbms "malloc: %s", pcap_strerror(errno)); 786127664Sbms return (-1); 787127664Sbms } 788127664Sbms (void)memcpy(*dlt_buffer, p->dlt_list, 789127664Sbms sizeof(**dlt_buffer) * p->dlt_count); 790127664Sbms return (p->dlt_count); 791109839Sfenner } 792127664Sbms} 793127664Sbms 794190225Srpaulo/* 795190225Srpaulo * In Windows, you might have a library built with one version of the 796190225Srpaulo * C runtime library and an application built with another version of 797190225Srpaulo * the C runtime library, which means that the library might use one 798190225Srpaulo * version of malloc() and free() and the application might use another 799190225Srpaulo * version of malloc() and free(). If so, that means something 800190225Srpaulo * allocated by the library cannot be freed by the application, so we 801190225Srpaulo * need to have a pcap_free_datalinks() routine to free up the list 802190225Srpaulo * allocated by pcap_list_datalinks(), even though it's just a wrapper 803190225Srpaulo * around free(). 804190225Srpaulo */ 805190225Srpaulovoid 806190225Srpaulopcap_free_datalinks(int *dlt_list) 807190225Srpaulo{ 808190225Srpaulo free(dlt_list); 809190225Srpaulo} 810190225Srpaulo 811127664Sbmsint 812127664Sbmspcap_set_datalink(pcap_t *p, int dlt) 813127664Sbms{ 814127664Sbms int i; 815127664Sbms const char *dlt_name; 816127664Sbms 817127664Sbms if (p->dlt_count == 0 || p->set_datalink_op == NULL) { 818127664Sbms /* 819127664Sbms * We couldn't fetch the list of DLTs, or we don't 820127664Sbms * have a "set datalink" operation, which means 821127664Sbms * this platform doesn't support changing the 822127664Sbms * DLT for an interface. Check whether the new 823127664Sbms * DLT is the one this interface supports. 824127664Sbms */ 825127664Sbms if (p->linktype != dlt) 826127664Sbms goto unsupported; 827127664Sbms 828127664Sbms /* 829127664Sbms * It is, so there's nothing we need to do here. 830127664Sbms */ 831127664Sbms return (0); 832109839Sfenner } 833127664Sbms for (i = 0; i < p->dlt_count; i++) 834127664Sbms if (p->dlt_list[i] == dlt) 835127664Sbms break; 836127664Sbms if (i >= p->dlt_count) 837127664Sbms goto unsupported; 838146768Ssam if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB && 839146768Ssam dlt == DLT_DOCSIS) { 840146768Ssam /* 841146768Ssam * This is presumably an Ethernet device, as the first 842146768Ssam * link-layer type it offers is DLT_EN10MB, and the only 843146768Ssam * other type it offers is DLT_DOCSIS. That means that 844146768Ssam * we can't tell the driver to supply DOCSIS link-layer 845146768Ssam * headers - we're just pretending that's what we're 846146768Ssam * getting, as, presumably, we're capturing on a dedicated 847146768Ssam * link to a Cisco Cable Modem Termination System, and 848146768Ssam * it's putting raw DOCSIS frames on the wire inside low-level 849146768Ssam * Ethernet framing. 850146768Ssam */ 851146768Ssam p->linktype = dlt; 852146768Ssam return (0); 853146768Ssam } 854127664Sbms if (p->set_datalink_op(p, dlt) == -1) 855127664Sbms return (-1); 856127664Sbms p->linktype = dlt; 857127664Sbms return (0); 858127664Sbms 859127664Sbmsunsupported: 860127664Sbms dlt_name = pcap_datalink_val_to_name(dlt); 861127664Sbms if (dlt_name != NULL) { 862127664Sbms (void) snprintf(p->errbuf, sizeof(p->errbuf), 863127664Sbms "%s is not one of the DLTs supported by this device", 864127664Sbms dlt_name); 865127664Sbms } else { 866127664Sbms (void) snprintf(p->errbuf, sizeof(p->errbuf), 867127664Sbms "DLT %d is not one of the DLTs supported by this device", 868127664Sbms dlt); 869127664Sbms } 870127664Sbms return (-1); 871109839Sfenner} 872109839Sfenner 873235426Sdelphij/* 874235426Sdelphij * This array is designed for mapping upper and lower case letter 875235426Sdelphij * together for a case independent comparison. The mappings are 876235426Sdelphij * based upon ascii character sequences. 877235426Sdelphij */ 878235426Sdelphijstatic const u_char charmap[] = { 879235426Sdelphij (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003', 880235426Sdelphij (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007', 881235426Sdelphij (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013', 882235426Sdelphij (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017', 883235426Sdelphij (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023', 884235426Sdelphij (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027', 885235426Sdelphij (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033', 886235426Sdelphij (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037', 887235426Sdelphij (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043', 888235426Sdelphij (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047', 889235426Sdelphij (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053', 890235426Sdelphij (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057', 891235426Sdelphij (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063', 892235426Sdelphij (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067', 893235426Sdelphij (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073', 894235426Sdelphij (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077', 895235426Sdelphij (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143', 896235426Sdelphij (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', 897235426Sdelphij (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', 898235426Sdelphij (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', 899235426Sdelphij (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', 900235426Sdelphij (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', 901235426Sdelphij (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133', 902235426Sdelphij (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137', 903235426Sdelphij (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143', 904235426Sdelphij (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', 905235426Sdelphij (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', 906235426Sdelphij (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', 907235426Sdelphij (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', 908235426Sdelphij (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', 909235426Sdelphij (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173', 910235426Sdelphij (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177', 911235426Sdelphij (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203', 912235426Sdelphij (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207', 913235426Sdelphij (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213', 914235426Sdelphij (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217', 915235426Sdelphij (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223', 916235426Sdelphij (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227', 917235426Sdelphij (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233', 918235426Sdelphij (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237', 919235426Sdelphij (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243', 920235426Sdelphij (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247', 921235426Sdelphij (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253', 922235426Sdelphij (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257', 923235426Sdelphij (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263', 924235426Sdelphij (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267', 925235426Sdelphij (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273', 926235426Sdelphij (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277', 927235426Sdelphij (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343', 928235426Sdelphij (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', 929235426Sdelphij (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', 930235426Sdelphij (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', 931235426Sdelphij (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', 932235426Sdelphij (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', 933235426Sdelphij (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333', 934235426Sdelphij (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337', 935235426Sdelphij (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343', 936235426Sdelphij (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', 937235426Sdelphij (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', 938235426Sdelphij (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', 939235426Sdelphij (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', 940235426Sdelphij (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', 941235426Sdelphij (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373', 942235426Sdelphij (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377', 943235426Sdelphij}; 944235426Sdelphij 945235426Sdelphijint 946235426Sdelphijpcap_strcasecmp(const char *s1, const char *s2) 947235426Sdelphij{ 948235426Sdelphij register const u_char *cm = charmap, 949235426Sdelphij *us1 = (const u_char *)s1, 950235426Sdelphij *us2 = (const u_char *)s2; 951235426Sdelphij 952235426Sdelphij while (cm[*us1] == cm[*us2++]) 953235426Sdelphij if (*us1++ == '\0') 954235426Sdelphij return(0); 955235426Sdelphij return (cm[*us1] - cm[*--us2]); 956235426Sdelphij} 957235426Sdelphij 958127664Sbmsstruct dlt_choice { 959127664Sbms const char *name; 960127664Sbms const char *description; 961127664Sbms int dlt; 962127664Sbms}; 963127664Sbms 964127664Sbms#define DLT_CHOICE(code, description) { #code, description, code } 965127664Sbms#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 } 966127664Sbms 967127664Sbmsstatic struct dlt_choice dlt_choices[] = { 968127664Sbms DLT_CHOICE(DLT_NULL, "BSD loopback"), 969127664Sbms DLT_CHOICE(DLT_EN10MB, "Ethernet"), 970127664Sbms DLT_CHOICE(DLT_IEEE802, "Token ring"), 971190225Srpaulo DLT_CHOICE(DLT_ARCNET, "BSD ARCNET"), 972127664Sbms DLT_CHOICE(DLT_SLIP, "SLIP"), 973127664Sbms DLT_CHOICE(DLT_PPP, "PPP"), 974127664Sbms DLT_CHOICE(DLT_FDDI, "FDDI"), 975147894Ssam DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"), 976127664Sbms DLT_CHOICE(DLT_RAW, "Raw IP"), 977127664Sbms DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"), 978127664Sbms DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"), 979127664Sbms DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"), 980127664Sbms DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"), 981127664Sbms DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"), 982190225Srpaulo DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"), 983127664Sbms DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"), 984127664Sbms DLT_CHOICE(DLT_IEEE802_11, "802.11"), 985127664Sbms DLT_CHOICE(DLT_FRELAY, "Frame Relay"), 986127664Sbms DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"), 987127664Sbms DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"), 988127664Sbms DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"), 989127664Sbms DLT_CHOICE(DLT_LTALK, "Localtalk"), 990127664Sbms DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"), 991241231Sdelphij DLT_CHOICE(DLT_PFSYNC, "Packet filter state syncing"), 992127664Sbms DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"), 993127664Sbms DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"), 994127664Sbms DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"), 995190225Srpaulo DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radiotap header"), 996190225Srpaulo DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"), 997190225Srpaulo DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"), 998190225Srpaulo DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"), 999190225Srpaulo DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"), 1000190225Srpaulo DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"), 1001190225Srpaulo DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"), 1002190225Srpaulo DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"), 1003190225Srpaulo DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"), 1004190225Srpaulo DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"), 1005127664Sbms DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"), 1006190225Srpaulo DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"), 1007190225Srpaulo DLT_CHOICE(DLT_MTP2, "SS7 MTP2"), 1008190225Srpaulo DLT_CHOICE(DLT_MTP3, "SS7 MTP3"), 1009190225Srpaulo DLT_CHOICE(DLT_SCCP, "SS7 SCCP"), 1010146768Ssam DLT_CHOICE(DLT_DOCSIS, "DOCSIS"), 1011127664Sbms DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"), 1012127664Sbms DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"), 1013190225Srpaulo DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"), 1014172677Smlaier DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"), 1015172677Smlaier DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"), 1016172677Smlaier DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"), 1017172677Smlaier DLT_CHOICE(DLT_GPRS_LLC, "GPRS LLC"), 1018172677Smlaier DLT_CHOICE(DLT_GPF_T, "GPF-T"), 1019172677Smlaier DLT_CHOICE(DLT_GPF_F, "GPF-F"), 1020172677Smlaier DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"), 1021146768Ssam DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"), 1022146768Ssam DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"), 1023190225Srpaulo DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"), 1024172677Smlaier DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"), 1025172677Smlaier DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"), 1026172677Smlaier DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"), 1027172677Smlaier DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"), 1028172677Smlaier DLT_CHOICE(DLT_MFR, "FRF.16 Frame Relay"), 1029172677Smlaier DLT_CHOICE(DLT_JUNIPER_VP, "Juniper Voice PIC"), 1030172677Smlaier DLT_CHOICE(DLT_A429, "Arinc 429"), 1031172677Smlaier DLT_CHOICE(DLT_A653_ICM, "Arinc 653 Interpartition Communication"), 1032172677Smlaier DLT_CHOICE(DLT_USB, "USB"), 1033172677Smlaier DLT_CHOICE(DLT_BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"), 1034190225Srpaulo DLT_CHOICE(DLT_IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"), 1035190225Srpaulo DLT_CHOICE(DLT_USB_LINUX, "USB with Linux header"), 1036172677Smlaier DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"), 1037190225Srpaulo DLT_CHOICE(DLT_IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"), 1038190225Srpaulo DLT_CHOICE(DLT_PPI, "Per-Packet Information"), 1039190225Srpaulo DLT_CHOICE(DLT_IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"), 1040190225Srpaulo DLT_CHOICE(DLT_JUNIPER_ISM, "Juniper Integrated Service Module"), 1041235426Sdelphij DLT_CHOICE(DLT_IEEE802_15_4, "IEEE 802.15.4 with FCS"), 1042190225Srpaulo DLT_CHOICE(DLT_SITA, "SITA pseudo-header"), 1043190225Srpaulo DLT_CHOICE(DLT_ERF, "Endace ERF header"), 1044190225Srpaulo DLT_CHOICE(DLT_RAIF1, "Ethernet with u10 Networks pseudo-header"), 1045190225Srpaulo DLT_CHOICE(DLT_IPMB, "IPMB"), 1046190225Srpaulo DLT_CHOICE(DLT_JUNIPER_ST, "Juniper Secure Tunnel"), 1047190225Srpaulo DLT_CHOICE(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"), 1048190225Srpaulo DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"), 1049190225Srpaulo DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"), 1050214518Srpaulo DLT_CHOICE(DLT_MPLS, "MPLS with label as link-layer header"), 1051214518Srpaulo DLT_CHOICE(DLT_USB_LINUX_MMAPPED, "USB with padded Linux header"), 1052214518Srpaulo DLT_CHOICE(DLT_DECT, "DECT"), 1053214518Srpaulo DLT_CHOICE(DLT_AOS, "AOS Space Data Link protocol"), 1054214518Srpaulo DLT_CHOICE(DLT_WIHART, "Wireless HART"), 1055214518Srpaulo DLT_CHOICE(DLT_FC_2, "Fibre Channel FC-2"), 1056214518Srpaulo DLT_CHOICE(DLT_FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"), 1057214518Srpaulo DLT_CHOICE(DLT_IPNET, "Solaris ipnet"), 1058214518Srpaulo DLT_CHOICE(DLT_CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"), 1059214518Srpaulo DLT_CHOICE(DLT_IPV4, "Raw IPv4"), 1060214518Srpaulo DLT_CHOICE(DLT_IPV6, "Raw IPv6"), 1061235426Sdelphij DLT_CHOICE(DLT_IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"), 1062235426Sdelphij DLT_CHOICE(DLT_JUNIPER_VS, "Juniper Virtual Server"), 1063235426Sdelphij DLT_CHOICE(DLT_JUNIPER_SRX_E2E, "Juniper SRX E2E"), 1064235426Sdelphij DLT_CHOICE(DLT_JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"), 1065235426Sdelphij DLT_CHOICE(DLT_DVB_CI, "DVB-CI"), 1066235426Sdelphij DLT_CHOICE(DLT_JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"), 1067235426Sdelphij DLT_CHOICE(DLT_NFLOG, "Linux netfilter log messages"), 1068235426Sdelphij DLT_CHOICE(DLT_NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"), 1069235426Sdelphij DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"), 1070235426Sdelphij DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"), 1071127664Sbms DLT_CHOICE_SENTINEL 1072127664Sbms}; 1073127664Sbms 1074109839Sfennerint 1075127664Sbmspcap_datalink_name_to_val(const char *name) 1076127664Sbms{ 1077127664Sbms int i; 1078127664Sbms 1079127664Sbms for (i = 0; dlt_choices[i].name != NULL; i++) { 1080127664Sbms if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1, 1081127664Sbms name) == 0) 1082127664Sbms return (dlt_choices[i].dlt); 1083127664Sbms } 1084127664Sbms return (-1); 1085127664Sbms} 1086127664Sbms 1087127664Sbmsconst char * 1088127664Sbmspcap_datalink_val_to_name(int dlt) 1089127664Sbms{ 1090127664Sbms int i; 1091127664Sbms 1092127664Sbms for (i = 0; dlt_choices[i].name != NULL; i++) { 1093127664Sbms if (dlt_choices[i].dlt == dlt) 1094127664Sbms return (dlt_choices[i].name + sizeof("DLT_") - 1); 1095127664Sbms } 1096127664Sbms return (NULL); 1097127664Sbms} 1098127664Sbms 1099127664Sbmsconst char * 1100127664Sbmspcap_datalink_val_to_description(int dlt) 1101127664Sbms{ 1102127664Sbms int i; 1103127664Sbms 1104127664Sbms for (i = 0; dlt_choices[i].name != NULL; i++) { 1105127664Sbms if (dlt_choices[i].dlt == dlt) 1106127664Sbms return (dlt_choices[i].description); 1107127664Sbms } 1108127664Sbms return (NULL); 1109127664Sbms} 1110127664Sbms 1111235426Sdelphijstruct tstamp_type_choice { 1112235426Sdelphij const char *name; 1113235426Sdelphij const char *description; 1114235426Sdelphij int type; 1115235426Sdelphij}; 1116235426Sdelphij 1117235426Sdelphijstatic struct tstamp_type_choice tstamp_type_choices[] = { 1118235426Sdelphij { "host", "Host", PCAP_TSTAMP_HOST }, 1119235426Sdelphij { "host_lowprec", "Host, low precision", PCAP_TSTAMP_HOST_LOWPREC }, 1120235426Sdelphij { "host_hiprec", "Host, high precision", PCAP_TSTAMP_HOST_HIPREC }, 1121235426Sdelphij { "adapter", "Adapter", PCAP_TSTAMP_ADAPTER }, 1122235426Sdelphij { "adapter_unsynced", "Adapter, not synced with system time", PCAP_TSTAMP_ADAPTER_UNSYNCED }, 1123235426Sdelphij { NULL, NULL, 0 } 1124235426Sdelphij}; 1125235426Sdelphij 1126127664Sbmsint 1127235426Sdelphijpcap_tstamp_type_name_to_val(const char *name) 1128235426Sdelphij{ 1129235426Sdelphij int i; 1130235426Sdelphij 1131235426Sdelphij for (i = 0; tstamp_type_choices[i].name != NULL; i++) { 1132235426Sdelphij if (pcap_strcasecmp(tstamp_type_choices[i].name, name) == 0) 1133235426Sdelphij return (tstamp_type_choices[i].type); 1134235426Sdelphij } 1135235426Sdelphij return (PCAP_ERROR); 1136235426Sdelphij} 1137235426Sdelphij 1138235426Sdelphijconst char * 1139235426Sdelphijpcap_tstamp_type_val_to_name(int tstamp_type) 1140235426Sdelphij{ 1141235426Sdelphij int i; 1142235426Sdelphij 1143235426Sdelphij for (i = 0; tstamp_type_choices[i].name != NULL; i++) { 1144235426Sdelphij if (tstamp_type_choices[i].type == tstamp_type) 1145235426Sdelphij return (tstamp_type_choices[i].name); 1146235426Sdelphij } 1147235426Sdelphij return (NULL); 1148235426Sdelphij} 1149235426Sdelphij 1150235426Sdelphijconst char * 1151235426Sdelphijpcap_tstamp_type_val_to_description(int tstamp_type) 1152235426Sdelphij{ 1153235426Sdelphij int i; 1154235426Sdelphij 1155235426Sdelphij for (i = 0; tstamp_type_choices[i].name != NULL; i++) { 1156235426Sdelphij if (tstamp_type_choices[i].type == tstamp_type) 1157235426Sdelphij return (tstamp_type_choices[i].description); 1158235426Sdelphij } 1159235426Sdelphij return (NULL); 1160235426Sdelphij} 1161235426Sdelphij 1162235426Sdelphijint 116317683Spstpcap_snapshot(pcap_t *p) 116417683Spst{ 116517683Spst return (p->snapshot); 116617683Spst} 116717683Spst 116817683Spstint 116917683Spstpcap_is_swapped(pcap_t *p) 117017683Spst{ 117117683Spst return (p->sf.swapped); 117217683Spst} 117317683Spst 117417683Spstint 117517683Spstpcap_major_version(pcap_t *p) 117617683Spst{ 117717683Spst return (p->sf.version_major); 117817683Spst} 117917683Spst 118017683Spstint 118117683Spstpcap_minor_version(pcap_t *p) 118217683Spst{ 118317683Spst return (p->sf.version_minor); 118417683Spst} 118517683Spst 118617683SpstFILE * 118717683Spstpcap_file(pcap_t *p) 118817683Spst{ 118917683Spst return (p->sf.rfile); 119017683Spst} 119117683Spst 119217683Spstint 119317683Spstpcap_fileno(pcap_t *p) 119417683Spst{ 1195127664Sbms#ifndef WIN32 119617683Spst return (p->fd); 1197127664Sbms#else 1198127664Sbms if (p->adapter != NULL) 1199127664Sbms return ((int)(DWORD)p->adapter->hFile); 1200127664Sbms else 1201127664Sbms return (-1); 1202127664Sbms#endif 120317683Spst} 120417683Spst 1205146768Ssam#if !defined(WIN32) && !defined(MSDOS) 1206127664Sbmsint 1207127664Sbmspcap_get_selectable_fd(pcap_t *p) 1208127664Sbms{ 1209127664Sbms return (p->selectable_fd); 1210127664Sbms} 1211127664Sbms#endif 1212127664Sbms 121317683Spstvoid 121417683Spstpcap_perror(pcap_t *p, char *prefix) 121517683Spst{ 121617683Spst fprintf(stderr, "%s: %s\n", prefix, p->errbuf); 121717683Spst} 121817683Spst 121917683Spstchar * 122017683Spstpcap_geterr(pcap_t *p) 122117683Spst{ 122217683Spst return (p->errbuf); 122317683Spst} 122417683Spst 1225127664Sbmsint 1226127664Sbmspcap_getnonblock(pcap_t *p, char *errbuf) 1227127664Sbms{ 1228251129Sdelphij int ret; 1229251129Sdelphij 1230251129Sdelphij ret = p->getnonblock_op(p, errbuf); 1231251129Sdelphij if (ret == -1) { 1232251129Sdelphij /* 1233251129Sdelphij * In case somebody depended on the bug wherein 1234251129Sdelphij * the error message was put into p->errbuf 1235251129Sdelphij * by pcap_getnonblock_fd(). 1236251129Sdelphij */ 1237251129Sdelphij strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE); 1238251129Sdelphij } 1239251129Sdelphij return (ret); 1240127664Sbms} 1241127664Sbms 124217683Spst/* 1243127664Sbms * Get the current non-blocking mode setting, under the assumption that 1244127664Sbms * it's just the standard POSIX non-blocking flag. 1245127664Sbms * 1246127664Sbms * We don't look at "p->nonblock", in case somebody tweaked the FD 1247127664Sbms * directly. 124898530Sfenner */ 1249146768Ssam#if !defined(WIN32) && !defined(MSDOS) 125098530Sfennerint 1251127664Sbmspcap_getnonblock_fd(pcap_t *p, char *errbuf) 125298530Sfenner{ 125398530Sfenner int fdflags; 125498530Sfenner 125598530Sfenner fdflags = fcntl(p->fd, F_GETFL, 0); 125698530Sfenner if (fdflags == -1) { 1257251129Sdelphij snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", 125898530Sfenner pcap_strerror(errno)); 125998530Sfenner return (-1); 126098530Sfenner } 126198530Sfenner if (fdflags & O_NONBLOCK) 126298530Sfenner return (1); 126398530Sfenner else 126498530Sfenner return (0); 126598530Sfenner} 1266127664Sbms#endif 126798530Sfenner 126898530Sfennerint 126998530Sfennerpcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) 127098530Sfenner{ 1271251129Sdelphij int ret; 1272251129Sdelphij 1273251129Sdelphij ret = p->setnonblock_op(p, nonblock, errbuf); 1274251129Sdelphij if (ret == -1) { 1275251129Sdelphij /* 1276251129Sdelphij * In case somebody depended on the bug wherein 1277251129Sdelphij * the error message was put into p->errbuf 1278251129Sdelphij * by pcap_setnonblock_fd(). 1279251129Sdelphij */ 1280251129Sdelphij strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE); 1281251129Sdelphij } 1282251129Sdelphij return (ret); 1283127664Sbms} 1284127664Sbms 1285146768Ssam#if !defined(WIN32) && !defined(MSDOS) 1286127664Sbms/* 1287127664Sbms * Set non-blocking mode, under the assumption that it's just the 1288127664Sbms * standard POSIX non-blocking flag. (This can be called by the 1289127664Sbms * per-platform non-blocking-mode routine if that routine also 1290127664Sbms * needs to do some additional work.) 1291127664Sbms */ 1292127664Sbmsint 1293127664Sbmspcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf) 1294127664Sbms{ 129598530Sfenner int fdflags; 129698530Sfenner 129798530Sfenner fdflags = fcntl(p->fd, F_GETFL, 0); 129898530Sfenner if (fdflags == -1) { 1299251129Sdelphij snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", 130098530Sfenner pcap_strerror(errno)); 130198530Sfenner return (-1); 130298530Sfenner } 130398530Sfenner if (nonblock) 130498530Sfenner fdflags |= O_NONBLOCK; 130598530Sfenner else 130698530Sfenner fdflags &= ~O_NONBLOCK; 130798530Sfenner if (fcntl(p->fd, F_SETFL, fdflags) == -1) { 1308251129Sdelphij snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s", 130998530Sfenner pcap_strerror(errno)); 131098530Sfenner return (-1); 131198530Sfenner } 131298530Sfenner return (0); 131398530Sfenner} 1314127664Sbms#endif 131598530Sfenner 1316127664Sbms#ifdef WIN32 131798530Sfenner/* 1318127664Sbms * Generate a string for the last Win32-specific error (i.e. an error generated when 1319127664Sbms * calling a Win32 API). 1320127664Sbms * For errors occurred during standard C calls, we still use pcap_strerror() 1321127664Sbms */ 1322127664Sbmschar * 1323127664Sbmspcap_win32strerror(void) 1324127664Sbms{ 1325127664Sbms DWORD error; 1326127664Sbms static char errbuf[PCAP_ERRBUF_SIZE+1]; 1327127664Sbms int errlen; 1328146768Ssam char *p; 1329127664Sbms 1330127664Sbms error = GetLastError(); 1331127664Sbms FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, 1332127664Sbms PCAP_ERRBUF_SIZE, NULL); 1333127664Sbms 1334127664Sbms /* 1335127664Sbms * "FormatMessage()" "helpfully" sticks CR/LF at the end of the 1336127664Sbms * message. Get rid of it. 1337127664Sbms */ 1338127664Sbms errlen = strlen(errbuf); 1339127664Sbms if (errlen >= 2) { 1340127664Sbms errbuf[errlen - 1] = '\0'; 1341127664Sbms errbuf[errlen - 2] = '\0'; 1342127664Sbms } 1343146768Ssam p = strchr(errbuf, '\0'); 1344146768Ssam snprintf (p, sizeof(errbuf)-(p-errbuf), " (%lu)", error); 1345127664Sbms return (errbuf); 1346127664Sbms} 1347127664Sbms#endif 1348127664Sbms 1349127664Sbms/* 1350190225Srpaulo * Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values. 1351190225Srpaulo */ 1352190225Srpauloconst char * 1353190225Srpaulopcap_statustostr(int errnum) 1354190225Srpaulo{ 1355190225Srpaulo static char ebuf[15+10+1]; 1356190225Srpaulo 1357190225Srpaulo switch (errnum) { 1358190225Srpaulo 1359190225Srpaulo case PCAP_WARNING: 1360190225Srpaulo return("Generic warning"); 1361190225Srpaulo 1362235426Sdelphij case PCAP_WARNING_TSTAMP_TYPE_NOTSUP: 1363235426Sdelphij return ("That type of time stamp is not supported by that device"); 1364235426Sdelphij 1365190225Srpaulo case PCAP_WARNING_PROMISC_NOTSUP: 1366190225Srpaulo return ("That device doesn't support promiscuous mode"); 1367190225Srpaulo 1368190225Srpaulo case PCAP_ERROR: 1369190225Srpaulo return("Generic error"); 1370190225Srpaulo 1371190225Srpaulo case PCAP_ERROR_BREAK: 1372190225Srpaulo return("Loop terminated by pcap_breakloop"); 1373190225Srpaulo 1374190225Srpaulo case PCAP_ERROR_NOT_ACTIVATED: 1375190225Srpaulo return("The pcap_t has not been activated"); 1376190225Srpaulo 1377190225Srpaulo case PCAP_ERROR_ACTIVATED: 1378190225Srpaulo return ("The setting can't be changed after the pcap_t is activated"); 1379190225Srpaulo 1380190225Srpaulo case PCAP_ERROR_NO_SUCH_DEVICE: 1381190225Srpaulo return ("No such device exists"); 1382190225Srpaulo 1383190225Srpaulo case PCAP_ERROR_RFMON_NOTSUP: 1384190225Srpaulo return ("That device doesn't support monitor mode"); 1385190225Srpaulo 1386190225Srpaulo case PCAP_ERROR_NOT_RFMON: 1387190225Srpaulo return ("That operation is supported only in monitor mode"); 1388190225Srpaulo 1389190225Srpaulo case PCAP_ERROR_PERM_DENIED: 1390190225Srpaulo return ("You don't have permission to capture on that device"); 1391190225Srpaulo 1392190225Srpaulo case PCAP_ERROR_IFACE_NOT_UP: 1393190225Srpaulo return ("That device is not up"); 1394235426Sdelphij 1395235426Sdelphij case PCAP_ERROR_CANTSET_TSTAMP_TYPE: 1396235426Sdelphij return ("That device doesn't support setting the time stamp type"); 1397235426Sdelphij 1398235426Sdelphij case PCAP_ERROR_PROMISC_PERM_DENIED: 1399235426Sdelphij return ("You don't have permission to capture in promiscuous mode on that device"); 1400190225Srpaulo } 1401190225Srpaulo (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); 1402190225Srpaulo return(ebuf); 1403190225Srpaulo} 1404190225Srpaulo 1405190225Srpaulo/* 140617683Spst * Not all systems have strerror(). 140717683Spst */ 1408172677Smlaierconst char * 140917683Spstpcap_strerror(int errnum) 141017683Spst{ 141117683Spst#ifdef HAVE_STRERROR 141217683Spst return (strerror(errnum)); 141317683Spst#else 141417683Spst extern int sys_nerr; 141517683Spst extern const char *const sys_errlist[]; 1416190225Srpaulo static char ebuf[15+10+1]; 141717683Spst 141817683Spst if ((unsigned int)errnum < sys_nerr) 141917683Spst return ((char *)sys_errlist[errnum]); 142075107Sfenner (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); 142117683Spst return(ebuf); 142217683Spst#endif 142317683Spst} 142417683Spst 1425127664Sbmsint 1426127664Sbmspcap_setfilter(pcap_t *p, struct bpf_program *fp) 1427127664Sbms{ 1428235426Sdelphij return (p->setfilter_op(p, fp)); 1429127664Sbms} 1430127664Sbms 1431147894Ssam/* 1432147894Ssam * Set direction flag, which controls whether we accept only incoming 1433147894Ssam * packets, only outgoing packets, or both. 1434147894Ssam * Note that, depending on the platform, some or all direction arguments 1435147894Ssam * might not be supported. 1436147894Ssam */ 1437127664Sbmsint 1438162012Ssampcap_setdirection(pcap_t *p, pcap_direction_t d) 1439147894Ssam{ 1440147894Ssam if (p->setdirection_op == NULL) { 1441147894Ssam snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1442147894Ssam "Setting direction is not implemented on this platform"); 1443235426Sdelphij return (-1); 1444147894Ssam } else 1445235426Sdelphij return (p->setdirection_op(p, d)); 1446147894Ssam} 1447147894Ssam 1448147894Ssamint 1449127664Sbmspcap_stats(pcap_t *p, struct pcap_stat *ps) 1450127664Sbms{ 1451235426Sdelphij return (p->stats_op(p, ps)); 1452127664Sbms} 1453127664Sbms 1454127664Sbmsstatic int 1455146768Ssampcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_) 1456127664Sbms{ 1457127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1458127664Sbms "Statistics aren't available from a pcap_open_dead pcap_t"); 1459127664Sbms return (-1); 1460127664Sbms} 1461127664Sbms 1462190225Srpaulo#ifdef WIN32 1463190225Srpauloint 1464190225Srpaulopcap_setbuff(pcap_t *p, int dim) 1465146768Ssam{ 1466235426Sdelphij return (p->setbuff_op(p, dim)); 1467190225Srpaulo} 1468190225Srpaulo 1469190225Srpaulostatic int 1470190225Srpaulopcap_setbuff_dead(pcap_t *p, int dim) 1471190225Srpaulo{ 1472190225Srpaulo snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1473190225Srpaulo "The kernel buffer size cannot be set on a pcap_open_dead pcap_t"); 1474190225Srpaulo return (-1); 1475190225Srpaulo} 1476190225Srpaulo 1477190225Srpauloint 1478190225Srpaulopcap_setmode(pcap_t *p, int mode) 1479190225Srpaulo{ 1480235426Sdelphij return (p->setmode_op(p, mode)); 1481190225Srpaulo} 1482190225Srpaulo 1483190225Srpaulostatic int 1484190225Srpaulopcap_setmode_dead(pcap_t *p, int mode) 1485190225Srpaulo{ 1486190225Srpaulo snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1487190225Srpaulo "impossible to set mode on a pcap_open_dead pcap_t"); 1488190225Srpaulo return (-1); 1489190225Srpaulo} 1490190225Srpaulo 1491190225Srpauloint 1492190225Srpaulopcap_setmintocopy(pcap_t *p, int size) 1493190225Srpaulo{ 1494235426Sdelphij return (p->setmintocopy_op(p, size)); 1495190225Srpaulo} 1496190225Srpaulo 1497190225Srpaulostatic int 1498190225Srpaulopcap_setmintocopy_dead(pcap_t *p, int size) 1499190225Srpaulo{ 1500190225Srpaulo snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1501190225Srpaulo "The mintocopy parameter cannot be set on a pcap_open_dead pcap_t"); 1502190225Srpaulo return (-1); 1503190225Srpaulo} 1504190225Srpaulo#endif 1505190225Srpaulo 1506190225Srpaulo/* 1507190225Srpaulo * On some platforms, we need to clean up promiscuous or monitor mode 1508190225Srpaulo * when we close a device - and we want that to happen even if the 1509190225Srpaulo * application just exits without explicitl closing devices. 1510190225Srpaulo * On those platforms, we need to register a "close all the pcaps" 1511190225Srpaulo * routine to be called when we exit, and need to maintain a list of 1512190225Srpaulo * pcaps that need to be closed to clean up modes. 1513190225Srpaulo * 1514190225Srpaulo * XXX - not thread-safe. 1515190225Srpaulo */ 1516190225Srpaulo 1517190225Srpaulo/* 1518190225Srpaulo * List of pcaps on which we've done something that needs to be 1519190225Srpaulo * cleaned up. 1520190225Srpaulo * If there are any such pcaps, we arrange to call "pcap_close_all()" 1521190225Srpaulo * when we exit, and have it close all of them. 1522190225Srpaulo */ 1523190225Srpaulostatic struct pcap *pcaps_to_close; 1524190225Srpaulo 1525190225Srpaulo/* 1526190225Srpaulo * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to 1527190225Srpaulo * be called on exit. 1528190225Srpaulo */ 1529190225Srpaulostatic int did_atexit; 1530190225Srpaulo 1531190225Srpaulostatic void 1532190225Srpaulopcap_close_all(void) 1533190225Srpaulo{ 1534190225Srpaulo struct pcap *handle; 1535190225Srpaulo 1536190225Srpaulo while ((handle = pcaps_to_close) != NULL) 1537190225Srpaulo pcap_close(handle); 1538190225Srpaulo} 1539190225Srpaulo 1540190225Srpauloint 1541190225Srpaulopcap_do_addexit(pcap_t *p) 1542190225Srpaulo{ 1543183102Scsjp /* 1544190225Srpaulo * If we haven't already done so, arrange to have 1545190225Srpaulo * "pcap_close_all()" called when we exit. 1546183102Scsjp */ 1547190225Srpaulo if (!did_atexit) { 1548190225Srpaulo if (atexit(pcap_close_all) == -1) { 1549190225Srpaulo /* 1550190225Srpaulo * "atexit()" failed; let our caller know. 1551190225Srpaulo */ 1552190225Srpaulo strncpy(p->errbuf, "atexit failed", 1553190225Srpaulo PCAP_ERRBUF_SIZE); 1554190225Srpaulo return (0); 1555190225Srpaulo } 1556190225Srpaulo did_atexit = 1; 1557190225Srpaulo } 1558190225Srpaulo return (1); 1559190225Srpaulo} 1560190225Srpaulo 1561190225Srpaulovoid 1562190225Srpaulopcap_add_to_pcaps_to_close(pcap_t *p) 1563190225Srpaulo{ 1564190225Srpaulo p->md.next = pcaps_to_close; 1565190225Srpaulo pcaps_to_close = p; 1566190225Srpaulo} 1567190225Srpaulo 1568190225Srpaulovoid 1569190225Srpaulopcap_remove_from_pcaps_to_close(pcap_t *p) 1570190225Srpaulo{ 1571190225Srpaulo pcap_t *pc, *prevpc; 1572190225Srpaulo 1573190225Srpaulo for (pc = pcaps_to_close, prevpc = NULL; pc != NULL; 1574190225Srpaulo prevpc = pc, pc = pc->md.next) { 1575190225Srpaulo if (pc == p) { 1576190225Srpaulo /* 1577190225Srpaulo * Found it. Remove it from the list. 1578190225Srpaulo */ 1579190225Srpaulo if (prevpc == NULL) { 1580190225Srpaulo /* 1581190225Srpaulo * It was at the head of the list. 1582190225Srpaulo */ 1583190225Srpaulo pcaps_to_close = pc->md.next; 1584190225Srpaulo } else { 1585190225Srpaulo /* 1586190225Srpaulo * It was in the middle of the list. 1587190225Srpaulo */ 1588190225Srpaulo prevpc->md.next = pc->md.next; 1589190225Srpaulo } 1590190225Srpaulo break; 1591190225Srpaulo } 1592190225Srpaulo } 1593190225Srpaulo} 1594190225Srpaulo 1595190225Srpaulovoid 1596190225Srpaulopcap_cleanup_live_common(pcap_t *p) 1597190225Srpaulo{ 1598190225Srpaulo if (p->buffer != NULL) { 1599190225Srpaulo free(p->buffer); 1600183102Scsjp p->buffer = NULL; 1601190225Srpaulo } 1602190225Srpaulo if (p->dlt_list != NULL) { 1603190225Srpaulo free(p->dlt_list); 1604190225Srpaulo p->dlt_list = NULL; 1605190225Srpaulo p->dlt_count = 0; 1606190225Srpaulo } 1607235426Sdelphij if (p->tstamp_type_list != NULL) { 1608235426Sdelphij free(p->tstamp_type_list); 1609235426Sdelphij p->tstamp_type_list = NULL; 1610235426Sdelphij p->tstamp_type_count = 0; 1611235426Sdelphij } 1612190225Srpaulo pcap_freecode(&p->fcode); 1613146768Ssam#if !defined(WIN32) && !defined(MSDOS) 1614190225Srpaulo if (p->fd >= 0) { 1615146768Ssam close(p->fd); 1616190225Srpaulo p->fd = -1; 1617190225Srpaulo } 1618214518Srpaulo p->selectable_fd = -1; 1619214518Srpaulo p->send_fd = -1; 1620146768Ssam#endif 1621146768Ssam} 1622146768Ssam 1623127664Sbmsstatic void 1624190225Srpaulopcap_cleanup_dead(pcap_t *p _U_) 1625127664Sbms{ 1626127664Sbms /* Nothing to do. */ 1627127664Sbms} 1628127664Sbms 162975107Sfennerpcap_t * 163075107Sfennerpcap_open_dead(int linktype, int snaplen) 163175107Sfenner{ 163275107Sfenner pcap_t *p; 163375107Sfenner 163475107Sfenner p = malloc(sizeof(*p)); 163575107Sfenner if (p == NULL) 163675107Sfenner return NULL; 163775107Sfenner memset (p, 0, sizeof(*p)); 163875107Sfenner p->snapshot = snaplen; 163975107Sfenner p->linktype = linktype; 1640127664Sbms p->stats_op = pcap_stats_dead; 1641190225Srpaulo#ifdef WIN32 1642190225Srpaulo p->setbuff_op = pcap_setbuff_dead; 1643190225Srpaulo p->setmode_op = pcap_setmode_dead; 1644190225Srpaulo p->setmintocopy_op = pcap_setmintocopy_dead; 1645190225Srpaulo#endif 1646190225Srpaulo p->cleanup_op = pcap_cleanup_dead; 1647190225Srpaulo p->activated = 1; 1648235426Sdelphij return (p); 164975107Sfenner} 165075107Sfenner 1651146768Ssam/* 1652146768Ssam * API compatible with WinPcap's "send a packet" routine - returns -1 1653146768Ssam * on error, 0 otherwise. 1654146768Ssam * 1655146768Ssam * XXX - what if we get a short write? 1656146768Ssam */ 1657146768Ssamint 1658146768Ssampcap_sendpacket(pcap_t *p, const u_char *buf, int size) 1659146768Ssam{ 1660146768Ssam if (p->inject_op(p, buf, size) == -1) 1661146768Ssam return (-1); 1662146768Ssam return (0); 1663146768Ssam} 1664146768Ssam 1665146768Ssam/* 1666146768Ssam * API compatible with OpenBSD's "send a packet" routine - returns -1 on 1667146768Ssam * error, number of bytes written otherwise. 1668146768Ssam */ 1669146768Ssamint 1670146768Ssampcap_inject(pcap_t *p, const void *buf, size_t size) 1671146768Ssam{ 1672146768Ssam return (p->inject_op(p, buf, size)); 1673146768Ssam} 1674146768Ssam 167517683Spstvoid 167617683Spstpcap_close(pcap_t *p) 167717683Spst{ 1678190225Srpaulo if (p->opt.source != NULL) 1679190225Srpaulo free(p->opt.source); 1680190225Srpaulo p->cleanup_op(p); 168117683Spst free(p); 168217683Spst} 1683127664Sbms 1684127664Sbms/* 1685190225Srpaulo * Given a BPF program, a pcap_pkthdr structure for a packet, and the raw 1686190225Srpaulo * data for the packet, check whether the packet passes the filter. 1687190225Srpaulo * Returns the return value of the filter program, which will be zero if 1688190225Srpaulo * the packet doesn't pass and non-zero if the packet does pass. 1689190225Srpaulo */ 1690190225Srpauloint 1691251129Sdelphijpcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h, 1692190225Srpaulo const u_char *pkt) 1693190225Srpaulo{ 1694251129Sdelphij const struct bpf_insn *fcode = fp->bf_insns; 1695190225Srpaulo 1696190225Srpaulo if (fcode != NULL) 1697190225Srpaulo return (bpf_filter(fcode, pkt, h->len, h->caplen)); 1698190225Srpaulo else 1699190225Srpaulo return (0); 1700190225Srpaulo} 1701190225Srpaulo 1702190225Srpaulo/* 1703127664Sbms * We make the version string static, and return a pointer to it, rather 1704127664Sbms * than exporting the version string directly. On at least some UNIXes, 1705127664Sbms * if you import data from a shared library into an program, the data is 1706127664Sbms * bound into the program binary, so if the string in the version of the 1707127664Sbms * library with which the program was linked isn't the same as the 1708127664Sbms * string in the version of the library with which the program is being 1709127664Sbms * run, various undesirable things may happen (warnings, the string 1710127664Sbms * being the one from the version of the library with which the program 1711127664Sbms * was linked, or even weirder things, such as the string being the one 1712127664Sbms * from the library but being truncated). 1713127664Sbms */ 1714146768Ssam#ifdef HAVE_VERSION_H 1715146768Ssam#include "version.h" 1716146768Ssam#else 1717214518Srpaulostatic const char pcap_version_string[] = "libpcap version 1.x.y"; 1718146768Ssam#endif 1719146768Ssam 1720127664Sbms#ifdef WIN32 1721127664Sbms/* 1722127664Sbms * XXX - it'd be nice if we could somehow generate the WinPcap and libpcap 1723127664Sbms * version numbers when building WinPcap. (It'd be nice to do so for 1724127664Sbms * the packet.dll version number as well.) 1725127664Sbms */ 1726172677Smlaierstatic const char wpcap_version_string[] = "4.0"; 1727127664Sbmsstatic const char pcap_version_string_fmt[] = 1728146768Ssam "WinPcap version %s, based on %s"; 1729127664Sbmsstatic const char pcap_version_string_packet_dll_fmt[] = 1730146768Ssam "WinPcap version %s (packet.dll version %s), based on %s"; 1731146768Ssamstatic char *full_pcap_version_string; 1732127664Sbms 1733127664Sbmsconst char * 1734127664Sbmspcap_lib_version(void) 1735127664Sbms{ 1736127664Sbms char *packet_version_string; 1737146768Ssam size_t full_pcap_version_string_len; 1738127664Sbms 1739146768Ssam if (full_pcap_version_string == NULL) { 1740127664Sbms /* 1741127664Sbms * Generate the version string. 1742127664Sbms */ 1743127664Sbms packet_version_string = PacketGetVersion(); 1744127664Sbms if (strcmp(wpcap_version_string, packet_version_string) == 0) { 1745127664Sbms /* 1746127664Sbms * WinPcap version string and packet.dll version 1747127664Sbms * string are the same; just report the WinPcap 1748127664Sbms * version. 1749127664Sbms */ 1750146768Ssam full_pcap_version_string_len = 1751146768Ssam (sizeof pcap_version_string_fmt - 4) + 1752146768Ssam strlen(wpcap_version_string) + 1753146768Ssam strlen(pcap_version_string); 1754146768Ssam full_pcap_version_string = 1755146768Ssam malloc(full_pcap_version_string_len); 1756146768Ssam sprintf(full_pcap_version_string, 1757146768Ssam pcap_version_string_fmt, wpcap_version_string, 1758146768Ssam pcap_version_string); 1759127664Sbms } else { 1760127664Sbms /* 1761127664Sbms * WinPcap version string and packet.dll version 1762127664Sbms * string are different; that shouldn't be the 1763127664Sbms * case (the two libraries should come from the 1764127664Sbms * same version of WinPcap), so we report both 1765127664Sbms * versions. 1766127664Sbms */ 1767146768Ssam full_pcap_version_string_len = 1768146768Ssam (sizeof pcap_version_string_packet_dll_fmt - 6) + 1769127664Sbms strlen(wpcap_version_string) + 1770146768Ssam strlen(packet_version_string) + 1771146768Ssam strlen(pcap_version_string); 1772146768Ssam full_pcap_version_string = malloc(full_pcap_version_string_len); 1773146768Ssam 1774146768Ssam sprintf(full_pcap_version_string, 1775127664Sbms pcap_version_string_packet_dll_fmt, 1776146768Ssam wpcap_version_string, packet_version_string, 1777146768Ssam pcap_version_string); 1778127664Sbms } 1779127664Sbms } 1780146768Ssam return (full_pcap_version_string); 1781127664Sbms} 1782127664Sbms 1783146768Ssam#elif defined(MSDOS) 1784146768Ssam 1785146768Ssamstatic char *full_pcap_version_string; 1786146768Ssam 1787127664Sbmsconst char * 1788146768Ssampcap_lib_version (void) 1789146768Ssam{ 1790146768Ssam char *packet_version_string; 1791146768Ssam size_t full_pcap_version_string_len; 1792146768Ssam static char dospfx[] = "DOS-"; 1793146768Ssam 1794146768Ssam if (full_pcap_version_string == NULL) { 1795146768Ssam /* 1796146768Ssam * Generate the version string. 1797146768Ssam */ 1798146768Ssam full_pcap_version_string_len = 1799146768Ssam sizeof dospfx + strlen(pcap_version_string); 1800146768Ssam full_pcap_version_string = 1801146768Ssam malloc(full_pcap_version_string_len); 1802146768Ssam strcpy(full_pcap_version_string, dospfx); 1803146768Ssam strcat(full_pcap_version_string, pcap_version_string); 1804146768Ssam } 1805146768Ssam return (full_pcap_version_string); 1806146768Ssam} 1807146768Ssam 1808146768Ssam#else /* UN*X */ 1809146768Ssam 1810146768Ssamconst char * 1811127664Sbmspcap_lib_version(void) 1812127664Sbms{ 1813127664Sbms return (pcap_version_string); 1814127664Sbms} 1815127664Sbms#endif 1816