]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Rewrite socket code to support new network abstraction
authorTed Lemon <source@isc.org>
Mon, 13 May 1996 00:08:05 +0000 (00:08 +0000)
committerTed Lemon <source@isc.org>
Mon, 13 May 1996 00:08:05 +0000 (00:08 +0000)
common/socket.c
socket.c

index 90335ebefc4e47eac14df6b23a8d194273efef4c..2218dd4b896a8cd522208e23eaef5586575ba366 100644 (file)
@@ -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 */
index 90335ebefc4e47eac14df6b23a8d194273efef4c..2218dd4b896a8cd522208e23eaef5586575ba366 100644 (file)
--- a/socket.c
+++ b/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 */