sd-radv: introduce sd_ndisc_router_solicit

It is not used in this stage, but will be used later in sd-radv.
This commit is contained in:
Yu Watanabe
2024-04-16 09:59:48 +09:00
parent e5689f04dd
commit 8c1f24fb95
6 changed files with 145 additions and 1 deletions
+1
View File
@@ -31,6 +31,7 @@ sources = files(
'sd-ndisc-neighbor.c',
'sd-ndisc-redirect.c',
'sd-ndisc-router.c',
'sd-ndisc-router-solicit.c',
'sd-radv.c',
)
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "sd-radv.h"
#include "icmp6-packet.h"
#include "set.h"
struct sd_ndisc_router_solicit {
unsigned n_ref;
ICMP6Packet *packet;
Set *options;
};
sd_ndisc_router_solicit* ndisc_router_solicit_new(ICMP6Packet *packet);
int ndisc_router_solicit_parse(sd_radv *ra, sd_ndisc_router_solicit *rs);
@@ -0,0 +1,83 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <netinet/icmp6.h>
#include "sd-radv.h"
#include "alloc-util.h"
#include "in-addr-util.h"
#include "ndisc-option.h"
#include "ndisc-router-solicit-internal.h"
#include "radv-internal.h"
static sd_ndisc_router_solicit* ndisc_router_solicit_free(sd_ndisc_router_solicit *rs) {
if (!rs)
return NULL;
icmp6_packet_unref(rs->packet);
set_free(rs->options);
return mfree(rs);
}
DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_ndisc_router_solicit, sd_ndisc_router_solicit, ndisc_router_solicit_free);
sd_ndisc_router_solicit* ndisc_router_solicit_new(ICMP6Packet *packet) {
sd_ndisc_router_solicit *rs;
assert(packet);
rs = new(sd_ndisc_router_solicit, 1);
if (!rs)
return NULL;
*rs = (sd_ndisc_router_solicit) {
.n_ref = 1,
.packet = icmp6_packet_ref(packet),
};
return rs;
}
int ndisc_router_solicit_parse(sd_radv *ra, sd_ndisc_router_solicit *rs) {
int r;
assert(rs);
assert(rs->packet);
if (rs->packet->raw_size < sizeof(struct nd_router_solicit))
return log_radv_errno(ra, SYNTHETIC_ERRNO(EBADMSG),
"Too small to be a router solicit, ignoring.");
const struct nd_router_solicit *a = (const struct nd_router_solicit*) rs->packet->raw_packet;
assert(a);
assert(a->nd_rs_type == ND_ROUTER_SOLICIT);
assert(a->nd_rs_code == 0);
r = ndisc_parse_options(rs->packet, &rs->options);
if (r < 0)
return log_radv_errno(ra, r, "Failed to parse NDisc options in router solicit, ignoring datagram: %m");
/* RFC 4861 section 4.1.
* Source link-layer address:
* The link-layer address of the sender, if known. MUST NOT be included if the Source
* Address is the unspecified address. Otherwise, it SHOULD be included on link
* layers that have addresses. */
if (ndisc_option_get_mac(rs->options, SD_NDISC_OPTION_SOURCE_LL_ADDRESS, NULL) >= 0&&
sd_ndisc_router_solicit_get_sender_address(rs, NULL) == -ENODATA)
return log_radv_errno(ra, SYNTHETIC_ERRNO(EBADMSG),
"Router Solicitation message from null address unexpectedly contains source link-layer address option, ignoring datagaram.");
return 0;
}
int sd_ndisc_router_solicit_get_sender_address(sd_ndisc_router_solicit *rs, struct in6_addr *ret) {
assert_return(rs, -EINVAL);
return icmp6_packet_get_sender_address(rs->packet, ret);
}
int sd_ndisc_router_solicit_get_sender_mac(sd_ndisc_router_solicit *rs, struct ether_addr *ret) {
assert_return(rs, -EINVAL);
return ndisc_option_get_mac(rs->options, SD_NDISC_OPTION_SOURCE_LL_ADDRESS, ret);
}
+1
View File
@@ -42,6 +42,7 @@ _not_installed_headers = [
'sd-ndisc-protocol.h',
'sd-ndisc-redirect.h',
'sd-ndisc-router.h',
'sd-ndisc-router-solicit.h',
'sd-netlink.h',
'sd-network.h',
'sd-radv.h',
+40
View File
@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#ifndef foosdndiscroutersolicitfoo
#define foosdndiscroutersolicitfoo
/***
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <https://www.gnu.org/licenses/>.
***/
#include <inttypes.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include "_sd-common.h"
_SD_BEGIN_DECLARATIONS;
typedef struct sd_ndisc_router_solicit sd_ndisc_router_solicit;
sd_ndisc_router_solicit *sd_ndisc_router_solicit_ref(sd_ndisc_router_solicit *rs);
sd_ndisc_router_solicit *sd_ndisc_router_solicit_unref(sd_ndisc_router_solicit *rs);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc_router_solicit, sd_ndisc_router_solicit_unref);
int sd_ndisc_router_solicit_get_sender_address(sd_ndisc_router_solicit *rs, struct in6_addr *ret);
int sd_ndisc_router_solicit_get_sender_mac(sd_ndisc_router_solicit *rs, struct ether_addr *ret);
_SD_END_DECLARATIONS;
#endif
+2 -1
View File
@@ -26,7 +26,8 @@
#include "_sd-common.h"
#include "sd-event.h"
#include "sd-ndisc.h"
#include "sd-ndisc-protocol.h"
#include "sd-ndisc-router-solicit.h"
_SD_BEGIN_DECLARATIONS;