/* ifconfig.c - Configure network interface.
 *
 * Copyright 2012 Ranjan Kumar <ranjankumar.bth@gmail.com>
 * Copyright 2012 Kyungwan Han <asura321@gamil.com>
 * Reviewed by Kyungsu Kim <kaspyx@gmail.com>
 *
 * Not in SUSv4.

USE_IFCONFIG(NEWTOY(ifconfig, "^?a", TOYFLAG_SBIN))

config IFCONFIG
  bool "ifconfig"
  default y
  help
    usage: ifconfig [-a] [INTERFACE [ACTION...]]

    Display or configure network interface.

    With no arguments, display active interfaces. First argument is interface
    to operate on, one argument by itself displays that interface.

    -a	Show all interfaces, not just active ones

    Additional arguments are actions to perform on the interface:

    ADDRESS[/NETMASK] - set IPv4 address (1.2.3.4/5)
    default - unset ipv4 address
    add|del ADDRESS[/PREFIXLEN] - add/remove IPv6 address (1111::8888/128)
    up - enable interface
    down - disable interface

    netmask|broadcast|pointopoint ADDRESS - set more IPv4 characteristics
    hw ether|infiniband ADDRESS - set LAN hardware address (AA:BB:CC...)
    txqueuelen LEN - number of buffered packets before output blocks
    mtu LEN - size of outgoing packets (Maximum Transmission Unit)

    Flags you can set on an interface (or -remove by prefixing with -):
    arp - don't use Address Resolution Protocol to map LAN routes
    promisc - don't discard packets that aren't to this LAN hardware address
    multicast - force interface into multicast mode if the driver doesn't
    allmulti - promisc for multicast packets

    Obsolete fields included for historical purposes:
    irq|io_addr|mem_start ADDR - micromanage obsolete hardware
    outfill|keepalive INTEGER - SLIP analog dialup line quality monitoring
    metric INTEGER - added to Linux 0.9.10 with comment "never used", still true
*/

#define FOR_ifconfig
#include "toys.h"

#include <net/if_arp.h>
#include <net/ethernet.h>

GLOBALS(
  int sockfd;
)

// Convert hostname to binary address for AF_INET or AF_INET6
// return /prefix (or range max if none)
int get_addrinfo(char *host, sa_family_t af, void *addr)
{
  struct addrinfo hints, *result, *rp = 0;
  int status, len;
  char *from, *slash;

  memset(&hints, 0 , sizeof(struct addrinfo));
  hints.ai_family = af;
  hints.ai_socktype = SOCK_STREAM;

  slash = strchr(host, '/');
  if (slash) *slash = 0;

  status = getaddrinfo(host, NULL, &hints, &result);
  if (!status)
    for (rp = result; rp; rp = rp->ai_next)
      if (rp->ai_family == af) break;
  if (!rp) error_exit("bad address '%s' : %s", host, gai_strerror(status));

  // ai_addr isn't struct in_addr or in6_addr, it's struct sockaddr. Of course.
  // You'd think ipv4 and ipv6 would have some basic compatibility, but no.
  from = ((char *)rp->ai_addr) + 4;
  if (af == AF_INET6) {
    len = 16;
    from += 4;  // skip "flowinfo" field ipv6 puts before address
  } else len = 4;
  memcpy(addr, from, len);
  freeaddrinfo(result);

  len = -1;
  if (slash) len = atolx_range(slash+1, 0, (af == AF_INET) ? 32 : 128);

  return len;
}

static void display_ifconfig(char *name, int always, unsigned long long val[])
{
  struct ifreq ifre;
  struct {
    int type;
    char *title;
  } types[] = {
    {ARPHRD_LOOPBACK, "Local Loopback"}, {ARPHRD_ETHER, "Ethernet"},
    {ARPHRD_PPP, "Point-to-Point Protocol"}, {ARPHRD_INFINIBAND, "InfiniBand"},
    {ARPHRD_SIT, "IPv6-in-IPv4"}, {-1, "UNSPEC"}
  };
  int i;
  char *pp;
  FILE *fp;
  short flags;

  xstrncpy(ifre.ifr_name, name, IFNAMSIZ);
  if (ioctl(TT.sockfd, SIOCGIFFLAGS, &ifre)<0) perror_exit("%s", name);
  flags = ifre.ifr_flags;
  if (!always && !(flags & IFF_UP)) return;

  // query hardware type and hardware address
  i = ioctl(TT.sockfd, SIOCGIFHWADDR, &ifre);

  for (i=0; i < (sizeof(types)/sizeof(*types))-1; i++)
    if (ifre.ifr_hwaddr.sa_family == types[i].type) break;

  xprintf("%-9s Link encap:%s  ", name, types[i].title);
  if(i >= 0 && ifre.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
    xprintf("HWaddr ");
    for (i=0; i<6; i++) xprintf(":%02X"+!i, ifre.ifr_hwaddr.sa_data[i]);
  }
  xputc('\n');

  // If an address is assigned record that.

  ifre.ifr_addr.sa_family = AF_INET;
  memset(&ifre.ifr_addr, 0, sizeof(ifre.ifr_addr));
  ioctl(TT.sockfd, SIOCGIFADDR, &ifre);
  pp = (char *)&ifre.ifr_addr;
  for (i = 0; i<sizeof(ifre.ifr_addr); i++) if (pp[i]) break;

  if (i != sizeof(ifre.ifr_addr)) {
    struct sockaddr_in *si = (struct sockaddr_in *)&ifre.ifr_addr;
    struct {
      char *name;
      int flag, ioctl;
    } addr[] = {
      {"addr", 0, 0},
      {"P-t-P", IFF_POINTOPOINT, SIOCGIFDSTADDR},
      {"Bcast", IFF_BROADCAST, SIOCGIFBRDADDR},
      {"Mask", 0, SIOCGIFNETMASK}
    };

    xprintf("%10c%s", ' ', (si->sin_family == AF_INET) ? "inet" :
        (si->sin_family == AF_INET6) ? "inet6" : "unspec");

    for (i=0; i < sizeof(addr)/sizeof(*addr); i++) {
      if (!addr[i].flag || (flags & addr[i].flag)) {
        if (addr[i].ioctl && ioctl(TT.sockfd, addr[i].ioctl, &ifre))
          si->sin_family = 0;
        xprintf(" %s:%s ", addr[i].name,
          (si->sin_family == 0xFFFF || !si->sin_family)
            ? "[NOT SET]" : inet_ntoa(si->sin_addr));
      }
    }

    xputc('\n');
  }

  fp = fopen(pp = "/proc/net/if_inet6", "r");
  if (fp) {
    char iface_name[IFNAMSIZ];
    int plen, iscope;

    while (fgets(toybuf, sizeof(toybuf), fp)) {
      int nitems;
      char ipv6_addr[40];

      nitems = sscanf(toybuf, "%32s %*08x %02x %02x %*02x %15s\n",
                      ipv6_addr, &plen, &iscope, iface_name);
      if (nitems<0 && feof(fp)) break;
      if (nitems != 4) perror_exit("bad %s", pp);

      if (!strcmp(name, iface_name)) {
        struct sockaddr_in6 s6;
        char *ptr = ipv6_addr+sizeof(ipv6_addr)-1;

        // convert giant hex string into colon-spearated ipv6 address by
        // inserting ':' every 4 characters. 
        for (i = 32; i; i--)
          if ((*(ptr--) = ipv6_addr[i])) if (!(i&3)) *(ptr--) = ':';

        // Convert to binary and back to get abbreviated :: version
        if (inet_pton(AF_INET6, ipv6_addr, (void *)&s6.sin6_addr) > 0) {
          if (inet_ntop(AF_INET6, &s6.sin6_addr, toybuf, sizeof(toybuf))) {
            char *scopes[] = {"Global","Host","Link","Site","Compat"},
                 *scope = "Unknown";

            for (i=0; i < sizeof(scopes)/sizeof(*scopes); i++)
              if (iscope == (!!i)<<(i+3)) scope = scopes[i];
            xprintf("%10cinet6 addr: %s/%d Scope: %s\n",
                    ' ', toybuf, plen, scope);
          }
        }
      }
    }
    fclose(fp);
  }

  xprintf("%10c", ' ');

  if (flags) {
    unsigned short mask = 1;
    char **s, *str[] = {
      "UP", "BROADCAST", "DEBUG", "LOOPBACK", "POINTOPOINT", "NOTRAILERS",
      "RUNNING", "NOARP", "PROMISC", "ALLMULTI", "MASTER", "SLAVE", "MULTICAST",
      "PORTSEL", "AUTOMEDIA", "DYNAMIC", NULL
    };

    for (s = str; *s; s++) {
      if (flags & mask) xprintf("%s ", *s);
      mask = mask << 1;
    }
  } else xprintf("[NO FLAGS] ");

  if (ioctl(TT.sockfd, SIOCGIFMTU, &ifre) < 0) ifre.ifr_mtu = 0;
  xprintf(" MTU:%d", ifre.ifr_mtu);
  if (ioctl(TT.sockfd, SIOCGIFMETRIC, &ifre) < 0) ifre.ifr_metric = 0;
  if (!ifre.ifr_metric) ifre.ifr_metric = 1;
  xprintf("  Metric:%d", ifre.ifr_metric);

  // non-virtual interface

  if (val) {
    char *label[] = {"RX bytes", "RX packets", "errors", "dropped", "overruns",
      "frame", 0, 0, "TX bytes", "TX packets", "errors", "dropped", "overruns",
      "collisions", "carrier", 0, "txqueuelen"};
    signed char order[] = {-1, 1, 2, 3, 4, 5, -1, 9, 10, 11, 12, 14, -1,
      13, 16, -1, 0, 8};
    int i;

    // Query txqueuelen
    if (ioctl(TT.sockfd, SIOCGIFTXQLEN, &ifre) >= 0) val[16] = ifre.ifr_qlen;
    else val[16] = -1;

    for (i = 0; i < sizeof(order); i++) {
      int j = order[i];

      if (j < 0) xprintf("\n%10c", ' ');
      else xprintf("%s:%llu ", label[j], val[j]);
    }
  }
  xputc('\n');

  if(!ioctl(TT.sockfd, SIOCGIFMAP, &ifre) && (ifre.ifr_map.irq ||
      ifre.ifr_map.mem_start || ifre.ifr_map.dma || ifre.ifr_map.base_addr))
  {
    xprintf("%10c", ' ');
    if(ifre.ifr_map.irq) xprintf("Interrupt:%d ", ifre.ifr_map.irq);
    if(ifre.ifr_map.base_addr >= 0x100) // IO_MAP_INDEX
      xprintf("Base address:0x%x ", ifre.ifr_map.base_addr);
    if(ifre.ifr_map.mem_start)
      xprintf("Memory:%lx-%lx ", ifre.ifr_map.mem_start, ifre.ifr_map.mem_end);
    if(ifre.ifr_map.dma) xprintf("DMA chan:%x ", ifre.ifr_map.dma);
    xputc('\n');
  }
  xputc('\n');
}

static void show_iface(char *iface_name)
{
  char *name;
  struct string_list *ifaces = 0, *sl;
  int i, j;
  FILE *fp;

  fp = xfopen("/proc/net/dev", "r");

  for (i=0; fgets(toybuf, sizeof(toybuf), fp); i++) {
    char *buf = toybuf;
    unsigned long long val[17];

    if (i<2) continue;

    while (isspace(*buf)) buf++;
    name = strsep(&buf, ":");
    if(!buf) error_exit("bad name %s", name);

    errno = 0;
    for (j=0; j<16 && !errno; j++) val[j] = strtoll(buf, &buf, 0);
    if (errno) perror_exit("bad %s at %s", name, buf);

    if (iface_name) {
      if (!strcmp(iface_name, name)) {
        display_ifconfig(iface_name, 1, val);

        return;
      }
    } else {
      sl = xmalloc(sizeof(*sl)+strlen(name)+1);
      strcpy(sl->str, name);
      sl->next = ifaces;
      ifaces = sl;

      display_ifconfig(sl->str, toys.optflags & FLAG_a, val);
    }
  }
  fclose(fp);

  if (iface_name) display_ifconfig(iface_name, 1, 0);
  else {
    struct ifconf ifcon;
    struct ifreq *ifre;
    int num;

    // Loop until buffer's big enough
    ifcon.ifc_buf = NULL;
    for (num = 30;;num += 10) {
      ifcon.ifc_len = sizeof(struct ifreq)*num;
      ifcon.ifc_buf = xrealloc(ifcon.ifc_buf, ifcon.ifc_len);
      xioctl(TT.sockfd, SIOCGIFCONF, &ifcon);
      if (ifcon.ifc_len != sizeof(struct ifreq)*num) break;
    }

    ifre = ifcon.ifc_req;
    for(num = 0; num < ifcon.ifc_len && ifre; num += sizeof(struct ifreq), ifre++)
    {
      // Skip duplicates
      for(sl = ifaces; sl; sl = sl->next)
        if(!strcmp(sl->str, ifre->ifr_name)) break;

      if(!sl) display_ifconfig(ifre->ifr_name, toys.optflags & FLAG_a, 0);
    }

    free(ifcon.ifc_buf);
  }

  llist_traverse(ifaces, free);
}

// Encode offset and size of field into an int, and make result negative
#define IFREQ_OFFSZ(x) -(int)((offsetof(struct ifreq, x)<<16) + sizeof(ifre.x))

void ifconfig_main(void)
{
  char **argv = toys.optargs;
  struct ifreq ifre;
  int i;

  TT.sockfd = xsocket(AF_INET, SOCK_DGRAM, 0);
  if(toys.optc < 2) {
    show_iface(*argv);
    return;
  }

  // Open interface
  memset(&ifre, 0, sizeof(struct ifreq));
  xstrncpy(ifre.ifr_name, *argv, IFNAMSIZ);

  // Perform operations on interface
  while(*++argv) {
    // Table of known operations
    struct argh {
      char *name;
      int on, off; // set, clear
    } try[] = {
      {0, IFF_UP|IFF_RUNNING, SIOCSIFADDR},
      {"up", IFF_UP|IFF_RUNNING, 0},
      {"down", 0, IFF_UP},
      {"arp", 0, IFF_NOARP},
      {"promisc", IFF_PROMISC, 0},
      {"allmulti", IFF_ALLMULTI, 0},
      {"multicast", IFF_MULTICAST, 0},
      {"pointopoint", IFF_POINTOPOINT, SIOCSIFDSTADDR},
      {"broadcast", IFF_BROADCAST, SIOCSIFBRDADDR},
      {"netmask", 0, SIOCSIFNETMASK},
      {"dstaddr", 0, SIOCSIFDSTADDR},
      {"mtu", IFREQ_OFFSZ(ifr_mtu), SIOCSIFMTU},
      {"keepalive", IFREQ_OFFSZ(ifr_data), SIOCDEVPRIVATE}, // SIOCSKEEPALIVE
      {"outfill", IFREQ_OFFSZ(ifr_data), SIOCDEVPRIVATE+2}, // SIOCSOUTFILL
      {"metric", IFREQ_OFFSZ(ifr_metric), SIOCSIFMETRIC},
      {"txqueuelen", IFREQ_OFFSZ(ifr_qlen), SIOCSIFTXQLEN},
      {"mem_start", IFREQ_OFFSZ(ifr_map.mem_start), SIOCSIFMAP},
      {"io_addr", IFREQ_OFFSZ(ifr_map.base_addr), SIOCSIFMAP},
      {"irq", IFREQ_OFFSZ(ifr_map.irq), SIOCSIFMAP},
      {"inet", 0, 0},
      {"inet6", 0, 0}
    };
    char *s = *argv;
    int rev = (*s == '-');

    s += rev;

    // "set hardware address" is oddball enough to special case
    if (!strcmp(*argv, "hw")) {
      char *hw_addr, *ptr, *p;
      struct sockaddr *sock = &ifre.ifr_hwaddr;
      int count = 6;

      ptr = p = (char *)sock->sa_data;
      memset(sock, 0, sizeof(struct sockaddr));
      if (argv[1]) {
        if (!strcmp("ether", *++argv)) sock->sa_family = ARPHRD_ETHER;
        else if (!strcmp("infiniband", *argv)) {
          sock->sa_family = ARPHRD_INFINIBAND;
          count = 20;
          p = ptr = toybuf;
        }
      }
      if (!sock->sa_family || !argv[1]) {
        toys.exithelp++;
        error_exit("bad hw '%s'", *argv);
      }
      hw_addr = *++argv;

      // Parse and verify address.
      while (*hw_addr && (p-ptr) < count) {
        int val, len = 0;

        if (*hw_addr == ':') hw_addr++;
        sscanf(hw_addr, "%2x%n", &val, &len);
        if (!len || len > 2) break; // 1 nibble can be set e.g. C2:79:38:95:D:A 
        hw_addr += len;
        *p++ = val;
      }

      if ((p-ptr) != count || *hw_addr)
        error_exit("bad hw-addr '%s'", *argv);

      // the linux kernel's "struct sockaddr" (include/linux/socket.h in the
      // kernel source) only has 14 bytes of sa_data, and an infiniband address
      // is 20. So if we go through the ioctl, the kernel will truncate
      // infiniband addresses, meaning we have to go through sysfs instead.
      if (sock->sa_family == ARPHRD_INFINIBAND && !strchr(ifre.ifr_name, '/')) {
        int fd;

        sprintf(toybuf, "/sys/class/net/%s/address", ifre.ifr_name);
        fd = xopen(toybuf, O_RDWR);
        xwrite(fd, *argv, strlen(*argv));
        close(fd);
      } else xioctl(TT.sockfd, SIOCSIFHWADDR, &ifre);
      continue;

    // Add/remove ipv6 address to interface

    } else if (!strcmp(*argv, "add") || !strcmp(*argv, "del")) {
      struct ifreq_inet6 {
        struct in6_addr addr;
        unsigned prefix;
        int index;
      } ifre6;
      int plen, fd6 = xsocket(AF_INET6, SOCK_DGRAM, 0);

      if (!argv[1]) {
        toys.exithelp++;
        error_exit("%s", *argv);
      }

      plen = get_addrinfo(argv[1], AF_INET6, &ifre6.addr);
      if (plen < 0) plen = 128;
      xioctl(fd6, SIOCGIFINDEX, &ifre);
      ifre6.index = ifre.ifr_ifindex;
      ifre6.prefix = plen;
      xioctl(fd6, **(argv++)=='a' ? SIOCSIFADDR : SIOCDIFADDR, &ifre6);

      close(fd6);
      continue;
    // Iterate through table to find/perform operation
    } else for (i = 0; i < ARRAY_LEN(try); i++) {
      struct argh *t = try+i;
      int on = t->on, off = t->off;

      if (!t->name) {
        if (isdigit(**argv) || !strcmp(*argv, "default")) argv--;
        else continue;
      } else if (strcmp(t->name, s)) continue;

      // Is this an SIOCSI entry?
      if ((off|0xff) == 0x89ff) {
        if (!rev) {
          if (!*++argv) error_exit("%s needs argument", t->name);

          // Assign value to ifre field and call ioctl? (via IFREQ_OFFSZ.)
          if (on < 0) {
            long l = strtoul(*argv, 0, 0);

            if (off == SIOCSIFMAP) xioctl(TT.sockfd, SIOCGIFMAP, &ifre);
            on = -on;
            poke((on>>16) + (char *)&ifre, l, on&15);
            xioctl(TT.sockfd, off, &ifre);
            break;
          } else {
            struct sockaddr_in *si = (struct sockaddr_in *)&ifre.ifr_addr;
            int mask = -1;

            si->sin_family = AF_INET;

            if (!strcmp(*argv, "default")) si->sin_addr.s_addr = INADDR_ANY;
            else mask = get_addrinfo(*argv, AF_INET, &si->sin_addr);
            xioctl(TT.sockfd, off, &ifre);

            // Handle /netmask
            if (mask >= 0) {
              // sin_addr probably isn't unaligned, but just in case...
              mask = htonl((~0)<<(32-mask));
              memcpy(&si->sin_addr, &mask, 4);
              xioctl(TT.sockfd, SIOCSIFNETMASK, &ifre);
            }
          }
        }
        off = 0;
      }

      // Set flags
      if (on || off) {
        xioctl(TT.sockfd, SIOCGIFFLAGS, &ifre);
        ifre.ifr_flags &= ~(rev ? on : off);
        ifre.ifr_flags |= (rev ? off : on);
        xioctl(TT.sockfd, SIOCSIFFLAGS, &ifre);
      }

      break;
    }
    if (i == sizeof(try)/sizeof(*try)) {
      toys.exithelp++;
      error_exit("bad argument '%s'", *argv);
    }
  }
  close(TT.sockfd);
}
