#include "icmp6-util.h"
#include "in-addr-util.h"
#include "iovec-util.h"
+#include "network-common.h"
#include "socket-util.h"
#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
.msg_control = &control,
.msg_controllen = sizeof(control),
};
- struct cmsghdr *cmsg;
struct in6_addr addr = {};
- triple_timestamp t = {};
ssize_t len;
iov = IOVEC_MAKE(buffer, size);
assert(!(msg.msg_flags & MSG_TRUNC));
- CMSG_FOREACH(cmsg, &msg) {
- if (cmsg->cmsg_level == SOL_IPV6 &&
- cmsg->cmsg_type == IPV6_HOPLIMIT &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
- int hops = *CMSG_TYPED_DATA(cmsg, int);
-
- if (hops != 255)
- return -EMULTIHOP;
- }
-
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_TIMESTAMP &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) {
- struct timeval *tv = memcpy(&(struct timeval) {}, CMSG_DATA(cmsg), sizeof(struct timeval));
- triple_timestamp_from_realtime(&t, timeval_load(tv));
- }
- }
-
- if (ret_timestamp) {
- if (triple_timestamp_is_set(&t))
- *ret_timestamp = t;
- else
- triple_timestamp_now(ret_timestamp);
- }
+ int *hops = CMSG_FIND_DATA(&msg, SOL_IPV6, IPV6_HOPLIMIT, int);
+ if (hops && *hops != 255)
+ return -EMULTIHOP;
+ if (ret_timestamp)
+ triple_timestamp_from_cmsg(ret_timestamp, &msg);
if (ret_sender)
*ret_sender = addr;
return 0;
#include "env-util.h"
#include "format-util.h"
#include "network-common.h"
+#include "socket-util.h"
#include "unaligned.h"
int get_ifname(int ifindex, char **ifname) {
return test_mode;
}
+
+triple_timestamp* triple_timestamp_from_cmsg(triple_timestamp *t, struct msghdr *mh) {
+ assert(t);
+ assert(mh);
+
+ struct timeval *tv = CMSG_FIND_AND_COPY_DATA(mh, SOL_SOCKET, SCM_TIMESTAMP, struct timeval);
+ if (tv)
+ return triple_timestamp_from_realtime(t, timeval_load(tv));
+
+ return triple_timestamp_now(t);
+}
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <sys/socket.h>
+
#include "log-link.h"
#include "sparse-endian.h"
#include "time-util.h"
usec_t time_span_to_stamp(usec_t span, usec_t base);
bool network_test_mode_enabled(void);
+
+triple_timestamp* triple_timestamp_from_cmsg(triple_timestamp *t, struct msghdr *mh);
+#define TRIPLE_TIMESTAMP_FROM_CMSG(mh) \
+ triple_timestamp_from_cmsg(&(triple_timestamp) {}, mh)
assert(client);
assert(message);
+ assert(timestamp);
if (client_verify_message_header(client, message, len) < 0)
return 0;
.msg_control = &control,
.msg_controllen = sizeof(control),
};
- triple_timestamp t = {};
int r;
assert(s);
return 0;
}
- struct timeval *tv = CMSG_FIND_AND_COPY_DATA(&msg, SOL_SOCKET, SCM_TIMESTAMP, struct timeval);
- if (tv)
- triple_timestamp_from_realtime(&t, timeval_load(tv));
-
log_dhcp_client(client, "Received message from UDP socket, processing.");
- r = client_handle_message(client, message, len, &t);
+ r = client_handle_message(client, message, len, TRIPLE_TIMESTAMP_FROM_CMSG(&msg));
if (r < 0)
client_stop(client, r);
.msg_controllen = sizeof(control),
};
bool checksum = true;
- triple_timestamp t = {};
ssize_t buflen, len;
int r;
return 0;
}
- struct tpacket_auxdata *aux = CMSG_FIND_AND_COPY_DATA(&msg, SOL_PACKET, PACKET_AUXDATA, struct tpacket_auxdata);
+ struct tpacket_auxdata *aux = CMSG_FIND_DATA(&msg, SOL_PACKET, PACKET_AUXDATA, struct tpacket_auxdata);
if (aux)
checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
- struct timeval *tv = CMSG_FIND_AND_COPY_DATA(&msg, SOL_SOCKET, SCM_TIMESTAMP, struct timeval);
- if (tv)
- triple_timestamp_from_realtime(&t, timeval_load(tv));
-
if (dhcp_packet_verify_headers(packet, len, checksum, client->port) < 0)
return 0;
len -= DHCP_IP_UDP_SIZE;
log_dhcp_client(client, "Received message from RAW socket, processing.");
- r = client_handle_message(client, &packet->dhcp, len, &t);
+ r = client_handle_message(client, &packet->dhcp, len, TRIPLE_TIMESTAMP_FROM_CMSG(&msg));
if (r < 0)
client_stop(client, r);
.msg_controllen = sizeof(control),
};
ssize_t datagram_size, len;
- struct cmsghdr *cmsg;
- triple_timestamp t = {};
int r;
datagram_size = next_datagram_size_fd(fd);
return 0;
/* TODO figure out if this can be done as a filter on the socket, like for IPv6 */
- CMSG_FOREACH(cmsg, &msg)
- if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
- struct in_pktinfo *info = CMSG_TYPED_DATA(cmsg, struct in_pktinfo);
- if (info->ipi_ifindex != server->ifindex)
- return 0;
- } else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP) {
- struct timeval *tv = CMSG_TYPED_DATA(cmsg, struct timeval);
- triple_timestamp_from_realtime(&t, timeval_load(tv));
- }
+ struct in_pktinfo *info = CMSG_FIND_DATA(&msg, IPPROTO_IP, IP_PKTINFO, struct in_pktinfo);
+ if (info && info->ipi_ifindex != server->ifindex)
+ return 0;
if (sd_dhcp_server_is_in_relay_mode(server)) {
r = dhcp_server_relay_message(server, message, len - sizeof(DHCPMessage), buflen);
if (r < 0)
log_dhcp_server_errno(server, r, "Couldn't relay message, ignoring: %m");
} else {
- r = dhcp_server_handle_message(server, message, (size_t) len, &t);
+ r = dhcp_server_handle_message(server, message, (size_t) len, TRIPLE_TIMESTAMP_FROM_CMSG(&msg));
if (r < 0)
log_dhcp_server_errno(server, r, "Couldn't process incoming message, ignoring: %m");
}
.msg_control = &control,
.msg_controllen = sizeof(control),
};
- triple_timestamp t = {};
+ triple_timestamp t;
_cleanup_free_ DHCP6Message *message = NULL;
struct in6_addr *server_address = NULL;
ssize_t buflen, len;
server_address = &sa.in6.sin6_addr;
}
- struct timeval *tv = CMSG_FIND_AND_COPY_DATA(&msg, SOL_SOCKET, SCM_TIMESTAMP, struct timeval);
- if (tv)
- triple_timestamp_from_realtime(&t, timeval_load(tv));
+ triple_timestamp_from_cmsg(&t, &msg);
if (client->transaction_id != (message->transaction_id & htobe32(0x00ffffff)))
return 0;