1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 #include <sys/param.h> 6 #include <sys/module.h> 7 8 #include <netlink/netlink.h> 9 #include <netlink/netlink_route.h> 10 #include "netlink/netlink_snl.h" 11 #include "netlink/netlink_snl_route.h" 12 13 #include <atf-c.h> 14 15 static void 16 require_netlink(void) 17 { 18 if (modfind("netlink") == -1) 19 atf_tc_skip("netlink module not loaded"); 20 } 21 22 23 ATF_TC(snl_list_ifaces); 24 ATF_TC_HEAD(snl_list_ifaces, tc) 25 { 26 atf_tc_set_md_var(tc, "descr", "Tests snl(3) listing interfaces"); 27 } 28 29 struct nl_parsed_link { 30 uint32_t ifi_index; 31 uint32_t ifla_mtu; 32 char *ifla_ifname; 33 }; 34 35 #define _IN(_field) offsetof(struct ifinfomsg, _field) 36 #define _OUT(_field) offsetof(struct nl_parsed_link, _field) 37 static struct snl_attr_parser ap_link[] = { 38 { .type = IFLA_IFNAME, .off = _OUT(ifla_ifname), .cb = snl_attr_get_string }, 39 { .type = IFLA_MTU, .off = _OUT(ifla_mtu), .cb = snl_attr_get_uint32 }, 40 }; 41 static struct snl_field_parser fp_link[] = { 42 {.off_in = _IN(ifi_index), .off_out = _OUT(ifi_index), .cb = snl_field_get_uint32 }, 43 }; 44 #undef _IN 45 #undef _OUT 46 SNL_DECLARE_PARSER(link_parser, struct ifinfomsg, fp_link, ap_link); 47 48 49 ATF_TC_BODY(snl_list_ifaces, tc) 50 { 51 struct snl_state ss; 52 53 require_netlink(); 54 55 if (!snl_init(&ss, NETLINK_ROUTE)) 56 atf_tc_fail("snl_init() failed"); 57 58 struct { 59 struct nlmsghdr hdr; 60 struct ifinfomsg ifmsg; 61 } msg = { 62 .hdr.nlmsg_type = RTM_GETLINK, 63 .hdr.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST, 64 .hdr.nlmsg_seq = snl_get_seq(&ss), 65 }; 66 msg.hdr.nlmsg_len = sizeof(msg); 67 68 if (!snl_send(&ss, &msg, sizeof(msg))) { 69 snl_free(&ss); 70 atf_tc_fail("snl_send() failed"); 71 } 72 73 struct nlmsghdr *hdr; 74 int count = 0; 75 while ((hdr = snl_read_message(&ss)) != NULL && hdr->nlmsg_type != NLMSG_DONE) { 76 if (hdr->nlmsg_seq != msg.hdr.nlmsg_seq) 77 continue; 78 79 struct nl_parsed_link link = {}; 80 if (!snl_parse_nlmsg(&ss, hdr, &link_parser, &link)) 81 continue; 82 count++; 83 } 84 ATF_REQUIRE_MSG(count > 0, "Empty interface list"); 85 } 86 87 ATF_TP_ADD_TCS(tp) 88 { 89 ATF_TP_ADD_TC(tp, snl_list_ifaces); 90 91 return (atf_no_error()); 92 } 93