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