blob: f5a6147dc2a2631d8fc68d889be0f67a7db0e7b1 [file] [log] [blame]
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -07001#include "ipaddress.hpp"
2#include "util.hpp"
3
4#include <arpa/inet.h>
5#include <linux/netlink.h>
6#include <linux/rtnetlink.h>
7
8#include <cstring>
9#include <stdexcept>
10#include <stdplus/raw.hpp>
11#include <string>
12#include <vector>
13
14#include <gtest/gtest.h>
15
16namespace phosphor
17{
18namespace network
19{
20namespace detail
21{
22
23TEST(ParseAddress, NotAddressType)
24{
25 nlmsghdr hdr{};
26 hdr.nlmsg_type = RTM_NEWLINK;
27 AddressFilter filter;
28
29 std::vector<AddressInfo> addresses;
30 EXPECT_THROW(parseAddress(filter, hdr, "", addresses), std::runtime_error);
31 EXPECT_EQ(0, addresses.size());
32}
33
34TEST(ParseAddress, SmallMsg)
35{
36 nlmsghdr hdr{};
37 hdr.nlmsg_type = RTM_NEWADDR;
38 std::string data = "1";
39 AddressFilter filter;
40
41 std::vector<AddressInfo> addresses;
42 EXPECT_THROW(parseAddress(filter, hdr, data, addresses),
43 std::runtime_error);
44 EXPECT_EQ(0, addresses.size());
45}
46
47TEST(ParseAddress, NoAttrs)
48{
49 nlmsghdr hdr{};
50 hdr.nlmsg_type = RTM_NEWADDR;
51 ifaddrmsg msg{};
52 msg.ifa_family = AF_INET;
53 msg.ifa_prefixlen = 24;
54 msg.ifa_index = 1;
55 msg.ifa_scope = RT_SCOPE_UNIVERSE;
56 std::string data;
57 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
58 AddressFilter filter;
59
60 std::vector<AddressInfo> addresses;
61 EXPECT_THROW(parseAddress(filter, hdr, data, addresses),
62 std::runtime_error);
63 EXPECT_EQ(0, addresses.size());
64}
65
66TEST(ParseAddress, NoAddress)
67{
68 nlmsghdr hdr{};
69 hdr.nlmsg_type = RTM_NEWADDR;
70 ifaddrmsg msg{};
71 msg.ifa_family = AF_INET;
72 msg.ifa_prefixlen = 24;
73 msg.ifa_index = 1;
74 msg.ifa_scope = RT_SCOPE_UNIVERSE;
75 in_addr addr{};
76 rtattr local{};
77 constexpr auto len = RTA_LENGTH(sizeof(addr));
78 local.rta_len = len;
79 local.rta_type = IFA_LOCAL;
80 char localbuf[RTA_ALIGN(len)];
81 std::memset(localbuf, '\0', sizeof(localbuf));
82 std::memcpy(localbuf, &local, sizeof(local));
83 std::memcpy(RTA_DATA(localbuf), &addr, sizeof(addr));
84 std::string data;
85 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
86 data.append(reinterpret_cast<char*>(&localbuf), sizeof(localbuf));
87 AddressFilter filter;
88
89 std::vector<AddressInfo> addresses;
90 EXPECT_THROW(parseAddress(filter, hdr, data, addresses),
91 std::runtime_error);
92 EXPECT_EQ(0, addresses.size());
93}
94
95TEST(ParseAddress, FilterInterface)
96{
97 nlmsghdr hdr{};
98 hdr.nlmsg_type = RTM_NEWADDR;
99 ifaddrmsg msg{};
100 msg.ifa_family = AF_INET;
101 msg.ifa_prefixlen = 24;
102 msg.ifa_index = 2;
103 msg.ifa_scope = RT_SCOPE_UNIVERSE;
104 in_addr addr;
105 ASSERT_EQ(1, inet_pton(msg.ifa_family, "192.168.10.1", &addr));
106 rtattr address{};
107 constexpr auto len = RTA_LENGTH(sizeof(addr));
108 address.rta_len = len;
109 address.rta_type = IFA_ADDRESS;
110 char addressbuf[RTA_ALIGN(len)];
111 std::memset(addressbuf, '\0', sizeof(addressbuf));
112 std::memcpy(addressbuf, &address, sizeof(address));
113 std::memcpy(RTA_DATA(addressbuf), &addr, sizeof(addr));
114 std::string data;
115 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
116 data.append(reinterpret_cast<char*>(&addressbuf), sizeof(addressbuf));
117 AddressFilter filter;
118
119 std::vector<AddressInfo> addresses;
120 filter.interface = 1;
121 parseAddress(filter, hdr, data, addresses);
122 EXPECT_EQ(0, addresses.size());
123 filter.interface = 2;
124 parseAddress(filter, hdr, data, addresses);
125 EXPECT_EQ(1, addresses.size());
126 EXPECT_EQ(msg.ifa_index, addresses[0].interface);
127 EXPECT_EQ(msg.ifa_scope, addresses[0].scope);
128 EXPECT_EQ(msg.ifa_prefixlen, addresses[0].prefix);
129 EXPECT_TRUE(
130 stdplus::raw::equal(addr, std::get<in_addr>(addresses[0].address)));
131}
132
133TEST(ParseNeighbor, FilterScope)
134{
135 nlmsghdr hdr{};
136 hdr.nlmsg_type = RTM_NEWADDR;
137 ifaddrmsg msg{};
138 msg.ifa_family = AF_INET;
139 msg.ifa_prefixlen = 24;
140 msg.ifa_index = 2;
141 msg.ifa_scope = RT_SCOPE_SITE;
142 in_addr addr;
143 ASSERT_EQ(1, inet_pton(msg.ifa_family, "192.168.10.1", &addr));
144 rtattr address{};
145 constexpr auto len = RTA_LENGTH(sizeof(addr));
146 address.rta_len = len;
147 address.rta_type = IFA_ADDRESS;
148 char addressbuf[RTA_ALIGN(len)];
149 std::memset(addressbuf, '\0', sizeof(addressbuf));
150 std::memcpy(addressbuf, &address, sizeof(address));
151 std::memcpy(RTA_DATA(addressbuf), &addr, sizeof(addr));
152 std::string data;
153 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
154 data.append(reinterpret_cast<char*>(&addressbuf), sizeof(addressbuf));
155 AddressFilter filter;
156
157 std::vector<AddressInfo> addresses;
158 filter.scope = RT_SCOPE_UNIVERSE;
159 parseAddress(filter, hdr, data, addresses);
160 EXPECT_EQ(0, addresses.size());
161 filter.scope = RT_SCOPE_SITE;
162 parseAddress(filter, hdr, data, addresses);
163 EXPECT_EQ(1, addresses.size());
164 EXPECT_EQ(msg.ifa_index, addresses[0].interface);
165 EXPECT_EQ(msg.ifa_scope, addresses[0].scope);
166 EXPECT_EQ(msg.ifa_prefixlen, addresses[0].prefix);
167 EXPECT_TRUE(
168 stdplus::raw::equal(addr, std::get<in_addr>(addresses[0].address)));
169}
170
171TEST(ParseNeighbor, NoFilter)
172{
173 nlmsghdr hdr{};
174 hdr.nlmsg_type = RTM_NEWADDR;
175 ifaddrmsg msg{};
176 msg.ifa_family = AF_INET6;
177 msg.ifa_prefixlen = 24;
178 msg.ifa_index = 1;
179 msg.ifa_scope = RT_SCOPE_UNIVERSE;
180 in6_addr addr;
181 ASSERT_EQ(1, inet_pton(msg.ifa_family, "fd00::2", &addr));
182 rtattr address{};
183 constexpr auto len = RTA_LENGTH(sizeof(addr));
184 address.rta_len = len;
185 address.rta_type = IFA_ADDRESS;
186 char addressbuf[RTA_ALIGN(len)];
187 std::memset(addressbuf, '\0', sizeof(addressbuf));
188 std::memcpy(addressbuf, &address, sizeof(address));
189 std::memcpy(RTA_DATA(addressbuf), &addr, sizeof(addr));
190 std::string data;
191 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
192 data.append(reinterpret_cast<char*>(&addressbuf), sizeof(addressbuf));
193 AddressFilter filter;
194
195 std::vector<AddressInfo> addresses;
196 parseAddress(filter, hdr, data, addresses);
197 EXPECT_EQ(1, addresses.size());
198 EXPECT_EQ(msg.ifa_index, addresses[0].interface);
199 EXPECT_EQ(msg.ifa_scope, addresses[0].scope);
200 EXPECT_EQ(msg.ifa_prefixlen, addresses[0].prefix);
201 EXPECT_TRUE(
202 stdplus::raw::equal(addr, std::get<in6_addr>(addresses[0].address)));
203}
204
205} // namespace detail
206} // namespace network
207} // namespace phosphor