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_parsers); 24 ATF_TC_HEAD(snl_verify_parsers, tc) 25 { 26 atf_tc_set_md_var(tc, "descr", "Tests snl(3) parsers are correct"); 27 } 28 29 ATF_TC_BODY(snl_verify_parsers, tc) 30 { 31 SNL_VERIFY_PARSERS(snl_all_route_parsers); 32 33 } 34 35 ATF_TC(snl_list_ifaces); 36 ATF_TC_HEAD(snl_list_ifaces, tc) 37 { 38 atf_tc_set_md_var(tc, "descr", "Tests snl(3) listing interfaces"); 39 } 40 41 struct nl_parsed_link { 42 uint32_t ifi_index; 43 uint32_t ifla_mtu; 44 char *ifla_ifname; 45 }; 46 47 #define _IN(_field) offsetof(struct ifinfomsg, _field) 48 #define _OUT(_field) offsetof(struct nl_parsed_link, _field) 49 static struct snl_attr_parser ap_link[] = { 50 { .type = IFLA_IFNAME, .off = _OUT(ifla_ifname), .cb = snl_attr_get_string }, 51 { .type = IFLA_MTU, .off = _OUT(ifla_mtu), .cb = snl_attr_get_uint32 }, 52 }; 53 static struct snl_field_parser fp_link[] = { 54 {.off_in = _IN(ifi_index), .off_out = _OUT(ifi_index), .cb = snl_field_get_uint32 }, 55 }; 56 #undef _IN 57 #undef _OUT 58 SNL_DECLARE_PARSER(link_parser, struct ifinfomsg, fp_link, ap_link); 59 60 61 ATF_TC_BODY(snl_list_ifaces, tc) 62 { 63 struct snl_state ss; 64 65 require_netlink(); 66 67 if (!snl_init(&ss, NETLINK_ROUTE)) 68 atf_tc_fail("snl_init() failed"); 69 70 struct { 71 struct nlmsghdr hdr; 72 struct ifinfomsg ifmsg; 73 } msg = { 74 .hdr.nlmsg_type = RTM_GETLINK, 75 .hdr.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST, 76 .hdr.nlmsg_seq = snl_get_seq(&ss), 77 }; 78 msg.hdr.nlmsg_len = sizeof(msg); 79 80 if (!snl_send(&ss, &msg, sizeof(msg))) { 81 snl_free(&ss); 82 atf_tc_fail("snl_send() failed"); 83 } 84 85 struct nlmsghdr *hdr; 86 int count = 0; 87 while ((hdr = snl_read_message(&ss)) != NULL && hdr->nlmsg_type != NLMSG_DONE) { 88 if (hdr->nlmsg_seq != msg.hdr.nlmsg_seq) 89 continue; 90 91 struct nl_parsed_link link = {}; 92 if (!snl_parse_nlmsg(&ss, hdr, &link_parser, &link)) 93 continue; 94 count++; 95 } 96 ATF_REQUIRE_MSG(count > 0, "Empty interface list"); 97 } 98 99 ATF_TP_ADD_TCS(tp) 100 { 101 ATF_TP_ADD_TC(tp, snl_list_ifaces); 102 ATF_TP_ADD_TC(tp, snl_verify_parsers); 103 104 return (atf_no_error()); 105 } 106