pcap.c revision 162012
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_ = 36162012Ssam "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.88.2.8 2005/08/13 22:29:46 hannes 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 */ 4617683Spst#include <sys/types.h> 47127664Sbms#endif /* WIN32 */ 4817683Spst 4917683Spst#include <stdio.h> 5017683Spst#include <stdlib.h> 5117683Spst#include <string.h> 52146768Ssam#if !defined(_MSC_VER) && !defined(__BORLANDC__) 5317683Spst#include <unistd.h> 54127664Sbms#endif 5598530Sfenner#include <fcntl.h> 5698530Sfenner#include <errno.h> 5717683Spst 5817683Spst#ifdef HAVE_OS_PROTO_H 5917683Spst#include "os-proto.h" 6017683Spst#endif 6117683Spst 62146768Ssam#ifdef MSDOS 63146768Ssam#include "pcap-dos.h" 64146768Ssam#endif 65146768Ssam 6617683Spst#include "pcap-int.h" 6717683Spst 68127664Sbms#ifdef HAVE_DAG_API 69127664Sbms#include <dagnew.h> 70127664Sbms#include <dagapi.h> 71127664Sbms#endif 72127664Sbms 7317683Spstint 7417683Spstpcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 7517683Spst{ 7617683Spst 77127664Sbms return p->read_op(p, cnt, callback, user); 7817683Spst} 7917683Spst 80127664Sbms/* 81127664Sbms * XXX - is this necessary? 82127664Sbms */ 8317683Spstint 84127664Sbmspcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 85127664Sbms{ 86127664Sbms 87127664Sbms return p->read_op(p, cnt, callback, user); 88127664Sbms} 89127664Sbms 90127664Sbmsint 9117683Spstpcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 9217683Spst{ 9339291Sfenner register int n; 9439291Sfenner 9517683Spst for (;;) { 96127664Sbms if (p->sf.rfile != NULL) { 97127664Sbms /* 98127664Sbms * 0 means EOF, so don't loop if we get 0. 99127664Sbms */ 10039291Sfenner n = pcap_offline_read(p, cnt, callback, user); 101127664Sbms } else { 10239291Sfenner /* 10339291Sfenner * XXX keep reading until we get something 10439291Sfenner * (or an error occurs) 10539291Sfenner */ 10639291Sfenner do { 107127664Sbms n = p->read_op(p, cnt, callback, user); 10839291Sfenner } while (n == 0); 10939291Sfenner } 11017683Spst if (n <= 0) 11117683Spst return (n); 11217683Spst if (cnt > 0) { 11317683Spst cnt -= n; 11417683Spst if (cnt <= 0) 11517683Spst return (0); 11617683Spst } 11717683Spst } 11817683Spst} 11917683Spst 12017683Spststruct singleton { 12117683Spst struct pcap_pkthdr *hdr; 12217683Spst const u_char *pkt; 12317683Spst}; 12417683Spst 12517683Spst 12617683Spststatic void 12717683Spstpcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt) 12817683Spst{ 12917683Spst struct singleton *sp = (struct singleton *)userData; 13017683Spst *sp->hdr = *h; 13117683Spst sp->pkt = pkt; 13217683Spst} 13317683Spst 13417683Spstconst u_char * 13517683Spstpcap_next(pcap_t *p, struct pcap_pkthdr *h) 13617683Spst{ 13717683Spst struct singleton s; 13817683Spst 13917683Spst s.hdr = h; 14017683Spst if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0) 14117683Spst return (0); 14217683Spst return (s.pkt); 14317683Spst} 14417683Spst 145127664Sbmsstruct pkt_for_fakecallback { 146127664Sbms struct pcap_pkthdr *hdr; 147127664Sbms const u_char **pkt; 148127664Sbms}; 149127664Sbms 150127664Sbmsstatic void 151127664Sbmspcap_fakecallback(u_char *userData, const struct pcap_pkthdr *h, 152127664Sbms const u_char *pkt) 153127664Sbms{ 154127664Sbms struct pkt_for_fakecallback *sp = (struct pkt_for_fakecallback *)userData; 155127664Sbms 156127664Sbms *sp->hdr = *h; 157127664Sbms *sp->pkt = pkt; 158127664Sbms} 159127664Sbms 160127664Sbmsint 161127664Sbmspcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, 162127664Sbms const u_char **pkt_data) 163127664Sbms{ 164127664Sbms struct pkt_for_fakecallback s; 165127664Sbms 166127664Sbms s.hdr = &p->pcap_header; 167127664Sbms s.pkt = pkt_data; 168127664Sbms 169127664Sbms /* Saves a pointer to the packet headers */ 170127664Sbms *pkt_header= &p->pcap_header; 171127664Sbms 172127664Sbms if (p->sf.rfile != NULL) { 173127664Sbms int status; 174127664Sbms 175127664Sbms /* We are on an offline capture */ 176127664Sbms status = pcap_offline_read(p, 1, pcap_fakecallback, 177127664Sbms (u_char *)&s); 178127664Sbms 179127664Sbms /* 180127664Sbms * Return codes for pcap_offline_read() are: 181127664Sbms * - 0: EOF 182127664Sbms * - -1: error 183127664Sbms * - >1: OK 184127664Sbms * The first one ('0') conflicts with the return code of 185127664Sbms * 0 from pcap_read() meaning "no packets arrived before 186127664Sbms * the timeout expired", so we map it to -2 so you can 187127664Sbms * distinguish between an EOF from a savefile and a 188127664Sbms * "no packets arrived before the timeout expired, try 189127664Sbms * again" from a live capture. 190127664Sbms */ 191127664Sbms if (status == 0) 192127664Sbms return (-2); 193127664Sbms else 194127664Sbms return (status); 195127664Sbms } 196127664Sbms 197127664Sbms /* 198127664Sbms * Return codes for pcap_read() are: 199127664Sbms * - 0: timeout 200127664Sbms * - -1: error 201127664Sbms * - -2: loop was broken out of with pcap_breakloop() 202127664Sbms * - >1: OK 203127664Sbms * The first one ('0') conflicts with the return code of 0 from 204127664Sbms * pcap_offline_read() meaning "end of file". 205127664Sbms */ 206127664Sbms return (p->read_op(p, 1, pcap_fakecallback, (u_char *)&s)); 207127664Sbms} 208127664Sbms 209127664Sbms/* 210127664Sbms * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate. 211127664Sbms */ 212127664Sbmsvoid 213127664Sbmspcap_breakloop(pcap_t *p) 214127664Sbms{ 215127664Sbms p->break_loop = 1; 216127664Sbms} 217127664Sbms 21817683Spstint 21917683Spstpcap_datalink(pcap_t *p) 22017683Spst{ 22117683Spst return (p->linktype); 22217683Spst} 22317683Spst 22417683Spstint 225109839Sfennerpcap_list_datalinks(pcap_t *p, int **dlt_buffer) 226109839Sfenner{ 227127664Sbms if (p->dlt_count == 0) { 228127664Sbms /* 229127664Sbms * We couldn't fetch the list of DLTs, which means 230127664Sbms * this platform doesn't support changing the 231127664Sbms * DLT for an interface. Return a list of DLTs 232127664Sbms * containing only the DLT this device supports. 233127664Sbms */ 234127664Sbms *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer)); 235127664Sbms if (*dlt_buffer == NULL) { 236127664Sbms (void)snprintf(p->errbuf, sizeof(p->errbuf), 237127664Sbms "malloc: %s", pcap_strerror(errno)); 238127664Sbms return (-1); 239127664Sbms } 240127664Sbms **dlt_buffer = p->linktype; 241127664Sbms return (1); 242127664Sbms } else { 243127664Sbms *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer) * p->dlt_count); 244127664Sbms if (*dlt_buffer == NULL) { 245127664Sbms (void)snprintf(p->errbuf, sizeof(p->errbuf), 246127664Sbms "malloc: %s", pcap_strerror(errno)); 247127664Sbms return (-1); 248127664Sbms } 249127664Sbms (void)memcpy(*dlt_buffer, p->dlt_list, 250127664Sbms sizeof(**dlt_buffer) * p->dlt_count); 251127664Sbms return (p->dlt_count); 252109839Sfenner } 253127664Sbms} 254127664Sbms 255127664Sbmsint 256127664Sbmspcap_set_datalink(pcap_t *p, int dlt) 257127664Sbms{ 258127664Sbms int i; 259127664Sbms const char *dlt_name; 260127664Sbms 261127664Sbms if (p->dlt_count == 0 || p->set_datalink_op == NULL) { 262127664Sbms /* 263127664Sbms * We couldn't fetch the list of DLTs, or we don't 264127664Sbms * have a "set datalink" operation, which means 265127664Sbms * this platform doesn't support changing the 266127664Sbms * DLT for an interface. Check whether the new 267127664Sbms * DLT is the one this interface supports. 268127664Sbms */ 269127664Sbms if (p->linktype != dlt) 270127664Sbms goto unsupported; 271127664Sbms 272127664Sbms /* 273127664Sbms * It is, so there's nothing we need to do here. 274127664Sbms */ 275127664Sbms return (0); 276109839Sfenner } 277127664Sbms for (i = 0; i < p->dlt_count; i++) 278127664Sbms if (p->dlt_list[i] == dlt) 279127664Sbms break; 280127664Sbms if (i >= p->dlt_count) 281127664Sbms goto unsupported; 282146768Ssam if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB && 283146768Ssam dlt == DLT_DOCSIS) { 284146768Ssam /* 285146768Ssam * This is presumably an Ethernet device, as the first 286146768Ssam * link-layer type it offers is DLT_EN10MB, and the only 287146768Ssam * other type it offers is DLT_DOCSIS. That means that 288146768Ssam * we can't tell the driver to supply DOCSIS link-layer 289146768Ssam * headers - we're just pretending that's what we're 290146768Ssam * getting, as, presumably, we're capturing on a dedicated 291146768Ssam * link to a Cisco Cable Modem Termination System, and 292146768Ssam * it's putting raw DOCSIS frames on the wire inside low-level 293146768Ssam * Ethernet framing. 294146768Ssam */ 295146768Ssam p->linktype = dlt; 296146768Ssam return (0); 297146768Ssam } 298127664Sbms if (p->set_datalink_op(p, dlt) == -1) 299127664Sbms return (-1); 300127664Sbms p->linktype = dlt; 301127664Sbms return (0); 302127664Sbms 303127664Sbmsunsupported: 304127664Sbms dlt_name = pcap_datalink_val_to_name(dlt); 305127664Sbms if (dlt_name != NULL) { 306127664Sbms (void) snprintf(p->errbuf, sizeof(p->errbuf), 307127664Sbms "%s is not one of the DLTs supported by this device", 308127664Sbms dlt_name); 309127664Sbms } else { 310127664Sbms (void) snprintf(p->errbuf, sizeof(p->errbuf), 311127664Sbms "DLT %d is not one of the DLTs supported by this device", 312127664Sbms dlt); 313127664Sbms } 314127664Sbms return (-1); 315109839Sfenner} 316109839Sfenner 317127664Sbmsstruct dlt_choice { 318127664Sbms const char *name; 319127664Sbms const char *description; 320127664Sbms int dlt; 321127664Sbms}; 322127664Sbms 323127664Sbms#define DLT_CHOICE(code, description) { #code, description, code } 324127664Sbms#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 } 325127664Sbms 326127664Sbmsstatic struct dlt_choice dlt_choices[] = { 327127664Sbms DLT_CHOICE(DLT_NULL, "BSD loopback"), 328127664Sbms DLT_CHOICE(DLT_EN10MB, "Ethernet"), 329127664Sbms DLT_CHOICE(DLT_IEEE802, "Token ring"), 330127664Sbms DLT_CHOICE(DLT_ARCNET, "ARCNET"), 331127664Sbms DLT_CHOICE(DLT_SLIP, "SLIP"), 332127664Sbms DLT_CHOICE(DLT_PPP, "PPP"), 333127664Sbms DLT_CHOICE(DLT_FDDI, "FDDI"), 334147894Ssam DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"), 335127664Sbms DLT_CHOICE(DLT_RAW, "Raw IP"), 336127664Sbms DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"), 337127664Sbms DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"), 338127664Sbms DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"), 339127664Sbms DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"), 340127664Sbms DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"), 341127664Sbms DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"), 342127664Sbms DLT_CHOICE(DLT_IEEE802_11, "802.11"), 343127664Sbms DLT_CHOICE(DLT_FRELAY, "Frame Relay"), 344127664Sbms DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"), 345127664Sbms DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"), 346127664Sbms DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"), 347127664Sbms DLT_CHOICE(DLT_LTALK, "Localtalk"), 348127664Sbms DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"), 349127664Sbms DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"), 350127664Sbms DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"), 351127664Sbms DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"), 352127664Sbms DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus BSD radio information header"), 353127664Sbms DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"), 354127664Sbms DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"), 355146768Ssam DLT_CHOICE(DLT_DOCSIS, "DOCSIS"), 356127664Sbms DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"), 357127664Sbms DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"), 358146768Ssam DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"), 359146768Ssam DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"), 360146768Ssam DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"), 361146768Ssam DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"), 362146768Ssam DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"), 363146768Ssam DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"), 364146768Ssam DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"), 365146768Ssam DLT_CHOICE(DLT_GPRS_LLC, "GPRS LLC"), 366146768Ssam DLT_CHOICE(DLT_GPF_T, "GPF-T"), 367146768Ssam DLT_CHOICE(DLT_GPF_F, "GPF-F"), 368146768Ssam DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"), 369146768Ssam DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"), 370146768Ssam DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"), 371146768Ssam DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"), 372147894Ssam DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"), 373147894Ssam DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"), 374147894Ssam DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"), 375147894Ssam DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"), 376162012Ssam DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"), 377162012Ssam DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"), 378162012Ssam DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"), 379162012Ssam DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"), 380162012Ssam DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"), 381127664Sbms DLT_CHOICE_SENTINEL 382127664Sbms}; 383127664Sbms 384127664Sbms/* 385127664Sbms * This array is designed for mapping upper and lower case letter 386127664Sbms * together for a case independent comparison. The mappings are 387127664Sbms * based upon ascii character sequences. 388127664Sbms */ 389127664Sbmsstatic const u_char charmap[] = { 390127664Sbms (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003', 391127664Sbms (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007', 392127664Sbms (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013', 393127664Sbms (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017', 394127664Sbms (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023', 395127664Sbms (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027', 396127664Sbms (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033', 397127664Sbms (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037', 398127664Sbms (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043', 399127664Sbms (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047', 400127664Sbms (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053', 401127664Sbms (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057', 402127664Sbms (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063', 403127664Sbms (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067', 404127664Sbms (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073', 405127664Sbms (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077', 406127664Sbms (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143', 407127664Sbms (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', 408127664Sbms (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', 409127664Sbms (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', 410127664Sbms (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', 411127664Sbms (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', 412127664Sbms (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133', 413127664Sbms (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137', 414127664Sbms (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143', 415127664Sbms (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', 416127664Sbms (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', 417127664Sbms (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', 418127664Sbms (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', 419127664Sbms (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', 420127664Sbms (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173', 421127664Sbms (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177', 422127664Sbms (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203', 423127664Sbms (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207', 424127664Sbms (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213', 425127664Sbms (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217', 426127664Sbms (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223', 427127664Sbms (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227', 428127664Sbms (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233', 429127664Sbms (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237', 430127664Sbms (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243', 431127664Sbms (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247', 432127664Sbms (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253', 433127664Sbms (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257', 434127664Sbms (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263', 435127664Sbms (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267', 436127664Sbms (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273', 437127664Sbms (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277', 438127664Sbms (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343', 439127664Sbms (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', 440127664Sbms (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', 441127664Sbms (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', 442127664Sbms (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', 443127664Sbms (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', 444127664Sbms (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333', 445127664Sbms (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337', 446127664Sbms (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343', 447127664Sbms (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', 448127664Sbms (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', 449127664Sbms (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', 450127664Sbms (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', 451127664Sbms (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', 452127664Sbms (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373', 453127664Sbms (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377', 454127664Sbms}; 455127664Sbms 456109839Sfennerint 457127664Sbmspcap_strcasecmp(const char *s1, const char *s2) 458127664Sbms{ 459127664Sbms register const u_char *cm = charmap, 460127664Sbms *us1 = (u_char *)s1, 461127664Sbms *us2 = (u_char *)s2; 462127664Sbms 463127664Sbms while (cm[*us1] == cm[*us2++]) 464127664Sbms if (*us1++ == '\0') 465127664Sbms return(0); 466127664Sbms return (cm[*us1] - cm[*--us2]); 467127664Sbms} 468127664Sbms 469127664Sbmsint 470127664Sbmspcap_datalink_name_to_val(const char *name) 471127664Sbms{ 472127664Sbms int i; 473127664Sbms 474127664Sbms for (i = 0; dlt_choices[i].name != NULL; i++) { 475127664Sbms if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1, 476127664Sbms name) == 0) 477127664Sbms return (dlt_choices[i].dlt); 478127664Sbms } 479127664Sbms return (-1); 480127664Sbms} 481127664Sbms 482127664Sbmsconst char * 483127664Sbmspcap_datalink_val_to_name(int dlt) 484127664Sbms{ 485127664Sbms int i; 486127664Sbms 487127664Sbms for (i = 0; dlt_choices[i].name != NULL; i++) { 488127664Sbms if (dlt_choices[i].dlt == dlt) 489127664Sbms return (dlt_choices[i].name + sizeof("DLT_") - 1); 490127664Sbms } 491127664Sbms return (NULL); 492127664Sbms} 493127664Sbms 494127664Sbmsconst char * 495127664Sbmspcap_datalink_val_to_description(int dlt) 496127664Sbms{ 497127664Sbms int i; 498127664Sbms 499127664Sbms for (i = 0; dlt_choices[i].name != NULL; i++) { 500127664Sbms if (dlt_choices[i].dlt == dlt) 501127664Sbms return (dlt_choices[i].description); 502127664Sbms } 503127664Sbms return (NULL); 504127664Sbms} 505127664Sbms 506127664Sbmsint 50717683Spstpcap_snapshot(pcap_t *p) 50817683Spst{ 50917683Spst return (p->snapshot); 51017683Spst} 51117683Spst 51217683Spstint 51317683Spstpcap_is_swapped(pcap_t *p) 51417683Spst{ 51517683Spst return (p->sf.swapped); 51617683Spst} 51717683Spst 51817683Spstint 51917683Spstpcap_major_version(pcap_t *p) 52017683Spst{ 52117683Spst return (p->sf.version_major); 52217683Spst} 52317683Spst 52417683Spstint 52517683Spstpcap_minor_version(pcap_t *p) 52617683Spst{ 52717683Spst return (p->sf.version_minor); 52817683Spst} 52917683Spst 53017683SpstFILE * 53117683Spstpcap_file(pcap_t *p) 53217683Spst{ 53317683Spst return (p->sf.rfile); 53417683Spst} 53517683Spst 53617683Spstint 53717683Spstpcap_fileno(pcap_t *p) 53817683Spst{ 539127664Sbms#ifndef WIN32 54017683Spst return (p->fd); 541127664Sbms#else 542127664Sbms if (p->adapter != NULL) 543127664Sbms return ((int)(DWORD)p->adapter->hFile); 544127664Sbms else 545127664Sbms return (-1); 546127664Sbms#endif 54717683Spst} 54817683Spst 549146768Ssam#if !defined(WIN32) && !defined(MSDOS) 550127664Sbmsint 551127664Sbmspcap_get_selectable_fd(pcap_t *p) 552127664Sbms{ 553127664Sbms return (p->selectable_fd); 554127664Sbms} 555127664Sbms#endif 556127664Sbms 55717683Spstvoid 55817683Spstpcap_perror(pcap_t *p, char *prefix) 55917683Spst{ 56017683Spst fprintf(stderr, "%s: %s\n", prefix, p->errbuf); 56117683Spst} 56217683Spst 56317683Spstchar * 56417683Spstpcap_geterr(pcap_t *p) 56517683Spst{ 56617683Spst return (p->errbuf); 56717683Spst} 56817683Spst 569127664Sbmsint 570127664Sbmspcap_getnonblock(pcap_t *p, char *errbuf) 571127664Sbms{ 572127664Sbms return p->getnonblock_op(p, errbuf); 573127664Sbms} 574127664Sbms 57517683Spst/* 576127664Sbms * Get the current non-blocking mode setting, under the assumption that 577127664Sbms * it's just the standard POSIX non-blocking flag. 578127664Sbms * 579127664Sbms * We don't look at "p->nonblock", in case somebody tweaked the FD 580127664Sbms * directly. 58198530Sfenner */ 582146768Ssam#if !defined(WIN32) && !defined(MSDOS) 58398530Sfennerint 584127664Sbmspcap_getnonblock_fd(pcap_t *p, char *errbuf) 58598530Sfenner{ 58698530Sfenner int fdflags; 58798530Sfenner 58898530Sfenner fdflags = fcntl(p->fd, F_GETFL, 0); 58998530Sfenner if (fdflags == -1) { 59098530Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", 59198530Sfenner pcap_strerror(errno)); 59298530Sfenner return (-1); 59398530Sfenner } 59498530Sfenner if (fdflags & O_NONBLOCK) 59598530Sfenner return (1); 59698530Sfenner else 59798530Sfenner return (0); 59898530Sfenner} 599127664Sbms#endif 60098530Sfenner 60198530Sfennerint 60298530Sfennerpcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) 60398530Sfenner{ 604127664Sbms return p->setnonblock_op(p, nonblock, errbuf); 605127664Sbms} 606127664Sbms 607146768Ssam#if !defined(WIN32) && !defined(MSDOS) 608127664Sbms/* 609127664Sbms * Set non-blocking mode, under the assumption that it's just the 610127664Sbms * standard POSIX non-blocking flag. (This can be called by the 611127664Sbms * per-platform non-blocking-mode routine if that routine also 612127664Sbms * needs to do some additional work.) 613127664Sbms */ 614127664Sbmsint 615127664Sbmspcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf) 616127664Sbms{ 61798530Sfenner int fdflags; 61898530Sfenner 61998530Sfenner fdflags = fcntl(p->fd, F_GETFL, 0); 62098530Sfenner if (fdflags == -1) { 62198530Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", 62298530Sfenner pcap_strerror(errno)); 62398530Sfenner return (-1); 62498530Sfenner } 62598530Sfenner if (nonblock) 62698530Sfenner fdflags |= O_NONBLOCK; 62798530Sfenner else 62898530Sfenner fdflags &= ~O_NONBLOCK; 62998530Sfenner if (fcntl(p->fd, F_SETFL, fdflags) == -1) { 63098530Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s", 63198530Sfenner pcap_strerror(errno)); 63298530Sfenner return (-1); 63398530Sfenner } 63498530Sfenner return (0); 63598530Sfenner} 636127664Sbms#endif 63798530Sfenner 638127664Sbms#ifdef WIN32 63998530Sfenner/* 640127664Sbms * Generate a string for the last Win32-specific error (i.e. an error generated when 641127664Sbms * calling a Win32 API). 642127664Sbms * For errors occurred during standard C calls, we still use pcap_strerror() 643127664Sbms */ 644127664Sbmschar * 645127664Sbmspcap_win32strerror(void) 646127664Sbms{ 647127664Sbms DWORD error; 648127664Sbms static char errbuf[PCAP_ERRBUF_SIZE+1]; 649127664Sbms int errlen; 650146768Ssam char *p; 651127664Sbms 652127664Sbms error = GetLastError(); 653127664Sbms FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, 654127664Sbms PCAP_ERRBUF_SIZE, NULL); 655127664Sbms 656127664Sbms /* 657127664Sbms * "FormatMessage()" "helpfully" sticks CR/LF at the end of the 658127664Sbms * message. Get rid of it. 659127664Sbms */ 660127664Sbms errlen = strlen(errbuf); 661127664Sbms if (errlen >= 2) { 662127664Sbms errbuf[errlen - 1] = '\0'; 663127664Sbms errbuf[errlen - 2] = '\0'; 664127664Sbms } 665146768Ssam p = strchr(errbuf, '\0'); 666146768Ssam snprintf (p, sizeof(errbuf)-(p-errbuf), " (%lu)", error); 667127664Sbms return (errbuf); 668127664Sbms} 669127664Sbms#endif 670127664Sbms 671127664Sbms/* 67217683Spst * Not all systems have strerror(). 67317683Spst */ 67417683Spstchar * 67517683Spstpcap_strerror(int errnum) 67617683Spst{ 67717683Spst#ifdef HAVE_STRERROR 67817683Spst return (strerror(errnum)); 67917683Spst#else 68017683Spst extern int sys_nerr; 68117683Spst extern const char *const sys_errlist[]; 68217683Spst static char ebuf[20]; 68317683Spst 68417683Spst if ((unsigned int)errnum < sys_nerr) 68517683Spst return ((char *)sys_errlist[errnum]); 68675107Sfenner (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); 68717683Spst return(ebuf); 68817683Spst#endif 68917683Spst} 69017683Spst 691127664Sbmsint 692127664Sbmspcap_setfilter(pcap_t *p, struct bpf_program *fp) 693127664Sbms{ 694127664Sbms return p->setfilter_op(p, fp); 695127664Sbms} 696127664Sbms 697147894Ssam/* 698147894Ssam * Set direction flag, which controls whether we accept only incoming 699147894Ssam * packets, only outgoing packets, or both. 700147894Ssam * Note that, depending on the platform, some or all direction arguments 701147894Ssam * might not be supported. 702147894Ssam */ 703127664Sbmsint 704162012Ssampcap_setdirection(pcap_t *p, pcap_direction_t d) 705147894Ssam{ 706147894Ssam if (p->setdirection_op == NULL) { 707147894Ssam snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 708147894Ssam "Setting direction is not implemented on this platform"); 709147894Ssam return -1; 710147894Ssam } else 711147894Ssam return p->setdirection_op(p, d); 712147894Ssam} 713147894Ssam 714147894Ssamint 715127664Sbmspcap_stats(pcap_t *p, struct pcap_stat *ps) 716127664Sbms{ 717127664Sbms return p->stats_op(p, ps); 718127664Sbms} 719127664Sbms 720127664Sbmsstatic int 721146768Ssampcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_) 722127664Sbms{ 723127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 724127664Sbms "Statistics aren't available from a pcap_open_dead pcap_t"); 725127664Sbms return (-1); 726127664Sbms} 727127664Sbms 728146768Ssamvoid 729146768Ssampcap_close_common(pcap_t *p) 730146768Ssam{ 731146768Ssam if (p->buffer != NULL) 732146768Ssam free(p->buffer); 733146768Ssam#if !defined(WIN32) && !defined(MSDOS) 734146768Ssam if (p->fd >= 0) 735146768Ssam close(p->fd); 736146768Ssam#endif 737146768Ssam} 738146768Ssam 739127664Sbmsstatic void 740146768Ssampcap_close_dead(pcap_t *p _U_) 741127664Sbms{ 742127664Sbms /* Nothing to do. */ 743127664Sbms} 744127664Sbms 74575107Sfennerpcap_t * 74675107Sfennerpcap_open_dead(int linktype, int snaplen) 74775107Sfenner{ 74875107Sfenner pcap_t *p; 74975107Sfenner 75075107Sfenner p = malloc(sizeof(*p)); 75175107Sfenner if (p == NULL) 75275107Sfenner return NULL; 75375107Sfenner memset (p, 0, sizeof(*p)); 75475107Sfenner p->snapshot = snaplen; 75575107Sfenner p->linktype = linktype; 756127664Sbms p->stats_op = pcap_stats_dead; 757127664Sbms p->close_op = pcap_close_dead; 75875107Sfenner return p; 75975107Sfenner} 76075107Sfenner 761146768Ssam/* 762146768Ssam * API compatible with WinPcap's "send a packet" routine - returns -1 763146768Ssam * on error, 0 otherwise. 764146768Ssam * 765146768Ssam * XXX - what if we get a short write? 766146768Ssam */ 767146768Ssamint 768146768Ssampcap_sendpacket(pcap_t *p, const u_char *buf, int size) 769146768Ssam{ 770146768Ssam if (p->inject_op(p, buf, size) == -1) 771146768Ssam return (-1); 772146768Ssam return (0); 773146768Ssam} 774146768Ssam 775146768Ssam/* 776146768Ssam * API compatible with OpenBSD's "send a packet" routine - returns -1 on 777146768Ssam * error, number of bytes written otherwise. 778146768Ssam */ 779146768Ssamint 780146768Ssampcap_inject(pcap_t *p, const void *buf, size_t size) 781146768Ssam{ 782146768Ssam return (p->inject_op(p, buf, size)); 783146768Ssam} 784146768Ssam 78517683Spstvoid 78617683Spstpcap_close(pcap_t *p) 78717683Spst{ 788127664Sbms p->close_op(p); 789109839Sfenner if (p->dlt_list != NULL) 790109839Sfenner free(p->dlt_list); 79175107Sfenner pcap_freecode(&p->fcode); 79217683Spst free(p); 79317683Spst} 794127664Sbms 795127664Sbms/* 796127664Sbms * We make the version string static, and return a pointer to it, rather 797127664Sbms * than exporting the version string directly. On at least some UNIXes, 798127664Sbms * if you import data from a shared library into an program, the data is 799127664Sbms * bound into the program binary, so if the string in the version of the 800127664Sbms * library with which the program was linked isn't the same as the 801127664Sbms * string in the version of the library with which the program is being 802127664Sbms * run, various undesirable things may happen (warnings, the string 803127664Sbms * being the one from the version of the library with which the program 804127664Sbms * was linked, or even weirder things, such as the string being the one 805127664Sbms * from the library but being truncated). 806127664Sbms */ 807146768Ssam#ifdef HAVE_VERSION_H 808146768Ssam#include "version.h" 809146768Ssam#else 810146768Ssamstatic const char pcap_version_string[] = "libpcap version 0.9[.x]"; 811146768Ssam#endif 812146768Ssam 813127664Sbms#ifdef WIN32 814127664Sbms/* 815127664Sbms * XXX - it'd be nice if we could somehow generate the WinPcap and libpcap 816127664Sbms * version numbers when building WinPcap. (It'd be nice to do so for 817127664Sbms * the packet.dll version number as well.) 818127664Sbms */ 819146768Ssamstatic const char wpcap_version_string[] = "3.1"; 820127664Sbmsstatic const char pcap_version_string_fmt[] = 821146768Ssam "WinPcap version %s, based on %s"; 822127664Sbmsstatic const char pcap_version_string_packet_dll_fmt[] = 823146768Ssam "WinPcap version %s (packet.dll version %s), based on %s"; 824146768Ssamstatic char *full_pcap_version_string; 825127664Sbms 826127664Sbmsconst char * 827127664Sbmspcap_lib_version(void) 828127664Sbms{ 829127664Sbms char *packet_version_string; 830146768Ssam size_t full_pcap_version_string_len; 831127664Sbms 832146768Ssam if (full_pcap_version_string == NULL) { 833127664Sbms /* 834127664Sbms * Generate the version string. 835127664Sbms */ 836127664Sbms packet_version_string = PacketGetVersion(); 837127664Sbms if (strcmp(wpcap_version_string, packet_version_string) == 0) { 838127664Sbms /* 839127664Sbms * WinPcap version string and packet.dll version 840127664Sbms * string are the same; just report the WinPcap 841127664Sbms * version. 842127664Sbms */ 843146768Ssam full_pcap_version_string_len = 844146768Ssam (sizeof pcap_version_string_fmt - 4) + 845146768Ssam strlen(wpcap_version_string) + 846146768Ssam strlen(pcap_version_string); 847146768Ssam full_pcap_version_string = 848146768Ssam malloc(full_pcap_version_string_len); 849146768Ssam sprintf(full_pcap_version_string, 850146768Ssam pcap_version_string_fmt, wpcap_version_string, 851146768Ssam pcap_version_string); 852127664Sbms } else { 853127664Sbms /* 854127664Sbms * WinPcap version string and packet.dll version 855127664Sbms * string are different; that shouldn't be the 856127664Sbms * case (the two libraries should come from the 857127664Sbms * same version of WinPcap), so we report both 858127664Sbms * versions. 859127664Sbms */ 860146768Ssam full_pcap_version_string_len = 861146768Ssam (sizeof pcap_version_string_packet_dll_fmt - 6) + 862127664Sbms strlen(wpcap_version_string) + 863146768Ssam strlen(packet_version_string) + 864146768Ssam strlen(pcap_version_string); 865146768Ssam full_pcap_version_string = malloc(full_pcap_version_string_len); 866146768Ssam 867146768Ssam sprintf(full_pcap_version_string, 868127664Sbms pcap_version_string_packet_dll_fmt, 869146768Ssam wpcap_version_string, packet_version_string, 870146768Ssam pcap_version_string); 871127664Sbms } 872127664Sbms } 873146768Ssam return (full_pcap_version_string); 874127664Sbms} 875127664Sbms 876146768Ssam#elif defined(MSDOS) 877146768Ssam 878146768Ssamstatic char *full_pcap_version_string; 879146768Ssam 880127664Sbmsconst char * 881146768Ssampcap_lib_version (void) 882146768Ssam{ 883146768Ssam char *packet_version_string; 884146768Ssam size_t full_pcap_version_string_len; 885146768Ssam static char dospfx[] = "DOS-"; 886146768Ssam 887146768Ssam if (full_pcap_version_string == NULL) { 888146768Ssam /* 889146768Ssam * Generate the version string. 890146768Ssam */ 891146768Ssam full_pcap_version_string_len = 892146768Ssam sizeof dospfx + strlen(pcap_version_string); 893146768Ssam full_pcap_version_string = 894146768Ssam malloc(full_pcap_version_string_len); 895146768Ssam strcpy(full_pcap_version_string, dospfx); 896146768Ssam strcat(full_pcap_version_string, pcap_version_string); 897146768Ssam } 898146768Ssam return (full_pcap_version_string); 899146768Ssam} 900146768Ssam 901146768Ssam#else /* UN*X */ 902146768Ssam 903146768Ssamconst char * 904127664Sbmspcap_lib_version(void) 905127664Sbms{ 906127664Sbms return (pcap_version_string); 907127664Sbms} 908127664Sbms#endif 909