#include "dhcp-network.h"
#include "dhcp-packet.h"
#include "fd-util.h"
+#include "iovec-util.h"
+#include "iovec-wrapper.h"
#include "socket-util.h"
static int client_get_socket(sd_dhcp_client *client, int domain) {
r = dhcp_network_send_raw_socket(
fd,
&client->link,
- packet,
- sizeof(DHCPPacket) + optoffset);
+ &(struct iovec_wrapper) {
+ .iovec = &IOVEC_MAKE(packet, sizeof(DHCPPacket) + optoffset),
+ .count = 1,
+ });
if (r < 0)
return r;
fd,
client->lease->server_address,
client->server_port,
- &packet->dhcp,
- sizeof(DHCPMessage) + optoffset);
+ &(struct iovec_wrapper) {
+ .iovec = &IOVEC_MAKE(&packet->dhcp, sizeof(DHCPMessage) + optoffset),
+ .count = 1,
+ });
if (r < 0)
return r;
#include <linux/if_infiniband.h>
#include <linux/if_packet.h>
#include <net/if_arp.h>
-#include <stdio.h>
#include <string.h>
#include "dhcp-network.h"
#include "dhcp-protocol.h"
#include "ether-addr-util.h"
#include "fd-util.h"
+#include "iovec-wrapper.h"
#include "socket-util.h"
#include "unaligned.h"
}
int dhcp_network_send_raw_socket(
- int s,
+ int fd,
const union sockaddr_union *link,
- const void *packet,
- size_t len) {
+ const struct iovec_wrapper *iovw) {
- /* Do not add assert(s >= 0) here, as this is called in fuzz-dhcp-server, and in that case this
- * function should fail with negative errno. */
+ /* Do not add assert(fd >= 0) here, as this is also called from fuzz-dhcp-server, and in that case
+ * fd is negative and this function should fail with negative errno. */
assert(link);
- assert(packet);
- assert(len > 0);
+ assert(!iovw_isempty(iovw));
- if (sendto(s, packet, len, 0, &link->sa, sockaddr_ll_len(&link->ll)) < 0)
+ struct msghdr mh = {
+ .msg_name = (struct sockaddr*) &link->sa,
+ .msg_namelen = sockaddr_ll_len(&link->ll),
+ .msg_iov = iovw->iovec,
+ .msg_iovlen = iovw->count,
+ };
+
+ if (sendmsg(fd, &mh, MSG_NOSIGNAL) < 0)
return -errno;
return 0;
}
int dhcp_network_send_udp_socket(
- int s,
+ int fd,
be32_t address,
uint16_t port,
- const void *packet,
- size_t len) {
+ const struct iovec_wrapper *iovw) {
+
+ assert(fd >= 0);
+ assert(!iovw_isempty(iovw));
union sockaddr_union dest = {
.in.sin_family = AF_INET,
.in.sin_addr.s_addr = address,
};
- assert(s >= 0);
- assert(packet);
- assert(len > 0);
+ struct msghdr mh = {
+ .msg_name = &dest.sa,
+ .msg_namelen = sizeof(dest.in),
+ .msg_iov = iovw->iovec,
+ .msg_iovlen = iovw->count,
+ };
- if (sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in)) < 0)
+ if (sendmsg(fd, &mh, MSG_NOSIGNAL) < 0)
return -errno;
return 0;
uint16_t port,
int ip_service_type);
int dhcp_network_send_raw_socket(
- int s,
+ int fd,
const union sockaddr_union *link,
- const void *packet,
- size_t len);
+ const struct iovec_wrapper *iovw);
int dhcp_network_send_udp_socket(
- int s,
+ int fd,
be32_t address,
uint16_t port,
- const void *packet,
- size_t len);
+ const struct iovec_wrapper *iovw);
return ASSERT_OK_ERRNO(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
}
-int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, const void *packet, size_t len) {
+int dhcp_network_send_raw_socket(int fd, const union sockaddr_union *link, const struct iovec_wrapper *iovw) {
return 0;
}
return ASSERT_OK_ERRNO(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
}
-int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, const void *packet, size_t len) {
+int dhcp_network_send_udp_socket(int fd, be32_t address, uint16_t port, const struct iovec_wrapper *iovw) {
return 0;
}
if (r < 0)
return r;
- return dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len);
+ return dhcp_network_send_raw_socket(
+ server->fd_raw,
+ &link,
+ &(struct iovec_wrapper) {
+ .iovec = &IOVEC_MAKE(packet, len),
+ .count = 1,
+ });
}
static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
#include "sd-dhcp-lease.h"
#include "sd-event.h"
-#include "alloc-util.h"
#include "dhcp-duid-internal.h"
#include "dhcp-network.h"
#include "dhcp-option.h"
#include "ether-addr-util.h"
#include "fd-util.h"
+#include "iovec-util.h"
+#include "iovec-wrapper.h"
#include "ip-util.h"
#include "log.h"
#include "tests.h"
return 0;
}
-int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, const void *packet, size_t len) {
+int dhcp_network_send_raw_socket(int fd, const union sockaddr_union *link, const struct iovec_wrapper *iovw) {
uint16_t ip_check, udp_check;
- ASSERT_OK(s);
- ASSERT_NOT_NULL(packet);
+ ASSERT_OK(fd);
+ ASSERT_NOT_NULL(iovw);
+ _cleanup_(iovec_done) struct iovec iov = {};
+ ASSERT_OK(iovw_concat(iovw, &iov));
+
+ size_t len = iov.iov_len;
ASSERT_GT(len, sizeof(DHCPPacket));
- _cleanup_free_ DHCPPacket *discover = ASSERT_NOT_NULL(memdup(packet, len));
+ DHCPPacket *discover = ASSERT_NOT_NULL(iov.iov_base);
ASSERT_EQ(discover->ip.ttl, IPDEFTTL);
ASSERT_EQ(discover->ip.protocol, IPPROTO_UDP);
return ASSERT_OK_ERRNO(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
}
-int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, const void *packet, size_t len) {
+int dhcp_network_send_udp_socket(int fd, be32_t address, uint16_t port, const struct iovec_wrapper *iovw) {
return 0;
}