static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) { int res = -1; int argc = *argc_p; char **argv = *argv_p; if (argc < 2) return -1; if (strcmp(*argv, "src") == 0) { NEXT_ARG(); res = parse_ip_addr(&argc, &argv, sel, 12); } else if (strcmp(*argv, "dst") == 0) { NEXT_ARG(); res = parse_ip_addr(&argc, &argv, sel, 16); } else if (strcmp(*argv, "tos") == 0 || matches(*argv, "dsfield") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 1, 0); } else if (strcmp(*argv, "ihl") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 0, 0); } else if (strcmp(*argv, "protocol") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 9, 0); } else if (matches(*argv, "precedence") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 1, 0); } else if (strcmp(*argv, "nofrag") == 0) { argc--; argv++; res = pack_key16(sel, 0, 0x3FFF, 6, 0); } else if (strcmp(*argv, "firstfrag") == 0) { argc--; argv++; res = pack_key16(sel, 0x2000, 0x3FFF, 6, 0); } else if (strcmp(*argv, "df") == 0) { argc--; argv++; res = pack_key16(sel, 0x4000, 0x4000, 6, 0); } else if (strcmp(*argv, "mf") == 0) { argc--; argv++; res = pack_key16(sel, 0x2000, 0x2000, 6, 0); } else if (strcmp(*argv, "dport") == 0) { NEXT_ARG(); res = parse_u16(&argc, &argv, sel, 22, 0); } else if (strcmp(*argv, "sport") == 0) { NEXT_ARG(); res = parse_u16(&argc, &argv, sel, 20, 0); } else if (strcmp(*argv, "icmp_type") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 20, 0); } else if (strcmp(*argv, "icmp_code") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 21, 0); } else return -1; *argc_p = argc; *argv_p = argv; return res; }
static int discover_print(char *target_ip_str) { uint32_t target_ip = 0; if (target_ip_str) { target_ip = parse_ip_addr(target_ip_str); if (target_ip == 0) { fprintf(stderr, "invalid ip address: %s\n", target_ip_str); return -1; } } struct hdhomerun_discover_device_t result_list[64]; int count = hdhomerun_discover_find_devices_custom(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, 64); if (count < 0) { fprintf(stderr, "error sending discover request\n"); return -1; } if (count == 0) { printf("no devices found\n"); return 0; } int index; for (index = 0; index < count; index++) { struct hdhomerun_discover_device_t *result = &result_list[index]; printf("hdhomerun device %08lX found at %u.%u.%u.%u\n", (unsigned long)result->device_id, (unsigned int)(result->ip_addr >> 24) & 0x0FF, (unsigned int)(result->ip_addr >> 16) & 0x0FF, (unsigned int)(result->ip_addr >> 8) & 0x0FF, (unsigned int)(result->ip_addr >> 0) & 0x0FF ); } return count; }
/** setup listening TCP */ static int setup_fd(char* addr, int port) { struct sockaddr_storage ad; socklen_t len; int fd; int c = 1; int fam = parse_ip_addr(addr, port, &ad, &len); fd = socket(fam, SOCK_STREAM, 0); if(fd == -1) { log_errno("socket"); return -1; } if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&c, (socklen_t) sizeof(int)) < 0) { log_errno("setsockopt(SOL_SOCKET, SO_REUSEADDR)"); } if(bind(fd, (struct sockaddr*)&ad, len) == -1) { log_errno("bind"); fd_close(fd); return -1; } if(listen(fd, 5) == -1) { log_errno("listen"); fd_close(fd); return -1; } return fd; }
void parse_reject_statement(FILE *cfile) { struct iaddrlist *list; struct iaddr addr; char *val; int token; do { if (!parse_ip_addr(cfile, &addr)) { parse_warn("expecting IP address."); skip_to_semi(cfile); return; } list = malloc(sizeof(struct iaddrlist)); if (!list) error("no memory for reject list!"); list->addr = addr; list->next = config->reject_list; config->reject_list = list; token = next_token(&val, cfile); } while (token == ','); if (token != ';') { parse_warn("expecting semicolon."); skip_to_semi(cfile); } }
/* * client-lease-declaration :== * BOOTP | * INTERFACE string | * FIXED_ADDR ip_address | * FILENAME string | * SERVER_NAME string | * OPTION option-decl | * RENEW time-decl | * REBIND time-decl | * EXPIRE time-decl */ void parse_client_lease_declaration(FILE *cfile, struct client_lease *lease) { char *val; int token; switch (next_token(&val, cfile)) { case TOK_BOOTP: lease->is_bootp = 1; break; case TOK_INTERFACE: token = next_token(&val, cfile); if (token != TOK_STRING) { parse_warn("expecting interface name (in quotes)."); skip_to_semi(cfile); break; } if (strcmp(ifi->name, val) != 0) { parse_warn("wrong interface name. Expecting '%s'.", ifi->name); skip_to_semi(cfile); break; } break; case TOK_FIXED_ADDR: if (!parse_ip_addr(cfile, &lease->address)) return; break; case TOK_MEDIUM: parse_string_list(cfile, &lease->medium, 0); return; case TOK_FILENAME: lease->filename = parse_string(cfile); return; case TOK_SERVER_NAME: lease->server_name = parse_string(cfile); return; case TOK_RENEW: lease->renewal = parse_date(cfile); return; case TOK_REBIND: lease->rebind = parse_date(cfile); return; case TOK_EXPIRE: lease->expiry = parse_date(cfile); return; case TOK_OPTION: parse_option_decl(cfile, lease->options); return; default: parse_warn("expecting lease declaration."); skip_to_semi(cfile); break; } token = next_token(&val, cfile); if (token != ';') { parse_warn("expecting semicolon."); skip_to_semi(cfile); } }
/* * client-lease-declaration :== * BOOTP | * INTERFACE string | * FIXED_ADDR ip_address | * FILENAME string | * SERVER_NAME string | * OPTION option-decl | * RENEW time-decl | * REBIND time-decl | * EXPIRE time-decl */ void parse_client_lease_declaration(FILE *cfile, struct client_lease *lease, struct interface_info **ipp) { int token; char *val; struct interface_info *ip; switch (next_token(&val, cfile)) { case BOOTP: lease->is_bootp = 1; break; case INTERFACE: token = next_token(&val, cfile); if (token != STRING) { parse_warn("expecting interface name (in quotes)."); skip_to_semi(cfile); break; } ip = interface_or_dummy(val); *ipp = ip; break; case FIXED_ADDR: if (!parse_ip_addr(cfile, &lease->address)) return; break; case MEDIUM: parse_string_list(cfile, &lease->medium, 0); return; case FILENAME: lease->filename = parse_string(cfile); return; case SERVER_NAME: lease->server_name = parse_string(cfile); return; case RENEW: lease->renewal = parse_date(cfile); return; case REBIND: lease->rebind = parse_date(cfile); return; case EXPIRE: lease->expiry = parse_date(cfile); return; case OPTION: parse_option_decl(cfile, lease->options); return; default: parse_warn("expecting lease declaration."); skip_to_semi(cfile); break; } token = next_token(&val, cfile); if (token != SEMI) { parse_warn("expecting semicolon."); skip_to_semi(cfile); } }
PyObject *py_device_discover(PyObject *cls, PyObject *args, PyObject *kwds) { PyObject *result = NULL; PyObject *tuner = NULL; char *target_ip_str = NULL; uint32_t target_ip = 0; int count = 0, i; char *kwlist[] = {"target_ip", NULL}; struct hdhomerun_discover_device_t result_list[64]; if(!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &target_ip_str)) return NULL; if(target_ip_str) { target_ip = parse_ip_addr(target_ip_str); if (target_ip == 0) { PyErr_SetString(hdhomerun_device_error, "invalid ip address"); return NULL; } } count = hdhomerun_discover_find_devices_custom(target_ip, HDHOMERUN_DEVICE_TYPE_TUNER, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, 64); if(count < 0) { PyErr_SetString(hdhomerun_device_error, "error sending discover request"); return NULL; } result = PyList_New((Py_ssize_t)count); if(!result) { return NULL; } if(count > 0) { for(i=0; i<count; i++) { tuner = PyObject_CallFunction(cls, "II", result_list[i].ip_addr, result_list[i].device_id); if(tuner == NULL) { Py_DECREF(result); return NULL; } if(PyList_SetItem(result, i, tuner) != 0) { Py_DECREF(result); return NULL; } } } return result; }
static void *kni_ifconfig(void *a) { struct ifconfig_arg *arg = a; struct knidev *dev = arg->dev; struct conf_opt *opt = arg->opt; struct ifreq ifr; const char *opt1; in_addr_t addr; int mask; strcpy(ifr.ifr_name, opt->name); if (ioctl(sock_fd, SIOCGIFINDEX, &ifr, sizeof(ifr))) { fprintf(stderr, "%s: SIOCGIFINDEX: %s\n", opt->name, strerror(errno)); arg->err = errno; return NULL; } dev->ifindex = ifr.ifr_ifindex; ioctl(sock_fd, SIOCGIFFLAGS, &ifr, sizeof(ifr)); ifr.ifr_flags |= IFF_UP | IFF_NOARP; while (ioctl(sock_fd, SIOCSIFFLAGS, &ifr, sizeof(ifr))) sleep(1); opt1 = conf_get_subopt(opt, "ip-addr"); if (opt1) { if (parse_ip_addr(opt1, &addr, &mask)) { arg->err = EINVAL; return NULL; } ipaddr_add(dev->ifindex, addr, mask); } arg->err = 0; return NULL; }
static int connect_server(const char *host, int port, int want_v4, char *errmsg, int msglen) { struct sockaddr_storage sa; int fd = -1; errmsg[0] = '\0'; if (parse_ip_addr(host, port, want_v4, &sa)) { fd = socket(sa.ss_family, SOCK_STREAM, 0); if (fd == -1) { snprintf(errmsg, msglen, "failed to create a socket: %s\n", strerror(errno)); return -1; } if (connect(fd, (struct sockaddr*)&sa, sizeof(sa)) == -1) { snprintf(errmsg, msglen, "could not connect: %s\n", strerror(errno)); close(fd); return -1; } } return fd; }
static int parse_config_line(char *line) { char *val; /* remove the spaces around the string */ line = trim(line); /* empty line? OK, done */ if (strlen(line) == 0) return TRUE; /* is it a comment? */ if (*line == '#') return TRUE; val = strchr(line, '='); if (!val) { fprintf(stderr, "Error: bad configuration line: \"%s\".\n", line); return FALSE; } /* the string at line now only has the param name and val is the value string */ *val++ = '\0'; /* remove more spaces */ line = trim(line); val = trim(val); /* * set the actual option */ if (!strcmp(line, "pidfile")) { if (!settings.pidfile) settings.pidfile = strdup(val); } else if (!strcmp(line, "logfile")) { if (!settings.logfile) settings.logfile = strdup(val); } else if (!strcmp(line, "port")) { if (!settings.port) settings.port = atoi(val); if (settings.port < 1 || settings.port > 65535) { fprintf(stderr, "Error: Port %d is outside the range of valid port numbers [1-65535].\n", settings.port); return FALSE; } } else if (!strcmp(line, "ipv6addr")) { struct sockaddr_in6 tmp; if (!parse_ip_addr(val, (struct sockaddr*)&tmp, FALSE)) { fprintf(stderr, "Error: %s is not a valid ipv6 address.\n", val); return FALSE; } if (!settings.bind_addr_6.sin6_family != AF_INET6) settings.bind_addr_6 = tmp; } else if (!strcmp(line, "ipv4addr")) { struct sockaddr_in tmp; if (!parse_ip_addr(val, (struct sockaddr*)&tmp, TRUE)) { fprintf(stderr, "Error: %s is not a valid ipv4 address.\n", val); return FALSE; } if (!settings.bind_addr_4.sin_family != AF_INET) settings.bind_addr_4 = tmp; } else if (!strcmp(line, "disable_family")) { if (!settings.disable_ipv4 && !strcmp(val, "v4")) settings.disable_ipv4 = TRUE; else if (!settings.disable_ipv6 && !strcmp(val, "v6")) settings.disable_ipv6 = TRUE; else if (strcmp(val, "v4") && strcmp(val, "v6")) { fprintf(stderr, "Error: the value for disable_family is either v4 or v6, not %s.\n", val); } } else if (!strcmp(line, "unixsocket")) { if (strlen(val) > SUN_PATH_MAX - 1) { fprintf(stderr, "Error: The unix socket filename is too long.\n"); return FALSE; } if (settings.bind_addr_unix.sun_family == 0) { settings.bind_addr_unix.sun_family = AF_UNIX; strncpy(settings.bind_addr_unix.sun_path, val, SUN_PATH_MAX - 1); settings.bind_addr_unix.sun_path[SUN_PATH_MAX-1] = '\0'; } } else if (!strcmp(line, "nodaemon")) { if (*val == '1' || !strcmp(val, "true")) settings.nodaemon = TRUE; else if (*val != '0' && strcmp(val, "false")) { fprintf(stderr, "Error: nodaemon may only be set to \"0\", \"1\", " "\"true\" or \"false\".\n"); return FALSE; } /* this option does not need to be set to false explicitly: that is the default value */ } else if (!strcmp(line, "workdir")) { if (!settings.workdir) settings.workdir = strdup(val); } else if (!strcmp(line, "client_timeout")) { if (!settings.client_timeout) settings.client_timeout = atoi(val); if (settings.client_timeout < 30 || settings.client_timeout > (24 * 60 * 60)) { fprintf(stderr, "Error: the value for client_timeout must be in the" " range [30, 86400].\n"); return FALSE; } } else if (!strcmp(line, "dbhost")) { if (!settings.dbhost) settings.dbhost = strdup(val); } else if (!strcmp(line, "dbport")) { if (!settings.dbport) settings.dbport = strdup(val); } else if (!strcmp(line, "dbuser")) { if (!settings.dbuser) settings.dbuser = strdup(val); } else if (!strcmp(line, "dbpass")) { if (!settings.dbpass) settings.dbpass = strdup(val); } else if (!strcmp(line, "dbname")) { if (!settings.dbname) settings.dbname = strdup(val); } else /* it's a warning, no need to return FALSE */ fprintf(stderr, "Warning: unrecognized option \"%s\".\n", line); return TRUE; }
static int read_parameters(int argc, char *argv[], char **conffile, int *request_kill, int *show_message) { int opt; while ((opt = getopt(argc, argv, "4:6:a:c:D:d:H:hkl:mno:P:p:s:t:u:w:")) != -1) { switch (opt) { case '4': /* bind address */ if (!parse_ip_addr(optarg, (struct sockaddr*)&settings.bind_addr_4, TRUE)) { fprintf(stderr, "Error: \"%s\" was not recognized as an ipv4 address.", optarg); return FALSE; } break; case '6': /* bind address */ if (!parse_ip_addr(optarg, (struct sockaddr*)&settings.bind_addr_6, FALSE)) { fprintf(stderr, "Error: \"%s\" was not recognized as an ipv6 address.", optarg); return FALSE; } break; case 'a': settings.dbpass = strdup(optarg); break; case 'c': /* config file */ *conffile = optarg; break; case 'D': settings.dbname = strdup(optarg); break; case 'd': /* disable ipv4 / ipv6 */ if (!strcmp(optarg, "v4")) settings.disable_ipv4 = TRUE; else if (!strcmp(optarg, "v6")) settings.disable_ipv6 = TRUE; else { fprintf(stderr, "Error: \"v4"" or \"v6\" expected after parameter -d."); return FALSE; } break; case 'H': settings.dbhost = strdup(optarg); break; case 'k': /* kill server */ *request_kill = TRUE; break; case 'l': /* log file */ settings.logfile = strdup(optarg); break; case 'm': *show_message = TRUE; break; case 'n': /* don't daemonize */ settings.nodaemon = TRUE; break; case 'o': settings.dbport = strdup(optarg); break; case 'P': /* port number */ settings.port = atoi(optarg); if (settings.port < 1 || settings.port > 65535) { fprintf(stderr, "Error: Port %d is outside the range of valid port numbers [1-65535].\n", settings.port); return FALSE; } break; case 'p': /* pid file */ settings.pidfile = strdup(optarg); break; case 's': if (strlen(optarg) > SUN_PATH_MAX - 1) { fprintf(stderr, "Error: The unix socket filename is too long.\n"); return FALSE; } settings.bind_addr_unix.sun_family = AF_UNIX; strncpy(settings.bind_addr_unix.sun_path, optarg, SUN_PATH_MAX - 1); settings.bind_addr_unix.sun_path[SUN_PATH_MAX-1] = '\0'; break; case 't': settings.client_timeout = atoi(optarg); if (settings.client_timeout <= 30 || settings.client_timeout > (24 * 60 * 60)) { fprintf(stderr, "Error: Silly value %s given as the client timeout.\n", optarg); return FALSE; } break; case 'u': settings.dbuser = strdup(optarg); break; case 'w': /* work dir */ settings.workdir = strdup(optarg); break; case 'h': /* help */ return FALSE; default: /* unrecognized */ fprintf(stderr, "Error: unknown option '%c'.\n", optopt); return FALSE; } } return TRUE; }
int parse_option_decl(FILE *cfile, struct option_data *options) { char *val; int token; u_int8_t buf[4]; u_int8_t hunkbuf[1024]; int hunkix = 0; char *fmt; struct iaddr ip_addr; u_int8_t *dp; int len, code; int nul_term = 0; token = next_token(&val, cfile); if (!is_identifier(token)) { parse_warn("expecting identifier after option keyword."); if (token != ';') skip_to_semi(cfile); return (-1); } /* Look up the actual option info. */ fmt = NULL; for (code = 0; code < 256; code++) if (strcmp(dhcp_options[code].name, val) == 0) break; if (code > 255) { parse_warn("no option named %s", val); skip_to_semi(cfile); return (-1); } /* Parse the option data... */ do { for (fmt = dhcp_options[code].format; *fmt; fmt++) { if (*fmt == 'A') break; switch (*fmt) { case 'X': len = parse_X(cfile, &hunkbuf[hunkix], sizeof(hunkbuf) - hunkix); hunkix += len; break; case 't': /* Text string... */ token = next_token(&val, cfile); if (token != TOK_STRING) { parse_warn("expecting string."); skip_to_semi(cfile); return (-1); } len = strlen(val); if (hunkix + len + 1 > sizeof(hunkbuf)) { parse_warn("option data buffer %s", "overflow"); skip_to_semi(cfile); return (-1); } memcpy(&hunkbuf[hunkix], val, len + 1); nul_term = 1; hunkix += len; break; case 'I': /* IP address. */ if (!parse_ip_addr(cfile, &ip_addr)) return (-1); len = ip_addr.len; dp = ip_addr.iabuf; alloc: if (hunkix + len > sizeof(hunkbuf)) { parse_warn("option data buffer " "overflow"); skip_to_semi(cfile); return (-1); } memcpy(&hunkbuf[hunkix], dp, len); hunkix += len; break; case 'L': /* Unsigned 32-bit integer... */ case 'l': /* Signed 32-bit integer... */ token = next_token(&val, cfile); if (token != TOK_NUMBER) { need_number: parse_warn("expecting number."); if (token != ';') skip_to_semi(cfile); return (-1); } convert_num(buf, val, 0, 32); len = 4; dp = buf; goto alloc; case 's': /* Signed 16-bit integer. */ case 'S': /* Unsigned 16-bit integer. */ token = next_token(&val, cfile); if (token != TOK_NUMBER) goto need_number; convert_num(buf, val, 0, 16); len = 2; dp = buf; goto alloc; case 'b': /* Signed 8-bit integer. */ case 'B': /* Unsigned 8-bit integer. */ token = next_token(&val, cfile); if (token != TOK_NUMBER) goto need_number; convert_num(buf, val, 0, 8); len = 1; dp = buf; goto alloc; case 'f': /* Boolean flag. */ token = next_token(&val, cfile); if (!is_identifier(token)) { parse_warn("expecting identifier."); bad_flag: if (token != ';') skip_to_semi(cfile); return (-1); } if (!strcasecmp(val, "true") || !strcasecmp(val, "on")) buf[0] = 1; else if (!strcasecmp(val, "false") || !strcasecmp(val, "off")) buf[0] = 0; else { parse_warn("expecting boolean."); goto bad_flag; } len = 1; dp = buf; goto alloc; default: warning("Bad format %c in parse_option_param.", *fmt); skip_to_semi(cfile); return (-1); } } token = next_token(&val, cfile); } while (*fmt == 'A' && token == ','); if (token != ';') { parse_warn("semicolon expected."); skip_to_semi(cfile); return (-1); } options[code].data = malloc(hunkix + nul_term); if (!options[code].data) error("out of memory allocating option data."); memcpy(options[code].data, hunkbuf, hunkix + nul_term); options[code].len = hunkix; return (code); }
static ftnPtr parse_ftn(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, struct mpls_switch *sw) { ftnPtr ret = NULL; nhlfePtr nhlfe_entry; xmlChar *str; uint32_t ip_wildcards; struct ofp_match match; // in network byte order // initialize match memset(&match, 0, sizeof(struct ofp_match)); match.mpls_label1 = htonl(MPLS_INVALID_LABEL); match.mpls_label2 = htonl(MPLS_INVALID_LABEL); // wildcard everything by default match.wildcards = htonl((OFPFW_ALL) ^ ((OFPFW_MPLS_L1) | (OFPFW_MPLS_L2))); // allocate the struct ret = (ftnPtr) malloc(sizeof(ftn)); if (ret == NULL) { fprintf(stderr,"out of memory\n"); return(NULL); } memset(ret, 0, sizeof(ftn)); /* We don't care what the top level element name is */ cur = cur->xmlChildrenNode; while (cur != NULL) { str = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (!xmlStrcmp(cur->name, (const xmlChar *) "dl_type")) { ret->FEC.dl_type = (uint16_t)atoi((char *)str); match.dl_type = htons(ret->FEC.dl_type); match.wildcards = match.wildcards ^ htonl(OFPFW_DL_TYPE); } else if (!xmlStrcmp(cur->name, (const xmlChar *) "dl_vlan")) { ret->FEC.dl_vlan = (uint16_t)atoi((char *)str); match.dl_vlan = htons(ret->FEC.dl_vlan); match.wildcards = match.wildcards ^ htonl(OFPFW_DL_VLAN); } else if (!xmlStrcmp(cur->name, (const xmlChar *) "in_port")) { ret->FEC.in_port = (uint16_t)atoi((char *)str); match.in_port = htons(ret->FEC.in_port); match.wildcards = match.wildcards ^ htonl(OFPFW_IN_PORT); } else if (!xmlStrcmp(cur->name, (const xmlChar *) "dl_src")) { eth_atoi((char *)str, ret->FEC.dl_src); // already in network byte order memcpy(&match.dl_src, &ret->FEC.dl_src, ETH_ADDR_LEN); match.wildcards = match.wildcards ^ htonl(OFPFW_DL_SRC); } else if (!xmlStrcmp(cur->name, (const xmlChar *) "dl_dst")) { eth_atoi((char *)str, ret->FEC.dl_dst); // already in network byte order memcpy(&match.dl_dst, &ret->FEC.dl_dst, ETH_ADDR_LEN); match.wildcards = match.wildcards ^ htonl(OFPFW_DL_DST); } else if (!xmlStrcmp(cur->name, (const xmlChar *) "nw_src")) { ret->FEC.nw_src = ntohl(parse_ip_addr((char *)str, &ip_wildcards)); match.nw_src = htonl(ret->FEC.nw_src); match.wildcards = (match.wildcards ^ ntohl(OFPFW_NW_SRC_MASK)) | ip_wildcards; } else if (!xmlStrcmp(cur->name, (const xmlChar *) "nw_dst")) { ret->FEC.nw_dst = ntohl(parse_ip_addr((char *)str, &ip_wildcards)); match.nw_dst = htonl(ret->FEC.nw_dst); match.wildcards = (match.wildcards ^ ntohl(OFPFW_NW_DST_MASK)) | ip_wildcards; } else if (!xmlStrcmp(cur->name, (const xmlChar *) "nw_proto")) { ret->FEC.nw_proto = (uint16_t)atoi((char *)str); match.nw_proto = ret->FEC.nw_proto; match.wildcards = match.wildcards ^ htonl(OFPFW_NW_PROTO); } else if (!xmlStrcmp(cur->name, (const xmlChar *) "tp_src")) { ret->FEC.tp_src = (uint16_t)atoi((char *)str); match.tp_src = htons(ret->FEC.tp_src); match.wildcards = match.wildcards ^ htonl(OFPFW_TP_SRC); } else if (!xmlStrcmp(cur->name, (const xmlChar *) "tp_dst")) { ret->FEC.tp_dst = (uint16_t)atoi((char *)str); match.tp_dst = htons(ret->FEC.tp_dst); match.wildcards = match.wildcards ^ htonl(OFPFW_TP_DST); } // XXX parse_nhlfe must be called last otherwise the match struct // will be incomplete // Note: assumes only one NHFLE per entry else if ((!xmlStrcmp(cur->name, (const xmlChar *) "NHLFE"))) { nhlfe_entry = parse_nhlfe(doc, ns, cur, sw, &match); if (nhlfe_entry) { // printf("parse_ftn: got an nhlfe_entry! actions_len = %u\n", nhlfe_entry->actions_len); nhlfe_entry->next_entry = NULL; ret->nhlfe = nhlfe_entry; } } // XXX FEC stores all but the wildcards in host byte order // wildcards bitmap is in network byte order ret->FEC.wildcards = match.wildcards; free(str); cur = cur->next; } return(ret); }
static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) { int res = -1; int argc = *argc_p; char **argv = *argv_p; if (argc < 2) return -1; if (strcmp(*argv, "src") == 0) { NEXT_ARG(); res = parse_ip_addr(&argc, &argv, sel, 12); goto done; } if (strcmp(*argv, "dst") == 0) { NEXT_ARG(); res = parse_ip_addr(&argc, &argv, sel, 16); goto done; } //------------->richie: add to parse ip range if (strcmp(*argv, "ssrc") == 0) { //fprintf(stderr, "enter ssrc\n"); NEXT_ARG(); res = nk_parse_ip_addr(&argc, &argv, sel, 12, TC_SSRC_IP); goto done; } if (strcmp(*argv, "esrc") == 0) { //fprintf(stderr, "enter esrc\n"); NEXT_ARG(); res = nk_parse_ip_addr(&argc, &argv, sel, 12, TC_ESRC_IP); goto done; } if (strcmp(*argv, "sdst") == 0) { //fprintf(stderr, "enter sdst\n"); NEXT_ARG(); res = nk_parse_ip_addr(&argc, &argv, sel, 16, TC_SDST_IP); goto done; } if (strcmp(*argv, "edst") == 0) { //fprintf(stderr, "enter edst\n"); NEXT_ARG(); res = nk_parse_ip_addr(&argc, &argv, sel, 16, TC_EDST_IP); goto done; } //<-------------------- if (strcmp(*argv, "tos") == 0 || matches(*argv, "dsfield") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 1, 0); goto done; } if (strcmp(*argv, "ihl") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 0, 0); goto done; } if (strcmp(*argv, "protocol") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 9, 0); goto done; } if (matches(*argv, "precedence") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 1, 0); goto done; } if (strcmp(*argv, "nofrag") == 0) { argc--; argv++; res = pack_key16(sel, 0, 0x3FFF, 6, 0); goto done; } if (strcmp(*argv, "firstfrag") == 0) { argc--; argv++; res = pack_key16(sel, 0, 0x1FFF, 6, 0); goto done; } if (strcmp(*argv, "df") == 0) { argc--; argv++; res = pack_key16(sel, 0x4000, 0x4000, 6, 0); goto done; } if (strcmp(*argv, "mf") == 0) { argc--; argv++; res = pack_key16(sel, 0x2000, 0x2000, 6, 0); goto done; } if (strcmp(*argv, "dport") == 0) { NEXT_ARG(); res = parse_u16(&argc, &argv, sel, 22, 0); goto done; } if (strcmp(*argv, "sport") == 0) { NEXT_ARG(); res = parse_u16(&argc, &argv, sel, 20, 0); goto done; } // 2004/05/12 Ryan : added to support QoS for port range setting // --> if (strcmp(*argv, "ssport") == 0) { NEXT_ARG(); //printf("enter ssport\n"); //fprintf(stderr, "enter ssport!!!!!!!!!!!\n"); res = nk_parse_u16(&argc, &argv, sel, 20, 0 , TC_SSRC_PORT); goto done; } if (strcmp(*argv, "esport") == 0) { NEXT_ARG(); //printf("enter esport\n"); //fprintf(stderr, "enter esport!!!!!!!!!!!\n"); res = nk_parse_u16(&argc, &argv, sel, 20, 0 , TC_ESRC_PORT); goto done; } if (strcmp(*argv, "sdport") == 0) { NEXT_ARG(); //printf("enter sdport\n"); //fprintf(stderr, "enter sdport!!!!!!!!!!!\n"); res = nk_parse_u16(&argc, &argv, sel, 22, 0 , TC_SDST_PORT); goto done; } if (strcmp(*argv, "edport") == 0) { NEXT_ARG(); //printf("enter edport\n"); //fprintf(stderr, "enter edport!!!!!!!!!!!\n"); res = nk_parse_u16(&argc, &argv, sel, 22, 0 , TC_EDST_PORT); goto done; } // <-- //2004/09/29 richie: add to support inbound QoS by interface if (strcmp(*argv, "wanif") == 0) { NEXT_ARG(); //printf("enter wanif!!!!!!!!!!!!!!!!!!!!!!!!!!11"); res = nk_parse_u16(&argc, &argv, sel, 100, 0 , TC_WANIF); goto done; } // //2004/09/29 richie: add to support inbound QoS by ALG type if (strcmp(*argv, "ap_type") == 0) { NEXT_ARG(); //printf("enter ap_type!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); res = nk_parse_u16(&argc, &argv, sel, 120, 0 , TC_AP_TYPE); goto done; } // if (strcmp(*argv, "icmp_type") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 20, 0); goto done; } if (strcmp(*argv, "icmp_code") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 20, 1); goto done; } return -1; done: *argc_p = argc; *argv_p = argv; return res; }
struct option * parse_option_decl(FILE *cfile, struct option_data *options) { char *val; int token; u_int8_t buf[4]; u_int8_t hunkbuf[1024]; int hunkix = 0; char *vendor; char *fmt; struct universe *universe; struct option *option; struct iaddr ip_addr; u_int8_t *dp; int len; int nul_term = 0; token = next_token(&val, cfile); if (!is_identifier(token)) { parse_warn("expecting identifier after option keyword."); if (token != SEMI) skip_to_semi(cfile); return (NULL); } if ((vendor = strdup(val)) == NULL) error("no memory for vendor information."); token = peek_token(&val, cfile); if (token == DOT) { /* Go ahead and take the DOT token... */ token = next_token(&val, cfile); /* The next token should be an identifier... */ token = next_token(&val, cfile); if (!is_identifier(token)) { parse_warn("expecting identifier after '.'"); if (token != SEMI) skip_to_semi(cfile); return (NULL); } /* Look up the option name hash table for the specified vendor. */ universe = ((struct universe *)hash_lookup(&universe_hash, (unsigned char *)vendor, 0)); /* If it's not there, we can't parse the rest of the declaration. */ if (!universe) { parse_warn("no vendor named %s.", vendor); skip_to_semi(cfile); return (NULL); } } else { /* Use the default hash table, which contains all the standard dhcp option names. */ val = vendor; universe = &dhcp_universe; } /* Look up the actual option info... */ option = (struct option *)hash_lookup(universe->hash, (unsigned char *)val, 0); /* If we didn't get an option structure, it's an undefined option. */ if (!option) { if (val == vendor) parse_warn("no option named %s", val); else parse_warn("no option named %s for vendor %s", val, vendor); skip_to_semi(cfile); return (NULL); } /* Free the initial identifier token. */ free(vendor); /* Parse the option data... */ do { for (fmt = option->format; *fmt; fmt++) { if (*fmt == 'A') break; switch (*fmt) { case 'X': len = parse_X(cfile, &hunkbuf[hunkix], sizeof(hunkbuf) - hunkix); hunkix += len; break; case 't': /* Text string... */ token = next_token(&val, cfile); if (token != STRING) { parse_warn("expecting string."); skip_to_semi(cfile); return (NULL); } len = strlen(val); if (hunkix + len + 1 > sizeof(hunkbuf)) { parse_warn("option data buffer %s", "overflow"); skip_to_semi(cfile); return (NULL); } memcpy(&hunkbuf[hunkix], val, len + 1); nul_term = 1; hunkix += len; break; case 'I': /* IP address. */ if (!parse_ip_addr(cfile, &ip_addr)) return (NULL); len = ip_addr.len; dp = ip_addr.iabuf; alloc: if (hunkix + len > sizeof(hunkbuf)) { parse_warn("option data buffer " "overflow"); skip_to_semi(cfile); return (NULL); } memcpy(&hunkbuf[hunkix], dp, len); hunkix += len; break; case 'L': /* Unsigned 32-bit integer... */ case 'l': /* Signed 32-bit integer... */ token = next_token(&val, cfile); if (token != NUMBER) { need_number: parse_warn("expecting number."); if (token != SEMI) skip_to_semi(cfile); return (NULL); } convert_num(buf, val, 0, 32); len = 4; dp = buf; goto alloc; case 's': /* Signed 16-bit integer. */ case 'S': /* Unsigned 16-bit integer. */ token = next_token(&val, cfile); if (token != NUMBER) goto need_number; convert_num(buf, val, 0, 16); len = 2; dp = buf; goto alloc; case 'b': /* Signed 8-bit integer. */ case 'B': /* Unsigned 8-bit integer. */ token = next_token(&val, cfile); if (token != NUMBER) goto need_number; convert_num(buf, val, 0, 8); len = 1; dp = buf; goto alloc; case 'f': /* Boolean flag. */ token = next_token(&val, cfile); if (!is_identifier(token)) { parse_warn("expecting identifier."); bad_flag: if (token != SEMI) skip_to_semi(cfile); return (NULL); } if (!strcasecmp(val, "true") || !strcasecmp(val, "on")) buf[0] = 1; else if (!strcasecmp(val, "false") || !strcasecmp(val, "off")) buf[0] = 0; else { parse_warn("expecting boolean."); goto bad_flag; } len = 1; dp = buf; goto alloc; default: warning("Bad format %c in parse_option_param.", *fmt); skip_to_semi(cfile); return (NULL); } } token = next_token(&val, cfile); } while (*fmt == 'A' && token == COMMA); if (token != SEMI) { parse_warn("semicolon expected."); skip_to_semi(cfile); return (NULL); } options[option->code].data = malloc(hunkix + nul_term); if (!options[option->code].data) error("out of memory allocating option data."); memcpy(options[option->code].data, hunkbuf, hunkix + nul_term); options[option->code].len = hunkix; return (option); }