/*
 * 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.
 *
 * config.c - configuration settings
 */

#include <arpa/inet.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <cutils/config_utils.h>
#include <netutils/checksum.h>
#include <netutils/ifc.h>

#include "clatd.h"
#include "config.h"
#include "dns64.h"
#include "getaddr.h"
#include "logging.h"

struct clat_config Global_Clatd_Config;

/* function: config_item_str
 * locates the config item and returns the pointer to a string, or NULL on failure.  Caller frees
 * pointer
 *   root       - parsed configuration
 *   item_name  - name of config item to locate
 *   defaultvar - value to use if config item isn't present
 */
char *config_item_str(cnode *root, const char *item_name, const char *defaultvar) {
  const char *tmp;

  if (!(tmp = config_str(root, item_name, defaultvar))) {
    logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name);
    return NULL;
  }
  return strdup(tmp);
}

/* function: config_item_int16_t
 * locates the config item, parses the integer, and returns the pointer ret_val_ptr, or NULL on
 * failure
 *   root        - parsed configuration
 *   item_name   - name of config item to locate
 *   defaultvar  - value to use if config item isn't present
 *   ret_val_ptr - pointer for return value storage
 */
int16_t *config_item_int16_t(cnode *root, const char *item_name, const char *defaultvar,
                             int16_t *ret_val_ptr) {
  const char *tmp;
  char *endptr;
  long int conf_int;

  if (!(tmp = config_str(root, item_name, defaultvar))) {
    logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name);
    return NULL;
  }

  errno    = 0;
  conf_int = strtol(tmp, &endptr, 10);
  if (errno > 0) {
    logmsg(ANDROID_LOG_FATAL, "%s config item is not numeric: %s (error=%s)", item_name, tmp,
           strerror(errno));
    return NULL;
  }
  if (endptr == tmp || *tmp == '\0') {
    logmsg(ANDROID_LOG_FATAL, "%s config item is not numeric: %s", item_name, tmp);
    return NULL;
  }
  if (*endptr != '\0') {
    logmsg(ANDROID_LOG_FATAL, "%s config item contains non-numeric characters: %s", item_name,
           endptr);
    return NULL;
  }
  if (conf_int > INT16_MAX || conf_int < INT16_MIN) {
    logmsg(ANDROID_LOG_FATAL, "%s config item is too big/small: %d", item_name, conf_int);
    return NULL;
  }
  *ret_val_ptr = conf_int;
  return ret_val_ptr;
}

/* function: config_item_ip
 * locates the config item, parses the ipv4 address, and returns the pointer ret_val_ptr, or NULL on
 * failure
 *   root        - parsed configuration
 *   item_name   - name of config item to locate
 *   defaultvar  - value to use if config item isn't present
 *   ret_val_ptr - pointer for return value storage
 */
struct in_addr *config_item_ip(cnode *root, const char *item_name, const char *defaultvar,
                               struct in_addr *ret_val_ptr) {
  const char *tmp;
  int status;

  if (!(tmp = config_str(root, item_name, defaultvar))) {
    logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name);
    return NULL;
  }

  status = inet_pton(AF_INET, tmp, ret_val_ptr);
  if (status <= 0) {
    logmsg(ANDROID_LOG_FATAL, "invalid IPv4 address specified for %s: %s", item_name, tmp);
    return NULL;
  }

  return ret_val_ptr;
}

/* function: config_item_ip6
 * locates the config item, parses the ipv6 address, and returns the pointer ret_val_ptr, or NULL on
 * failure
 *   root        - parsed configuration
 *   item_name   - name of config item to locate
 *   defaultvar  - value to use if config item isn't present
 *   ret_val_ptr - pointer for return value storage
 */
struct in6_addr *config_item_ip6(cnode *root, const char *item_name, const char *defaultvar,
                                 struct in6_addr *ret_val_ptr) {
  const char *tmp;
  int status;

  if (!(tmp = config_str(root, item_name, defaultvar))) {
    logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name);
    return NULL;
  }

  status = inet_pton(AF_INET6, tmp, ret_val_ptr);
  if (status <= 0) {
    logmsg(ANDROID_LOG_FATAL, "invalid IPv6 address specified for %s: %s", item_name, tmp);
    return NULL;
  }

  return ret_val_ptr;
}

/* function: ipv6_prefix_equal
 * compares the prefixes two ipv6 addresses. assumes the prefix lengths are both /64.
 *   a1 - first address
 *   a2 - second address
 *   returns: 0 if the subnets are different, 1 if they are the same.
 */
int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2) { return !memcmp(a1, a2, 8); }

/* function: dns64_detection
 * does dns lookups to set the plat subnet or exits on failure, waits forever for a dns response
 * with a query backoff timer
 *   net_id - (optional) netId to use, NETID_UNSET indicates use of default network
 */
void dns64_detection(unsigned net_id) {
  int backoff_sleep, status;
  struct in6_addr tmp_ptr;

  backoff_sleep = 1;

  while (1) {
    status = plat_prefix(DNS64_DETECTION_HOSTNAME, net_id, &tmp_ptr);
    if (status > 0) {
      memcpy(&Global_Clatd_Config.plat_subnet, &tmp_ptr, sizeof(struct in6_addr));
      return;
    }
    logmsg(ANDROID_LOG_WARN, "dns64_detection -- error, sleeping for %d seconds", backoff_sleep);
    sleep(backoff_sleep);
    backoff_sleep *= 2;
    if (backoff_sleep >= 1800) {
      // Scale down to one DNS query per half hour. Unnecessary DNS queries waste power, and the
      // benefit is minimal (basically, only limited to the case where a network goes from IPv6-only
      // to IPv6 with NAT64).
      backoff_sleep = 1800;
    }
  }
}

/* function: gen_random_iid
 * picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix
 *   myaddr            - IPv6 address to write to
 *   ipv4_local_subnet - clat IPv4 address
 *   plat_subnet       - NAT64 prefix
 */
void gen_random_iid(struct in6_addr *myaddr, struct in_addr *ipv4_local_subnet,
                    struct in6_addr *plat_subnet) {
  // Fill last 8 bytes of IPv6 address with random bits.
  arc4random_buf(&myaddr->s6_addr[8], 8);

  // Make the IID checksum-neutral. That is, make it so that:
  //   checksum(Local IPv4 | Remote IPv4) = checksum(Local IPv6 | Remote IPv6)
  // in other words (because remote IPv6 = NAT64 prefix | Remote IPv4):
  //   checksum(Local IPv4) = checksum(Local IPv6 | NAT64 prefix)
  // Do this by adjusting the two bytes in the middle of the IID.

  uint16_t middlebytes = (myaddr->s6_addr[11] << 8) + myaddr->s6_addr[12];

  uint32_t c1 = ip_checksum_add(0, ipv4_local_subnet, sizeof(*ipv4_local_subnet));
  uint32_t c2 = ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
                ip_checksum_add(0, myaddr, sizeof(*myaddr));

  uint16_t delta      = ip_checksum_adjust(middlebytes, c1, c2);
  myaddr->s6_addr[11] = delta >> 8;
  myaddr->s6_addr[12] = delta & 0xff;
}

// Factored out to a separate function for testability.
int connect_is_ipv4_address_free(in_addr_t addr) {
  int s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
  if (s == -1) {
    return 0;
  }

  // Attempt to connect to the address. If the connection succeeds and getsockname returns the same
  // the address then the address is already assigned to the system and we can't use it.
  struct sockaddr_in sin = { .sin_family = AF_INET, .sin_addr = { addr }, .sin_port = htons(53) };
  socklen_t len          = sizeof(sin);
  int inuse              = connect(s, (struct sockaddr *)&sin, sizeof(sin)) == 0 &&
              getsockname(s, (struct sockaddr *)&sin, &len) == 0 && (size_t)len >= sizeof(sin) &&
              sin.sin_addr.s_addr == addr;

  close(s);
  return !inuse;
}

addr_free_func config_is_ipv4_address_free = connect_is_ipv4_address_free;

/* function: config_select_ipv4_address
 * picks a free IPv4 address, starting from ip and trying all addresses in the prefix in order
 *   ip        - the IP address from the configuration file
 *   prefixlen - the length of the prefix from which addresses may be selected.
 *   returns: the IPv4 address, or INADDR_NONE if no addresses were available
 */
in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen) {
  in_addr_t chosen = INADDR_NONE;

  // Don't accept prefixes that are too large because we scan addresses one by one.
  if (prefixlen < 16 || prefixlen > 32) {
    return chosen;
  }

  // All these are in host byte order.
  in_addr_t mask       = 0xffffffff >> (32 - prefixlen) << (32 - prefixlen);
  in_addr_t ipv4       = ntohl(ip->s_addr);
  in_addr_t first_ipv4 = ipv4;
  in_addr_t prefix     = ipv4 & mask;

  // Pick the first IPv4 address in the pool, wrapping around if necessary.
  // So, for example, 192.0.0.4 -> 192.0.0.5 -> 192.0.0.6 -> 192.0.0.7 -> 192.0.0.0.
  do {
    if (config_is_ipv4_address_free(htonl(ipv4))) {
      chosen = htonl(ipv4);
      break;
    }
    ipv4 = prefix | ((ipv4 + 1) & ~mask);
  } while (ipv4 != first_ipv4);

  return chosen;
}

/* function: config_generate_local_ipv6_subnet
 * generates the local ipv6 subnet when given the interface ip requires config.ipv6_host_id
 *   interface_ip - in: interface ip, out: local ipv6 host address
 */
void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip) {
  int i;

  if (Global_Clatd_Config.use_dynamic_iid) {
    /* Generate a random interface ID. */
    gen_random_iid(interface_ip, &Global_Clatd_Config.ipv4_local_subnet,
                   &Global_Clatd_Config.plat_subnet);
  } else {
    /* Use the specified interface ID. */
    for (i = 2; i < 4; i++) {
      interface_ip->s6_addr32[i] = Global_Clatd_Config.ipv6_host_id.s6_addr32[i];
    }
  }
}

/* function: read_config
 * reads the config file and parses it into the global variable Global_Clatd_Config. returns 0 on
 * failure, 1 on success
 *   file             - filename to parse
 *   uplink_interface - interface to use to reach the internet and supplier of address space
 *   plat_prefix      - (optional) plat prefix to use, otherwise follow config file
 *   net_id           - (optional) netId to use, NETID_UNSET indicates use of default network
 */
int read_config(const char *file, const char *uplink_interface, const char *plat_prefix,
                unsigned net_id) {
  cnode *root   = config_node("", "");
  void *tmp_ptr = NULL;
  unsigned flags;

  if (!root) {
    logmsg(ANDROID_LOG_FATAL, "out of memory");
    return 0;
  }

  memset(&Global_Clatd_Config, '\0', sizeof(Global_Clatd_Config));

  config_load_file(root, file);
  if (root->first_child == NULL) {
    logmsg(ANDROID_LOG_FATAL, "Could not read config file %s", file);
    goto failed;
  }

  Global_Clatd_Config.default_pdp_interface = strdup(uplink_interface);
  if (!Global_Clatd_Config.default_pdp_interface) goto failed;

  if (!config_item_ip(root, "ipv4_local_subnet", DEFAULT_IPV4_LOCAL_SUBNET,
                      &Global_Clatd_Config.ipv4_local_subnet))
    goto failed;

  if (!config_item_int16_t(root, "ipv4_local_prefixlen", DEFAULT_IPV4_LOCAL_PREFIXLEN,
                           &Global_Clatd_Config.ipv4_local_prefixlen))
    goto failed;

  if (plat_prefix) {  // plat subnet is coming from the command line
    if (inet_pton(AF_INET6, plat_prefix, &Global_Clatd_Config.plat_subnet) <= 0) {
      logmsg(ANDROID_LOG_FATAL, "invalid IPv6 address specified for plat prefix: %s", plat_prefix);
      goto failed;
    }
  } else {
    tmp_ptr = (void *)config_item_str(root, "plat_from_dns64", "yes");
    if (!tmp_ptr || strcmp(tmp_ptr, "no") == 0) {
      free(tmp_ptr);

      if (!config_item_ip6(root, "plat_subnet", NULL, &Global_Clatd_Config.plat_subnet)) {
        logmsg(ANDROID_LOG_FATAL, "plat_from_dns64 disabled, but no plat_subnet specified");
        goto failed;
      }
    } else {
      free(tmp_ptr);

      dns64_detection(net_id);
    }
  }

  if (!config_item_ip6(root, "ipv6_host_id", "::", &Global_Clatd_Config.ipv6_host_id)) goto failed;

  /* In order to prevent multiple devices attempting to use the same clat address, never use a
     statically-configured interface ID on a broadcast interface such as wifi. */
  if (!IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_host_id)) {
    ifc_init();
    ifc_get_info(Global_Clatd_Config.default_pdp_interface, NULL, NULL, &flags);
    ifc_close();
    Global_Clatd_Config.use_dynamic_iid = (flags & IFF_BROADCAST) != 0;
  } else {
    Global_Clatd_Config.use_dynamic_iid = 1;
  }

  return 1;

failed:
  free(root);
  return 0;
}

/* function; dump_config
 * prints the current config
 */
void dump_config() {
  char charbuffer[INET6_ADDRSTRLEN];

  logmsg(
    ANDROID_LOG_DEBUG, "ipv6_local_subnet = %s",
    inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, charbuffer, sizeof(charbuffer)));
  logmsg(
    ANDROID_LOG_DEBUG, "ipv4_local_subnet = %s",
    inet_ntop(AF_INET, &Global_Clatd_Config.ipv4_local_subnet, charbuffer, sizeof(charbuffer)));
  logmsg(ANDROID_LOG_DEBUG, "ipv4_local_prefixlen = %d", Global_Clatd_Config.ipv4_local_prefixlen);
  logmsg(ANDROID_LOG_DEBUG, "plat_subnet = %s",
         inet_ntop(AF_INET6, &Global_Clatd_Config.plat_subnet, charbuffer, sizeof(charbuffer)));
  logmsg(ANDROID_LOG_DEBUG, "default_pdp_interface = %s",
         Global_Clatd_Config.default_pdp_interface);
}
