ISC DHCP  4.3.5
A reference DHCPv4 and DHCPv6 implementation
bpf.c
Go to the documentation of this file.
1 /* bpf.c
2 
3  BPF socket interface code, originally contributed by Archie Cobbs. */
4 
5 /*
6  * Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1996-2003 by Internet Software Consortium
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  * Internet Systems Consortium, Inc.
22  * 950 Charter Street
23  * Redwood City, CA 94063
24  * <info@isc.org>
25  * https://www.isc.org/
26  *
27  * This software was contributed to Internet Systems Consortium
28  * by Archie Cobbs.
29  *
30  * Patches for FDDI support on Digital Unix were written by Bill
31  * Stapleton, and maintained for a while by Mike Meredith before he
32  * managed to get me to integrate them.
33  */
34 
35 #include "dhcpd.h"
36 #if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE) \
37  || defined (USE_LPF_RECEIVE)
38 # if defined (USE_LPF_RECEIVE)
39 # include <asm/types.h>
40 # include <linux/filter.h>
41 # define bpf_insn sock_filter /* Linux: dare to be gratuitously different. */
42 # else
43 # include <sys/ioctl.h>
44 # include <sys/uio.h>
45 # include <net/bpf.h>
46 # if defined (NEED_OSF_PFILT_HACKS)
47 # include <net/pfilt.h>
48 # endif
49 # endif
50 
51 #include <netinet/in_systm.h>
52 #include "includes/netinet/ip.h"
53 #include "includes/netinet/udp.h"
55 #endif
56 
57 #if defined(USE_BPF_SEND) || defined(USE_BPF_RECEIVE) || defined(USE_BPF_HWADDR)
58 #include <net/if_types.h>
59 #include <ifaddrs.h>
60 #endif
61 
62 #include <errno.h>
63 
64 /* Reinitializes the specified interface after an address change. This
65  is not required for packet-filter APIs. */
66 
67 #ifdef USE_BPF_SEND
68 void if_reinitialize_send (info)
69  struct interface_info *info;
70 {
71 }
72 #endif
73 
74 #ifdef USE_BPF_RECEIVE
75 void if_reinitialize_receive (info)
76  struct interface_info *info;
77 {
78 }
79 #endif
80 
81 /* Called by get_interface_list for each interface that's discovered.
82  Opens a packet filter for each interface and adds it to the select
83  mask. */
84 
85 #if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
86 int if_register_bpf (info)
87  struct interface_info *info;
88 {
89  int sock;
90  char filename[50];
91  int b;
92 
93  /* Open a BPF device */
94  for (b = 0; 1; b++) {
95  /* %Audit% 31 bytes max. %2004.06.17,Safe% */
96  sprintf(filename, BPF_FORMAT, b);
97  sock = open (filename, O_RDWR | O_CLOEXEC, 0);
98  if (sock < 0) {
99  if (errno == EBUSY) {
100  continue;
101  } else {
102  if (!b)
103  log_fatal ("No bpf devices.%s%s%s",
104  " Please read the README",
105  " section for your operating",
106  " system.");
107  log_fatal ("Can't find free bpf: %m");
108  }
109  } else {
110  break;
111  }
112  }
113 
114  /* Set the BPF device to point at this interface. */
115  if (ioctl (sock, BIOCSETIF, info -> ifp) < 0)
116  log_fatal ("Can't attach interface %s to bpf device %s: %m",
117  info -> name, filename);
118 
119  get_hw_addr(info->name, &info->hw_address);
120 
121  return sock;
122 }
123 #endif /* USE_BPF_SEND || USE_BPF_RECEIVE */
124 
125 #ifdef USE_BPF_SEND
126 void if_register_send (info)
127  struct interface_info *info;
128 {
129  /* If we're using the bpf API for sending and receiving,
130  we don't need to register this interface twice. */
131 #ifndef USE_BPF_RECEIVE
132  info -> wfdesc = if_register_bpf (info, interface);
133 #else
134  info -> wfdesc = info -> rfdesc;
135 #endif
137  log_info ("Sending on BPF/%s/%s%s%s",
138  info -> name,
139  print_hw_addr (info -> hw_address.hbuf [0],
140  info -> hw_address.hlen - 1,
141  &info -> hw_address.hbuf [1]),
142  (info -> shared_network ? "/" : ""),
143  (info -> shared_network ?
144  info -> shared_network -> name : ""));
145 }
146 
147 void if_deregister_send (info)
148  struct interface_info *info;
149 {
150  /* If we're using the bpf API for sending and receiving,
151  we don't need to register this interface twice. */
152 #ifndef USE_BPF_RECEIVE
153  close (info -> wfdesc);
154 #endif
155  info -> wfdesc = -1;
156 
158  log_info ("Disabling output on BPF/%s/%s%s%s",
159  info -> name,
160  print_hw_addr (info -> hw_address.hbuf [0],
161  info -> hw_address.hlen - 1,
162  &info -> hw_address.hbuf [1]),
163  (info -> shared_network ? "/" : ""),
164  (info -> shared_network ?
165  info -> shared_network -> name : ""));
166 }
167 #endif /* USE_BPF_SEND */
168 
169 #if defined (USE_BPF_RECEIVE) || defined (USE_LPF_RECEIVE)
170 /* Packet filter program...
171  XXX Changes to the filter program may require changes to the constant
172  offsets used in if_register_send to patch the BPF program! XXX */
173 
174 struct bpf_insn dhcp_bpf_filter [] = {
175  /* Make sure this is an IP packet... */
176  BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
177  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
178 
179  /* Make sure it's a UDP packet... */
180  BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23),
181  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
182 
183  /* Make sure this isn't a fragment... */
184  BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
185  BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
186 
187  /* Get the IP header length... */
188  BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14),
189 
190  /* Make sure it's to the right port... */
191  BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
192  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */
193 
194  /* If we passed all the tests, ask for the whole packet. */
195  BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
196 
197  /* Otherwise, drop it. */
198  BPF_STMT(BPF_RET+BPF_K, 0),
199 };
200 
201 /* Packet filter program for DHCP over Infiniband.
202  *
203  * XXX
204  * Changes to the filter program may require changes to the constant offsets
205  * used in lpf_gen_filter_setup to patch the port in the BPF program!
206  * XXX
207  */
208 struct bpf_insn dhcp_ib_bpf_filter [] = {
209  /* Packet filter for Infiniband */
210  /* Make sure it's a UDP packet... */
211  BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
212  BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
213 
214  /* Make sure this isn't a fragment... */
215  BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6),
216  BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
217 
218  /* Get the IP header length... */
219  BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
220 
221  /* Make sure it's to the right port... */
222  BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
223  BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
224 
225  /* If we passed all the tests, ask for the whole packet. */
226  BPF_STMT(BPF_RET + BPF_K, (u_int)-1),
227 
228  /* Otherwise, drop it. */
229  BPF_STMT(BPF_RET + BPF_K, 0),
230 };
231 
232 #if defined (DEC_FDDI)
233 struct bpf_insn *bpf_fddi_filter = NULL;
234 #endif
235 
236 int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
237 int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
238 #if defined (HAVE_TR_SUPPORT)
239 struct bpf_insn dhcp_bpf_tr_filter [] = {
240  /* accept all token ring packets due to variable length header */
241  /* if we want to get clever, insert the program here */
242 
243  /* If we passed all the tests, ask for the whole packet. */
244  BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
245 
246  /* Otherwise, drop it. */
247  BPF_STMT(BPF_RET+BPF_K, 0),
248 };
249 
250 int dhcp_bpf_tr_filter_len = (sizeof dhcp_bpf_tr_filter /
251  sizeof (struct bpf_insn));
252 #endif /* HAVE_TR_SUPPORT */
253 #endif /* USE_LPF_RECEIVE || USE_BPF_RECEIVE */
254 
255 #if defined (USE_BPF_RECEIVE)
256 void if_register_receive (info)
257  struct interface_info *info;
258 {
259  int flag = 1;
260  struct bpf_version v;
261  struct bpf_program p;
262 #ifdef NEED_OSF_PFILT_HACKS
263  u_int32_t bits;
264 #endif
265 #ifdef DEC_FDDI
266  int link_layer;
267 #endif /* DEC_FDDI */
268 
269  /* Open a BPF device and hang it on this interface... */
270  info -> rfdesc = if_register_bpf (info);
271 
272  /* Make sure the BPF version is in range... */
273  if (ioctl (info -> rfdesc, BIOCVERSION, &v) < 0)
274  log_fatal ("Can't get BPF version: %m");
275 
276  if (v.bv_major != BPF_MAJOR_VERSION ||
277  v.bv_minor < BPF_MINOR_VERSION)
278  log_fatal ("BPF version mismatch - recompile DHCP!");
279 
280  /* Set immediate mode so that reads return as soon as a packet
281  comes in, rather than waiting for the input buffer to fill with
282  packets. */
283  if (ioctl (info -> rfdesc, BIOCIMMEDIATE, &flag) < 0)
284  log_fatal ("Can't set immediate mode on bpf device: %m");
285 
286 #ifdef NEED_OSF_PFILT_HACKS
287  /* Allow the copyall flag to be set... */
288  if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0)
289  log_fatal ("Can't set ALLOWCOPYALL: %m");
290 
291  /* Clear all the packet filter mode bits first... */
292  bits = 0;
293  if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
294  log_fatal ("Can't clear pfilt bits: %m");
295 
296  /* Set the ENBATCH, ENCOPYALL, ENBPFHDR bits... */
297  bits = ENBATCH | ENCOPYALL | ENBPFHDR;
298  if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
299  log_fatal ("Can't set ENBATCH|ENCOPYALL|ENBPFHDR: %m");
300 #endif
301  /* Get the required BPF buffer length from the kernel. */
302  if (ioctl (info -> rfdesc, BIOCGBLEN, &info -> rbuf_max) < 0)
303  log_fatal ("Can't get bpf buffer length: %m");
304  info -> rbuf = dmalloc (info -> rbuf_max, MDL);
305  if (!info -> rbuf)
306  log_fatal ("Can't allocate %ld bytes for bpf input buffer.",
307  (long)(info -> rbuf_max));
308  info -> rbuf_offset = 0;
309  info -> rbuf_len = 0;
310 
311  /* Set up the bpf filter program structure. */
312  p.bf_len = dhcp_bpf_filter_len;
313 
314 #ifdef DEC_FDDI
315  /* See if this is an FDDI interface, flag it for later. */
316  if (ioctl(info -> rfdesc, BIOCGDLT, &link_layer) >= 0 &&
317  link_layer == DLT_FDDI) {
318  if (!bpf_fddi_filter) {
319  bpf_fddi_filter = dmalloc (sizeof dhcp_bpf_filter,
320  MDL);
321  if (!bpf_fddi_filter)
322  log_fatal ("No memory for FDDI filter.");
323  memcpy (bpf_fddi_filter,
324  dhcp_bpf_filter, sizeof dhcp_bpf_filter);
325  /* Patch the BPF program to account for the difference
326  in length between ethernet headers (14), FDDI and
327  802.2 headers (16 +8=24, +10).
328  XXX changes to filter program may require changes to
329  XXX the insn number(s) used below! */
330  bpf_fddi_filter[0].k += 10;
331  bpf_fddi_filter[2].k += 10;
332  bpf_fddi_filter[4].k += 10;
333  bpf_fddi_filter[6].k += 10;
334  bpf_fddi_filter[7].k += 10;
335  }
336  p.bf_insns = bpf_fddi_filter;
337  } else
338 #endif /* DEC_FDDI */
339  p.bf_insns = dhcp_bpf_filter;
340 
341  /* Patch the server port into the BPF program...
342  XXX changes to filter program may require changes
343  to the insn number(s) used below! XXX */
344  dhcp_bpf_filter [8].k = ntohs (local_port);
345 
346  if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)
347  log_fatal ("Can't install packet filter program: %m");
349  log_info ("Listening on BPF/%s/%s%s%s",
350  info -> name,
351  print_hw_addr (info -> hw_address.hbuf [0],
352  info -> hw_address.hlen - 1,
353  &info -> hw_address.hbuf [1]),
354  (info -> shared_network ? "/" : ""),
355  (info -> shared_network ?
356  info -> shared_network -> name : ""));
357 }
358 
359 void if_deregister_receive (info)
360  struct interface_info *info;
361 {
362  close (info -> rfdesc);
363  info -> rfdesc = -1;
364 
366  log_info ("Disabling input on BPF/%s/%s%s%s",
367  info -> name,
368  print_hw_addr (info -> hw_address.hbuf [0],
369  info -> hw_address.hlen - 1,
370  &info -> hw_address.hbuf [1]),
371  (info -> shared_network ? "/" : ""),
372  (info -> shared_network ?
373  info -> shared_network -> name : ""));
374 }
375 #endif /* USE_BPF_RECEIVE */
376 
377 #ifdef USE_BPF_SEND
378 ssize_t send_packet (interface, packet, raw, len, from, to, hto)
379  struct interface_info *interface;
380  struct packet *packet;
381  struct dhcp_packet *raw;
382  size_t len;
383  struct in_addr from;
384  struct sockaddr_in *to;
385  struct hardware *hto;
386 {
387  unsigned hbufp = 0, ibufp = 0;
388  double hw [4];
389  double ip [32];
390  struct iovec iov [3];
391  int result;
392 
393  if (!strcmp (interface -> name, "fallback"))
394  return send_fallback (interface, packet, raw,
395  len, from, to, hto);
396 
397  if (hto == NULL && interface->anycast_mac_addr.hlen)
398  hto = &interface->anycast_mac_addr;
399 
400  /* Assemble the headers... */
401  assemble_hw_header (interface, (unsigned char *)hw, &hbufp, hto);
402  assemble_udp_ip_header (interface,
403  (unsigned char *)ip, &ibufp, from.s_addr,
404  to -> sin_addr.s_addr, to -> sin_port,
405  (unsigned char *)raw, len);
406 
407  /* Fire it off */
408  iov [0].iov_base = ((char *)hw);
409  iov [0].iov_len = hbufp;
410  iov [1].iov_base = ((char *)ip);
411  iov [1].iov_len = ibufp;
412  iov [2].iov_base = (char *)raw;
413  iov [2].iov_len = len;
414 
415  result = writev(interface -> wfdesc, iov, 3);
416  if (result < 0)
417  log_error ("send_packet: %m");
418  return result;
419 }
420 #endif /* USE_BPF_SEND */
421 
422 #ifdef USE_BPF_RECEIVE
423 ssize_t receive_packet (interface, buf, len, from, hfrom)
424  struct interface_info *interface;
425  unsigned char *buf;
426  size_t len;
427  struct sockaddr_in *from;
428  struct hardware *hfrom;
429 {
430  int length = 0;
431  int offset = 0;
432  struct bpf_hdr hdr;
433  unsigned paylen;
434 
435  /* All this complexity is because BPF doesn't guarantee
436  that only one packet will be returned at a time. We're
437  getting what we deserve, though - this is a terrible abuse
438  of the BPF interface. Sigh. */
439 
440  /* Process packets until we get one we can return or until we've
441  done a read and gotten nothing we can return... */
442 
443  /* If the buffer is empty, fill it. */
444  if (interface->rbuf_offset >= interface->rbuf_len) {
445  length = read(interface->rfdesc, interface->rbuf,
446  (size_t)interface->rbuf_max);
447  if (length <= 0) {
448 #ifdef __FreeBSD__
449  if (errno == ENXIO) {
450 #else
451  if (errno == EIO) {
452 #endif
454  ((omapi_object_t *)interface, NULL);
455  }
456  return (length);
457  }
458  interface->rbuf_offset = 0;
459  interface->rbuf_len = BPF_WORDALIGN(length);
460  }
461 
462  do {
463  /* If there isn't room for a whole bpf header, something went
464  wrong, but we'll ignore it and hope it goes away... XXX */
465  if (interface->rbuf_len -
466  interface->rbuf_offset < sizeof hdr) {
467  interface->rbuf_offset = interface->rbuf_len;
468  continue;
469  }
470 
471  /* Copy out a bpf header... */
472  memcpy(&hdr, &interface->rbuf[interface->rbuf_offset],
473  sizeof hdr);
474 
475  /* If the bpf header plus data doesn't fit in what's left
476  of the buffer, stick head in sand yet again... */
477  if (interface->rbuf_offset +
478  hdr.bh_hdrlen + hdr.bh_caplen > interface->rbuf_len) {
479  interface->rbuf_offset = interface->rbuf_len;
480  continue;
481  }
482 
483  /* If the captured data wasn't the whole packet, or if
484  the packet won't fit in the input buffer, all we
485  can do is drop it. */
486  if (hdr.bh_caplen != hdr.bh_datalen) {
487  interface->rbuf_offset =
488  BPF_WORDALIGN(interface->rbuf_offset +
489  hdr.bh_hdrlen + hdr.bh_caplen);
490  continue;
491  }
492 
493  /* Skip over the BPF header... */
494  interface->rbuf_offset += hdr.bh_hdrlen;
495 
496  /* Decode the physical header... */
497  offset = decode_hw_header(interface, interface->rbuf,
498  interface->rbuf_offset, hfrom);
499 
500  /* If a physical layer checksum failed (dunno of any
501  physical layer that supports this, but WTH), skip this
502  packet. */
503  if (offset < 0) {
504  interface->rbuf_offset =
505  BPF_WORDALIGN(interface->rbuf_offset +
506  hdr.bh_caplen);
507  continue;
508  }
509  interface->rbuf_offset += offset;
510  hdr.bh_caplen -= offset;
511 
512  /* Decode the IP and UDP headers... */
513  offset = decode_udp_ip_header(interface, interface->rbuf,
514  interface->rbuf_offset,
515  from, hdr.bh_caplen, &paylen, 1);
516 
517  /* If the IP or UDP checksum was bad, skip the packet... */
518  if (offset < 0) {
519  interface->rbuf_offset =
520  BPF_WORDALIGN(interface->rbuf_offset +
521  hdr.bh_caplen);
522  continue;
523  }
524  interface->rbuf_offset = interface->rbuf_offset + offset;
525  hdr.bh_caplen -= offset;
526 
527  /* If there's not enough room to stash the packet data,
528  we have to skip it (this shouldn't happen in real
529  life, though). */
530  if (hdr.bh_caplen > len) {
531  interface->rbuf_offset =
532  BPF_WORDALIGN(interface->rbuf_offset +
533  hdr.bh_caplen);
534  continue;
535  }
536 
537  /* Copy out the data in the packet... */
538  memcpy(buf, interface->rbuf + interface->rbuf_offset, paylen);
539  interface->rbuf_offset =
540  BPF_WORDALIGN(interface->rbuf_offset + hdr.bh_caplen);
541  return paylen;
542  } while (interface->rbuf_offset < interface->rbuf_len);
543 
544  return (0);
545 }
546 
548  struct interface_info *ip;
549 {
550  return 1;
551 }
552 
554  struct interface_info *ip;
555 {
556  return 1;
557 }
558 
560  struct interface_info *ip;
561 {
562  return 1;
563 }
564 
565 void maybe_setup_fallback ()
566 {
567  isc_result_t status;
568  struct interface_info *fbi = (struct interface_info *)0;
569  if (setup_fallback (&fbi, MDL)) {
570  if_register_fallback (fbi);
571  status = omapi_register_io_object ((omapi_object_t *)fbi,
572  if_readsocket, 0,
573  fallback_discard, 0, 0);
574  if (status != ISC_R_SUCCESS)
575  log_fatal ("Can't register I/O handle for %s: %s",
576  fbi -> name, isc_result_totext (status));
577  interface_dereference (&fbi, MDL);
578  }
579 }
580 #endif
581 
582 #if defined(USE_BPF_RECEIVE) || defined(USE_BPF_HWADDR)
583 void
584 get_hw_addr(const char *name, struct hardware *hw) {
585  struct ifaddrs *ifa;
586  struct ifaddrs *p;
587  struct sockaddr_dl *sa;
588 
589  if (getifaddrs(&ifa) != 0) {
590  log_fatal("Error getting interface information; %m");
591  }
592 
593  /*
594  * Loop through our interfaces finding a match.
595  */
596  sa = NULL;
597  for (p=ifa; (p != NULL) && (sa == NULL); p = p->ifa_next) {
598  if ((p->ifa_addr->sa_family == AF_LINK) &&
599  !strcmp(p->ifa_name, name)) {
600  sa = (struct sockaddr_dl *)p->ifa_addr;
601  }
602  }
603  if (sa == NULL) {
604  log_fatal("No interface called '%s'", name);
605  }
606 
607  /*
608  * Pull out the appropriate information.
609  */
610  switch (sa->sdl_type) {
611  case IFT_ETHER:
612 #if defined (IFT_L2VLAN)
613  case IFT_L2VLAN:
614 #endif
615  hw->hlen = sa->sdl_alen + 1;
616  hw->hbuf[0] = HTYPE_ETHER;
617  memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
618  break;
619  case IFT_ISO88023:
620  case IFT_ISO88024: /* "token ring" */
621  case IFT_ISO88025:
622  case IFT_ISO88026:
623  hw->hlen = sa->sdl_alen + 1;
624  hw->hbuf[0] = HTYPE_IEEE802;
625  memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
626  break;
627 #ifdef IFT_FDDI
628  case IFT_FDDI:
629  hw->hlen = sa->sdl_alen + 1;
630  hw->hbuf[0] = HTYPE_FDDI;
631  memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
632  break;
633 #endif /* IFT_FDDI */
634 #if defined(IFT_PPP)
635  case IFT_PPP:
636  if (local_family != AF_INET6)
637  log_fatal("Unsupported device type %d for \"%s\"",
638  sa->sdl_type, name);
639  hw->hlen = 0;
640  hw->hbuf[0] = HTYPE_RESERVED;
641  /* 0xdeadbeef should never occur on the wire,
642  * and is a signature that something went wrong.
643  */
644  hw->hbuf[1] = 0xde;
645  hw->hbuf[2] = 0xad;
646  hw->hbuf[3] = 0xbe;
647  hw->hbuf[4] = 0xef;
648  break;
649 #endif
650  default:
651  log_fatal("Unsupported device type %d for \"%s\"",
652  sa->sdl_type, name);
653  }
654 
655  freeifaddrs(ifa);
656 }
657 #endif
void if_register_send(struct interface_info *)
isc_result_t omapi_register_io_object(omapi_object_t *, int(*)(omapi_object_t *), int(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *))
Definition: dispatch.c:199
void assemble_udp_ip_header(struct interface_info *, unsigned char *, unsigned *, u_int32_t, u_int32_t, u_int32_t, unsigned char *, unsigned)
#define ETHERTYPE_IP
Definition: if_ether.h:57
u_int8_t hlen
Definition: dhcpd.h:489
int if_readsocket(omapi_object_t *h)
Definition: discover.c:991
char name[IFNAMSIZ]
Definition: dhcpd.h:1375
void if_reinitialize_send(struct interface_info *)
ssize_t decode_udp_ip_header(struct interface_info *, unsigned char *, unsigned, struct sockaddr_in *, unsigned, unsigned *, int)
#define HTYPE_RESERVED
Definition: dhcp.h:84
#define MDL
Definition: omapip.h:568
int can_receive_unicast_unconfigured(struct interface_info *)
isc_result_t dhcp_interface_remove(omapi_object_t *lp, omapi_object_t *id)
Definition: discover.c:1412
int setup_fallback(struct interface_info **fp, const char *file, int line)
Definition: discover.c:1002
int log_error(const char *,...) __attribute__((__format__(__printf__
void if_deregister_receive(struct interface_info *)
void get_hw_addr(struct interface_info *info)
void maybe_setup_fallback(void)
void if_deregister_send(struct interface_info *)
void log_fatal(const char *,...) __attribute__((__format__(__printf__
#define HTYPE_ETHER
Definition: dhcp.h:76
u_int16_t local_port
Definition: dhclient.c:91
Definition: dhcpd.h:405
void assemble_hw_header(struct interface_info *, unsigned char *, unsigned *, struct hardware *)
Definition: ip.h:47
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
int int log_info(const char *,...) __attribute__((__format__(__printf__
void * dmalloc(size_t, const char *, int)
Definition: alloc.c:56
int local_family
Definition: discover.c:55
int quiet_interface_discovery
Definition: discover.c:44
#define HTYPE_FDDI
Definition: dhcp.h:78
#define BPF_FORMAT
Definition: osdep.h:204
void if_register_fallback(struct interface_info *)
ssize_t send_fallback(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
int supports_multiple_interfaces(struct interface_info *)
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
Definition: dhcpd.h:490
ssize_t receive_packet(struct interface_info *, unsigned char *, size_t, struct sockaddr_in *, struct hardware *)
#define HTYPE_IEEE802
Definition: dhcp.h:77
ssize_t decode_hw_header(struct interface_info *, unsigned char *, unsigned, struct hardware *)
void if_reinitialize_receive(struct interface_info *)
int can_unicast_without_arp(struct interface_info *)
void if_register_receive(struct interface_info *)
isc_result_t fallback_discard(omapi_object_t *)