1169689Skan/*	$NetBSD: bpf.c,v 1.5 2022/04/03 01:10:58 christos Exp $	*/
2169689Skan
3169689Skan/* bpf.c
4169689Skan
5169689Skan   BPF socket interface code, originally contributed by Archie Cobbs. */
6169689Skan
7169689Skan/*
8169689Skan * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC")
9169689Skan * Copyright (c) 1996-2003 by Internet Software Consortium
10169689Skan *
11169689Skan * This Source Code Form is subject to the terms of the Mozilla Public
12169689Skan * License, v. 2.0. If a copy of the MPL was not distributed with this
13169689Skan * file, You can obtain one at http://mozilla.org/MPL/2.0/.
14169689Skan *
15169689Skan * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16169689Skan * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17169689Skan * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
18169689Skan * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19169689Skan * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20169689Skan * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21169689Skan * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22169689Skan *
23169689Skan *   Internet Systems Consortium, Inc.
24169689Skan *   PO Box 360
25169689Skan *   Newmarket, NH 03857 USA
26169689Skan *   <info@isc.org>
27169689Skan *   https://www.isc.org/
28169689Skan *
29169689Skan * This software was contributed to Internet Systems Consortium
30169689Skan * by Archie Cobbs.
31169689Skan *
32169689Skan * Patches for FDDI support on Digital Unix were written by Bill
33169689Skan * Stapleton, and maintained for a while by Mike Meredith before he
34169689Skan * managed to get me to integrate them.
35169689Skan */
36169689Skan
37169689Skan#include <sys/cdefs.h>
38169689Skan__RCSID("$NetBSD: bpf.c,v 1.5 2022/04/03 01:10:58 christos Exp $");
39169689Skan
40169689Skan#include "dhcpd.h"
41169689Skan#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)	\
42169689Skan				|| defined (USE_LPF_RECEIVE)
43169689Skan# if defined (USE_LPF_RECEIVE)
44169689Skan#  include <asm/types.h>
45169689Skan#  include <linux/filter.h>
46169689Skan#  define bpf_insn sock_filter /* Linux: dare to be gratuitously different. */
47169689Skan# else
48169689Skan#  include <sys/ioctl.h>
49169689Skan#  include <sys/uio.h>
50169689Skan#  include <net/bpf.h>
51169689Skan#  if defined (NEED_OSF_PFILT_HACKS)
52169689Skan#   include <net/pfilt.h>
53169689Skan#  endif
54169689Skan# endif
55169689Skan
56169689Skan#include <sys/param.h>
57169689Skan#include <netinet/in_systm.h>
58169689Skan#include "includes/netinet/ip.h"
59169689Skan#include "includes/netinet/udp.h"
60169689Skan#include "includes/netinet/if_ether.h"
61169689Skan#endif
62169689Skan
63169689Skan#if defined(USE_BPF_SEND) || defined(USE_BPF_RECEIVE) || defined(USE_BPF_HWADDR)
64169689Skan#include <net/if_types.h>
65169689Skan#include <ifaddrs.h>
66169689Skan#endif
67169689Skan
68169689Skan#include <errno.h>
69169689Skan
70169689Skan/* Reinitializes the specified interface after an address change.   This
71169689Skan   is not required for packet-filter APIs. */
72169689Skan
73169689Skan#ifdef USE_BPF_SEND
74169689Skanvoid if_reinitialize_send (info)
75169689Skan	struct interface_info *info;
76169689Skan{
77169689Skan}
78169689Skan#endif
79169689Skan
80169689Skan#ifdef USE_BPF_RECEIVE
81169689Skanvoid if_reinitialize_receive (info)
82169689Skan	struct interface_info *info;
83169689Skan{
84169689Skan}
85169689Skan#endif
86169689Skan
87169689Skan/* Called by get_interface_list for each interface that's discovered.
88169689Skan   Opens a packet filter for each interface and adds it to the select
89169689Skan   mask. */
90169689Skan
91169689Skan#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
92169689Skanint if_register_bpf (info)
93169689Skan	struct interface_info *info;
94169689Skan{
95169689Skan	int sock;
96169689Skan	char filename[50];
97169689Skan	int b;
98169689Skan
99169689Skan	/* Open a BPF device */
100169689Skan	for (b = 0; 1; b++) {
101169689Skan		/* %Audit% 31 bytes max. %2004.06.17,Safe% */
102169689Skan		sprintf(filename, BPF_FORMAT, b);
103169689Skan		sock = open (filename, O_RDWR, 0);
104169689Skan		if (sock < 0) {
105169689Skan			if (errno == EBUSY) {
106169689Skan				continue;
107169689Skan			} else {
108169689Skan				if (!b)
109169689Skan					log_fatal ("No bpf devices.%s%s%s",
110169689Skan					       "   Please read the README",
111169689Skan					       " section for your operating",
112169689Skan					       " system.");
113169689Skan				log_fatal ("Can't find free bpf: %m");
114169689Skan			}
115169689Skan		} else {
116169689Skan			break;
117169689Skan		}
118169689Skan	}
119169689Skan
120169689Skan	/* Set the BPF device to point at this interface. */
121169689Skan	if (ioctl (sock, BIOCSETIF, info -> ifp) < 0)
122169689Skan		log_fatal ("Can't attach interface %s to bpf device %s: %m",
123169689Skan		       info -> name, filename);
124169689Skan
125169689Skan	get_hw_addr(info->name, &info->hw_address);
126169689Skan
127169689Skan	return sock;
128169689Skan}
129169689Skan#endif /* USE_BPF_SEND || USE_BPF_RECEIVE */
130169689Skan
131169689Skan#ifdef USE_BPF_SEND
132169689Skanvoid if_register_send (info)
133169689Skan	struct interface_info *info;
134169689Skan{
135169689Skan	/* If we're using the bpf API for sending and receiving,
136169689Skan	   we don't need to register this interface twice. */
137169689Skan#ifndef USE_BPF_RECEIVE
138169689Skan	info -> wfdesc = if_register_bpf (info, interface);
139169689Skan#else
140169689Skan	info -> wfdesc = info -> rfdesc;
141169689Skan#endif
142169689Skan	if (!quiet_interface_discovery)
143169689Skan		log_info ("Sending on   BPF/%s/%s%s%s",
144169689Skan		      info -> name,
145169689Skan		      print_hw_addr (info -> hw_address.hbuf [0],
146169689Skan				     info -> hw_address.hlen - 1,
147169689Skan				     &info -> hw_address.hbuf [1]),
148169689Skan		      (info -> shared_network ? "/" : ""),
149169689Skan		      (info -> shared_network ?
150169689Skan		       info -> shared_network -> name : ""));
151169689Skan}
152169689Skan
153169689Skanvoid if_deregister_send (info)
154169689Skan	struct interface_info *info;
155169689Skan{
156169689Skan	/* If we're using the bpf API for sending and receiving,
157169689Skan	   we don't need to register this interface twice. */
158169689Skan#ifndef USE_BPF_RECEIVE
159169689Skan	close (info -> wfdesc);
160169689Skan#endif
161169689Skan	info -> wfdesc = -1;
162169689Skan
163169689Skan	if (!quiet_interface_discovery)
164169689Skan		log_info ("Disabling output on BPF/%s/%s%s%s",
165169689Skan		      info -> name,
166169689Skan		      print_hw_addr (info -> hw_address.hbuf [0],
167169689Skan				     info -> hw_address.hlen - 1,
168169689Skan				     &info -> hw_address.hbuf [1]),
169169689Skan		      (info -> shared_network ? "/" : ""),
170169689Skan		      (info -> shared_network ?
171169689Skan		       info -> shared_network -> name : ""));
172169689Skan}
173169689Skan#endif /* USE_BPF_SEND */
174169689Skan
175169689Skan#if defined (USE_BPF_RECEIVE) || defined (USE_LPF_RECEIVE)
176169689Skan/* Packet filter program...
177169689Skan   XXX Changes to the filter program may require changes to the constant
178169689Skan   offsets used in if_register_send to patch the BPF program! XXX */
179169689Skan
180169689Skanstruct bpf_insn dhcp_bpf_filter [] = {
181169689Skan	/* Make sure this is an IP packet... */
182169689Skan	BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
183169689Skan	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
184169689Skan
185169689Skan	/* Make sure it's a UDP packet... */
186169689Skan	BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23),
187169689Skan	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
188169689Skan
189169689Skan	/* Make sure this isn't a fragment... */
190169689Skan	BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
191169689Skan	BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
192169689Skan
193169689Skan	/* Get the IP header length... */
194169689Skan	BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14),
195169689Skan
196169689Skan	/* Make sure it's to the right port... */
197169689Skan	BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
198169689Skan	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),             /* patch */
199169689Skan
200169689Skan	/* If we passed all the tests, ask for the whole packet. */
201169689Skan	BPF_STMT (BPF_RET + BPF_K, (u_int)-1),
202169689Skan
203169689Skan	/* Otherwise, drop it. */
204169689Skan	BPF_STMT (BPF_RET + BPF_K, 0),
205169689Skan};
206169689Skan
207169689Skan#if defined(RELAY_PORT)
208169689Skan/*
209169689Skan * For relay port extension
210169689Skan */
211169689Skanstruct bpf_insn dhcp_bpf_relay_filter [] = {
212169689Skan	/* Make sure this is an IP packet... */
213169689Skan	BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
214169689Skan	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 10),
215169689Skan
216169689Skan	/* Make sure it's a UDP packet... */
217169689Skan	BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23),
218169689Skan	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 8),
219169689Skan
220169689Skan	/* Make sure this isn't a fragment... */
221169689Skan	BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
222169689Skan	BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 6, 0),
223169689Skan
224169689Skan	/* Get the IP header length... */
225169689Skan	BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14),
226169689Skan
227169689Skan	/* Make sure it's to the right port... */
228169689Skan	BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
229169689Skan	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 2, 0),             /* patch */
230169689Skan
231169689Skan	/* relay can have an alternative port... */
232169689Skan	BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
233169689Skan	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),             /* patch */
234169689Skan
235169689Skan	/* If we passed all the tests, ask for the whole packet. */
236169689Skan	BPF_STMT (BPF_RET + BPF_K, (u_int)-1),
237169689Skan
238169689Skan	/* Otherwise, drop it. */
239169689Skan	BPF_STMT (BPF_RET + BPF_K, 0),
240169689Skan};
241169689Skan
242169689Skanint dhcp_bpf_relay_filter_len =
243169689Skan	sizeof dhcp_bpf_relay_filter / sizeof (struct bpf_insn);
244169689Skan#endif
245169689Skan
246169689Skan#if defined (DEC_FDDI)
247169689Skanstruct bpf_insn *bpf_fddi_filter = NULL;
248169689Skan#endif
249169689Skan
250169689Skanint dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
251169689Skan#if defined (HAVE_TR_SUPPORT)
252169689Skanstruct bpf_insn dhcp_bpf_tr_filter [] = {
253169689Skan        /* accept all token ring packets due to variable length header */
254169689Skan        /* if we want to get clever, insert the program here */
255169689Skan
256169689Skan	/* If we passed all the tests, ask for the whole packet. */
257169689Skan	BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
258169689Skan
259169689Skan	/* Otherwise, drop it. */
260169689Skan	BPF_STMT(BPF_RET+BPF_K, 0),
261169689Skan};
262169689Skan
263169689Skanint dhcp_bpf_tr_filter_len = (sizeof dhcp_bpf_tr_filter /
264169689Skan			      sizeof (struct bpf_insn));
265169689Skan#endif /* HAVE_TR_SUPPORT */
266169689Skan#endif /* USE_LPF_RECEIVE || USE_BPF_RECEIVE */
267169689Skan
268169689Skan#if defined (USE_BPF_RECEIVE)
269169689Skanvoid if_register_receive (info)
270169689Skan	struct interface_info *info;
271169689Skan{
272169689Skan	int flag = 1;
273169689Skan	struct bpf_version v;
274169689Skan	struct bpf_program p;
275169689Skan#ifdef NEED_OSF_PFILT_HACKS
276169689Skan	u_int32_t bits;
277169689Skan#endif
278169689Skan#ifdef DEC_FDDI
279169689Skan	int link_layer;
280169689Skan#endif /* DEC_FDDI */
281169689Skan
282169689Skan	/* Open a BPF device and hang it on this interface... */
283169689Skan	info -> rfdesc = if_register_bpf (info);
284169689Skan
285169689Skan	/* Make sure the BPF version is in range... */
286169689Skan	if (ioctl (info -> rfdesc, BIOCVERSION, &v) < 0)
287169689Skan		log_fatal ("Can't get BPF version: %m");
288169689Skan
289169689Skan	if (v.bv_major != BPF_MAJOR_VERSION ||
290169689Skan	    v.bv_minor < BPF_MINOR_VERSION)
291169689Skan		log_fatal ("BPF version mismatch - recompile DHCP!");
292169689Skan
293169689Skan	/* Set immediate mode so that reads return as soon as a packet
294169689Skan	   comes in, rather than waiting for the input buffer to fill with
295169689Skan	   packets. */
296169689Skan	if (ioctl (info -> rfdesc, BIOCIMMEDIATE, &flag) < 0)
297169689Skan		log_fatal ("Can't set immediate mode on bpf device: %m");
298169689Skan
299169689Skan#ifdef NEED_OSF_PFILT_HACKS
300169689Skan	/* Allow the copyall flag to be set... */
301169689Skan	if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0)
302169689Skan		log_fatal ("Can't set ALLOWCOPYALL: %m");
303169689Skan
304169689Skan	/* Clear all the packet filter mode bits first... */
305169689Skan	bits = 0;
306169689Skan	if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
307169689Skan		log_fatal ("Can't clear pfilt bits: %m");
308169689Skan
309169689Skan	/* Set the ENBATCH, ENCOPYALL, ENBPFHDR bits... */
310169689Skan	bits = ENBATCH | ENCOPYALL | ENBPFHDR;
311169689Skan	if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
312169689Skan		log_fatal ("Can't set ENBATCH|ENCOPYALL|ENBPFHDR: %m");
313169689Skan#endif
314169689Skan	/* Get the required BPF buffer length from the kernel. */
315169689Skan	if (ioctl (info -> rfdesc, BIOCGBLEN, &info -> rbuf_max) < 0)
316169689Skan		log_fatal ("Can't get bpf buffer length: %m");
317169689Skan	info -> rbuf = dmalloc (info -> rbuf_max, MDL);
318169689Skan	if (!info -> rbuf)
319169689Skan		log_fatal ("Can't allocate %ld bytes for bpf input buffer.",
320169689Skan			   (long)(info -> rbuf_max));
321169689Skan	info -> rbuf_offset = 0;
322169689Skan	info -> rbuf_len = 0;
323169689Skan
324169689Skan	/* Set up the bpf filter program structure. */
325169689Skan	p.bf_len = dhcp_bpf_filter_len;
326169689Skan
327169689Skan#ifdef DEC_FDDI
328169689Skan	/* See if this is an FDDI interface, flag it for later. */
329169689Skan	if (ioctl(info -> rfdesc, BIOCGDLT, &link_layer) >= 0 &&
330169689Skan	    link_layer == DLT_FDDI) {
331169689Skan		if (!bpf_fddi_filter) {
332169689Skan			bpf_fddi_filter = dmalloc (sizeof dhcp_bpf_filter,
333169689Skan						    MDL);
334169689Skan			if (!bpf_fddi_filter)
335169689Skan				log_fatal ("No memory for FDDI filter.");
336169689Skan			memcpy (bpf_fddi_filter,
337169689Skan				dhcp_bpf_filter, sizeof dhcp_bpf_filter);
338169689Skan			/* Patch the BPF program to account for the difference
339169689Skan			   in length between ethernet headers (14), FDDI and
340169689Skan			   802.2 headers (16 +8=24, +10).
341169689Skan			   XXX changes to filter program may require changes to
342169689Skan			   XXX the insn number(s) used below! */
343169689Skan			bpf_fddi_filter[0].k += 10;
344169689Skan			bpf_fddi_filter[2].k += 10;
345169689Skan			bpf_fddi_filter[4].k += 10;
346169689Skan			bpf_fddi_filter[6].k += 10;
347169689Skan			bpf_fddi_filter[7].k += 10;
348169689Skan		}
349169689Skan		p.bf_insns = bpf_fddi_filter;
350169689Skan	} else
351169689Skan#endif /* DEC_FDDI */
352169689Skan	p.bf_insns = dhcp_bpf_filter;
353169689Skan
354169689Skan        /* Patch the server port into the BPF  program...
355169689Skan	   XXX changes to filter program may require changes
356169689Skan	   to the insn number(s) used below! XXX */
357169689Skan#if defined(RELAY_PORT)
358169689Skan	if (relay_port) {
359169689Skan		/*
360169689Skan		 * If user defined relay UDP port, we need to filter
361169689Skan		 * also on the user UDP port.
362169689Skan		 */
363169689Skan		p.bf_len = dhcp_bpf_relay_filter_len;
364169689Skan		p.bf_insns = dhcp_bpf_relay_filter;
365169689Skan
366169689Skan		dhcp_bpf_relay_filter [10].k = ntohs (relay_port);
367169689Skan	}
368169689Skan#endif
369169689Skan	p.bf_insns [8].k = ntohs (*libdhcp_callbacks.local_port);
370169689Skan
371169689Skan	if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)
372169689Skan		log_fatal ("Can't install packet filter program: %m");
373169689Skan	if (!quiet_interface_discovery)
374169689Skan		log_info ("Listening on BPF/%s/%s%s%s",
375169689Skan		      info -> name,
376169689Skan		      print_hw_addr (info -> hw_address.hbuf [0],
377169689Skan				     info -> hw_address.hlen - 1,
378169689Skan				     &info -> hw_address.hbuf [1]),
379169689Skan		      (info -> shared_network ? "/" : ""),
380169689Skan		      (info -> shared_network ?
381169689Skan		       info -> shared_network -> name : ""));
382169689Skan}
383169689Skan
384169689Skanvoid if_deregister_receive (info)
385169689Skan	struct interface_info *info;
386169689Skan{
387169689Skan	close (info -> rfdesc);
388169689Skan	info -> rfdesc = -1;
389169689Skan
390169689Skan	if (!quiet_interface_discovery)
391169689Skan		log_info ("Disabling input on BPF/%s/%s%s%s",
392169689Skan		      info -> name,
393169689Skan		      print_hw_addr (info -> hw_address.hbuf [0],
394169689Skan				     info -> hw_address.hlen - 1,
395169689Skan				     &info -> hw_address.hbuf [1]),
396169689Skan		      (info -> shared_network ? "/" : ""),
397169689Skan		      (info -> shared_network ?
398169689Skan		       info -> shared_network -> name : ""));
399169689Skan}
400169689Skan#endif /* USE_BPF_RECEIVE */
401169689Skan
402169689Skan#ifdef USE_BPF_SEND
403169689Skanssize_t send_packet (interface, packet, raw, len, from, to, hto)
404169689Skan	struct interface_info *interface;
405169689Skan	struct packet *packet;
406169689Skan	struct dhcp_packet *raw;
407169689Skan	size_t len;
408169689Skan	struct in_addr from;
409169689Skan	struct sockaddr_in *to;
410169689Skan	struct hardware *hto;
411169689Skan{
412169689Skan	unsigned hbufp = 0, ibufp = 0;
413169689Skan	double hw [4];
414169689Skan	double ip [32];
415169689Skan	struct iovec iov [3];
416169689Skan	int result;
417169689Skan
418169689Skan	if (!strcmp (interface -> name, "fallback"))
419169689Skan		return send_fallback (interface, packet, raw,
420169689Skan				      len, from, to, hto);
421169689Skan
422169689Skan	if (hto == NULL && interface->anycast_mac_addr.hlen)
423169689Skan		hto = &interface->anycast_mac_addr;
424169689Skan
425169689Skan	/* Assemble the headers... */
426169689Skan	assemble_hw_header (interface, (unsigned char *)hw, &hbufp, hto);
427169689Skan	assemble_udp_ip_header (interface,
428169689Skan				(unsigned char *)ip, &ibufp, from.s_addr,
429169689Skan				to -> sin_addr.s_addr, to -> sin_port,
430169689Skan				(unsigned char *)raw, len);
431169689Skan
432169689Skan	/* Fire it off */
433169689Skan	iov [0].iov_base = ((char *)hw);
434169689Skan	iov [0].iov_len = hbufp;
435169689Skan	iov [1].iov_base = ((char *)ip);
436169689Skan	iov [1].iov_len = ibufp;
437169689Skan	iov [2].iov_base = (char *)raw;
438169689Skan	iov [2].iov_len = len;
439169689Skan
440169689Skan	result = writev(interface -> wfdesc, iov, 3);
441169689Skan	if (result < 0)
442169689Skan		log_error ("send_packet: %m");
443169689Skan	return result;
444169689Skan}
445169689Skan#endif /* USE_BPF_SEND */
446169689Skan
447169689Skan#ifdef USE_BPF_RECEIVE
448169689Skanssize_t receive_packet (interface, buf, len, from, hfrom)
449169689Skan	struct interface_info *interface;
450169689Skan	unsigned char *buf;
451169689Skan	size_t len;
452169689Skan	struct sockaddr_in *from;
453169689Skan	struct hardware *hfrom;
454169689Skan{
455169689Skan	int length = 0;
456169689Skan	int offset = 0;
457169689Skan	struct bpf_hdr hdr;
458169689Skan	unsigned paylen;
459169689Skan
460169689Skan	/* All this complexity is because BPF doesn't guarantee
461169689Skan	   that only one packet will be returned at a time.   We're
462169689Skan	   getting what we deserve, though - this is a terrible abuse
463169689Skan	   of the BPF interface.   Sigh. */
464169689Skan
465169689Skan	/* Process packets until we get one we can return or until we've
466169689Skan	   done a read and gotten nothing we can return... */
467169689Skan
468169689Skan	/* If the buffer is empty, fill it. */
469169689Skan	if (interface->rbuf_offset >= interface->rbuf_len) {
470169689Skan		length = read(interface->rfdesc, interface->rbuf,
471169689Skan			      (size_t)interface->rbuf_max);
472169689Skan		if (length <= 0) {
473169689Skan#ifdef __FreeBSD__
474169689Skan			if (errno == ENXIO) {
475169689Skan#else
476169689Skan			if (errno == EIO) {
477169689Skan#endif
478169689Skan				dhcp_interface_remove
479169689Skan					((omapi_object_t *)interface, NULL);
480169689Skan			}
481169689Skan			return (length);
482169689Skan		}
483169689Skan		interface->rbuf_offset = 0;
484169689Skan		interface->rbuf_len = BPF_WORDALIGN(length);
485169689Skan	}
486169689Skan
487169689Skan	do {
488169689Skan		/* If there isn't room for a whole bpf header, something went
489169689Skan		   wrong, but we'll ignore it and hope it goes away... XXX */
490169689Skan		if (interface->rbuf_len -
491169689Skan		    interface->rbuf_offset < sizeof hdr) {
492169689Skan			interface->rbuf_offset = interface->rbuf_len;
493169689Skan			continue;
494169689Skan		}
495169689Skan
496169689Skan		/* Copy out a bpf header... */
497169689Skan		memcpy(&hdr, &interface->rbuf[interface->rbuf_offset],
498169689Skan		       sizeof hdr);
499169689Skan
500169689Skan		/* If the bpf header plus data doesn't fit in what's left
501169689Skan		   of the buffer, stick head in sand yet again... */
502169689Skan		if (interface->rbuf_offset +
503169689Skan		    hdr.bh_hdrlen + hdr.bh_caplen > interface->rbuf_len) {
504169689Skan			interface->rbuf_offset = interface->rbuf_len;
505169689Skan			continue;
506169689Skan		}
507169689Skan
508169689Skan		/* If the captured data wasn't the whole packet, or if
509169689Skan		   the packet won't fit in the input buffer, all we
510169689Skan		   can do is drop it. */
511169689Skan		if (hdr.bh_caplen != hdr.bh_datalen) {
512169689Skan			interface->rbuf_offset =
513169689Skan				BPF_WORDALIGN(interface->rbuf_offset +
514169689Skan					      hdr.bh_hdrlen + hdr.bh_caplen);
515169689Skan			continue;
516169689Skan		}
517169689Skan
518169689Skan		/* Skip over the BPF header... */
519169689Skan		interface->rbuf_offset += hdr.bh_hdrlen;
520169689Skan
521169689Skan		/* Decode the physical header... */
522169689Skan		offset = decode_hw_header(interface, interface->rbuf,
523169689Skan					  interface->rbuf_offset, hfrom);
524169689Skan
525169689Skan		/* If a physical layer checksum failed (dunno of any
526169689Skan		   physical layer that supports this, but WTH), skip this
527169689Skan		   packet. */
528169689Skan		if (offset < 0) {
529169689Skan			interface->rbuf_offset =
530169689Skan				BPF_WORDALIGN(interface->rbuf_offset +
531169689Skan					      hdr.bh_caplen);
532169689Skan			continue;
533169689Skan		}
534169689Skan		interface->rbuf_offset += offset;
535169689Skan		hdr.bh_caplen -= offset;
536169689Skan
537169689Skan		/* Decode the IP and UDP headers... */
538169689Skan		offset = decode_udp_ip_header(interface, interface->rbuf,
539169689Skan					      interface->rbuf_offset,
540169689Skan                                              from, hdr.bh_caplen, &paylen, 1);
541169689Skan
542169689Skan		/* If the IP or UDP checksum was bad, skip the packet... */
543169689Skan		if (offset < 0) {
544169689Skan			interface->rbuf_offset =
545169689Skan				BPF_WORDALIGN(interface->rbuf_offset +
546169689Skan					      hdr.bh_caplen);
547169689Skan			continue;
548169689Skan		}
549169689Skan		interface->rbuf_offset = interface->rbuf_offset + offset;
550169689Skan		hdr.bh_caplen -= offset;
551169689Skan
552169689Skan		/* If there's not enough room to stash the packet data,
553169689Skan		   we have to skip it (this shouldn't happen in real
554169689Skan		   life, though). */
555169689Skan		if (hdr.bh_caplen > len) {
556169689Skan			interface->rbuf_offset =
557169689Skan				BPF_WORDALIGN(interface->rbuf_offset +
558169689Skan					       hdr.bh_caplen);
559169689Skan			continue;
560169689Skan		}
561169689Skan
562169689Skan		/* Copy out the data in the packet... */
563169689Skan		memcpy(buf, interface->rbuf + interface->rbuf_offset, paylen);
564169689Skan		interface->rbuf_offset =
565169689Skan			BPF_WORDALIGN(interface->rbuf_offset + hdr.bh_caplen);
566169689Skan		return paylen;
567169689Skan	} while (interface->rbuf_offset < interface->rbuf_len);
568169689Skan
569169689Skan	return (0);
570169689Skan}
571169689Skan
572169689Skanint can_unicast_without_arp (ip)
573169689Skan	struct interface_info *ip;
574169689Skan{
575169689Skan	return 1;
576169689Skan}
577169689Skan
578169689Skanint can_receive_unicast_unconfigured (ip)
579169689Skan	struct interface_info *ip;
580169689Skan{
581169689Skan	return 1;
582169689Skan}
583169689Skan
584169689Skanint supports_multiple_interfaces (ip)
585169689Skan	struct interface_info *ip;
586169689Skan{
587169689Skan	return 1;
588169689Skan}
589169689Skan
590169689Skanvoid maybe_setup_fallback ()
591169689Skan{
592169689Skan	isc_result_t status;
593169689Skan	struct interface_info *fbi = (struct interface_info *)0;
594169689Skan	if (setup_fallback (&fbi, MDL)) {
595169689Skan		if_register_fallback (fbi);
596169689Skan		status = omapi_register_io_object ((omapi_object_t *)fbi,
597169689Skan						   if_readsocket, 0,
598169689Skan						   fallback_discard, 0, 0);
599169689Skan		if (status != ISC_R_SUCCESS)
600169689Skan			log_fatal ("Can't register I/O handle for %s: %s",
601169689Skan				   fbi -> name, isc_result_totext (status));
602169689Skan		interface_dereference (&fbi, MDL);
603169689Skan	}
604169689Skan}
605169689Skan
606169689Skan#endif
607169689Skan
608169689Skan#if defined(USE_BPF_RECEIVE) || defined(USE_BPF_HWADDR)
609169689Skanstatic int
610169689Skanlladdr_active(int s, const char *name, const struct ifaddrs *ifa)
611169689Skan{
612169689Skan	if (ifa->ifa_addr->sa_family != AF_LINK)
613169689Skan		return 0;
614169689Skan	if (strcmp(ifa->ifa_name, name) != 0)
615169689Skan		return 0;
616169689Skan
617169689Skan#ifdef SIOCGLIFADDR
618169689Skan{
619169689Skan	struct if_laddrreq iflr;
620169689Skan	const struct sockaddr_dl *sdl;
621169689Skan
622169689Skan	sdl = satocsdl(ifa->ifa_addr);
623169689Skan	memset(&iflr, 0, sizeof(iflr));
624169689Skan
625169689Skan	strlcpy(iflr.iflr_name, ifa->ifa_name, sizeof(iflr.iflr_name));
626169689Skan	memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len,
627169689Skan	   sizeof(iflr.addr)));
628169689Skan	iflr.flags = IFLR_PREFIX;
629169689Skan	iflr.prefixlen = sdl->sdl_alen * NBBY;
630169689Skan
631169689Skan	if (ioctl(s, SIOCGLIFADDR, &iflr) == -1) {
632169689Skan		log_fatal("ioctl(SIOCGLIFADDR): %m");
633169689Skan	}
634169689Skan
635169689Skan	if ((iflr.flags & IFLR_ACTIVE) == 0)
636169689Skan		return 0;
637169689Skan}
638169689Skan#endif
639169689Skan	return 1;
640169689Skan}
641169689Skan
642169689Skanvoid
643169689Skanget_hw_addr(const char *name, struct hardware *hw) {
644169689Skan	struct ifaddrs *ifa;
645169689Skan	struct ifaddrs *p;
646169689Skan	struct sockaddr_dl *sa;
647169689Skan	int s;
648169689Skan
649169689Skan	if ((s = socket(AF_LINK, SOCK_DGRAM, 0)) == -1) {
650169689Skan		log_fatal("socket AF_LINK: %m");
651169689Skan	}
652169689Skan
653169689Skan	if (getifaddrs(&ifa) != 0) {
654169689Skan		log_fatal("Error getting interface information; %m");
655169689Skan	}
656169689Skan
657169689Skan	/*
658169689Skan	 * Loop through our interfaces finding a match.
659169689Skan	 */
660169689Skan	sa = NULL;
661169689Skan	for (p=ifa; (p != NULL) && (sa == NULL); p = p->ifa_next) {
662169689Skan		if (lladdr_active(s, name, p)) {
663169689Skan		    	sa = (struct sockaddr_dl *)p->ifa_addr;
664169689Skan			break;
665169689Skan		}
666169689Skan	}
667169689Skan	if (sa == NULL) {
668169689Skan		log_fatal("No interface called '%s'", name);
669169689Skan	}
670169689Skan	close(s);
671169689Skan
672169689Skan	/*
673169689Skan	 * Pull out the appropriate information.
674169689Skan	 */
675169689Skan        switch (sa->sdl_type) {
676169689Skan                case IFT_ETHER:
677169689Skan#ifdef IFT_CARP
678169689Skan		case IFT_CARP:
679169689Skan#endif
680169689Skan#if defined (IFT_L2VLAN)
681169689Skan		case IFT_L2VLAN:
682169689Skan#endif
683169689Skan                        hw->hlen = sa->sdl_alen + 1;
684169689Skan                        hw->hbuf[0] = HTYPE_ETHER;
685169689Skan                        memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
686169689Skan                        break;
687169689Skan		case IFT_ISO88023:
688169689Skan		case IFT_ISO88024: /* "token ring" */
689169689Skan		case IFT_ISO88025:
690169689Skan		case IFT_ISO88026:
691169689Skan                        hw->hlen = sa->sdl_alen + 1;
692169689Skan                        hw->hbuf[0] = HTYPE_IEEE802;
693169689Skan                        memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
694169689Skan                        break;
695169689Skan#ifdef IFT_FDDI
696169689Skan                case IFT_FDDI:
697169689Skan                        hw->hlen = sa->sdl_alen + 1;
698169689Skan                        hw->hbuf[0] = HTYPE_FDDI;
699169689Skan                        memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
700169689Skan                        break;
701169689Skan#endif /* IFT_FDDI */
702169689Skan                default:
703169689Skan                        log_fatal("Unsupported device type %d for \"%s\"",
704169689Skan                                  sa->sdl_type, name);
705169689Skan        }
706169689Skan
707169689Skan	freeifaddrs(ifa);
708169689Skan}
709169689Skan#endif
710169689Skan