/*
 * Copyright 2012 Daniel Drown <dan-android@drown.org>
 *
 * 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.
 *
 * setif.c - network interface configuration
 */
#include <errno.h>
#include <net/if.h>
#include <netinet/in.h>

#include <linux/rtnetlink.h>
#include <netlink/handlers.h>
#include <netlink/msg.h>

#include "logging.h"
#include "netlink_msg.h"

#define DEBUG_OPTNAME(a)                                                                           \
  case (a): {                                                                                      \
    optname = #a;                                                                                  \
    break;                                                                                         \
  }

/* function: add_address
 * adds an IP address to/from an interface, returns 0 on success and <0 on failure
 * ifname    - name of interface to change
 * family    - address family (AF_INET, AF_INET6)
 * address   - pointer to a struct in_addr or in6_addr
 * prefixlen - bitlength of network (example: 24 for AF_INET's 255.255.255.0)
 * broadcast - broadcast address (only for AF_INET, ignored for AF_INET6)
 */
int add_address(const char *ifname, int family, const void *address, int prefixlen,
                const void *broadcast) {
  int retval;
  size_t addr_size;
  struct ifaddrmsg ifa;
  struct nl_msg *msg = NULL;

  addr_size = inet_family_size(family);
  if (addr_size == 0) {
    retval = -EAFNOSUPPORT;
    goto cleanup;
  }

  memset(&ifa, 0, sizeof(ifa));
  if (!(ifa.ifa_index = if_nametoindex(ifname))) {
    retval = -ENODEV;
    goto cleanup;
  }
  ifa.ifa_family    = family;
  ifa.ifa_prefixlen = prefixlen;
  ifa.ifa_scope     = RT_SCOPE_UNIVERSE;

  msg =
    nlmsg_alloc_ifaddr(RTM_NEWADDR, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE, &ifa);
  if (!msg) {
    retval = -ENOMEM;
    goto cleanup;
  }

  if (nla_put(msg, IFA_LOCAL, addr_size, address) < 0) {
    retval = -ENOMEM;
    goto cleanup;
  }
  if (family == AF_INET6) {
    // AF_INET6 gets IFA_LOCAL + IFA_ADDRESS
    if (nla_put(msg, IFA_ADDRESS, addr_size, address) < 0) {
      retval = -ENOMEM;
      goto cleanup;
    }
  } else if (family == AF_INET) {
    // AF_INET gets IFA_LOCAL + IFA_BROADCAST
    if (nla_put(msg, IFA_BROADCAST, addr_size, broadcast) < 0) {
      retval = -ENOMEM;
      goto cleanup;
    }
  } else {
    retval = -EAFNOSUPPORT;
    goto cleanup;
  }

  retval = netlink_sendrecv(msg);

cleanup:
  if (msg) nlmsg_free(msg);

  return retval;
}

/* function: if_up
 * sets interface link state to up and sets mtu, returns 0 on success and <0 on failure
 * ifname - interface name to change
 * mtu    - new mtu
 */
int if_up(const char *ifname, int mtu) {
  int retval = -1;
  struct ifinfomsg ifi;
  struct nl_msg *msg = NULL;

  memset(&ifi, 0, sizeof(ifi));
  if (!(ifi.ifi_index = if_nametoindex(ifname))) {
    retval = -ENODEV;
    goto cleanup;
  }
  ifi.ifi_change = IFF_UP;
  ifi.ifi_flags  = IFF_UP;

  msg = nlmsg_alloc_ifinfo(RTM_SETLINK, NLM_F_ACK | NLM_F_REQUEST | NLM_F_ROOT, &ifi);
  if (!msg) {
    retval = -ENOMEM;
    goto cleanup;
  }

  if (nla_put(msg, IFLA_MTU, 4, &mtu) < 0) {
    retval = -ENOMEM;
    goto cleanup;
  }

  retval = netlink_sendrecv(msg);

cleanup:
  if (msg) nlmsg_free(msg);

  return retval;
}

static int do_anycast_setsockopt(int sock, int what, struct in6_addr *addr, int ifindex) {
  struct ipv6_mreq mreq = { *addr, ifindex };
  char *optname;
  int ret;

  switch (what) {
    DEBUG_OPTNAME(IPV6_JOIN_ANYCAST)
    DEBUG_OPTNAME(IPV6_LEAVE_ANYCAST)
    default:
      optname = "???";
      break;
  }

  ret = setsockopt(sock, SOL_IPV6, what, &mreq, sizeof(mreq));
  if (ret) {
    logmsg(ANDROID_LOG_ERROR, "%s: setsockopt(%s): %s", __func__, optname, strerror(errno));
  }

  return ret;
}

/* function: add_anycast_address
 * adds an anycast IPv6 address to an interface, returns 0 on success and <0 on failure
 * sock      - the socket to add the address to
 * addr      - the IP address to add
 * ifname    - name of interface to add the address to
 */
int add_anycast_address(int sock, struct in6_addr *addr, const char *ifname) {
  int ifindex;

  ifindex = if_nametoindex(ifname);
  if (!ifindex) {
    logmsg(ANDROID_LOG_ERROR, "%s: unknown ifindex for interface %s", __func__, ifname);
    return -ENODEV;
  }

  return do_anycast_setsockopt(sock, IPV6_JOIN_ANYCAST, addr, ifindex);
}

/* function: del_anycast_address
 * removes an anycast IPv6 address from the system, returns 0 on success and <0 on failure
 * sock      - the socket to remove from, must have had the address added via add_anycast_address
 * addr      - the IP address to remove
 */
int del_anycast_address(int sock, struct in6_addr *addr) {
  return do_anycast_setsockopt(sock, IPV6_LEAVE_ANYCAST, addr, 0);
}
