xref: /aosp_15_r20/external/ot-br-posix/tests/gtest/test_netif.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker  *    Copyright (c) 2024, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker  *    All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker  *
5*4a64e381SAndroid Build Coastguard Worker  *    Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker  *    modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker  *    1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker  *    2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker  *       documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker  *    3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker  *       names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker  *       derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker  *
16*4a64e381SAndroid Build Coastguard Worker  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker  *    POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker  */
28*4a64e381SAndroid Build Coastguard Worker 
29*4a64e381SAndroid Build Coastguard Worker #include <gmock/gmock.h>
30*4a64e381SAndroid Build Coastguard Worker #include <gtest/gtest.h>
31*4a64e381SAndroid Build Coastguard Worker 
32*4a64e381SAndroid Build Coastguard Worker #include <arpa/inet.h>
33*4a64e381SAndroid Build Coastguard Worker #include <cstring>
34*4a64e381SAndroid Build Coastguard Worker #include <fstream>
35*4a64e381SAndroid Build Coastguard Worker #include <ifaddrs.h>
36*4a64e381SAndroid Build Coastguard Worker #include <iostream>
37*4a64e381SAndroid Build Coastguard Worker #include <net/if.h>
38*4a64e381SAndroid Build Coastguard Worker #include <netinet/in.h>
39*4a64e381SAndroid Build Coastguard Worker #include <netinet/ip6.h>
40*4a64e381SAndroid Build Coastguard Worker #include <netinet/udp.h>
41*4a64e381SAndroid Build Coastguard Worker #include <stdio.h>
42*4a64e381SAndroid Build Coastguard Worker #include <stdlib.h>
43*4a64e381SAndroid Build Coastguard Worker #include <string.h>
44*4a64e381SAndroid Build Coastguard Worker #include <string>
45*4a64e381SAndroid Build Coastguard Worker #include <sys/ioctl.h>
46*4a64e381SAndroid Build Coastguard Worker #include <sys/select.h>
47*4a64e381SAndroid Build Coastguard Worker #include <sys/socket.h>
48*4a64e381SAndroid Build Coastguard Worker #include <sys/types.h>
49*4a64e381SAndroid Build Coastguard Worker #include <vector>
50*4a64e381SAndroid Build Coastguard Worker 
51*4a64e381SAndroid Build Coastguard Worker #ifdef __linux__
52*4a64e381SAndroid Build Coastguard Worker #include <linux/if_link.h>
53*4a64e381SAndroid Build Coastguard Worker #endif
54*4a64e381SAndroid Build Coastguard Worker 
55*4a64e381SAndroid Build Coastguard Worker #include <openthread/ip6.h>
56*4a64e381SAndroid Build Coastguard Worker 
57*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
58*4a64e381SAndroid Build Coastguard Worker #include "common/mainloop.hpp"
59*4a64e381SAndroid Build Coastguard Worker #include "common/types.hpp"
60*4a64e381SAndroid Build Coastguard Worker #include "ncp/posix/netif.hpp"
61*4a64e381SAndroid Build Coastguard Worker #include "utils/socket_utils.hpp"
62*4a64e381SAndroid Build Coastguard Worker 
63*4a64e381SAndroid Build Coastguard Worker // Only Test on linux platform for now.
64*4a64e381SAndroid Build Coastguard Worker #ifdef __linux__
65*4a64e381SAndroid Build Coastguard Worker 
66*4a64e381SAndroid Build Coastguard Worker static constexpr size_t kMaxIp6Size = 1280;
67*4a64e381SAndroid Build Coastguard Worker 
GetAllIp6Addrs(const char * aInterfaceName)68*4a64e381SAndroid Build Coastguard Worker std::vector<std::string> GetAllIp6Addrs(const char *aInterfaceName)
69*4a64e381SAndroid Build Coastguard Worker {
70*4a64e381SAndroid Build Coastguard Worker     struct ifaddrs          *ifaddr, *ifa;
71*4a64e381SAndroid Build Coastguard Worker     int                      family;
72*4a64e381SAndroid Build Coastguard Worker     std::vector<std::string> ip6Addrs;
73*4a64e381SAndroid Build Coastguard Worker 
74*4a64e381SAndroid Build Coastguard Worker     if (getifaddrs(&ifaddr) == -1)
75*4a64e381SAndroid Build Coastguard Worker     {
76*4a64e381SAndroid Build Coastguard Worker         perror("getifaddrs");
77*4a64e381SAndroid Build Coastguard Worker         exit(EXIT_FAILURE);
78*4a64e381SAndroid Build Coastguard Worker     }
79*4a64e381SAndroid Build Coastguard Worker 
80*4a64e381SAndroid Build Coastguard Worker     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
81*4a64e381SAndroid Build Coastguard Worker     {
82*4a64e381SAndroid Build Coastguard Worker         if (ifa->ifa_addr == NULL)
83*4a64e381SAndroid Build Coastguard Worker         {
84*4a64e381SAndroid Build Coastguard Worker             continue;
85*4a64e381SAndroid Build Coastguard Worker         }
86*4a64e381SAndroid Build Coastguard Worker 
87*4a64e381SAndroid Build Coastguard Worker         family = ifa->ifa_addr->sa_family;
88*4a64e381SAndroid Build Coastguard Worker         if (family == AF_INET6 && strcmp(ifa->ifa_name, aInterfaceName) == 0)
89*4a64e381SAndroid Build Coastguard Worker         {
90*4a64e381SAndroid Build Coastguard Worker             struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)ifa->ifa_addr;
91*4a64e381SAndroid Build Coastguard Worker             char                 addrstr[INET6_ADDRSTRLEN];
92*4a64e381SAndroid Build Coastguard Worker             if (inet_ntop(AF_INET6, &(in6->sin6_addr), addrstr, sizeof(addrstr)) == NULL)
93*4a64e381SAndroid Build Coastguard Worker             {
94*4a64e381SAndroid Build Coastguard Worker                 perror("inet_ntop");
95*4a64e381SAndroid Build Coastguard Worker                 exit(EXIT_FAILURE);
96*4a64e381SAndroid Build Coastguard Worker             }
97*4a64e381SAndroid Build Coastguard Worker 
98*4a64e381SAndroid Build Coastguard Worker             ip6Addrs.emplace_back(addrstr);
99*4a64e381SAndroid Build Coastguard Worker         }
100*4a64e381SAndroid Build Coastguard Worker     }
101*4a64e381SAndroid Build Coastguard Worker 
102*4a64e381SAndroid Build Coastguard Worker     freeifaddrs(ifaddr);
103*4a64e381SAndroid Build Coastguard Worker 
104*4a64e381SAndroid Build Coastguard Worker     return ip6Addrs;
105*4a64e381SAndroid Build Coastguard Worker }
106*4a64e381SAndroid Build Coastguard Worker 
ParseHex(char * aStr,unsigned char * aAddr)107*4a64e381SAndroid Build Coastguard Worker static int ParseHex(char *aStr, unsigned char *aAddr)
108*4a64e381SAndroid Build Coastguard Worker {
109*4a64e381SAndroid Build Coastguard Worker     int len = 0;
110*4a64e381SAndroid Build Coastguard Worker 
111*4a64e381SAndroid Build Coastguard Worker     while (*aStr)
112*4a64e381SAndroid Build Coastguard Worker     {
113*4a64e381SAndroid Build Coastguard Worker         int tmp;
114*4a64e381SAndroid Build Coastguard Worker         if (aStr[1] == 0)
115*4a64e381SAndroid Build Coastguard Worker         {
116*4a64e381SAndroid Build Coastguard Worker             return -1;
117*4a64e381SAndroid Build Coastguard Worker         }
118*4a64e381SAndroid Build Coastguard Worker         if (sscanf(aStr, "%02x", &tmp) != 1)
119*4a64e381SAndroid Build Coastguard Worker         {
120*4a64e381SAndroid Build Coastguard Worker             return -1;
121*4a64e381SAndroid Build Coastguard Worker         }
122*4a64e381SAndroid Build Coastguard Worker         aAddr[len] = tmp;
123*4a64e381SAndroid Build Coastguard Worker         len++;
124*4a64e381SAndroid Build Coastguard Worker         aStr += 2;
125*4a64e381SAndroid Build Coastguard Worker     }
126*4a64e381SAndroid Build Coastguard Worker 
127*4a64e381SAndroid Build Coastguard Worker     return len;
128*4a64e381SAndroid Build Coastguard Worker }
129*4a64e381SAndroid Build Coastguard Worker 
GetAllIp6MulAddrs(const char * aInterfaceName)130*4a64e381SAndroid Build Coastguard Worker std::vector<std::string> GetAllIp6MulAddrs(const char *aInterfaceName)
131*4a64e381SAndroid Build Coastguard Worker {
132*4a64e381SAndroid Build Coastguard Worker     const char              *kPathIgmp6 = "/proc/net/igmp6";
133*4a64e381SAndroid Build Coastguard Worker     std::string              line;
134*4a64e381SAndroid Build Coastguard Worker     std::vector<std::string> ip6MulAddrs;
135*4a64e381SAndroid Build Coastguard Worker 
136*4a64e381SAndroid Build Coastguard Worker     std::ifstream file(kPathIgmp6);
137*4a64e381SAndroid Build Coastguard Worker     if (!file.is_open())
138*4a64e381SAndroid Build Coastguard Worker     {
139*4a64e381SAndroid Build Coastguard Worker         perror("Cannot open IGMP6 file");
140*4a64e381SAndroid Build Coastguard Worker         exit(EXIT_FAILURE);
141*4a64e381SAndroid Build Coastguard Worker     }
142*4a64e381SAndroid Build Coastguard Worker 
143*4a64e381SAndroid Build Coastguard Worker     while (std::getline(file, line))
144*4a64e381SAndroid Build Coastguard Worker     {
145*4a64e381SAndroid Build Coastguard Worker         char          interfaceName[256] = {0};
146*4a64e381SAndroid Build Coastguard Worker         char          hexa[256]          = {0};
147*4a64e381SAndroid Build Coastguard Worker         int           index;
148*4a64e381SAndroid Build Coastguard Worker         int           users;
149*4a64e381SAndroid Build Coastguard Worker         unsigned char addr[16];
150*4a64e381SAndroid Build Coastguard Worker 
151*4a64e381SAndroid Build Coastguard Worker         sscanf(line.c_str(), "%d%s%s%d", &index, interfaceName, hexa, &users);
152*4a64e381SAndroid Build Coastguard Worker         if (strcmp(interfaceName, aInterfaceName) == 0)
153*4a64e381SAndroid Build Coastguard Worker         {
154*4a64e381SAndroid Build Coastguard Worker             char addrStr[INET6_ADDRSTRLEN];
155*4a64e381SAndroid Build Coastguard Worker             ParseHex(hexa, addr);
156*4a64e381SAndroid Build Coastguard Worker             if (inet_ntop(AF_INET6, addr, addrStr, sizeof(addrStr)) == NULL)
157*4a64e381SAndroid Build Coastguard Worker             {
158*4a64e381SAndroid Build Coastguard Worker                 perror("inet_ntop");
159*4a64e381SAndroid Build Coastguard Worker                 exit(EXIT_FAILURE);
160*4a64e381SAndroid Build Coastguard Worker             }
161*4a64e381SAndroid Build Coastguard Worker             ip6MulAddrs.emplace_back(addrStr);
162*4a64e381SAndroid Build Coastguard Worker         }
163*4a64e381SAndroid Build Coastguard Worker     }
164*4a64e381SAndroid Build Coastguard Worker 
165*4a64e381SAndroid Build Coastguard Worker     file.close();
166*4a64e381SAndroid Build Coastguard Worker 
167*4a64e381SAndroid Build Coastguard Worker     return ip6MulAddrs;
168*4a64e381SAndroid Build Coastguard Worker }
169*4a64e381SAndroid Build Coastguard Worker 
Ip6SendEmptyImpl(const uint8_t * aData,uint16_t aLength)170*4a64e381SAndroid Build Coastguard Worker otbrError Ip6SendEmptyImpl(const uint8_t *aData, uint16_t aLength)
171*4a64e381SAndroid Build Coastguard Worker {
172*4a64e381SAndroid Build Coastguard Worker     OTBR_UNUSED_VARIABLE(aData);
173*4a64e381SAndroid Build Coastguard Worker     OTBR_UNUSED_VARIABLE(aLength);
174*4a64e381SAndroid Build Coastguard Worker     return OTBR_ERROR_NONE;
175*4a64e381SAndroid Build Coastguard Worker }
176*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanInitWithFullInterfaceName)177*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanInitWithFullInterfaceName)
178*4a64e381SAndroid Build Coastguard Worker {
179*4a64e381SAndroid Build Coastguard Worker     const char  *wpan = "wpan0";
180*4a64e381SAndroid Build Coastguard Worker     int          sockfd;
181*4a64e381SAndroid Build Coastguard Worker     struct ifreq ifr;
182*4a64e381SAndroid Build Coastguard Worker 
183*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
184*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init(wpan, Ip6SendEmptyImpl), OT_ERROR_NONE);
185*4a64e381SAndroid Build Coastguard Worker 
186*4a64e381SAndroid Build Coastguard Worker     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
187*4a64e381SAndroid Build Coastguard Worker     if (sockfd < 0)
188*4a64e381SAndroid Build Coastguard Worker     {
189*4a64e381SAndroid Build Coastguard Worker         FAIL() << "Error creating socket: " << std::strerror(errno);
190*4a64e381SAndroid Build Coastguard Worker     }
191*4a64e381SAndroid Build Coastguard Worker 
192*4a64e381SAndroid Build Coastguard Worker     memset(&ifr, 0, sizeof(ifr));
193*4a64e381SAndroid Build Coastguard Worker     strncpy(ifr.ifr_name, wpan, IFNAMSIZ - 1);
194*4a64e381SAndroid Build Coastguard Worker 
195*4a64e381SAndroid Build Coastguard Worker     EXPECT_GE(ioctl(sockfd, SIOCGIFFLAGS, &ifr), 0) << "'" << wpan << "' not found";
196*4a64e381SAndroid Build Coastguard Worker 
197*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
198*4a64e381SAndroid Build Coastguard Worker }
199*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanInitWithFormatInterfaceName)200*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanInitWithFormatInterfaceName)
201*4a64e381SAndroid Build Coastguard Worker {
202*4a64e381SAndroid Build Coastguard Worker     const char  *wpan    = "tun%d";
203*4a64e381SAndroid Build Coastguard Worker     const char  *if_name = "tun0";
204*4a64e381SAndroid Build Coastguard Worker     int          sockfd;
205*4a64e381SAndroid Build Coastguard Worker     struct ifreq ifr;
206*4a64e381SAndroid Build Coastguard Worker 
207*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
208*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init(wpan, Ip6SendEmptyImpl), OT_ERROR_NONE);
209*4a64e381SAndroid Build Coastguard Worker 
210*4a64e381SAndroid Build Coastguard Worker     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
211*4a64e381SAndroid Build Coastguard Worker     if (sockfd < 0)
212*4a64e381SAndroid Build Coastguard Worker     {
213*4a64e381SAndroid Build Coastguard Worker         FAIL() << "Error creating socket: " << std::strerror(errno);
214*4a64e381SAndroid Build Coastguard Worker     }
215*4a64e381SAndroid Build Coastguard Worker 
216*4a64e381SAndroid Build Coastguard Worker     memset(&ifr, 0, sizeof(ifr));
217*4a64e381SAndroid Build Coastguard Worker     strncpy(ifr.ifr_name, if_name, IFNAMSIZ - 1);
218*4a64e381SAndroid Build Coastguard Worker 
219*4a64e381SAndroid Build Coastguard Worker     EXPECT_GE(ioctl(sockfd, SIOCGIFFLAGS, &ifr), 0) << "'" << if_name << "' not found";
220*4a64e381SAndroid Build Coastguard Worker 
221*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
222*4a64e381SAndroid Build Coastguard Worker }
223*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanInitWithEmptyInterfaceName)224*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanInitWithEmptyInterfaceName)
225*4a64e381SAndroid Build Coastguard Worker {
226*4a64e381SAndroid Build Coastguard Worker     const char  *if_name = "wpan0";
227*4a64e381SAndroid Build Coastguard Worker     int          sockfd;
228*4a64e381SAndroid Build Coastguard Worker     struct ifreq ifr;
229*4a64e381SAndroid Build Coastguard Worker 
230*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
231*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init("", Ip6SendEmptyImpl), OT_ERROR_NONE);
232*4a64e381SAndroid Build Coastguard Worker 
233*4a64e381SAndroid Build Coastguard Worker     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
234*4a64e381SAndroid Build Coastguard Worker     if (sockfd < 0)
235*4a64e381SAndroid Build Coastguard Worker     {
236*4a64e381SAndroid Build Coastguard Worker         FAIL() << "Error creating socket: " << std::strerror(errno);
237*4a64e381SAndroid Build Coastguard Worker     }
238*4a64e381SAndroid Build Coastguard Worker 
239*4a64e381SAndroid Build Coastguard Worker     memset(&ifr, 0, sizeof(ifr));
240*4a64e381SAndroid Build Coastguard Worker     strncpy(ifr.ifr_name, if_name, IFNAMSIZ - 1);
241*4a64e381SAndroid Build Coastguard Worker 
242*4a64e381SAndroid Build Coastguard Worker     EXPECT_GE(ioctl(sockfd, SIOCGIFFLAGS, &ifr), 0) << "'" << if_name << "' not found";
243*4a64e381SAndroid Build Coastguard Worker 
244*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
245*4a64e381SAndroid Build Coastguard Worker }
246*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanInitWithInvalidInterfaceName)247*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanInitWithInvalidInterfaceName)
248*4a64e381SAndroid Build Coastguard Worker {
249*4a64e381SAndroid Build Coastguard Worker     const char *invalid_netif_name = "invalid_netif_name";
250*4a64e381SAndroid Build Coastguard Worker 
251*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
252*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init(invalid_netif_name, Ip6SendEmptyImpl), OTBR_ERROR_INVALID_ARGS);
253*4a64e381SAndroid Build Coastguard Worker }
254*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanMtuSize)255*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanMtuSize)
256*4a64e381SAndroid Build Coastguard Worker {
257*4a64e381SAndroid Build Coastguard Worker     const char  *wpan = "wpan0";
258*4a64e381SAndroid Build Coastguard Worker     int          sockfd;
259*4a64e381SAndroid Build Coastguard Worker     struct ifreq ifr;
260*4a64e381SAndroid Build Coastguard Worker 
261*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
262*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init(wpan, Ip6SendEmptyImpl), OT_ERROR_NONE);
263*4a64e381SAndroid Build Coastguard Worker 
264*4a64e381SAndroid Build Coastguard Worker     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
265*4a64e381SAndroid Build Coastguard Worker     if (sockfd < 0)
266*4a64e381SAndroid Build Coastguard Worker     {
267*4a64e381SAndroid Build Coastguard Worker         FAIL() << "Error creating socket: " << std::strerror(errno);
268*4a64e381SAndroid Build Coastguard Worker     }
269*4a64e381SAndroid Build Coastguard Worker 
270*4a64e381SAndroid Build Coastguard Worker     memset(&ifr, 0, sizeof(ifr));
271*4a64e381SAndroid Build Coastguard Worker     strncpy(ifr.ifr_name, wpan, IFNAMSIZ - 1);
272*4a64e381SAndroid Build Coastguard Worker     EXPECT_GE(ioctl(sockfd, SIOCGIFMTU, &ifr), 0) << "Error getting MTU for '" << wpan << "': " << std::strerror(errno);
273*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(ifr.ifr_mtu, kMaxIp6Size) << "MTU isn't set correctly";
274*4a64e381SAndroid Build Coastguard Worker 
275*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
276*4a64e381SAndroid Build Coastguard Worker }
277*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanDeinit)278*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanDeinit)
279*4a64e381SAndroid Build Coastguard Worker {
280*4a64e381SAndroid Build Coastguard Worker     const char  *wpan = "wpan0";
281*4a64e381SAndroid Build Coastguard Worker     int          sockfd;
282*4a64e381SAndroid Build Coastguard Worker     struct ifreq ifr;
283*4a64e381SAndroid Build Coastguard Worker 
284*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
285*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init(wpan, Ip6SendEmptyImpl), OT_ERROR_NONE);
286*4a64e381SAndroid Build Coastguard Worker 
287*4a64e381SAndroid Build Coastguard Worker     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
288*4a64e381SAndroid Build Coastguard Worker     if (sockfd < 0)
289*4a64e381SAndroid Build Coastguard Worker     {
290*4a64e381SAndroid Build Coastguard Worker         FAIL() << "Error creating socket: " << std::strerror(errno);
291*4a64e381SAndroid Build Coastguard Worker     }
292*4a64e381SAndroid Build Coastguard Worker 
293*4a64e381SAndroid Build Coastguard Worker     memset(&ifr, 0, sizeof(ifr));
294*4a64e381SAndroid Build Coastguard Worker     strncpy(ifr.ifr_name, wpan, IFNAMSIZ - 1);
295*4a64e381SAndroid Build Coastguard Worker     EXPECT_GE(ioctl(sockfd, SIOCGIFFLAGS, &ifr), 0) << "'" << wpan << "' not found";
296*4a64e381SAndroid Build Coastguard Worker 
297*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
298*4a64e381SAndroid Build Coastguard Worker     EXPECT_LT(ioctl(sockfd, SIOCGIFFLAGS, &ifr), 0) << "'" << wpan << "' isn't shutdown";
299*4a64e381SAndroid Build Coastguard Worker }
300*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanAddrGenMode)301*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanAddrGenMode)
302*4a64e381SAndroid Build Coastguard Worker {
303*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
304*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init("wpan0", Ip6SendEmptyImpl), OT_ERROR_NONE);
305*4a64e381SAndroid Build Coastguard Worker 
306*4a64e381SAndroid Build Coastguard Worker     std::fstream file("/proc/sys/net/ipv6/conf/wpan0/addr_gen_mode", std::ios::in);
307*4a64e381SAndroid Build Coastguard Worker     if (!file.is_open())
308*4a64e381SAndroid Build Coastguard Worker     {
309*4a64e381SAndroid Build Coastguard Worker         FAIL() << "wpan0 interface doesn't exist!";
310*4a64e381SAndroid Build Coastguard Worker     }
311*4a64e381SAndroid Build Coastguard Worker     std::string fileContents((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
312*4a64e381SAndroid Build Coastguard Worker 
313*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(std::stoi(fileContents), IN6_ADDR_GEN_MODE_NONE);
314*4a64e381SAndroid Build Coastguard Worker 
315*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
316*4a64e381SAndroid Build Coastguard Worker }
317*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanIfHasCorrectUnicastAddresses_AfterUpdatingUnicastAddresses)318*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanIfHasCorrectUnicastAddresses_AfterUpdatingUnicastAddresses)
319*4a64e381SAndroid Build Coastguard Worker {
320*4a64e381SAndroid Build Coastguard Worker     const char *wpan = "wpan0";
321*4a64e381SAndroid Build Coastguard Worker 
322*4a64e381SAndroid Build Coastguard Worker     const otIp6Address kLl = {
323*4a64e381SAndroid Build Coastguard Worker         {0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x14, 0x03, 0x32, 0x4c, 0xc2, 0xf8, 0xd0}};
324*4a64e381SAndroid Build Coastguard Worker     const otIp6Address kMlEid = {
325*4a64e381SAndroid Build Coastguard Worker         {0xfd, 0x0d, 0x07, 0xfc, 0xa1, 0xb9, 0xf0, 0x50, 0x03, 0xf1, 0x47, 0xce, 0x85, 0xd3, 0x07, 0x7f}};
326*4a64e381SAndroid Build Coastguard Worker     const otIp6Address kMlRloc = {
327*4a64e381SAndroid Build Coastguard Worker         {0xfd, 0x0d, 0x07, 0xfc, 0xa1, 0xb9, 0xf0, 0x50, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0xb8, 0x00}};
328*4a64e381SAndroid Build Coastguard Worker     const otIp6Address kMlAloc = {
329*4a64e381SAndroid Build Coastguard Worker         {0xfd, 0x0d, 0x07, 0xfc, 0xa1, 0xb9, 0xf0, 0x50, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0xfc, 0x00}};
330*4a64e381SAndroid Build Coastguard Worker 
331*4a64e381SAndroid Build Coastguard Worker     const char *kLlStr     = "fe80::8014:332:4cc2:f8d0";
332*4a64e381SAndroid Build Coastguard Worker     const char *kMlEidStr  = "fd0d:7fc:a1b9:f050:3f1:47ce:85d3:77f";
333*4a64e381SAndroid Build Coastguard Worker     const char *kMlRlocStr = "fd0d:7fc:a1b9:f050:0:ff:fe00:b800";
334*4a64e381SAndroid Build Coastguard Worker     const char *kMlAlocStr = "fd0d:7fc:a1b9:f050:0:ff:fe00:fc00";
335*4a64e381SAndroid Build Coastguard Worker 
336*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
337*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init(wpan, Ip6SendEmptyImpl), OT_ERROR_NONE);
338*4a64e381SAndroid Build Coastguard Worker 
339*4a64e381SAndroid Build Coastguard Worker     otbr::Ip6AddressInfo testArray1[] = {
340*4a64e381SAndroid Build Coastguard Worker         {kLl, 64, 0, 1, 0},
341*4a64e381SAndroid Build Coastguard Worker         {kMlEid, 64, 0, 1, 1},
342*4a64e381SAndroid Build Coastguard Worker         {kMlRloc, 64, 0, 1, 1},
343*4a64e381SAndroid Build Coastguard Worker     };
344*4a64e381SAndroid Build Coastguard Worker     std::vector<otbr::Ip6AddressInfo> testVec1(testArray1,
345*4a64e381SAndroid Build Coastguard Worker                                                testArray1 + sizeof(testArray1) / sizeof(otbr::Ip6AddressInfo));
346*4a64e381SAndroid Build Coastguard Worker     netif.UpdateIp6UnicastAddresses(testVec1);
347*4a64e381SAndroid Build Coastguard Worker     std::vector<std::string> wpan_addrs = GetAllIp6Addrs(wpan);
348*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(wpan_addrs.size(), 3);
349*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpan_addrs, ::testing::Contains(kLlStr));
350*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpan_addrs, ::testing::Contains(kMlEidStr));
351*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpan_addrs, ::testing::Contains(kMlRlocStr));
352*4a64e381SAndroid Build Coastguard Worker 
353*4a64e381SAndroid Build Coastguard Worker     otbr::Ip6AddressInfo testArray2[] = {
354*4a64e381SAndroid Build Coastguard Worker         {kLl, 64, 0, 1, 0},
355*4a64e381SAndroid Build Coastguard Worker         {kMlEid, 64, 0, 1, 1},
356*4a64e381SAndroid Build Coastguard Worker         {kMlRloc, 64, 0, 1, 1},
357*4a64e381SAndroid Build Coastguard Worker         {kMlAloc, 64, 0, 1, 1},
358*4a64e381SAndroid Build Coastguard Worker     };
359*4a64e381SAndroid Build Coastguard Worker     std::vector<otbr::Ip6AddressInfo> testVec2(testArray2,
360*4a64e381SAndroid Build Coastguard Worker                                                testArray2 + sizeof(testArray2) / sizeof(otbr::Ip6AddressInfo));
361*4a64e381SAndroid Build Coastguard Worker     netif.UpdateIp6UnicastAddresses(testVec2);
362*4a64e381SAndroid Build Coastguard Worker     wpan_addrs = GetAllIp6Addrs(wpan);
363*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(wpan_addrs.size(), 4);
364*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpan_addrs, ::testing::Contains(kLlStr));
365*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpan_addrs, ::testing::Contains(kMlEidStr));
366*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpan_addrs, ::testing::Contains(kMlRlocStr));
367*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpan_addrs, ::testing::Contains(kMlAlocStr));
368*4a64e381SAndroid Build Coastguard Worker 
369*4a64e381SAndroid Build Coastguard Worker     std::vector<otbr::Ip6AddressInfo> testVec3;
370*4a64e381SAndroid Build Coastguard Worker     netif.UpdateIp6UnicastAddresses(testVec3);
371*4a64e381SAndroid Build Coastguard Worker     wpan_addrs = GetAllIp6Addrs(wpan);
372*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(wpan_addrs.size(), 0);
373*4a64e381SAndroid Build Coastguard Worker 
374*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
375*4a64e381SAndroid Build Coastguard Worker }
376*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanIfHasCorrectMulticastAddresses_AfterUpdatingMulticastAddresses)377*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanIfHasCorrectMulticastAddresses_AfterUpdatingMulticastAddresses)
378*4a64e381SAndroid Build Coastguard Worker {
379*4a64e381SAndroid Build Coastguard Worker     const char *wpan = "wpan0";
380*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
381*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init(wpan, Ip6SendEmptyImpl), OT_ERROR_NONE);
382*4a64e381SAndroid Build Coastguard Worker 
383*4a64e381SAndroid Build Coastguard Worker     otbr::Ip6Address kDefaultMulAddr1 = {
384*4a64e381SAndroid Build Coastguard Worker         {0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}};
385*4a64e381SAndroid Build Coastguard Worker     const char *kDefaultMulAddr1Str = "ff01::1";
386*4a64e381SAndroid Build Coastguard Worker     const char *kDefaultMulAddr2Str = "ff02::1";
387*4a64e381SAndroid Build Coastguard Worker     const char *kDefaultMulAddr3Str = "ff02::2";
388*4a64e381SAndroid Build Coastguard Worker 
389*4a64e381SAndroid Build Coastguard Worker     otbr::Ip6Address kMulAddr1 = {
390*4a64e381SAndroid Build Coastguard Worker         {0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc}};
391*4a64e381SAndroid Build Coastguard Worker     otbr::Ip6Address kMulAddr2 = {
392*4a64e381SAndroid Build Coastguard Worker         {0xff, 0x32, 0x00, 0x40, 0xfd, 0x0d, 0x07, 0xfc, 0xa1, 0xb9, 0xf0, 0x50, 0x00, 0x00, 0x00, 0x01}};
393*4a64e381SAndroid Build Coastguard Worker     const char *kMulAddr1Str = "ff03::fc";
394*4a64e381SAndroid Build Coastguard Worker     const char *kMulAddr2Str = "ff32:40:fd0d:7fc:a1b9:f050:0:1";
395*4a64e381SAndroid Build Coastguard Worker 
396*4a64e381SAndroid Build Coastguard Worker     otbr::Ip6Address testArray1[] = {
397*4a64e381SAndroid Build Coastguard Worker         kMulAddr1,
398*4a64e381SAndroid Build Coastguard Worker     };
399*4a64e381SAndroid Build Coastguard Worker     std::vector<otbr::Ip6Address> testVec1(testArray1, testArray1 + sizeof(testArray1) / sizeof(otbr::Ip6Address));
400*4a64e381SAndroid Build Coastguard Worker     netif.UpdateIp6MulticastAddresses(testVec1);
401*4a64e381SAndroid Build Coastguard Worker     std::vector<std::string> wpanMulAddrs = GetAllIp6MulAddrs(wpan);
402*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(wpanMulAddrs.size(), 4);
403*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kMulAddr1Str));
404*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr1Str));
405*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr2Str));
406*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr3Str));
407*4a64e381SAndroid Build Coastguard Worker 
408*4a64e381SAndroid Build Coastguard Worker     otbr::Ip6Address              testArray2[] = {kMulAddr1, kMulAddr2};
409*4a64e381SAndroid Build Coastguard Worker     std::vector<otbr::Ip6Address> testVec2(testArray2, testArray2 + sizeof(testArray2) / sizeof(otbr::Ip6Address));
410*4a64e381SAndroid Build Coastguard Worker     netif.UpdateIp6MulticastAddresses(testVec2);
411*4a64e381SAndroid Build Coastguard Worker     wpanMulAddrs = GetAllIp6MulAddrs(wpan);
412*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(wpanMulAddrs.size(), 5);
413*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kMulAddr1Str));
414*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kMulAddr2Str));
415*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr1Str));
416*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr2Str));
417*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr3Str));
418*4a64e381SAndroid Build Coastguard Worker 
419*4a64e381SAndroid Build Coastguard Worker     otbr::Ip6Address              testArray3[] = {kDefaultMulAddr1};
420*4a64e381SAndroid Build Coastguard Worker     std::vector<otbr::Ip6Address> testVec3(testArray3, testArray3 + sizeof(testArray3) / sizeof(otbr::Ip6Address));
421*4a64e381SAndroid Build Coastguard Worker     netif.UpdateIp6MulticastAddresses(testVec3);
422*4a64e381SAndroid Build Coastguard Worker     wpanMulAddrs = GetAllIp6MulAddrs(wpan);
423*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(wpanMulAddrs.size(), 3);
424*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr1Str));
425*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr2Str));
426*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr3Str));
427*4a64e381SAndroid Build Coastguard Worker 
428*4a64e381SAndroid Build Coastguard Worker     std::vector<otbr::Ip6Address> empty;
429*4a64e381SAndroid Build Coastguard Worker     netif.UpdateIp6MulticastAddresses(empty);
430*4a64e381SAndroid Build Coastguard Worker     wpanMulAddrs = GetAllIp6MulAddrs(wpan);
431*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(wpanMulAddrs.size(), 3);
432*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr1Str));
433*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr2Str));
434*4a64e381SAndroid Build Coastguard Worker     EXPECT_THAT(wpanMulAddrs, ::testing::Contains(kDefaultMulAddr3Str));
435*4a64e381SAndroid Build Coastguard Worker 
436*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
437*4a64e381SAndroid Build Coastguard Worker }
438*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanIfStateChangesCorrectly_AfterSettingNetifState)439*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanIfStateChangesCorrectly_AfterSettingNetifState)
440*4a64e381SAndroid Build Coastguard Worker {
441*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
442*4a64e381SAndroid Build Coastguard Worker     const char *wpan = "wpan0";
443*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init(wpan, Ip6SendEmptyImpl), OTBR_ERROR_NONE);
444*4a64e381SAndroid Build Coastguard Worker 
445*4a64e381SAndroid Build Coastguard Worker     int fd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP, kSocketNonBlock);
446*4a64e381SAndroid Build Coastguard Worker     if (fd < 0)
447*4a64e381SAndroid Build Coastguard Worker     {
448*4a64e381SAndroid Build Coastguard Worker         perror("Failed to create test socket");
449*4a64e381SAndroid Build Coastguard Worker         exit(EXIT_FAILURE);
450*4a64e381SAndroid Build Coastguard Worker     }
451*4a64e381SAndroid Build Coastguard Worker 
452*4a64e381SAndroid Build Coastguard Worker     struct ifreq ifr;
453*4a64e381SAndroid Build Coastguard Worker     memset(&ifr, 0, sizeof(ifr));
454*4a64e381SAndroid Build Coastguard Worker     strncpy(ifr.ifr_name, wpan, IFNAMSIZ - 1);
455*4a64e381SAndroid Build Coastguard Worker 
456*4a64e381SAndroid Build Coastguard Worker     netif.SetNetifState(true);
457*4a64e381SAndroid Build Coastguard Worker     ioctl(fd, SIOCGIFFLAGS, &ifr);
458*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(ifr.ifr_flags & IFF_UP, IFF_UP);
459*4a64e381SAndroid Build Coastguard Worker 
460*4a64e381SAndroid Build Coastguard Worker     netif.SetNetifState(false);
461*4a64e381SAndroid Build Coastguard Worker     ioctl(fd, SIOCGIFFLAGS, &ifr);
462*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(ifr.ifr_flags & IFF_UP, 0);
463*4a64e381SAndroid Build Coastguard Worker 
464*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
465*4a64e381SAndroid Build Coastguard Worker }
466*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanIfRecvIp6PacketCorrectly_AfterReceivingFromNetif)467*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanIfRecvIp6PacketCorrectly_AfterReceivingFromNetif)
468*4a64e381SAndroid Build Coastguard Worker {
469*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
470*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init("wpan0", Ip6SendEmptyImpl), OTBR_ERROR_NONE);
471*4a64e381SAndroid Build Coastguard Worker 
472*4a64e381SAndroid Build Coastguard Worker     const otIp6Address kOmr = {
473*4a64e381SAndroid Build Coastguard Worker         {0xfd, 0x2a, 0xc3, 0x0c, 0x87, 0xd3, 0x00, 0x01, 0xed, 0x1c, 0x0c, 0x91, 0xcc, 0xb6, 0x57, 0x8b}};
474*4a64e381SAndroid Build Coastguard Worker     std::vector<otbr::Ip6AddressInfo> addrs = {
475*4a64e381SAndroid Build Coastguard Worker         {kOmr, 64, 0, 1, 0},
476*4a64e381SAndroid Build Coastguard Worker     };
477*4a64e381SAndroid Build Coastguard Worker     netif.UpdateIp6UnicastAddresses(addrs);
478*4a64e381SAndroid Build Coastguard Worker     netif.SetNetifState(true);
479*4a64e381SAndroid Build Coastguard Worker 
480*4a64e381SAndroid Build Coastguard Worker     // Receive UDP packets on wpan address with specified port.
481*4a64e381SAndroid Build Coastguard Worker     int                 sockFd;
482*4a64e381SAndroid Build Coastguard Worker     const uint16_t      port = 12345;
483*4a64e381SAndroid Build Coastguard Worker     struct sockaddr_in6 listenAddr;
484*4a64e381SAndroid Build Coastguard Worker     const char         *listenIp = "fd2a:c30c:87d3:1:ed1c:c91:ccb6:578b";
485*4a64e381SAndroid Build Coastguard Worker     uint8_t             recvBuf[kMaxIp6Size];
486*4a64e381SAndroid Build Coastguard Worker 
487*4a64e381SAndroid Build Coastguard Worker     if ((sockFd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
488*4a64e381SAndroid Build Coastguard Worker     {
489*4a64e381SAndroid Build Coastguard Worker         perror("socket creation failed");
490*4a64e381SAndroid Build Coastguard Worker         exit(EXIT_FAILURE);
491*4a64e381SAndroid Build Coastguard Worker     }
492*4a64e381SAndroid Build Coastguard Worker 
493*4a64e381SAndroid Build Coastguard Worker     memset(&listenAddr, 0, sizeof(listenAddr));
494*4a64e381SAndroid Build Coastguard Worker     listenAddr.sin6_family = AF_INET6;
495*4a64e381SAndroid Build Coastguard Worker     listenAddr.sin6_port   = htons(port);
496*4a64e381SAndroid Build Coastguard Worker     inet_pton(AF_INET6, listenIp, &(listenAddr.sin6_addr));
497*4a64e381SAndroid Build Coastguard Worker 
498*4a64e381SAndroid Build Coastguard Worker     if (bind(sockFd, (const struct sockaddr *)&listenAddr, sizeof(listenAddr)) < 0)
499*4a64e381SAndroid Build Coastguard Worker     {
500*4a64e381SAndroid Build Coastguard Worker         perror("bind failed");
501*4a64e381SAndroid Build Coastguard Worker         exit(EXIT_FAILURE);
502*4a64e381SAndroid Build Coastguard Worker     }
503*4a64e381SAndroid Build Coastguard Worker 
504*4a64e381SAndroid Build Coastguard Worker     // Udp Packet
505*4a64e381SAndroid Build Coastguard Worker     // Ip6 source: fd2a:c30c:87d3:1:ed1c:c91:ccb6:578a
506*4a64e381SAndroid Build Coastguard Worker     // Ip6 destination: fd2a:c30c:87d3:1:ed1c:c91:ccb6:578b
507*4a64e381SAndroid Build Coastguard Worker     // Udp destination port: 12345
508*4a64e381SAndroid Build Coastguard Worker     // Udp payload: "Hello Otbr Netif!"
509*4a64e381SAndroid Build Coastguard Worker     const uint8_t udpPacket[] = {0x60, 0x0e, 0xea, 0x69, 0x00, 0x19, 0x11, 0x40, 0xfd, 0x2a, 0xc3, 0x0c, 0x87,
510*4a64e381SAndroid Build Coastguard Worker                                  0xd3, 0x00, 0x01, 0xed, 0x1c, 0x0c, 0x91, 0xcc, 0xb6, 0x57, 0x8a, 0xfd, 0x2a,
511*4a64e381SAndroid Build Coastguard Worker                                  0xc3, 0x0c, 0x87, 0xd3, 0x00, 0x01, 0xed, 0x1c, 0x0c, 0x91, 0xcc, 0xb6, 0x57,
512*4a64e381SAndroid Build Coastguard Worker                                  0x8b, 0xe7, 0x08, 0x30, 0x39, 0x00, 0x19, 0x36, 0x81, 0x48, 0x65, 0x6c, 0x6c,
513*4a64e381SAndroid Build Coastguard Worker                                  0x6f, 0x20, 0x4f, 0x74, 0x62, 0x72, 0x20, 0x4e, 0x65, 0x74, 0x69, 0x66, 0x21};
514*4a64e381SAndroid Build Coastguard Worker     netif.Ip6Receive(udpPacket, sizeof(udpPacket));
515*4a64e381SAndroid Build Coastguard Worker 
516*4a64e381SAndroid Build Coastguard Worker     socklen_t   len = sizeof(listenAddr);
517*4a64e381SAndroid Build Coastguard Worker     int         n   = recvfrom(sockFd, (char *)recvBuf, kMaxIp6Size, MSG_WAITALL, (struct sockaddr *)&listenAddr, &len);
518*4a64e381SAndroid Build Coastguard Worker     std::string udpPayload(reinterpret_cast<const char *>(recvBuf), n);
519*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(udpPayload, "Hello Otbr Netif!");
520*4a64e381SAndroid Build Coastguard Worker 
521*4a64e381SAndroid Build Coastguard Worker     close(sockFd);
522*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
523*4a64e381SAndroid Build Coastguard Worker }
524*4a64e381SAndroid Build Coastguard Worker 
TEST(Netif,WpanIfSendIp6PacketCorrectly_AfterReceivingOnIf)525*4a64e381SAndroid Build Coastguard Worker TEST(Netif, WpanIfSendIp6PacketCorrectly_AfterReceivingOnIf)
526*4a64e381SAndroid Build Coastguard Worker {
527*4a64e381SAndroid Build Coastguard Worker     bool        received = false;
528*4a64e381SAndroid Build Coastguard Worker     std::string receivedPayload;
529*4a64e381SAndroid Build Coastguard Worker     const char *hello = "Hello Otbr Netif!";
530*4a64e381SAndroid Build Coastguard Worker 
531*4a64e381SAndroid Build Coastguard Worker     auto Ip6SendTestImpl = [&received, &receivedPayload](const uint8_t *aData, uint16_t aLength) {
532*4a64e381SAndroid Build Coastguard Worker         const ip6_hdr *ipv6_header = reinterpret_cast<const ip6_hdr *>(aData);
533*4a64e381SAndroid Build Coastguard Worker         if (ipv6_header->ip6_nxt == IPPROTO_UDP)
534*4a64e381SAndroid Build Coastguard Worker         {
535*4a64e381SAndroid Build Coastguard Worker             const uint8_t *udpPayload    = aData + aLength - ntohs(ipv6_header->ip6_plen) + sizeof(udphdr);
536*4a64e381SAndroid Build Coastguard Worker             uint16_t       udpPayloadLen = ntohs(ipv6_header->ip6_plen) - sizeof(udphdr);
537*4a64e381SAndroid Build Coastguard Worker             receivedPayload              = std::string(reinterpret_cast<const char *>(udpPayload), udpPayloadLen);
538*4a64e381SAndroid Build Coastguard Worker 
539*4a64e381SAndroid Build Coastguard Worker             received = true;
540*4a64e381SAndroid Build Coastguard Worker         }
541*4a64e381SAndroid Build Coastguard Worker 
542*4a64e381SAndroid Build Coastguard Worker         return OTBR_ERROR_NONE;
543*4a64e381SAndroid Build Coastguard Worker     };
544*4a64e381SAndroid Build Coastguard Worker 
545*4a64e381SAndroid Build Coastguard Worker     otbr::Netif netif;
546*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(netif.Init("wpan0", Ip6SendTestImpl), OT_ERROR_NONE);
547*4a64e381SAndroid Build Coastguard Worker 
548*4a64e381SAndroid Build Coastguard Worker     // OMR Prefix: fd76:a5d1:fcb0:1707::/64
549*4a64e381SAndroid Build Coastguard Worker     const otIp6Address kOmr = {
550*4a64e381SAndroid Build Coastguard Worker         {0xfd, 0x76, 0xa5, 0xd1, 0xfc, 0xb0, 0x17, 0x07, 0xf3, 0xc7, 0xd8, 0x8c, 0xef, 0xd1, 0x24, 0xa9}};
551*4a64e381SAndroid Build Coastguard Worker     std::vector<otbr::Ip6AddressInfo> addrs = {
552*4a64e381SAndroid Build Coastguard Worker         {kOmr, 64, 0, 1, 0},
553*4a64e381SAndroid Build Coastguard Worker     };
554*4a64e381SAndroid Build Coastguard Worker     netif.UpdateIp6UnicastAddresses(addrs);
555*4a64e381SAndroid Build Coastguard Worker     netif.SetNetifState(true);
556*4a64e381SAndroid Build Coastguard Worker 
557*4a64e381SAndroid Build Coastguard Worker     // Send a UDP packet destined to an address with OMR prefix.
558*4a64e381SAndroid Build Coastguard Worker     {
559*4a64e381SAndroid Build Coastguard Worker         int                 sockFd;
560*4a64e381SAndroid Build Coastguard Worker         const uint16_t      destPort = 12345;
561*4a64e381SAndroid Build Coastguard Worker         struct sockaddr_in6 destAddr;
562*4a64e381SAndroid Build Coastguard Worker         const char         *destIp = "fd76:a5d1:fcb0:1707:3f1:47ce:85d3:77f";
563*4a64e381SAndroid Build Coastguard Worker 
564*4a64e381SAndroid Build Coastguard Worker         if ((sockFd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
565*4a64e381SAndroid Build Coastguard Worker         {
566*4a64e381SAndroid Build Coastguard Worker             perror("socket creation failed");
567*4a64e381SAndroid Build Coastguard Worker             exit(EXIT_FAILURE);
568*4a64e381SAndroid Build Coastguard Worker         }
569*4a64e381SAndroid Build Coastguard Worker 
570*4a64e381SAndroid Build Coastguard Worker         memset(&destAddr, 0, sizeof(destAddr));
571*4a64e381SAndroid Build Coastguard Worker         destAddr.sin6_family = AF_INET6;
572*4a64e381SAndroid Build Coastguard Worker         destAddr.sin6_port   = htons(destPort);
573*4a64e381SAndroid Build Coastguard Worker         inet_pton(AF_INET6, destIp, &(destAddr.sin6_addr));
574*4a64e381SAndroid Build Coastguard Worker 
575*4a64e381SAndroid Build Coastguard Worker         if (sendto(sockFd, hello, strlen(hello), MSG_CONFIRM, (const struct sockaddr *)&destAddr, sizeof(destAddr)) < 0)
576*4a64e381SAndroid Build Coastguard Worker         {
577*4a64e381SAndroid Build Coastguard Worker             FAIL() << "Failed to send UDP packet through WPAN interface";
578*4a64e381SAndroid Build Coastguard Worker         }
579*4a64e381SAndroid Build Coastguard Worker         close(sockFd);
580*4a64e381SAndroid Build Coastguard Worker     }
581*4a64e381SAndroid Build Coastguard Worker 
582*4a64e381SAndroid Build Coastguard Worker     otbr::MainloopContext context;
583*4a64e381SAndroid Build Coastguard Worker     while (!received)
584*4a64e381SAndroid Build Coastguard Worker     {
585*4a64e381SAndroid Build Coastguard Worker         context.mMaxFd   = -1;
586*4a64e381SAndroid Build Coastguard Worker         context.mTimeout = {100, 0};
587*4a64e381SAndroid Build Coastguard Worker         FD_ZERO(&context.mReadFdSet);
588*4a64e381SAndroid Build Coastguard Worker         FD_ZERO(&context.mWriteFdSet);
589*4a64e381SAndroid Build Coastguard Worker         FD_ZERO(&context.mErrorFdSet);
590*4a64e381SAndroid Build Coastguard Worker 
591*4a64e381SAndroid Build Coastguard Worker         netif.UpdateFdSet(&context);
592*4a64e381SAndroid Build Coastguard Worker         int rval = select(context.mMaxFd + 1, &context.mReadFdSet, &context.mWriteFdSet, &context.mErrorFdSet,
593*4a64e381SAndroid Build Coastguard Worker                           &context.mTimeout);
594*4a64e381SAndroid Build Coastguard Worker         if (rval < 0)
595*4a64e381SAndroid Build Coastguard Worker         {
596*4a64e381SAndroid Build Coastguard Worker             perror("select failed");
597*4a64e381SAndroid Build Coastguard Worker             exit(EXIT_FAILURE);
598*4a64e381SAndroid Build Coastguard Worker         }
599*4a64e381SAndroid Build Coastguard Worker         netif.Process(&context);
600*4a64e381SAndroid Build Coastguard Worker     }
601*4a64e381SAndroid Build Coastguard Worker 
602*4a64e381SAndroid Build Coastguard Worker     EXPECT_STREQ(receivedPayload.c_str(), hello);
603*4a64e381SAndroid Build Coastguard Worker 
604*4a64e381SAndroid Build Coastguard Worker     netif.Deinit();
605*4a64e381SAndroid Build Coastguard Worker }
606*4a64e381SAndroid Build Coastguard Worker #endif // __linux__
607