1 /*
2  * Copyright 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * clatd_test.cpp - unit tests for clatd
17  */
18 
19 #include <iostream>
20 
21 #include <arpa/inet.h>
22 #include <netinet/in6.h>
23 #include <stdio.h>
24 #include <sys/uio.h>
25 
26 #include <gtest/gtest.h>
27 
28 #include "netutils/ifc.h"
29 #include "tun_interface.h"
30 
31 extern "C" {
32 #include "clatd.h"
33 #include "config.h"
34 #include "getaddr.h"
35 #include "netutils/checksum.h"
36 #include "translate.h"
37 #include "tun.h"
38 }
39 
40 // For convenience.
41 #define ARRAYSIZE(x) sizeof((x)) / sizeof((x)[0])
42 
43 using android::net::TunInterface;
44 
45 // Default translation parameters.
46 static const char kIPv4LocalAddr[]  = "192.0.0.4";
47 static const char kIPv6LocalAddr[]  = "2001:db8:0:b11::464";
48 static const char kIPv6PlatSubnet[] = "64:ff9b::";
49 
50 // clang-format off
51 // Test packet portions. Defined as macros because it's easy to concatenate them to make packets.
52 #define IPV4_HEADER(p, c1, c2) \
53     0x45, 0x00,    0,   41,  /* Version=4, IHL=5, ToS=0x80, len=41 */     \
54     0x00, 0x00, 0x40, 0x00,  /* ID=0x0000, flags=IP_DF, offset=0 */       \
55       55,  (p), (c1), (c2),  /* TTL=55, protocol=p, checksum=c1,c2 */     \
56      192,    0,    0,    4,  /* Src=192.0.0.4 */                          \
57        8,    8,    8,    8,  /* Dst=8.8.8.8 */
58 #define IPV4_UDP_HEADER IPV4_HEADER(IPPROTO_UDP, 0x73, 0xb0)
59 #define IPV4_ICMP_HEADER IPV4_HEADER(IPPROTO_ICMP, 0x73, 0xc0)
60 
61 #define IPV6_HEADER(p) \
62     0x60, 0x00,    0,    0,  /* Version=6, tclass=0x00, flowlabel=0 */    \
63        0,   21,  (p),   55,  /* plen=11, nxthdr=p, hlim=55 */             \
64     0x20, 0x01, 0x0d, 0xb8,  /* Src=2001:db8:0:b11::464 */                \
65     0x00, 0x00, 0x0b, 0x11,                                               \
66     0x00, 0x00, 0x00, 0x00,                                               \
67     0x00, 0x00, 0x04, 0x64,                                               \
68     0x00, 0x64, 0xff, 0x9b,  /* Dst=64:ff9b::8.8.8.8 */                   \
69     0x00, 0x00, 0x00, 0x00,                                               \
70     0x00, 0x00, 0x00, 0x00,                                               \
71     0x08, 0x08, 0x08, 0x08,
72 #define IPV6_UDP_HEADER IPV6_HEADER(IPPROTO_UDP)
73 #define IPV6_ICMPV6_HEADER IPV6_HEADER(IPPROTO_ICMPV6)
74 
75 #define UDP_LEN 21
76 #define UDP_HEADER \
77     0xc8, 0x8b,    0,   53,  /* Port 51339->53 */                         \
78     0x00, UDP_LEN, 0,    0,  /* Length 21, checksum empty for now */
79 
80 #define PAYLOAD 'H', 'e', 'l', 'l', 'o', ' ', 0x4e, 0xb8, 0x96, 0xe7, 0x95, 0x8c, 0x00
81 
82 #define IPV4_PING \
83     0x08, 0x00, 0x88, 0xd0,  /* Type 8, code 0, checksum 0x88d0 */        \
84     0xd0, 0x0d, 0x00, 0x03,  /* ID=0xd00d, seq=3 */
85 
86 #define IPV6_PING \
87     0x80, 0x00, 0xc3, 0x42,  /* Type 128, code 0, checksum 0xc342 */      \
88     0xd0, 0x0d, 0x00, 0x03,  /* ID=0xd00d, seq=3 */
89 
90 // Macros to return pseudo-headers from packets.
91 #define IPV4_PSEUDOHEADER(ip, tlen)                                  \
92   ip[12], ip[13], ip[14], ip[15],        /* Source address      */   \
93   ip[16], ip[17], ip[18], ip[19],        /* Destination address */   \
94   0, ip[9],                              /* 0, protocol         */   \
95   ((tlen) >> 16) & 0xff, (tlen) & 0xff,  /* Transport length */
96 
97 #define IPV6_PSEUDOHEADER(ip6, protocol, tlen)                       \
98   ip6[8],  ip6[9],  ip6[10], ip6[11],  /* Source address */          \
99   ip6[12], ip6[13], ip6[14], ip6[15],                                \
100   ip6[16], ip6[17], ip6[18], ip6[19],                                \
101   ip6[20], ip6[21], ip6[22], ip6[23],                                \
102   ip6[24], ip6[25], ip6[26], ip6[27],  /* Destination address */     \
103   ip6[28], ip6[29], ip6[30], ip6[31],                                \
104   ip6[32], ip6[33], ip6[34], ip6[35],                                \
105   ip6[36], ip6[37], ip6[38], ip6[39],                                \
106   ((tlen) >> 24) & 0xff,               /* Transport length */        \
107   ((tlen) >> 16) & 0xff,                                             \
108   ((tlen) >> 8) & 0xff,                                              \
109   (tlen) & 0xff,                                                     \
110   0, 0, 0, (protocol),
111 
112 // A fragmented DNS request.
113 static const uint8_t kIPv4Frag1[] = {
114     0x45, 0x00, 0x00, 0x24, 0xfe, 0x47, 0x20, 0x00, 0x40, 0x11,
115     0x8c, 0x6d, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
116     0x14, 0x5d, 0x00, 0x35, 0x00, 0x29, 0x68, 0xbb, 0x50, 0x47,
117     0x01, 0x00, 0x00, 0x01, 0x00, 0x00
118 };
119 static const uint8_t kIPv4Frag2[] = {
120     0x45, 0x00, 0x00, 0x24, 0xfe, 0x47, 0x20, 0x02, 0x40, 0x11,
121     0x8c, 0x6b, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
122     0x00, 0x00, 0x00, 0x00, 0x04, 0x69, 0x70, 0x76, 0x34, 0x06,
123     0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65
124 };
125 static const uint8_t kIPv4Frag3[] = {
126     0x45, 0x00, 0x00, 0x1d, 0xfe, 0x47, 0x00, 0x04, 0x40, 0x11,
127     0xac, 0x70, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
128     0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01
129 };
130 static const uint8_t *kIPv4Fragments[] = { kIPv4Frag1, kIPv4Frag2, kIPv4Frag3 };
131 static const size_t kIPv4FragLengths[] = { sizeof(kIPv4Frag1), sizeof(kIPv4Frag2),
132                                            sizeof(kIPv4Frag3) };
133 
134 static const uint8_t kIPv6Frag1[] = {
135     0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0x40, 0x20, 0x01,
136     0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00,
137     0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00,
138     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
139     0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0xfe, 0x47, 0x14, 0x5d,
140     0x00, 0x35, 0x00, 0x29, 0xeb, 0x91, 0x50, 0x47, 0x01, 0x00,
141     0x00, 0x01, 0x00, 0x00
142 };
143 
144 static const uint8_t kIPv6Frag2[] = {
145     0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0x40, 0x20, 0x01,
146     0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00,
147     0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00,
148     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
149     0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0xfe, 0x47, 0x00, 0x00,
150     0x00, 0x00, 0x04, 0x69, 0x70, 0x76, 0x34, 0x06, 0x67, 0x6f,
151     0x6f, 0x67, 0x6c, 0x65
152 };
153 
154 static const uint8_t kIPv6Frag3[] = {
155     0x60, 0x00, 0x00, 0x00, 0x00, 0x11, 0x2c, 0x40, 0x20, 0x01,
156     0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00,
157     0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00,
158     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
159     0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0xfe, 0x47, 0x03, 0x63,
160     0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01
161 };
162 static const uint8_t *kIPv6Fragments[] = { kIPv6Frag1, kIPv6Frag2, kIPv6Frag3 };
163 static const size_t kIPv6FragLengths[] = { sizeof(kIPv6Frag1), sizeof(kIPv6Frag2),
164                                            sizeof(kIPv6Frag3) };
165 
166 static const uint8_t kReassembledIPv4[] = {
167     0x45, 0x00, 0x00, 0x3d, 0xfe, 0x47, 0x00, 0x00, 0x40, 0x11,
168     0xac, 0x54, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08,
169     0x14, 0x5d, 0x00, 0x35, 0x00, 0x29, 0x68, 0xbb, 0x50, 0x47,
170     0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171     0x04, 0x69, 0x70, 0x76, 0x34, 0x06, 0x67, 0x6f, 0x6f, 0x67,
172     0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00,
173     0x01
174 };
175 // clang-format on
176 
177 // Expected checksums.
178 static const uint32_t kUdpPartialChecksum     = 0xd5c8;
179 static const uint32_t kPayloadPartialChecksum = 0x31e9c;
180 static const uint16_t kUdpV4Checksum          = 0xd0c7;
181 static const uint16_t kUdpV6Checksum          = 0xa74a;
182 
ip_version(const uint8_t * packet)183 uint8_t ip_version(const uint8_t *packet) {
184   uint8_t version = packet[0] >> 4;
185   return version;
186 }
187 
is_ipv4_fragment(struct iphdr * ip)188 int is_ipv4_fragment(struct iphdr *ip) {
189   // A packet is a fragment if its fragment offset is nonzero or if the MF flag is set.
190   return ntohs(ip->frag_off) & (IP_OFFMASK | IP_MF);
191 }
192 
is_ipv6_fragment(struct ip6_hdr * ip6,size_t len)193 int is_ipv6_fragment(struct ip6_hdr *ip6, size_t len) {
194   if (ip6->ip6_nxt != IPPROTO_FRAGMENT) {
195     return 0;
196   }
197   struct ip6_frag *frag = (struct ip6_frag *)(ip6 + 1);
198   return len >= sizeof(*ip6) + sizeof(*frag) &&
199          (frag->ip6f_offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG));
200 }
201 
ipv4_fragment_offset(struct iphdr * ip)202 int ipv4_fragment_offset(struct iphdr *ip) {
203   return ntohs(ip->frag_off) & IP_OFFMASK;
204 }
205 
ipv6_fragment_offset(struct ip6_frag * frag)206 int ipv6_fragment_offset(struct ip6_frag *frag) {
207   return ntohs((frag->ip6f_offlg & IP6F_OFF_MASK) >> 3);
208 }
209 
check_packet(const uint8_t * packet,size_t len,const char * msg)210 void check_packet(const uint8_t *packet, size_t len, const char *msg) {
211   void *payload;
212   size_t payload_length    = 0;
213   uint32_t pseudo_checksum = 0;
214   uint8_t protocol         = 0;
215   int version              = ip_version(packet);
216   switch (version) {
217     case 4: {
218       struct iphdr *ip = (struct iphdr *)packet;
219       ASSERT_GE(len, sizeof(*ip)) << msg << ": IPv4 packet shorter than IPv4 header\n";
220       EXPECT_EQ(5, ip->ihl) << msg << ": Unsupported IP header length\n";
221       EXPECT_EQ(len, ntohs(ip->tot_len)) << msg << ": Incorrect IPv4 length\n";
222       EXPECT_EQ(0, ip_checksum(ip, sizeof(*ip))) << msg << ": Incorrect IP checksum\n";
223       protocol = ip->protocol;
224       payload  = ip + 1;
225       if (!is_ipv4_fragment(ip)) {
226         payload_length  = len - sizeof(*ip);
227         pseudo_checksum = ipv4_pseudo_header_checksum(ip, payload_length);
228       }
229       ASSERT_TRUE(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP || protocol == IPPROTO_ICMP)
230         << msg << ": Unsupported IPv4 protocol " << protocol << "\n";
231       break;
232     }
233     case 6: {
234       struct ip6_hdr *ip6 = (struct ip6_hdr *)packet;
235       ASSERT_GE(len, sizeof(*ip6)) << msg << ": IPv6 packet shorter than IPv6 header\n";
236       EXPECT_EQ(len - sizeof(*ip6), htons(ip6->ip6_plen)) << msg << ": Incorrect IPv6 length\n";
237 
238       if (ip6->ip6_nxt == IPPROTO_FRAGMENT) {
239         struct ip6_frag *frag = (struct ip6_frag *)(ip6 + 1);
240         ASSERT_GE(len, sizeof(*ip6) + sizeof(*frag))
241           << msg << ": IPv6 fragment: short fragment header\n";
242         protocol = frag->ip6f_nxt;
243         payload  = frag + 1;
244         // Even though the packet has a Fragment header, it might not be a fragment.
245         if (!is_ipv6_fragment(ip6, len)) {
246           payload_length = len - sizeof(*ip6) - sizeof(*frag);
247         }
248       } else {
249         // Since there are no extension headers except Fragment, this must be the payload.
250         protocol       = ip6->ip6_nxt;
251         payload        = ip6 + 1;
252         payload_length = len - sizeof(*ip6);
253       }
254       ASSERT_TRUE(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP || protocol == IPPROTO_ICMPV6)
255         << msg << ": Unsupported IPv6 next header " << protocol;
256       if (payload_length) {
257         pseudo_checksum = ipv6_pseudo_header_checksum(ip6, payload_length, protocol);
258       }
259       break;
260     }
261     default:
262       FAIL() << msg << ": Unsupported IP version " << version << "\n";
263       return;
264   }
265 
266   // If we understand the payload, verify the checksum.
267   if (payload_length) {
268     uint16_t checksum;
269     switch (protocol) {
270       case IPPROTO_UDP:
271       case IPPROTO_TCP:
272       case IPPROTO_ICMPV6:
273         checksum = ip_checksum_finish(ip_checksum_add(pseudo_checksum, payload, payload_length));
274         break;
275       case IPPROTO_ICMP:
276         checksum = ip_checksum(payload, payload_length);
277         break;
278       default:
279         checksum = 0;  // Don't check.
280         break;
281     }
282     EXPECT_EQ(0, checksum) << msg << ": Incorrect transport checksum\n";
283   }
284 
285   if (protocol == IPPROTO_UDP) {
286     struct udphdr *udp = (struct udphdr *)payload;
287     EXPECT_NE(0, udp->check) << msg << ": UDP checksum 0 should be 0xffff";
288     // If this is not a fragment, check the UDP length field.
289     if (payload_length) {
290       EXPECT_EQ(payload_length, ntohs(udp->len)) << msg << ": Incorrect UDP length\n";
291     }
292   }
293 }
294 
reassemble_packet(const uint8_t ** fragments,const size_t lengths[],int numpackets,uint8_t * reassembled,size_t * reassembled_len,const char * msg)295 void reassemble_packet(const uint8_t **fragments, const size_t lengths[], int numpackets,
296                        uint8_t *reassembled, size_t *reassembled_len, const char *msg) {
297   struct iphdr *ip    = nullptr;
298   struct ip6_hdr *ip6 = nullptr;
299   size_t total_length, pos = 0;
300   uint8_t protocol = 0;
301   uint8_t version  = ip_version(fragments[0]);
302 
303   for (int i = 0; i < numpackets; i++) {
304     const uint8_t *packet = fragments[i];
305     int len               = lengths[i];
306     int headersize, payload_offset;
307 
308     ASSERT_EQ(ip_version(packet), version) << msg << ": Inconsistent fragment versions\n";
309     check_packet(packet, len, "Fragment sanity check");
310 
311     switch (version) {
312       case 4: {
313         struct iphdr *ip_orig = (struct iphdr *)packet;
314         headersize            = sizeof(*ip_orig);
315         ASSERT_TRUE(is_ipv4_fragment(ip_orig))
316           << msg << ": IPv4 fragment #" << i + 1 << " not a fragment\n";
317         ASSERT_EQ(pos, ipv4_fragment_offset(ip_orig) * 8 + ((i != 0) ? sizeof(*ip) : 0))
318           << msg << ": IPv4 fragment #" << i + 1 << ": inconsistent offset\n";
319 
320         headersize     = sizeof(*ip_orig);
321         payload_offset = headersize;
322         if (pos == 0) {
323           ip = (struct iphdr *)reassembled;
324         }
325         break;
326       }
327       case 6: {
328         struct ip6_hdr *ip6_orig = (struct ip6_hdr *)packet;
329         struct ip6_frag *frag    = (struct ip6_frag *)(ip6_orig + 1);
330         ASSERT_TRUE(is_ipv6_fragment(ip6_orig, len))
331           << msg << ": IPv6 fragment #" << i + 1 << " not a fragment\n";
332         ASSERT_EQ(pos, ipv6_fragment_offset(frag) * 8 + ((i != 0) ? sizeof(*ip6) : 0))
333           << msg << ": IPv6 fragment #" << i + 1 << ": inconsistent offset\n";
334 
335         headersize     = sizeof(*ip6_orig);
336         payload_offset = sizeof(*ip6_orig) + sizeof(*frag);
337         if (pos == 0) {
338           ip6      = (struct ip6_hdr *)reassembled;
339           protocol = frag->ip6f_nxt;
340         }
341         break;
342       }
343       default:
344         FAIL() << msg << ": Invalid IP version << " << version;
345     }
346 
347     // If this is the first fragment, copy the header.
348     if (pos == 0) {
349       ASSERT_LT(headersize, (int)*reassembled_len) << msg << ": Reassembly buffer too small\n";
350       memcpy(reassembled, packet, headersize);
351       total_length = headersize;
352       pos += headersize;
353     }
354 
355     // Copy the payload.
356     int payload_length = len - payload_offset;
357     total_length += payload_length;
358     ASSERT_LT(total_length, *reassembled_len) << msg << ": Reassembly buffer too small\n";
359     memcpy(reassembled + pos, packet + payload_offset, payload_length);
360     pos += payload_length;
361   }
362 
363   // Fix up the reassembled headers to reflect fragmentation and length (and IPv4 checksum).
364   ASSERT_EQ(total_length, pos) << msg << ": Reassembled packet length incorrect\n";
365   if (ip) {
366     ip->frag_off &= ~htons(IP_MF);
367     ip->tot_len = htons(total_length);
368     ip->check   = 0;
369     ip->check   = ip_checksum(ip, sizeof(*ip));
370     ASSERT_FALSE(is_ipv4_fragment(ip)) << msg << ": reassembled IPv4 packet is a fragment!\n";
371   }
372   if (ip6) {
373     ip6->ip6_nxt  = protocol;
374     ip6->ip6_plen = htons(total_length - sizeof(*ip6));
375     ASSERT_FALSE(is_ipv6_fragment(ip6, ip6->ip6_plen))
376       << msg << ": reassembled IPv6 packet is a fragment!\n";
377   }
378 
379   *reassembled_len = total_length;
380 }
381 
check_data_matches(const void * expected,const void * actual,size_t len,const char * msg)382 void check_data_matches(const void *expected, const void *actual, size_t len, const char *msg) {
383   if (memcmp(expected, actual, len)) {
384     // Hex dump, 20 bytes per line, one space between bytes (1 byte = 3 chars), indented by 4.
385     int hexdump_len = len * 3 + (len / 20 + 1) * 5;
386     char expected_hexdump[hexdump_len], actual_hexdump[hexdump_len];
387     unsigned pos = 0;
388     for (unsigned i = 0; i < len; i++) {
389       if (i % 20 == 0) {
390         snprintf(expected_hexdump + pos, hexdump_len - pos, "\n   ");
391         snprintf(actual_hexdump + pos, hexdump_len - pos, "\n   ");
392         pos += 4;
393       }
394       snprintf(expected_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *)expected)[i]);
395       snprintf(actual_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *)actual)[i]);
396       pos += 3;
397     }
398     FAIL() << msg << ": Data doesn't match"
399            << "\n  Expected:" << (char *) expected_hexdump
400            << "\n  Actual:" << (char *) actual_hexdump << "\n";
401   }
402 }
403 
fix_udp_checksum(uint8_t * packet)404 void fix_udp_checksum(uint8_t *packet) {
405   uint32_t pseudo_checksum;
406   uint8_t version = ip_version(packet);
407   struct udphdr *udp;
408   switch (version) {
409     case 4: {
410       struct iphdr *ip = (struct iphdr *)packet;
411       udp              = (struct udphdr *)(ip + 1);
412       pseudo_checksum  = ipv4_pseudo_header_checksum(ip, ntohs(udp->len));
413       break;
414     }
415     case 6: {
416       struct ip6_hdr *ip6 = (struct ip6_hdr *)packet;
417       udp                 = (struct udphdr *)(ip6 + 1);
418       pseudo_checksum     = ipv6_pseudo_header_checksum(ip6, ntohs(udp->len), IPPROTO_UDP);
419       break;
420     }
421     default:
422       FAIL() << "unsupported IP version" << version << "\n";
423       return;
424   }
425 
426   udp->check = 0;
427   udp->check = ip_checksum_finish(ip_checksum_add(pseudo_checksum, udp, ntohs(udp->len)));
428 }
429 
430 // Testing stub for send_rawv6. The real version uses sendmsg() with a
431 // destination IPv6 address, and attempting to call that on our test socketpair
432 // fd results in EINVAL.
send_rawv6(int fd,clat_packet out,int iov_len)433 extern "C" void send_rawv6(int fd, clat_packet out, int iov_len) { writev(fd, out, iov_len); }
434 
do_translate_packet(const uint8_t * original,size_t original_len,uint8_t * out,size_t * outlen,const char * msg)435 void do_translate_packet(const uint8_t *original, size_t original_len, uint8_t *out, size_t *outlen,
436                          const char *msg) {
437   int fds[2];
438   if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, fds)) {
439     abort();
440   }
441 
442   char foo[512];
443   snprintf(foo, sizeof(foo), "%s: Invalid original packet", msg);
444   check_packet(original, original_len, foo);
445 
446   int read_fd, write_fd;
447   uint16_t expected_proto;
448   int version = ip_version(original);
449   switch (version) {
450     case 4:
451       expected_proto = htons(ETH_P_IPV6);
452       read_fd        = fds[1];
453       write_fd       = fds[0];
454       break;
455     case 6:
456       expected_proto = htons(ETH_P_IP);
457       read_fd        = fds[0];
458       write_fd       = fds[1];
459       break;
460     default:
461       FAIL() << msg << ": Unsupported IP version " << version << "\n";
462       break;
463   }
464 
465   translate_packet(write_fd, (version == 4), original, original_len);
466 
467   snprintf(foo, sizeof(foo), "%s: Invalid translated packet", msg);
468   if (version == 6) {
469     // Translating to IPv4. Expect a tun header.
470     struct tun_pi new_tun_header;
471     struct iovec iov[] = {
472       { &new_tun_header, sizeof(new_tun_header) },
473       { out, *outlen },
474     };
475 
476     int len = readv(read_fd, iov, 2);
477     if (len > (int)sizeof(new_tun_header)) {
478       ASSERT_LT((size_t)len, *outlen) << msg << ": Translated packet buffer too small\n";
479       EXPECT_EQ(expected_proto, new_tun_header.proto) << msg << "Unexpected tun proto\n";
480       *outlen = len - sizeof(new_tun_header);
481       check_packet(out, *outlen, msg);
482     } else {
483       FAIL() << msg << ": Packet was not translated: len=" << len;
484       *outlen = 0;
485     }
486   } else {
487     // Translating to IPv6. Expect raw packet.
488     *outlen = read(read_fd, out, *outlen);
489     check_packet(out, *outlen, msg);
490   }
491 }
492 
check_translated_packet(const uint8_t * original,size_t original_len,const uint8_t * expected,size_t expected_len,const char * msg)493 void check_translated_packet(const uint8_t *original, size_t original_len, const uint8_t *expected,
494                              size_t expected_len, const char *msg) {
495   uint8_t translated[MAXMTU];
496   size_t translated_len = sizeof(translated);
497   do_translate_packet(original, original_len, translated, &translated_len, msg);
498   EXPECT_EQ(expected_len, translated_len) << msg << ": Translated packet length incorrect\n";
499   check_data_matches(expected, translated, translated_len, msg);
500 }
501 
check_fragment_translation(const uint8_t * original[],const size_t original_lengths[],const uint8_t * expected[],const size_t expected_lengths[],int numfragments,const char * msg)502 void check_fragment_translation(const uint8_t *original[], const size_t original_lengths[],
503                                 const uint8_t *expected[], const size_t expected_lengths[],
504                                 int numfragments, const char *msg) {
505   for (int i = 0; i < numfragments; i++) {
506     // Check that each of the fragments translates as expected.
507     char frag_msg[512];
508     snprintf(frag_msg, sizeof(frag_msg), "%s: fragment #%d", msg, i + 1);
509     check_translated_packet(original[i], original_lengths[i], expected[i], expected_lengths[i],
510                             frag_msg);
511   }
512 
513   // Sanity check that reassembling the original and translated fragments produces valid packets.
514   uint8_t reassembled[MAXMTU];
515   size_t reassembled_len = sizeof(reassembled);
516   reassemble_packet(original, original_lengths, numfragments, reassembled, &reassembled_len, msg);
517   check_packet(reassembled, reassembled_len, msg);
518 
519   uint8_t translated[MAXMTU];
520   size_t translated_len = sizeof(translated);
521   do_translate_packet(reassembled, reassembled_len, translated, &translated_len, msg);
522   check_packet(translated, translated_len, msg);
523 }
524 
get_transport_checksum(const uint8_t * packet)525 int get_transport_checksum(const uint8_t *packet) {
526   struct iphdr *ip;
527   struct ip6_hdr *ip6;
528   uint8_t protocol;
529   const void *payload;
530 
531   int version = ip_version(packet);
532   switch (version) {
533     case 4:
534       ip = (struct iphdr *)packet;
535       if (is_ipv4_fragment(ip)) {
536         return -1;
537       }
538       protocol = ip->protocol;
539       payload  = ip + 1;
540       break;
541     case 6:
542       ip6      = (struct ip6_hdr *)packet;
543       protocol = ip6->ip6_nxt;
544       payload  = ip6 + 1;
545       break;
546     default:
547       return -1;
548   }
549 
550   switch (protocol) {
551     case IPPROTO_UDP:
552       return ((struct udphdr *)payload)->check;
553 
554     case IPPROTO_TCP:
555       return ((struct tcphdr *)payload)->check;
556 
557     case IPPROTO_FRAGMENT:
558     default:
559       return -1;
560   }
561 }
562 
makeTunData()563 static tun_data makeTunData() {
564   // Create some fake but realistic-looking sockets so update_clat_ipv6_address doesn't balk.
565   return {
566     .write_fd6 = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW),
567     .read_fd6  = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)),
568     .fd4       = socket(AF_UNIX, SOCK_DGRAM, 0),
569   };
570 }
571 
freeTunData(tun_data * tunnel)572 void freeTunData(tun_data *tunnel) {
573   close(tunnel->write_fd6);
574   close(tunnel->read_fd6);
575   close(tunnel->fd4);
576 }
577 
578 struct clat_config Global_Clatd_Config;
579 
580 class ClatdTest : public ::testing::Test {
581  protected:
582   static TunInterface sTun;
583 
SetUp()584   virtual void SetUp() {
585     inet_pton(AF_INET, kIPv4LocalAddr, &Global_Clatd_Config.ipv4_local_subnet);
586     inet_pton(AF_INET6, kIPv6PlatSubnet, &Global_Clatd_Config.plat_subnet);
587     memset(&Global_Clatd_Config.ipv6_local_subnet, 0, sizeof(in6_addr));
588     Global_Clatd_Config.ipv6_host_id    = in6addr_any;
589     Global_Clatd_Config.use_dynamic_iid = 1;
590     Global_Clatd_Config.default_pdp_interface = const_cast<char *>(sTun.name().c_str());
591   }
592 
593   // Static because setting up the tun interface takes about 40ms.
SetUpTestCase()594   static void SetUpTestCase() { ASSERT_EQ(0, sTun.init()); }
595 
596   // Closing the socket removes the interface and IP addresses.
TearDownTestCase()597   static void TearDownTestCase() { sTun.destroy(); }
598 };
599 
600 TunInterface ClatdTest::sTun;
601 
expect_ipv6_addr_equal(struct in6_addr * expected,struct in6_addr * actual)602 void expect_ipv6_addr_equal(struct in6_addr *expected, struct in6_addr *actual) {
603   if (!IN6_ARE_ADDR_EQUAL(expected, actual)) {
604     char expected_str[INET6_ADDRSTRLEN], actual_str[INET6_ADDRSTRLEN];
605     inet_ntop(AF_INET6, expected, expected_str, sizeof(expected_str));
606     inet_ntop(AF_INET6, actual, actual_str, sizeof(actual_str));
607     FAIL()
608         << "Unexpected IPv6 address:: "
609         << "\n  Expected: " << expected_str
610         << "\n  Actual:   " << actual_str
611         << "\n";
612   }
613 }
614 
TEST_F(ClatdTest,TestIPv6PrefixEqual)615 TEST_F(ClatdTest, TestIPv6PrefixEqual) {
616   EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.plat_subnet,
617                                 &Global_Clatd_Config.plat_subnet));
618   EXPECT_FALSE(ipv6_prefix_equal(&Global_Clatd_Config.plat_subnet,
619                                  &Global_Clatd_Config.ipv6_local_subnet));
620 
621   struct in6_addr subnet2 = Global_Clatd_Config.ipv6_local_subnet;
622   EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &subnet2));
623   EXPECT_TRUE(ipv6_prefix_equal(&subnet2, &Global_Clatd_Config.ipv6_local_subnet));
624 
625   subnet2.s6_addr[6] = 0xff;
626   EXPECT_FALSE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &subnet2));
627   EXPECT_FALSE(ipv6_prefix_equal(&subnet2, &Global_Clatd_Config.ipv6_local_subnet));
628 }
629 
count_onebits(const void * data,size_t size)630 int count_onebits(const void *data, size_t size) {
631   int onebits = 0;
632   for (size_t pos = 0; pos < size; pos++) {
633     uint8_t *byte = ((uint8_t *)data) + pos;
634     for (int shift = 0; shift < 8; shift++) {
635       onebits += (*byte >> shift) & 1;
636     }
637   }
638   return onebits;
639 }
640 
TEST_F(ClatdTest,TestCountOnebits)641 TEST_F(ClatdTest, TestCountOnebits) {
642   uint64_t i;
643   i = 1;
644   ASSERT_EQ(1, count_onebits(&i, sizeof(i)));
645   i <<= 61;
646   ASSERT_EQ(1, count_onebits(&i, sizeof(i)));
647   i |= ((uint64_t)1 << 33);
648   ASSERT_EQ(2, count_onebits(&i, sizeof(i)));
649   i = 0xf1000202020000f0;
650   ASSERT_EQ(5 + 1 + 1 + 1 + 4, count_onebits(&i, sizeof(i)));
651 }
652 
TEST_F(ClatdTest,TestGenIIDConfigured)653 TEST_F(ClatdTest, TestGenIIDConfigured) {
654   struct in6_addr myaddr, expected;
655   Global_Clatd_Config.use_dynamic_iid = 0;
656   ASSERT_TRUE(inet_pton(AF_INET6, "::bad:ace:d00d", &Global_Clatd_Config.ipv6_host_id));
657   ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:0:bad:ace:d00d", &expected));
658   ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &myaddr));
659   config_generate_local_ipv6_subnet(&myaddr);
660   expect_ipv6_addr_equal(&expected, &myaddr);
661 
662   Global_Clatd_Config.use_dynamic_iid = 1;
663   config_generate_local_ipv6_subnet(&myaddr);
664   EXPECT_FALSE(IN6_ARE_ADDR_EQUAL(&expected, &myaddr));
665 }
666 
TEST_F(ClatdTest,TestGenIIDRandom)667 TEST_F(ClatdTest, TestGenIIDRandom) {
668   struct in6_addr interface_ipv6;
669   ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &interface_ipv6));
670   Global_Clatd_Config.ipv6_host_id = in6addr_any;
671 
672   // Generate a boatload of random IIDs.
673   int onebits       = 0;
674   uint64_t prev_iid = 0;
675   for (int i = 0; i < 100000; i++) {
676     struct in6_addr myaddr = interface_ipv6;
677 
678     config_generate_local_ipv6_subnet(&myaddr);
679 
680     // Check the generated IP address is in the same prefix as the interface IPv6 address.
681     EXPECT_TRUE(ipv6_prefix_equal(&interface_ipv6, &myaddr));
682 
683     // Check that consecutive IIDs are not the same.
684     uint64_t iid = *(uint64_t *)(&myaddr.s6_addr[8]);
685     ASSERT_TRUE(iid != prev_iid)
686         << "Two consecutive random IIDs are the same: "
687         << std::showbase << std::hex
688         << iid << "\n";
689     prev_iid = iid;
690 
691     // Check that the IID is checksum-neutral with the NAT64 prefix and the
692     // local prefix.
693     struct in_addr *ipv4addr     = &Global_Clatd_Config.ipv4_local_subnet;
694     struct in6_addr *plat_subnet = &Global_Clatd_Config.plat_subnet;
695 
696     uint16_t c1 = ip_checksum_finish(ip_checksum_add(0, ipv4addr, sizeof(*ipv4addr)));
697     uint16_t c2 = ip_checksum_finish(ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
698                                      ip_checksum_add(0, &myaddr, sizeof(myaddr)));
699 
700     if (c1 != c2) {
701       char myaddr_str[INET6_ADDRSTRLEN], plat_str[INET6_ADDRSTRLEN], ipv4_str[INET6_ADDRSTRLEN];
702       inet_ntop(AF_INET6, &myaddr, myaddr_str, sizeof(myaddr_str));
703       inet_ntop(AF_INET6, plat_subnet, plat_str, sizeof(plat_str));
704       inet_ntop(AF_INET, ipv4addr, ipv4_str, sizeof(ipv4_str));
705       FAIL()
706           << "Bad IID: " << myaddr_str
707           << " not checksum-neutral with " << ipv4_str << " and " << plat_str
708           << std::showbase << std::hex
709           << "\n  IPv4 checksum: " << c1
710           << "\n  IPv6 checksum: " << c2
711           << "\n";
712     }
713 
714     // Check that IIDs are roughly random and use all the bits by counting the
715     // total number of bits set to 1 in a random sample of 100000 generated IIDs.
716     onebits += count_onebits(&iid, sizeof(iid));
717   }
718   EXPECT_LE(3190000, onebits);
719   EXPECT_GE(3210000, onebits);
720 }
721 
722 extern "C" addr_free_func config_is_ipv4_address_free;
never_free(in_addr_t)723 int never_free(in_addr_t /* addr */) { return 0; }
always_free(in_addr_t)724 int always_free(in_addr_t /* addr */) { return 1; }
only2_free(in_addr_t addr)725 int only2_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 2; }
over6_free(in_addr_t addr)726 int over6_free(in_addr_t addr) { return (ntohl(addr) & 0xff) >= 6; }
only10_free(in_addr_t addr)727 int only10_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 10; }
728 
TEST_F(ClatdTest,SelectIPv4Address)729 TEST_F(ClatdTest, SelectIPv4Address) {
730   struct in_addr addr;
731 
732   inet_pton(AF_INET, kIPv4LocalAddr, &addr);
733 
734   addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
735 
736   // If no addresses are free, return INADDR_NONE.
737   config_is_ipv4_address_free = never_free;
738   EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29));
739   EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 16));
740 
741   // If the configured address is free, pick that. But a prefix that's too big is invalid.
742   config_is_ipv4_address_free = always_free;
743   EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 29));
744   EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 20));
745   EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 15));
746 
747   // A prefix length of 32 works, but anything above it is invalid.
748   EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 32));
749   EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 33));
750 
751   // If another address is free, pick it.
752   config_is_ipv4_address_free = over6_free;
753   EXPECT_EQ(inet_addr("192.0.0.6"), config_select_ipv4_address(&addr, 29));
754 
755   // Check that we wrap around to addresses that are lower than the first address.
756   config_is_ipv4_address_free = only2_free;
757   EXPECT_EQ(inet_addr("192.0.0.2"), config_select_ipv4_address(&addr, 29));
758   EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 30));
759 
760   // If a free address exists outside the prefix, we don't pick it.
761   config_is_ipv4_address_free = only10_free;
762   EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29));
763   EXPECT_EQ(inet_addr("192.0.0.10"), config_select_ipv4_address(&addr, 24));
764 
765   // Now try using the real function which sees if IP addresses are free using bind().
766   // Assume that the machine running the test has the address 127.0.0.1, but not 8.8.8.8.
767   config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
768   addr.s_addr                 = inet_addr("8.8.8.8");
769   EXPECT_EQ(inet_addr("8.8.8.8"), config_select_ipv4_address(&addr, 29));
770 
771   addr.s_addr = inet_addr("127.0.0.1");
772   EXPECT_EQ(inet_addr("127.0.0.2"), config_select_ipv4_address(&addr, 29));
773 }
774 
TEST_F(ClatdTest,ConfigureTunIp)775 TEST_F(ClatdTest, ConfigureTunIp) {
776   addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
777   config_is_ipv4_address_free                     = over6_free;
778 
779   Global_Clatd_Config.ipv4_local_prefixlen = 29;
780   Global_Clatd_Config.ipv4mtu              = 1472;
781 
782   // Create an interface for configure_tun_ip to configure and bring up.
783   TunInterface v4Iface;
784   ASSERT_EQ(0, v4Iface.init());
785   struct tun_data tunnel = makeTunData();
786   strlcpy(tunnel.device4, v4Iface.name().c_str(), sizeof(tunnel.device4));
787 
788   configure_tun_ip(&tunnel, nullptr /* v4_addr */);
789   EXPECT_EQ(inet_addr("192.0.0.6"), Global_Clatd_Config.ipv4_local_subnet.s_addr);
790 
791   union anyip *ip = getinterface_ip(v4Iface.name().c_str(), AF_INET);
792   EXPECT_EQ(inet_addr("192.0.0.6"), ip->ip4.s_addr);
793   free(ip);
794 
795   config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
796   v4Iface.destroy();
797 }
798 
TEST_F(ClatdTest,ConfigureTunIpManual)799 TEST_F(ClatdTest, ConfigureTunIpManual) {
800   addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
801   config_is_ipv4_address_free                     = over6_free;
802 
803   Global_Clatd_Config.ipv4_local_prefixlen = 29;
804   Global_Clatd_Config.ipv4mtu              = 1472;
805 
806   // Create an interface for configure_tun_ip to configure and bring up.
807   TunInterface v4Iface;
808   ASSERT_EQ(0, v4Iface.init());
809   struct tun_data tunnel = makeTunData();
810   strlcpy(tunnel.device4, v4Iface.name().c_str(), sizeof(tunnel.device4));
811 
812   configure_tun_ip(&tunnel, "192.0.2.1" /* v4_addr */);
813   EXPECT_EQ(inet_addr("192.0.2.1"), Global_Clatd_Config.ipv4_local_subnet.s_addr);
814 
815   union anyip *ip = getinterface_ip(v4Iface.name().c_str(), AF_INET);
816   ASSERT_NE(nullptr, ip);
817   EXPECT_EQ(inet_addr("192.0.2.1"), ip->ip4.s_addr);
818   free(ip);
819 
820   config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
821   v4Iface.destroy();
822 }
823 
TEST_F(ClatdTest,DataSanitycheck)824 TEST_F(ClatdTest, DataSanitycheck) {
825   // Sanity checks the data.
826   uint8_t v4_header[] = { IPV4_UDP_HEADER };
827   ASSERT_EQ(sizeof(struct iphdr), sizeof(v4_header)) << "Test IPv4 header: incorrect length\n";
828 
829   uint8_t v6_header[] = { IPV6_UDP_HEADER };
830   ASSERT_EQ(sizeof(struct ip6_hdr), sizeof(v6_header)) << "Test IPv6 header: incorrect length\n";
831 
832   uint8_t udp_header[] = { UDP_HEADER };
833   ASSERT_EQ(sizeof(struct udphdr), sizeof(udp_header)) << "Test UDP header: incorrect length\n";
834 
835   // Sanity checks check_packet.
836   struct udphdr *udp;
837   uint8_t v4_udp_packet[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD };
838   udp                     = (struct udphdr *)(v4_udp_packet + sizeof(struct iphdr));
839   fix_udp_checksum(v4_udp_packet);
840   ASSERT_EQ(kUdpV4Checksum, udp->check) << "UDP/IPv4 packet checksum sanity check\n";
841   check_packet(v4_udp_packet, sizeof(v4_udp_packet), "UDP/IPv4 packet sanity check");
842 
843   uint8_t v6_udp_packet[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD };
844   udp                     = (struct udphdr *)(v6_udp_packet + sizeof(struct ip6_hdr));
845   fix_udp_checksum(v6_udp_packet);
846   ASSERT_EQ(kUdpV6Checksum, udp->check) << "UDP/IPv6 packet checksum sanity check\n";
847   check_packet(v6_udp_packet, sizeof(v6_udp_packet), "UDP/IPv6 packet sanity check");
848 
849   uint8_t ipv4_ping[] = { IPV4_ICMP_HEADER IPV4_PING PAYLOAD };
850   check_packet(ipv4_ping, sizeof(ipv4_ping), "IPv4 ping sanity check");
851 
852   uint8_t ipv6_ping[] = { IPV6_ICMPV6_HEADER IPV6_PING PAYLOAD };
853   check_packet(ipv6_ping, sizeof(ipv6_ping), "IPv6 ping sanity check");
854 
855   // Sanity checks reassemble_packet.
856   uint8_t reassembled[MAXMTU];
857   size_t total_length = sizeof(reassembled);
858   reassemble_packet(kIPv4Fragments, kIPv4FragLengths, ARRAYSIZE(kIPv4Fragments), reassembled,
859                     &total_length, "Reassembly sanity check");
860   check_packet(reassembled, total_length, "IPv4 Reassembled packet is valid");
861   ASSERT_EQ(sizeof(kReassembledIPv4), total_length) << "IPv4 reassembly sanity check: length\n";
862   ASSERT_TRUE(!is_ipv4_fragment((struct iphdr *)reassembled))
863     << "Sanity check: reassembled packet is a fragment!\n";
864   check_data_matches(kReassembledIPv4, reassembled, total_length, "IPv4 reassembly sanity check");
865 
866   total_length = sizeof(reassembled);
867   reassemble_packet(kIPv6Fragments, kIPv6FragLengths, ARRAYSIZE(kIPv6Fragments), reassembled,
868                     &total_length, "IPv6 reassembly sanity check");
869   ASSERT_TRUE(!is_ipv6_fragment((struct ip6_hdr *)reassembled, total_length))
870     << "Sanity check: reassembled packet is a fragment!\n";
871   check_packet(reassembled, total_length, "IPv6 Reassembled packet is valid");
872 }
873 
TEST_F(ClatdTest,PseudoChecksum)874 TEST_F(ClatdTest, PseudoChecksum) {
875   uint32_t pseudo_checksum;
876 
877   uint8_t v4_header[]        = { IPV4_UDP_HEADER };
878   uint8_t v4_pseudo_header[] = { IPV4_PSEUDOHEADER(v4_header, UDP_LEN) };
879   pseudo_checksum            = ipv4_pseudo_header_checksum((struct iphdr *)v4_header, UDP_LEN);
880   EXPECT_EQ(ip_checksum_finish(pseudo_checksum),
881             ip_checksum(v4_pseudo_header, sizeof(v4_pseudo_header)))
882     << "ipv4_pseudo_header_checksum incorrect\n";
883 
884   uint8_t v6_header[]        = { IPV6_UDP_HEADER };
885   uint8_t v6_pseudo_header[] = { IPV6_PSEUDOHEADER(v6_header, IPPROTO_UDP, UDP_LEN) };
886   pseudo_checksum = ipv6_pseudo_header_checksum((struct ip6_hdr *)v6_header, UDP_LEN, IPPROTO_UDP);
887   EXPECT_EQ(ip_checksum_finish(pseudo_checksum),
888             ip_checksum(v6_pseudo_header, sizeof(v6_pseudo_header)))
889     << "ipv6_pseudo_header_checksum incorrect\n";
890 }
891 
TEST_F(ClatdTest,TransportChecksum)892 TEST_F(ClatdTest, TransportChecksum) {
893   uint8_t udphdr[]  = { UDP_HEADER };
894   uint8_t payload[] = { PAYLOAD };
895   EXPECT_EQ(kUdpPartialChecksum, ip_checksum_add(0, udphdr, sizeof(udphdr)))
896     << "UDP partial checksum\n";
897   EXPECT_EQ(kPayloadPartialChecksum, ip_checksum_add(0, payload, sizeof(payload)))
898     << "Payload partial checksum\n";
899 
900   uint8_t ip[]             = { IPV4_UDP_HEADER };
901   uint8_t ip6[]            = { IPV6_UDP_HEADER };
902   uint32_t ipv4_pseudo_sum = ipv4_pseudo_header_checksum((struct iphdr *)ip, UDP_LEN);
903   uint32_t ipv6_pseudo_sum =
904     ipv6_pseudo_header_checksum((struct ip6_hdr *)ip6, UDP_LEN, IPPROTO_UDP);
905 
906   EXPECT_EQ(0x3ad0U, ipv4_pseudo_sum) << "IPv4 pseudo-checksum sanity check\n";
907   EXPECT_EQ(0x2644bU, ipv6_pseudo_sum) << "IPv6 pseudo-checksum sanity check\n";
908   EXPECT_EQ(
909       kUdpV4Checksum,
910       ip_checksum_finish(ipv4_pseudo_sum + kUdpPartialChecksum + kPayloadPartialChecksum))
911       << "Unexpected UDP/IPv4 checksum\n";
912   EXPECT_EQ(
913       kUdpV6Checksum,
914       ip_checksum_finish(ipv6_pseudo_sum + kUdpPartialChecksum + kPayloadPartialChecksum))
915       << "Unexpected UDP/IPv6 checksum\n";
916 
917   EXPECT_EQ(kUdpV6Checksum,
918       ip_checksum_adjust(kUdpV4Checksum, ipv4_pseudo_sum, ipv6_pseudo_sum))
919       << "Adjust IPv4/UDP checksum to IPv6\n";
920   EXPECT_EQ(kUdpV4Checksum,
921       ip_checksum_adjust(kUdpV6Checksum, ipv6_pseudo_sum, ipv4_pseudo_sum))
922       << "Adjust IPv6/UDP checksum to IPv4\n";
923 }
924 
TEST_F(ClatdTest,AdjustChecksum)925 TEST_F(ClatdTest, AdjustChecksum) {
926   struct checksum_data {
927     uint16_t checksum;
928     uint32_t old_hdr_sum;
929     uint32_t new_hdr_sum;
930     uint16_t result;
931   } DATA[] = {
932     { 0x1423, 0xb8ec, 0x2d757, 0xf5b5 },
933     { 0xf5b5, 0x2d757, 0xb8ec, 0x1423 },
934     { 0xdd2f, 0x5555, 0x3285, 0x0000 },
935     { 0x1215, 0x5560, 0x15560 + 20, 0x1200 },
936     { 0xd0c7, 0x3ad0, 0x2644b, 0xa74a },
937   };
938   unsigned i = 0;
939 
940   for (i = 0; i < ARRAYSIZE(DATA); i++) {
941     struct checksum_data *data = DATA + i;
942     uint16_t result = ip_checksum_adjust(data->checksum, data->old_hdr_sum, data->new_hdr_sum);
943     EXPECT_EQ(result, data->result)
944         << "Incorrect checksum" << std::showbase << std::hex
945         << "\n  Expected: " << data->result
946         << "\n  Actual:   " << result
947         << "\n    checksum=" << data->checksum
948         << " old_sum=" << data->old_hdr_sum << " new_sum=" << data->new_hdr_sum << "\n";
949   }
950 }
951 
TEST_F(ClatdTest,Translate)952 TEST_F(ClatdTest, Translate) {
953   // This test uses hardcoded packets so the clatd address must be fixed.
954   inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet);
955 
956   uint8_t udp_ipv4[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD };
957   uint8_t udp_ipv6[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD };
958   fix_udp_checksum(udp_ipv4);
959   fix_udp_checksum(udp_ipv6);
960   check_translated_packet(udp_ipv4, sizeof(udp_ipv4), udp_ipv6, sizeof(udp_ipv6),
961                           "UDP/IPv4 -> UDP/IPv6 translation");
962   check_translated_packet(udp_ipv6, sizeof(udp_ipv6), udp_ipv4, sizeof(udp_ipv4),
963                           "UDP/IPv6 -> UDP/IPv4 translation");
964 
965   uint8_t ipv4_ping[] = { IPV4_ICMP_HEADER IPV4_PING PAYLOAD };
966   uint8_t ipv6_ping[] = { IPV6_ICMPV6_HEADER IPV6_PING PAYLOAD };
967   check_translated_packet(ipv4_ping, sizeof(ipv4_ping), ipv6_ping, sizeof(ipv6_ping),
968                           "ICMP->ICMPv6 translation");
969   check_translated_packet(ipv6_ping, sizeof(ipv6_ping), ipv4_ping, sizeof(ipv4_ping),
970                           "ICMPv6->ICMP translation");
971 }
972 
TEST_F(ClatdTest,Fragmentation)973 TEST_F(ClatdTest, Fragmentation) {
974   // This test uses hardcoded packets so the clatd address must be fixed.
975   inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet);
976 
977   check_fragment_translation(kIPv4Fragments, kIPv4FragLengths, kIPv6Fragments, kIPv6FragLengths,
978                              ARRAYSIZE(kIPv4Fragments), "IPv4->IPv6 fragment translation");
979 
980   check_fragment_translation(kIPv6Fragments, kIPv6FragLengths, kIPv4Fragments, kIPv4FragLengths,
981                              ARRAYSIZE(kIPv6Fragments), "IPv6->IPv4 fragment translation");
982 }
983 
check_translate_checksum_neutral(const uint8_t * original,size_t original_len,size_t expected_len,const char * msg)984 void check_translate_checksum_neutral(const uint8_t *original, size_t original_len,
985                                       size_t expected_len, const char *msg) {
986   uint8_t translated[MAXMTU];
987   size_t translated_len = sizeof(translated);
988   do_translate_packet(original, original_len, translated, &translated_len, msg);
989   EXPECT_EQ(expected_len, translated_len) << msg << ": Translated packet length incorrect\n";
990   // do_translate_packet already checks packets for validity and verifies the checksum.
991   int original_check   = get_transport_checksum(original);
992   int translated_check = get_transport_checksum(translated);
993   ASSERT_NE(-1, original_check);
994   ASSERT_NE(-1, translated_check);
995   ASSERT_EQ(original_check, translated_check)
996     << "Not checksum neutral: original and translated checksums differ\n";
997 }
998 
TEST_F(ClatdTest,TranslateChecksumNeutral)999 TEST_F(ClatdTest, TranslateChecksumNeutral) {
1000   // Generate a random clat IPv6 address and check that translation is checksum-neutral.
1001   Global_Clatd_Config.ipv6_host_id = in6addr_any;
1002   ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54",
1003                         &Global_Clatd_Config.ipv6_local_subnet));
1004   config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet);
1005   ASSERT_NE(htonl((uint32_t)0x00000464), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
1006   ASSERT_NE((uint32_t)0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
1007 
1008   // Check that translating UDP packets is checksum-neutral. First, IPv4.
1009   uint8_t udp_ipv4[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD };
1010   fix_udp_checksum(udp_ipv4);
1011   check_translate_checksum_neutral(udp_ipv4, sizeof(udp_ipv4), sizeof(udp_ipv4) + 20,
1012                                    "UDP/IPv4 -> UDP/IPv6 checksum neutral");
1013 
1014   // Now try IPv6.
1015   uint8_t udp_ipv6[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD };
1016   // The test packet uses the static IID, not the random IID. Fix up the source address.
1017   struct ip6_hdr *ip6 = (struct ip6_hdr *)udp_ipv6;
1018   memcpy(&ip6->ip6_src, &Global_Clatd_Config.ipv6_local_subnet, sizeof(ip6->ip6_src));
1019   fix_udp_checksum(udp_ipv6);
1020   check_translate_checksum_neutral(udp_ipv4, sizeof(udp_ipv4), sizeof(udp_ipv4) + 20,
1021                                    "UDP/IPv4 -> UDP/IPv6 checksum neutral");
1022 }
1023 
TEST_F(ClatdTest,GetInterfaceIp)1024 TEST_F(ClatdTest, GetInterfaceIp) {
1025   union anyip *ip = getinterface_ip(sTun.name().c_str(), AF_INET6);
1026   ASSERT_NE(nullptr, ip);
1027   in6_addr expected = sTun.srcAddr();
1028   in6_addr actual   = ip->ip6;
1029   expect_ipv6_addr_equal(&expected, &actual);
1030 }
1031 
expectSocketBound(int ifindex,int sock)1032 void expectSocketBound(int ifindex, int sock) {
1033   // Check that the packet socket is bound to the interface. We can't check the socket filter
1034   // because there is no way to fetch it from the kernel.
1035   sockaddr_ll sll;
1036   socklen_t len = sizeof(sll);
1037   ASSERT_EQ(0, getsockname(sock, reinterpret_cast<sockaddr *>(&sll), &len));
1038   EXPECT_EQ(htons(ETH_P_IPV6), sll.sll_protocol);
1039   EXPECT_EQ(ifindex, sll.sll_ifindex);
1040 }
1041 
TEST_F(ClatdTest,ConfigureIpv6Address)1042 TEST_F(ClatdTest, ConfigureIpv6Address) {
1043   struct tun_data tunnel = makeTunData();
1044 
1045   // Run configure_clat_ipv6_address.
1046   ASSERT_TRUE(IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_local_subnet));
1047   ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, sTun.name().c_str(), nullptr /* v6_addr */));
1048 
1049   // Check that it generated an IID in the same prefix as the address assigned to the interface,
1050   // and that the IID is not the default IID.
1051   in6_addr addr = sTun.srcAddr();
1052   EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &addr));
1053   EXPECT_FALSE(IN6_ARE_ADDR_EQUAL(&Global_Clatd_Config.ipv6_local_subnet, &addr));
1054   EXPECT_NE(htonl((uint32_t)0x00000464), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
1055   EXPECT_NE((uint32_t)0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
1056 
1057   expectSocketBound(sTun.ifindex(), tunnel.read_fd6);
1058 
1059   freeTunData(&tunnel);
1060 }
1061 
TEST_F(ClatdTest,ConfigureIpv6AddressCommandLine)1062 TEST_F(ClatdTest, ConfigureIpv6AddressCommandLine) {
1063   struct tun_data tunnel = makeTunData();
1064 
1065   ASSERT_TRUE(IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_local_subnet));
1066 
1067   const char *addrStr = "2001:db8::f00";
1068   in6_addr addr;
1069   ASSERT_EQ(1, inet_pton(AF_INET6, addrStr, &addr));
1070   ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, sTun.name().c_str(), addrStr));
1071 
1072   EXPECT_EQ(htonl(0x20010db8), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[0]);
1073   EXPECT_EQ(htonl(0x00000000), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[1]);
1074   EXPECT_EQ(htonl(0x00000000), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[2]);
1075   EXPECT_EQ(htonl(0x00000f00), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
1076 
1077   // Check that the packet socket is bound to the interface. We can't check the socket filter
1078   // because there is no way to fetch it from the kernel.
1079   sockaddr_ll sll;
1080   socklen_t len = sizeof(sll);
1081   ASSERT_EQ(0, getsockname(tunnel.read_fd6, reinterpret_cast<sockaddr *>(&sll), &len));
1082   EXPECT_EQ(htons(ETH_P_IPV6), sll.sll_protocol);
1083   EXPECT_EQ(sll.sll_ifindex, sTun.ifindex());
1084 
1085   expectSocketBound(sTun.ifindex(), tunnel.read_fd6);
1086 
1087   freeTunData(&tunnel);
1088 }
1089 
TEST_F(ClatdTest,Ipv6AddressChanged)1090 TEST_F(ClatdTest, Ipv6AddressChanged) {
1091   // Configure the clat IPv6 address.
1092   struct tun_data tunnel = {
1093     .write_fd6 = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW),
1094     .read_fd6  = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)),
1095   };
1096   const char *ifname = sTun.name().c_str();
1097   ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, ifname, nullptr));
1098   EXPECT_EQ(0, ipv6_address_changed(ifname));
1099   EXPECT_EQ(0, ipv6_address_changed(ifname));
1100 
1101   // Change the IP address on the tun interface to a new prefix.
1102   char srcaddr[INET6_ADDRSTRLEN];
1103   char dstaddr[INET6_ADDRSTRLEN];
1104   ASSERT_NE(nullptr, inet_ntop(AF_INET6, &sTun.srcAddr(), srcaddr, sizeof(srcaddr)));
1105   ASSERT_NE(nullptr, inet_ntop(AF_INET6, &sTun.dstAddr(), dstaddr, sizeof(dstaddr)));
1106   EXPECT_EQ(0, ifc_del_address(ifname, srcaddr, 64));
1107   EXPECT_EQ(0, ifc_del_address(ifname, dstaddr, 64));
1108 
1109   // Check that we can tell that the address has changed.
1110   EXPECT_EQ(0, ifc_add_address(ifname, "2001:db8::1:2", 64));
1111   EXPECT_EQ(1, ipv6_address_changed(ifname));
1112   EXPECT_EQ(1, ipv6_address_changed(ifname));
1113 
1114   // Restore the tun interface configuration.
1115   sTun.destroy();
1116   ASSERT_EQ(0, sTun.init());
1117 }
1118