bpf.c revision 252628
1176667Sjfv/*	$OpenBSD: bpf.c,v 1.13 2004/05/05 14:28:58 deraadt Exp $	*/
2176667Sjfv
3247064Sjfv/* BPF socket interface code, originally contributed by Archie Cobbs. */
4176667Sjfv
5176667Sjfv/*
6176667Sjfv * Copyright (c) 1995, 1996, 1998, 1999
7176667Sjfv * The Internet Software Consortium.    All rights reserved.
8176667Sjfv *
9176667Sjfv * Redistribution and use in source and binary forms, with or without
10176667Sjfv * modification, are permitted provided that the following conditions
11176667Sjfv * are met:
12176667Sjfv *
13176667Sjfv * 1. Redistributions of source code must retain the above copyright
14176667Sjfv *    notice, this list of conditions and the following disclaimer.
15176667Sjfv * 2. Redistributions in binary form must reproduce the above copyright
16176667Sjfv *    notice, this list of conditions and the following disclaimer in the
17176667Sjfv *    documentation and/or other materials provided with the distribution.
18176667Sjfv * 3. Neither the name of The Internet Software Consortium nor the names
19176667Sjfv *    of its contributors may be used to endorse or promote products derived
20176667Sjfv *    from this software without specific prior written permission.
21176667Sjfv *
22176667Sjfv * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23176667Sjfv * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24176667Sjfv * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25176667Sjfv * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26176667Sjfv * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27176667Sjfv * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28176667Sjfv * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29176667Sjfv * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30176667Sjfv * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31176667Sjfv * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32176667Sjfv * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33176667Sjfv * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34176667Sjfv * SUCH DAMAGE.
35176667Sjfv *
36176667Sjfv * This software has been written for the Internet Software Consortium
37176667Sjfv * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
38228386Sjfv * Enterprises.  To learn more about the Internet Software Consortium,
39228386Sjfv * see ``http://www.vix.com/isc''.  To learn more about Vixie
40228386Sjfv * Enterprises, see ``http://www.vix.com''.
41228386Sjfv */
42176667Sjfv
43176667Sjfv#include <sys/cdefs.h>
44176667Sjfv__FBSDID("$FreeBSD: head/sbin/dhclient/bpf.c 252628 2013-07-03 22:16:02Z pjd $");
45176667Sjfv
46176667Sjfv#include "dhcpd.h"
47176667Sjfv#include "privsep.h"
48181027Sjfv#include <sys/capability.h>
49181027Sjfv#include <sys/ioctl.h>
50181027Sjfv#include <sys/uio.h>
51181027Sjfv
52228386Sjfv#include <net/bpf.h>
53228386Sjfv#include <netinet/in_systm.h>
54228386Sjfv#include <netinet/ip.h>
55228386Sjfv#include <netinet/udp.h>
56228386Sjfv#include <netinet/if_ether.h>
57228386Sjfv
58228386Sjfv#define BPF_FORMAT "/dev/bpf%d"
59176667Sjfv
60176667Sjfv/*
61176667Sjfv * Called by get_interface_list for each interface that's discovered.
62200243Sjfv * Opens a packet filter for each interface and adds it to the select
63176667Sjfv * mask.
64176667Sjfv */
65176667Sjfvint
66228386Sjfvif_register_bpf(struct interface_info *info, int flags)
67228386Sjfv{
68228386Sjfv	char filename[50];
69228386Sjfv	int sock, b;
70176667Sjfv
71176667Sjfv	/* Open a BPF device */
72176667Sjfv	for (b = 0;; b++) {
73176667Sjfv		snprintf(filename, sizeof(filename), BPF_FORMAT, b);
74176667Sjfv		sock = open(filename, flags);
75228386Sjfv		if (sock < 0) {
76228386Sjfv			if (errno == EBUSY)
77228386Sjfv				continue;
78228386Sjfv			else
79176667Sjfv				error("Can't find free bpf: %m");
80176667Sjfv		} else
81176667Sjfv			break;
82176667Sjfv	}
83228386Sjfv
84228386Sjfv	/* Set the BPF device to point at this interface. */
85228386Sjfv	if (ioctl(sock, BIOCSETIF, info->ifp) < 0)
86228386Sjfv		error("Can't attach interface %s to bpf device %s: %m",
87228386Sjfv		    info->name, filename);
88228386Sjfv
89228386Sjfv	return (sock);
90228386Sjfv}
91228386Sjfv
92228386Sjfv/*
93228386Sjfv * Packet write filter program:
94228386Sjfv * 'ip and udp and src port bootps and dst port (bootps or bootpc)'
95228386Sjfv */
96176667Sjfvstruct bpf_insn dhcp_bpf_wfilter[] = {
97228386Sjfv	BPF_STMT(BPF_LD + BPF_B + BPF_IND, 14),
98176667Sjfv	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (IPVERSION << 4) + 5, 0, 12),
99176667Sjfv
100176667Sjfv	/* Make sure this is an IP packet... */
101176667Sjfv	BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
102176667Sjfv	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 10),
103228386Sjfv
104228386Sjfv	/* Make sure it's a UDP packet... */
105228386Sjfv	BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23),
106176667Sjfv	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 8),
107176667Sjfv
108176667Sjfv	/* Make sure this isn't a fragment... */
109176667Sjfv	BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
110176667Sjfv	BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 6, 0),	/* patched */
111176667Sjfv
112228386Sjfv	/* Get the IP header length... */
113228386Sjfv	BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14),
114228386Sjfv
115228386Sjfv	/* Make sure it's from the right port... */
116228386Sjfv	BPF_STMT(BPF_LD + BPF_H + BPF_IND, 14),
117228386Sjfv	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 68, 0, 3),
118228386Sjfv
119228386Sjfv	/* Make sure it is to the right ports ... */
120176667Sjfv	BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16),
121176667Sjfv	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
122176667Sjfv
123176667Sjfv	/* If we passed all the tests, ask for the whole packet. */
124176667Sjfv	BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
125176667Sjfv
126228386Sjfv	/* Otherwise, drop it. */
127228386Sjfv	BPF_STMT(BPF_RET+BPF_K, 0),
128228386Sjfv};
129228386Sjfv
130228386Sjfvint dhcp_bpf_wfilter_len = sizeof(dhcp_bpf_wfilter) / sizeof(struct bpf_insn);
131228386Sjfv
132228386Sjfvvoid
133228386Sjfvif_register_send(struct interface_info *info)
134176667Sjfv{
135228386Sjfv	struct bpf_version v;
136228386Sjfv	struct bpf_program p;
137228386Sjfv	int sock, on = 1;
138176667Sjfv
139228386Sjfv	/* Open a BPF device and hang it on this interface... */
140228386Sjfv	info->wfdesc = if_register_bpf(info, O_WRONLY);
141176667Sjfv
142228386Sjfv	/* Make sure the BPF version is in range... */
143228386Sjfv	if (ioctl(info->wfdesc, BIOCVERSION, &v) < 0)
144176667Sjfv		error("Can't get BPF version: %m");
145228386Sjfv
146228386Sjfv	if (v.bv_major != BPF_MAJOR_VERSION ||
147228386Sjfv	    v.bv_minor < BPF_MINOR_VERSION)
148228386Sjfv		error("Kernel BPF version out of range - recompile dhcpd!");
149228386Sjfv
150228386Sjfv	/* Set up the bpf write filter program structure. */
151228386Sjfv	p.bf_len = dhcp_bpf_wfilter_len;
152176667Sjfv	p.bf_insns = dhcp_bpf_wfilter;
153228386Sjfv
154228386Sjfv	if (dhcp_bpf_wfilter[7].k == 0x1fff)
155228386Sjfv		dhcp_bpf_wfilter[7].k = htons(IP_MF|IP_OFFMASK);
156228386Sjfv
157228386Sjfv	if (ioctl(info->wfdesc, BIOCSETWF, &p) < 0)
158228386Sjfv		error("Can't install write filter program: %m");
159181027Sjfv
160176667Sjfv	if (ioctl(info->wfdesc, BIOCLOCK, NULL) < 0)
161228386Sjfv		error("Cannot lock bpf");
162228386Sjfv
163228386Sjfv	if (cap_rights_limit(info->wfdesc, CAP_WRITE) < 0 && errno != ENOSYS)
164228386Sjfv		error("Can't limit bpf descriptor: %m");
165176667Sjfv
166176667Sjfv	/*
167228386Sjfv	 * Use raw socket for unicast send.
168228386Sjfv	 */
169228386Sjfv	if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) == -1)
170228386Sjfv		error("socket(SOCK_RAW): %m");
171176667Sjfv	if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on,
172228386Sjfv	    sizeof(on)) == -1)
173228386Sjfv		error("setsockopt(IP_HDRINCL): %m");
174176667Sjfv	info->ufdesc = sock;
175176667Sjfv}
176228386Sjfv
177228386Sjfv/*
178228386Sjfv * Packet filter program...
179228386Sjfv *
180176667Sjfv * XXX: Changes to the filter program may require changes to the
181176667Sjfv * constant offsets used in if_register_send to patch the BPF program!
182228386Sjfv */
183228386Sjfvstruct bpf_insn dhcp_bpf_filter[] = {
184228386Sjfv	/* Make sure this is an IP packet... */
185228386Sjfv	BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
186228386Sjfv	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
187228386Sjfv
188228386Sjfv	/* Make sure it's a UDP packet... */
189228386Sjfv	BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23),
190228386Sjfv	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
191228386Sjfv
192176667Sjfv	/* Make sure this isn't a fragment... */
193176667Sjfv	BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
194176667Sjfv	BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
195176667Sjfv
196228386Sjfv	/* Get the IP header length... */
197228386Sjfv	BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14),
198176667Sjfv
199176667Sjfv	/* Make sure it's to the right port... */
200176667Sjfv	BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16),
201176667Sjfv	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),		/* patch */
202200243Sjfv
203176667Sjfv	/* If we passed all the tests, ask for the whole packet. */
204200243Sjfv	BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
205218530Sjfv
206218530Sjfv	/* Otherwise, drop it. */
207176667Sjfv	BPF_STMT(BPF_RET+BPF_K, 0),
208176667Sjfv};
209176667Sjfv
210228386Sjfvint dhcp_bpf_filter_len = sizeof(dhcp_bpf_filter) / sizeof(struct bpf_insn);
211176667Sjfv
212228386Sjfvvoid
213228386Sjfvif_register_receive(struct interface_info *info)
214176667Sjfv{
215176667Sjfv	static const unsigned long cmds[2] = { SIOCGIFFLAGS, SIOCGIFMEDIA };
216176667Sjfv	struct bpf_version v;
217176667Sjfv	struct bpf_program p;
218228386Sjfv	int flag = 1, sz;
219228386Sjfv
220228386Sjfv	/* Open a BPF device and hang it on this interface... */
221176667Sjfv	info->rfdesc = if_register_bpf(info, O_RDONLY);
222176667Sjfv
223176667Sjfv	/* Make sure the BPF version is in range... */
224176667Sjfv	if (ioctl(info->rfdesc, BIOCVERSION, &v) < 0)
225228386Sjfv		error("Can't get BPF version: %m");
226228386Sjfv
227228386Sjfv	if (v.bv_major != BPF_MAJOR_VERSION ||
228228386Sjfv	    v.bv_minor < BPF_MINOR_VERSION)
229228386Sjfv		error("Kernel BPF version out of range - recompile dhcpd!");
230228386Sjfv
231228386Sjfv	/*
232228386Sjfv	 * Set immediate mode so that reads return as soon as a packet
233228386Sjfv	 * comes in, rather than waiting for the input buffer to fill
234176667Sjfv	 * with packets.
235176667Sjfv	 */
236228386Sjfv	if (ioctl(info->rfdesc, BIOCIMMEDIATE, &flag) < 0)
237228386Sjfv		error("Can't set immediate mode on bpf device: %m");
238228386Sjfv
239228386Sjfv	/* Get the required BPF buffer length from the kernel. */
240228386Sjfv	if (ioctl(info->rfdesc, BIOCGBLEN, &sz) < 0)
241228386Sjfv		error("Can't get bpf buffer length: %m");
242176667Sjfv	info->rbuf_max = sz;
243228386Sjfv	info->rbuf = malloc(info->rbuf_max);
244228386Sjfv	if (!info->rbuf)
245176667Sjfv		error("Can't allocate %lu bytes for bpf input buffer.",
246176667Sjfv		    (unsigned long)info->rbuf_max);
247176667Sjfv	info->rbuf_offset = 0;
248256200Sjfv	info->rbuf_len = 0;
249256200Sjfv
250228386Sjfv	/* Set up the bpf filter program structure. */
251228386Sjfv	p.bf_len = dhcp_bpf_filter_len;
252228386Sjfv	p.bf_insns = dhcp_bpf_filter;
253228386Sjfv
254228386Sjfv	/* Patch the server port into the BPF program...
255228386Sjfv	 *
256228386Sjfv	 * XXX: changes to filter program may require changes to the
257228386Sjfv	 * insn number(s) used below!
258228386Sjfv	 */
259176667Sjfv	dhcp_bpf_filter[8].k = LOCAL_PORT;
260228386Sjfv
261228386Sjfv	if (ioctl(info->rfdesc, BIOCSETF, &p) < 0)
262228386Sjfv		error("Can't install packet filter program: %m");
263228386Sjfv
264228386Sjfv	if (ioctl(info->rfdesc, BIOCLOCK, NULL) < 0)
265228386Sjfv		error("Cannot lock bpf");
266181027Sjfv
267181027Sjfv	if (cap_rights_limit(info->rfdesc,
268181027Sjfv	    CAP_IOCTL | CAP_POLL_EVENT | CAP_READ) < 0 && errno != ENOSYS) {
269228386Sjfv		error("Can't limit bpf descriptor: %m");
270228386Sjfv	}
271228386Sjfv	if (cap_ioctls_limit(info->rfdesc, cmds, 2) < 0 && errno != ENOSYS)
272228386Sjfv		error("Can't limit ioctls for bpf descriptor: %m");
273228386Sjfv}
274181027Sjfv
275228386Sjfvvoid
276228386Sjfvsend_packet_unpriv(int privfd, struct dhcp_packet *raw, size_t len,
277228386Sjfv    struct in_addr from, struct in_addr to)
278228386Sjfv{
279228386Sjfv	struct imsg_hdr hdr;
280181027Sjfv	struct buf *buf;
281176667Sjfv	int errs;
282176667Sjfv
283176667Sjfv	hdr.code = IMSG_SEND_PACKET;
284200243Sjfv	hdr.len = sizeof(hdr) +
285200243Sjfv	    sizeof(size_t) + len +
286200243Sjfv	    sizeof(from) + sizeof(to);
287176667Sjfv
288176667Sjfv	if ((buf = buf_open(hdr.len)) == NULL)
289200243Sjfv		error("buf_open: %m");
290200243Sjfv
291200243Sjfv	errs = 0;
292176667Sjfv	errs += buf_add(buf, &hdr, sizeof(hdr));
293176667Sjfv	errs += buf_add(buf, &len, sizeof(len));
294176667Sjfv	errs += buf_add(buf, raw, len);
295176667Sjfv	errs += buf_add(buf, &from, sizeof(from));
296228386Sjfv	errs += buf_add(buf, &to, sizeof(to));
297228386Sjfv	if (errs)
298228386Sjfv		error("buf_add: %m");
299228386Sjfv
300228386Sjfv	if (buf_close(privfd, buf) == -1)
301228386Sjfv		error("buf_close: %m");
302228386Sjfv}
303228386Sjfv
304228386Sjfvvoid
305228386Sjfvsend_packet_priv(struct interface_info *interface, struct imsg_hdr *hdr, int fd)
306228386Sjfv{
307228386Sjfv	unsigned char buf[256];
308228386Sjfv	struct iovec iov[2];
309228386Sjfv	struct msghdr msg;
310228386Sjfv	struct dhcp_packet raw;
311228386Sjfv	size_t len;
312228386Sjfv	struct in_addr from, to;
313228386Sjfv	int result, bufp = 0;
314228386Sjfv
315228386Sjfv	if (hdr->len < sizeof(*hdr) + sizeof(size_t))
316176667Sjfv		error("corrupted message received");
317176667Sjfv	buf_read(fd, &len, sizeof(len));
318176667Sjfv	if (hdr->len != sizeof(*hdr) + sizeof(size_t) + len +
319200243Sjfv	    sizeof(from) + sizeof(to)) {
320200243Sjfv		error("corrupted message received");
321200243Sjfv	}
322200243Sjfv	if (len > sizeof(raw))
323176667Sjfv		error("corrupted message received");
324176667Sjfv	buf_read(fd, &raw, len);
325228386Sjfv	buf_read(fd, &from, sizeof(from));
326228386Sjfv	buf_read(fd, &to, sizeof(to));
327228386Sjfv
328228386Sjfv	/* Assemble the headers... */
329228386Sjfv	if (to.s_addr == INADDR_BROADCAST)
330228386Sjfv		assemble_hw_header(interface, buf, &bufp);
331228386Sjfv	assemble_udp_ip_header(buf, &bufp, from.s_addr, to.s_addr,
332228386Sjfv	    htons(REMOTE_PORT), (unsigned char *)&raw, len);
333176667Sjfv
334228386Sjfv	iov[0].iov_base = buf;
335228386Sjfv	iov[0].iov_len = bufp;
336228386Sjfv	iov[1].iov_base = &raw;
337228386Sjfv	iov[1].iov_len = len;
338228386Sjfv
339176667Sjfv	/* Fire it off */
340228386Sjfv	if (to.s_addr == INADDR_BROADCAST)
341176667Sjfv		result = writev(interface->wfdesc, iov, 2);
342228386Sjfv	else {
343176667Sjfv		struct sockaddr_in sato;
344176667Sjfv
345228386Sjfv		sato.sin_addr = to;
346228386Sjfv		sato.sin_port = htons(REMOTE_PORT);
347176667Sjfv		sato.sin_family = AF_INET;
348228386Sjfv		sato.sin_len = sizeof(sato);
349176667Sjfv
350176667Sjfv		memset(&msg, 0, sizeof(msg));
351228386Sjfv		msg.msg_name = (struct sockaddr *)&sato;
352228386Sjfv		msg.msg_namelen = sizeof(sato);
353176667Sjfv		msg.msg_iov = iov;
354176667Sjfv		msg.msg_iovlen = 2;
355228386Sjfv		result = sendmsg(interface->ufdesc, &msg, 0);
356228386Sjfv	}
357176667Sjfv
358228386Sjfv	if (result < 0)
359228386Sjfv		warning("send_packet: %m");
360176667Sjfv}
361228386Sjfv
362228386Sjfvssize_t
363228386Sjfvreceive_packet(struct interface_info *interface, unsigned char *buf,
364228386Sjfv    size_t len, struct sockaddr_in *from, struct hardware *hfrom)
365247064Sjfv{
366176667Sjfv	int length = 0, offset = 0;
367228386Sjfv	struct bpf_hdr hdr;
368228386Sjfv
369247064Sjfv	/*
370228386Sjfv	 * All this complexity is because BPF doesn't guarantee that
371247064Sjfv	 * only one packet will be returned at a time.  We're getting
372176667Sjfv	 * what we deserve, though - this is a terrible abuse of the BPF
373228386Sjfv	 * interface.  Sigh.
374228386Sjfv	 */
375228386Sjfv
376228386Sjfv	/* Process packets until we get one we can return or until we've
377176667Sjfv	 * done a read and gotten nothing we can return...
378181027Sjfv	 */
379228386Sjfv	do {
380228386Sjfv		/* If the buffer is empty, fill it. */
381228386Sjfv		if (interface->rbuf_offset >= interface->rbuf_len) {
382176667Sjfv			length = read(interface->rfdesc, interface->rbuf,
383181027Sjfv			    interface->rbuf_max);
384228386Sjfv			if (length <= 0)
385228386Sjfv				return (length);
386228386Sjfv			interface->rbuf_offset = 0;
387228386Sjfv			interface->rbuf_len = length;
388181027Sjfv		}
389181027Sjfv
390181027Sjfv		/*
391181027Sjfv		 * If there isn't room for a whole bpf header, something
392181027Sjfv		 * went wrong, but we'll ignore it and hope it goes
393181027Sjfv		 * away... XXX
394181027Sjfv		 */
395181027Sjfv		if (interface->rbuf_len - interface->rbuf_offset <
396228386Sjfv		    sizeof(hdr)) {
397181027Sjfv			interface->rbuf_offset = interface->rbuf_len;
398228386Sjfv			continue;
399228386Sjfv		}
400228386Sjfv
401228386Sjfv		/* Copy out a bpf header... */
402228386Sjfv		memcpy(&hdr, &interface->rbuf[interface->rbuf_offset],
403228386Sjfv		    sizeof(hdr));
404228386Sjfv
405200243Sjfv		/*
406228386Sjfv		 * If the bpf header plus data doesn't fit in what's
407228386Sjfv		 * left of the buffer, stick head in sand yet again...
408181027Sjfv		 */
409228386Sjfv		if (interface->rbuf_offset + hdr.bh_hdrlen + hdr.bh_caplen >
410228386Sjfv		    interface->rbuf_len) {
411228386Sjfv			interface->rbuf_offset = interface->rbuf_len;
412228386Sjfv			continue;
413228386Sjfv		}
414228386Sjfv
415181027Sjfv		/* Skip over the BPF header... */
416181027Sjfv		interface->rbuf_offset += hdr.bh_hdrlen;
417228386Sjfv
418228386Sjfv		/*
419181027Sjfv		 * If the captured data wasn't the whole packet, or if
420181027Sjfv		 * the packet won't fit in the input buffer, all we can
421228386Sjfv		 * do is drop it.
422228386Sjfv		 */
423228386Sjfv		if (hdr.bh_caplen != hdr.bh_datalen) {
424181027Sjfv			interface->rbuf_offset =
425181027Sjfv			    BPF_WORDALIGN(interface->rbuf_offset +
426228386Sjfv			    hdr.bh_caplen);
427228386Sjfv			continue;
428228386Sjfv		}
429228386Sjfv
430228386Sjfv		/* Decode the physical header... */
431228386Sjfv		offset = decode_hw_header(interface->rbuf,
432228386Sjfv		    interface->rbuf_offset, hfrom);
433228386Sjfv
434228386Sjfv		/*
435228386Sjfv		 * If a physical layer checksum failed (dunno of any
436181027Sjfv		 * physical layer that supports this, but WTH), skip
437228386Sjfv		 * this packet.
438228386Sjfv		 */
439228386Sjfv		if (offset < 0) {
440228386Sjfv			interface->rbuf_offset =
441228386Sjfv			    BPF_WORDALIGN(interface->rbuf_offset +
442205869Sjfv			    hdr.bh_caplen);
443228386Sjfv			continue;
444228386Sjfv		}
445218530Sjfv		interface->rbuf_offset += offset;
446228386Sjfv		hdr.bh_caplen -= offset;
447228386Sjfv
448228386Sjfv		/* Decode the IP and UDP headers... */
449228386Sjfv		offset = decode_udp_ip_header(interface->rbuf,
450228386Sjfv		    interface->rbuf_offset, from, NULL, hdr.bh_caplen);
451228386Sjfv
452181027Sjfv		/* If the IP or UDP checksum was bad, skip the packet... */
453228386Sjfv		if (offset < 0) {
454228386Sjfv			interface->rbuf_offset =
455200243Sjfv			    BPF_WORDALIGN(interface->rbuf_offset +
456228386Sjfv			    hdr.bh_caplen);
457181027Sjfv			continue;
458228386Sjfv		}
459228386Sjfv		interface->rbuf_offset += offset;
460181027Sjfv		hdr.bh_caplen -= offset;
461228386Sjfv
462228386Sjfv		/*
463194865Sjfv		 * If there's not enough room to stash the packet data,
464228386Sjfv		 * we have to skip it (this shouldn't happen in real
465228386Sjfv		 * life, though).
466203049Sjfv		 */
467228386Sjfv		if (hdr.bh_caplen > len) {
468228386Sjfv			interface->rbuf_offset =
469228386Sjfv			    BPF_WORDALIGN(interface->rbuf_offset +
470228386Sjfv			    hdr.bh_caplen);
471228386Sjfv			continue;
472200243Sjfv		}
473228386Sjfv
474185353Sjfv		/* Copy out the data in the packet... */
475228386Sjfv		memcpy(buf, interface->rbuf + interface->rbuf_offset,
476228386Sjfv		    hdr.bh_caplen);
477218530Sjfv		interface->rbuf_offset =
478228386Sjfv		    BPF_WORDALIGN(interface->rbuf_offset +
479194865Sjfv		    hdr.bh_caplen);
480213234Sjfv		return (hdr.bh_caplen);
481194865Sjfv	} while (!length);
482219753Sjfv	return (0);
483219753Sjfv}
484209616Sjfv