static struct AstNode *parse_special( struct DomNode *dom, struct ParserState *state) { struct AstNode *result; if ((!err_state() && (result = parse_do_block(dom, state))) || (!err_state() && (result = parse_match(dom, state))) || (!err_state() && (result = parse_if(dom, state))) || (!err_state() && (result = parse_while(dom, state))) || (!err_state() && (result = parse_func_def(dom, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_AND, ast_make_spec_bool_and, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_OR, ast_make_spec_bool_or, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_SET_OF, ast_make_spec_set_of, state))) || (!err_state() && (result = parse_binary(dom, DOM_RES_RANGE_OF, ast_make_spec_range_of, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_ARRAY_OF, ast_make_spec_array_of, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_TUPLE_OF, ast_make_spec_tuple_of, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_POINTER_TO, ast_make_spec_pointer_to, state))) || (!err_state() && (result = parse_min_nary(dom, 1, DOM_RES_FUNCTION, ast_make_spec_function_type, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_TYPE_PRODUCT, ast_make_spec_type_product, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_TYPE_UNION, ast_make_spec_type_union, state))) || (!err_state() && (result = parse_bind(dom, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_PTR, ast_make_spec_ptr, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_PEEK, ast_make_spec_peek, state))) || (!err_state() && (result = parse_binary(dom, DOM_RES_POKE, ast_make_spec_poke, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_BEGIN, ast_make_spec_begin, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_END, ast_make_spec_end, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_INC, ast_make_spec_inc, state))) || (!err_state() && (result = parse_unary(dom, DOM_RES_SUCC, ast_make_spec_succ, state)))) { return result; } else { return NULL; } }
/* This is quite horrible, but it does seem to work... We make a shallow copy of config, and then recall read_config. config will now be changed with any additional options in the subsection - we copy it where we want it, and restore config. The copy is only a shallow one, but we get away with it as other funcs overwrite pointers not their contents. */ int store_subsect(sstr * str, struct subsect_list *subsecs) { struct options tmp; struct subsect item; parse_match(str, &item.match); memcpy(&tmp, &config, sizeof(struct options)); sublevel++; config.acls.list = NULL; config.subsecs.list = NULL; config.acls.num = config.subsecs.num = 0; if (read_config() == -1) return (-1); sublevel--; if(process_opts()==-1) return(-1); memcpy(&item.config, &config, sizeof(struct options)); memcpy(&config, &tmp, sizeof(struct options)); subsecs->list = realloc(subsecs->list, (subsecs->num + 1) * sizeof(struct subsect)); memcpy(subsecs->list + subsecs->num, &item, sizeof(struct subsect)); subsecs->num++; return (0); }
int store_acl(sstr * str, struct acl_list *acls) { sstr *tok; struct acl_item item; tok = sstr_init(0); sstr_token(str, tok, " \t\n", 0); if (!sstr_casecmp2(tok, "Allow")) item.action = ALLOW; else if (!sstr_casecmp2(tok, "Deny")) item.action = DENY; else return (-1); sstr_free(tok); parse_match(str, &item); acls->list = realloc(acls->list, (acls->num + 1) * sizeof(struct acl_item)); if(!acls->list) return(-1); memcpy(acls->list + acls->num, &item, sizeof(struct acl_item)); acls->num++; return (0); }
int parse_match(char *str, char *pattern) { int i; int j; i = 0; j = 0; while (str[i] != 0 && pattern[j] != 0) { if (pattern[j] == 'a' && (str[i] > 122 || str[i] < 97)) return (0); else if (pattern[j] == 'A' && (str[i] > 90 || str[i] < 65)) return (0); else if (pattern[j] == 'i' && (str[i] > 57 || str[i] < 48)) return (0); else if (pattern[j] == '.' && !is_punctuation(pattern[i])) return (0); else if (pattern[j] == '*' && !parse_match(str + i, pattern + j + 1)) ++i; else if (pattern[j] != 'a' && pattern[j] != 'A' && pattern[j] != 'i' && pattern[j] != '.' && pattern[j] != '*') return (0); else { ++i; ++j; } } return (pattern[j] == 0 ? 1 : 0); }
/* * Returns the next entry of the list after * each separator */ char * parse(char **line, char *seps) { char *start = *line; while (**line != 0) { *line = *line + 1; if (parse_match(**line, seps)) { /* hit a terminator, skip trailing terminators */ while (parse_match(**line, seps)) { **line = 0; *line = *line + 1; } break; } } return (start); }
static char * parse_dump_flows( char *cmd, const uint64_t own_datapath_id ) { if ( prefixcmp( cmd, "dump_flows" ) ) { return NULL; } char *opt = strchr ( cmd, ' ' ); assert( opt ); uint64_t datapath_val; uint32_t in_port_val; uint16_t eth_type_val; uint8_t ip_proto_val; uint64_t metadata_val[ 2 ]; uint16_t udp_src_val; uint16_t udp_dst_val; uint8_t table_id_val; uint32_t out_port_val; uint32_t out_group_val; uint64_t cookie_val[ 2 ]; struct option opts[] = { OPT_UINT64( "--datapath_id", "datapath_id:", OPT_NO_MASK, &datapath_val ), OPT_UINT32( "--in_port", "in_port:", OPT_NO_MASK, &in_port_val ), OPT_UINT16( "--eth_type", "eth_type:", OPT_NO_MASK, ð_type_val ), OPT_UINT8( "--ip_proto", "ip_proto:", OPT_NO_MASK, &ip_proto_val ), OPT_UINT64( "--metadata", "metadata:", OPT_HAS_MASK, &metadata_val ), OPT_UINT16( "--udp_src", "udp_src:", OPT_NO_MASK, &udp_src_val ), OPT_UINT16( "--udp_dst", "udp_dst:", OPT_NO_MASK, &udp_dst_val ), OPT_UINT8( "--table_id", "table_id:", OPT_NO_MASK, &table_id_val ), OPT_UINT64( "--cookie", "cookie:", OPT_HAS_MASK, &cookie_val ), OPT_UINT32( "--out_port", "out_port:", OPT_NO_MASK, &out_port_val ), OPT_UINT32( "--out_group", "out_group:", OPT_NO_MASK, &out_group_val ), OPT_END() }; char *saveptr; const char *sep = " "; for ( opt = strtok_r( opt, sep, &saveptr ); opt; opt = strtok_r( NULL, sep, &saveptr ) ) { parse_option( opt, opts ); if ( *( uint64_t * ) opts[ 0 ].value != own_datapath_id ) { return NULL; } } match *match = create_match(); parse_match( match, opts ); flow_stats *stats = NULL; uint32_t nr_stats; OFDPE ret = get_flow_stats( ( uint8_t ) table_id_val, match, cookie_val[ 0 ], cookie_val[ 1 ], out_port_val, out_group_val, &stats, &nr_stats ); if ( ret != OFDPE_SUCCESS ) { error( "Failed to retrieve flow stats from datapath ( ret = %d ).", ret ); } delete_match( match ); char *reply_buf = xmalloc( PATH_MAX + 1 ); reply_buf[ 0 ] = '\0'; size_t used = 0; int left; const char *term = ","; const char *orig = "{ \"dump_flows\": ["; if ( stats != NULL && nr_stats ) { for ( uint32_t i = 0; i < nr_stats; i++ ) { if ( i != 0 ) { orig = ""; } if ( i == nr_stats - 1 ) { term = "]}"; } left = snprintf( reply_buf + used, PATH_MAX - used, "%s {" DUMP_FLOW_FIELDS "} %s", orig, stats->table_id, stats->duration_sec, stats->priority, stats->idle_timeout, stats->hard_timeout, stats->flags, stats->cookie, stats->packet_count, stats->byte_count, term ); used = ( size_t ) left - used; stats++; } } return reply_buf; }
static int process_file(char *fname,struct contig *ctg,int block_size,int fmt,u_int64_t *number,struct lk_compress *lkc) { int i,k,err,sz,nn; FILE *fptr; string *s; tokens *tok; void *tbuf; char *p,*p1; struct match m; struct contig *c; count *ct; u_int32_t x,x1; s=0; tok=0; tbuf=0; err=0; nn=(fmt==GEM_FMT?1:0); fptr=open_readfile(fname,&i,lkc); if(!fptr) return -1; printf("Reading matches file '%s'\n",fname); while(!err) { s=fget_string(fptr,s,&tbuf); if(!s->len) break; tok=tokenize(get_cstring(s),'\t',tok); if(tok->n_tok>=4+nn) { p=tok->toks[2+nn]; i=0; if(!isdigit(*p)) continue; while(*p && !err) { k=(int)strtol(p,&p1,10); i+=k; if(i>1) break; if(*p1) { if(*p1!=':' && *p1!='+') err=5; else p1++; } p=p1; if(!k && i) break; } if(err) { fprintf(stderr,"Bad format for match number column '%s'\n",tok->toks[3]); err=0; continue; } else if(i==1) { p=parse_match(tok->toks[3+nn],fmt,&m); if(!p) { /* err=10;*/ fprintf(stderr,"Bad format for match\n"); continue; } else { if(*number) { (*number)--; if(!(*number)) { err=1; break; } } HASH_FIND_STR(ctg,m.ctg,c); if(c) { sz=strlen(tok->toks[1]); ct=c->counts; x=m.pos-1; if(block_size>1) { if(m.orientation) { for(i=0; i<sz; i++) { if(x<c->size) { x1=x/block_size; x1*=block_size; if(ct[x1]<MAX_COUNT) ct[x1]++; } if(!x) break; x--; } } else { for(i=0; i<sz && x<c->size; i++) { x1=x/block_size; x1*=block_size; if(ct[x1]<MAX_COUNT) ct[x1]++; x++; } } } else { if(m.orientation) { for(i=0; i<sz; i++) { if(x<c->size) { if(ct[x]<MAX_COUNT) ct[x]++; } if(!x) break; x--; } } else { for(i=0; i<sz && x<c->size; i++) { if(ct[x]<MAX_COUNT) ct[x]++; x++; } } } if((ct=c->tcounts)) { x=m.pos-1; if(block_size>1) { if(m.orientation) { for(i=0; i<sz; i++) { if(x<c->tsize) { x1=x/block_size; x1*=block_size; if(ct[x1]<MAX_COUNT) ct[x1]++; } if(!x) break; x--; } } else { for(i=0; i<sz && x<c->tsize; i++) { x1=x/block_size; x1*=block_size; if(ct[x1]<MAX_COUNT) ct[x1]++; x++; } } } else { if(m.orientation) { for(i=0; i<sz; i++) { if(x<c->tsize) { if(ct[x]<MAX_COUNT) ct[x]++; } if(!x) break; x--; } } else { for(i=0; i<sz && x<c->tsize; i++) { if(ct[x]<MAX_COUNT) ct[x]++; x++; } } } } } } } } } fclose(fptr); if(s) free_string(s); if(tok) free_tokens(tok); if(tbuf) free_fget_buffer(&tbuf); signal(SIGCHLD,SIG_DFL); while(waitpid(-1,&i,WNOHANG)>0); return err; }
static bool parse_line_v1 (RuleSet* rs, const char* line) { if (0 == strcmp (line, "forward-unmatched")) { rs->forward_unmatched = true; return true; } if (0 == strcmp (line, "match-all")) { rs->match_all = true; return true; } Rule r; clear_rule (&r); char *tmp, *fre, *prt; int i = 0; bool in_match = true; tmp = fre = strdup (line); for (prt = strtok (tmp, " "); prt; prt = strtok (NULL, " "), ++i) { bool rv; if (prt[0] == '#') { break; } if (0 == strcmp (prt, "|")) { if (i == 0 || !in_match) { i = -1; break; } in_match = false; r.len = i; i = -1; // continue bumps it continue; } if (i >= MAX_MSG) { i = -1; break; } if (in_match) { switch (i) { case 0: rv = parse_status (&r, prt); break; case 1: r.match[i] = parse_note (prt); // TODO IFF note-status.. if (r.match[i] < 128) { r.mask[i] = 0x7f; rv = true; break; } // no break - fall through default: rv = parse_match (&r, i, prt); break; } } else { switch (i) { case 1: r.tx_set[i] = parse_note (prt); // TODO IFF note-status.. if (r.tx_set[i] < 128) { r.tx_mask[i] = 0x00; rv = true; break; } // no break - fall through default: rv = parse_replacement (&r, i, prt); break; } } if (!rv) { i = -1; break; } } r.tx_len = i; free (fre); if (r.tx_len < 1 || r.tx_len > MAX_MSG || r.len < 1 || r.len > MAX_MSG || in_match) { return false; } add_rule (rs, &r); return true; }