summaryrefslogtreecommitdiffstats
path: root/contrib/isc-dhcp/common/socket.c
diff options
context:
space:
mode:
authormurray <murray@FreeBSD.org>2002-02-19 11:04:34 +0000
committermurray <murray@FreeBSD.org>2002-02-19 11:04:34 +0000
commit57b30d23e7c11fa1a8c8c23f27de40971872952f (patch)
tree229464d9b3244ab78e2784c9a0a1f78de317089a /contrib/isc-dhcp/common/socket.c
parent7acb11388cf5d680b16902b8ed6f46c46dc4d47b (diff)
downloadFreeBSD-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.c152
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
}
OpenPOWER on IntegriCloud