/* route.c - Display routing table.
 *
 * Copyright 2012 Ranjan Kumar <ranjankumar.bth@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
 *
 * No Standard
 *
USE_ROUTE(NEWTOY(route, "?neA:", TOYFLAG_BIN))
config ROUTE
  bool "route"
  default n
  help
    usage: route -neA inet{6} / [{add|del}]

    Display/Edit kernel routing tables.

    -n  Don't resolve names
    -e  Display other/more information
    -A  inet{6} Select Address Family
*/

#define FOR_route
#include "toys.h"
#include <net/route.h>
#include <sys/param.h>

GLOBALS(
  char *family;
)

#define DEFAULT_PREFIXLEN 128
#define INVALID_ADDR 0xffffffffUL
#define IPV6_ADDR_LEN 40 //32 + 7 (':') + 1 ('\0')

#define TEST_ARGV(argv) if (!*argv) show_route_help()

struct _arglist {
  char *arg;
  int action;
};

static struct _arglist arglist1[] = {
  { "add", 1 }, { "del", 2 },
  { "delete", 2 }, { NULL, 0 }
};

static struct _arglist arglist2[] = {
  { "-net", 1 }, { "-host", 2 },
  { NULL, 0 }
};

// display help info and exit.
static void show_route_help(void)
{
  toys.exithelp = 1;
  error_exit("Invalid Argument");
}

// to get the host name from the given ip.
static int get_hostname(char *ipstr, struct sockaddr_in *sockin)
{
  struct hostent *host;

  sockin->sin_family = AF_INET;
  sockin->sin_port = 0;

  if (!strcmp(ipstr, "default")) {
    sockin->sin_addr.s_addr = INADDR_ANY;
    return 1;
  }

  if (inet_aton(ipstr, &sockin->sin_addr)) return 0;
  if (!(host = gethostbyname(ipstr))) return -1;
  memcpy(&sockin->sin_addr, host->h_addr_list[0], sizeof(struct in_addr));
  return 0;
}

// used to extract the address info from the given ip.
static int get_addrinfo(char *ip, struct sockaddr_in6 *sock_in6)
{
  struct addrinfo hints, *result;
  int status = 0;

  memset(&hints, 0, sizeof(struct addrinfo));
  hints.ai_family = AF_INET6;
  if ((status = getaddrinfo(ip, NULL, &hints, &result))) {
    perror_msg("getaddrinfo: %s", gai_strerror(status));
    return -1;
  }
  if (result) {
    memcpy(sock_in6, result->ai_addr, sizeof(*sock_in6));
    freeaddrinfo(result);
  }
  return 0;
}

//get the flag values for route command.
static void get_flag_value(char *str, int flags)
{
  int i = 0;
  static unsigned flagarray[] = {
    RTF_GATEWAY, RTF_HOST, RTF_REINSTATE, RTF_DYNAMIC,
    RTF_MODIFIED, RTF_DEFAULT, RTF_ADDRCONF, RTF_CACHE
  };

  *str++ = 'U';
  while ((*str = "GHRDMDAC"[i]))
    if (flags & flagarray[i++]) ++str;
}

// extract inet4 route info from /proc/net/route file and display it.
static void display_routes(void)
{
  unsigned long dest, gate, mask;
  int flags, ref, use, metric, mss, win, irtt, items;
  char iface[64] = {0,}, flag_val[10]; //there are 9 flags "UGHRDMDAC" for route.

  FILE *fp = xfopen("/proc/net/route", "r");

  xprintf("Kernel IP routing table\n"
      "Destination     Gateway         Genmask         Flags %s Iface\n",
      (toys.optflags & FLAG_e)? "  MSS Window  irtt" : "Metric Ref    Use");

  if (fscanf(fp, "%*[^\n]\n") < 0) perror_exit("fscanf"); //skip 1st line
  while ((items = fscanf(fp, "%63s%lx%lx%X%d%d%d%lx%d%d%d\n", iface, &dest, 
          &gate, &flags, &ref, &use, &metric, &mask, &mss, &win, &irtt)) == 11) {

    char *destip = toybuf, *gateip = toybuf+32, *maskip = toybuf+64; //ip string 16
    memset(flag_val, 0, 10);

    if (!(flags & RTF_UP)) continue; //skip down interfaces.

    if (!dest && !(toys.optflags & FLAG_n)) strcpy( destip, "default");
    else if (!inet_ntop(AF_INET, &dest, destip, 32)) perror_exit("inet");

    if (!gate && !(toys.optflags & FLAG_n)) strcpy( gateip, "*");
    else if (!inet_ntop(AF_INET, &gate, gateip, 32)) perror_exit("inet");

    if (!inet_ntop(AF_INET, &mask, maskip, 32)) perror_exit("inet");

    //Get flag Values
    get_flag_value(flag_val, (flags & (RTF_GATEWAY|RTF_HOST|RTF_REINSTATE
            |RTF_DYNAMIC|RTF_MODIFIED)));
    if (flags & RTF_REJECT) flag_val[0] = '!';
    xprintf("%-15.15s %-15.15s %-16s%-6s", destip, gateip, maskip, flag_val);
    if (toys.optflags & FLAG_e) xprintf("%5d %-5d %6d %s\n", mss, win, irtt, iface);
    else xprintf("%-6d %-2d %7d %s\n", metric, ref, use, iface);
  }

  if (items > 0 && feof(fp)) perror_exit("fscanf %d", items);
  fclose(fp);
}


/*
 * find the given parameter in list like add/del/net/host.
 * and if match found return the appropriate action.
 */
static int get_action(char ***argv, struct _arglist *list)
{
  struct _arglist *alist;

  if (!**argv) return 0;
  for (alist = list; alist->arg; alist++) { //find the given parameter in list
    if (!strcmp(**argv, alist->arg)) {
      *argv += 1;
      return alist->action;
    }
  }
  return 0;
}

/*
 * get prefix len (if any) and remove the prefix from target ip.
 * if no prefix then set netmask as default.
 */
static void is_prefix(char **tip, char **netmask, struct rtentry *rt)
{
  char *prefix = strchr(*tip, '/');
  if (prefix) {
    unsigned long plen;
    plen = atolx_range(prefix + 1, 0, 32);
    //used to verify the netmask and route conflict.
    (((struct sockaddr_in *)&((rt)->rt_genmask))->sin_addr.s_addr)
      = htonl( ~(INVALID_ADDR >> plen));
    *prefix = '\0';
    rt->rt_genmask.sa_family = AF_INET;
  } else *netmask = "default"; //default netmask.
}

/*
 * used to get the params like: metric, netmask, gw, mss, window, irtt, dev and their values.
 * additionally set the flag values for reject, mod, dyn and reinstate.
 */
static void get_next_params(char **argv, struct rtentry *rt, char **netmask)
{
  while (*argv) {
    //set the metric field in the routing table.
    if (!strcmp(*argv, "metric")) {
      argv++;
      TEST_ARGV(argv);
      rt->rt_metric = atolx_range(*argv, 0, ULONG_MAX) + 1;
      argv++;
    } else if (!strcmp(*argv, "netmask")) {
      //when adding a network route, the netmask to be used.
      struct sockaddr sock;
      unsigned int addr_mask = (((struct sockaddr_in *)&((rt)->rt_genmask))->sin_addr.s_addr);
      if (addr_mask) show_route_help();
      argv++;
      TEST_ARGV(argv);
      *netmask = *argv;
      if (get_hostname(*netmask, (struct sockaddr_in *) &sock) < 0)
        perror_exit("resolving '%s'", *netmask);
      rt->rt_genmask = sock;
      argv++;
    } else if (!strcmp(*argv, "gw")) { 
      //route packets via a gateway.
      if (!(rt->rt_flags & RTF_GATEWAY)) {
        int ishost;
        argv++;
        TEST_ARGV(argv);
        if ((ishost = get_hostname(*argv, (struct sockaddr_in *) &rt->rt_gateway)) == 0) {
          rt->rt_flags |= RTF_GATEWAY;
          argv++;
        } else if (ishost < 0) perror_exit("resolving '%s'", *argv);
        else perror_exit("gateway '%s' is a NETWORK", *argv);
      } else show_route_help();
    } else if (!strcmp(*argv, "mss")) {
      //set the TCP Maximum Segment Size for connections over this route.
      argv++;
      TEST_ARGV(argv);
      rt->rt_mss = atolx_range(*argv, 64, 32768); //MSS low and max
      rt->rt_flags |= RTF_MSS;
      argv++;
    } else if (!strcmp(*argv, "window")) {
      //set the TCP window size for connections over this route to W bytes.
      argv++;
      TEST_ARGV(argv);
      rt->rt_window = atolx_range(*argv, 128, INT_MAX); //win low
      rt->rt_flags |= RTF_WINDOW;
      argv++;
    } else if (!strcmp(*argv, "irtt")) {
      long nclock_ticks = sysconf(_SC_CLK_TCK); //number of clock ticks per second.
      argv++;
      TEST_ARGV(argv);
      nclock_ticks /= 100;
      rt->rt_irtt = strtoul(*argv, NULL, 10);
      if (nclock_ticks > 0) rt->rt_irtt *= nclock_ticks;
      rt->rt_flags |= 0x0100; //RTF_IRTT
      argv++;
    } else if (!strcmp(*argv, "dev")) {
      argv++;
      TEST_ARGV(argv);
      if ((!rt->rt_dev)) rt->rt_dev = *argv;
      argv++;
    } else if (!strcmp(*argv, "reject")) {
      rt->rt_flags |= RTF_REJECT;
      argv++;
    } else if (!strcmp(*argv, "mod")) {
      rt->rt_flags |= RTF_MODIFIED;
      argv++;
    } else if (!strcmp(*argv, "dyn")) {
      rt->rt_flags |= RTF_DYNAMIC;
      argv++;
    } else if (!strcmp(*argv, "reinstate")) {
      rt->rt_flags |= RTF_REINSTATE;
      argv++;
    } else show_route_help();  //No match found; exit form the application.
  }//end of while loop.

  if (!rt->rt_dev && (rt->rt_flags & RTF_REJECT)) rt->rt_dev = (char *)"lo";
}

// verify the netmask and conflict in netmask and route address.
static void verify_netmask(struct rtentry *rt, char *netmask)
{
  unsigned int addr_mask = (((struct sockaddr_in *)&((rt)->rt_genmask))->sin_addr.s_addr);
  unsigned int router_addr = ~(unsigned int)(((struct sockaddr_in *)&((rt)->rt_dst))->sin_addr.s_addr);

  if (addr_mask) {
    addr_mask = ~ntohl(addr_mask);
    if ((rt->rt_flags & RTF_HOST) && addr_mask != INVALID_ADDR)
      perror_exit("conflicting netmask and host route");
    if (addr_mask & (addr_mask + 1)) perror_exit("wrong netmask '%s'", netmask);
    addr_mask = ((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr;
    if (addr_mask & router_addr) perror_exit("conflicting netmask and route address");
  }
}

// add/del a route.
static void setroute(char **argv)
{
  struct rtentry rt;
  char *netmask = NULL, *targetip;
  int is_net_or_host = 0, sokfd, arg2_action;
  int action = get_action(&argv, arglist1); //verify the arg for add/del.

  if (!action || !*argv) show_route_help();

  arg2_action = get_action(&argv, arglist2); //verify the arg for -net or -host
  if (!*argv) show_route_help(); 

  memset(&rt, 0, sizeof(struct rtentry));
  targetip = *argv++;

  is_prefix((char **)&targetip, (char **)&netmask, &rt);
  if ((is_net_or_host = get_hostname(targetip, 
          (struct sockaddr_in *) &rt.rt_dst)) < 0)
    perror_exit("resolving '%s'", targetip);

  if (arg2_action) is_net_or_host = arg2_action & 1;
  rt.rt_flags = ((is_net_or_host) ? RTF_UP : (RTF_UP | RTF_HOST));

  get_next_params(argv, &rt, (char **)&netmask);
  verify_netmask(&rt, (char *)netmask);

  if ((action == 1) && (rt.rt_flags & RTF_HOST))
    (((struct sockaddr_in *)&((rt).rt_genmask))->sin_addr.s_addr) = INVALID_ADDR;

  sokfd = xsocket(AF_INET, SOCK_DGRAM, 0);
  if (action == 1) xioctl(sokfd, SIOCADDRT, &rt);
  else xioctl(sokfd, SIOCDELRT, &rt);
  xclose(sokfd);
}

/*
 * get prefix len (if any) and remove the prefix from target ip.
 * if no prefix then set default prefix len.
 */
static void is_prefix_inet6(char **tip, struct in6_rtmsg *rt)
{
  unsigned long plen;
  char *prefix = strchr(*tip, '/');

  if (prefix) {
    *prefix = '\0';
    plen = atolx_range(prefix + 1, 0, 128); //DEFAULT_PREFIXLEN);
  } else plen = DEFAULT_PREFIXLEN;

  rt->rtmsg_flags = (plen == DEFAULT_PREFIXLEN) ? (RTF_UP | RTF_HOST) : RTF_UP;
  rt->rtmsg_dst_len = plen;
}

/*
 * used to get the params like: metric, gw, dev and their values.
 * additionally set the flag values for mod and dyn.
 */
static void get_next_params_inet6(char **argv, struct sockaddr_in6 *sock_in6, struct in6_rtmsg *rt, char **dev_name)
{
  while (*argv) {
    if (!strcmp(*argv, "metric")) {
      //set the metric field in the routing table.
      argv++;
      TEST_ARGV(argv);
      rt->rtmsg_metric = atolx_range(*argv, 0, ULONG_MAX);
      argv++;
    } else if (!strcmp(*argv, "gw")) {
      //route packets via a gateway.
      if (!(rt->rtmsg_flags & RTF_GATEWAY)) {
        argv++;
        TEST_ARGV(argv);
        if (!get_addrinfo(*argv, (struct sockaddr_in6 *) &sock_in6)) {
          memcpy(&rt->rtmsg_gateway, sock_in6->sin6_addr.s6_addr, sizeof(struct in6_addr));
          rt->rtmsg_flags |= RTF_GATEWAY;
          argv++;
        } else perror_exit("resolving '%s'", *argv);
      } else show_route_help();
    } else if (!strcmp(*argv, "dev")) {
      argv++;
      TEST_ARGV(argv);
      if (!*dev_name) *dev_name = *argv;
      argv++;
    } else if (!strcmp(*argv, "mod")) {
      rt->rtmsg_flags |= RTF_MODIFIED;
      argv++;
    } else if (!strcmp(*argv, "dyn")) {
      rt->rtmsg_flags |= RTF_DYNAMIC;
      argv++;
    } else show_route_help();
  }//end of while loop.
}

// add/del a route.
static void setroute_inet6(char **argv)
{
  struct sockaddr_in6 sock_in6;
  struct in6_rtmsg rt;
  char *targetip;
  int sockfd, action = get_action(&argv, arglist1);

  if (!action || !*argv) show_route_help();
  memset(&sock_in6, 0, sizeof(struct sockaddr_in6));
  memset(&rt, 0, sizeof(struct in6_rtmsg));
  targetip = *argv++;
  if (*argv) {
    unsigned long plen = 0;
    char *dev_name = NULL;
    if (!strcmp(targetip, "default")) {
      rt.rtmsg_flags = RTF_UP;
      rt.rtmsg_dst_len = plen;
    } else {
      is_prefix_inet6((char **)&targetip, &rt);
      if (get_addrinfo(targetip, (struct sockaddr_in6 *) &sock_in6))
        perror_exit("resolving '%s'", targetip);
    }
    rt.rtmsg_metric = 1; //default metric.
    memcpy(&rt.rtmsg_dst, sock_in6.sin6_addr.s6_addr, sizeof(struct in6_addr));
    get_next_params_inet6(argv, &sock_in6, &rt, (char **)&dev_name);

    sockfd = xsocket(AF_INET6, SOCK_DGRAM, 0);
    if (dev_name) {
      char ifre_buf[sizeof(struct ifreq)] = {0,};
      struct ifreq *ifre = (struct ifreq*)ifre_buf;
      strncpy(ifre->ifr_name, dev_name, IFNAMSIZ-1);
      xioctl(sockfd, SIOGIFINDEX, ifre);
      rt.rtmsg_ifindex = ifre->ifr_ifindex;
    }          
    if (action == 1) xioctl(sockfd, SIOCADDRT, &rt);
    else xioctl(sockfd, SIOCDELRT, &rt);
    xclose(sockfd);
  } else show_route_help();
}

/*
 * format the dest and src address in ipv6 format.
 * e.g. 2002:6b6d:26c8:d:ea03:9aff:fe65:9d62
 */
static void ipv6_addr_formating(char *ptr, char *addr)
{
  int i = 0;
  while (i <= IPV6_ADDR_LEN) {
    if (!*ptr) {
      if (i == IPV6_ADDR_LEN) {
        addr[IPV6_ADDR_LEN - 1] = 0; //NULL terminating the ':' seperated address.
        break;
      }
      error_exit("IPv6 ip format error");
    }
    addr[i++] = *ptr++;
    if (!((i+1) % 5)) addr[i++] = ':'; //put ':' after 4th bit
  }
}

static void display_routes6(void)
{
  char iface[16] = {0,}, ipv6_dest_addr[41]; 
  char ipv6_src_addr[41], flag_val[10], buf2[INET6_ADDRSTRLEN];
  int prefixlen, metric, use, refcount, flag, items = 0;
  unsigned char buf[sizeof(struct in6_addr)];

  FILE *fp = xfopen("/proc/net/ipv6_route", "r");

  xprintf("Kernel IPv6 routing table\n"
      "%-43s%-40s Flags Metric Ref    Use Iface\n", "Destination", "Next Hop");

  while ((items = fscanf(fp, "%32s%x%*s%*x%32s%x%x%x%x%10s\n", ipv6_dest_addr+8,
          &prefixlen, ipv6_src_addr+8, &metric, &use, &refcount, &flag, 
          iface)) == 8) {

    memset(flag_val, 0, 10);

    if (!(flag & RTF_UP)) continue; //skip down interfaces.

    //ipv6_dest_addr+8: as the values are filled from the 8th location of the array.
    ipv6_addr_formating(ipv6_dest_addr+8, ipv6_dest_addr);
    ipv6_addr_formating(ipv6_src_addr+8, ipv6_src_addr);

    get_flag_value(flag_val, (flag & (RTF_GATEWAY|RTF_HOST|RTF_DEFAULT|
            RTF_ADDRCONF|RTF_CACHE)));
    if (inet_pton(AF_INET6, ipv6_dest_addr, buf) <= 0) perror_exit("inet");
    if (inet_ntop(AF_INET6, buf, buf2, INET6_ADDRSTRLEN)) {
      sprintf(toybuf, "%s/%d", buf2, prefixlen);
    }

    if (inet_pton(AF_INET6, ipv6_src_addr, buf) <= 0) perror_exit("inet");
    if (inet_ntop(AF_INET6, buf, buf2, INET6_ADDRSTRLEN)) {
      xprintf("%-43s %-39s %-5s %-6d %-4d %5d %-8s\n",
          toybuf, buf2, flag_val, metric, refcount, use, iface);
    }
  }
  if ((items > 0) && feof(fp)) perror_exit("fscanf");

  fclose(fp);
}

void route_main(void)
{
  if (!(toys.optflags & FLAG_A)) TT.family = "inet";
  if (!*toys.optargs) {
    if (!strcmp(TT.family, "inet")) display_routes();
    else if (!strcmp(TT.family, "inet6")) display_routes6();
    else show_route_help();
    return;
  }//End of if statement.

  if (!strcmp(TT.family, "inet6")) setroute_inet6(toys.optargs);
  else setroute(toys.optargs);
}
