/* *=========================================================================== * ipnet_cmd_qc_parse_parent *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_cmd_qc_parse_parent(Ipnet_cmd_qc *p) { p->p.ifq.ifq_parent_id = IP_IFQ_ID_NONE; if (p->argc < 1) return 0; if (ipcom_strcmp(*p->argv, "root") == 0) { ipnet_cmd_qc_next_arg(p); return 0; } if (ipcom_strcmp(*p->argv, "parent") == 0) { ipnet_cmd_qc_next_arg(p); if (p->argc < 1) { ipcom_printf("Expected [ root | parent <q-id> ]"IP_LF); return -1; } p->p.ifq.ifq_parent_id = ipcom_atoi(*p->argv); ipnet_cmd_qc_next_arg(p); } return 0; }
/* *=========================================================================== * ipnet_cmd_qc_parse_number *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_bool ipnet_cmd_qc_parse_number(const char *str_num, Ip_u32 *num) { char *end; long lnum; lnum = ipcom_strtol(str_num, &end, 10); if (lnum < 0) *num = 0; else *num = (Ip_u32) lnum; if (end && ipcom_strlen(end) > 0) { if (ipcom_strcmp(end, "k") == 0 || ipcom_strcmp(end, "kb") == 0) *num *= 1000; else if (ipcom_strcmp(end, "M") == 0 || ipcom_strcmp(end, "Mb") == 0) *num *= 1000000; else { ipcom_printf("'%s' is an unsupported number suffix"IP_LF, str_num); return IP_FALSE; } } return IP_TRUE; }
/* *=========================================================================== * ipcom_shellalias_find *=========================================================================== * Description: Find a given alias based on name. * Parameters: name - The alias name. * Returns: The alias if found. * */ IP_STATIC struct Ipcom_shellalias_alias * ipcom_shellalias_find(const char *name) { struct Ipcom_shellalias_alias *alias; /* Go through the aliases */ for (alias = IPCOM_LIST_FIRST(&ipcom_shellalias_head); alias != IP_NULL; alias = IPCOM_LIST_NEXT(&alias->next)) { if (name == IP_NULL) { int i; ipcom_printf("%-15s\t'", alias->name); for (i = 0; i < alias->argc; i++) { ipcom_printf("%s%s", alias->argv[i], (i == alias->argc - 1)? "" : " "); } ipcom_printf("'"IP_LF); } /* Did it match? */ else if (ipcom_strcmp(alias->name, name) == 0) { /* Return it */ return alias; } } /* No go */ return IP_NULL; }
/* *=========================================================================== * ipsecctrl_set *=========================================================================== */ static int ipsecctrl_set(Argvars *vars) { int i; Ip_tag tags[3]; if (vars->argc != 4) { ipcom_printf("usage: > ipsecctrl set <name> <integer value>"IP_LF); return -1; } for (i = 0; params[i].name != IP_NULL; i++) if (ipcom_strcmp(vars->argv[2], params[i].name) == 0) { tags[0] = params[i].set; tags[1] = ipcom_atoi(vars->argv[3]); tags[2] = IP_TAG_END; ipipsec_conf(tags); ipcom_printf("ipsecctrl: %s set to %d"IP_LF, params[i].name, tags[1]); return 0; } ipcom_printf("ipsecctrl set: '%s' not found"IP_LF, vars->argv[2]); return -1; }
/* *=========================================================================== * ipcom_shell_cmd_help *=========================================================================== * Description: Shell command: Get help on command or display all commands * Parameters: argc - number of arguments * argv - pointer to pointer to the arguments * Returns: 0 * */ IP_STATIC int ipcom_shell_cmd_help(int argc, char **argv) { Ipcom_shell_cmd *cmd; Ipcom_shell_intcmd *intcmd; Ip_s32 i = 0; /* Check if argument is supplied */ if (argc > 1) { intcmd = IP_NULL; /* Find shell internal command */ while(shell_intcmd[i].name[0] != 0) { intcmd = (Ipcom_shell_intcmd *)&shell_intcmd[i]; if (ipcom_strcmp(intcmd->name, argv[1]) == 0) break; intcmd = IP_NULL; i++; } if (intcmd) { ipcom_printf("Usage: %s\n", intcmd->usage); return 0; } /* Find shell command */ cmd = ipcom_shell_find_cmd(argv[1]); if (cmd) { ipcom_printf("Usage: %s\n", cmd->usage); return 0; } /* Command not found */ ipcom_printf("help: Unknown command '%s'\n", argv[1]); } else { /* List all shell internal commands */ while(shell_intcmd[i].name[0] != 0) { ipcom_printf("%-32s %s\n", shell_intcmd[i].name, shell_intcmd[i].description); i++; } /* List all shell commands */ for (cmd = IPCOM_LIST_FIRST(&ipcom_shell_cmd_head); cmd; cmd = IPCOM_LIST_NEXT(&cmd->cmd_list)) { ipcom_printf("%-32s %s\n", cmd->name, cmd->description); } ipcom_printf("\n"); } return 0; }
/* *=========================================================================== * ipsecctrl_run_command *=========================================================================== */ static int ipsecctrl_run_command(char *name, Argvars *vars) { int i; if (ipcom_strcmp(name, "exit") == 0) ipcom_exit(1); for (i = 0; commands[i].name; i++) if (ipcom_strcmp(name, commands[i].name) == 0) { return commands[i].func(vars); } ipcom_printf( "<ipsecctrl> : unknown command '%s'."IP_LF, name); return -1; }
/* *=========================================================================== * ipnet_config_run_boot_cmd *=========================================================================== * Description: Configures one route entry. * Parameters: * Returns: * */ IP_STATIC int ipnet_config_run_boot_cmd(const char *conf) { char *option_org; char *option; char *argv[20]; char *arg; int argc = 0; int ret = -IP_ERRNO_EINVAL; option_org = option = ipcom_strdup(conf); if (option == IP_NULL) return -IP_ERRNO_ENOMEM; while (IP_NULL != (arg = ipcom_strtok_r(option, " \t", &option))) { if (argc == 1) argv[argc++] = "-silent"; argv[argc++] = arg; if (argc >= (int) (sizeof(argv) / sizeof(*argv))) { IPCOM_LOG1(ERR, "Too many arguments in command %s", conf); IP_PANIC(); } } argv[argc] = IP_NULL; if (argc > 2) { if (ipcom_strcmp(argv[0], "route") == 0) ret = ipnet_config_cmd_route(argc, argv); else if (ipcom_strcmp(argv[0], "ifconfig") == 0) ret = ipnet_config_cmd_ifconfig(argc, argv); else if (ipcom_strcmp(argv[0], "qc") == 0) ret = ipnet_config_cmd_qc(argc, argv); #if defined(IPNET_USE_NAT) && !defined(IP_PORT_LKM) && !defined(IP_PORT_VXWORKS) else if (ipcom_strcmp(argv[0], "nat") == 0) ret = ipnet_cmd_nat(argc, argv); #endif } ipcom_free(option_org); return ret; }
/* *=========================================================================== * ipcom_find_service_byname *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC struct Ipcom_service * ipcom_find_service_byname(const char *name, const char *proto) { int i = 0; while(services[i].name != IP_NULL) { if(ipcom_strcmp(services[i].name, name) == 0 || (services[i].alias1 != IP_NULL && ipcom_strcmp(services[i].alias1, name) == 0) || (services[i].alias2 != IP_NULL && ipcom_strcmp(services[i].alias2, name) == 0)) { if(proto == IP_NULL || ipcom_strcmp(services[i].proto, proto) == 0) return (struct Ipcom_service *)&services[i]; } ++i; } return IP_NULL; }
/* *=========================================================================== * ipnet_config_add_gateway6 *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_config_add_gateway6(char *ifname, char *option) { char *gw; gw = ipcom_strtok_r(option, " \t", &option); if (gw == IP_NULL || ipcom_strcmp(gw, "::") == 0) return ipnet_config_add_route(IP_AF_INET6, "::", 0, (char *) ifname); return ipnet_config_add_route(IP_AF_INET6, "::", 0, gw); }
/* *=========================================================================== * ipnet_cmd_qc_get_op_func *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ipnet_cmd_qc_op ipnet_cmd_qc_get_op_func(const char *type, const char *op) { int i; int count = sizeof(ipnet_cmd_qc_op_handlers) / sizeof(ipnet_cmd_qc_op_handlers[0]); for (i = 0; i < count; i++) if (ipcom_strcmp(ipnet_cmd_qc_op_handlers[i].type, type) == 0 && ipcom_strcmp(ipnet_cmd_qc_op_handlers[i].op, op) == 0) return ipnet_cmd_qc_op_handlers[i].f_op; ipcom_printf("'%s %s' is an unknown operation, knowed operations are:"IP_LF, type, op); for (i = 0; i < count; i++) ipcom_printf(" '%s %s', " IP_LF, ipnet_cmd_qc_op_handlers[i].type, ipnet_cmd_qc_op_handlers[i].op); return IP_NULL; }
/* *=========================================================================== * ipnet_cmd_qc_parse_mbc *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_cmd_qc_parse_mbc(Ipnet_cmd_qc *p) { struct Ipnet_ifqueue_mbc *m = &p->p.ifq.ifq_data.mbc; if (p->argc == 0) return ipnet_cmd_qc_help_mbc(); m->mbc_bands = 0; m->mbc_default_band = 1; while (p->argc) { if (ipcom_strcmp(*p->argv, "bands") == 0) { ipnet_cmd_qc_next_arg(p); if (!ipnet_cmd_qc_parse_number(*p->argv, &m->mbc_bands)) return -1; } else if (ipcom_strcmp(*p->argv, "default_band") == 0) { ipnet_cmd_qc_next_arg(p); if (!ipnet_cmd_qc_parse_number(*p->argv, &m->mbc_default_band)) return -1; } else { ipcom_printf("'%s' is not a MBC parameter"IP_LF, *p->argv); return ipnet_cmd_qc_help_mbc(); } ipnet_cmd_qc_next_arg(p); } if (m->mbc_bands < 2 || m->mbc_bands > IPNET_IFQ_CONTAINER_MAX_COUNT) { ipcom_printf("The number of bands for MBC must be between 2 and %d"IP_LF, IPNET_IFQ_CONTAINER_MAX_COUNT); return ipnet_cmd_qc_help_mbc(); } return 0; }
/* *=========================================================================== * ipnet_cmd_qc_parse_htbc *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_cmd_qc_parse_htbc(Ipnet_cmd_qc *p) { struct Ipnet_ifqueue_htbc *h = &p->p.ifq.ifq_data.htbc; if (p->argc == 0) return ipnet_cmd_qc_help_htbc(); h->htbc_byterate = 0; h->htbc_token_limit = 0; while (p->argc) { if (ipcom_strcmp(*p->argv, "rate") == 0) { ipnet_cmd_qc_next_arg(p); if (!ipnet_cmd_qc_parse_rate(*p->argv, &h->htbc_byterate)) return -1; } else if (ipcom_strcmp(*p->argv, "burst") == 0) { ipnet_cmd_qc_next_arg(p); if (!ipnet_cmd_qc_parse_number(*p->argv, &h->htbc_token_limit)) return -1; } else { ipcom_printf("'%s' is not a HTBC parameter"IP_LF, *p->argv); return ipnet_cmd_qc_help_htbc(); } ipnet_cmd_qc_next_arg(p); } if (h->htbc_byterate == 0) { ipcom_printf("The data rate for HTBC must be >0"IP_LF); return ipnet_cmd_qc_help_htbc(); } return 0; }
/* *=========================================================================== * ipcom_shell_find_cmd *=========================================================================== * Description: Search for a command in the list of available ipcom_shell * commands * Parameters: name : the command to search for * Returns: pointer to the command or IP_NULL if not found * */ IP_PUBLIC Ipcom_shell_cmd * ipcom_shell_find_cmd(const char *name) { Ipcom_shell_cmd *cmd; /* First check if present */ for (cmd = IPCOM_LIST_FIRST(&ipcom_shell_cmd_head); cmd; cmd = IPCOM_LIST_NEXT(&cmd->cmd_list)) if (ipcom_strcmp(cmd->name, name) == 0) break; return cmd; }
/* *=========================================================================== * ipnet_cmd_qc_parse_rate *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_bool ipnet_cmd_qc_parse_rate(const char *str_rate, Ip_u32 *rate) { char *end; *rate = (Ip_u32) ipcom_strtol(str_rate, &end, 10); if (end && ipcom_strlen(end) > 0) { if (ipcom_strcmp(end, "kbps") == 0) *rate *= 1000; else if (ipcom_strcmp(end, "Mbps") == 0) *rate *= 1000000; else if (ipcom_strcmp(end, "kbit") == 0) *rate *= 1000 / 8; else if (ipcom_strcmp(end, "Mbit") == 0) *rate *= 1000000 / 8; else if (ipcom_strcmp(end, "bit") == 0) *rate /= 8; else if (ipcom_strcmp(end, "bps") == 0) ; else { ipcom_printf("'%s' is an unsupported rate suffix"IP_LF, end); return IP_FALSE; } } return IP_TRUE; }
/* *=========================================================================== * ipnet_rtnetlink_get_ops *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL struct Ip_rtnl_link_ops * ipnet_rtnetlink_get_ops(const char *kind) { struct Ip_rtnl_link_ops *ops = ipnet->rtnetlink_ops; while (ops != IP_NULL) { if (ipcom_strcmp(ops->kind, kind) == 0) return ops; ops = ops->next; } return IP_NULL; }
/* *=========================================================================== * ipnet_cmd_qc_parse_id *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_cmd_qc_parse_id(Ipnet_cmd_qc *p) { p->p.ifq.ifq_id = (p->cmd_op == ipnet_cmd_qc_show_queue ? IP_IFQ_ID_NONE : IP_IFQ_ID_DEFAULT); if (p->argc < 2 || ipcom_strcmp(*p->argv, "handle") != 0) return 0; ipnet_cmd_qc_next_arg(p); p->p.ifq.ifq_id = ipcom_atoi(*p->argv); ipnet_cmd_qc_next_arg(p); return 0; }
/* *=========================================================================== * ipcom_find_service_byport *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC struct Ipcom_service * ipcom_find_service_byport(int port, char *proto) { int i = 0; while(services[i].name != IP_NULL) { if(services[i].port == port) { if(proto == IP_NULL || ipcom_strcmp(services[i].proto, proto) == 0) return (struct Ipcom_service *)&services[i]; } ++i; } return IP_NULL; }
/* *=========================================================================== * ipnet_cmd_qc_get_type_handler *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ipnet_cmd_qc_type_handler * ipnet_cmd_qc_get_type_handler(const char *type) { int i; int count = sizeof(ipnet_qc_type_handlers) / sizeof(ipnet_qc_type_handlers[0]); for (i = 0; i < count; i++) if (ipcom_strcmp(ipnet_qc_type_handlers[i].type, type) == 0) return &ipnet_qc_type_handlers[i]; ipcom_printf("'%s' is an unknown queue type, known types are: ", type); for (i = 0; i < count; i++) ipcom_printf("%s, ", ipnet_qc_type_handlers[i].type); ipcom_printf(IP_LF); return IP_NULL; }
/* *=========================================================================== * ipnet_cmd_qc_parse_dpaf *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_cmd_qc_parse_dpaf(Ipnet_cmd_qc *p) { struct Ipnet_ifqueue_dpaf *d = &p->p.ifq.ifq_data.dpaf; if (p->argc != 2 || ipcom_strcmp(*p->argv, "limit") != 0) return ipnet_cmd_qc_help_dpaf(); ipnet_cmd_qc_next_arg(p); if (!ipnet_cmd_qc_parse_number(*p->argv, &d->dpaf_limit)) return -IP_ERRNO_EINVAL; if (d->dpaf_limit == 0) { ipcom_printf("The queue limit must be >0"IP_LF); return -IP_ERRNO_EINVAL; } ipnet_cmd_qc_next_arg(p); return 0; }
/* *=========================================================================== * ipnet_cmd_qc_parse_dev *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_cmd_qc_parse_dev(Ipnet_cmd_qc *p) { if (p->argc < 2 || ipcom_strcmp(*p->argv, "dev") != 0) { ipcom_printf("expected 'dev <if>'" IP_LF); return -IP_ERRNO_EINVAL; } ipnet_cmd_qc_next_arg(p); if (ipcom_if_nametoindex(*p->argv) == 0) { ipcom_printf("'%s' is not a valid interface name" IP_LF, *p->argv); return -IP_ERRNO_EINVAL; } ipcom_strcpy(p->p.ifq.ifq_name, *p->argv); ipnet_cmd_qc_next_arg(p); return 0; }
/* *=========================================================================== * ipnet_config_add_gateway *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipnet_config_add_gateway(Ip_fd fd, char *ifname, char *option) { char gw_str[IP_INET_ADDRSTRLEN]; char *gw; gw = ipcom_strtok_r(option, " \t", &option); if (gw == IP_NULL) { IPCOM_LOG1(ERR, "Wrong gateway format specified for interface %s, must be 'gateway <driver|gw_address>", ifname); IP_PANIC(); return -IP_ERRNO_EINVAL; } if (ipcom_strcmp(gw, "driver") == 0) { /* Get the IPv4 gateway address to use from the driver */ struct Ip_ethreq ethreq; ipcom_strcpy(ethreq.ethr_name, ifname); if (ipcom_socketioctl(fd, IP_SIOCXETHGINET, ðreq) < 0) { IPCOM_LOG1(ERR, "Failed to read the IPv4 gateway address " "from the driver for %s", ifname); return ipcom_errno; } if (ethreq.ethru.inet.gateway.s_addr == 0xffffffff) return 0; /* using dhcp, ignore gateway */ if (ethreq.ethru.inet.gateway.s_addr == 0) { IPCOM_LOG1(NOTICE, "No IPv4 gateway address set in driver for %s", ifname); return 0; } (void) ipcom_inet_ntop(IP_AF_INET, ðreq.ethru.inet.gateway, gw_str, sizeof(gw_str)); gw = gw_str; } return ipnet_config_add_route(IP_AF_INET, "0.0.0.0", 0, gw); }
int vlan_check(int ifindex, char * parent) { struct Ip_ifreq ifreq; struct Ip_vlanreq vlanreq; int fd; fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0); ipcom_memset(&vlanreq, 0, sizeof(struct Ip_vlanreq)); ifreq.ip_ifr_data = &vlanreq; if (ipcom_if_indextoname(ifindex, ifreq.ifr_name) == IP_NULL || ipcom_socketioctl(fd, IP_SIOCGETVLAN, &ifreq) < 0) return 0; if(ipcom_strcmp(parent,vlanreq.vlr_parent) == 0) { return 1; } else return -1; }
/* *=========================================================================== * ipcom_cmd_ipd *=========================================================================== * Description: * Parameters: * Returns: */ IP_PUBLIC int ipcom_cmd_ipd(int argc, char **argv) { Ipcom_getopt opt; int i, c, msgtype; Ip_err err = IPCOM_SUCCESS; #if IPCOM_VR_MAX > 1 int vr = ipcom_proc_vr_get(); int vr_new = vr; #endif if (argc < 2) { usage: ipcom_fprintf(ip_stderr, "Interpeak daemon (IPD) command, version 1.2"IP_LF "usage: "IP_LF " ipd [-V <vr>] list"IP_LF " ipd [-V <vr>] start <service>"IP_LF " ipd [-V <vr>] kill <service>"IP_LF " ipd [-V <vr>] reconfigure <service>"IP_LF " ipd [-V <vr>] <#> <service>"IP_LF IP_LF); return 0; } ipcom_getopt_clear_r(&opt); while ((c = ipcom_getopt_r(argc, argv, "V:", &opt)) != -1) { switch(c) { case 'V': #if IPCOM_VR_MAX > 1 vr_new = ipcom_atoi(opt.optarg); #endif break; default: ipcom_printf("ipd: unknown option %c"IP_LF, (char)c); return -1; } } if (opt.optind >= argc) { ipcom_printf("ipd: missing <command> argument"IP_LF); goto usage; } if(ipcom_strcmp(argv[opt.optind], "list") == 0) { #if IPCOM_VR_MAX > 1 if (vr != vr_new) ipcom_proc_vr_set(vr_new); #endif ipcom_printf("Services:"IP_LF); for (i = 0; ipcom_ipd_products[i].name != IP_NULL; i++) { if ((argc - (opt.optind + 1)) > 0) { int p; for (p = opt.optind + 1; p < argc; p++) { if (ipcom_strcasecmp(ipcom_ipd_products[i].name, argv[p]) == 0) goto print_service; } continue; } print_service: if (IP_BIT_ISSET(ipcom_ipd_products[i].flags, IPCOM_IPD_FLAG_IPD_START)) { #ifdef IP_PORT_OSE5 if (ipcom_ipd_products[i].start == IP_NULL && ipcom_ipd_isinstalled_ose5(ipcom_ipd_products[i].name) != IPCOM_SUCCESS) continue; #endif err = ipcom_ipd_send(ipcom_ipd_products[i].name, IPCOM_IPD_MSGTYPE_PING); ipcom_printf("%-20s %-s"IP_LF, ipcom_ipd_products[i].name, err == IPCOM_SUCCESS ? "started" : "killed"); } else if (ipcom_ipd_products[i].start) ipcom_printf("%-20s %-s"IP_LF, ipcom_ipd_products[i].name, "started"); } ipcom_printf(IP_LF); #if IPCOM_VR_MAX > 1 if (vr != vr_new) ipcom_proc_vr_set(vr); #endif return 0; } if ((argc - opt.optind) < 2) { ipcom_printf("ipd: missing <service> argument"IP_LF); return -1; } for (i = 0; ipcom_cmd_ipd_messages[i].name; i++) if (ipcom_strcmp(argv[opt.optind], ipcom_cmd_ipd_messages[i].name) == 0) { msgtype = ipcom_cmd_ipd_messages[i].msgtype; goto sendmsg; } if (*argv[opt.optind] == '-' && ipcom_isdigit(argv[opt.optind][1])) { /* "UNIX" signal support (using negative numbers) */ msgtype = -ipcom_atoi(argv[opt.optind] + 1); goto sendmsg; } if (ipcom_isdigit(argv[opt.optind][0])) { /* positive numbers */ msgtype = ipcom_atoi(argv[1]); goto sendmsg; } /* unknown command. */ ipcom_printf ("ipd: unknown command '%s'"IP_LF, argv[opt.optind]); return -1; /* send msg */ sendmsg: #if IPCOM_VR_MAX > 1 if (vr != vr_new) ipcom_proc_vr_set(vr_new); #endif if ((argc - opt.optind) < 3) err = ipcom_ipd_send(argv[opt.optind+1], msgtype); else { Ipcom_ipd_msg *msg; int sz = ipcom_strlen(argv[opt.optind + 2]) + 1; msg = ipcom_calloc(1, sz + sizeof(*msg)); if (msg != IP_NULL) { msg->msgtype = msgtype; ipcom_memcpy(msg + 1, argv[opt.optind + 2], sz); err = ipcom_ipd_sendmsg(argv[opt.optind+1], msg, sz + sizeof(*msg)); ipcom_free(msg); } } if(err == IPCOM_SUCCESS) ipcom_printf("ipd: %s %s ok"IP_LF, argv[opt.optind], argv[opt.optind+1]); else ipcom_printf("ipd: %s %s failed: %s"IP_LF, argv[opt.optind], argv[opt.optind+1], ipcom_err_string(err)); #if IPCOM_VR_MAX > 1 if (vr != vr_new) ipcom_proc_vr_set(vr); #endif return 0; }
/* *=========================================================================== * ipnet_loopback_ioctl *=========================================================================== * Description: IO control. Accept join/leave from multicast groups. * Parameters: netif - The network interface on which to perform the operation. * command - The command to perform. * data - Data associated with the command. * Returns: 0 = success, 0< = error code. * */ IP_STATIC int ipnet_loopback_ioctl(Ipnet_netif *netif, Ip_u32 command, void *data) { struct Ip_ifreq *ifreq = data; int ret = 0; switch (command) { case IP_SIOCXOPEN: #ifdef IP_PORT_LKM /* Call linux loopback device */ ipnet_if_drv_ioctl(netif, IP_SIOCXOPEN, IP_NULL); #endif /* IP_PORT_LKM */ ipnet_kioevent(netif, IP_EIOXRUNNING, IP_NULL, IP_FLAG_FC_STACKCONTEXT); ipnet_kioevent(netif, IP_EIOXUP, IP_NULL, IP_FLAG_FC_STACKCONTEXT); break; case IP_SIOCXCLOSE: #ifdef IP_PORT_LKM /* Call linux loopback device */ ipnet_if_drv_ioctl(netif, IP_SIOCXCLOSE, IP_NULL); #endif /* IP_PORT_LKM */ ipnet_kioevent(netif, IP_EIOXDOWN, IP_NULL, IP_FLAG_FC_STACKCONTEXT); ipnet_kioevent(netif, IP_EIOXSTOP, IP_NULL, IP_FLAG_FC_STACKCONTEXT); break; case IP_SIOCGIFHWADDR: /* Switch to our if type */ ifreq->ip_ifr_addr.sa_family = netif->ipcom.type; /* Return */ break; case IP_SIOCGIFLLADDR: ifreq->ip_ifr_addr.sa_family = IP_AF_LINK; IPCOM_SA_LEN_SET(&ifreq->ip_ifr_addr, 0); break; case IP_SIOCIFDESTROY: if (ipcom_strcmp(netif->ipcom.name, IPNET_IF_LOOPBACK_NAME) == 0) ret = -IP_ERRNO_EPERM; else { ret = ipcom_if_detach(&netif->ipcom); if (ret >= 0) ret = ipcom_if_free(&netif->ipcom); } break; #ifdef IPCOM_USE_INET case IP_SIOCXADDMULTI_IN: case IP_SIOCXDELMULTI_IN: #endif #ifdef IPCOM_USE_INET6 case IP_SIOCXADDMULTI_IN6: case IP_SIOCXDELMULTI_IN6: #endif break; default: return -IP_ERRNO_EINVAL; } return ret; }
/* *=========================================================================== * ipcom_sysvar_pqueue_cmp *=========================================================================== * Description: * Parameters: * Returns: */ IP_STATIC Ip_bool ipcom_sysvar_pqueue_cmp(Ipcom_sysvar_entry *s1, Ipcom_sysvar_entry *s2) { return ipcom_strcmp(s2->name, s1->name); }
/* *=========================================================================== * ipcom_sysvar_hash_cmp *=========================================================================== * Description: * Parameters: * Returns: */ IP_STATIC Ip_bool ipcom_sysvar_hash_cmp(Ipcom_sysvar_entry *s, char *key) { return ipcom_strcmp(s->name, key) == 0; }
/* *=========================================================================== * ipcom_waitif_gifaddr *=========================================================================== * Description: Get interface address. * Parameters: fd - socket descriptor * ifindex - Interface index. * domain - The address domain. * Returns: 0 = No address available, 1 = No address available, -1 = error. * */ IP_STATIC int ipcom_waitif_gifaddr(Ip_fd fd, int ifindex, int domain) { int ret = -1; switch (domain) { case IP_AF_INET: { struct Ip_ifreq ifreq; /* Get if name */ ipcom_memset(&ifreq, 0, sizeof(ifreq)); (void)ipcom_if_indextoname(ifindex, ifreq.ifr_name); /* Get main address */ if (ipcom_socketioctl(fd, IP_SIOCGIFADDR, &ifreq) < 0) { if (ipcom_errno != IP_ERRNO_EADDRNOTAVAIL && ipcom_errno != IP_ERRNO_ENXIO) { IPCOM_LOG1(ERR, "ipcom_waitif :: ipcom_socketioctl(SIOCGIFADDR) failed, errno = %d", ipcom_errno); } } else { struct Ip_in_addr network = ((struct Ip_sockaddr_in *)&ifreq.ip_ifr_addr)->sin_addr; if (network.s_addr != IP_INADDR_DEFAULT) { ret = 0; } } break; } #ifdef IPCOM_USE_INET6 case IP_AF_INET6: { int len = IPNET_WAITIF_MAXIF * sizeof(struct Ip_ifreq); char ifname[IP_IFNAMSIZ]; struct Ip_ifconf ifc; char *buf = IP_NULL; char *ptr; /* Get if name */ (void)ipcom_if_indextoname(ifindex, ifname); /* Get if data buffer */ if ((buf = ipcom_malloc(IPNET_WAITIF_MAXIF * sizeof(struct Ip_ifreq))) == IP_NULL) { IPCOM_LOG0(ERR, "ipcom_waitif :: Out of memory"); goto leave; } /* Enter buf in ifconf struct */ ifc.ifc_len = len; ifc.ip_ifc_buf = buf; if (ipcom_socketioctl(fd, IP_SIOCGIFCONF, &ifc) < 0) { IPCOM_LOG1(ERR, "ipcom_socketioctl(SIOCGIFCONF) failed, errno = %d\n", ipcom_errno); goto leave; } /* Loop for all interfaces */ for (ptr = buf; ptr < buf + ifc.ifc_len; ) { struct Ip_ifreq *ifr = (struct Ip_ifreq *)ptr; char *cptr; /* Calculate pointer to next if */ len = IP_MAX(sizeof(struct Ip_sockaddr_in), ifr->ip_ifr_addr.sa_len); ptr += sizeof(ifr->ifr_name) + len; if ((cptr = ipcom_strchr(ifr->ifr_name, ':')) != IP_NULL) { *cptr = '\0'; } /* Only for v6 addresses */ if (ipcom_strcmp(ifr->ifr_name, ifname) == 0 && ifr->ip_ifr_addr.sa_family == IP_AF_INET6) { struct Ip_sockaddr_in6 *in6 = (struct Ip_sockaddr_in6 *)&ifr->ip_ifr_addr; if (!IP_IN6_IS_ADDR_UNSPECIFIED(&in6->sin6_addr)) { ret = 0; break; } } } leave: if (buf != IP_NULL) { ipcom_free(buf); } break; } #endif /* IPCOM_USE_INET6 */ } return ret; }
/* *=========================================================================== * ipcom_shell_run_extcmd *=========================================================================== * Description: Starts a shell command process and delivers the command arguments * and stdio socket to that process. * Parameters: argc, argv - traditional command arguments * stdio_fd - the standard input, output and error sock * ppid - parent pid * cmd_pid - shell command process id * * Returns: 1 : command process started * 0 : not an external command * -1 : error * */ IP_PUBLIC Ip_err ipcom_shell_run_extcmd(int argc, char **argv, Ip_fd *stdio_fd, Ip_pid_t ppid, Ip_u32 seqno, Ip_pid_t *cmd_pid, int *proc_index) { Ipcom_proc_attr attr; Ipcom_ipc ipc; Ipcom_shellcmd_info *sinfo; Ipcom_shell_cmd *cmd = IP_NULL; Ipcom_shell_cmd *tcmd; Ip_err retval; char procname[40]; Ip_u32 stack = IPCOM_PROC_STACK_DEFAULT; Ip_pid_t pid; pid = ipcom_getpid(); ipcom_sprintf(procname, "ipcom_sc_0x%lx_%d", (Ip_u32)pid, *proc_index); /* Find command and max stack size (since we are reusing the process). */ if (argc > 0) { for (tcmd = IPCOM_LIST_FIRST(&ipcom_shell_cmd_head); tcmd; tcmd = IPCOM_LIST_NEXT(&tcmd->cmd_list)) { stack = (Ip_u32)IP_MAX(stack, tcmd->stack_size); if (cmd == IP_NULL && ipcom_strcmp(tcmd->name, argv[0]) == 0) { cmd = tcmd; if (*cmd_pid != 0) break; } } if (cmd == IP_NULL) return 0; /* Start the shell_cmd process. */ if (*cmd_pid == 0) { ipcom_proc_attr_init(&attr); attr.priority = (Ip_u32)cmd->priority; attr.stacksize = stack; attr.flags |= IPCOM_PROC_FLAG_FP; if (ipcom_proc_acreate(procname, (Ipcom_proc_func)ipcom_shell_cmd, &attr, cmd_pid)) { IPCOM_LOG0(ERR, "ipcom_shell_run_extcmd :: ipcom_proc_acreate() failed"); goto fail; } ip_assert(*cmd_pid != 0); } } else { /* argc == 0 is used to kill the shell_cmd process. */ ip_assert(*cmd_pid != 0); } /* Open IPC with ipcom_shell. */ retval = ipcom_ipc_open(&ipc, procname, -1); if (retval != IPCOM_SUCCESS) { IPCOM_LOG2(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_open(%s) failed, ret = %d", procname, retval); goto fail; } /* Send a message to ipcom_shell. */ sinfo = ipcom_ipc_malloc(sizeof(Ipcom_shellcmd_info)); if (sinfo == IP_NULL) { IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_malloc() failed, ret = %d", retval); goto fail; } /* Fill in IPC info. */ sinfo->argc = argc; if (argc > 0) { sinfo->hook = cmd->hook; sinfo->argv = argv; sinfo->fd = *stdio_fd; sinfo->pid = pid; sinfo->ppid = ppid; sinfo->seqno = seqno; #if IPCOM_USE_FILE != IPCOM_FILE_NONE if (ipcom_getcwd(sinfo->cwd, sizeof(sinfo->cwd)) == IP_NULL) ipcom_memset(sinfo->cwd, 0, sizeof(sinfo->cwd)); else sinfo->cwd[sizeof(sinfo->cwd)-1] = '\0'; #endif sinfo->prio = cmd->priority; } /* Send the IPC info. */ retval = ipcom_ipc_send(&ipc, sinfo); if (retval != IPCOM_SUCCESS) { IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_send() failed, ret = %d", retval); ipcom_ipc_free(sinfo); goto fail; } (void)ipcom_ipc_close(&ipc); #ifdef IP_PORT_OSE5 if (argc > 0) { /* OSE5 has process specific sockets -> donate child fd */ ip_assert(*cmd_pid != 0); retval = (Ip_err)efs_donate_fd(*stdio_fd, *cmd_pid); if (retval != 0) { IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: efs_donate_fd, ret = %d", retval); goto fail; } } #endif /* IP_PORT_OSE5 */ /* Wait for exit message from shell_cmd process. */ retval = ipcom_ipc_receive(IP_NULL, &sinfo, -1); if (retval != IPCOM_SUCCESS) { IPCOM_LOG1(ERR, "ipcom_shell_run_extcmd :: ipcom_ipc_receive(shell_cmd) failed, ret = %d", retval); goto fail; } ip_assert(argc > 0 || *(Ip_u32 *)sinfo == 1); if (*(Ip_u32 *)sinfo == 1) { *cmd_pid = 0; /* shell command called ipcom_exit(). */ (*proc_index)++; } else { #ifdef IP_PORT_OSE5 *stdio_fd = efs_receive_fd(0); if (*stdio_fd == -1) { IP_PANIC(); goto fail; } #endif #if defined(IP_PORT_OSE) || defined(IP_PORT_OSE5) /* Change child socket owner (A must for OSE to work due to poor ipcom_block impl). */ pid = ipcom_getpid(); if (ipcom_socketioctl(*stdio_fd, IP_SIOCSPGRP, &pid) < 0) { IP_PANIC2(); IPCOM_LOG1(WARNING, "ipcom_shell_run_extcmd :: ipcom_socketioctl(IP_SIOCSPGRP) failed, errno = %d", ipcom_errno); } #endif } ipcom_ipc_free(sinfo); return 1; fail: if (ipcom_ipc_isopen(&ipc)) (void)ipcom_ipc_close(&ipc); return -1; }
/* *=========================================================================== * ipcom_shellalias_remove *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipcom_shellalias_set(char *name, char *cmd) { struct Ipcom_shellalias_alias *alias; if (ipcom_strcmp(name, "alias") == 0 || ipcom_strcmp(name, "unalias") == 0) return -IPCOM_ERR_INVALID_ARG; /* Remove any old references */ ipcom_shellalias_remove(name); /* Allocate a new alias structure */ alias = ipcom_calloc(1, sizeof(*alias)); /* Could we allocate? */ if (alias != IP_NULL) { Ip_err retval; int argc; char **argv = IP_NULL; /* Allocate the name */ alias->name = ipcom_strdup(name); if (alias->name == IP_NULL) goto fail; /* Allocate the command */ alias->cmd = ipcom_strdup(cmd); if (alias->cmd == IP_NULL) goto fail; /* Parse the string */ retval = ipcom_parse_argstr(alias->cmd, (int *)&argc, &argv); switch(retval) { case IPCOM_SUCCESS: break; case IPCOM_ERR_INVALID_ARG: ipcom_printf("Unmatched string delimiters"IP_LF); goto fail; case IPCOM_ERR_FAILED: default: goto fail; } /* Store */ alias->argv = argv; alias->argc = argc; /* Link the alias into the major list */ ipcom_list_insert_first(&ipcom_shellalias_head, &alias->next); /* Success */ return IPCOM_SUCCESS; } /* No memory */ return -IP_ERRNO_ENOMEM; fail: /* Did we manage to allocate the name? */ if (alias->name != IP_NULL) ipcom_free(alias->name); /* Free the stored command */ if (alias->cmd != IP_NULL) ipcom_free(alias->cmd); /* Free the vector */ if (alias->argv != IP_NULL) ipcom_free(alias->argv); /* Free the structure */ ipcom_free(alias); return -IP_ERRNO_ENOMEM; }
/* *=========================================================================== * ipnet_cmd_ifconfig *=========================================================================== * Description: ifconfig shell command entry point. * Parameters: * Returns: * */ IP_PUBLIC int ipnet_cmd_sysctl(int argc, char **argv) { int next_arg = 1; Ip_bool set = IP_FALSE; if (argc < 2) { ipnet_cmd_sysctl_usage(); return IPCOM_SHELL_ERR_USAGE; } /* Silent must only be used by the configuration daemon */ if (argc > next_arg && ipcom_strcmp(argv[next_arg], "-a") == 0) { char *names[12]; int name[12]; ipnet_cmd_sysctl_print_ctl(ipnet_sysctl_base_table, name, 0, names, 0, IP_NULL); return IPCOM_SHELL_SUCCESS; } /* Silent must only be used by the configuration daemon */ if (argc > next_arg && ipcom_strcmp(argv[next_arg], "-w") == 0) { set = IP_TRUE; next_arg++; } /* Process all switches */ while (argc > next_arg) { int ret; if (argv[next_arg][0] == '-') { ipnet_cmd_sysctl_usage(); return IPCOM_SHELL_ERR_USAGE; } ret = ipnet_cmd_sysctl_do(set, argv[next_arg]); if (ret > 0) { ipcom_printf("sysctl: unknown key: %s"IP_LF, argv[next_arg]); return IPCOM_SHELL_ERR_USAGE; } else if (ret < 0) { ipcom_printf("sysctl: syntax error: %s"IP_LF, argv[next_arg]); return IPCOM_SHELL_ERR_USAGE; } next_arg++; } return IPCOM_SHELL_SUCCESS; }