]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libpcap/pcap-bpf.c
This commit was generated by cvs2svn to compensate for changes in r95978,
[FreeBSD/FreeBSD.git] / contrib / libpcap / pcap-bpf.c
1 /*
2  * Copyright (c) 1993, 1994, 1995, 1996, 1998
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  */
21 #ifndef lint
22 static const char rcsid[] =
23     "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.44 2000/10/28 00:01:28 guy Exp $ (LBL)";
24 #endif
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <sys/param.h>                  /* optionally get BSD define */
31 #include <sys/time.h>
32 #include <sys/timeb.h>
33 #include <sys/socket.h>
34 #include <sys/file.h>
35 #include <sys/ioctl.h>
36
37 #include <net/if.h>
38
39 #include <ctype.h>
40 #include <errno.h>
41 #include <netdb.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46
47 #include "pcap-int.h"
48
49 #ifdef HAVE_OS_PROTO_H
50 #include "os-proto.h"
51 #endif
52
53 #include "gencode.h"
54
55 int
56 pcap_stats(pcap_t *p, struct pcap_stat *ps)
57 {
58         struct bpf_stat s;
59
60         if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
61                 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s",
62                     pcap_strerror(errno));
63                 return (-1);
64         }
65
66         ps->ps_recv = s.bs_recv;
67         ps->ps_drop = s.bs_drop;
68         return (0);
69 }
70
71 int
72 pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
73 {
74         int cc;
75         int n = 0;
76         register u_char *bp, *ep;
77
78  again:
79         cc = p->cc;
80         if (p->cc == 0) {
81                 cc = read(p->fd, (char *)p->buffer, p->bufsize);
82                 if (cc < 0) {
83                         /* Don't choke when we get ptraced */
84                         switch (errno) {
85
86                         case EINTR:
87                                 goto again;
88
89                         case EWOULDBLOCK:
90                                 return (0);
91 #if defined(sun) && !defined(BSD)
92                         /*
93                          * Due to a SunOS bug, after 2^31 bytes, the kernel
94                          * file offset overflows and read fails with EINVAL.
95                          * The lseek() to 0 will fix things.
96                          */
97                         case EINVAL:
98                                 if (lseek(p->fd, 0L, SEEK_CUR) +
99                                     p->bufsize < 0) {
100                                         (void)lseek(p->fd, 0L, SEEK_SET);
101                                         goto again;
102                                 }
103                                 /* fall through */
104 #endif
105                         }
106                         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s",
107                             pcap_strerror(errno));
108                         return (-1);
109                 }
110                 bp = p->buffer;
111         } else
112                 bp = p->bp;
113
114         /*
115          * Loop through each packet.
116          */
117 #define bhp ((struct bpf_hdr *)bp)
118         ep = bp + cc;
119         while (bp < ep) {
120                 register int caplen, hdrlen;
121                 caplen = bhp->bh_caplen;
122                 hdrlen = bhp->bh_hdrlen;
123                 /*
124                  * XXX A bpf_hdr matches a pcap_pkthdr.
125                  */
126                 (*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
127                 bp += BPF_WORDALIGN(caplen + hdrlen);
128                 if (++n >= cnt && cnt > 0) {
129                         p->bp = bp;
130                         p->cc = ep - bp;
131                         return (n);
132                 }
133         }
134 #undef bhp
135         p->cc = 0;
136         return (n);
137 }
138
139 static inline int
140 bpf_open(pcap_t *p, char *errbuf)
141 {
142         int fd;
143         int n = 0;
144         char device[sizeof "/dev/bpf0000000000"];
145
146         /*
147          * Go through all the minors and find one that isn't in use.
148          */
149         do {
150                 (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
151                 fd = open(device, O_RDONLY);
152         } while (fd < 0 && errno == EBUSY);
153
154         /*
155          * XXX better message for all minors used
156          */
157         if (fd < 0)
158                 snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s",
159                     device, pcap_strerror(errno));
160
161         return (fd);
162 }
163
164 pcap_t *
165 pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
166 {
167         int fd;
168         struct ifreq ifr;
169         struct bpf_version bv;
170         u_int v;
171         pcap_t *p;
172
173         p = (pcap_t *)malloc(sizeof(*p));
174         if (p == NULL) {
175                 snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
176                     pcap_strerror(errno));
177                 return (NULL);
178         }
179         memset(p, 0, sizeof(*p));
180         fd = bpf_open(p, ebuf);
181         if (fd < 0)
182                 goto bad;
183
184         p->fd = fd;
185         p->snapshot = snaplen;
186
187         if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
188                 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
189                     pcap_strerror(errno));
190                 goto bad;
191         }
192         if (bv.bv_major != BPF_MAJOR_VERSION ||
193             bv.bv_minor < BPF_MINOR_VERSION) {
194                 snprintf(ebuf, PCAP_ERRBUF_SIZE,
195                     "kernel bpf filter out of date");
196                 goto bad;
197         }
198
199         /*
200          * Try finding a good size for the buffer; 32768 may be too
201          * big, so keep cutting it in half until we find a size
202          * that works, or run out of sizes to try.
203          *
204          * XXX - there should be a user-accessible hook to set the
205          * initial buffer size.
206          */
207         for (v = 32768; v != 0; v >>= 1) {
208                 /* Ignore the return value - this is because the call fails
209                  * on BPF systems that don't have kernel malloc.  And if
210                  * the call fails, it's no big deal, we just continue to
211                  * use the standard buffer size.
212                  */
213                 (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
214
215                 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
216                 if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
217                         break;  /* that size worked; we're done */
218
219                 if (errno != ENOBUFS) {
220                         snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
221                             device, pcap_strerror(errno));
222                         goto bad;
223                 }
224         }
225
226         if (v == 0) {
227                 snprintf(ebuf, PCAP_ERRBUF_SIZE,
228                          "BIOCSBLEN: %s: No buffer size worked", device);
229                 goto bad;
230         }
231
232         /* Get the data link layer type. */
233         if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
234                 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
235                     pcap_strerror(errno));
236                 goto bad;
237         }
238 #ifdef __OpenBSD__
239         switch (v) {
240         case DLT_LOOP:
241                 /*
242                  * XXX - DLT_LOOP has a network-byte-order, rather than
243                  * a host-byte-order, AF_ value as the link-layer
244                  * header; will the BPF code generator handle that
245                  * correctly on little-endian machines?
246                  */
247                 v = DLT_NULL;
248                 break;
249         }
250 #endif
251 #if _BSDI_VERSION - 0 >= 199510
252         /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */
253         switch (v) {
254
255         case DLT_SLIP:
256                 v = DLT_SLIP_BSDOS;
257                 break;
258
259         case DLT_PPP:
260                 v = DLT_PPP_BSDOS;
261                 break;
262
263         case 11:        /*DLT_FR*/
264                 v = DLT_RAW;    /*XXX*/
265                 break;
266
267         case 12:        /*DLT_C_HDLC*/
268                 v = DLT_CHDLC;
269                 break;
270         }
271 #endif
272         p->linktype = v;
273
274         /* set timeout */
275         if (to_ms != 0) {
276                 struct timeval to;
277                 to.tv_sec = to_ms / 1000;
278                 to.tv_usec = (to_ms * 1000) % 1000000;
279                 if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
280                         snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
281                             pcap_strerror(errno));
282                         goto bad;
283                 }
284         }
285
286 #ifdef _AIX
287 #ifdef  BIOCIMMEDIATE
288         /*
289          * Darren Reed notes that
290          *
291          *      On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the
292          *      timeout appears to be ignored and it waits until the buffer
293          *      is filled before returning.  The result of not having it
294          *      set is almost worse than useless if your BPF filter
295          *      is reducing things to only a few packets (i.e. one every
296          *      second or so).
297          *
298          * so we turn BIOCIMMEDIATE mode on if this is AIX.
299          *
300          * We don't turn it on for other platforms, as that means we
301          * get woken up for every packet, which may not be what we want;
302          * in the Winter 1993 USENIX paper on BPF, they say:
303          *
304          *      Since a process might want to look at every packet on a
305          *      network and the time between packets can be only a few
306          *      microseconds, it is not possible to do a read system call
307          *      per packet and BPF must collect the data from several
308          *      packets and return it as a unit when the monitoring
309          *      application does a read.
310          *
311          * which I infer is the reason for the timeout - it means we
312          * wait that amount of time, in the hopes that more packets
313          * will arrive and we'll get them all with one read.
314          *
315          * Setting BIOCIMMEDIATE mode on FreeBSD (and probably other
316          * BSDs) causes the timeout to be ignored.
317          *
318          * On the other hand, some platforms (e.g., Linux) don't support
319          * timeouts, they just hand stuff to you as soon as it arrives;
320          * if that doesn't cause a problem on those platforms, it may
321          * be OK to have BIOCIMMEDIATE mode on BSD as well.
322          *
323          * (Note, though, that applications may depend on the read
324          * completing, even if no packets have arrived, when the timeout
325          * expires, e.g. GUI applications that have to check for input
326          * while waiting for packets to arrive; a non-zero timeout
327          * prevents "select()" from working right on FreeBSD and
328          * possibly other BSDs, as the timer doesn't start until a
329          * "read()" is done, so the timer isn't in effect if the
330          * application is blocked on a "select()", and the "select()"
331          * doesn't get woken up for a BPF device until the buffer
332          * fills up.)
333          */
334         v = 1;
335         if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
336                 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
337                     pcap_strerror(errno));
338                 goto bad;
339         }
340 #endif  /* BIOCIMMEDIATE */
341 #endif  /* _AIX */
342
343         if (promisc)
344                 /* set promiscuous mode, okay if it fails */
345                 (void)ioctl(p->fd, BIOCPROMISC, NULL);
346
347         if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
348                 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
349                     pcap_strerror(errno));
350                 goto bad;
351         }
352         p->bufsize = v;
353         p->buffer = (u_char *)malloc(p->bufsize);
354         if (p->buffer == NULL) {
355                 snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
356                     pcap_strerror(errno));
357                 goto bad;
358         }
359
360         return (p);
361  bad:
362         (void)close(fd);
363         free(p);
364         return (NULL);
365 }
366
367 int
368 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
369 {
370         /*
371          * It looks that BPF code generated by gen_protochain() is not
372          * compatible with some of kernel BPF code (for example BSD/OS 3.1).
373          * Take a safer side for now.
374          */
375         if (no_optimize) {
376                 if (install_bpf_program(p, fp) < 0)
377                         return (-1);
378         } else if (p->sf.rfile != NULL) {
379                 if (install_bpf_program(p, fp) < 0)
380                         return (-1);
381         } else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
382                 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
383                     pcap_strerror(errno));
384                 return (-1);
385         }
386         return (0);
387 }