static int test_acd(const char *ifname, const char *address) { _cleanup_(sd_event_unrefp) sd_event *e = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL; union in_addr_union pa; struct ether_addr ha; int ifindex; assert_se(in_addr_from_string(AF_INET, address, &pa) >= 0); assert_se(sd_event_new(&e) >= 0); assert_se(sd_netlink_open(&rtnl) >= 0); assert_se(sd_netlink_attach_event(rtnl, e, 0) >= 0); assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, 0) >= 0); assert_se(sd_netlink_message_append_string(m, IFLA_IFNAME, ifname) >= 0); assert_se(sd_netlink_call(rtnl, m, 0, &reply) >= 0); assert_se(sd_rtnl_message_link_get_ifindex(reply, &ifindex) >= 0); assert_se(sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS, &ha) >= 0); client_run(ifindex, &pa.in, &ha, e); return EXIT_SUCCESS; }
static void test_link_configure(sd_netlink *rtnl, int ifindex) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; const char *mac = "98:fe:94:3f:c6:18", *name = "test"; char buffer[ETHER_ADDR_TO_STRING_MAX]; uint32_t mtu = 1450, mtu_out; const char *name_out; struct ether_addr mac_out; /* we'd really like to test NEWLINK, but let's not mess with the running kernel */ assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, ifindex) >= 0); assert_se(sd_netlink_message_append_string(message, IFLA_IFNAME, name) >= 0); assert_se(sd_netlink_message_append_ether_addr(message, IFLA_ADDRESS, ether_aton(mac)) >= 0); assert_se(sd_netlink_message_append_u32(message, IFLA_MTU, mtu) >= 0); assert_se(sd_netlink_call(rtnl, message, 0, NULL) == 1); assert_se(sd_netlink_message_rewind(message) >= 0); assert_se(sd_netlink_message_read_string(message, IFLA_IFNAME, &name_out) >= 0); assert_se(streq(name, name_out)); assert_se(sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &mac_out) >= 0); assert_se(streq(mac, ether_addr_to_string(&mac_out, buffer))); assert_se(sd_netlink_message_read_u32(message, IFLA_MTU, &mtu_out) >= 0); assert_se(mtu == mtu_out); }
static void test_link_get(sd_netlink *rtnl, int ifindex) { sd_netlink_message *m; sd_netlink_message *r; uint32_t mtu = 1500; const char *str_data; uint8_t u8_data; uint32_t u32_data; struct ether_addr eth_data; assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); assert_se(m); /* u8 test cases */ assert_se(sd_netlink_message_append_u8(m, IFLA_CARRIER, 0) >= 0); assert_se(sd_netlink_message_append_u8(m, IFLA_OPERSTATE, 0) >= 0); assert_se(sd_netlink_message_append_u8(m, IFLA_LINKMODE, 0) >= 0); /* u32 test cases */ assert_se(sd_netlink_message_append_u32(m, IFLA_MTU, mtu) >= 0); assert_se(sd_netlink_message_append_u32(m, IFLA_GROUP, 0) >= 0); assert_se(sd_netlink_message_append_u32(m, IFLA_TXQLEN, 0) >= 0); assert_se(sd_netlink_message_append_u32(m, IFLA_NUM_TX_QUEUES, 0) >= 0); assert_se(sd_netlink_message_append_u32(m, IFLA_NUM_RX_QUEUES, 0) >= 0); assert_se(sd_netlink_call(rtnl, m, -1, &r) == 1); assert_se(sd_netlink_message_read_string(r, IFLA_IFNAME, &str_data) == 0); assert_se(sd_netlink_message_read_u8(r, IFLA_CARRIER, &u8_data) == 0); assert_se(sd_netlink_message_read_u8(r, IFLA_OPERSTATE, &u8_data) == 0); assert_se(sd_netlink_message_read_u8(r, IFLA_LINKMODE, &u8_data) == 0); assert_se(sd_netlink_message_read_u32(r, IFLA_MTU, &u32_data) == 0); assert_se(sd_netlink_message_read_u32(r, IFLA_GROUP, &u32_data) == 0); assert_se(sd_netlink_message_read_u32(r, IFLA_TXQLEN, &u32_data) == 0); assert_se(sd_netlink_message_read_u32(r, IFLA_NUM_TX_QUEUES, &u32_data) == 0); assert_se(sd_netlink_message_read_u32(r, IFLA_NUM_RX_QUEUES, &u32_data) == 0); assert_se(sd_netlink_message_read_ether_addr(r, IFLA_ADDRESS, ð_data) == 0); assert_se((m = sd_netlink_message_unref(m)) == NULL); assert_se((r = sd_netlink_message_unref(r)) == NULL); }
static int get_gateway_description( sd_netlink *rtnl, sd_hwdb *hwdb, int ifindex, int family, union in_addr_union *gateway, char **gateway_description) { _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL; sd_netlink_message *m; int r; assert(rtnl); assert(ifindex >= 0); assert(family == AF_INET || family == AF_INET6); assert(gateway); assert(gateway_description); r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_GETNEIGH, ifindex, family); if (r < 0) return r; r = sd_netlink_message_request_dump(req, true); if (r < 0) return r; r = sd_netlink_call(rtnl, req, 0, &reply); if (r < 0) return r; for (m = reply; m; m = sd_netlink_message_next(m)) { union in_addr_union gw = {}; struct ether_addr mac = {}; uint16_t type; int ifi, fam; r = sd_netlink_message_get_errno(m); if (r < 0) { log_error_errno(r, "got error: %m"); continue; } r = sd_netlink_message_get_type(m, &type); if (r < 0) { log_error_errno(r, "could not get type: %m"); continue; } if (type != RTM_NEWNEIGH) { log_error("type is not RTM_NEWNEIGH"); continue; } r = sd_rtnl_message_neigh_get_family(m, &fam); if (r < 0) { log_error_errno(r, "could not get family: %m"); continue; } if (fam != family) { log_error("family is not correct"); continue; } r = sd_rtnl_message_neigh_get_ifindex(m, &ifi); if (r < 0) { log_error_errno(r, "could not get ifindex: %m"); continue; } if (ifindex > 0 && ifi != ifindex) continue; switch (fam) { case AF_INET: r = sd_netlink_message_read_in_addr(m, NDA_DST, &gw.in); if (r < 0) continue; break; case AF_INET6: r = sd_netlink_message_read_in6_addr(m, NDA_DST, &gw.in6); if (r < 0) continue; break; default: continue; } if (!in_addr_equal(fam, &gw, gateway)) continue; r = sd_netlink_message_read_ether_addr(m, NDA_LLADDR, &mac); if (r < 0) continue; r = ieee_oui(hwdb, &mac, gateway_description); if (r < 0) continue; return 0; } return -ENODATA; }