diff options
Diffstat (limited to 'contrib/isc-dhcp/common/nit.c')
-rw-r--r-- | contrib/isc-dhcp/common/nit.c | 160 |
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 *)𝔦 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 |