/*
 * 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.
 *
 * netlink_msg.c - send an ifaddrmsg/ifinfomsg/rtmsg via netlink
 */

#include <netinet/in.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <string.h>
#include <errno.h>

#include <netlink-private/object-api.h>
#include <netlink-private/types.h>
#include <netlink/socket.h>
#include <netlink/netlink.h>
#include <netlink/msg.h>

#include "netlink_msg.h"
#include "netlink_callbacks.h"

/* function: family_size
 * returns the size of the address structure for the given family, or 0 on error
 * family - AF_INET or AF_INET6
 */
size_t inet_family_size(int family) {
  if(family == AF_INET) {
    return sizeof(struct in_addr);
  } else if(family == AF_INET6) {
    return sizeof(struct in6_addr);
  } else {
    return 0;
  }
}

/* function: nlmsg_alloc_generic
 * allocates a netlink message with the given struct inside of it. returns NULL on failure
 * type           - netlink message type
 * flags          - netlink message flags
 * payload_struct - pointer to a struct to add to netlink message
 * payload_len    - bytelength of structure
 */
struct nl_msg *nlmsg_alloc_generic(uint16_t type, uint16_t flags, void *payload_struct, size_t payload_len) {
  struct nl_msg *msg;

  msg = nlmsg_alloc();
  if(!msg) {
    return NULL;
  }

  if ((sizeof(struct nl_msg) + payload_len) > msg->nm_size) {
    nlmsg_free(msg);
    return NULL;
  }

  msg->nm_nlh->nlmsg_len = NLMSG_LENGTH(payload_len);
  msg->nm_nlh->nlmsg_flags = flags;
  msg->nm_nlh->nlmsg_type = type;

  memcpy(nlmsg_data(msg->nm_nlh), payload_struct, payload_len);

  return msg;
}

/* function: nlmsg_alloc_ifaddr
 * allocates a netlink message with a struct ifaddrmsg inside of it. returns NULL on failure
 * type  - netlink message type
 * flags - netlink message flags
 * ifa   - ifaddrmsg to copy into the new netlink message
 */
struct nl_msg *nlmsg_alloc_ifaddr(uint16_t type, uint16_t flags, struct ifaddrmsg *ifa) {
  return nlmsg_alloc_generic(type, flags, ifa, sizeof(*ifa));
}

/* function: nlmsg_alloc_ifinfo
 * allocates a netlink message with a struct ifinfomsg inside of it. returns NULL on failure
 * type  - netlink message type
 * flags - netlink message flags
 * ifi   - ifinfomsg to copy into the new netlink message
 */
struct nl_msg *nlmsg_alloc_ifinfo(uint16_t type, uint16_t flags, struct ifinfomsg *ifi) {
  return nlmsg_alloc_generic(type, flags, ifi, sizeof(*ifi));
}

/* function: nlmsg_alloc_rtmsg
 * allocates a netlink message with a struct rtmsg inside of it. returns NULL on failure
 * type  - netlink message type
 * flags - netlink message flags
 * rt    - rtmsg to copy into the new netlink message
 */
struct nl_msg *nlmsg_alloc_rtmsg(uint16_t type, uint16_t flags, struct rtmsg *rt) {
  return nlmsg_alloc_generic(type, flags, rt, sizeof(*rt));
}

/* function: netlink_set_kernel_only
 * sets a socket to receive messages only from the kernel
 * sock - socket to connect
 */
int netlink_set_kernel_only(struct nl_sock *nl_sk) {
  struct sockaddr_nl addr = { AF_NETLINK, 0, 0, 0 };

  if (!nl_sk) {
    return -EFAULT;
  }

  int sockfd = nl_socket_get_fd(nl_sk);
  return connect(sockfd, (struct sockaddr *) &addr, sizeof(addr));
}

/* function: send_netlink_msg
 * sends a netlink message, reads a response, and hands the response(s) to the callbacks
 * msg       - netlink message to send
 * callbacks - callbacks to use on responses
 */
void send_netlink_msg(struct nl_msg *msg, struct nl_cb *callbacks) {
  struct nl_sock *nl_sk;

  nl_sk = nl_socket_alloc();
  if(!nl_sk)
    goto cleanup;

  if(nl_connect(nl_sk, NETLINK_ROUTE) != 0)
    goto cleanup;

  if(nl_send_auto_complete(nl_sk, msg) < 0)
    goto cleanup;

  if(netlink_set_kernel_only(nl_sk) < 0)
    goto cleanup;

  nl_recvmsgs(nl_sk, callbacks);

cleanup:
  if(nl_sk)
    nl_socket_free(nl_sk);
}

/* function: send_ifaddrmsg
 * sends a netlink/ifaddrmsg message and hands the responses to the callbacks
 * type      - netlink message type
 * flags     - netlink message flags
 * ifa       - ifaddrmsg to send
 * callbacks - callbacks to use with the responses
 */
void send_ifaddrmsg(uint16_t type, uint16_t flags, struct ifaddrmsg *ifa, struct nl_cb *callbacks) {
  struct nl_msg *msg = NULL;

  msg = nlmsg_alloc_ifaddr(type, flags, ifa);
  if(!msg)
    return;

  send_netlink_msg(msg, callbacks);

  nlmsg_free(msg);
}

/* function: netlink_sendrecv
 * send a nl_msg and return an int status - only supports OK/ERROR responses
 * msg - msg to send
 */
int netlink_sendrecv(struct nl_msg *msg) {
  struct nl_cb *callbacks = NULL;
  int retval = -EIO;

  callbacks = alloc_ack_callbacks(&retval);
  if(!callbacks) {
    return -ENOMEM;
  }

  send_netlink_msg(msg, callbacks);

  nl_cb_put(callbacks);

  return retval;
}
