pcap.c revision 98530
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
3526175Sfennerstatic const char rcsid[] =
3698530Sfenner    "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.38 2001/12/29 21:55:32 guy Exp $ (LBL)";
3717683Spst#endif
3817683Spst
3975107Sfenner#ifdef HAVE_CONFIG_H
4075107Sfenner#include "config.h"
4175107Sfenner#endif
4275107Sfenner
4317683Spst#include <sys/types.h>
4417683Spst
4517683Spst#include <stdio.h>
4617683Spst#include <stdlib.h>
4717683Spst#include <string.h>
4817683Spst#include <unistd.h>
4998530Sfenner#include <fcntl.h>
5098530Sfenner#include <errno.h>
5117683Spst
5217683Spst#ifdef HAVE_OS_PROTO_H
5317683Spst#include "os-proto.h"
5417683Spst#endif
5517683Spst
5617683Spst#include "pcap-int.h"
5717683Spst
5817683Spstint
5917683Spstpcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
6017683Spst{
6117683Spst
6217683Spst	if (p->sf.rfile != NULL)
6317683Spst		return (pcap_offline_read(p, cnt, callback, user));
6439291Sfenner	return (pcap_read(p, cnt, callback, user));
6517683Spst}
6617683Spst
6717683Spstint
6817683Spstpcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
6917683Spst{
7039291Sfenner	register int n;
7139291Sfenner
7217683Spst	for (;;) {
7339291Sfenner		if (p->sf.rfile != NULL)
7439291Sfenner			n = pcap_offline_read(p, cnt, callback, user);
7539291Sfenner		else {
7639291Sfenner			/*
7739291Sfenner			 * XXX keep reading until we get something
7839291Sfenner			 * (or an error occurs)
7939291Sfenner			 */
8039291Sfenner			do {
8139291Sfenner				n = pcap_read(p, cnt, callback, user);
8239291Sfenner			} while (n == 0);
8339291Sfenner		}
8417683Spst		if (n <= 0)
8517683Spst			return (n);
8617683Spst		if (cnt > 0) {
8717683Spst			cnt -= n;
8817683Spst			if (cnt <= 0)
8917683Spst				return (0);
9017683Spst		}
9117683Spst	}
9217683Spst}
9317683Spst
9417683Spststruct singleton {
9517683Spst	struct pcap_pkthdr *hdr;
9617683Spst	const u_char *pkt;
9717683Spst};
9817683Spst
9917683Spst
10017683Spststatic void
10117683Spstpcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt)
10217683Spst{
10317683Spst	struct singleton *sp = (struct singleton *)userData;
10417683Spst	*sp->hdr = *h;
10517683Spst	sp->pkt = pkt;
10617683Spst}
10717683Spst
10817683Spstconst u_char *
10917683Spstpcap_next(pcap_t *p, struct pcap_pkthdr *h)
11017683Spst{
11117683Spst	struct singleton s;
11217683Spst
11317683Spst	s.hdr = h;
11417683Spst	if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0)
11517683Spst		return (0);
11617683Spst	return (s.pkt);
11717683Spst}
11817683Spst
11917683Spstint
12017683Spstpcap_datalink(pcap_t *p)
12117683Spst{
12217683Spst	return (p->linktype);
12317683Spst}
12417683Spst
12517683Spstint
12617683Spstpcap_snapshot(pcap_t *p)
12717683Spst{
12817683Spst	return (p->snapshot);
12917683Spst}
13017683Spst
13117683Spstint
13217683Spstpcap_is_swapped(pcap_t *p)
13317683Spst{
13417683Spst	return (p->sf.swapped);
13517683Spst}
13617683Spst
13717683Spstint
13817683Spstpcap_major_version(pcap_t *p)
13917683Spst{
14017683Spst	return (p->sf.version_major);
14117683Spst}
14217683Spst
14317683Spstint
14417683Spstpcap_minor_version(pcap_t *p)
14517683Spst{
14617683Spst	return (p->sf.version_minor);
14717683Spst}
14817683Spst
14917683SpstFILE *
15017683Spstpcap_file(pcap_t *p)
15117683Spst{
15217683Spst	return (p->sf.rfile);
15317683Spst}
15417683Spst
15517683Spstint
15617683Spstpcap_fileno(pcap_t *p)
15717683Spst{
15817683Spst	return (p->fd);
15917683Spst}
16017683Spst
16117683Spstvoid
16217683Spstpcap_perror(pcap_t *p, char *prefix)
16317683Spst{
16417683Spst	fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
16517683Spst}
16617683Spst
16717683Spstchar *
16817683Spstpcap_geterr(pcap_t *p)
16917683Spst{
17017683Spst	return (p->errbuf);
17117683Spst}
17217683Spst
17317683Spst/*
17498530Sfenner * NOTE: in the future, these may need to call platform-dependent routines,
17598530Sfenner * e.g. on platforms with memory-mapped packet-capture mechanisms where
17698530Sfenner * "pcap_read()" uses "select()" or "poll()" to wait for packets to arrive.
17798530Sfenner */
17898530Sfennerint
17998530Sfennerpcap_getnonblock(pcap_t *p, char *errbuf)
18098530Sfenner{
18198530Sfenner	int fdflags;
18298530Sfenner
18398530Sfenner	if (p->sf.rfile != NULL) {
18498530Sfenner		/*
18598530Sfenner		 * This is a savefile, not a live capture file, so
18698530Sfenner		 * never say it's in non-blocking mode.
18798530Sfenner		 */
18898530Sfenner		return (0);
18998530Sfenner	}
19098530Sfenner	fdflags = fcntl(p->fd, F_GETFL, 0);
19198530Sfenner	if (fdflags == -1) {
19298530Sfenner		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
19398530Sfenner		    pcap_strerror(errno));
19498530Sfenner		return (-1);
19598530Sfenner	}
19698530Sfenner	if (fdflags & O_NONBLOCK)
19798530Sfenner		return (1);
19898530Sfenner	else
19998530Sfenner		return (0);
20098530Sfenner}
20198530Sfenner
20298530Sfennerint
20398530Sfennerpcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
20498530Sfenner{
20598530Sfenner	int fdflags;
20698530Sfenner
20798530Sfenner	if (p->sf.rfile != NULL) {
20898530Sfenner		/*
20998530Sfenner		 * This is a savefile, not a live capture file, so
21098530Sfenner		 * ignore requests to put it in non-blocking mode.
21198530Sfenner		 */
21298530Sfenner		return (0);
21398530Sfenner	}
21498530Sfenner	fdflags = fcntl(p->fd, F_GETFL, 0);
21598530Sfenner	if (fdflags == -1) {
21698530Sfenner		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
21798530Sfenner		    pcap_strerror(errno));
21898530Sfenner		return (-1);
21998530Sfenner	}
22098530Sfenner	if (nonblock)
22198530Sfenner		fdflags |= O_NONBLOCK;
22298530Sfenner	else
22398530Sfenner		fdflags &= ~O_NONBLOCK;
22498530Sfenner	if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
22598530Sfenner		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
22698530Sfenner		    pcap_strerror(errno));
22798530Sfenner		return (-1);
22898530Sfenner	}
22998530Sfenner	return (0);
23098530Sfenner}
23198530Sfenner
23298530Sfenner/*
23317683Spst * Not all systems have strerror().
23417683Spst */
23517683Spstchar *
23617683Spstpcap_strerror(int errnum)
23717683Spst{
23817683Spst#ifdef HAVE_STRERROR
23917683Spst	return (strerror(errnum));
24017683Spst#else
24117683Spst	extern int sys_nerr;
24217683Spst	extern const char *const sys_errlist[];
24317683Spst	static char ebuf[20];
24417683Spst
24517683Spst	if ((unsigned int)errnum < sys_nerr)
24617683Spst		return ((char *)sys_errlist[errnum]);
24775107Sfenner	(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
24817683Spst	return(ebuf);
24917683Spst#endif
25017683Spst}
25117683Spst
25275107Sfennerpcap_t *
25375107Sfennerpcap_open_dead(int linktype, int snaplen)
25475107Sfenner{
25575107Sfenner	pcap_t *p;
25675107Sfenner
25775107Sfenner	p = malloc(sizeof(*p));
25875107Sfenner	if (p == NULL)
25975107Sfenner		return NULL;
26075107Sfenner	memset (p, 0, sizeof(*p));
26175107Sfenner	p->fd = -1;
26275107Sfenner	p->snapshot = snaplen;
26375107Sfenner	p->linktype = linktype;
26475107Sfenner	return p;
26575107Sfenner}
26675107Sfenner
26717683Spstvoid
26817683Spstpcap_close(pcap_t *p)
26917683Spst{
27017683Spst	/*XXX*/
27175107Sfenner	if (p->fd >= 0) {
27275107Sfenner#ifdef linux
27375107Sfenner		pcap_close_linux(p);
27475107Sfenner#endif
27517683Spst		close(p->fd);
27675107Sfenner	}
27717683Spst	if (p->sf.rfile != NULL) {
27875107Sfenner		if (p->sf.rfile != stdin)
27975107Sfenner			(void)fclose(p->sf.rfile);
28017683Spst		if (p->sf.base != NULL)
28117683Spst			free(p->sf.base);
28217683Spst	} else if (p->buffer != NULL)
28317683Spst		free(p->buffer);
28417683Spst
28575107Sfenner	pcap_freecode(&p->fcode);
28617683Spst	free(p);
28717683Spst}
288