18cf6c252SPaul Traina /* 28cf6c252SPaul Traina * Copyright (c) 1993, 1994, 1995, 1996 38cf6c252SPaul Traina * The Regents of the University of California. All rights reserved. 48cf6c252SPaul Traina * 58cf6c252SPaul Traina * Redistribution and use in source and binary forms, with or without 68cf6c252SPaul Traina * modification, are permitted provided that the following conditions 78cf6c252SPaul Traina * are met: 88cf6c252SPaul Traina * 1. Redistributions of source code must retain the above copyright 98cf6c252SPaul Traina * notice, this list of conditions and the following disclaimer. 108cf6c252SPaul Traina * 2. Redistributions in binary form must reproduce the above copyright 118cf6c252SPaul Traina * notice, this list of conditions and the following disclaimer in the 128cf6c252SPaul Traina * documentation and/or other materials provided with the distribution. 138cf6c252SPaul Traina * 3. All advertising materials mentioning features or use of this software 148cf6c252SPaul Traina * must display the following acknowledgement: 158cf6c252SPaul Traina * This product includes software developed by the Computer Systems 168cf6c252SPaul Traina * Engineering Group at Lawrence Berkeley Laboratory. 178cf6c252SPaul Traina * 4. Neither the name of the University nor of the Laboratory may be used 188cf6c252SPaul Traina * to endorse or promote products derived from this software without 198cf6c252SPaul Traina * specific prior written permission. 208cf6c252SPaul Traina * 218cf6c252SPaul Traina * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 228cf6c252SPaul Traina * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 238cf6c252SPaul Traina * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 248cf6c252SPaul Traina * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 258cf6c252SPaul Traina * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 268cf6c252SPaul Traina * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 278cf6c252SPaul Traina * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 288cf6c252SPaul Traina * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 298cf6c252SPaul Traina * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 308cf6c252SPaul Traina * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 318cf6c252SPaul Traina * SUCH DAMAGE. 328cf6c252SPaul Traina */ 338cf6c252SPaul Traina 348cf6c252SPaul Traina #ifndef lint 358cf6c252SPaul Traina static char rcsid[] = 368cf6c252SPaul Traina "@(#) $Header: pcap.c,v 1.25 96/06/05 21:45:26 leres Exp $ (LBL)"; 378cf6c252SPaul Traina #endif 388cf6c252SPaul Traina 398cf6c252SPaul Traina #include <sys/types.h> 408cf6c252SPaul Traina 418cf6c252SPaul Traina #include <stdio.h> 428cf6c252SPaul Traina #include <stdlib.h> 438cf6c252SPaul Traina #include <string.h> 448cf6c252SPaul Traina #include <unistd.h> 458cf6c252SPaul Traina 468cf6c252SPaul Traina #include "gnuc.h" 478cf6c252SPaul Traina #ifdef HAVE_OS_PROTO_H 488cf6c252SPaul Traina #include "os-proto.h" 498cf6c252SPaul Traina #endif 508cf6c252SPaul Traina 518cf6c252SPaul Traina #include "pcap-int.h" 528cf6c252SPaul Traina 538cf6c252SPaul Traina int 548cf6c252SPaul Traina pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 558cf6c252SPaul Traina { 568cf6c252SPaul Traina register int cc; 578cf6c252SPaul Traina 588cf6c252SPaul Traina if (p->sf.rfile != NULL) 598cf6c252SPaul Traina return (pcap_offline_read(p, cnt, callback, user)); 608cf6c252SPaul Traina /* XXX keep reading until we get something (or an error occurs) */ 618cf6c252SPaul Traina do { 628cf6c252SPaul Traina cc = pcap_read(p, cnt, callback, user); 638cf6c252SPaul Traina } while (cc == 0); 648cf6c252SPaul Traina return (cc); 658cf6c252SPaul Traina } 668cf6c252SPaul Traina 678cf6c252SPaul Traina int 688cf6c252SPaul Traina pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 698cf6c252SPaul Traina { 708cf6c252SPaul Traina for (;;) { 718cf6c252SPaul Traina int n = pcap_dispatch(p, cnt, callback, user); 728cf6c252SPaul Traina if (n <= 0) 738cf6c252SPaul Traina return (n); 748cf6c252SPaul Traina if (cnt > 0) { 758cf6c252SPaul Traina cnt -= n; 768cf6c252SPaul Traina if (cnt <= 0) 778cf6c252SPaul Traina return (0); 788cf6c252SPaul Traina } 798cf6c252SPaul Traina } 808cf6c252SPaul Traina } 818cf6c252SPaul Traina 828cf6c252SPaul Traina struct singleton { 838cf6c252SPaul Traina struct pcap_pkthdr *hdr; 848cf6c252SPaul Traina const u_char *pkt; 858cf6c252SPaul Traina }; 868cf6c252SPaul Traina 878cf6c252SPaul Traina 888cf6c252SPaul Traina static void 898cf6c252SPaul Traina pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt) 908cf6c252SPaul Traina { 918cf6c252SPaul Traina struct singleton *sp = (struct singleton *)userData; 928cf6c252SPaul Traina *sp->hdr = *h; 938cf6c252SPaul Traina sp->pkt = pkt; 948cf6c252SPaul Traina } 958cf6c252SPaul Traina 968cf6c252SPaul Traina const u_char * 978cf6c252SPaul Traina pcap_next(pcap_t *p, struct pcap_pkthdr *h) 988cf6c252SPaul Traina { 998cf6c252SPaul Traina struct singleton s; 1008cf6c252SPaul Traina 1018cf6c252SPaul Traina s.hdr = h; 1028cf6c252SPaul Traina if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0) 1038cf6c252SPaul Traina return (0); 1048cf6c252SPaul Traina return (s.pkt); 1058cf6c252SPaul Traina } 1068cf6c252SPaul Traina 1078cf6c252SPaul Traina int 1088cf6c252SPaul Traina pcap_datalink(pcap_t *p) 1098cf6c252SPaul Traina { 1108cf6c252SPaul Traina return (p->linktype); 1118cf6c252SPaul Traina } 1128cf6c252SPaul Traina 1138cf6c252SPaul Traina int 1148cf6c252SPaul Traina pcap_snapshot(pcap_t *p) 1158cf6c252SPaul Traina { 1168cf6c252SPaul Traina return (p->snapshot); 1178cf6c252SPaul Traina } 1188cf6c252SPaul Traina 1198cf6c252SPaul Traina int 1208cf6c252SPaul Traina pcap_is_swapped(pcap_t *p) 1218cf6c252SPaul Traina { 1228cf6c252SPaul Traina return (p->sf.swapped); 1238cf6c252SPaul Traina } 1248cf6c252SPaul Traina 1258cf6c252SPaul Traina int 1268cf6c252SPaul Traina pcap_major_version(pcap_t *p) 1278cf6c252SPaul Traina { 1288cf6c252SPaul Traina return (p->sf.version_major); 1298cf6c252SPaul Traina } 1308cf6c252SPaul Traina 1318cf6c252SPaul Traina int 1328cf6c252SPaul Traina pcap_minor_version(pcap_t *p) 1338cf6c252SPaul Traina { 1348cf6c252SPaul Traina return (p->sf.version_minor); 1358cf6c252SPaul Traina } 1368cf6c252SPaul Traina 1378cf6c252SPaul Traina FILE * 1388cf6c252SPaul Traina pcap_file(pcap_t *p) 1398cf6c252SPaul Traina { 1408cf6c252SPaul Traina return (p->sf.rfile); 1418cf6c252SPaul Traina } 1428cf6c252SPaul Traina 1438cf6c252SPaul Traina int 1448cf6c252SPaul Traina pcap_fileno(pcap_t *p) 1458cf6c252SPaul Traina { 1468cf6c252SPaul Traina return (p->fd); 1478cf6c252SPaul Traina } 1488cf6c252SPaul Traina 1498cf6c252SPaul Traina void 1508cf6c252SPaul Traina pcap_perror(pcap_t *p, char *prefix) 1518cf6c252SPaul Traina { 1528cf6c252SPaul Traina fprintf(stderr, "%s: %s\n", prefix, p->errbuf); 1538cf6c252SPaul Traina } 1548cf6c252SPaul Traina 1558cf6c252SPaul Traina char * 1568cf6c252SPaul Traina pcap_geterr(pcap_t *p) 1578cf6c252SPaul Traina { 1588cf6c252SPaul Traina return (p->errbuf); 1598cf6c252SPaul Traina } 1608cf6c252SPaul Traina 1618cf6c252SPaul Traina /* 1628cf6c252SPaul Traina * Not all systems have strerror(). 1638cf6c252SPaul Traina */ 1648cf6c252SPaul Traina char * 1658cf6c252SPaul Traina pcap_strerror(int errnum) 1668cf6c252SPaul Traina { 1678cf6c252SPaul Traina #ifdef HAVE_STRERROR 1688cf6c252SPaul Traina return (strerror(errnum)); 1698cf6c252SPaul Traina #else 1708cf6c252SPaul Traina extern int sys_nerr; 1718cf6c252SPaul Traina extern const char *const sys_errlist[]; 1728cf6c252SPaul Traina static char ebuf[20]; 1738cf6c252SPaul Traina 1748cf6c252SPaul Traina if ((unsigned int)errnum < sys_nerr) 1758cf6c252SPaul Traina return ((char *)sys_errlist[errnum]); 1768cf6c252SPaul Traina (void)sprintf(ebuf, "Unknown error: %d", errnum); 1778cf6c252SPaul Traina return(ebuf); 1788cf6c252SPaul Traina #endif 1798cf6c252SPaul Traina } 1808cf6c252SPaul Traina 1818cf6c252SPaul Traina void 1828cf6c252SPaul Traina pcap_close(pcap_t *p) 1838cf6c252SPaul Traina { 1848cf6c252SPaul Traina /*XXX*/ 1858cf6c252SPaul Traina if (p->fd >= 0) 1868cf6c252SPaul Traina close(p->fd); 1878cf6c252SPaul Traina if (p->sf.rfile != NULL) { 1888cf6c252SPaul Traina (void)fclose(p->sf.rfile); 1898cf6c252SPaul Traina if (p->sf.base != NULL) 1908cf6c252SPaul Traina free(p->sf.base); 1918cf6c252SPaul Traina } else if (p->buffer != NULL) 1928cf6c252SPaul Traina free(p->buffer); 1938cf6c252SPaul Traina 1948cf6c252SPaul Traina free(p); 1958cf6c252SPaul Traina } 196