/*
 * Copyright 2011 Daniel Drown
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * translate.c - CLAT functions / partial implementation of rfc6145
 */
#include "translate.h"

#include <string.h>

#include "checksum.h"
#include "clatd.h"
#include "common.h"
#include "config.h"
#include "debug.h"
#include "icmp.h"
#include "logging.h"

/* function: packet_checksum
 * calculates the checksum over all the packet components starting from pos
 * checksum - checksum of packet components before pos
 * packet   - packet to calculate the checksum of
 * pos      - position to start counting from
 * returns  - the completed 16-bit checksum, ready to write into a checksum header field
 */
uint16_t packet_checksum(uint32_t checksum, clat_packet packet, clat_packet_index pos) {
  int i;
  for (i = pos; i < CLAT_POS_MAX; i++) {
    if (packet[i].iov_len > 0) {
      checksum = ip_checksum_add(checksum, packet[i].iov_base, packet[i].iov_len);
    }
  }
  return ip_checksum_finish(checksum);
}

/* function: packet_length
 * returns the total length of all the packet components after pos
 * packet - packet to calculate the length of
 * pos    - position to start counting after
 * returns: the total length of the packet components after pos
 */
uint16_t packet_length(clat_packet packet, clat_packet_index pos) {
  size_t len = 0;
  int i;
  for (i = pos + 1; i < CLAT_POS_MAX; i++) {
    len += packet[i].iov_len;
  }
  return len;
}

/* function: is_in_plat_subnet
 * returns true iff the given IPv6 address is in the plat subnet.
 * addr - IPv6 address
 */
int is_in_plat_subnet(const struct in6_addr *addr6) {
  // Assumes a /96 plat subnet.
  return (addr6 != NULL) && (memcmp(addr6, &Global_Clatd_Config.plat_subnet, 12) == 0);
}

/* function: ipv6_addr_to_ipv4_addr
 * return the corresponding ipv4 address for the given ipv6 address
 * addr6 - ipv6 address
 * returns: the IPv4 address
 */
uint32_t ipv6_addr_to_ipv4_addr(const struct in6_addr *addr6) {
  if (is_in_plat_subnet(addr6)) {
    // Assumes a /96 plat subnet.
    return addr6->s6_addr32[3];
  } else if (IN6_ARE_ADDR_EQUAL(addr6, &Global_Clatd_Config.ipv6_local_subnet)) {
    // Special-case our own address.
    return Global_Clatd_Config.ipv4_local_subnet.s_addr;
  } else {
    // Third party packet. Let the caller deal with it.
    return INADDR_NONE;
  }
}

/* function: ipv4_addr_to_ipv6_addr
 * return the corresponding ipv6 address for the given ipv4 address
 * addr4 - ipv4 address
 */
struct in6_addr ipv4_addr_to_ipv6_addr(uint32_t addr4) {
  struct in6_addr addr6;
  // Both addresses are in network byte order (addr4 comes from a network packet, and the config
  // file entry is read using inet_ntop).
  if (addr4 == Global_Clatd_Config.ipv4_local_subnet.s_addr) {
    return Global_Clatd_Config.ipv6_local_subnet;
  } else {
    // Assumes a /96 plat subnet.
    addr6              = Global_Clatd_Config.plat_subnet;
    addr6.s6_addr32[3] = addr4;
    return addr6;
  }
}

/* function: fill_tun_header
 * fill in the header for the tun fd
 * tun_header - tunnel header, already allocated
 * proto      - ethernet protocol id: ETH_P_IP(ipv4) or ETH_P_IPV6(ipv6)
 */
void fill_tun_header(struct tun_pi *tun_header, uint16_t proto) {
  tun_header->flags = 0;
  tun_header->proto = htons(proto);
}

/* function: fill_ip_header
 * generate an ipv4 header from an ipv6 header
 * ip_targ     - (ipv4) target packet header, source: original ipv4 addr, dest: local subnet addr
 * payload_len - length of other data inside packet
 * protocol    - protocol number (tcp, udp, etc)
 * old_header  - (ipv6) source packet header, source: nat64 prefix, dest: local subnet prefix
 */
void fill_ip_header(struct iphdr *ip, uint16_t payload_len, uint8_t protocol,
                    const struct ip6_hdr *old_header) {
  int ttl_guess;
  memset(ip, 0, sizeof(struct iphdr));

  ip->ihl      = 5;
  ip->version  = 4;
  ip->tos      = 0;
  ip->tot_len  = htons(sizeof(struct iphdr) + payload_len);
  ip->id       = 0;
  ip->frag_off = htons(IP_DF);
  ip->ttl      = old_header->ip6_hlim;
  ip->protocol = protocol;
  ip->check    = 0;

  ip->saddr = ipv6_addr_to_ipv4_addr(&old_header->ip6_src);
  ip->daddr = ipv6_addr_to_ipv4_addr(&old_header->ip6_dst);

  // Third-party ICMPv6 message. This may have been originated by an native IPv6 address.
  // In that case, the source IPv6 address can't be translated and we need to make up an IPv4
  // source address. For now, use 255.0.0.<ttl>, which at least looks useful in traceroute.
  if ((uint32_t)ip->saddr == INADDR_NONE) {
    ttl_guess = icmp_guess_ttl(old_header->ip6_hlim);
    ip->saddr = htonl((0xff << 24) + ttl_guess);
  }
}

/* function: fill_ip6_header
 * generate an ipv6 header from an ipv4 header
 * ip6         - (ipv6) target packet header, source: local subnet prefix, dest: nat64 prefix
 * payload_len - length of other data inside packet
 * protocol    - protocol number (tcp, udp, etc)
 * old_header  - (ipv4) source packet header, source: local subnet addr, dest: internet's ipv4 addr
 */
void fill_ip6_header(struct ip6_hdr *ip6, uint16_t payload_len, uint8_t protocol,
                     const struct iphdr *old_header) {
  memset(ip6, 0, sizeof(struct ip6_hdr));

  ip6->ip6_vfc  = 6 << 4;
  ip6->ip6_plen = htons(payload_len);
  ip6->ip6_nxt  = protocol;
  ip6->ip6_hlim = old_header->ttl;

  ip6->ip6_src = ipv4_addr_to_ipv6_addr(old_header->saddr);
  ip6->ip6_dst = ipv4_addr_to_ipv6_addr(old_header->daddr);
}

/* function: maybe_fill_frag_header
 * fills a fragmentation header
 * generate an ipv6 fragment header from an ipv4 header
 * frag_hdr    - target (ipv6) fragmentation header
 * ip6_targ    - target (ipv6) header
 * old_header  - (ipv4) source packet header
 * returns: the length of the fragmentation header if present, or zero if not present
 */
size_t maybe_fill_frag_header(struct ip6_frag *frag_hdr, struct ip6_hdr *ip6_targ,
                              const struct iphdr *old_header) {
  uint16_t frag_flags = ntohs(old_header->frag_off);
  uint16_t frag_off   = frag_flags & IP_OFFMASK;
  if (frag_off == 0 && (frag_flags & IP_MF) == 0) {
    // Not a fragment.
    return 0;
  }

  frag_hdr->ip6f_nxt      = ip6_targ->ip6_nxt;
  frag_hdr->ip6f_reserved = 0;
  // In IPv4, the offset is the bottom 13 bits; in IPv6 it's the top 13 bits.
  frag_hdr->ip6f_offlg = htons(frag_off << 3);
  if (frag_flags & IP_MF) {
    frag_hdr->ip6f_offlg |= IP6F_MORE_FRAG;
  }
  frag_hdr->ip6f_ident = htonl(ntohs(old_header->id));
  ip6_targ->ip6_nxt    = IPPROTO_FRAGMENT;

  return sizeof(*frag_hdr);
}

/* function: parse_frag_header
 * return the length of the fragmentation header if present, or zero if not present
 * generate an ipv6 fragment header from an ipv4 header
 * frag_hdr    - (ipv6) fragmentation header
 * ip_targ     - target (ipv4) header
 * returns: the next header value
 */
uint8_t parse_frag_header(const struct ip6_frag *frag_hdr, struct iphdr *ip_targ) {
  uint16_t frag_off = (ntohs(frag_hdr->ip6f_offlg & IP6F_OFF_MASK) >> 3);
  if (frag_hdr->ip6f_offlg & IP6F_MORE_FRAG) {
    frag_off |= IP_MF;
  }
  ip_targ->frag_off = htons(frag_off);
  ip_targ->id       = htons(ntohl(frag_hdr->ip6f_ident) & 0xffff);
  ip_targ->protocol = frag_hdr->ip6f_nxt;
  return frag_hdr->ip6f_nxt;
}

/* function: icmp_to_icmp6
 * translate ipv4 icmp to ipv6 icmp
 * out          - output packet
 * icmp         - source packet icmp header
 * checksum     - pseudo-header checksum
 * payload      - icmp payload
 * payload_size - size of payload
 * returns: the highest position in the output clat_packet that's filled in
 */
int icmp_to_icmp6(clat_packet out, clat_packet_index pos, const struct icmphdr *icmp,
                  uint32_t checksum, const uint8_t *payload, size_t payload_size) {
  struct icmp6_hdr *icmp6_targ = out[pos].iov_base;
  uint8_t icmp6_type;
  int clat_packet_len;

  memset(icmp6_targ, 0, sizeof(struct icmp6_hdr));

  icmp6_type             = icmp_to_icmp6_type(icmp->type, icmp->code);
  icmp6_targ->icmp6_type = icmp6_type;
  icmp6_targ->icmp6_code = icmp_to_icmp6_code(icmp->type, icmp->code);

  out[pos].iov_len = sizeof(struct icmp6_hdr);

  if (pos == CLAT_POS_TRANSPORTHDR && is_icmp_error(icmp->type) && icmp6_type != ICMP6_PARAM_PROB) {
    // An ICMP error we understand, one level deep.
    // Translate the nested packet (the one that caused the error).
    clat_packet_len = ipv4_packet(out, pos + 1, payload, payload_size);

    // The pseudo-header checksum was calculated on the transport length of the original IPv4
    // packet that we were asked to translate. This transport length is 20 bytes smaller than it
    // needs to be, because the ICMP error contains an IPv4 header, which we will be translating to
    // an IPv6 header, which is 20 bytes longer. Fix it up here.
    // We only need to do this for ICMP->ICMPv6, not ICMPv6->ICMP, because ICMP does not use the
    // pseudo-header when calculating its checksum (as the IPv4 header has its own checksum).
    checksum = checksum + htons(20);
  } else if (icmp6_type == ICMP6_ECHO_REQUEST || icmp6_type == ICMP6_ECHO_REPLY) {
    // Ping packet.
    icmp6_targ->icmp6_id           = icmp->un.echo.id;
    icmp6_targ->icmp6_seq          = icmp->un.echo.sequence;
    out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *)payload;
    out[CLAT_POS_PAYLOAD].iov_len  = payload_size;
    clat_packet_len                = CLAT_POS_PAYLOAD + 1;
  } else {
    // Unknown type/code. The type/code conversion functions have already logged an error.
    return 0;
  }

  icmp6_targ->icmp6_cksum = 0;  // Checksum field must be 0 when calculating checksum.
  icmp6_targ->icmp6_cksum = packet_checksum(checksum, out, pos);

  return clat_packet_len;
}

/* function: icmp6_to_icmp
 * translate ipv6 icmp to ipv4 icmp
 * out          - output packet
 * icmp6        - source packet icmp6 header
 * payload      - icmp6 payload
 * payload_size - size of payload
 * returns: the highest position in the output clat_packet that's filled in
 */
int icmp6_to_icmp(clat_packet out, clat_packet_index pos, const struct icmp6_hdr *icmp6,
                  const uint8_t *payload, size_t payload_size) {
  struct icmphdr *icmp_targ = out[pos].iov_base;
  uint8_t icmp_type;
  int clat_packet_len;

  memset(icmp_targ, 0, sizeof(struct icmphdr));

  icmp_type       = icmp6_to_icmp_type(icmp6->icmp6_type, icmp6->icmp6_code);
  icmp_targ->type = icmp_type;
  icmp_targ->code = icmp6_to_icmp_code(icmp6->icmp6_type, icmp6->icmp6_code);

  out[pos].iov_len = sizeof(struct icmphdr);

  if (pos == CLAT_POS_TRANSPORTHDR && is_icmp6_error(icmp6->icmp6_type) &&
      icmp_type != ICMP_PARAMETERPROB) {
    // An ICMPv6 error we understand, one level deep.
    // Translate the nested packet (the one that caused the error).
    clat_packet_len = ipv6_packet(out, pos + 1, payload, payload_size);
  } else if (icmp_type == ICMP_ECHO || icmp_type == ICMP_ECHOREPLY) {
    // Ping packet.
    icmp_targ->un.echo.id          = icmp6->icmp6_id;
    icmp_targ->un.echo.sequence    = icmp6->icmp6_seq;
    out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *)payload;
    out[CLAT_POS_PAYLOAD].iov_len  = payload_size;
    clat_packet_len                = CLAT_POS_PAYLOAD + 1;
  } else {
    // Unknown type/code. The type/code conversion functions have already logged an error.
    return 0;
  }

  icmp_targ->checksum = 0;  // Checksum field must be 0 when calculating checksum.
  icmp_targ->checksum = packet_checksum(0, out, pos);

  return clat_packet_len;
}

/* function: generic_packet
 * takes a generic IP packet and sets it up for translation
 * out      - output packet
 * pos      - position in the output packet of the transport header
 * payload  - pointer to IP payload
 * len      - size of ip payload
 * returns: the highest position in the output clat_packet that's filled in
 */
int generic_packet(clat_packet out, clat_packet_index pos, const uint8_t *payload, size_t len) {
  out[pos].iov_len               = 0;
  out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *)payload;
  out[CLAT_POS_PAYLOAD].iov_len  = len;

  return CLAT_POS_PAYLOAD + 1;
}

/* function: udp_packet
 * takes a udp packet and sets it up for translation
 * out      - output packet
 * udp      - pointer to udp header in packet
 * old_sum  - pseudo-header checksum of old header
 * new_sum  - pseudo-header checksum of new header
 * len      - size of ip payload
 */
int udp_packet(clat_packet out, clat_packet_index pos, const struct udphdr *udp, uint32_t old_sum,
               uint32_t new_sum, size_t len) {
  const uint8_t *payload;
  size_t payload_size;

  if (len < sizeof(struct udphdr)) {
    logmsg_dbg(ANDROID_LOG_ERROR, "udp_packet/(too small)");
    return 0;
  }

  payload      = (const uint8_t *)(udp + 1);
  payload_size = len - sizeof(struct udphdr);

  return udp_translate(out, pos, udp, old_sum, new_sum, payload, payload_size);
}

/* function: tcp_packet
 * takes a tcp packet and sets it up for translation
 * out      - output packet
 * tcp      - pointer to tcp header in packet
 * checksum - pseudo-header checksum
 * len      - size of ip payload
 * returns: the highest position in the output clat_packet that's filled in
 */
int tcp_packet(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp, uint32_t old_sum,
               uint32_t new_sum, size_t len) {
  const uint8_t *payload;
  size_t payload_size, header_size;

  if (len < sizeof(struct tcphdr)) {
    logmsg_dbg(ANDROID_LOG_ERROR, "tcp_packet/(too small)");
    return 0;
  }

  if (tcp->doff < 5) {
    logmsg_dbg(ANDROID_LOG_ERROR, "tcp_packet/tcp header length set to less than 5: %x", tcp->doff);
    return 0;
  }

  if ((size_t)tcp->doff * 4 > len) {
    logmsg_dbg(ANDROID_LOG_ERROR, "tcp_packet/tcp header length set too large: %x", tcp->doff);
    return 0;
  }

  header_size  = tcp->doff * 4;
  payload      = ((const uint8_t *)tcp) + header_size;
  payload_size = len - header_size;

  return tcp_translate(out, pos, tcp, header_size, old_sum, new_sum, payload, payload_size);
}

/* function: udp_translate
 * common between ipv4/ipv6 - setup checksum and send udp packet
 * out          - output packet
 * udp          - udp header
 * old_sum      - pseudo-header checksum of old header
 * new_sum      - pseudo-header checksum of new header
 * payload      - tcp payload
 * payload_size - size of payload
 * returns: the highest position in the output clat_packet that's filled in
 */
int udp_translate(clat_packet out, clat_packet_index pos, const struct udphdr *udp,
                  uint32_t old_sum, uint32_t new_sum, const uint8_t *payload, size_t payload_size) {
  struct udphdr *udp_targ = out[pos].iov_base;

  memcpy(udp_targ, udp, sizeof(struct udphdr));

  out[pos].iov_len               = sizeof(struct udphdr);
  out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *)payload;
  out[CLAT_POS_PAYLOAD].iov_len  = payload_size;

  if (udp_targ->check) {
    udp_targ->check = ip_checksum_adjust(udp->check, old_sum, new_sum);
  } else {
    // Zero checksums are special. RFC 768 says, "An all zero transmitted checksum value means that
    // the transmitter generated no checksum (for debugging or for higher level protocols that
    // don't care)." However, in IPv6 zero UDP checksums were only permitted by RFC 6935 (2013). So
    // for safety we recompute it.
    udp_targ->check = 0;  // Checksum field must be 0 when calculating checksum.
    udp_targ->check = packet_checksum(new_sum, out, pos);
  }

  // RFC 768: "If the computed checksum is zero, it is transmitted as all ones (the equivalent
  // in one's complement arithmetic)."
  if (!udp_targ->check) {
    udp_targ->check = 0xffff;
  }

  return CLAT_POS_PAYLOAD + 1;
}

/* function: tcp_translate
 * common between ipv4/ipv6 - setup checksum and send tcp packet
 * out          - output packet
 * tcp          - tcp header
 * header_size  - size of tcp header including options
 * checksum     - partial checksum covering ipv4/ipv6 header
 * payload      - tcp payload
 * payload_size - size of payload
 * returns: the highest position in the output clat_packet that's filled in
 */
int tcp_translate(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp,
                  size_t header_size, uint32_t old_sum, uint32_t new_sum, const uint8_t *payload,
                  size_t payload_size) {
  struct tcphdr *tcp_targ = out[pos].iov_base;
  out[pos].iov_len        = header_size;

  if (header_size > MAX_TCP_HDR) {
    // A TCP header cannot be more than MAX_TCP_HDR bytes long because it's a 4-bit field that
    // counts in 4-byte words. So this can never happen unless there is a bug in the caller.
    logmsg(ANDROID_LOG_ERROR, "tcp_translate: header too long %d > %d, truncating", header_size,
           MAX_TCP_HDR);
    header_size = MAX_TCP_HDR;
  }

  memcpy(tcp_targ, tcp, header_size);

  out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *)payload;
  out[CLAT_POS_PAYLOAD].iov_len  = payload_size;

  tcp_targ->check = ip_checksum_adjust(tcp->check, old_sum, new_sum);

  return CLAT_POS_PAYLOAD + 1;
}

// Weak symbol so we can override it in the unit test.
void send_rawv6(int fd, clat_packet out, int iov_len) __attribute__((weak));

void send_rawv6(int fd, clat_packet out, int iov_len) {
  // A send on a raw socket requires a destination address to be specified even if the socket's
  // protocol is IPPROTO_RAW. This is the address that will be used in routing lookups; the
  // destination address in the packet header only affects what appears on the wire, not where the
  // packet is sent to.
  static struct sockaddr_in6 sin6 = { AF_INET6, 0, 0, { { { 0, 0, 0, 0 } } }, 0 };
  static struct msghdr msg        = {
    .msg_name    = &sin6,
    .msg_namelen = sizeof(sin6),
  };

  msg.msg_iov = out, msg.msg_iovlen = iov_len,
  sin6.sin6_addr = ((struct ip6_hdr *)out[CLAT_POS_IPHDR].iov_base)->ip6_dst;
  sendmsg(fd, &msg, 0);
}

/* function: translate_packet
 * takes a packet, translates it, and writes it to fd
 * fd         - fd to write translated packet to
 * to_ipv6    - true if translating to ipv6, false if translating to ipv4
 * packet     - packet
 * packetsize - size of packet
 */
void translate_packet(int fd, int to_ipv6, const uint8_t *packet, size_t packetsize) {
  int iov_len = 0;

  // Allocate buffers for all packet headers.
  struct tun_pi tun_targ;
  char iphdr[sizeof(struct ip6_hdr)];
  char fraghdr[sizeof(struct ip6_frag)];
  char transporthdr[MAX_TCP_HDR];
  char icmp_iphdr[sizeof(struct ip6_hdr)];
  char icmp_fraghdr[sizeof(struct ip6_frag)];
  char icmp_transporthdr[MAX_TCP_HDR];

  // iovec of the packets we'll send. This gets passed down to the translation functions.
  clat_packet out = {
    { &tun_targ, 0 },          // Tunnel header.
    { iphdr, 0 },              // IP header.
    { fraghdr, 0 },            // Fragment header.
    { transporthdr, 0 },       // Transport layer header.
    { icmp_iphdr, 0 },         // ICMP error inner IP header.
    { icmp_fraghdr, 0 },       // ICMP error fragmentation header.
    { icmp_transporthdr, 0 },  // ICMP error transport layer header.
    { NULL, 0 },               // Payload. No buffer, it's a pointer to the original payload.
  };

  if (to_ipv6) {
    iov_len = ipv4_packet(out, CLAT_POS_IPHDR, packet, packetsize);
    if (iov_len > 0) {
      send_rawv6(fd, out, iov_len);
    }
  } else {
    iov_len = ipv6_packet(out, CLAT_POS_IPHDR, packet, packetsize);
    if (iov_len > 0) {
      fill_tun_header(&tun_targ, ETH_P_IP);
      out[CLAT_POS_TUNHDR].iov_len = sizeof(tun_targ);
      writev(fd, out, iov_len);
    }
  }
}
