1 /* $NetBSD: loop-bsd.c,v 1.9 2006/10/07 17:27:57 elad Exp $ */
4 * Copyright (c) 1993-95 Mats O Jansson. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
29 __RCSID("$NetBSD: loop-bsd.c,v 1.9 2006/10/07 17:27:57 elad Exp $");
36 #if defined(__bsdi__) || defined(__FreeBSD__) || defined(__NetBSD__)
40 #include <sys/ioctl.h>
56 return (*(p
->iopen
))(p
->if_name
,
71 return (*(p
->iopen
))(p
->if_name
,
91 * The list of all interfaces that are being listened to. loop()
92 * "polls" on the descriptors in this list.
94 struct if_info
*iflist
;
96 void mopProcess
__P((struct if_info
*, u_char
*));
99 * Loop indefinitely listening for MOP requests on the
100 * interfaces in 'iflist'.
105 u_char
*buf
, *bp
, *ep
;
112 mopLogErrX("no interfaces");
113 if (iflist
->fd
!= -1) {
114 if (ioctl(iflist
->fd
, BIOCGBLEN
, (caddr_t
) & bufsize
) < 0)
115 mopLogErr("BIOCGBLEN");
117 mopLogErrX("cannot get buffer size");
118 buf
= (u_char
*) malloc((unsigned) bufsize
);
122 * Find the highest numbered file descriptor for poll().
123 * Initialize the set of descriptors to listen to.
125 for (ii
= iflist
, n
= 0; ii
; ii
= ii
->next
, n
++)
127 set
= malloc(n
* sizeof(*set
));
128 for (ii
= iflist
, m
= 0; ii
; ii
= ii
->next
, m
++) {
129 assert(ii
->fd
!= -1);
131 set
[m
].events
= POLLIN
;
134 if (poll(set
, n
, INFTIM
) < 0)
136 for (ii
= iflist
, m
= 0; ii
; ii
= ii
->next
, m
++) {
137 if (!(set
[m
].revents
& POLLIN
))
140 cc
= read(ii
->fd
, (char *) buf
, bufsize
);
141 /* Don't choke when we get ptraced */
142 if (cc
< 0 && errno
== EINTR
)
144 /* Due to a SunOS bug, after 2^31 bytes, the file
145 * offset overflows and read fails with EINVAL. The
146 * lseek() to 0 will fix things. */
148 if (errno
== EINVAL
&&
149 (lseek(ii
->fd
, 0, SEEK_CUR
) + bufsize
) < 0) {
150 (void) lseek(ii
->fd
, 0, 0);
155 /* Loop through the packet(s) */
156 #define bhp ((struct bpf_hdr *)bp)
162 caplen
= bhp
->bh_caplen
;
163 hdrlen
= bhp
->bh_hdrlen
;
164 mopProcess(ii
, bp
+ hdrlen
);
165 bp
+= BPF_WORDALIGN(hdrlen
+ caplen
);