aboutsummaryrefslogtreecommitdiff
path: root/contrib/isc-dhcp/common/nit.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/isc-dhcp/common/nit.c')
-rw-r--r--contrib/isc-dhcp/common/nit.c160
1 files changed, 105 insertions, 55 deletions
diff --git a/contrib/isc-dhcp/common/nit.c b/contrib/isc-dhcp/common/nit.c
index 77f43b38d98d..59197f2a46f3 100644
--- a/contrib/isc-dhcp/common/nit.c
+++ b/contrib/isc-dhcp/common/nit.c
@@ -4,7 +4,7 @@
with one crucial tidbit of help from Stu Grossmen. */
/*
- * Copyright (c) 1996, 1998, 1999 The Internet Software Consortium.
+ * Copyright (c) 1996-2000 Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,14 +35,16 @@
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises. To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''. To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''. */
+ * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
+ * To learn more about the Internet Software Consortium, see
+ * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
+ * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
+ * ``http://www.nominum.com''.
+ */
#ifndef lint
static char copyright[] =
-"$Id: nit.c,v 1.15.2.4 1999/03/29 22:07:14 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: nit.c,v 1.34 2001/02/17 21:17:25 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -95,7 +97,7 @@ int if_register_nit (info)
/* Open a NIT device */
sock = open ("/dev/nit", O_RDWR);
if (sock < 0)
- error ("Can't open NIT device for %s: %m", info -> name);
+ log_fatal ("Can't open NIT device for %s: %m", info -> name);
/* Set the NIT device to point at this interface. */
sio.ic_cmd = NIOCBIND;
@@ -103,7 +105,7 @@ int if_register_nit (info)
sio.ic_dp = (char *)(info -> ifp);
sio.ic_timout = INFTIM;
if (ioctl (sock, I_STR, &sio) < 0)
- error ("Can't attach interface %s to nit device: %m",
+ log_fatal ("Can't attach interface %s to nit device: %m",
info -> name);
/* Get the low-level address... */
@@ -112,16 +114,17 @@ int if_register_nit (info)
sio.ic_dp = (char *)&ifr;
sio.ic_timout = INFTIM;
if (ioctl (sock, I_STR, &sio) < 0)
- error ("Can't get physical layer address for %s: %m",
+ log_fatal ("Can't get physical layer address for %s: %m",
info -> name);
/* XXX code below assumes ethernet interface! */
- info -> hw_address.hlen = 6;
- info -> hw_address.htype = ARPHRD_ETHER;
- memcpy (info -> hw_address.haddr, ifr.ifr_ifru.ifru_addr.sa_data, 6);
+ info -> hw_address.hlen = 7;
+ info -> hw_address.hbuf [0] = ARPHRD_ETHER;
+ memcpy (&info -> hw_address.hbuf [1],
+ ifr.ifr_ifru.ifru_addr.sa_data, 6);
if (ioctl (sock, I_PUSH, "pf") < 0)
- error ("Can't push packet filter onto NIT for %s: %m",
+ log_fatal ("Can't push packet filter onto NIT for %s: %m",
info -> name);
return sock;
@@ -150,15 +153,34 @@ void if_register_send (info)
sio.ic_dp = (char *)&pf;
sio.ic_timout = INFTIM;
if (ioctl (info -> wfdesc, I_STR, &sio) < 0)
- error ("Can't set NIT filter: %m");
+ log_fatal ("Can't set NIT filter: %m");
#else
info -> wfdesc = info -> rfdesc;
#endif
if (!quiet_interface_discovery)
- note ("Sending on NIT/%s%s%s",
- print_hw_addr (info -> hw_address.htype,
- info -> hw_address.hlen,
- info -> hw_address.haddr),
+ log_info ("Sending on NIT/%s%s%s",
+ print_hw_addr (info -> hw_address.hbuf [0],
+ info -> hw_address.hlen - 1,
+ &info -> hw_address.hbuf [1]),
+ (info -> shared_network ? "/" : ""),
+ (info -> shared_network ?
+ info -> shared_network -> name : ""));
+}
+
+void if_deregister_send (info)
+ struct interface_info *info;
+{
+ /* If we're using the nit API for sending and receiving,
+ we don't need to register this interface twice. */
+#ifndef USE_NIT_RECEIVE
+ close (info -> wfdesc);
+#endif
+ info -> wfdesc = -1;
+ if (!quiet_interface_discovery)
+ log_info ("Disabling output on NIT/%s%s%s",
+ print_hw_addr (info -> hw_address.hbuf [0],
+ info -> hw_address.hlen - 1,
+ &info -> hw_address.hbuf [1]),
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : ""));
@@ -187,28 +209,28 @@ void if_register_receive (info)
packet. */
x = 0;
if (ioctl (info -> rfdesc, NIOCSSNAP, &x) < 0)
- error ("Can't set NIT snap length on %s: %m", info -> name);
+ log_fatal ("Can't set NIT snap length on %s: %m", info -> name);
/* Set the stream to byte stream mode */
if (ioctl (info -> rfdesc, I_SRDOPT, RMSGN) != 0)
- note ("I_SRDOPT failed on %s: %m", info -> name);
+ log_info ("I_SRDOPT failed on %s: %m", info -> name);
#if 0
/* Push on the chunker... */
if (ioctl (info -> rfdesc, I_PUSH, "nbuf") < 0)
- error ("Can't push chunker onto NIT STREAM: %m");
+ log_fatal ("Can't push chunker onto NIT STREAM: %m");
/* Set the timeout to zero. */
t.tv_sec = 0;
t.tv_usec = 0;
if (ioctl (info -> rfdesc, NIOCSTIME, &t) < 0)
- error ("Can't set chunk timeout: %m");
+ log_fatal ("Can't set chunk timeout: %m");
#endif
/* Ask for no header... */
x = 0;
if (ioctl (info -> rfdesc, NIOCSFLAGS, &x) < 0)
- error ("Can't set NIT flags on %s: %m", info -> name);
+ log_fatal ("Can't set NIT flags on %s: %m", info -> name);
/* Set up the NIT filter program. */
/* XXX Unlike the BPF filter program, this one won't work if the
@@ -236,13 +258,31 @@ void if_register_receive (info)
sio.ic_dp = (char *)&pf;
sio.ic_timout = INFTIM;
if (ioctl (info -> rfdesc, I_STR, &sio) < 0)
- error ("Can't set NIT filter on %s: %m", info -> name);
+ log_fatal ("Can't set NIT filter on %s: %m", info -> name);
if (!quiet_interface_discovery)
- note ("Listening on NIT/%s%s%s",
- print_hw_addr (info -> hw_address.htype,
- info -> hw_address.hlen,
- info -> hw_address.haddr),
+ log_info ("Listening on NIT/%s%s%s",
+ print_hw_addr (info -> hw_address.hbuf [0],
+ info -> hw_address.hlen - 1,
+ &info -> hw_address.hbuf [1]),
+ (info -> shared_network ? "/" : ""),
+ (info -> shared_network ?
+ info -> shared_network -> name : ""));
+}
+
+void if_deregister_receive (info)
+ struct interface_info *info;
+{
+ /* If we're using the nit API for sending and receiving,
+ we don't need to register this interface twice. */
+ close (info -> rfdesc);
+ info -> rfdesc = -1;
+
+ if (!quiet_interface_discovery)
+ log_info ("Disabling input on NIT/%s%s%s",
+ print_hw_addr (info -> hw_address.hbuf [0],
+ info -> hw_address.hlen - 1,
+ &info -> hw_address.hbuf [1]),
(info -> shared_network ? "/" : ""),
(info -> shared_network ?
info -> shared_network -> name : ""));
@@ -259,11 +299,12 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct sockaddr_in *to;
struct hardware *hto;
{
- int bufp;
- unsigned char buf [1536 + sizeof (struct sockaddr)];
+ unsigned hbufp, ibufp;
+ double hh [16];
+ double ih [1536 / sizeof (double)];
+ unsigned char *buf = (unsigned char *)ih;
struct sockaddr *junk;
struct strbuf ctl, data;
- int hw_end;
struct sockaddr_in foo;
int result;
@@ -272,38 +313,35 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
len, from, to, hto);
/* Start with the sockaddr struct... */
- junk = (struct sockaddr *)&buf [0];
- bufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0];
+ junk = (struct sockaddr *)&hh [0];
+ hbufp = (((unsigned char *)&junk -> sa_data [0]) -
+ (unsigned char *)&hh[0]);
+ ibufp = 0;
/* Assemble the headers... */
- assemble_hw_header (interface, buf, &bufp, hto);
- hw_end = bufp;
- assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
- to -> sin_addr.s_addr, to -> sin_port,
- raw, len);
+ assemble_hw_header (interface, (unsigned char *)junk, &hbufp, hto);
+ assemble_udp_ip_header (interface, buf, &ibufp,
+ from.s_addr, to -> sin_addr.s_addr,
+ to -> sin_port, (unsigned char *)raw, len);
/* Copy the data into the buffer (yuk). */
- memcpy (buf + bufp, raw, len);
+ memcpy (buf + ibufp, raw, len);
/* Set up the sockaddr structure... */
#if USE_SIN_LEN
- junk -> sa_len = hw_end - 2; /* XXX */
+ junk -> sa_len = hbufp - 2; /* XXX */
#endif
junk -> sa_family = AF_UNSPEC;
-#if 0 /* Already done. */
- memcpy (junk.sa_data, buf, hw_len);
-#endif
-
/* Set up the msg_buf structure... */
- ctl.buf = (char *)&buf [0];
- ctl.maxlen = ctl.len = hw_end;
- data.buf = (char *)&buf [hw_end];
- data.maxlen = data.len = bufp + len - hw_end;
+ ctl.buf = (char *)&hh [0];
+ ctl.maxlen = ctl.len = hbufp;
+ data.buf = (char *)&ih [0];
+ data.maxlen = data.len = ibufp + len;
result = putmsg (interface -> wfdesc, &ctl, &data, 0);
if (result < 0)
- warn ("send_packet: %m");
+ log_error ("send_packet: %m");
return result;
}
#endif /* USE_NIT_SEND */
@@ -355,7 +393,8 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
return length;
}
-int can_unicast_without_arp ()
+int can_unicast_without_arp (ip)
+ struct interface_info *ip;
{
return 1;
}
@@ -366,14 +405,25 @@ int can_receive_unicast_unconfigured (ip)
return 1;
}
+int supports_multiple_interfaces (ip)
+ struct interface_info *ip;
+{
+ return 1;
+}
+
void maybe_setup_fallback ()
{
- struct interface_info *fbi;
- fbi = setup_fallback ();
- if (fbi) {
+ isc_result_t status;
+ struct interface_info *fbi = (struct interface_info *)0;
+ if (setup_fallback (&fbi, MDL)) {
if_register_fallback (fbi);
- add_protocol ("fallback", fallback_interface -> wfdesc,
- fallback_discard, fallback_interface);
+ status = omapi_register_io_object ((omapi_object_t *)fbi,
+ if_readsocket, 0,
+ fallback_discard, 0, 0);
+ if (status != ISC_R_SUCCESS)
+ log_fatal ("Can't register I/O handle for %s: %s",
+ fbi -> name, isc_result_totext (status));
+ interface_dereference (&fbi, MDL);
}
}
#endif