1 #include "rtnetlink.hpp" 2 3 #include <linux/netlink.h> 4 #include <linux/rtnetlink.h> 5 6 #include <stdplus/raw.hpp> 7 8 #include <gtest/gtest.h> 9 10 namespace phosphor::network::netlink 11 { 12 13 TEST(AddrFromRtm, MissingAddr) 14 { 15 struct 16 { 17 alignas(NLMSG_ALIGNTO) ifaddrmsg ifa = {}; 18 } msg; 19 EXPECT_THROW(addrFromRtm(stdplus::raw::asView<char>(msg)), 20 std::runtime_error); 21 } 22 23 TEST(AddrFromRtm, Regular) 24 { 25 struct 26 { 27 alignas(NLMSG_ALIGNTO) ifaddrmsg ifa; 28 alignas(NLMSG_ALIGNTO) rtattr addr_hdr; 29 alignas(NLMSG_ALIGNTO) uint8_t addr[4] = {192, 168, 1, 20}; 30 } msg; 31 msg.ifa.ifa_family = AF_INET; 32 msg.ifa.ifa_prefixlen = 28; 33 msg.ifa.ifa_flags = 4; 34 msg.ifa.ifa_scope = 3; 35 msg.ifa.ifa_index = 10; 36 msg.addr_hdr.rta_type = IFA_ADDRESS; 37 msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr)); 38 39 auto ret = addrFromRtm(stdplus::raw::asView<char>(msg)); 40 EXPECT_EQ(msg.ifa.ifa_flags, ret.flags); 41 EXPECT_EQ(msg.ifa.ifa_scope, ret.scope); 42 EXPECT_EQ(msg.ifa.ifa_index, ret.ifidx); 43 EXPECT_EQ((IfAddr{in_addr{hton(0xc0a80114)}, 28}), ret.ifaddr); 44 } 45 46 TEST(AddrFromRtm, ExtraFlags) 47 { 48 struct 49 { 50 alignas(NLMSG_ALIGNTO) ifaddrmsg ifa = {}; 51 alignas(NLMSG_ALIGNTO) rtattr flags_hdr; 52 alignas(NLMSG_ALIGNTO) uint32_t flags = 0xff00ff00; 53 alignas(NLMSG_ALIGNTO) rtattr addr_hdr; 54 alignas(NLMSG_ALIGNTO) uint8_t addr[16] = {}; 55 } msg; 56 msg.ifa.ifa_family = AF_INET6; 57 msg.flags_hdr.rta_type = IFA_FLAGS; 58 msg.flags_hdr.rta_len = RTA_LENGTH(sizeof(msg.flags)); 59 msg.addr_hdr.rta_type = IFA_ADDRESS; 60 msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr)); 61 62 auto ret = addrFromRtm(stdplus::raw::asView<char>(msg)); 63 EXPECT_EQ(0xff00ff00, ret.flags); 64 } 65 66 TEST(NeighFromRtm, MissingAddr) 67 { 68 struct 69 { 70 alignas(NLMSG_ALIGNTO) ndmsg ndm = {}; 71 } msg; 72 EXPECT_THROW(neighFromRtm(stdplus::raw::asView<char>(msg)), 73 std::runtime_error); 74 } 75 76 TEST(NeighFromRtm, NoMac) 77 { 78 struct 79 { 80 alignas(NLMSG_ALIGNTO) ndmsg ndm; 81 alignas(NLMSG_ALIGNTO) rtattr addr_hdr; 82 alignas(NLMSG_ALIGNTO) uint8_t addr[4] = {192, 168, 1, 20}; 83 } msg; 84 msg.ndm.ndm_family = AF_INET; 85 msg.ndm.ndm_state = 4; 86 msg.addr_hdr.rta_type = NDA_DST; 87 msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr)); 88 89 auto ret = neighFromRtm(stdplus::raw::asView<char>(msg)); 90 EXPECT_EQ(msg.ndm.ndm_state, ret.state); 91 EXPECT_EQ((in_addr{hton(0xc0a80114)}), ret.addr); 92 EXPECT_FALSE(ret.mac); 93 } 94 95 TEST(NeighFromRtm, Full) 96 { 97 struct 98 { 99 alignas(NLMSG_ALIGNTO) ndmsg ndm; 100 alignas(NLMSG_ALIGNTO) rtattr addr_hdr; 101 alignas(NLMSG_ALIGNTO) uint8_t addr[4] = {192, 168, 1, 20}; 102 alignas(NLMSG_ALIGNTO) rtattr mac_hdr; 103 alignas(NLMSG_ALIGNTO) uint8_t mac[6] = {1, 2, 3, 4, 5, 6}; 104 } msg; 105 msg.ndm.ndm_family = AF_INET; 106 msg.addr_hdr.rta_type = NDA_DST; 107 msg.addr_hdr.rta_len = RTA_LENGTH(sizeof(msg.addr)); 108 msg.mac_hdr.rta_type = NDA_LLADDR; 109 msg.mac_hdr.rta_len = RTA_LENGTH(sizeof(msg.mac)); 110 111 auto ret = neighFromRtm(stdplus::raw::asView<char>(msg)); 112 EXPECT_EQ((in_addr{hton(0xc0a80114)}), ret.addr); 113 EXPECT_EQ((ether_addr{1, 2, 3, 4, 5, 6}), ret.mac); 114 } 115 116 } // namespace phosphor::network::netlink 117