]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/icmp6-packet.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <netinet/icmp6.h>
5 #include "icmp6-packet.h"
6 #include "icmp6-util.h"
7 #include "in-addr-util.h"
8 #include "iovec-util.h"
9 #include "network-common.h"
10 #include "socket-util.h"
12 DEFINE_TRIVIAL_REF_UNREF_FUNC(ICMP6Packet
, icmp6_packet
, mfree
);
14 static ICMP6Packet
* icmp6_packet_new(size_t size
) {
17 if (size
> SIZE_MAX
- offsetof(ICMP6Packet
, raw_packet
))
20 p
= malloc0(offsetof(ICMP6Packet
, raw_packet
) + size
);
30 int icmp6_packet_get_sender_address(ICMP6Packet
*p
, struct in6_addr
*ret
) {
33 if (in6_addr_is_null(&p
->sender_address
))
37 *ret
= p
->sender_address
;
41 int icmp6_packet_get_timestamp(ICMP6Packet
*p
, clockid_t clock
, usec_t
*ret
) {
45 if (!TRIPLE_TIMESTAMP_HAS_CLOCK(clock
) || !clock_supported(clock
))
48 if (!triple_timestamp_is_set(&p
->timestamp
))
51 *ret
= triple_timestamp_by_clock(&p
->timestamp
, clock
);
55 const struct icmp6_hdr
* icmp6_packet_get_header(ICMP6Packet
*p
) {
58 if (p
->raw_size
< sizeof(struct icmp6_hdr
))
61 return (const struct icmp6_hdr
*) p
->raw_packet
;
64 int icmp6_packet_get_type(ICMP6Packet
*p
) {
65 const struct icmp6_hdr
*hdr
= icmp6_packet_get_header(p
);
69 return hdr
->icmp6_type
;
72 static int icmp6_packet_verify(ICMP6Packet
*p
) {
73 const struct icmp6_hdr
*hdr
= icmp6_packet_get_header(p
);
77 if (hdr
->icmp6_code
!= 0)
83 int icmp6_packet_receive(int fd
, ICMP6Packet
**ret
) {
84 _cleanup_(icmp6_packet_unrefp
) ICMP6Packet
*p
= NULL
;
91 len
= next_datagram_size_fd(fd
);
95 p
= icmp6_packet_new(len
);
99 r
= icmp6_receive(fd
, p
->raw_packet
, p
->raw_size
, &p
->sender_address
, &p
->timestamp
);
103 return log_debug_errno(r
, "ICMPv6: Received a packet from neither link-local nor null address.");
106 return log_debug_errno(r
, "ICMPv6: Received a packet with an invalid hop limit.");
109 return log_debug_errno(r
, "ICMPv6: Received a packet with an invalid source address.");
112 return log_debug_errno(r
, "ICMPv6: Unexpected error while receiving a packet: %m");
115 r
= icmp6_packet_verify(p
);