/*
 * 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 <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <limits.h>
#include <errno.h>
#include <unistd.h>

//#include <cutils/config_utils.h>
#include "ifc.h"
#include "config_utils.h"

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

void arc4random_buf(void *buf, size_t n);

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: free_config
 * frees the memory used by the global config variable
 */
void free_config() {
  if(Global_Clatd_Config.plat_from_dns64_hostname) {
    free(Global_Clatd_Config.plat_from_dns64_hostname);
    Global_Clatd_Config.plat_from_dns64_hostname = NULL;
  }
}

/* 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(Global_Clatd_Config.plat_from_dns64_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);
  //arc4random_addrandom(&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, 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 = 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_int16_t(root, "mtu", "-1", &Global_Clatd_Config.mtu))
    goto failed;

  if(!config_item_int16_t(root, "ipv4mtu", "-1", &Global_Clatd_Config.ipv4mtu))
    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);

      if(!(Global_Clatd_Config.plat_from_dns64_hostname = config_item_str(root, "plat_from_dns64_hostname", DEFAULT_DNS64_DETECTION_HOSTNAME)))
        goto failed;
      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);
  free_config();
  return 0;
}

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

  logmsg(ANDROID_LOG_DEBUG,"mtu = %d",Global_Clatd_Config.mtu);
  logmsg(ANDROID_LOG_DEBUG,"ipv4mtu = %d",Global_Clatd_Config.ipv4mtu);
  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);
}
