blob: 3cdb209814ffe4d33c6365a4a9e687cc8aa78b0b [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>
11#include <string>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070012#include <vector>
13
14#include <gtest/gtest.h>
15
16namespace phosphor
17{
18namespace network
19{
20namespace detail
21{
22
23TEST(ParseNeighbor, NotNeighborType)
24{
25 nlmsghdr hdr{};
26 hdr.nlmsg_type = RTM_NEWLINK;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070027 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070028
29 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070030 EXPECT_THROW(parseNeighbor(filter, hdr, "", neighbors), std::runtime_error);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070031 EXPECT_EQ(0, neighbors.size());
32}
33
34TEST(ParseNeighbor, SmallMsg)
35{
36 nlmsghdr hdr{};
37 hdr.nlmsg_type = RTM_NEWNEIGH;
38 std::string data = "1";
William A. Kennington IIId7946a72019-04-19 14:24:09 -070039 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070040
41 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070042 EXPECT_THROW(parseNeighbor(filter, hdr, data, neighbors),
43 std::runtime_error);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070044 EXPECT_EQ(0, neighbors.size());
45}
46
47TEST(ParseNeighbor, NoAttrs)
48{
49 nlmsghdr hdr{};
50 hdr.nlmsg_type = RTM_NEWNEIGH;
51 ndmsg msg{};
William A. Kennington IIId7946a72019-04-19 14:24:09 -070052 msg.ndm_ifindex = 1;
53 msg.ndm_state = NUD_REACHABLE;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070054 std::string data;
55 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
William A. Kennington IIId7946a72019-04-19 14:24:09 -070056 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070057
58 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070059 EXPECT_THROW(parseNeighbor(filter, hdr, data, neighbors),
60 std::runtime_error);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070061 EXPECT_EQ(0, neighbors.size());
62}
63
64TEST(ParseNeighbor, NoAddress)
65{
66 nlmsghdr hdr{};
67 hdr.nlmsg_type = RTM_NEWNEIGH;
68 ndmsg msg{};
William A. Kennington IIId7946a72019-04-19 14:24:09 -070069 msg.ndm_ifindex = 1;
70 msg.ndm_state = NUD_REACHABLE;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070071 ether_addr mac = {{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}};
72 rtattr lladdr{};
William A. Kennington IIIa19558e2021-05-13 18:56:51 -070073 constexpr size_t len = RTA_LENGTH(sizeof(mac));
74 lladdr.rta_len = len;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070075 lladdr.rta_type = NDA_LLADDR;
William A. Kennington IIIa19558e2021-05-13 18:56:51 -070076 char lladdrbuf[RTA_ALIGN(len)];
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070077 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{};
William A. Kennington IIIa19558e2021-05-13 18:56:51 -0700102 constexpr size_t len = RTA_LENGTH(sizeof(addr));
103 dst.rta_len = len;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700104 dst.rta_type = NDA_DST;
William A. Kennington IIIa19558e2021-05-13 18:56:51 -0700105 char dstbuf[RTA_ALIGN(len)];
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700106 std::memset(dstbuf, '\0', sizeof(dstbuf));
107 std::memcpy(dstbuf, &dst, sizeof(dst));
108 std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
109 std::string data;
110 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
111 data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700112 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700113
114 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700115 parseNeighbor(filter, hdr, data, neighbors);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700116 EXPECT_EQ(1, neighbors.size());
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700117 EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
118 EXPECT_EQ(msg.ndm_state, neighbors[0].state);
119 EXPECT_FALSE(neighbors[0].mac);
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700120 EXPECT_EQ(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{};
William A. Kennington IIIa19558e2021-05-13 18:56:51 -0700134 constexpr size_t len = RTA_LENGTH(sizeof(addr));
135 dst.rta_len = len;
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700136 dst.rta_type = NDA_DST;
William A. Kennington IIIa19558e2021-05-13 18:56:51 -0700137 char dstbuf[RTA_ALIGN(len)];
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700138 std::memset(dstbuf, '\0', sizeof(dstbuf));
139 std::memcpy(dstbuf, &dst, sizeof(dst));
140 std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
141 std::string data;
142 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
143 data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
144 NeighborFilter filter;
145
146 std::vector<NeighborInfo> neighbors;
147 filter.interface = 1;
148 parseNeighbor(filter, hdr, data, neighbors);
149 EXPECT_EQ(0, neighbors.size());
150 filter.interface = 2;
151 parseNeighbor(filter, hdr, data, neighbors);
152 EXPECT_EQ(1, neighbors.size());
153 EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
154 EXPECT_EQ(msg.ndm_state, neighbors[0].state);
155 EXPECT_FALSE(neighbors[0].mac);
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700156 EXPECT_EQ(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{};
William A. Kennington IIIa19558e2021-05-13 18:56:51 -0700170 constexpr size_t len = RTA_LENGTH(sizeof(addr));
171 dst.rta_len = len;
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700172 dst.rta_type = NDA_DST;
William A. Kennington IIIa19558e2021-05-13 18:56:51 -0700173 char dstbuf[RTA_ALIGN(len)];
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700174 std::memset(dstbuf, '\0', sizeof(dstbuf));
175 std::memcpy(dstbuf, &dst, sizeof(dst));
176 std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
177 std::string data;
178 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
179 data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
180 NeighborFilter filter;
181
182 std::vector<NeighborInfo> neighbors;
183 filter.state = NUD_NOARP;
184 parseNeighbor(filter, hdr, data, neighbors);
185 EXPECT_EQ(0, neighbors.size());
186 filter.state = NUD_PERMANENT | NUD_NOARP;
187 parseNeighbor(filter, hdr, data, neighbors);
188 EXPECT_EQ(1, neighbors.size());
189 EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
190 EXPECT_EQ(msg.ndm_state, neighbors[0].state);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700191 EXPECT_FALSE(neighbors[0].mac);
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700192 EXPECT_EQ(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{};
William A. Kennington IIIa19558e2021-05-13 18:56:51 -0700205 constexpr size_t lladdr_len = RTA_LENGTH(sizeof(mac));
206 lladdr.rta_len = lladdr_len;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700207 lladdr.rta_type = NDA_LLADDR;
William A. Kennington IIIa19558e2021-05-13 18:56:51 -0700208 char lladdrbuf[RTA_ALIGN(lladdr_len)];
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700209 std::memset(lladdrbuf, '\0', sizeof(lladdrbuf));
210 std::memcpy(lladdrbuf, &lladdr, sizeof(lladdr));
211 std::memcpy(RTA_DATA(lladdrbuf), &mac, sizeof(mac));
212 in6_addr addr;
213 ASSERT_EQ(1, inet_pton(msg.ndm_family, "fd00::1", &addr));
214 rtattr dst{};
William A. Kennington IIIa19558e2021-05-13 18:56:51 -0700215 constexpr size_t dst_len = RTA_LENGTH(sizeof(addr));
216 dst.rta_len = dst_len;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700217 dst.rta_type = NDA_DST;
William A. Kennington IIIa19558e2021-05-13 18:56:51 -0700218 char dstbuf[RTA_ALIGN(dst_len)];
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700219 std::memset(dstbuf, '\0', sizeof(dstbuf));
220 std::memcpy(dstbuf, &dst, sizeof(dst));
221 std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
222 std::string data;
223 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
224 data.append(reinterpret_cast<char*>(&lladdrbuf), sizeof(lladdrbuf));
225 data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700226 NeighborFilter filter;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700227
228 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700229 parseNeighbor(filter, hdr, data, neighbors);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700230 EXPECT_EQ(1, neighbors.size());
William A. Kennington IIId7946a72019-04-19 14:24:09 -0700231 EXPECT_EQ(msg.ndm_ifindex, neighbors[0].interface);
232 EXPECT_EQ(msg.ndm_state, neighbors[0].state);
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700233 EXPECT_EQ(mac, neighbors[0].mac);
234 EXPECT_EQ(addr, neighbors[0].address);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700235}
236
237} // namespace detail
238} // namespace network
239} // namespace phosphor