1f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti/* 2f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * Copyright 2014 The Android Open Source Project 3f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * 4f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * Licensed under the Apache License, Version 2.0 (the "License"); 5f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * you may not use this file except in compliance with the License. 6f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * You may obtain a copy of the License at 7f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * 8f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * http://www.apache.org/licenses/LICENSE-2.0 9f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * 10f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * Unless required by applicable law or agreed to in writing, software 11f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * distributed under the License is distributed on an "AS IS" BASIS, 12f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * See the License for the specific language governing permissions and 14f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * limitations under the License. 15f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * 16f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti * clatd_test.cpp - unit tests for clatd 17f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti */ 18f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 19f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#include <iostream> 20f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 21f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#include <stdio.h> 22f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#include <arpa/inet.h> 239808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti#include <netinet/in6.h> 24f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#include <sys/uio.h> 25f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 26f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#include <gtest/gtest.h> 27f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 28f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittiextern "C" { 29f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#include "checksum.h" 30f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#include "translate.h" 31f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#include "config.h" 32f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#include "clatd.h" 33f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 34f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 35f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti// For convenience. 36f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define ARRAYSIZE(x) sizeof((x)) / sizeof((x)[0]) 37f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 38f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti// Default translation parameters. 39f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittistatic const char kIPv4LocalAddr[] = "192.0.0.4"; 40f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittistatic const char kIPv6LocalAddr[] = "2001:db8:0:b11::464"; 41f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittistatic const char kIPv6PlatSubnet[] = "64:ff9b::"; 42f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 43f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti// Test packet portions. Defined as macros because it's easy to concatenate them to make packets. 44f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define IPV4_HEADER(p, c1, c2) \ 45f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x45, 0x00, 0, 41, /* Version=4, IHL=5, ToS=0x80, len=41 */ \ 46f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x40, 0x00, /* ID=0x0000, flags=IP_DF, offset=0 */ \ 47f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 55, (p), (c1), (c2), /* TTL=55, protocol=p, checksum=c1,c2 */ \ 48f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 192, 0, 0, 4, /* Src=192.0.0.4 */ \ 49f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 8, 8, 8, 8, /* Dst=8.8.8.8 */ 50f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define IPV4_UDP_HEADER IPV4_HEADER(IPPROTO_UDP, 0x73, 0xb0) 51f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define IPV4_ICMP_HEADER IPV4_HEADER(IPPROTO_ICMP, 0x73, 0xc0) 52f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 53f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define IPV6_HEADER(p) \ 54f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x60, 0x00, 0, 0, /* Version=6, tclass=0x00, flowlabel=0 */ \ 55f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0, 21, (p), 55, /* plen=11, nxthdr=p, hlim=55 */ \ 56f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x20, 0x01, 0x0d, 0xb8, /* Src=2001:db8:0:b11::464 */ \ 57f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x0b, 0x11, \ 58f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x00, 0x00, \ 59f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x04, 0x64, \ 60f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x64, 0xff, 0x9b, /* Dst=64:ff9b::8.8.8.8 */ \ 61f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x00, 0x00, \ 62f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x00, 0x00, \ 63f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x08, 0x08, 0x08, 0x08, 64f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define IPV6_UDP_HEADER IPV6_HEADER(IPPROTO_UDP) 65f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define IPV6_ICMPV6_HEADER IPV6_HEADER(IPPROTO_ICMPV6) 66f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 67f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define UDP_LEN 21 68f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define UDP_HEADER \ 69f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0xc8, 0x8b, 0, 53, /* Port 51339->53 */ \ 70f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, UDP_LEN, 0, 0, /* Length 21, checksum empty for now */ 71f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 72f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define PAYLOAD 'H', 'e', 'l', 'l', 'o', ' ', 0x4e, 0xb8, 0x96, 0xe7, 0x95, 0x8c, 0x00 73f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 74f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define IPV4_PING \ 75f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x08, 0x00, 0x88, 0xd0, /* Type 8, code 0, checksum 0x88d0 */ \ 76f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0xd0, 0x0d, 0x00, 0x03, /* ID=0xd00d, seq=3 */ 77f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 78f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define IPV6_PING \ 79f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x80, 0x00, 0xc3, 0x42, /* Type 128, code 0, checksum 0xc342 */ \ 80f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0xd0, 0x0d, 0x00, 0x03, /* ID=0xd00d, seq=3 */ 81f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 82f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti// Macros to return pseudo-headers from packets. 83f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define IPV4_PSEUDOHEADER(ip, tlen) \ 84f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip[12], ip[13], ip[14], ip[15], /* Source address */ \ 85f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip[16], ip[17], ip[18], ip[19], /* Destination address */ \ 86f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0, ip[9], /* 0, protocol */ \ 87f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ((tlen) >> 16) & 0xff, (tlen) & 0xff, /* Transport length */ 88f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 89f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti#define IPV6_PSEUDOHEADER(ip6, protocol, tlen) \ 90f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6[8], ip6[9], ip6[10], ip6[11], /* Source address */ \ 91f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6[12], ip6[13], ip6[14], ip6[15], \ 92f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6[16], ip6[17], ip6[18], ip6[19], \ 93f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6[20], ip6[21], ip6[22], ip6[23], \ 94f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6[24], ip6[25], ip6[26], ip6[27], /* Destination address */ \ 95f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6[28], ip6[29], ip6[30], ip6[31], \ 96f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6[32], ip6[33], ip6[34], ip6[35], \ 97f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6[36], ip6[37], ip6[38], ip6[39], \ 98f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ((tlen) >> 24) & 0xff, /* Transport length */ \ 99f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ((tlen) >> 16) & 0xff, \ 100f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ((tlen) >> 8) & 0xff, \ 101f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti (tlen) & 0xff, \ 102f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0, 0, 0, (protocol), 103f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 104f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti// A fragmented DNS request. 105fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const uint8_t kIPv4Frag1[] = { 106f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x45, 0x00, 0x00, 0x24, 0xfe, 0x47, 0x20, 0x00, 0x40, 0x11, 107f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x8c, 0x6d, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 108f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x14, 0x5d, 0x00, 0x35, 0x00, 0x29, 0x68, 0xbb, 0x50, 0x47, 109f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x01, 0x00, 0x00, 0x01, 0x00, 0x00 110f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti}; 111fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const uint8_t kIPv4Frag2[] = { 112f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x45, 0x00, 0x00, 0x24, 0xfe, 0x47, 0x20, 0x02, 0x40, 0x11, 113f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x8c, 0x6b, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 114f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x00, 0x00, 0x04, 0x69, 0x70, 0x76, 0x34, 0x06, 115f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65 116f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti}; 117fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const uint8_t kIPv4Frag3[] = { 118f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x45, 0x00, 0x00, 0x1d, 0xfe, 0x47, 0x00, 0x04, 0x40, 0x11, 119f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0xac, 0x70, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 120f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 121f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti}; 122fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const uint8_t *kIPv4Fragments[] = { kIPv4Frag1, kIPv4Frag2, kIPv4Frag3 }; 123fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const size_t kIPv4FragLengths[] = { sizeof(kIPv4Frag1), sizeof(kIPv4Frag2), 124fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom sizeof(kIPv4Frag3) }; 125f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 126fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const uint8_t kIPv6Frag1[] = { 127f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0x40, 0x20, 0x01, 128f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00, 129f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 130f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 131f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0xfe, 0x47, 0x14, 0x5d, 132f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x35, 0x00, 0x29, 0xeb, 0x91, 0x50, 0x47, 0x01, 0x00, 133f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x01, 0x00, 0x00 134f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti}; 135f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 136fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const uint8_t kIPv6Frag2[] = { 137f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x60, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0x40, 0x20, 0x01, 138f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00, 139f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 140f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 141f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0xfe, 0x47, 0x00, 0x00, 142f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x04, 0x69, 0x70, 0x76, 0x34, 0x06, 0x67, 0x6f, 143f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x6f, 0x67, 0x6c, 0x65 144f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti}; 145f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 146fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const uint8_t kIPv6Frag3[] = { 147f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x60, 0x00, 0x00, 0x00, 0x00, 0x11, 0x2c, 0x40, 0x20, 0x01, 148f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x0d, 0xb8, 0x00, 0x00, 0x0b, 0x11, 0x00, 0x00, 0x00, 0x00, 149f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x04, 0x64, 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 150f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 151f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0xfe, 0x47, 0x03, 0x63, 152f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 153f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti}; 154fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const uint8_t *kIPv6Fragments[] = { kIPv6Frag1, kIPv6Frag2, kIPv6Frag3 }; 155fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const size_t kIPv6FragLengths[] = { sizeof(kIPv6Frag1), sizeof(kIPv6Frag2), 156fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom sizeof(kIPv6Frag3) }; 157f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 158fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromstatic const uint8_t kReassembledIPv4[] = { 159f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x45, 0x00, 0x00, 0x3d, 0xfe, 0x47, 0x00, 0x00, 0x40, 0x11, 160f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0xac, 0x54, 0xc0, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 161f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x14, 0x5d, 0x00, 0x35, 0x00, 0x29, 0x68, 0xbb, 0x50, 0x47, 162f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 163f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x04, 0x69, 0x70, 0x76, 0x34, 0x06, 0x67, 0x6f, 0x6f, 0x67, 164f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 165f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 0x01 166f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti}; 167f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 168f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti// Expected checksums. 169f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittistatic const uint32_t kUdpPartialChecksum = 0xd5c8; 170f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittistatic const uint32_t kPayloadPartialChecksum = 0x31e9c; 171f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittistatic const uint16_t kUdpV4Checksum = 0xd0c7; 172f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittistatic const uint16_t kUdpV6Checksum = 0xa74a; 173f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 174fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromuint8_t ip_version(const uint8_t *packet) { 175fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t version = packet[0] >> 4; 176f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti return version; 177f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 178f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 179f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittiint is_ipv4_fragment(struct iphdr *ip) { 180f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // A packet is a fragment if its fragment offset is nonzero or if the MF flag is set. 181f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti return ntohs(ip->frag_off) & (IP_OFFMASK | IP_MF); 182f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 183f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 184f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittiint is_ipv6_fragment(struct ip6_hdr *ip6, size_t len) { 185f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (ip6->ip6_nxt != IPPROTO_FRAGMENT) { 186f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti return 0; 187f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 188f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct ip6_frag *frag = (struct ip6_frag *) (ip6 + 1); 189f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti return len >= sizeof(*ip6) + sizeof(*frag) && 190f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti (frag->ip6f_offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG)); 191f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 192f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 193f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittiint ipv4_fragment_offset(struct iphdr *ip) { 194f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti return ntohs(ip->frag_off) & IP_OFFMASK; 195f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 196f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 197f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittiint ipv6_fragment_offset(struct ip6_frag *frag) { 198f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti return ntohs((frag->ip6f_offlg & IP6F_OFF_MASK) >> 3); 199f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 200f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 201fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromvoid check_packet(const uint8_t *packet, size_t len, const char *msg) { 202f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti void *payload; 203f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti size_t payload_length = 0; 204f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint32_t pseudo_checksum = 0; 205f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint8_t protocol = 0; 206f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti int version = ip_version(packet); 207f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti switch (version) { 208f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case 4: { 209f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct iphdr *ip = (struct iphdr *) packet; 210f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_GE(len, sizeof(*ip)) << msg << ": IPv4 packet shorter than IPv4 header\n"; 211f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(5, ip->ihl) << msg << ": Unsupported IP header length\n"; 212f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(len, ntohs(ip->tot_len)) << msg << ": Incorrect IPv4 length\n"; 213f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(0, ip_checksum(ip, sizeof(*ip))) << msg << ": Incorrect IP checksum\n"; 214f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti protocol = ip->protocol; 215f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti payload = ip + 1; 216f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (!is_ipv4_fragment(ip)) { 217f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti payload_length = len - sizeof(*ip); 218f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti pseudo_checksum = ipv4_pseudo_header_checksum(ip, payload_length); 219f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 220f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_TRUE(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP || protocol == IPPROTO_ICMP) 221f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << msg << ": Unsupported IPv4 protocol " << protocol << "\n"; 222f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 223f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 224f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case 6: { 225f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct ip6_hdr *ip6 = (struct ip6_hdr *) packet; 226f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_GE(len, sizeof(*ip6)) << msg << ": IPv6 packet shorter than IPv6 header\n"; 227f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(len - sizeof(*ip6), htons(ip6->ip6_plen)) << msg << ": Incorrect IPv6 length\n"; 228f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 229f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (ip6->ip6_nxt == IPPROTO_FRAGMENT) { 230f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct ip6_frag *frag = (struct ip6_frag *) (ip6 + 1); 231f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_GE(len, sizeof(*ip6) + sizeof(*frag)) 232f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << msg << ": IPv6 fragment: short fragment header\n"; 233f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti protocol = frag->ip6f_nxt; 234f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti payload = frag + 1; 235f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // Even though the packet has a Fragment header, it might not be a fragment. 236f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (!is_ipv6_fragment(ip6, len)) { 237f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti payload_length = len - sizeof(*ip6) - sizeof(*frag); 238f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 239f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } else { 240f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // Since there are no extension headers except Fragment, this must be the payload. 241f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti protocol = ip6->ip6_nxt; 242f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti payload = ip6 + 1; 243f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti payload_length = len - sizeof(*ip6); 244f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 245f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_TRUE(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP || protocol == IPPROTO_ICMPV6) 246f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << msg << ": Unsupported IPv6 next header " << protocol; 247f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (payload_length) { 248f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti pseudo_checksum = ipv6_pseudo_header_checksum(ip6, payload_length, protocol); 249f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 250f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 251f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 252f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti default: 253f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti FAIL() << msg << ": Unsupported IP version " << version << "\n"; 254f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti return; 255f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 256f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 257f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // If we understand the payload, verify the checksum. 258f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (payload_length) { 259f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint16_t checksum; 260f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti switch(protocol) { 261f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case IPPROTO_UDP: 262f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case IPPROTO_TCP: 263f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case IPPROTO_ICMPV6: 264f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti checksum = ip_checksum_finish(ip_checksum_add(pseudo_checksum, payload, payload_length)); 265f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 266f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case IPPROTO_ICMP: 267f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti checksum = ip_checksum(payload, payload_length); 268f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 269f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti default: 270f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti checksum = 0; // Don't check. 271f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 272f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 273f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(0, checksum) << msg << ": Incorrect transport checksum\n"; 274f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 275f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 276f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (protocol == IPPROTO_UDP) { 277f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct udphdr *udp = (struct udphdr *) payload; 278f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_NE(0, udp->check) << msg << ": UDP checksum 0 should be 0xffff"; 279f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // If this is not a fragment, check the UDP length field. 280f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (payload_length) { 281f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(payload_length, ntohs(udp->len)) << msg << ": Incorrect UDP length\n"; 282f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 283f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 284f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 285f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 286fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromvoid reassemble_packet(const uint8_t **fragments, const size_t lengths[], int numpackets, 287fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t *reassembled, size_t *reassembled_len, const char *msg) { 288f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct iphdr *ip = NULL; 289f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct ip6_hdr *ip6 = NULL; 290932614ee5e740704d7ef951dff6daede4fe12904Ben Cheng size_t total_length, pos = 0; 291932614ee5e740704d7ef951dff6daede4fe12904Ben Cheng uint8_t protocol = 0; 292fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t version = ip_version(fragments[0]); 293f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 294f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti for (int i = 0; i < numpackets; i++) { 295fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom const uint8_t *packet = fragments[i]; 296f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti int len = lengths[i]; 297f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti int headersize, payload_offset; 298f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 299f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_EQ(ip_version(packet), version) << msg << ": Inconsistent fragment versions\n"; 300f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_packet(packet, len, "Fragment sanity check"); 301f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 302f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti switch (version) { 303f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case 4: { 304f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct iphdr *ip_orig = (struct iphdr *) packet; 305f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti headersize = sizeof(*ip_orig); 306f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_TRUE(is_ipv4_fragment(ip_orig)) 307f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << msg << ": IPv4 fragment #" << i + 1 << " not a fragment\n"; 308f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_EQ(pos, ipv4_fragment_offset(ip_orig) * 8 + ((i != 0) ? sizeof(*ip): 0)) 309f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << msg << ": IPv4 fragment #" << i + 1 << ": inconsistent offset\n"; 310f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 311f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti headersize = sizeof(*ip_orig); 312f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti payload_offset = headersize; 313f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (pos == 0) { 314f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip = (struct iphdr *) reassembled; 315f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 316f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 317f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 318f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case 6: { 319f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct ip6_hdr *ip6_orig = (struct ip6_hdr *) packet; 320f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct ip6_frag *frag = (struct ip6_frag *) (ip6_orig + 1); 321f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_TRUE(is_ipv6_fragment(ip6_orig, len)) 322f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << msg << ": IPv6 fragment #" << i + 1 << " not a fragment\n"; 323f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_EQ(pos, ipv6_fragment_offset(frag) * 8 + ((i != 0) ? sizeof(*ip6): 0)) 324f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << msg << ": IPv6 fragment #" << i + 1 << ": inconsistent offset\n"; 325f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 326f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti headersize = sizeof(*ip6_orig); 327f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti payload_offset = sizeof(*ip6_orig) + sizeof(*frag); 328f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (pos == 0) { 329f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6 = (struct ip6_hdr *) reassembled; 330f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti protocol = frag->ip6f_nxt; 331f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 332f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 333f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 334f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti default: 335f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti FAIL() << msg << ": Invalid IP version << " << version; 336f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 337f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 338f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // If this is the first fragment, copy the header. 339f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (pos == 0) { 340f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_LT(headersize, (int) *reassembled_len) << msg << ": Reassembly buffer too small\n"; 341f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti memcpy(reassembled, packet, headersize); 342f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti total_length = headersize; 343f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti pos += headersize; 344f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 345f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 346f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // Copy the payload. 347f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti int payload_length = len - payload_offset; 348f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti total_length += payload_length; 349932614ee5e740704d7ef951dff6daede4fe12904Ben Cheng ASSERT_LT(total_length, *reassembled_len) << msg << ": Reassembly buffer too small\n"; 350f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti memcpy(reassembled + pos, packet + payload_offset, payload_length); 351f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti pos += payload_length; 352f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 353f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 354f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 355f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // Fix up the reassembled headers to reflect fragmentation and length (and IPv4 checksum). 356f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_EQ(total_length, pos) << msg << ": Reassembled packet length incorrect\n"; 357f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (ip) { 358f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip->frag_off &= ~htons(IP_MF); 359f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip->tot_len = htons(total_length); 360f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip->check = 0; 361f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip->check = ip_checksum(ip, sizeof(*ip)); 362f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_FALSE(is_ipv4_fragment(ip)) << msg << ": reassembled IPv4 packet is a fragment!\n"; 363f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 364f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (ip6) { 365f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6->ip6_nxt = protocol; 366f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip6->ip6_plen = htons(total_length - sizeof(*ip6)); 367f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_FALSE(is_ipv6_fragment(ip6, ip6->ip6_plen)) 368f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << msg << ": reassembled IPv6 packet is a fragment!\n"; 369f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 370f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 371f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti *reassembled_len = total_length; 372f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 373f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 3749808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colittivoid check_data_matches(const void *expected, const void *actual, size_t len, const char *msg) { 375f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (memcmp(expected, actual, len)) { 376f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // Hex dump, 20 bytes per line, one space between bytes (1 byte = 3 chars), indented by 4. 377f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti int hexdump_len = len * 3 + (len / 20 + 1) * 5; 378f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti char expected_hexdump[hexdump_len], actual_hexdump[hexdump_len]; 379f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti unsigned pos = 0; 380f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti for (unsigned i = 0; i < len; i++) { 381f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (i % 20 == 0) { 3822dcca6feb91fd917e26c4989af6400de904466a2George Burgess IV snprintf(expected_hexdump + pos, hexdump_len - pos, "\n "); 3832dcca6feb91fd917e26c4989af6400de904466a2George Burgess IV snprintf(actual_hexdump + pos, hexdump_len - pos, "\n "); 384f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti pos += 4; 385f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 3862dcca6feb91fd917e26c4989af6400de904466a2George Burgess IV snprintf(expected_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *) expected)[i]); 3872dcca6feb91fd917e26c4989af6400de904466a2George Burgess IV snprintf(actual_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *) actual)[i]); 388f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti pos += 3; 389f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 3909808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti FAIL() << msg << ": Data doesn't match" 391f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "\n Expected:" << (char *) expected_hexdump 392f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "\n Actual:" << (char *) actual_hexdump << "\n"; 393f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 394f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 395f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 396fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromvoid fix_udp_checksum(uint8_t* packet) { 397f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint32_t pseudo_checksum; 398fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t version = ip_version(packet); 399f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct udphdr *udp; 400f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti switch (version) { 401f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case 4: { 402f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct iphdr *ip = (struct iphdr *) packet; 403f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti udp = (struct udphdr *) (ip + 1); 404f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti pseudo_checksum = ipv4_pseudo_header_checksum(ip, ntohs(udp->len)); 405f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 406f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 407f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case 6: { 408f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct ip6_hdr *ip6 = (struct ip6_hdr *) packet; 409f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti udp = (struct udphdr *) (ip6 + 1); 410f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti pseudo_checksum = ipv6_pseudo_header_checksum(ip6, ntohs(udp->len), IPPROTO_UDP); 411f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 412f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 413f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti default: 414f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti FAIL() << "unsupported IP version" << version << "\n"; 415f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti return; 416f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 417f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 418f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti udp->check = 0; 419f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti udp->check = ip_checksum_finish(ip_checksum_add(pseudo_checksum, udp, ntohs(udp->len))); 420f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 421f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 422ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti// Testing stub for send_rawv6. The real version uses sendmsg() with a 423ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti// destination IPv6 address, and attempting to call that on our test socketpair 424ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti// fd results in EINVAL. 425ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colittiextern "C" void send_rawv6(int fd, clat_packet out, int iov_len) { 426ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti writev(fd, out, iov_len); 427ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti} 428ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti 429fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromvoid do_translate_packet(const uint8_t *original, size_t original_len, uint8_t *out, size_t *outlen, 430f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti const char *msg) { 431f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti int fds[2]; 432f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, fds)) { 433f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti abort(); 434f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 435f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 436f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti char foo[512]; 437f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti snprintf(foo, sizeof(foo), "%s: Invalid original packet", msg); 438f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_packet(original, original_len, foo); 439f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 440e24982ea3a4480d9d62c75b4d9a416b9479f7f0bLorenzo Colitti int read_fd, write_fd; 441f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint16_t expected_proto; 442f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti int version = ip_version(original); 443f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti switch (version) { 444f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case 4: 445f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti expected_proto = htons(ETH_P_IPV6); 446f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti read_fd = fds[1]; 447e24982ea3a4480d9d62c75b4d9a416b9479f7f0bLorenzo Colitti write_fd = fds[0]; 448f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 449f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti case 6: 450f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti expected_proto = htons(ETH_P_IP); 451f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti read_fd = fds[0]; 452e24982ea3a4480d9d62c75b4d9a416b9479f7f0bLorenzo Colitti write_fd = fds[1]; 453f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 454f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti default: 455f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti FAIL() << msg << ": Unsupported IP version " << version << "\n"; 456f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti break; 457f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 458f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 459e24982ea3a4480d9d62c75b4d9a416b9479f7f0bLorenzo Colitti translate_packet(write_fd, (version == 4), original, original_len); 460f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 4619808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti snprintf(foo, sizeof(foo), "%s: Invalid translated packet", msg); 462ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti if (version == 6) { 463ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti // Translating to IPv4. Expect a tun header. 464ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti struct tun_pi new_tun_header; 465ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti struct iovec iov[] = { 466ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti { &new_tun_header, sizeof(new_tun_header) }, 467ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti { out, *outlen } 468ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti }; 469ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti int len = readv(read_fd, iov, 2); 470ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti if (len > (int) sizeof(new_tun_header)) { 471ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti ASSERT_LT((size_t) len, *outlen) << msg << ": Translated packet buffer too small\n"; 472ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti EXPECT_EQ(expected_proto, new_tun_header.proto) << msg << "Unexpected tun proto\n"; 473ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti *outlen = len - sizeof(new_tun_header); 4749808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti check_packet(out, *outlen, msg); 475ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti } else { 4769808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti FAIL() << msg << ": Packet was not translated: len=" << len; 477ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti *outlen = 0; 478ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti } 479f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } else { 480ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti // Translating to IPv6. Expect raw packet. 481ce14088b80c2d22add83a616e567f9025d252ef7Lorenzo Colitti *outlen = read(read_fd, out, *outlen); 4829808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti check_packet(out, *outlen, msg); 483f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 484f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 485f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 486fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromvoid check_translated_packet(const uint8_t *original, size_t original_len, 487fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom const uint8_t *expected, size_t expected_len, const char *msg) { 488fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t translated[MAXMTU]; 489f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti size_t translated_len = sizeof(translated); 490f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti do_translate_packet(original, original_len, translated, &translated_len, msg); 491f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(expected_len, translated_len) << msg << ": Translated packet length incorrect\n"; 492f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_data_matches(expected, translated, translated_len, msg); 493f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 494f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 495fcac410fa15613873a07143ccd46470b869346a3Brian Carlstromvoid check_fragment_translation(const uint8_t *original[], const size_t original_lengths[], 496fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom const uint8_t *expected[], const size_t expected_lengths[], 497f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti int numfragments, const char *msg) { 498f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti for (int i = 0; i < numfragments; i++) { 499f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // Check that each of the fragments translates as expected. 500f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti char frag_msg[512]; 501f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti snprintf(frag_msg, sizeof(frag_msg), "%s: fragment #%d", msg, i + 1); 502f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_translated_packet(original[i], original_lengths[i], 503f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti expected[i], expected_lengths[i], frag_msg); 504f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 505f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 506f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // Sanity check that reassembling the original and translated fragments produces valid packets. 507fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t reassembled[MAXMTU]; 508f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti size_t reassembled_len = sizeof(reassembled); 509f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti reassemble_packet(original, original_lengths, numfragments, reassembled, &reassembled_len, msg); 510f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_packet(reassembled, reassembled_len, msg); 511f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 512fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t translated[MAXMTU]; 513f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti size_t translated_len = sizeof(translated); 514f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti do_translate_packet(reassembled, reassembled_len, translated, &translated_len, msg); 515f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_packet(translated, translated_len, msg); 516f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 517f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 5189808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colittiint get_transport_checksum(const uint8_t *packet) { 5199808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti struct iphdr *ip; 5209808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti struct ip6_hdr *ip6; 5219808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti uint8_t protocol; 5229808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti const void *payload; 5239808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 5249808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti int version = ip_version(packet); 5259808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti switch (version) { 5269808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti case 4: 5279808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ip = (struct iphdr *) packet; 5289808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti if (is_ipv4_fragment(ip)) { 5299808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti return -1; 5309808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti } 5319808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti protocol = ip->protocol; 5329808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti payload = ip + 1; 5339808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti break; 5349808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti case 6: 5359808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ip6 = (struct ip6_hdr *) packet; 5369808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti protocol = ip6->ip6_nxt; 5379808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti payload = ip6 + 1; 5389808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti break; 5399808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti default: 5409808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti return -1; 5419808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti } 5429808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 5439808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti switch (protocol) { 5449808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti case IPPROTO_UDP: 5459808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti return ((struct udphdr *) payload)->check; 5469808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 5479808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti case IPPROTO_TCP: 5489808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti return ((struct tcphdr *) payload)->check; 5499808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 5509808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti case IPPROTO_FRAGMENT: 5519808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti default: 5529808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti return -1; 5539808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti } 5549808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti} 5559808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 556f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colittistruct clat_config Global_Clatd_Config; 557f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 558f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitticlass ClatdTest : public ::testing::Test { 559f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti protected: 560f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti virtual void SetUp() { 561f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti inet_pton(AF_INET, kIPv4LocalAddr, &Global_Clatd_Config.ipv4_local_subnet); 562f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti inet_pton(AF_INET6, kIPv6PlatSubnet, &Global_Clatd_Config.plat_subnet); 563f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet); 5649808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti Global_Clatd_Config.ipv6_host_id = in6addr_any; 5652596f42a4f4c42bfb96ccbfc2700dbf70502ec75Lorenzo Colitti Global_Clatd_Config.use_dynamic_iid = 1; 566f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 567f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti}; 568f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 5699808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colittivoid expect_ipv6_addr_equal(struct in6_addr *expected, struct in6_addr *actual) { 5709808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti if (!IN6_ARE_ADDR_EQUAL(expected, actual)) { 5719808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti char expected_str[INET6_ADDRSTRLEN], actual_str[INET6_ADDRSTRLEN]; 5729808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti inet_ntop(AF_INET6, expected, expected_str, sizeof(expected_str)); 5739808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti inet_ntop(AF_INET6, actual, actual_str, sizeof(actual_str)); 5749808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti FAIL() 5759808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << "Unexpected IPv6 address:: " 5769808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << "\n Expected: " << expected_str 5779808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << "\n Actual: " << actual_str 5789808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << "\n"; 5799808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti } 5809808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti} 5819808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 5829808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo ColittiTEST_F(ClatdTest, TestIPv6PrefixEqual) { 5839808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.plat_subnet, 5849808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti &Global_Clatd_Config.plat_subnet)); 5859808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti EXPECT_FALSE(ipv6_prefix_equal(&Global_Clatd_Config.plat_subnet, 5869808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti &Global_Clatd_Config.ipv6_local_subnet)); 5879808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 5889808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti struct in6_addr subnet2 = Global_Clatd_Config.ipv6_local_subnet; 5899808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti EXPECT_TRUE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &subnet2)); 5909808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti EXPECT_TRUE(ipv6_prefix_equal(&subnet2, &Global_Clatd_Config.ipv6_local_subnet)); 5919808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 5929808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti subnet2.s6_addr[6] = 0xff; 5939808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti EXPECT_FALSE(ipv6_prefix_equal(&Global_Clatd_Config.ipv6_local_subnet, &subnet2)); 5949808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti EXPECT_FALSE(ipv6_prefix_equal(&subnet2, &Global_Clatd_Config.ipv6_local_subnet)); 5959808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti} 5969808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 5979808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colittiint count_onebits(const void *data, size_t size) { 5989808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti int onebits = 0; 5999808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti for (size_t pos = 0; pos < size; pos++) { 6009808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti uint8_t *byte = ((uint8_t*) data) + pos; 6019808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti for (int shift = 0; shift < 8; shift++) { 6029808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti onebits += (*byte >> shift) & 1; 6039808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti } 6049808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti } 6059808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti return onebits; 6069808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti} 6079808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6089808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo ColittiTEST_F(ClatdTest, TestCountOnebits) { 6099808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti uint64_t i; 6109808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti i = 1; 6119808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_EQ(1, count_onebits(&i, sizeof(i))); 6129808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti i <<= 61; 6139808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_EQ(1, count_onebits(&i, sizeof(i))); 6149808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti i |= ((uint64_t) 1 << 33); 6159808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_EQ(2, count_onebits(&i, sizeof(i))); 6169808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti i = 0xf1000202020000f0; 6179808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_EQ(5 + 1 + 1 + 1 + 4, count_onebits(&i, sizeof(i))); 6189808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti} 6199808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6209808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo ColittiTEST_F(ClatdTest, TestGenIIDConfigured) { 6219808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti struct in6_addr myaddr, expected; 6222596f42a4f4c42bfb96ccbfc2700dbf70502ec75Lorenzo Colitti Global_Clatd_Config.use_dynamic_iid = 0; 6239808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_TRUE(inet_pton(AF_INET6, "::bad:ace:d00d", &Global_Clatd_Config.ipv6_host_id)); 6249808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:0:bad:ace:d00d", &expected)); 6259808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &myaddr)); 6269808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti config_generate_local_ipv6_subnet(&myaddr); 6279808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti expect_ipv6_addr_equal(&expected, &myaddr); 6282596f42a4f4c42bfb96ccbfc2700dbf70502ec75Lorenzo Colitti 6292596f42a4f4c42bfb96ccbfc2700dbf70502ec75Lorenzo Colitti Global_Clatd_Config.use_dynamic_iid = 1; 6302596f42a4f4c42bfb96ccbfc2700dbf70502ec75Lorenzo Colitti config_generate_local_ipv6_subnet(&myaddr); 6312596f42a4f4c42bfb96ccbfc2700dbf70502ec75Lorenzo Colitti EXPECT_FALSE(IN6_ARE_ADDR_EQUAL(&expected, &myaddr)); 6329808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti} 6339808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6349808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo ColittiTEST_F(ClatdTest, TestGenIIDRandom) { 6359808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti struct in6_addr interface_ipv6; 6369808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &interface_ipv6)); 6379808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti Global_Clatd_Config.ipv6_host_id = in6addr_any; 6389808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6399808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // Generate a boatload of random IIDs. 6409808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti int onebits = 0; 6419808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti uint64_t prev_iid = 0; 6429808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti for (int i = 0; i < 100000; i++) { 6439808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti struct in6_addr myaddr = interface_ipv6; 6449808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6459808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti config_generate_local_ipv6_subnet(&myaddr); 6469808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6479808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // Check the generated IP address is in the same prefix as the interface IPv6 address. 6489808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti EXPECT_TRUE(ipv6_prefix_equal(&interface_ipv6, &myaddr)); 6499808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6509808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // Check that consecutive IIDs are not the same. 6519808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti uint64_t iid = * (uint64_t*) (&myaddr.s6_addr[8]); 6529808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_TRUE(iid != prev_iid) 6539808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << "Two consecutive random IIDs are the same: " 6549808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << std::showbase << std::hex 6559808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << iid << "\n"; 6569808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti prev_iid = iid; 6579808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6589808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // Check that the IID is checksum-neutral with the NAT64 prefix and the 6599808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // local prefix. 6609808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti struct in_addr *ipv4addr = &Global_Clatd_Config.ipv4_local_subnet; 6619808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti struct in6_addr *plat_subnet = &Global_Clatd_Config.plat_subnet; 6629808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6639808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti uint16_t c1 = ip_checksum_finish(ip_checksum_add(0, ipv4addr, sizeof(*ipv4addr))); 6649808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti uint16_t c2 = ip_checksum_finish(ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) + 6659808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ip_checksum_add(0, &myaddr, sizeof(myaddr))); 6669808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6679808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti if (c1 != c2) { 6689808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti char myaddr_str[INET6_ADDRSTRLEN], plat_str[INET6_ADDRSTRLEN], ipv4_str[INET6_ADDRSTRLEN]; 6699808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti inet_ntop(AF_INET6, &myaddr, myaddr_str, sizeof(myaddr_str)); 6709808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti inet_ntop(AF_INET6, plat_subnet, plat_str, sizeof(plat_str)); 6719808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti inet_ntop(AF_INET, ipv4addr, ipv4_str, sizeof(ipv4_str)); 6729808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti FAIL() 6739808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << "Bad IID: " << myaddr_str 6749808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << " not checksum-neutral with " << ipv4_str << " and " << plat_str 6759808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << std::showbase << std::hex 6769808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << "\n IPv4 checksum: " << c1 6779808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << "\n IPv6 checksum: " << c2 6789808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << "\n"; 6799808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti } 6809808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 6819808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // Check that IIDs are roughly random and use all the bits by counting the 6829808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // total number of bits set to 1 in a random sample of 100000 generated IIDs. 6839808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti onebits += count_onebits(&iid, sizeof(iid)); 6849808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti } 6859808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti EXPECT_LE(3190000, onebits); 6869808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti EXPECT_GE(3210000, onebits); 6879808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti} 6889808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 689798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colittiextern "C" addr_free_func config_is_ipv4_address_free; 690798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colittiint never_free(in_addr_t /* addr */) { return 0; } 691798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colittiint always_free(in_addr_t /* addr */) { return 1; } 692798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colittiint only2_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 2; } 693798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colittiint over6_free(in_addr_t addr) { return (ntohl(addr) & 0xff) >= 6; } 694798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colittiint only10_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 10; } 695798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 696798f9934fca523dfb57136bd185cf6e9460323adLorenzo ColittiTEST_F(ClatdTest, SelectIPv4Address) { 697798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti struct in_addr addr; 698798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 699798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti inet_pton(AF_INET, kIPv4LocalAddr, &addr); 700798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 701798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free; 702798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 703798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti // If no addresses are free, return INADDR_NONE. 704798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti config_is_ipv4_address_free = never_free; 705798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29)); 706798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 16)); 707798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 708798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti // If the configured address is free, pick that. But a prefix that's too big is invalid. 709798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti config_is_ipv4_address_free = always_free; 710798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 29)); 711798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 20)); 712798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 15)); 713798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 714798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti // A prefix length of 32 works, but anything above it is invalid. 715798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 32)); 716798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 33)); 717798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 718798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti // If another address is free, pick it. 719798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti config_is_ipv4_address_free = over6_free; 720798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(inet_addr("192.0.0.6"), config_select_ipv4_address(&addr, 29)); 721798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 722798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti // Check that we wrap around to addresses that are lower than the first address. 723798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti config_is_ipv4_address_free = only2_free; 724798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(inet_addr("192.0.0.2"), config_select_ipv4_address(&addr, 29)); 725798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 30)); 726798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 727798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti // If a free address exists outside the prefix, we don't pick it. 728798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti config_is_ipv4_address_free = only10_free; 729798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29)); 730798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(inet_addr("192.0.0.10"), config_select_ipv4_address(&addr, 24)); 731798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 732798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti // Now try using the real function which sees if IP addresses are free using bind(). 733798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti // Assume that the machine running the test has the address 127.0.0.1, but not 8.8.8.8. 734798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti config_is_ipv4_address_free = orig_config_is_ipv4_address_free; 735798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti addr.s_addr = inet_addr("8.8.8.8"); 736798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(inet_addr("8.8.8.8"), config_select_ipv4_address(&addr, 29)); 737798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 738798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti addr.s_addr = inet_addr("127.0.0.1"); 739798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti EXPECT_EQ(inet_addr("127.0.0.2"), config_select_ipv4_address(&addr, 29)); 740798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti} 741798f9934fca523dfb57136bd185cf6e9460323adLorenzo Colitti 7429808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo ColittiTEST_F(ClatdTest, DataSanitycheck) { 743f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // Sanity checks the data. 744fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t v4_header[] = { IPV4_UDP_HEADER }; 745f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_EQ(sizeof(struct iphdr), sizeof(v4_header)) << "Test IPv4 header: incorrect length\n"; 746f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 747fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t v6_header[] = { IPV6_UDP_HEADER }; 748f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_EQ(sizeof(struct ip6_hdr), sizeof(v6_header)) << "Test IPv6 header: incorrect length\n"; 749f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 750fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t udp_header[] = { UDP_HEADER }; 751f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_EQ(sizeof(struct udphdr), sizeof(udp_header)) << "Test UDP header: incorrect length\n"; 752f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 753f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // Sanity checks check_packet. 754f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct udphdr *udp; 755fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t v4_udp_packet[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD }; 756f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti udp = (struct udphdr *) (v4_udp_packet + sizeof(struct iphdr)); 757f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti fix_udp_checksum(v4_udp_packet); 758f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_EQ(kUdpV4Checksum, udp->check) << "UDP/IPv4 packet checksum sanity check\n"; 759f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_packet(v4_udp_packet, sizeof(v4_udp_packet), "UDP/IPv4 packet sanity check"); 760f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 761fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t v6_udp_packet[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD }; 762f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti udp = (struct udphdr *) (v6_udp_packet + sizeof(struct ip6_hdr)); 763f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti fix_udp_checksum(v6_udp_packet); 764f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_EQ(kUdpV6Checksum, udp->check) << "UDP/IPv6 packet checksum sanity check\n"; 765f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_packet(v6_udp_packet, sizeof(v6_udp_packet), "UDP/IPv6 packet sanity check"); 766f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 767fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t ipv4_ping[] = { IPV4_ICMP_HEADER IPV4_PING PAYLOAD }; 768f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_packet(ipv4_ping, sizeof(ipv4_ping), "IPv4 ping sanity check"); 769f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 770fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t ipv6_ping[] = { IPV6_ICMPV6_HEADER IPV6_PING PAYLOAD }; 771f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_packet(ipv6_ping, sizeof(ipv6_ping), "IPv6 ping sanity check"); 772f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 773f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti // Sanity checks reassemble_packet. 774fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t reassembled[MAXMTU]; 775f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti size_t total_length = sizeof(reassembled); 776f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti reassemble_packet(kIPv4Fragments, kIPv4FragLengths, ARRAYSIZE(kIPv4Fragments), 777f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti reassembled, &total_length, "Reassembly sanity check"); 778f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_packet(reassembled, total_length, "IPv4 Reassembled packet is valid"); 779f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_EQ(sizeof(kReassembledIPv4), total_length) << "IPv4 reassembly sanity check: length\n"; 780f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_TRUE(!is_ipv4_fragment((struct iphdr *) reassembled)) 781f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "Sanity check: reassembled packet is a fragment!\n"; 782f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_data_matches(kReassembledIPv4, reassembled, total_length, "IPv4 reassembly sanity check"); 783f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 784f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti total_length = sizeof(reassembled); 785f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti reassemble_packet(kIPv6Fragments, kIPv6FragLengths, ARRAYSIZE(kIPv6Fragments), 786f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti reassembled, &total_length, "IPv6 reassembly sanity check"); 787f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ASSERT_TRUE(!is_ipv6_fragment((struct ip6_hdr *) reassembled, total_length)) 788f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "Sanity check: reassembled packet is a fragment!\n"; 789f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_packet(reassembled, total_length, "IPv6 Reassembled packet is valid"); 790f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 791f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 792f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo ColittiTEST_F(ClatdTest, PseudoChecksum) { 793f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint32_t pseudo_checksum; 794f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 795fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t v4_header[] = { IPV4_UDP_HEADER }; 796fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t v4_pseudo_header[] = { IPV4_PSEUDOHEADER(v4_header, UDP_LEN) }; 797f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti pseudo_checksum = ipv4_pseudo_header_checksum((struct iphdr *) v4_header, UDP_LEN); 798f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(ip_checksum_finish(pseudo_checksum), 799f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip_checksum(v4_pseudo_header, sizeof(v4_pseudo_header))) 800f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "ipv4_pseudo_header_checksum incorrect\n"; 801f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 802fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t v6_header[] = { IPV6_UDP_HEADER }; 803fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t v6_pseudo_header[] = { IPV6_PSEUDOHEADER(v6_header, IPPROTO_UDP, UDP_LEN) }; 804f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti pseudo_checksum = ipv6_pseudo_header_checksum((struct ip6_hdr *) v6_header, UDP_LEN, IPPROTO_UDP); 805f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(ip_checksum_finish(pseudo_checksum), 806f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip_checksum(v6_pseudo_header, sizeof(v6_pseudo_header))) 807f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "ipv6_pseudo_header_checksum incorrect\n"; 808f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 809f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 810f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo ColittiTEST_F(ClatdTest, TransportChecksum) { 811fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t udphdr[] = { UDP_HEADER }; 812fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t payload[] = { PAYLOAD }; 813f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(kUdpPartialChecksum, ip_checksum_add(0, udphdr, sizeof(udphdr))) 814f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "UDP partial checksum\n"; 815f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(kPayloadPartialChecksum, ip_checksum_add(0, payload, sizeof(payload))) 816f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "Payload partial checksum\n"; 817f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 818fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t ip[] = { IPV4_UDP_HEADER }; 819fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t ip6[] = { IPV6_UDP_HEADER }; 820f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint32_t ipv4_pseudo_sum = ipv4_pseudo_header_checksum((struct iphdr *) ip, UDP_LEN); 821f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint32_t ipv6_pseudo_sum = ipv6_pseudo_header_checksum((struct ip6_hdr *) ip6, UDP_LEN, 822f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti IPPROTO_UDP); 823f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 824932614ee5e740704d7ef951dff6daede4fe12904Ben Cheng EXPECT_EQ(0x3ad0U, ipv4_pseudo_sum) << "IPv4 pseudo-checksum sanity check\n"; 825932614ee5e740704d7ef951dff6daede4fe12904Ben Cheng EXPECT_EQ(0x2644bU, ipv6_pseudo_sum) << "IPv6 pseudo-checksum sanity check\n"; 826f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ( 827f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti kUdpV4Checksum, 828f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip_checksum_finish(ipv4_pseudo_sum + kUdpPartialChecksum + kPayloadPartialChecksum)) 829f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "Unexpected UDP/IPv4 checksum\n"; 830f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ( 831f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti kUdpV6Checksum, 832f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip_checksum_finish(ipv6_pseudo_sum + kUdpPartialChecksum + kPayloadPartialChecksum)) 833f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "Unexpected UDP/IPv6 checksum\n"; 834f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 835f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(kUdpV6Checksum, 836f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip_checksum_adjust(kUdpV4Checksum, ipv4_pseudo_sum, ipv6_pseudo_sum)) 837f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "Adjust IPv4/UDP checksum to IPv6\n"; 838f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(kUdpV4Checksum, 839f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ip_checksum_adjust(kUdpV6Checksum, ipv6_pseudo_sum, ipv4_pseudo_sum)) 840f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "Adjust IPv6/UDP checksum to IPv4\n"; 841f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 842f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 843f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo ColittiTEST_F(ClatdTest, AdjustChecksum) { 844f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct checksum_data { 845f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint16_t checksum; 846f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint32_t old_hdr_sum; 847f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint32_t new_hdr_sum; 848f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint16_t result; 849f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } DATA[] = { 850f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti { 0x1423, 0xb8ec, 0x2d757, 0xf5b5 }, 851f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti { 0xf5b5, 0x2d757, 0xb8ec, 0x1423 }, 852f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti { 0xdd2f, 0x5555, 0x3285, 0x0000 }, 853f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti { 0x1215, 0x5560, 0x15560 + 20, 0x1200 }, 854f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti { 0xd0c7, 0x3ad0, 0x2644b, 0xa74a }, 855f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti }; 85605ff508a793c2113ca2a06942f0cec1aec220799Chih-Hung Hsieh unsigned i = 0; 857f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 858f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti for (i = 0; i < ARRAYSIZE(DATA); i++) { 859f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti struct checksum_data *data = DATA + i; 860f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti uint16_t result = ip_checksum_adjust(data->checksum, data->old_hdr_sum, data->new_hdr_sum); 861f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti EXPECT_EQ(result, data->result) 862f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "Incorrect checksum" << std::showbase << std::hex 863f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "\n Expected: " << data->result 864f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "\n Actual: " << result 865f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << "\n checksum=" << data->checksum 866f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti << " old_sum=" << data->old_hdr_sum << " new_sum=" << data->new_hdr_sum << "\n"; 867f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti } 868f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 869f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 870f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo ColittiTEST_F(ClatdTest, Translate) { 871fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t udp_ipv4[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD }; 872fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t udp_ipv6[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD }; 873f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti fix_udp_checksum(udp_ipv4); 874f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti fix_udp_checksum(udp_ipv6); 875f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_translated_packet(udp_ipv4, sizeof(udp_ipv4), udp_ipv6, sizeof(udp_ipv6), 876f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti "UDP/IPv4 -> UDP/IPv6 translation"); 877f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_translated_packet(udp_ipv6, sizeof(udp_ipv6), udp_ipv4, sizeof(udp_ipv4), 878f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti "UDP/IPv6 -> UDP/IPv4 translation"); 879f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 880fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t ipv4_ping[] = { IPV4_ICMP_HEADER IPV4_PING PAYLOAD }; 881fcac410fa15613873a07143ccd46470b869346a3Brian Carlstrom uint8_t ipv6_ping[] = { IPV6_ICMPV6_HEADER IPV6_PING PAYLOAD }; 882f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_translated_packet(ipv4_ping, sizeof(ipv4_ping), ipv6_ping, sizeof(ipv6_ping), 883f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti "ICMP->ICMPv6 translation"); 884f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_translated_packet(ipv6_ping, sizeof(ipv6_ping), ipv4_ping, sizeof(ipv4_ping), 885f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti "ICMPv6->ICMP translation"); 886f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 887f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 888f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo ColittiTEST_F(ClatdTest, Fragmentation) { 889f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_fragment_translation(kIPv4Fragments, kIPv4FragLengths, 890f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti kIPv6Fragments, kIPv6FragLengths, 891f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ARRAYSIZE(kIPv4Fragments), "IPv4->IPv6 fragment translation"); 892f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti 893f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti check_fragment_translation(kIPv6Fragments, kIPv6FragLengths, 894f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti kIPv4Fragments, kIPv4FragLengths, 895f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti ARRAYSIZE(kIPv6Fragments), "IPv6->IPv4 fragment translation"); 896f3beefc96a5a4f295562f60d648bd6e795980a10Lorenzo Colitti} 8979808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 8989808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colittivoid check_translate_checksum_neutral(const uint8_t *original, size_t original_len, 8999808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti size_t expected_len, const char *msg) { 9009808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti uint8_t translated[MAXMTU]; 9019808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti size_t translated_len = sizeof(translated); 9029808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti do_translate_packet(original, original_len, translated, &translated_len, msg); 9039808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti EXPECT_EQ(expected_len, translated_len) << msg << ": Translated packet length incorrect\n"; 9049808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // do_translate_packet already checks packets for validity and verifies the checksum. 9059808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti int original_check = get_transport_checksum(original); 9069808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti int translated_check = get_transport_checksum(translated); 9079808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_NE(-1, original_check); 9089808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_NE(-1, translated_check); 9099808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_EQ(original_check, translated_check) 9109808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti << "Not checksum neutral: original and translated checksums differ\n"; 9119808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti} 9129808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 9139808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo ColittiTEST_F(ClatdTest, TranslateChecksumNeutral) { 9149808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // Generate a random clat IPv6 address and check that translation is checksum-neutral. 9159808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti Global_Clatd_Config.ipv6_host_id = in6addr_any; 9169808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", 9179808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti &Global_Clatd_Config.ipv6_local_subnet)); 9189808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet); 9199808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_NE((uint32_t) 0x00000464, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); 9209808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti ASSERT_NE((uint32_t) 0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); 9219808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 9229808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // Check that translating UDP packets is checksum-neutral. First, IPv4. 9239808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti uint8_t udp_ipv4[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD }; 9249808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti fix_udp_checksum(udp_ipv4); 9259808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti check_translate_checksum_neutral(udp_ipv4, sizeof(udp_ipv4), sizeof(udp_ipv4) + 20, 9269808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti "UDP/IPv4 -> UDP/IPv6 checksum neutral"); 9279808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti 9289808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // Now try IPv6. 9299808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti uint8_t udp_ipv6[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD }; 9309808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti // The test packet uses the static IID, not the random IID. Fix up the source address. 9319808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti struct ip6_hdr *ip6 = (struct ip6_hdr *) udp_ipv6; 9329808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti memcpy(&ip6->ip6_src, &Global_Clatd_Config.ipv6_local_subnet, sizeof(ip6->ip6_src)); 9339808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti fix_udp_checksum(udp_ipv6); 9349808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti check_translate_checksum_neutral(udp_ipv4, sizeof(udp_ipv4), sizeof(udp_ipv4) + 20, 9359808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti "UDP/IPv4 -> UDP/IPv6 checksum neutral"); 9369808952bdf2fa6ce4cbd790d1967691bb95bf327Lorenzo Colitti} 937