diff options
author | Ted Lemon <source@isc.org> | 1996-05-13 00:08:05 +0000 |
---|---|---|
committer | Ted Lemon <source@isc.org> | 1996-05-13 00:08:05 +0000 |
commit | e23c9055ccb4b09ccc95d6f944b7d95fc0eed06e (patch) | |
tree | ea15f8b7e009e51cdff42bf89b6b486a00a4f6ce | |
parent | 62f52c1f15205341f0a7bf1094231cbe048d4914 (diff) | |
download | isc-dhcp-e23c9055ccb4b09ccc95d6f944b7d95fc0eed06e.tar.gz |
Rewrite socket code to support new network abstraction
-rw-r--r-- | common/socket.c | 66 | ||||
-rw-r--r-- | socket.c | 66 |
2 files changed, 106 insertions, 26 deletions
diff --git a/common/socket.c b/common/socket.c index 90335ebe..2218dd4b 100644 --- a/common/socket.c +++ b/common/socket.c @@ -47,7 +47,9 @@ static char copyright[] = #include "dhcpd.h" -void if_register_socket (info, interface) +#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) +/* Generic interface registration routine... */ +int if_register_socket (info, interface) struct interface_info *info; struct ifreq *interface; { @@ -55,10 +57,22 @@ void if_register_socket (info, interface) int sock; struct socklist *tmp; int flag; + static int once = 0; + /* Make sure only one interface is registered. */ + if (once) + error ("The standard socket API can only support hosts " + "with a single network interface. If you must " + "run dhcpd on a host with multiple interfaces, " + "you must compile in BPF or NIT support. If neither " + "option is supported on your system, please let us " + "know."); + once = 1; + + /* Set up the address we're going to bind to. */ name.sin_family = AF_INET; name.sin_port = server_port; - memcpy (&name.sin_addr.s_addr, info -> address.iabuf, 4); + name.sin_addr.s_addr = INADDR_ANY; memset (name.sin_zero, 0, sizeof (name.sin_zero)); /* List addresses on which we're listening. */ @@ -67,35 +81,58 @@ void if_register_socket (info, interface) if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) error ("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, &flag, sizeof flag) < 0) error ("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, &flag, sizeof flag) < 0) error ("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"); - info -> rfdesc = sock; + return sock; } +#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */ #ifdef USE_SOCKET_SEND void if_register_send (info, interface) struct interface_info *info; struct ifreq *interface; { - if_register_socket (info, interface); +#ifndef USE_SOCKET_RECEIVE + info -> wfdesc = if_register_socket (info, interface); +#else + info -> wfdesc = info -> rfdesc; +#endif } +#endif /* USE_SOCKET_SEND */ -int send_packet (interface, packet, raw, len, to, hto) +#ifdef USE_SOCKET_RECEIVE +void if_register_receive (info, interface) + struct interface_info *info; + struct ifreq *interface; +{ + /* If we're using the socket API for sending and receiving, + we don't need to register this interface twice. */ + info -> rfdesc = if_register_socket (info, interface); +} +#endif /* USE_SOCKET_RECEIVE */ + +#ifdef USE_SOCKET_SEND +size_t send_packet (interface, packet, raw, len, to, hto) + struct interface_info *interface; struct packet *packet; struct dhcp_packet *raw; size_t len; struct sockaddr_in *to; - struct hardware_addr *hto; + struct hardware *hto; { return sendto (interface -> wfdesc, raw, len, 0, (struct sockaddr *)to, sizeof *to); @@ -103,13 +140,16 @@ int send_packet (interface, packet, raw, len, to, hto) #endif /* USE_SOCKET_SEND */ #ifdef USE_SOCKET_RECEIVE -void if_register_send (info, interface) - struct interface_info *info; - struct ifreq *interface; +size_t receive_packet (interface, buf, len, from, hfrom) + struct interface_info *interface; + unsigned char *buf; + size_t len; + struct sockaddr_in *from; + struct hardware *hfrom; { -/* Do nothing unless we're using a different API for sending packets... */ -#ifndef USE_SOCKET_SEND - if_register_socket (info, interface); -#endif + int flen = sizeof *from; + + return recvfrom (interface -> rfdesc, buf, len, 0, + (struct sockaddr *)from, &flen); } #endif /* USE_SOCKET_RECEIVE */ @@ -47,7 +47,9 @@ static char copyright[] = #include "dhcpd.h" -void if_register_socket (info, interface) +#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) +/* Generic interface registration routine... */ +int if_register_socket (info, interface) struct interface_info *info; struct ifreq *interface; { @@ -55,10 +57,22 @@ void if_register_socket (info, interface) int sock; struct socklist *tmp; int flag; + static int once = 0; + /* Make sure only one interface is registered. */ + if (once) + error ("The standard socket API can only support hosts " + "with a single network interface. If you must " + "run dhcpd on a host with multiple interfaces, " + "you must compile in BPF or NIT support. If neither " + "option is supported on your system, please let us " + "know."); + once = 1; + + /* Set up the address we're going to bind to. */ name.sin_family = AF_INET; name.sin_port = server_port; - memcpy (&name.sin_addr.s_addr, info -> address.iabuf, 4); + name.sin_addr.s_addr = INADDR_ANY; memset (name.sin_zero, 0, sizeof (name.sin_zero)); /* List addresses on which we're listening. */ @@ -67,35 +81,58 @@ void if_register_socket (info, interface) if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) error ("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, &flag, sizeof flag) < 0) error ("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, &flag, sizeof flag) < 0) error ("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"); - info -> rfdesc = sock; + return sock; } +#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */ #ifdef USE_SOCKET_SEND void if_register_send (info, interface) struct interface_info *info; struct ifreq *interface; { - if_register_socket (info, interface); +#ifndef USE_SOCKET_RECEIVE + info -> wfdesc = if_register_socket (info, interface); +#else + info -> wfdesc = info -> rfdesc; +#endif } +#endif /* USE_SOCKET_SEND */ -int send_packet (interface, packet, raw, len, to, hto) +#ifdef USE_SOCKET_RECEIVE +void if_register_receive (info, interface) + struct interface_info *info; + struct ifreq *interface; +{ + /* If we're using the socket API for sending and receiving, + we don't need to register this interface twice. */ + info -> rfdesc = if_register_socket (info, interface); +} +#endif /* USE_SOCKET_RECEIVE */ + +#ifdef USE_SOCKET_SEND +size_t send_packet (interface, packet, raw, len, to, hto) + struct interface_info *interface; struct packet *packet; struct dhcp_packet *raw; size_t len; struct sockaddr_in *to; - struct hardware_addr *hto; + struct hardware *hto; { return sendto (interface -> wfdesc, raw, len, 0, (struct sockaddr *)to, sizeof *to); @@ -103,13 +140,16 @@ int send_packet (interface, packet, raw, len, to, hto) #endif /* USE_SOCKET_SEND */ #ifdef USE_SOCKET_RECEIVE -void if_register_send (info, interface) - struct interface_info *info; - struct ifreq *interface; +size_t receive_packet (interface, buf, len, from, hfrom) + struct interface_info *interface; + unsigned char *buf; + size_t len; + struct sockaddr_in *from; + struct hardware *hfrom; { -/* Do nothing unless we're using a different API for sending packets... */ -#ifndef USE_SOCKET_SEND - if_register_socket (info, interface); -#endif + int flen = sizeof *from; + + return recvfrom (interface -> rfdesc, buf, len, 0, + (struct sockaddr *)from, &flen); } #endif /* USE_SOCKET_RECEIVE */ |