/*
 * Copyright 2012 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.
 *
 * getaddr.c - get a locally configured address
 */
#include <netinet/in.h>
#include <strings.h>
#include <string.h>
#include <net/if.h>

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

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

// shared state between getinterface_ip and getaddr_cb
struct target {
  int family;
  unsigned int ifindex;
  union anyip ip;
  int foundip;
};

/* function: getaddr_cb
 * callback for getinterface_ip
 * msg  - netlink message
 * data - (struct target) info for which address we're looking for
 */
static int getaddr_cb(struct nl_msg *msg, void *data) {
  struct ifaddrmsg *ifa_p;
  struct rtattr *rta_p;
  int rta_len;
  struct target *targ_p = (struct target *)data;

  ifa_p = (struct ifaddrmsg *)nlmsg_data(nlmsg_hdr(msg));
  rta_p = (struct rtattr *)IFA_RTA(ifa_p);

  if(ifa_p->ifa_index != targ_p->ifindex)
    return NL_OK;

  if(ifa_p->ifa_scope != RT_SCOPE_UNIVERSE)
    return NL_OK;

  rta_len = RTM_PAYLOAD(nlmsg_hdr(msg));
  for (; RTA_OK(rta_p, rta_len); rta_p = RTA_NEXT(rta_p, rta_len)) {
    switch(rta_p->rta_type) {
      case IFA_ADDRESS:
        if((targ_p->family == AF_INET6) && !(ifa_p->ifa_flags & IFA_F_SECONDARY)) {
          memcpy(&targ_p->ip.ip6, RTA_DATA(rta_p), rta_p->rta_len - sizeof(struct rtattr));
          targ_p->foundip = 1;
          return NL_OK;
        }
        break;
      case IFA_LOCAL:
        if(targ_p->family == AF_INET) {
          memcpy(&targ_p->ip.ip4, RTA_DATA(rta_p), rta_p->rta_len - sizeof(struct rtattr));
          targ_p->foundip = 1;
          return NL_OK;
        }
        break;
    }
  }

  return NL_OK;
}

/* function: error_handler
 * error callback for getinterface_ip
 * nla  - source of the error message
 * err  - netlink message
 * arg  - (struct target) info for which address we're looking for
 */
static int error_handler(__attribute__((unused)) struct sockaddr_nl *nla,
                         __attribute__((unused)) struct nlmsgerr *err,
                         __attribute__((unused)) void *arg) {
  return NL_OK;
}

/* function: getinterface_ip
 * finds the first global non-privacy IP of the given family for the given interface, or returns NULL.  caller frees pointer
 * interface - interface to look for
 * family    - family
 */
union anyip *getinterface_ip(const char *interface, int family) {
  struct ifaddrmsg ifa;
  struct nl_cb *callbacks = NULL;
  struct target targ;
  union anyip *retval = NULL;

  targ.family = family;
  targ.foundip = 0;
  targ.ifindex = if_nametoindex(interface);
  if(targ.ifindex == 0) {
    return NULL; // interface not found
  }

  memset(&ifa, 0, sizeof(ifa));
  ifa.ifa_family = targ.family;

  callbacks = nl_cb_alloc(NL_CB_DEFAULT);
  if(!callbacks) {
    goto cleanup;
  }
  nl_cb_set(callbacks, NL_CB_VALID, NL_CB_CUSTOM, getaddr_cb, &targ);
  nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, &targ);

  // sends message and waits for a response
  send_ifaddrmsg(RTM_GETADDR, NLM_F_REQUEST | NLM_F_ROOT, &ifa, callbacks);

  if(targ.foundip) {
    retval = malloc(sizeof(union anyip));
    if(!retval) {
      logmsg(ANDROID_LOG_FATAL,"getinterface_ip/out of memory");
      goto cleanup;
    }
    memcpy(retval, &targ.ip, sizeof(union anyip));
  }

cleanup:
  if(callbacks)
    nl_cb_put(callbacks);

  return retval;
}
