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 #include "netlink/netlink_snl_route_parsers.h" 13 14 #include <atf-c.h> 15 16 static void 17 require_netlink(void) 18 { 19 if (modfind("netlink") == -1) 20 atf_tc_skip("netlink module not loaded"); 21 } 22 23 ATF_TC(snl_verify_core_parsers); 24 ATF_TC_HEAD(snl_verify_core_parsers, tc) 25 { 26 atf_tc_set_md_var(tc, "descr", "Tests snl(3) core nlmsg parsers are correct"); 27 } 28 29 ATF_TC_BODY(snl_verify_core_parsers, tc) 30 { 31 SNL_VERIFY_PARSERS(snl_all_core_parsers); 32 33 } 34 35 ATF_TC(snl_verify_route_parsers); 36 ATF_TC_HEAD(snl_verify_route_parsers, tc) 37 { 38 atf_tc_set_md_var(tc, "descr", "Tests snl(3) route parsers are correct"); 39 } 40 41 ATF_TC_BODY(snl_verify_route_parsers, tc) 42 { 43 SNL_VERIFY_PARSERS(snl_all_route_parsers); 44 45 } 46 47 ATF_TC(snl_list_ifaces); 48 ATF_TC_HEAD(snl_list_ifaces, tc) 49 { 50 atf_tc_set_md_var(tc, "descr", "Tests snl(3) listing interfaces"); 51 } 52 53 struct nl_parsed_link { 54 uint32_t ifi_index; 55 uint32_t ifla_mtu; 56 char *ifla_ifname; 57 }; 58 59 #define _IN(_field) offsetof(struct ifinfomsg, _field) 60 #define _OUT(_field) offsetof(struct nl_parsed_link, _field) 61 static struct snl_attr_parser ap_link[] = { 62 { .type = IFLA_IFNAME, .off = _OUT(ifla_ifname), .cb = snl_attr_get_string }, 63 { .type = IFLA_MTU, .off = _OUT(ifla_mtu), .cb = snl_attr_get_uint32 }, 64 }; 65 static struct snl_field_parser fp_link[] = { 66 {.off_in = _IN(ifi_index), .off_out = _OUT(ifi_index), .cb = snl_field_get_uint32 }, 67 }; 68 #undef _IN 69 #undef _OUT 70 SNL_DECLARE_PARSER(link_parser, struct ifinfomsg, fp_link, ap_link); 71 72 73 ATF_TC_BODY(snl_list_ifaces, tc) 74 { 75 struct snl_state ss; 76 struct snl_writer nw; 77 78 require_netlink(); 79 80 if (!snl_init(&ss, NETLINK_ROUTE)) 81 atf_tc_fail("snl_init() failed"); 82 83 snl_init_writer(&ss, &nw); 84 85 struct nlmsghdr *hdr = snl_create_msg_request(&nw, RTM_GETLINK); 86 ATF_CHECK(hdr != NULL); 87 ATF_CHECK(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL); 88 ATF_CHECK(snl_finalize_msg(&nw) != NULL); 89 uint32_t seq_id = hdr->nlmsg_seq; 90 91 ATF_CHECK(snl_send_message(&ss, hdr)); 92 93 struct snl_errmsg_data e = {}; 94 int count = 0; 95 96 while ((hdr = snl_read_reply_multi(&ss, seq_id, &e)) != NULL) { 97 count++; 98 } 99 ATF_REQUIRE(e.error == 0); 100 101 ATF_REQUIRE_MSG(count > 0, "Empty interface list"); 102 } 103 104 ATF_TP_ADD_TCS(tp) 105 { 106 ATF_TP_ADD_TC(tp, snl_verify_core_parsers); 107 ATF_TP_ADD_TC(tp, snl_verify_route_parsers); 108 ATF_TP_ADD_TC(tp, snl_list_ifaces); 109 110 return (atf_no_error()); 111 } 112