diff options
author | murray <murray@FreeBSD.org> | 2002-02-19 11:04:34 +0000 |
---|---|---|
committer | murray <murray@FreeBSD.org> | 2002-02-19 11:04:34 +0000 |
commit | 57b30d23e7c11fa1a8c8c23f27de40971872952f (patch) | |
tree | 229464d9b3244ab78e2784c9a0a1f78de317089a /contrib/isc-dhcp/common/socket.c | |
parent | 7acb11388cf5d680b16902b8ed6f46c46dc4d47b (diff) | |
download | FreeBSD-src-57b30d23e7c11fa1a8c8c23f27de40971872952f.zip FreeBSD-src-57b30d23e7c11fa1a8c8c23f27de40971872952f.tar.gz |
Import ISC DHCP 3.0.1 RC6 client.
Diffstat (limited to 'contrib/isc-dhcp/common/socket.c')
-rw-r--r-- | contrib/isc-dhcp/common/socket.c | 152 |
1 files changed, 116 insertions, 36 deletions
diff --git a/contrib/isc-dhcp/common/socket.c b/contrib/isc-dhcp/common/socket.c index 0a6b0b8..b4ecd14 100644 --- a/contrib/isc-dhcp/common/socket.c +++ b/contrib/isc-dhcp/common/socket.c @@ -3,8 +3,8 @@ BSD socket interface code... */ /* - * Copyright (c) 1995, 1996, 1997, 1998, 1999 - * The Internet Software Consortium. All rights reserved. + * Copyright (c) 1995-2000 Internet Software Consortium. + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,10 +34,11 @@ * 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''. */ /* SO_BINDTODEVICE support added by Elliot Poger (poger@leland.stanford.edu). @@ -50,7 +51,7 @@ #ifndef lint static char copyright[] = -"$Id: socket.c,v 1.26.2.12 1999/10/25 15:39:55 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; +"$Id: socket.c,v 1.55.2.1 2002/01/17 19:42:55 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -108,7 +109,7 @@ int if_register_socket (info) #if !defined (HAVE_SO_BINDTODEVICE) && !defined (USE_FALLBACK) /* Make sure only one interface is registered. */ if (once) - error ("The standard socket API can only support %s", + log_fatal ("The standard socket API can only support %s", "hosts with a single network interface."); once = 1; #endif @@ -116,35 +117,44 @@ int if_register_socket (info) /* Set up the address we're going to bind to. */ name.sin_family = AF_INET; name.sin_port = local_port; - name.sin_addr.s_addr = INADDR_ANY; + name.sin_addr = local_address; memset (name.sin_zero, 0, sizeof (name.sin_zero)); /* Make a socket... */ if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) - error ("Can't create dhcp socket: %m"); + log_fatal ("Can't create dhcp socket: %m"); /* Set the REUSEADDR option so that we don't fail to start if we're being restarted. */ flag = 1; if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof flag) < 0) - error ("Can't set SO_REUSEADDR option on dhcp socket: %m"); + log_fatal ("Can't set SO_REUSEADDR option on dhcp socket: %m"); - /* Set the BROADCAST option so that we can broadcast DHCP responses. */ - if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST, - (char *)&flag, sizeof flag) < 0) - error ("Can't set SO_BROADCAST option on dhcp socket: %m"); + /* Set the BROADCAST option so that we can broadcast DHCP responses. + We shouldn't do this for fallback devices, and we can detect that + a device is a fallback because it has no ifp structure. */ + if (info -> ifp && + (setsockopt (sock, SOL_SOCKET, SO_BROADCAST, + (char *)&flag, sizeof flag) < 0)) + log_fatal ("Can't set SO_BROADCAST option on dhcp socket: %m"); /* Bind the socket to this interface's IP address. */ - if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0) - error ("Can't bind to dhcp address: %m"); + if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0) { + log_error ("Can't bind to dhcp address: %m"); + log_error ("Please make sure there is no other dhcp server"); + log_error ("running and that there's no entry for dhcp or"); + log_error ("bootp in /etc/inetd.conf. Also make sure you"); + log_error ("are not running HP JetAdmin software, which"); + log_fatal ("includes a bootp server."); + } #if defined (HAVE_SO_BINDTODEVICE) /* Bind this socket to this interface. */ if (info -> ifp && setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)(info -> ifp), sizeof *(info -> ifp)) < 0) { - error("setsockopt: SO_BINDTODEVICE: %m"); + log_fatal ("setsockopt: SO_BINDTODEVICE: %m"); } #endif @@ -158,16 +168,39 @@ void if_register_send (info) { #ifndef USE_SOCKET_RECEIVE info -> wfdesc = if_register_socket (info); +#if defined (USE_SOCKET_FALLBACK) + /* Fallback only registers for send, but may need to receive as + well. */ + info -> rfdesc = info -> wfdesc; +#endif #else info -> wfdesc = info -> rfdesc; #endif if (!quiet_interface_discovery) - note ("Sending on Socket/%s%s%s", + log_info ("Sending on Socket/%s%s%s", + info -> name, + (info -> shared_network ? "/" : ""), + (info -> shared_network ? + info -> shared_network -> name : "")); +} + +#if defined (USE_SOCKET_SEND) +void if_deregister_send (info) + struct interface_info *info; +{ +#ifndef USE_SOCKET_RECEIVE + close (info -> wfdesc); +#endif + info -> wfdesc = -1; + + if (!quiet_interface_discovery) + log_info ("Disabling output on Socket/%s%s%s", info -> name, (info -> shared_network ? "/" : ""), (info -> shared_network ? info -> shared_network -> name : "")); } +#endif /* USE_SOCKET_SEND */ #endif /* USE_SOCKET_SEND || USE_SOCKET_FALLBACK */ #ifdef USE_SOCKET_RECEIVE @@ -178,7 +211,21 @@ void if_register_receive (info) we don't need to register this interface twice. */ info -> rfdesc = if_register_socket (info); if (!quiet_interface_discovery) - note ("Listening on Socket/%s%s%s", + log_info ("Listening on Socket/%s%s%s", + info -> name, + (info -> shared_network ? "/" : ""), + (info -> shared_network ? + info -> shared_network -> name : "")); +} + +void if_deregister_receive (info) + struct interface_info *info; +{ + close (info -> rfdesc); + info -> rfdesc = -1; + + if (!quiet_interface_discovery) + log_info ("Disabling input on Socket/%s%s%s", info -> name, (info -> shared_network ? "/" : ""), (info -> shared_network ? @@ -211,10 +258,10 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) retry++ < 10); #endif if (result < 0) { - warn ("send_packet: %m"); + log_error ("send_packet: %m"); if (errno == ENETUNREACH) - warn ("send_packet: please consult README file %s", - "regarding broadcast address."); + log_error ("send_packet: please consult README file%s", + " regarding broadcast address."); } return result; } @@ -228,7 +275,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) struct sockaddr_in *from; struct hardware *hfrom; { - int flen = sizeof *from; + SOCKLEN_T flen = sizeof *from; int result; #ifdef IGNORE_HOSTUNREACH @@ -250,24 +297,35 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) #if defined (USE_SOCKET_FALLBACK) /* This just reads in a packet and silently discards it. */ -void fallback_discard (protocol) - struct protocol *protocol; +isc_result_t fallback_discard (object) + omapi_object_t *object; { char buf [1540]; struct sockaddr_in from; - int flen = sizeof from; + SOCKLEN_T flen = sizeof from; int status; - struct interface_info *interface = protocol -> local; + struct interface_info *interface; + + if (object -> type != dhcp_type_interface) + return ISC_R_INVALIDARG; + interface = (struct interface_info *)object; status = recvfrom (interface -> wfdesc, buf, sizeof buf, 0, (struct sockaddr *)&from, &flen); - if (status < 0) - warn ("fallback_discard: %m"); +#if defined (DEBUG) + /* Only report fallback discard errors if we're debugging. */ + if (status < 0) { + log_error ("fallback_discard: %m"); + return ISC_R_UNEXPECTED; + } +#endif + return ISC_R_SUCCESS; } #endif /* USE_SOCKET_FALLBACK */ #if defined (USE_SOCKET_SEND) -int can_unicast_without_arp () +int can_unicast_without_arp (ip) + struct interface_info *ip; { return 0; } @@ -282,18 +340,40 @@ int can_receive_unicast_unconfigured (ip) #endif } +int supports_multiple_interfaces (ip) + struct interface_info *ip; +{ +#if defined (SO_BINDTODEVICE) + return 1; +#else + return 0; +#endif +} + /* If we have SO_BINDTODEVICE, set up a fallback interface; otherwise, do not. */ void maybe_setup_fallback () { #if defined (USE_SOCKET_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)) { fbi -> wfdesc = if_register_socket (fbi); - add_protocol ("fallback", - fbi -> wfdesc, fallback_discard, fbi); + fbi -> rfdesc = fbi -> wfdesc; + log_info ("Sending on Socket/%s%s%s", + fbi -> name, + (fbi -> shared_network ? "/" : ""), + (fbi -> shared_network ? + fbi -> shared_network -> name : "")); + + 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 } |