#include "alloc-util.h"
#include "ndisc-internal.h"
#include "ndisc-router-internal.h"
+#include "string-table.h"
static sd_ndisc_router* ndisc_router_free(sd_ndisc_router *rt) {
if (!rt)
return 0;
}
+int ndisc_router_flags_to_string(uint64_t flags, char **ret) {
+ _cleanup_free_ char *s = NULL;
+
+ assert(ret);
+
+ if (FLAGS_SET(flags, ND_RA_FLAG_MANAGED) &&
+ !strextend_with_separator(&s, ", ", "managed"))
+ return -ENOMEM;
+
+ if (FLAGS_SET(flags, ND_RA_FLAG_OTHER) &&
+ !strextend_with_separator(&s, ", ", "other"))
+ return -ENOMEM;
+
+ if (FLAGS_SET(flags, ND_RA_FLAG_HOME_AGENT) &&
+ !strextend_with_separator(&s, ", ", "home-agent"))
+ return -ENOMEM;
+
+ *ret = TAKE_PTR(s);
+ return 0;
+}
+
int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint64_t *ret) {
assert_return(rt, -EINVAL);
return 0;
}
+static const char* const ndisc_router_preference_table[] = {
+ [SD_NDISC_PREFERENCE_LOW] = "low",
+ [SD_NDISC_PREFERENCE_MEDIUM] = "medium",
+ [SD_NDISC_PREFERENCE_HIGH] = "high",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_TO_STRING(ndisc_router_preference, int);
+
int sd_ndisc_router_get_sender_mac(sd_ndisc_router *rt, struct ether_addr *ret) {
assert_return(rt, -EINVAL);
(void) event_source_disable(nd->timeout_event_source);
(void) event_source_disable(nd->timeout_no_ra);
- log_ndisc(nd, "Received Router Advertisement: flags %s preference %s lifetime %s",
- rt->flags & ND_RA_FLAG_MANAGED ? "MANAGED" : rt->flags & ND_RA_FLAG_OTHER ? "OTHER" : "none",
- rt->preference == SD_NDISC_PREFERENCE_HIGH ? "high" : rt->preference == SD_NDISC_PREFERENCE_LOW ? "low" : "medium",
- FORMAT_TIMESPAN(rt->lifetime_usec, USEC_PER_SEC));
+ if (DEBUG_LOGGING) {
+ _cleanup_free_ char *s = NULL;
+ struct in6_addr a;
+ uint64_t flags;
+ uint8_t pref;
+ usec_t lifetime;
+
+ r = sd_ndisc_router_get_sender_address(rt, &a);
+ if (r < 0)
+ return r;
+
+ r = sd_ndisc_router_get_flags(rt, &flags);
+ if (r < 0)
+ return r;
+
+ r = ndisc_router_flags_to_string(flags, &s);
+ if (r < 0)
+ return r;
+
+ r = sd_ndisc_router_get_preference(rt, &pref);
+ if (r < 0)
+ return r;
+
+ r = sd_ndisc_router_get_lifetime(rt, &lifetime);
+ if (r < 0)
+ return r;
+
+ log_ndisc(nd, "Received Router Advertisement from %s: flags=0x%0*"PRIx64"%s%s%s, preference=%s, lifetime=%s",
+ IN6_ADDR_TO_STRING(&a),
+ flags & UINT64_C(0x00ffffffffffff00) ? 14 : 2, flags, /* suppress too many zeros if no extension */
+ s ? " (" : "", s, s ? ")" : "",
+ ndisc_router_preference_to_string(pref),
+ FORMAT_TIMESPAN(lifetime, USEC_PER_SEC));
+ }
ndisc_callback(nd, SD_NDISC_EVENT_ROUTER, rt);
return 0;
static int ndisc_handle_neighbor(sd_ndisc *nd, ICMP6Packet *packet) {
_cleanup_(sd_ndisc_neighbor_unrefp) sd_ndisc_neighbor *na = NULL;
- struct in6_addr a;
int r;
assert(nd);
if (r < 0)
return r;
- r = sd_ndisc_neighbor_get_sender_address(na, &a);
- if (r < 0)
- return r;
+ if (DEBUG_LOGGING) {
+ struct in6_addr a;
- log_ndisc(nd, "Received Neighbor Advertisement from %s: Router=%s, Solicited=%s, Override=%s",
- IN6_ADDR_TO_STRING(&a),
- yes_no(sd_ndisc_neighbor_is_router(na) > 0),
- yes_no(sd_ndisc_neighbor_is_solicited(na) > 0),
- yes_no(sd_ndisc_neighbor_is_override(na) > 0));
+ r = sd_ndisc_neighbor_get_sender_address(na, &a);
+ if (r < 0)
+ return r;
+
+ log_ndisc(nd, "Received Neighbor Advertisement from %s: Router=%s, Solicited=%s, Override=%s",
+ IN6_ADDR_TO_STRING(&a),
+ yes_no(sd_ndisc_neighbor_is_router(na) > 0),
+ yes_no(sd_ndisc_neighbor_is_solicited(na) > 0),
+ yes_no(sd_ndisc_neighbor_is_override(na) > 0));
+ }
ndisc_callback(nd, SD_NDISC_EVENT_NEIGHBOR, na);
return 0;
static int ndisc_handle_redirect(sd_ndisc *nd, ICMP6Packet *packet) {
_cleanup_(sd_ndisc_redirect_unrefp) sd_ndisc_redirect *rd = NULL;
- struct in6_addr a;
int r;
assert(nd);
if (r < 0)
return r;
- r = sd_ndisc_redirect_get_sender_address(rd, &a);
- if (r < 0)
- return r;
+ if (DEBUG_LOGGING) {
+ struct in6_addr sender, target, dest;
- log_ndisc(nd, "Received Redirect message from %s: Target=%s, Destination=%s",
- IN6_ADDR_TO_STRING(&a),
- IN6_ADDR_TO_STRING(&rd->target_address),
- IN6_ADDR_TO_STRING(&rd->destination_address));
+ r = sd_ndisc_redirect_get_sender_address(rd, &sender);
+ if (r < 0)
+ return r;
+
+ r = sd_ndisc_redirect_get_target_address(rd, &target);
+ if (r < 0)
+ return r;
+
+ r = sd_ndisc_redirect_get_destination_address(rd, &dest);
+ if (r < 0)
+ return r;
+
+ log_ndisc(nd, "Received Redirect message from %s: Target=%s, Destination=%s",
+ IN6_ADDR_TO_STRING(&sender),
+ IN6_ADDR_TO_STRING(&target),
+ IN6_ADDR_TO_STRING(&dest));
+ }
ndisc_callback(nd, SD_NDISC_EVENT_REDIRECT, rd);
return 0;