bool core::Receiver::OnEvent(irr::SEvent const &event) { if (event.EventType == irr::EET_KEY_INPUT_EVENT && match_input(event.KeyInput.Key)) { if (event.KeyInput.PressedDown) core::Receiver::inputs |= this->match_irr_keys[event.KeyInput.Key]; else core::Receiver::inputs &= ~(this->match_irr_keys[event.KeyInput.Key]); } if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) if (event.MouseInput.Wheel) core::Receiver::scroll = event.MouseInput.Wheel; return false; }
/* 0 == ERROR here! */ double get_labeled_arg(int fd, char *label, char **nextargs) { char *arg = strtok_r(NULL, " ", nextargs); if (!arg) { printoutc(fd, "missing parameter '%s'", label); return 0.0; //error } if (!match_input(label, arg)) { printoutc(fd, "invalid parameter \"%s\", expecting \"%s\"", arg, label); return 0.0; //error } arg = strtok_r(NULL, " ", nextargs); if (not_a_number(arg) && arg[0] != '.') { printoutc(fd, "invalid value \"%s\"", arg); return 0.0; //error } return strtod(arg, NULL); }
static int queue(int fd, char *s) { struct vder_iface *cur = Router.iflist, *selected = NULL; struct vder_queue *q; char *nextargs, *arg; int if_id; int prio_id = -1; char output_word[MAXCMD] = ""; enum queue_policy_e newpolicy; arg = strtok_r(s, " ", &nextargs); if(!arg) { /* No arguments */ while(cur) { show_queues(fd, cur); cur = cur->next; } return 0; } if ((sscanf(arg, "eth%d:prio%d", &if_id, &prio_id) != 2) && (sscanf(arg, "eth%d:%s", &if_id, output_word) != 2)) return EINVAL; else { if (prio_id < 0 && !match_input("output", output_word)) { return EINVAL; } cur = Router.iflist; while(cur) { if (cur->interface_id == if_id) { selected = cur; break; } cur = cur->next; } if (!selected) { printoutc(fd, "Cannot find interface eth%d", if_id); return ENOENT; } /* Match policy */ arg = strtok_r(NULL, " ", &nextargs); if (!arg) { printoutc(fd, "queue: queue policy required"); return EINVAL; } if (match_input("unlimited", arg)) { newpolicy = QPOLICY_UNLIMITED; } else if (match_input("fifo", arg)) { newpolicy = QPOLICY_FIFO; } else if (match_input("red", arg)) { newpolicy = QPOLICY_RED; } else if (match_input("token", arg)) { newpolicy = QPOLICY_TOKEN; } else { printoutc(fd, "queue: invalid queue policy \"%s\"", arg); return EINVAL; } if (prio_id >= 0) { if (prio_id > 31) { printoutc(fd, "Invalid priority queue %s", arg); return EINVAL; } q = &selected->prio_q[prio_id]; } else { printoutc(fd, "selected if=%d, outq", if_id); q = &selected->out_q; } /* Match arguments */ if (newpolicy == QPOLICY_UNLIMITED) { qunlimited_setup(q); } else if (newpolicy == QPOLICY_FIFO) { uint32_t limit; arg = strtok_r(NULL, " ", &nextargs); if (!arg) { printoutc(fd, "fifo: missing parameter 'limit'"); return EINVAL; } if (!match_input("limit", arg)) { printoutc(fd, "fifo: invalid parameter \"%s\"", arg); return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); if (not_a_number(arg)) { printoutc(fd, "fifo: invalid limit"); return EINVAL; } limit = strtol(arg, NULL, 10); qfifo_setup(q,limit); } else if (newpolicy == QPOLICY_RED) { uint32_t min, max, limit; double P; min = (uint32_t) get_labeled_arg(fd,"min", &nextargs); max = (uint32_t) get_labeled_arg(fd,"max", &nextargs); P = get_labeled_arg(fd,"probability", &nextargs); limit = (uint32_t) get_labeled_arg(fd,"limit", &nextargs); if (!min || !max || !limit) return EINVAL; qred_setup(q, min, max, P, limit); } else if (newpolicy == QPOLICY_TOKEN) { uint32_t limit, bitrate; limit = (uint32_t) get_labeled_arg(fd, "limit", &nextargs); bitrate = (uint32_t) get_labeled_arg(fd, "bitrate", &nextargs); if (!limit || !bitrate) return EINVAL; qtoken_setup(q, bitrate, limit); } return 0; } }
static int filter(int fd,char *s) { struct vder_filter *cur = Router.filtering_table; int action; struct vder_iface *vif = NULL; uint8_t proto = 0; struct in_addr s_addr = {0}, s_nm = {0}, d_addr = {0}, d_nm = {0}; uint16_t sport = 0, dport = 0; int tos = -1; uint8_t priority = PRIO_BESTEFFORT; enum filter_action filter_action = filter_invalid; char *nextargs = NULL, *arg; arg = strtok_r(s, " ", &nextargs); if(!arg) { /* No arguments */ while(cur) { show_filter(fd, cur); cur = cur->next; } return 0; } if ((!arg) || (strlen(arg) != 3) || ((strncmp(arg, "add", 3) != 0) && (strncmp(arg, "del", 3) != 0))) { printoutc(fd, "Invalid action \"%s\".", arg); return EINVAL; } if (strncmp(arg, "del", 3) == 0) action = ACTION_DELETE; else action = ACTION_ADD; arg = strtok_r(NULL, " ", &nextargs); if (!arg) { not_understood(fd, ""); return EINVAL; } while(arg) { if (match_input("src", arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; vif = select_interface(arg); } else if(match_input("proto", arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; if (not_a_number(arg)) { if (match_input("tcp", arg)) proto = IPPROTO_TCP; else if (match_input("udp", arg)) proto = IPPROTO_UDP; else if (match_input("igmp", arg)) proto = IPPROTO_IGMP; else if (match_input("icmp", arg)) proto = IPPROTO_ICMP; else { printoutc(fd, "Invalid protocol \"%s\"", arg); return EINVAL; } } else { proto = atoi(arg); if (proto <= 0) { printoutc(fd, "Invalid protocol \"%s\"", arg); return EINVAL; } } } else if (match_input("from",arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; if (!inet_aton(arg, &s_addr) || !is_unicast(s_addr.s_addr)) { printoutc(fd, "Invalid from address \"%s\"", arg); return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); if (!arg) { printoutc(fd, "from address: netmask is required"); return EINVAL; } if (!inet_aton(arg, &s_nm) || !is_netmask(s_nm.s_addr)) { printoutc(fd, "Invalid netmask \"%s\"", arg); return EINVAL; } } else if (match_input("to",arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; if (!inet_aton(arg, &d_addr) || !is_unicast(d_addr.s_addr)) { printoutc(fd, "Invalid from address \"%s\"", arg); return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); if (!arg) { printoutc(fd, "from address: netmask is required"); return EINVAL; } if (!inet_aton(arg, &d_nm) || !is_netmask(d_nm.s_addr)) { printoutc(fd, "Invalid netmask \"%s\"", arg); return EINVAL; } } else if (match_input("tos",arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; tos = atoi(arg); if ((tos < 0) || not_a_number(arg)) { printoutc(fd, "Invalid tos %s", arg); return EINVAL; } } else if (match_input("sport",arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; if ((sport < 0) || not_a_number(arg)) { printoutc(fd, "Invalid sport %s", arg); return EINVAL; } sport = htons(atoi(arg)); } else if (match_input("dport",arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; if (not_a_number(arg)) { printoutc(fd, "Invalid dport %s", arg); return EINVAL; } dport = htons(atoi(arg)); } else if (match_input("prio",arg)) { if (filter_action != filter_invalid) { printoutc(fd, "Invalid double action for filter"); } arg = strtok_r(NULL, " ", &nextargs); if (!arg) return EINVAL; priority = atoi(arg); if ((priority < 0) || (priority >= PRIO_NUM) || not_a_number(arg)) { printoutc(fd, "Invalid priority %s", arg); return EINVAL; } filter_action = filter_priority; } else if (match_input("accept",arg)) { if (filter_action != filter_invalid) { printoutc(fd, "Invalid double action for filter"); } filter_action = filter_accept; } else if (match_input("reject",arg)) { if (filter_action != filter_invalid) { printoutc(fd, "Invalid double action for filter"); } filter_action = filter_reject; } else if (match_input("drop",arg)) { if (filter_action != filter_invalid) { printoutc(fd, "Invalid double action for filter"); } filter_action = filter_drop; } arg = strtok_r(NULL, " ", &nextargs); } if ((filter_action == filter_invalid) && (action == ACTION_ADD)) { printoutc(fd, "Error: an action is required for filter"); return EINVAL; } if (action == ACTION_ADD) { if (vder_filter_add(vif, proto, s_addr.s_addr, s_nm.s_addr, d_addr.s_addr, d_nm.s_addr, tos, sport, dport, filter_action, priority)) return errno; } else { if (vder_filter_del(vif, proto, s_addr.s_addr, s_nm.s_addr, d_addr.s_addr, d_nm.s_addr, tos, sport, dport)) return errno; } return 0; }
static int help(int fd,char *s) { char *nextargs = NULL, *arg; arg = strtok_r(s, " ", &nextargs); if(!arg) { /* No arguments */ printoutc(fd, "COMMAND HELP"); printoutc(fd, "------------ ------------"); printoutc(fd, "help print a summary of mgmt commands. Use \"help <command>\" for details."); printoutc(fd, "connect create a new interface connect it to vde socket"); printoutc(fd, "ifconfig show/change interface addresses configuration"); printoutc(fd, "dhcpd start/stop dhcp server on a specific interface"); printoutc(fd, "olsr start/stop OLSR"); printoutc(fd, "route show/change routing table"); printoutc(fd, "arp show neighbors ip/mac associations"); printoutc(fd, "queue show/change outgoing frames queues"); printoutc(fd, "ipfilter show/change ip filtering configuration"); printoutc(fd, "stats print interface statistics"); printoutc(fd, "logout close current management session"); printoutc(fd, "shutdown turn the router off"); return 0; } else if (match_input("help",arg)) { printoutc(fd, "help print a summary of mgmt commands."); printoutc(fd, "Use \"help <command>\" for details."); return 0; } else if (match_input("connect",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\tconnect <vde_sock_path> [<macaddress>]"); printoutc(fd, "Connects to a vde socket at path <vde_sock_path> by creating a new virtual ethernet device."); printoutc(fd, "If no <macaddress> is provided, it will be assigned automatically."); printoutc(fd, ""); printoutc(fd, "Examples:"); printoutc(fd, "connect /var/run/vde.ctl"); printoutc(fd, "connect /var/run/my_sock.ctl 00:11:22:33:44:55"); return 0; } else if (match_input("ifconfig",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\tifconfig [<devname> [<action> <address> <netmask>]]"); printoutc(fd, "--or--"); printoutc(fd, "\tifconfig <devname> add dhcp"); printoutc(fd, "Show/store IP address configuration. If no <devname> is provided, the default action"); printoutc(fd, "will be to display the current configuration for all the existing ethernet devices."); printoutc(fd, "<action> can be \"add\" or \"del\". If \"add\" is specified, all other arguments are mandatory."); printoutc(fd, "If \"del\" is specified, only <address> will be used to search for an existing entry."); printoutc(fd, "Each virtual ethernet can be associated to more than one IP addresses. A static route for"); printoutc(fd, "the resulting neighborhood will be added."); printoutc(fd, "Dhcp option allows to ask for a dynamic IP address."); printoutc(fd, ""); printoutc(fd, "Examples:"); printoutc(fd, "ifconfig"); printoutc(fd, "ifconfig eth0"); printoutc(fd, "ifconfig eth1 add 10.0.0.1 255.0.0.0"); printoutc(fd, "ifconfig eth1 add dhcp"); printoutc(fd, "ifconfig eth1 del 10.0.0.1"); return 0; } else if (match_input("dhcpd",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\tdhcpd start <devname> <dhcp_pool_start> <dhcp_pool_end>"); printoutc(fd, "--or--"); printoutc(fd, "\tdhcpd stop <devname>"); printoutc(fd, "Start/stop DHCP server on a specific interface. Devices/machines connected to the router"); printoutc(fd, "will be provided with a dynamic IP address on request."); printoutc(fd, ""); printoutc(fd, "Examples:"); printoutc(fd, "dhcpd start eth0 10.0.0.101 10.0.0.120"); printoutc(fd, "dhcpd stop eth0"); return 0; } else if (match_input("olsr",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\tolsr start <devname> [<devname> [<devname> [<...>]]]"); printoutc(fd, "--or--"); printoutc(fd, "\tolsr stop"); printoutc(fd, "Start/stop olsr service on specified interface(s). Devices/machines connected to the router"); printoutc(fd, "will be notified about routing via OLSR messages"); printoutc(fd, ""); printoutc(fd, "Examples:"); printoutc(fd, "olsr start eth0 eth1"); printoutc(fd, "olsr stop"); return 0; } else if (match_input("route",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\troute [<action> <address> <netmask> [gw <gateway>] [via <interface>] [metric <metric>]]"); printoutc(fd, "--or--"); printoutc(fd, "\troute <action> default [address]"); printoutc(fd, "Show/store routing table information. If no <action> is given, the default behavior is to"); printoutc(fd, "show the current (full) routing table."); printoutc(fd, "<action> can be \"add\" or \"del\". If \"add\" or \"del\" is specified, address and netmask are"); printoutc(fd, "mandatory, unless the \"default\" keyword is present. \"default\" is used to manage default "); printoutc(fd, "gateway entry."); printoutc(fd, ""); printoutc(fd, "Examples:"); printoutc(fd, "route"); printoutc(fd, "route add default 10.0.0.254"); printoutc(fd, "route del default"); printoutc(fd, "route add 192.168.0.0 255.255.0.0 gw 10.0.0.253 metric 2"); printoutc(fd, "route add 192.168.1.0 255.255.255.0 via eth2"); return 0; } else if (match_input("queue",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\tqueue [<devname>:<queuename> <policy> <policy_options>]"); printoutc(fd, ""); printoutc(fd, "Show/store queuing policy information. If no <action> is specified,"); printoutc(fd, "the current queue policy and information are displayed, otherwise you need"); printoutc(fd, "to specify the options for the selected queue."); printoutc(fd, ""); printoutc(fd, "Selecting the queue consists in naming the interface and the associated queue."); printoutc(fd, "Every interface has one \":output\" queue and 32 priority queues named from"); printoutc(fd, "\":prio0\" to \":prio31\"."); printoutc(fd, ""); printoutc(fd, "The following policies are available:"); printoutc(fd, ""); printoutc(fd, "- 'unlimited' (default)."); printoutc(fd, "\tthis policy requires no options. It is the default policy, and it will allow"); printoutc(fd, "\tto enqueue virtually an unlimited amount of data before it is dequeued."); printoutc(fd, ""); printoutc(fd, "- 'fifo' (usage: fifo limit <limit>)"); printoutc(fd, "\tthis policy will allow at most <limit> bytes to be enqueued, and a tail-drop"); printoutc(fd, "\twill be adopted to all the exceeding frames when the queue is full."); printoutc(fd, ""); printoutc(fd, ""); printoutc(fd, "- 'red' (usage: red min <min> max <max> probability <P> limit <limit>)"); printoutc(fd, "\tthis is the \"Random Early Detection\" queuing policy. It consists of setting"); printoutc(fd, "\ta dynamic limit to the queue during the enqueue operation. The probability"); printoutc(fd, "\tof dropping packets during enqueue will be 0 under <min> bytes, then it will "); printoutc(fd, "\tincrease linearly to reach <P> between <min> and <max>. Between <max> and <limit>"); printoutc(fd, "\tit will be <P>. Over the physical limit <limit>, all packets will be dropped (P=1)."); printoutc(fd, ""); printoutc(fd, "- 'token' (usage: tbf limit <limit> bitrate <bitrate>"); printoutc(fd, "\tThis is the \"Token Bucket\" queuing policy, allowing traffic to be dequeued at"); printoutc(fd, "\tthe specified <bitrate>. Enqueuing will be limited to <limit> bytes, so if the"); printoutc(fd, "\tqueue is full all the exceeding frames will be dropped."); printoutc(fd, "Examples:"); printoutc(fd, "queue"); printoutc(fd, "queue eth0:output fifo limit 40000"); printoutc(fd, "queue eth0:prio3 red min 80000 max 160000 probability 0.1 limit 300000"); printoutc(fd, "queue eth0:prio15 unlimited"); return 0; } else if (match_input("ipfilter",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\tipfilter [<action> [src <interface>] [from <address> <netmask>]"); printoutc(fd, " [to <address> <netmask>] [proto <proto>] [tos <tos>]"); printoutc(fd, " [sport <sport>] [dport <dport>] <filter_action> [<priority>]]"); printoutc(fd, "Show/store IP filtering information. If no <action> is specified, "); printoutc(fd, "the current ip filtering table is shown, else <action> can be \"add\" or \"del\""); printoutc(fd, "If \"add\" is specified, no other argument is mandatory but the <filter_action>."); printoutc(fd, "<filter_action> can be one of \"accept\" \"drop\" \"reject\" or \"prio\". Accept is the"); printoutc(fd, "default behavior. \"reject\" is like \"drop\" except that it will send a icmp packet filtered "); printoutc(fd, "towards the source every time the rule is hit. \"prio\" changes the priority of the "); printoutc(fd, "packet when it gets inserted to the output queue system, allowing IP-based QoS."); printoutc(fd, "When \"prio\" is selected as <filter_action>, the argument <priority> is mandatory."); printoutc(fd, "If <del> is specified as <action>, all the arguments must match the previously "); printoutc(fd, "inserted rule, except the <filter_action> and the <priority> that get discarded."); printoutc(fd, ""); printoutc(fd, "Please note that the rules will be processed on the inverse order as they were "); printoutc(fd, "inserted, so to drop all packets from eth0 except those coming from 10.0.0.3, insert"); printoutc(fd, "the rules in the followinf order (generic to specific):"); printoutc(fd, ""); printoutc(fd, "ipfilter add src eth0 drop"); printoutc(fd, "ipfilter add src eth0 from 10.0.0.3 255.255.255.255 accept"); printoutc(fd, ""); printoutc(fd, "other Examples:"); printoutc(fd, ""); printoutc(fd, "ipfilter"); printoutc(fd, "ipfilter add src eth1 tos 2 to 172.16.0.0 255.255.0.0 prio 7"); printoutc(fd, "ipfilter del src eth1 tos 2 to 172.16.0.0 255.255.0.0"); return 0; } else if (match_input("arp",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\tarp"); return 0; } else if (match_input("stats",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\tstats"); return 0; } else if (match_input("logout",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\tlogout"); return 0; } else if (match_input("shutdown",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\tshutdown"); return 0; } else { printoutc(fd, "No help available for %s", arg); } return ENOENT; }
static int route(int fd,char *s) { char *nextargs = NULL, *arg; struct vder_route *ro; struct vder_iface *selected = NULL; struct in_addr temp_address, temp_netmask, temp_gateway; int metric = 1; enum command_action_enum action = -1; arg = strtok_r(s, " ", &nextargs); if(!arg) { /* No arguments */ ro = Router.routing_table; while(ro) { show_route(fd, ro); ro = ro->next; } return 0; } if ((!arg) || (strlen(arg) != 3) || ((strncmp(arg, "add", 3) != 0) && (strncmp(arg, "del", 3) != 0))) { printoutc(fd, "Invalid action \"%s\".", arg); return EINVAL; } if (strncmp(arg, "del", 3) == 0) action = ACTION_DELETE; else action = ACTION_ADD; arg = strtok_r(NULL, " ", &nextargs); if (!arg) { not_understood(fd, ""); return EINVAL; } if (match_input("default", arg)) { if (action == ACTION_ADD) action = ACTION_ADD_DEFAULT; if (action == ACTION_DELETE) { if (vder_route_del(0, 0, 1)) return errno; else return 0; } arg = strtok_r(NULL, " ", &nextargs); } if (!inet_aton(arg, &temp_address) || !is_unicast(temp_address.s_addr)) { printoutc(fd, "Invalid address \"%s\"", arg); return EINVAL; } if (action == ACTION_ADD_DEFAULT) { if (vder_route_add(0, 0, temp_address.s_addr, 1, NULL)) return errno; else return 0; } arg = strtok_r(NULL, " ", &nextargs); if (!arg) { printoutc(fd, "Error: parameter 'netmask' required."); return EINVAL; } if (!inet_aton(arg, &temp_netmask) || !is_netmask(temp_netmask.s_addr)) { printoutc(fd, "Invalid netmask \"%s\"", arg); return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); while(arg) { if (match_input("via", arg)) { arg = strtok_r(NULL, " ", &nextargs); selected = select_interface(arg); if (!selected) return EINVAL; } else if (match_input("gw", arg)) { arg = strtok_r(NULL, " ", &nextargs); if (!inet_aton(arg, &temp_gateway) || !is_unicast(temp_gateway.s_addr)) { printoutc(fd, "Invalid gateway \"%s\"", arg); return EINVAL; } } else if (match_input("metric", arg)) { arg = strtok_r(NULL, " ", &nextargs); metric = atoi(arg); if (metric < 1) { printoutc(fd, "Invalid metric \"%s\"", arg); return EINVAL; } } else { return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); } if ((action == ACTION_DELETE) && (vder_route_del(temp_address.s_addr, temp_netmask.s_addr, metric))) { return errno; } else if ((action == ACTION_ADD) && (vder_route_add(temp_address.s_addr, temp_netmask.s_addr, temp_gateway.s_addr, metric, selected))) { return errno; } return 0; }
static int ifconfig(int fd,char *s) { char *nextargs = NULL, *arg; struct vder_iface *iface; arg = strtok_r(s, " ", &nextargs); if(!arg) { /* No arguments */ iface = Router.iflist; while(iface) { show_ifconfig(fd, iface); printoutc(fd, ""); iface = iface->next; } return 0; } else { struct vder_iface *selected; struct in_addr temp_address, temp_netmask; enum command_action_enum action = -1; selected = select_interface(arg); if (!selected) { printoutc(fd, "Interface %s not found.", arg); return ENOENT; } arg = strtok_r(NULL, " ", &nextargs); if (!arg) { show_ifconfig(fd, selected); return 0; } if ((!arg) || (strlen(arg) != 3) || ((strncmp(arg, "add", 3) != 0) && (strncmp(arg, "del", 3) != 0))) { printoutc(fd, "Invalid action \"%s\".", arg); return EINVAL; } if (strncmp(arg, "del", 3) == 0) action = ACTION_DELETE; else action = ACTION_ADD; arg = strtok_r(NULL, " ", &nextargs); if (!arg) { not_understood(fd, ""); return EINVAL; } if (match_input("dhcp", arg)) { temp_address.s_addr = (uint32_t)(-1); pthread_create(&selected->dhcpclient, 0, dhcp_client_loop, selected); } else if (!inet_aton(arg, &temp_address) || !is_unicast(temp_address.s_addr)) { printoutc(fd, "Invalid address \"%s\"", arg); return EINVAL; } arg = strtok_r(NULL, " ", &nextargs); if (!arg && (action == ACTION_ADD) && (temp_address.s_addr != (uint32_t)(-1))) { printoutc(fd, "Error: parameter 'netmask' required."); return EINVAL; } if ((action == ACTION_ADD) && (temp_address.s_addr != (uint32_t)(-1)) && (!inet_aton(arg, &temp_netmask) || !is_netmask(temp_netmask.s_addr))) { printoutc(fd, "Invalid netmask \"%s\"", arg); return EINVAL; } if (action == ACTION_ADD) { if (vder_iface_address_add(selected, temp_address.s_addr, temp_netmask.s_addr) != 0) return errno; } else { if (vder_iface_address_del(selected, temp_address.s_addr) != 0) return errno; } } return 0; }