blob: 6b14912c38740dd9b8f6805a0af46f843f1e5ffc [file] [log] [blame]
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07001#include "neighbor.hpp"
2#include "util.hpp"
3
4#include <arpa/inet.h>
5#include <linux/netlink.h>
6#include <linux/rtnetlink.h>
7#include <net/ethernet.h>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07008
9#include <cstring>
10#include <stdexcept>
William A. Kennington III12beaad2020-06-13 19:30:41 -070011#include <stdplus/raw.hpp>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070012#include <string>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070013#include <vector>
14
15#include <gtest/gtest.h>
16
17namespace phosphor
18{
19namespace network
20{
21namespace detail
22{
23
24TEST(ParseNeighbor, NotNeighborType)
25{
26 nlmsghdr hdr{};
27 hdr.nlmsg_type = RTM_NEWLINK;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070028 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070029
30 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070031 EXPECT_THROW(parseNeighbor(filter, hdr, "", neighbors), std::runtime_error);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070032 EXPECT_EQ(0, neighbors.size());
33}
34
35TEST(ParseNeighbor, SmallMsg)
36{
37 nlmsghdr hdr{};
38 hdr.nlmsg_type = RTM_NEWNEIGH;
39 std::string data = "1";
William A. Kennington IIId7946a72019-04-19 14:24:09 -070040 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070041
42 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070043 EXPECT_THROW(parseNeighbor(filter, hdr, data, neighbors),
44 std::runtime_error);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070045 EXPECT_EQ(0, neighbors.size());
46}
47
48TEST(ParseNeighbor, NoAttrs)
49{
50 nlmsghdr hdr{};
51 hdr.nlmsg_type = RTM_NEWNEIGH;
52 ndmsg msg{};
William A. Kennington IIId7946a72019-04-19 14:24:09 -070053 msg.ndm_ifindex = 1;
54 msg.ndm_state = NUD_REACHABLE;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070055 std::string data;
56 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
William A. Kennington IIId7946a72019-04-19 14:24:09 -070057 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070058
59 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070060 EXPECT_THROW(parseNeighbor(filter, hdr, data, neighbors),
61 std::runtime_error);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070062 EXPECT_EQ(0, neighbors.size());
63}
64
65TEST(ParseNeighbor, NoAddress)
66{
67 nlmsghdr hdr{};
68 hdr.nlmsg_type = RTM_NEWNEIGH;
69 ndmsg msg{};
William A. Kennington IIId7946a72019-04-19 14:24:09 -070070 msg.ndm_ifindex = 1;
71 msg.ndm_state = NUD_REACHABLE;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070072 ether_addr mac = {{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}};
73 rtattr lladdr{};
74 lladdr.rta_len = RTA_LENGTH(sizeof(mac));
75 lladdr.rta_type = NDA_LLADDR;
76 char lladdrbuf[RTA_ALIGN(lladdr.rta_len)];
77 std::memset(lladdrbuf, '\0', sizeof(lladdrbuf));
78 std::memcpy(lladdrbuf, &lladdr, sizeof(lladdr));
79 std::memcpy(RTA_DATA(lladdrbuf), &mac, sizeof(mac));
80 std::string data;
81 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
82 data.append(reinterpret_cast<char*>(&lladdrbuf), sizeof(lladdrbuf));
William A. Kennington IIId7946a72019-04-19 14:24:09 -070083 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070084
85 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070086 EXPECT_THROW(parseNeighbor(filter, hdr, data, neighbors),
87 std::runtime_error);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070088 EXPECT_EQ(0, neighbors.size());
89}
90
91TEST(ParseNeighbor, NoMAC)
92{
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070093 nlmsghdr hdr{};
94 hdr.nlmsg_type = RTM_NEWNEIGH;
95 ndmsg msg{};
96 msg.ndm_family = AF_INET;
97 msg.ndm_state = NUD_PERMANENT;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070098 msg.ndm_ifindex = 1;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070099 in_addr addr;
100 ASSERT_EQ(1, inet_pton(msg.ndm_family, "192.168.10.1", &addr));
101 rtattr dst{};
102 dst.rta_len = RTA_LENGTH(sizeof(addr));
103 dst.rta_type = NDA_DST;
104 char dstbuf[RTA_ALIGN(dst.rta_len)];
105 std::memset(dstbuf, '\0', sizeof(dstbuf));
106 std::memcpy(dstbuf, &dst, sizeof(dst));
107 std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
108 std::string data;
109 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
110 data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700111 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700112
113 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700114 parseNeighbor(filter, hdr, data, neighbors);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700115 EXPECT_EQ(1, neighbors.size());
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700116 EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
117 EXPECT_EQ(msg.ndm_state, neighbors[0].state);
118 EXPECT_FALSE(neighbors[0].mac);
William A. Kennington III12beaad2020-06-13 19:30:41 -0700119 EXPECT_TRUE(
120 stdplus::raw::equal(addr, std::get<in_addr>(neighbors[0].address)));
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700121}
122
123TEST(ParseNeighbor, FilterInterface)
124{
125 nlmsghdr hdr{};
126 hdr.nlmsg_type = RTM_NEWNEIGH;
127 ndmsg msg{};
128 msg.ndm_family = AF_INET;
129 msg.ndm_state = NUD_PERMANENT;
130 msg.ndm_ifindex = 2;
131 in_addr addr;
132 ASSERT_EQ(1, inet_pton(msg.ndm_family, "192.168.10.1", &addr));
133 rtattr dst{};
134 dst.rta_len = RTA_LENGTH(sizeof(addr));
135 dst.rta_type = NDA_DST;
136 char dstbuf[RTA_ALIGN(dst.rta_len)];
137 std::memset(dstbuf, '\0', sizeof(dstbuf));
138 std::memcpy(dstbuf, &dst, sizeof(dst));
139 std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
140 std::string data;
141 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
142 data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
143 NeighborFilter filter;
144
145 std::vector<NeighborInfo> neighbors;
146 filter.interface = 1;
147 parseNeighbor(filter, hdr, data, neighbors);
148 EXPECT_EQ(0, neighbors.size());
149 filter.interface = 2;
150 parseNeighbor(filter, hdr, data, neighbors);
151 EXPECT_EQ(1, neighbors.size());
152 EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
153 EXPECT_EQ(msg.ndm_state, neighbors[0].state);
154 EXPECT_FALSE(neighbors[0].mac);
William A. Kennington III12beaad2020-06-13 19:30:41 -0700155 EXPECT_TRUE(
156 stdplus::raw::equal(addr, std::get<in_addr>(neighbors[0].address)));
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700157}
158
159TEST(ParseNeighbor, FilterState)
160{
161 nlmsghdr hdr{};
162 hdr.nlmsg_type = RTM_NEWNEIGH;
163 ndmsg msg{};
164 msg.ndm_family = AF_INET;
165 msg.ndm_state = NUD_PERMANENT;
166 msg.ndm_ifindex = 2;
167 in_addr addr;
168 ASSERT_EQ(1, inet_pton(msg.ndm_family, "192.168.10.1", &addr));
169 rtattr dst{};
170 dst.rta_len = RTA_LENGTH(sizeof(addr));
171 dst.rta_type = NDA_DST;
172 char dstbuf[RTA_ALIGN(dst.rta_len)];
173 std::memset(dstbuf, '\0', sizeof(dstbuf));
174 std::memcpy(dstbuf, &dst, sizeof(dst));
175 std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
176 std::string data;
177 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
178 data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
179 NeighborFilter filter;
180
181 std::vector<NeighborInfo> neighbors;
182 filter.state = NUD_NOARP;
183 parseNeighbor(filter, hdr, data, neighbors);
184 EXPECT_EQ(0, neighbors.size());
185 filter.state = NUD_PERMANENT | NUD_NOARP;
186 parseNeighbor(filter, hdr, data, neighbors);
187 EXPECT_EQ(1, neighbors.size());
188 EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
189 EXPECT_EQ(msg.ndm_state, neighbors[0].state);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700190 EXPECT_FALSE(neighbors[0].mac);
William A. Kennington III12beaad2020-06-13 19:30:41 -0700191 EXPECT_TRUE(
192 stdplus::raw::equal(addr, std::get<in_addr>(neighbors[0].address)));
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700193}
194
195TEST(ParseNeighbor, Full)
196{
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700197 nlmsghdr hdr{};
198 hdr.nlmsg_type = RTM_NEWNEIGH;
199 ndmsg msg{};
200 msg.ndm_family = AF_INET6;
201 msg.ndm_state = NUD_NOARP;
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700202 msg.ndm_ifindex = 1;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700203 ether_addr mac = {{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}};
204 rtattr lladdr{};
205 lladdr.rta_len = RTA_LENGTH(sizeof(mac));
206 lladdr.rta_type = NDA_LLADDR;
207 char lladdrbuf[RTA_ALIGN(lladdr.rta_len)];
208 std::memset(lladdrbuf, '\0', sizeof(lladdrbuf));
209 std::memcpy(lladdrbuf, &lladdr, sizeof(lladdr));
210 std::memcpy(RTA_DATA(lladdrbuf), &mac, sizeof(mac));
211 in6_addr addr;
212 ASSERT_EQ(1, inet_pton(msg.ndm_family, "fd00::1", &addr));
213 rtattr dst{};
214 dst.rta_len = RTA_LENGTH(sizeof(addr));
215 dst.rta_type = NDA_DST;
216 char dstbuf[RTA_ALIGN(dst.rta_len)];
217 std::memset(dstbuf, '\0', sizeof(dstbuf));
218 std::memcpy(dstbuf, &dst, sizeof(dst));
219 std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
220 std::string data;
221 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
222 data.append(reinterpret_cast<char*>(&lladdrbuf), sizeof(lladdrbuf));
223 data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700224 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700225
226 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700227 parseNeighbor(filter, hdr, data, neighbors);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700228 EXPECT_EQ(1, neighbors.size());
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700229 EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
230 EXPECT_EQ(msg.ndm_state, neighbors[0].state);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700231 EXPECT_TRUE(neighbors[0].mac);
William A. Kennington III12beaad2020-06-13 19:30:41 -0700232 EXPECT_TRUE(stdplus::raw::equal(mac, *neighbors[0].mac));
233 EXPECT_TRUE(
234 stdplus::raw::equal(addr, std::get<in6_addr>(neighbors[0].address)));
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700235}
236
237} // namespace detail
238} // namespace network
239} // namespace phosphor