/* vconfig.c - Creates virtual ethernet devices.
 *
 * Copyright 2012 Sandeep Sharma <sandeep.jack2756@gmail.com>, Kyungwan Han <asura321@gmail.com>
 *
 * Not in SUSv4.

USE_VCONFIG(NEWTOY(vconfig, "<2>4", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))

config VCONFIG
  bool "vconfig"
  default y
  help
    usage: vconfig COMMAND [OPTIONS]

       add             [interface-name] [vlan_id]
       rem             [vlan-name]
       set_flag        [interface-name] [flag-num]       [0 | 1]
       set_egress_map  [vlan-name]      [skb_priority]   [vlan_qos]
       set_ingress_map [vlan-name]      [skb_priority]   [vlan_qos]
       set_name_type   [name-type]

    Create and remove virtual ethernet devices
*/

#include "toys.h"
#include "toynet.h"
#include <linux/if_vlan.h>
#include <linux/sockios.h>
/*
 * convert str to long within given range
 */
static int strtol_range(char *str, int min, int max)
{
  char *endptr = NULL;
  errno = 0;
  long ret_value = strtol(str, &endptr, 10);

  if(errno) perror_exit("Invalid num %s", str);
  else if(endptr && (*endptr != '\0' || endptr == str))
    perror_exit("Not a valid num %s", str);
  if(ret_value >= min && ret_value <= max) return ret_value;
  else perror_exit("Number %s is not in valid [%d-%d] Range\n", str, min, max);
}
/*
 * vconfig main function.
 */
void vconfig_main(void)
{
#define MAX_VLAN_ID 4094
  struct vlan_ioctl_args request;
  char *interface_name = NULL;
  unsigned int name_type = VLAN_NAME_TYPE_PLUS_VID;
  char *cmd;
  int fd = 0;
  int vlan_id = 0;

  if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) perror_exit("Can't open socket"); //Use socket instead of open
  memset(&request, 0, sizeof(struct vlan_ioctl_args));		// Null set all the VLAN info's.
  cmd = toys.optargs[0];					// Fetch cmd and proceed.
  if(strcmp(cmd, "set_name_type") == 0) {
    if(strcmp(toys.optargs[1], "VLAN_PLUS_VID") == 0) {
      name_type = VLAN_NAME_TYPE_PLUS_VID;
    }
    else if(strcmp(toys.optargs[1], "VLAN_PLUS_VID_NO_PAD") == 0) {
      name_type = VLAN_NAME_TYPE_PLUS_VID_NO_PAD;
    }
    else if(strcmp(toys.optargs[1], "DEV_PLUS_VID") == 0) {
      name_type = VLAN_NAME_TYPE_RAW_PLUS_VID;
    }
    else if(strcmp(toys.optargs[1], "DEV_PLUS_VID_NO_PAD") == 0) {
      name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
    }
    else perror_exit("ERROR: Invalid name type");

    request.u.name_type = name_type;
    request.cmd = SET_VLAN_NAME_TYPE_CMD;
    if(ioctl(fd, SIOCSIFVLAN, &request) == 0) {
      xprintf("Successful set_name_type for VLAN subsystem\n");
      exit(EXIT_SUCCESS);
    }
    else perror_exit("Failed to set set_name_type:");
  }
  else {
    interface_name = toys.optargs[1]; // Store interface name.
    if(strlen(interface_name) > 15) perror_exit("ERROR:if_name length can not be greater than 15");
    strcpy(request.device1, interface_name); //we had exited if interface_name length greater than 15, so here it never overflows.
  }

  if(strcmp(cmd, "add") == 0) {
    request.cmd = ADD_VLAN_CMD;
    if(toys.optargs[2]) vlan_id = strtol_range(toys.optargs[2], 0, MAX_VLAN_ID);
    else vlan_id = 0;
    request.u.VID = vlan_id;
  }
  else if(strcmp(cmd, "rem") == 0) {
    request.cmd = DEL_VLAN_CMD;
  }
  else if(strcmp(cmd, "set_flag") == 0) {
    request.cmd = SET_VLAN_FLAG_CMD;
    if(toys.optargs[2]) request.u.flag = strtol_range(toys.optargs[2], 0, 1);
    else request.u.flag = 0;
    if(toys.optargs[3]) request.vlan_qos = strtol_range(toys.optargs[3], 0, 7);
    else request.vlan_qos = 0;
  }
  else if(strcmp(cmd, "set_egress_map") == 0) {
    request.cmd = SET_VLAN_EGRESS_PRIORITY_CMD;
    if(toys.optargs[2]) request.u.skb_priority = strtol_range(toys.optargs[2], 0, INT_MAX);
    else request.u.skb_priority = 0;
    if(toys.optargs[3]) request.vlan_qos = strtol_range(toys.optargs[3], 0, 7);
    else request.vlan_qos = 0;
  }
  else if(strcmp(cmd, "set_ingress_map") == 0) {
    request.cmd = SET_VLAN_INGRESS_PRIORITY_CMD;
    if(toys.optargs[2]) request.u.skb_priority = strtol_range(toys.optargs[2], 0, INT_MAX);
    else request.u.skb_priority = 0;
    //To set flag we must have to set vlan_qos
    if(toys.optargs[3]) request.vlan_qos = strtol_range(toys.optargs[3], 0, 7);
    else request.vlan_qos = 0;
  }
  else {
    xclose(fd);
    perror_exit("Unknown command %s", cmd);
  }
  if(ioctl(fd, SIOCSIFVLAN, &request) == 0) {
    if(strcmp(cmd, "add") == 0 && vlan_id == 1)
      xprintf("WARNING: VLAN 1 does not work with many switches,consider another number if you have problems.\n");
    xprintf("Successful %s on device %s\n", cmd, interface_name);
  }
  else perror_exit("Failed to %s, on vlan subsystem %s.", cmd, interface_name);
}
