chiark / gitweb /
libsystemd-dhcp: Return proper error if bind fails
[elogind.git] / src / libsystemd-dhcp / dhcp-network.c
index ed34228f6709c3e91d902cc18f7c30dac6b58048..7fecf270f8fec30b6415adb94cc3f783c89b1803 100644 (file)
 
 #include "dhcp-internal.h"
 
-int dhcp_network_send_raw_packet(int index, const void *packet, size_t len)
+int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link)
 {
-        _cleanup_close_ int s;
-        union sockaddr_union link = {};
+        int s;
 
-        s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IP));
+        s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
+                   htons(ETH_P_IP));
         if (s < 0)
                 return -errno;
 
-        link.ll.sll_family = AF_PACKET;
-        link.ll.sll_protocol = htons(ETH_P_IP);
-        link.ll.sll_ifindex =  index;
-        link.ll.sll_halen = ETH_ALEN;
-        memset(&link.ll.sll_addr, 0xff, ETH_ALEN);
+        link->ll.sll_family = AF_PACKET;
+        link->ll.sll_protocol = htons(ETH_P_IP);
+        link->ll.sll_ifindex =  index;
+        link->ll.sll_halen = ETH_ALEN;
+        memset(link->ll.sll_addr, 0xff, ETH_ALEN);
 
-        if (bind(s, &link.sa, sizeof(link.ll)) < 0)
+        if (bind(s, &link->sa, sizeof(link->ll)) < 0) {
+                close_nointr_nofail(s);
                 return -errno;
+        }
 
-        if (sendto(s, packet, len, 0, &link.sa, sizeof(link.ll)) < 0)
+        return s;
+}
+
+int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
+                                 const void *packet, size_t len)
+{
+        if (sendto(s, packet, len, 0, &link->sa, sizeof(link->ll)) < 0)
                 return -errno;
 
         return 0;