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