summaryrefslogtreecommitdiff
path: root/lib/libpcap
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2006-03-26 20:58:52 +0000
committerDamien Miller <djm@cvs.openbsd.org>2006-03-26 20:58:52 +0000
commit9abeba6a9640964dca82b6116b6410eb404ef725 (patch)
tree3175d7fa482f202499efa111b6f4df7df9c0baf4 /lib/libpcap
parentde2969b748faebff4bd8661c93932a2522f4363b (diff)
add remaining tcpdump.org libpcap 0.9 APIs, most notably
pcap_setdirection() (which depends on the kernel-side bpf changes committed yesterday); ok canacar@
Diffstat (limited to 'lib/libpcap')
-rw-r--r--lib/libpcap/inet.c12
-rw-r--r--lib/libpcap/pcap-bpf.c38
-rw-r--r--lib/libpcap/pcap-int.h6
-rw-r--r--lib/libpcap/pcap.353
-rw-r--r--lib/libpcap/pcap.c72
-rw-r--r--lib/libpcap/pcap.h32
-rw-r--r--lib/libpcap/savefile.c87
-rw-r--r--lib/libpcap/shlib_version2
8 files changed, 264 insertions, 38 deletions
diff --git a/lib/libpcap/inet.c b/lib/libpcap/inet.c
index 1382ae97b4b..48aca3d437a 100644
--- a/lib/libpcap/inet.c
+++ b/lib/libpcap/inet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: inet.c,v 1.18 2005/11/25 20:25:44 krw Exp $ */
+/* $OpenBSD: inet.c,v 1.19 2006/03/26 20:58:50 djm Exp $ */
/*
* Copyright (c) 1994, 1995, 1996, 1997, 1998
@@ -246,13 +246,11 @@ pcap_lookupdev(errbuf)
}
int
-pcap_lookupnet(device, netp, maskp, errbuf)
- register char *device;
- register bpf_u_int32 *netp, *maskp;
- register char *errbuf;
+pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
+ char *errbuf)
{
- register int fd;
- register struct sockaddr_in *sin;
+ int fd;
+ struct sockaddr_in *sin;
struct ifreq ifr;
fd = socket(AF_INET, SOCK_DGRAM, 0);
diff --git a/lib/libpcap/pcap-bpf.c b/lib/libpcap/pcap-bpf.c
index 60b5cc7b140..bc988b1325f 100644
--- a/lib/libpcap/pcap-bpf.c
+++ b/lib/libpcap/pcap-bpf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcap-bpf.c,v 1.19 2006/01/16 22:45:57 reyk Exp $ */
+/* $OpenBSD: pcap-bpf.c,v 1.20 2006/03/26 20:58:51 djm Exp $ */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1998
@@ -170,6 +170,13 @@ pcap_inject(pcap_t *p, const void *buf, size_t len)
return (write(p->fd, buf, len));
}
+int
+pcap_sendpacket(pcap_t *p, const u_char *buf, int size)
+{
+ return (pcap_inject(p, buf, size) == -1 ? -1 : 0);
+}
+
+/* ARGSUSED */
static __inline int
bpf_open(pcap_t *p, char *errbuf)
{
@@ -340,7 +347,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
- int buflen;
+ size_t buflen;
/*
* It looks that BPF code generated by gen_protochain() is not
* compatible with some of kernel BPF code (for example BSD/OS 3.1).
@@ -367,6 +374,33 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp)
}
int
+pcap_setdirection(pcap_t *p, pcap_direction_t d)
+{
+ u_int dirfilt;
+
+ switch (d) {
+ case PCAP_D_INOUT:
+ dirfilt = 0;
+ break;
+ case PCAP_D_IN:
+ dirfilt = BPF_DIRECTION_OUT;
+ break;
+ case PCAP_D_OUT:
+ dirfilt = BPF_DIRECTION_IN;
+ break;
+ default:
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Invalid direction");
+ return (-1);
+ }
+ if (ioctl(p->fd, BIOCSDIRFILT, &dirfilt) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSDIRFILT: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ return (0);
+}
+
+int
pcap_set_datalink(pcap_t *p, int dlt)
{
int i;
diff --git a/lib/libpcap/pcap-int.h b/lib/libpcap/pcap-int.h
index e5d2e204b33..d870d326bca 100644
--- a/lib/libpcap/pcap-int.h
+++ b/lib/libpcap/pcap-int.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcap-int.h,v 1.10 2005/11/18 11:05:39 djm Exp $ */
+/* $OpenBSD: pcap-int.h,v 1.11 2006/03/26 20:58:51 djm Exp $ */
/*
* Copyright (c) 1994, 1995, 1996
@@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#) $Header: /cvs/OpenBSD/src/lib/libpcap/pcap-int.h,v 1.10 2005/11/18 11:05:39 djm Exp $ (LBL)
+ * @(#) $Header: /cvs/OpenBSD/src/lib/libpcap/pcap-int.h,v 1.11 2006/03/26 20:58:51 djm Exp $ (LBL)
*/
#ifndef pcap_int_h
@@ -104,6 +104,8 @@ struct pcap {
u_int *dlt_list;
char errbuf[PCAP_ERRBUF_SIZE];
+
+ struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
};
/*
diff --git a/lib/libpcap/pcap.3 b/lib/libpcap/pcap.3
index 3a4c30774ee..5e35c94d456 100644
--- a/lib/libpcap/pcap.3
+++ b/lib/libpcap/pcap.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pcap.3,v 1.27 2005/11/18 15:27:09 jmc Exp $
+.\" $OpenBSD: pcap.3,v 1.28 2006/03/26 20:58:51 djm Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
@@ -33,10 +33,12 @@
.Fn pcap_open_offline "char *fname" "char *errbuf"
.Ft "pcap_dumper_t *"
.Fn pcap_dump_open "pcap_t *p" "char *fname"
+.Ft "pcap_dumper_t *"
+.Fn pcap_dump_fopen "pcap_t *p" "FILE *f"
.Ft "char *"
.Fn pcap_lookupdev "char *errbuf"
.Ft uint
-.Fn pcap_lookupnet "char *device" "bpf_u_int32 *netp" "bpf_u_int32 *maskp" "char *errbuf"
+.Fn pcap_lookupnet "const char *device" "bpf_u_int32 *netp" "bpf_u_int32 *maskp" "char *errbuf"
.Ft int
.Fn pcap_dispatch "pcap_t *p" "int cnt" "pcap_handler callback" "u_char *user"
.Ft int
@@ -46,6 +48,8 @@
.Ft int
.Fn pcap_inject "pcap_t *p" "void *, size_t"
.Ft int
+.Fn pcap_sendpacket "pcap_t *p" "void *, int"
+.Ft int
.Fn pcap_compile "pcap_t *p" "struct bpf_program *fp" "char *str" "int optimize" "bpf_u_int32 netmask"
.Ft int
.Fn pcap_setfilter "pcap_t *p" "struct bpf_program *fp"
@@ -54,6 +58,10 @@
.Ft "u_char *"
.Fn pcap_next "pcap_t *p" "struct pcap_pkthdr *h"
.Ft int
+.Fn pcap_next_ex "pcap_t *p" "struct pcap_pkthdr **hp" "const u_char **pktp"
+.Ft int
+.Fn pcap_setdirection "pcap_t *p" "pcap_direction_t dir"
+.Ft int
.Fn pcap_datalink "pcap_t *p"
.Ft int
.Fn pcap_snapshot "pcap_t *p"
@@ -77,6 +85,12 @@
.Fn pcap_strerror "int error"
.Ft void
.Fn pcap_close "pcap_t *p"
+.Ft "FILE *"
+.Fn pcap_dump_file "pcap_dumper_t *p"
+.Ft long
+.Fn pcap_dump_ftell "pcap_dumper_t *p"
+.Ft int
+.Fn pcap_dump_flush "pcap_dumper_t *p"
.Ft void
.Fn pcap_dump_close "pcap_dumper_t *p"
.Ft int
@@ -95,6 +109,8 @@
.Fn pcap_list_datalinks "pcap_t *p" "int **dlts"
.Ft pcap_t
.Fn pcap_open_dead "int linktype" "int snaplen"
+.Ft pcap_t
+.Fn pcap_fopen_offline "FILE *fp" "char *errbuf"
.Ft const char *
.Fn pcap_lib_version "void"
.Ft const char *
@@ -187,6 +203,10 @@ is returned,
.Fn pcap_geterr
can be used to get the error text.
.Pp
+.Fn pcap_dump_fopen
+allows the use of savefile functions on the already-opened stream
+.Dq f .
+.Pp
.Fn pcap_lookupdev
returns a pointer to a network device suitable for use with
.Fn pcap_open_live
@@ -257,6 +277,11 @@ Note that its calling arguments are suitable for use with
uses
.Xr write 2
to inject a raw packet through the network interface.
+It returns the number of bytes written or \-1 on failure.
+.Pp
+.Fn pcap_sendpacket
+is an alternate interface for packet injection (provided for compatibility).
+It returns 0 on success or \-1 on failure.
.Pp
.Fn pcap_compile
is used to compile the string
@@ -325,6 +350,13 @@ returns a
.Fa u_char
pointer to the next packet.
.Pp
+.Fn pcap_next_ex
+reads the next packet and returns a success/failure indication: a
+return value of 1 indicates success, 0 means that the timeout was exceeded
+on a live capture, \-1 indicates that an error occurred whilst reading
+the packet and \-2 is returned when there are no more packets to read in a
+savefile.
+.Pp
.Fn pcap_datalink
returns the link layer type, e.g.,
.Tn DLT_EN10MB .
@@ -382,6 +414,15 @@ closes the files associated with
.Fa p
and deallocates resources.
.Pp
+.Fn pcap_dump_file
+returns the stream associated with a savefile.
+.Pp
+.Fn pcap_dump_ftell
+returns the current file offset within a savefile.
+.Pp
+.Fn pcap_dump_flush
+ensures that any buffered data has been written to a savefile.
+.Pp
.Fn pcap_dump_close
closes the savefile.
.Pp
@@ -405,6 +446,10 @@ sets or resets non-blocking mode on a capture file descriptor.
sets the datalink type on a live capture device that supports multiple
datalink types.
.Pp
+.Fn pcap_setdirection
+is used to limit the direction that packets must be flowing in order
+to be captured.
+.Pp
.Fn pcap_list_datalinks
returns an array of the supported datalink types for an opened live capture
device as a \-1 terminated array.
@@ -421,6 +466,10 @@ is used for creating a pcap_t structure to use when calling the
other functions in libpcap.
It is typically used when just using libpcap for compiling BPF code.
.Pp
+.Fn pcap_fopen_offline
+may be used to read dumped data from an existing open stream
+.Dq fp .
+.Pp
.Fn pcap_lib_version
returns a string describing the version of libpcap.
.Fn pcap_datalink_val_to_name
diff --git a/lib/libpcap/pcap.c b/lib/libpcap/pcap.c
index 30f58292718..6c516f39e32 100644
--- a/lib/libpcap/pcap.c
+++ b/lib/libpcap/pcap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcap.c,v 1.9 2005/11/18 11:05:39 djm Exp $ */
+/* $OpenBSD: pcap.c,v 1.10 2006/03/26 20:58:51 djm Exp $ */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
@@ -111,6 +111,70 @@ pcap_next(pcap_t *p, struct pcap_pkthdr *h)
return (s.pkt);
}
+struct pkt_for_fakecallback {
+ struct pcap_pkthdr *hdr;
+ const u_char **pkt;
+};
+
+static void
+pcap_fakecallback(u_char *userData, const struct pcap_pkthdr *h,
+ const u_char *pkt)
+{
+ struct pkt_for_fakecallback *sp = (struct pkt_for_fakecallback *)userData;
+
+ *sp->hdr = *h;
+ *sp->pkt = pkt;
+}
+
+int
+pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
+ const u_char **pkt_data)
+{
+ struct pkt_for_fakecallback s;
+
+ s.hdr = &p->pcap_header;
+ s.pkt = pkt_data;
+
+ /* Saves a pointer to the packet headers */
+ *pkt_header= &p->pcap_header;
+
+ if (p->sf.rfile != NULL) {
+ int status;
+
+ /* We are on an offline capture */
+ status = pcap_offline_read(p, 1, pcap_fakecallback,
+ (u_char *)&s);
+
+ /*
+ * Return codes for pcap_offline_read() are:
+ * - 0: EOF
+ * - -1: error
+ * - >1: OK
+ * The first one ('0') conflicts with the return code of
+ * 0 from pcap_read() meaning "no packets arrived before
+ * the timeout expired", so we map it to -2 so you can
+ * distinguish between an EOF from a savefile and a
+ * "no packets arrived before the timeout expired, try
+ * again" from a live capture.
+ */
+ if (status == 0)
+ return (-2);
+ else
+ return (status);
+ }
+
+ /*
+ * Return codes for pcap_read() are:
+ * - 0: timeout
+ * - -1: error
+ * - -2: loop was broken out of with pcap_breakloop()
+ * - >1: OK
+ * The first one ('0') conflicts with the return code of 0 from
+ * pcap_offline_read() meaning "end of file".
+ */
+ return (pcap_read(p, 1, pcap_fakecallback, (u_char *)&s));
+}
+
/*
* Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate.
*/
@@ -271,6 +335,12 @@ pcap_perror(pcap_t *p, char *prefix)
fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
}
+int
+pcap_get_selectable_fd(pcap_t *p)
+{
+ return (p->fd);
+}
+
char *
pcap_geterr(pcap_t *p)
{
diff --git a/lib/libpcap/pcap.h b/lib/libpcap/pcap.h
index f4c0e2eade6..bb71365e32a 100644
--- a/lib/libpcap/pcap.h
+++ b/lib/libpcap/pcap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcap.h,v 1.13 2005/11/18 11:05:39 djm Exp $ */
+/* $OpenBSD: pcap.h,v 1.14 2006/03/26 20:58:51 djm Exp $ */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
@@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#) $Header: /cvs/OpenBSD/src/lib/libpcap/pcap.h,v 1.13 2005/11/18 11:05:39 djm Exp $ (LBL)
+ * @(#) $Header: /cvs/OpenBSD/src/lib/libpcap/pcap.h,v 1.14 2006/03/26 20:58:51 djm Exp $ (LBL)
*/
#ifndef lib_pcap_h
@@ -80,6 +80,12 @@ struct pcap_file_header {
bpf_u_int32 linktype; /* data link type (DLT_*) */
};
+typedef enum {
+ PCAP_D_INOUT = 0,
+ PCAP_D_IN,
+ PCAP_D_OUT
+} pcap_direction_t;
+
/*
* Each packet in the dump file is prepended with this generic header.
* This gets around the problem of different headers for different
@@ -129,21 +135,26 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
__BEGIN_DECLS
char *pcap_lookupdev(char *);
-int pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
+int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_open_live(const char *, int, int, int, char *);
-pcap_t *pcap_open_offline(const char *, char *);
pcap_t *pcap_open_dead(int, int);
+pcap_t *pcap_open_offline(const char *, char *);
+pcap_t *pcap_fopen_offline(FILE *, char *);
void pcap_close(pcap_t *);
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
const u_char*
pcap_next(pcap_t *, struct pcap_pkthdr *);
+int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
+void pcap_breakloop(pcap_t *);
int pcap_stats(pcap_t *, struct pcap_stat *);
-int pcap_inject(pcap_t *, const void *, size_t);
int pcap_setfilter(pcap_t *, struct bpf_program *);
+int pcap_setdirection(pcap_t *, pcap_direction_t);
int pcap_getnonblock(pcap_t *, char *);
int pcap_setnonblock(pcap_t *, int, char *);
void pcap_perror(pcap_t *, char *);
+int pcap_inject(pcap_t *, const void *, size_t);
+int pcap_sendpacket(pcap_t *, const u_char *, int);
char *pcap_strerror(int);
char *pcap_geterr(pcap_t *);
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
@@ -151,14 +162,12 @@ int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
int pcap_compile_nopcap(int, int, struct bpf_program *,
char *, int, bpf_u_int32);
void pcap_freecode(struct bpf_program *);
-void pcap_breakloop(pcap_t *);
int pcap_datalink(pcap_t *);
int pcap_list_datalinks(pcap_t *, int **);
int pcap_set_datalink(pcap_t *, int);
int pcap_datalink_name_to_val(const char *);
const char *pcap_datalink_val_to_name(int);
const char *pcap_datalink_val_to_description(int);
-const char *pcap_lib_version(void);
int pcap_snapshot(pcap_t *);
int pcap_is_swapped(pcap_t *);
int pcap_major_version(pcap_t *);
@@ -169,14 +178,23 @@ FILE *pcap_file(pcap_t *);
int pcap_fileno(pcap_t *);
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
+pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
+FILE *pcap_dump_file(pcap_dumper_t *);
+long pcap_dump_ftell(pcap_dumper_t *);
+int pcap_dump_flush(pcap_dumper_t *);
void pcap_dump_close(pcap_dumper_t *);
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
int pcap_findalldevs(pcap_if_t **, char *);
void pcap_freealldevs(pcap_if_t *);
+const char *pcap_lib_version(void);
+
/* XXX this guy lives in the bpf tree */
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
char *bpf_image(struct bpf_insn *, int);
+
+int pcap_get_selectable_fd(pcap_t *);
+
__END_DECLS
#endif
diff --git a/lib/libpcap/savefile.c b/lib/libpcap/savefile.c
index 7652fa9fa23..e9ccefff3c0 100644
--- a/lib/libpcap/savefile.c
+++ b/lib/libpcap/savefile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: savefile.c,v 1.8 2004/01/27 06:58:03 tedu Exp $ */
+/* $OpenBSD: savefile.c,v 1.9 2006/03/26 20:58:51 djm Exp $ */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
@@ -101,8 +101,31 @@ swap_hdr(struct pcap_file_header *hp)
pcap_t *
pcap_open_offline(const char *fname, char *errbuf)
{
- register pcap_t *p;
- register FILE *fp;
+ pcap_t *p;
+ FILE *fp;
+
+ if (fname[0] == '-' && fname[1] == '\0')
+ fp = stdin;
+ else {
+ fp = fopen(fname, "r");
+ if (fp == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
+ pcap_strerror(errno));
+ return (NULL);
+ }
+ }
+ p = pcap_fopen_offline(fp, errbuf);
+ if (p == NULL) {
+ if (fp != stdin)
+ fclose(fp);
+ }
+ return (p);
+}
+
+pcap_t *
+pcap_fopen_offline(FILE *fp, char *errbuf)
+{
+ pcap_t *p;
struct pcap_file_header hdr;
int linklen;
@@ -114,20 +137,10 @@ pcap_open_offline(const char *fname, char *errbuf)
memset((char *)p, 0, sizeof(*p));
/*
- * Set this field so we don't close stdin in pcap_close!
+ * Set this field so we don't double-close in pcap_close!
*/
p->fd = -1;
- if (fname[0] == '-' && fname[1] == '\0')
- fp = stdin;
- else {
- fp = fopen(fname, "r");
- if (fp == NULL) {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
- pcap_strerror(errno));
- goto bad;
- }
- }
if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s",
pcap_strerror(errno));
@@ -328,6 +341,19 @@ pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
(void)fwrite((char *)sp, h->caplen, 1, f);
}
+static pcap_dumper_t *
+pcap_setup_dump(pcap_t *p, FILE *f, const char *fname)
+{
+ if (sf_write_header(f, p->linktype, p->tzoff, p->snapshot) == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
+ fname, pcap_strerror(errno));
+ if (f != stdout)
+ (void)fclose(f);
+ return (NULL);
+ }
+ return ((pcap_dumper_t *)f);
+}
+
/*
* Initialize so that sf_write() will output to the file named 'fname'.
*/
@@ -345,8 +371,37 @@ pcap_dump_open(pcap_t *p, const char *fname)
return (NULL);
}
}
- (void)sf_write_header(f, p->linktype, p->tzoff, p->snapshot);
- return ((pcap_dumper_t *)f);
+ return (pcap_setup_dump(p, f, fname));
+}
+
+/*
+ * Initialize so that sf_write() will output to the given stream.
+ */
+pcap_dumper_t *
+pcap_dump_fopen(pcap_t *p, FILE *f)
+{
+ return (pcap_setup_dump(p, f, "stream"));
+}
+
+FILE *
+pcap_dump_file(pcap_dumper_t *p)
+{
+ return ((FILE *)p);
+}
+
+long
+pcap_dump_ftell(pcap_dumper_t *p)
+{
+ return (ftell((FILE *)p));
+}
+
+pcap_dump_flush(pcap_dumper_t *p)
+{
+
+ if (fflush((FILE *)p) == EOF)
+ return (-1);
+ else
+ return (0);
}
void
diff --git a/lib/libpcap/shlib_version b/lib/libpcap/shlib_version
index d9961ea9fef..3066b9771e7 100644
--- a/lib/libpcap/shlib_version
+++ b/lib/libpcap/shlib_version
@@ -1,2 +1,2 @@
-major=4
+major=5
minor=0