/* arp.c - manipulate the system ARP cache
 *
 * Copyright 2014 Sandeep Sharma <sandeep.jack2756@gmail.com>
 * Copyright 2014 Kyungwan Han <asura321@gamil.com>
 * No Standard 

USE_ARP(NEWTOY(arp, "vi:nDsdap:A:H:[+Ap][!sd]", TOYFLAG_USR|TOYFLAG_BIN))

config ARP
  bool "arp"
  default n
  help
    usage: arp
    [-vn] [-H HWTYPE] [-i IF] -a [HOSTNAME]
    [-v]              [-i IF] -d HOSTNAME [pub]
    [-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp]
    [-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub
    [-v]  [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub

    Manipulate ARP cache

    -a    Display (all) hosts
    -s    Set new ARP entry
    -d    Delete a specified entry
    -v    Verbose
    -n    Don't resolve names
    -i IF Network interface
    -D    Read <hwaddr> from given device
    -A,-p AF  Protocol family
    -H    HWTYPE Hardware address type

*/

#define FOR_arp
#include "toys.h"
#include <net/if_arp.h>

GLOBALS(
    char *hw_type;
    char *af_type_A;
    char *af_type_p;
    char *interface;
    
    int sockfd;
    char *device;
)

struct arpreq req; //Global request structure 

struct type {
  char *name;
  int val;
};

struct type hwtype[] = {
  {"ether", ARPHRD_ETHER }, 
  {"loop" ,ARPHRD_LOOPBACK},
  {"ppp" ,ARPHRD_PPP},
  {"infiniband" ,ARPHRD_INFINIBAND},
  {NULL, -1},
};

struct type aftype[] = {
  {"inet", AF_INET }, 
  {"inet6" ,AF_INET6},
  {"unspec" ,AF_UNSPEC},
  {NULL, -1},
};

struct type flag_type[] = {
  {"PERM", ATF_PERM }, 
  {"PUB" ,ATF_PUBL},
  {"DONTPUB" ,ATF_DONTPUB},
  {"TRAIL" ,ATF_USETRAILERS},
  {NULL, -1},
};

static int get_index(struct type arr[], char *name)
{
  int i;
  
  for (i = 0; arr[i].name; i++) 
    if (!strcmp(arr[i].name, name)) break;
  return arr[i].val;
}

static void resolve_host(char *host, struct sockaddr *sa)
{
  struct addrinfo hints, *res = NULL;
  int ret;

  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_STREAM;
  if ((ret = getaddrinfo(host, NULL, &hints, &res))) 
    perror_exit("%s", gai_strerror(ret));

  memcpy(sa, res->ai_addr, res->ai_addrlen);
  freeaddrinfo(res);
}

static void check_flags(int *i, char** argv)
{
  struct sockaddr sa;
  int flag = *i, j;
  struct flags {
    char *name;
    int or, flag;
  } f[] = {
    {"pub",  1 ,ATF_PUBL},
    {"priv", 0 ,~ATF_PUBL},
    {"trail", 1, ATF_USETRAILERS},
    {"temp", 0, ~ATF_PERM},
    {"dontpub",1, ATF_DONTPUB},
  };
  
  for (;*argv; argv++) {
    for (j = 0;  j < ARRAY_LEN(f); j++) { 
      if (!strcmp(*argv, f[j].name)) {
        (f[j].or) ?(flag |= f[j].flag):(flag &= f[j].flag);
        break;
      }
    }
    if (j > 4 && !strcmp(*argv, "netmask")) {
      if (!*++argv) error_exit("NULL netmask");
      if (strcmp(*argv, "255.255.255.255")) {
        resolve_host(toys.optargs[0], &sa);
        memcpy(&req.arp_netmask, &sa, sizeof(sa));
        flag |= ATF_NETMASK;
      } else argv++; 
    } else if (j > 4 && !strcmp(*argv, "dev")) {
      if (!*++argv) error_exit("NULL dev");
      TT.device = *argv;
    } else if (j > 4) error_exit("invalid arg");
  }
  *i = flag;
}

static int set_entry(void) 
{
  int flags = 0;
  
  if (!toys.optargs[1]) error_exit("bad syntax");

  if (!(toys.optflags & FLAG_D)) {
    char *ptr = toys.optargs[1];
    char *p = ptr, *hw_addr = req.arp_ha.sa_data;

    while (*hw_addr && (p-ptr) < 6) {
      int val, len;

      if (*hw_addr == ':') hw_addr++;
      if (!sscanf(hw_addr, "%2x%n", &val, &len)) break;
      hw_addr += len;
      *p++ = val;
    }

    if ((p-ptr) != 6 || *hw_addr)
      error_exit("bad hw addr '%s'", req.arp_ha.sa_data);
  } else {
    struct ifreq ifre;

    xstrncpy(ifre.ifr_name, toys.optargs[1], IFNAMSIZ);
    xioctl(TT.sockfd, SIOCGIFHWADDR, &ifre);
    if ((toys.optflags & FLAG_H) && (ifre.ifr_hwaddr.sa_family != ARPHRD_ETHER)) 
      error_exit("protocol type mismatch");
    memcpy(&req.arp_ha, &(ifre.ifr_hwaddr), sizeof(req.arp_ha));
  }

  flags = ATF_PERM | ATF_COM;
  if (toys.optargs[2]) check_flags(&flags, (toys.optargs+2));
  req.arp_flags = flags;
  xstrncpy(req.arp_dev, TT.device, sizeof(req.arp_dev));
  xioctl(TT.sockfd, SIOCSARP, &req);
  
  if (toys.optflags & FLAG_v) xprintf("Entry set for %s\n", toys.optargs[0]);
  return 0;
}

static int ip_to_host(struct sockaddr *sa, int flag) 
{
  int status = 0;
  char hbuf[NI_MAXHOST] = {0,}, sbuf[NI_MAXSERV] = {0,}; 
  socklen_t len = sizeof(struct sockaddr_in6);
  
  *toybuf = 0;
  if (!(status = getnameinfo(sa, len, hbuf, sizeof(hbuf), sbuf, 
          sizeof(sbuf), flag))) {
    strcpy(toybuf, hbuf);
    return 0;
  }
  return 1;
}

static int delete_entry(void)
{
  int flags;
  
  flags = ATF_PERM;
  if (toys.optargs[1]) check_flags(&flags, (toys.optargs+1));
  req.arp_flags = flags;
  xstrncpy(req.arp_dev, TT.device, sizeof(req.arp_dev));
  xioctl(TT.sockfd, SIOCDARP, &req);
  
  if (toys.optflags & FLAG_v) xprintf("Delete entry for  %s\n", toys.optargs[0]);
  return 0;
}

void arp_main(void)
{
  struct sockaddr sa;
  char ip[128], hw_addr[128], mask[12], dev[128], *host_ip = NULL, *buf;
  int h_type, type, flag, i, fd, entries = 0, disp = 0;

  TT.device = "";
  memset(&sa, 0, sizeof(sa));
  memset(&req, 0, sizeof(req));
  TT.sockfd = xsocket(AF_INET, SOCK_STREAM, 0);

  if ((toys.optflags & FLAG_A) || (toys.optflags & FLAG_p)) {
    if ((type = get_index(aftype, 
            (TT.af_type_A)?TT.af_type_A:TT.af_type_p)) != AF_INET) 
      error_exit((type != -1)?"only inet supported by kernel":"unknown family");
  } 

  req.arp_ha.sa_family = ARPHRD_ETHER;
  if (toys.optflags & FLAG_H) {
    if ((type = get_index(hwtype, TT.hw_type)) != ARPHRD_ETHER) 
      error_exit((type != -1)?"h/w type not supported":"unknown h/w type");
    req.arp_ha.sa_family = type;
  }

  if (((toys.optflags & FLAG_s) || toys.optflags & FLAG_d)) { 
    if (!toys.optargs[0]) error_exit("host name req");
    resolve_host(toys.optargs[0], &sa);
    memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr));
  }

  if ((toys.optflags & FLAG_s) && !set_entry()) return;
  if ((toys.optflags & FLAG_d) && !delete_entry()) return; 

  //show arp chache
  fd = xopenro("/proc/net/arp");
  buf = get_line(fd);
  free(buf); //skip first line

  if (toys.optargs[0]) {
    resolve_host(toys.optargs[0], &sa);
    ip_to_host(&sa, NI_NUMERICHOST);
    host_ip = xstrdup(toybuf);
  }

  while ((buf = get_line(fd))) {
    char *host_name = "?";
    
    if ((sscanf(buf, "%s 0x%x 0x%x %s %s %s\n", ip,
        &h_type, &flag, hw_addr, mask, dev )) != 6) break;
    entries++;
    if (((toys.optflags & FLAG_H) && (get_index(hwtype, TT.hw_type) != h_type))
     || ((toys.optflags & FLAG_i) && strcmp(TT.interface, dev))
     || (toys.optargs[0] && strcmp(host_ip, ip))) {
      free(buf);
      continue;
    }

    resolve_host(buf, &sa);
    if (!(toys.optflags & FLAG_n)) { 
      if (!ip_to_host(&sa, NI_NAMEREQD)) host_name = toybuf;
    } else ip_to_host(&sa, NI_NUMERICHOST);
    
    disp++;
    printf("%s (%s) at" , host_name, ip);

    for (i = 0; hwtype[i].name; i++) 
      if (hwtype[i].val & h_type) break;
    if (!hwtype[i].name) error_exit("unknown h/w type");

    if (!(flag & ATF_COM)) {
      if ((flag & ATF_PUBL)) printf(" *");
      else printf(" <incomplete>");
    } else printf(" %s [%s]", hw_addr, hwtype[i].name);

    if (flag & ATF_NETMASK) printf("netmask %s ", mask);

    for (i = 0; flag_type[i].name; i++) 
      if (flag_type[i].val & flag) printf(" %s", flag_type[i].name);

    printf(" on %s\n", dev);
    free(buf);
  }
  
  if (toys.optflags & FLAG_v) 
    xprintf("Entries: %d\tSkipped: %d\tFound: %d\n",
        entries, entries - disp, disp);
  if (!disp) xprintf("No Match found in %d entries\n", entries);
  
  if (CFG_TOYBOX_FREE) {
    free(host_ip);
    free(buf);
    xclose(fd);
  }
}
