Пример #1
0
struct t_value * exec_i_assign(struct t_exec *exec, struct t_icode *icode)
{
  struct t_var *var;
  struct t_value *ret = NULL;
  struct t_value *opnd1, *opnd2;
  
  debug(2, "%s(): Begin\n", __FUNCTION__);
  
  opnd2 = list_pop(&exec->stack);
  assert(opnd2);
  opnd1 = list_pop(&exec->stack);
  assert(opnd1);
  
  debug(3, "%s(): Got operands from stack\n", __FUNCTION__);

  if (opnd2->type == VAL_VAR) {
    debug(3, "%s(): Fetching value for opnd2\n", __FUNCTION__);
    var = var_lookup(exec, opnd2->name);
    opnd2 = var->value;
    assert(opnd2);
  }

  if (opnd1->type != VAL_VAR) {
    fprintf(stderr, "Left side of assignment must be a variable. Got %s=%d instead.\n", value_types[opnd1->type], opnd1->intval);
    return NULL;
  }
  debug(3, "%s(): Looking up opnd1 var name=%s\n", __FUNCTION__, opnd1->name);
  var = var_lookup(exec, opnd1->name);
  if (var) {
    if (var->value->type != opnd2->type) {
      fprintf(stderr, "Type mismatch when assigning new value: %s = %s\n", opnd1->name, value_types[opnd2->type]);
      return NULL;
    }
  }
  else {
    var = var_new(opnd1->name, opnd2);
    list_push(&exec->vars, var);
  }
  debug(3, "%s(): Copying value to variable\n", __FUNCTION__);

  if (var->value->type == VAL_INT) {
    var->value->intval = opnd2->intval;
    ret = create_num_from_int(var->value->intval);
    list_push(&exec->values, ret);
    debug(3, "%s(): New int val: %d\n", __FUNCTION__, ret->intval);
  }
  else if (var->value->type == VAL_STRING) {
    var->value->stringval = opnd2->stringval;
    ret = var->value;
    debug(3, "%s(): Assigned string: %s\n", __FUNCTION__, ret->stringval);
  }
  else {
    fprintf(stderr, "Don't know how to assign %s type value\n", value_types[opnd2->type]);
    return NULL;
  }
  
  list_push(&exec->stack, ret);

  return ret;
}
Пример #2
0
var_t *var_add(var_table_t *hashtable, char *str, BYTE type, block_t *parent)
{
    var_t *new_list;
    var_t *current_list;
    unsigned int hashval = var_hash(hashtable, str);

    if ((new_list = malloc(sizeof(var_t))) == NULL) return NULL;

    current_list = var_lookup(hashtable, str);

    /* item already exists, dont insert it again. */
    if (current_list != NULL) return current_list; // NULL;

    /* Insert into list */
    new_list->v.data = NULL;
    new_list->v.data_size = 0;
    new_list->v.name = strdup(str);
    new_list->v.type = type;
    // TODO: figure out shit with level
    new_list->v.level = 0;
    new_list->parent = parent;
    new_list->next = hashtable->table[hashval];
    hashtable->table[hashval] = new_list;

    return new_list;
}
Пример #3
0
inline struct var *
var_lookup(struct var *tree, char *key) {
    if (!tree)
	return NULL;
    if (strcmp(tree->name, key) == 0)
	return tree;
    return var_lookup((strcmp(tree->name, key) > 0) ? tree->left : tree->
		      right, key);
}
Пример #4
0
int
var_fetch_int(char *var_name) {
    struct var *v = var_lookup(vars, var_name);

    if ( v == NULL ) return 0;

    switch ( v->type ) {
    case    int_t: return v->value.i;
    case string_t: return 0;
    case       mu: return 0;
    }

    return 0;
}
Пример #5
0
/*
    Synchronizes var with vars[] if necessary
    Var is NOT modified
*/
void var_sync(bombyx_env_t *env, var *a)
{
    if (a->ref)
    {
        op_copy(env, &(a->ref)->v, a);
    }
    else if (a->name)
    {
        var_t *vt = var_lookup(env->vars, a->name);
        if (vt)
        {
            op_copy(env, &vt->v, a);
        }
        else
        {
            runtime_error(env, "Variable '%s' not found.", a->name);
        }
    }
}
Пример #6
0
/* retrieve a variable's contents, and make a string if need be */
char *
var_fetch(char *var_name) {
    struct var *v = var_lookup(vars, var_name);
    if (v) {
	char *foo;
	switch (v->type) {
        case mu:
            fprintf( stderr, "var_fetch: unhandled var type\n" );
            exit( -1 );
	case string_t:
	    return v->value.s;
	case int_t:
	    foo = (char *) malloc(16);
	    sprintf(foo, "%i", v->value.i);
	    return foo;
	}
    }

    return NULL;
}
Пример #7
0
static int parse_single_var(char *val, size_t len, const char *name)
{
	struct var *match;

	match = var_lookup(name);
	if (match) {
		if (strlen(match->val) + 1 > len) {
			set_errf("Variables '%s' with value '%s' is too long\n",
				 match->name, match->val);
			return -1;
		}
		strncpy(val, match->val, len);
		return 0;
	}
	else {
		/* name + 1 to skip leading '$' */
		if (lua_to_string(prox_lua(), GLOBAL, name + 1, val, len) >= 0)
			return 0;
	}

	set_errf("Variable '%s' not defined!", name);
	return 1;
}
Пример #8
0
type_t
var_type(struct var * tree, char *key) {
    struct var *v = var_lookup(tree, key);
    return v ? v->type : mu;
}
Пример #9
0
struct t_value * exec_icode(struct t_exec *exec, struct t_icode *icode)
{
  struct t_value *ret;
  struct t_value *opnd1, *opnd2;
  struct t_value *val1, *val2;
  struct t_icode_op op;
  struct t_var *var;

  debug(1, "%s(): Executing icode addr=%d: %s\n", __FUNCTION__, icode->addr, format_icode(&exec->parser, icode));

  if (icode->type < 0 || icode->type >= operations_len) {
    fprintf(stderr, "Invalid operation type (value=%d)\n", icode->type);
    return NULL;
  }

  op = operations[icode->type];

  if (op.opnd_count == 0) {
    ret = op.op0(exec, icode);
  }
  else if (op.opnd_count == 1) {
    opnd1 = list_pop(&exec->stack);
    assert(opnd1);
    if (opnd1->type == VAL_VAR) {
      var = var_lookup(exec, opnd1->name);
      val1 = var->value;
      assert(opnd1);
    }
    else {
      val1 = opnd1;
    }

    ret = op.op1(exec, icode, val1);
    list_push(&exec->stack, ret);
  }
  else if (op.opnd_count == 2) {
    opnd2 = list_pop(&exec->stack);
    assert(opnd2);
    opnd1 = list_pop(&exec->stack);
    assert(opnd1);

    if (opnd1->type == VAL_VAR) {
      var = var_lookup(exec, opnd1->name);
      val1 = var->value;
      assert(val1);
    }
    else {
      val1 = opnd1;
    }

    if (opnd2->type == VAL_VAR) {
      var = var_lookup(exec, opnd2->name);
      val2 = var->value;
      assert(val2);
    }
    else {
      val2 = opnd2;
    }

    ret = op.op2(exec, icode, val1, val2);
    list_push(&exec->stack, ret);
  }
  else {
    fprintf(stderr, "Invalid number of operations (%d) for op '%s'\n", op.opnd_count, icodes[icode->type]);
    return NULL;
  }
  
  return ret;
}
Пример #10
0
static char *
exec_instr( pInstr s ) {
    pCell tc, tc2;
    char buffer[16];

    switch (s->opcode) {
    case SET:
	/* operand must be a string */
	tc = temp_pop();
	switch (tc->type) {
	case mu:
            fprintf(stderr, "exec_inst/SET: warning - unhandled case mu\n" );
            break;
	case string_t:
	    var_put(s->operand.contents.s, tc->contents.s);
	    break;
	case int_t:
	    var_put_int(s->operand.contents.s, tc->contents.i);
	    break;
	}
	break;
    case EMIT:
	tc = temp_pop();
	switch (tc->type) {
	case mu:
            fprintf(stderr, "exec_inst/EMIT: warning - unhandled case mu\n" );
            break;
	case string_t:
	    return tc->contents.s;
	case int_t:
	    sprintf(buffer, "%i", tc->contents.i);
	    return strdup(buffer);
	}
    case PUSHV:
	{
	    struct var *v = var_lookup(vars, s->operand.contents.s);
	    if (v == 0) {
		fprintf(stderr,
			"attempted to use unknown variable \"%s\" in expression.\n",
			s->operand.contents.s);
		push_str("(NULL)");
	    } else {
		switch (v->type) {
	        case mu:
                    fprintf(stderr, "exec_inst/PUSHV: warning - unhandled case mu\n" );
                    break;
		case string_t:
		    push_str(strdup(v->value.s));
		    break;
		case int_t:
		    push_int(v->value.i);
		    break;
		}
	    }
	}
	break;
    case INVOKE:
	{
	    pRule r = rule_find(rule_base, s->operand.contents.s);
	    if (r) {
		push_str(resolve_rule(rule_base, r));
	    } else {
		fprintf(stderr,
			"attempted to invoke non-existent rule \"%s\" in expression.\n",
			s->operand.contents.s);
		push_str(NULL);
	    }
	}
	break;
    case PUSH:
	switch (s->operand.type) {
	case mu:
            fprintf(stderr, "exec_inst/PUSH: warning - unhandled case mu\n" );
            break;
	case string_t:
	    push_str(strdup(s->operand.contents.s));
	    break;
	case int_t:
	    push_int(s->operand.contents.i);
	    break;
	}
	break;
    case ADD:
	tc = temp_pop();
	tc2 = temp_pop();
	if ((tc->type == int_t) && (tc2->type == int_t)) {
	    push_int(tc->contents.i + tc2->contents.i);
	} else {
	    char *s0, *s1;
	    /* string concatenation */
	    s0 = ((tc->type ==
		   int_t) ? itoa(tc->contents.i) : (tc->contents.s));
	    s1 = ((tc2->type ==
		   int_t) ? itoa(tc2->contents.i) : (tc2->contents.s));
	    push_str(concat(s1, s0));
	    free(s0);
	    free(s1);
	}
	break;
    case SUB:
	tc = temp_pop();
	tc2 = temp_pop();
	if ((tc->type == int_t) && (tc2->type == int_t)) {
	    push_int(tc2->contents.i + tc->contents.i);
	}
	break;
    case MUL:
	tc = temp_pop();
	tc2 = temp_pop();
	if ((tc->type == int_t) && (tc2->type == int_t)) {
	    push_int(tc->contents.i * tc2->contents.i);
	}
	break;
    case DIV:
	tc = temp_pop();
	tc2 = temp_pop();
	if ((tc->type == int_t) && (tc2->type == int_t)) {
	    push_int(tc2->contents.i / tc->contents.i);
	}
	break;
    case MOD:
	tc = temp_pop();
	tc2 = temp_pop();
	if ((tc->type == int_t) && (tc2->type == int_t)) {
	    push_int(tc2->contents.i % tc->contents.i);
	}
	break;
    case RANDOM:
	tc2 = temp_pop();
	tc = temp_pop();
	if ((tc->type == int_t) && (tc2->type == int_t)) {
	    push_int((ranq1() % (tc2->contents.i - tc->contents.i + 1))
		     + tc->contents.i);
	}
	break;
    case LESSER:
	tc2 = temp_pop();
	tc = temp_pop();
	if ((tc->type == int_t) && (tc2->type == int_t)) {
	    push_int(min(tc->contents.i, tc2->contents.i));
	}
	break;
    case GREATER:
	tc2 = temp_pop();
	tc = temp_pop();
	if ((tc->type == int_t) && (tc2->type == int_t)) {
	    push_int(max(tc->contents.i, tc2->contents.i));
	}
	break;
    }
    return NULL;
}
Пример #11
0
void StreamVm::build_program(){

    /* build the commands into a buffer */
    m_instructions.clear();
    int var_cnt=0;
    clean_max_field_cnt();
    uint32_t ins_id=0;

    for (auto inst : m_inst_list) {
        StreamVmInstruction::instruction_type_t ins_type=inst->get_instruction_type();

        /* itFIX_IPV4_CS */
        if (ins_type == StreamVmInstruction::itFIX_IPV4_CS) {
            StreamVmInstructionFixChecksumIpv4 *lpFix =(StreamVmInstructionFixChecksumIpv4 *)inst;

            if ( (lpFix->m_pkt_offset + IPV4_HDR_LEN) > m_pkt_size  ) {

                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' fix ipv4 command offset  " << lpFix->m_pkt_offset << "  is too high relative to packet size  "<< m_pkt_size;
                err(ss.str());
            }

            uint16_t offset_next_layer = IPV4_HDR_LEN;

            if ( m_pkt ){
                IPHeader * ipv4= (IPHeader *)(m_pkt+lpFix->m_pkt_offset);
                offset_next_layer = ipv4->getSize();
            }

            if (offset_next_layer<IPV4_HDR_LEN) {
                offset_next_layer=IPV4_HDR_LEN;
            }

            if ( (lpFix->m_pkt_offset + offset_next_layer) > m_pkt_size  ) {

                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' fix ipv4 command offset  " << lpFix->m_pkt_offset << "plus "<<offset_next_layer<< " is too high relative to packet size  "<< m_pkt_size;
                err(ss.str());
            }
            /* calculate this offset from the packet */
            add_field_cnt(lpFix->m_pkt_offset + offset_next_layer);

            StreamDPOpIpv4Fix ipv_fix;
            ipv_fix.m_offset = lpFix->m_pkt_offset;
            ipv_fix.m_op = StreamDPVmInstructions::ditFIX_IPV4_CS;
            m_instructions.add_command(&ipv_fix,sizeof(ipv_fix));
        }


        /* flow man */
        if (ins_type == StreamVmInstruction::itFLOW_MAN) {
            StreamVmInstructionFlowMan *lpMan =(StreamVmInstructionFlowMan *)inst;

            var_cnt++;

            if (lpMan->m_size_bytes == 1 ){
                if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){
                    uint8_t op=StreamDPVmInstructions::ditINC8;

                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
                        op = StreamDPVmInstructions::ditINC8 ;
                    }

                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
                        op = StreamDPVmInstructions::ditDEC8 ;
                    }

                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){
                        op = StreamDPVmInstructions::ditRANDOM8 ;
                    }

                    StreamDPOpFlowVar8 fv8;
                    fv8.m_op = op;
                    fv8.m_flow_offset = get_var_offset(lpMan->m_var_name);
                    fv8.m_min_val     = (uint8_t)lpMan->m_min_value;
                    fv8.m_max_val     = (uint8_t)lpMan->m_max_value;
                    m_instructions.add_command(&fv8,sizeof(fv8));
                }else{
                    uint8_t op=StreamDPVmInstructions::ditINC8_STEP;

                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
                        op = StreamDPVmInstructions::ditINC8_STEP ;
                    }

                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
                        op = StreamDPVmInstructions::ditDEC8_STEP ;
                    }

                    StreamDPOpFlowVar8Step fv8;
                    fv8.m_op = op;
                    fv8.m_flow_offset = get_var_offset(lpMan->m_var_name);
                    fv8.m_min_val     = (uint8_t)lpMan->m_min_value;
                    fv8.m_max_val     = (uint8_t)lpMan->m_max_value;
                    fv8.m_step        = (uint8_t)lpMan->m_step;
                    m_instructions.add_command(&fv8,sizeof(fv8));
                }
            }

            if (lpMan->m_size_bytes == 2 ){
                uint8_t op;
                if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){


                op = StreamDPVmInstructions::ditINC16;

                if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
                    op = StreamDPVmInstructions::ditINC16 ;
                }

                if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
                    op = StreamDPVmInstructions::ditDEC16 ;
                }

                if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){
                    op = StreamDPVmInstructions::ditRANDOM16 ;
                }

                StreamDPOpFlowVar16 fv16;
                fv16.m_op = op;
                fv16.m_flow_offset = get_var_offset(lpMan->m_var_name);
                fv16.m_min_val     = (uint16_t)lpMan->m_min_value;
                fv16.m_max_val     = (uint16_t)lpMan->m_max_value;
                m_instructions.add_command(&fv16,sizeof(fv16));
              }else{

                  op = StreamDPVmInstructions::ditINC16_STEP;

                  if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
                      op = StreamDPVmInstructions::ditINC16_STEP ;
                  }

                  if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
                      op = StreamDPVmInstructions::ditDEC16_STEP ;
                  }

                  StreamDPOpFlowVar16Step fv16;
                  fv16.m_op = op;
                  fv16.m_flow_offset = get_var_offset(lpMan->m_var_name);
                  fv16.m_min_val     = (uint16_t)lpMan->m_min_value;
                  fv16.m_max_val     = (uint16_t)lpMan->m_max_value;
                  fv16.m_step        = (uint16_t)lpMan->m_step;

                  m_instructions.add_command(&fv16,sizeof(fv16));
              }
            }

            if (lpMan->m_size_bytes == 4 ){
                uint8_t op;
                if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){
                    op = StreamDPVmInstructions::ditINC32;
    
                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
                        op = StreamDPVmInstructions::ditINC32 ;
                    }
    
                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
                        op = StreamDPVmInstructions::ditDEC32 ;
                    }
    
                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){
                        op = StreamDPVmInstructions::ditRANDOM32 ;
                    }
    
                    StreamDPOpFlowVar32 fv32;
                    fv32.m_op = op;
                    fv32.m_flow_offset = get_var_offset(lpMan->m_var_name);
                    fv32.m_min_val     = (uint32_t)lpMan->m_min_value;
                    fv32.m_max_val     = (uint32_t)lpMan->m_max_value;
                    m_instructions.add_command(&fv32,sizeof(fv32));
                }else{
                    op = StreamDPVmInstructions::ditINC32_STEP;

                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
                        op = StreamDPVmInstructions::ditINC32_STEP ;
                    }

                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
                        op = StreamDPVmInstructions::ditDEC32_STEP ;
                    }

                    StreamDPOpFlowVar32Step fv32;
                    fv32.m_op = op;
                    fv32.m_flow_offset = get_var_offset(lpMan->m_var_name);
                    fv32.m_min_val     = (uint32_t)lpMan->m_min_value;
                    fv32.m_max_val     = (uint32_t)lpMan->m_max_value;
                    fv32.m_step        = (uint32_t)lpMan->m_step;
                    m_instructions.add_command(&fv32,sizeof(fv32));
                }
            }


            if (lpMan->m_size_bytes == 8 ){
                uint8_t op;

                if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){

                    op = StreamDPVmInstructions::ditINC64;
    
                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
                        op = StreamDPVmInstructions::ditINC64 ;
                    }
    
                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
                        op = StreamDPVmInstructions::ditDEC64 ;
                    }
    
                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){
                        op = StreamDPVmInstructions::ditRANDOM64 ;
                    }
    
                    StreamDPOpFlowVar64 fv64;
                    fv64.m_op = op;
                    fv64.m_flow_offset = get_var_offset(lpMan->m_var_name);
                    fv64.m_min_val     = (uint64_t)lpMan->m_min_value;
                    fv64.m_max_val     = (uint64_t)lpMan->m_max_value;
                    m_instructions.add_command(&fv64,sizeof(fv64));
                }else{

                    op = StreamDPVmInstructions::ditINC64_STEP;

                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
                        op = StreamDPVmInstructions::ditINC64_STEP ;
                    }

                    if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
                        op = StreamDPVmInstructions::ditDEC64_STEP ;
                    }

                    StreamDPOpFlowVar64Step fv64;
                    fv64.m_op = op;
                    fv64.m_flow_offset = get_var_offset(lpMan->m_var_name);
                    fv64.m_min_val     = (uint64_t)lpMan->m_min_value;
                    fv64.m_max_val     = (uint64_t)lpMan->m_max_value;
                    fv64.m_step        = (uint64_t)lpMan->m_step;
                    m_instructions.add_command(&fv64,sizeof(fv64));
                }
            }
        }

        if (ins_type == StreamVmInstruction::itPKT_WR) {
            StreamVmInstructionWriteToPkt *lpPkt =(StreamVmInstructionWriteToPkt *)inst;

            VmFlowVarRec var;
            if ( var_lookup(lpPkt->m_flow_var_name ,var) == false){

                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' packet write with no valid flow varible name '" << lpPkt->m_flow_var_name << "'" ;
                err(ss.str());
            }

            if (lpPkt->m_pkt_offset + var.m_size_bytes > m_pkt_size ) {
                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' packet write with packet_offset   " << lpPkt->m_pkt_offset + var.m_size_bytes  << "   bigger than packet size   "<< m_pkt_size;
                err(ss.str());
            }


            add_field_cnt(lpPkt->m_pkt_offset + var.m_size_bytes);


            uint8_t       op_size=var.m_size_bytes;
            bool is_big    = lpPkt->m_is_big_endian;
            uint8_t       flags = (is_big?StreamDPOpPktWrBase::PKT_WR_IS_BIG:0);
            uint8_t       flow_offset = get_var_offset(lpPkt->m_flow_var_name);

            if (op_size == 1) {
                StreamDPOpPktWr8 pw8;
                pw8.m_op = StreamDPVmInstructions::itPKT_WR8;
                pw8.m_flags =flags;
                pw8.m_offset =flow_offset;
                pw8.m_pkt_offset = lpPkt->m_pkt_offset;
                pw8.m_val_offset = (int8_t)lpPkt->m_add_value;
                m_instructions.add_command(&pw8,sizeof(pw8));
            }

            if (op_size == 2) {
                StreamDPOpPktWr16 pw16;
                pw16.m_op = StreamDPVmInstructions::itPKT_WR16;
                pw16.m_flags =flags;
                pw16.m_offset =flow_offset;
                pw16.m_pkt_offset = lpPkt->m_pkt_offset;
                pw16.m_val_offset = (int16_t)lpPkt->m_add_value;
                m_instructions.add_command(&pw16,sizeof(pw16));
            }

            if (op_size == 4) {
                StreamDPOpPktWr32 pw32;
                pw32.m_op = StreamDPVmInstructions::itPKT_WR32;
                pw32.m_flags =flags;
                pw32.m_offset =flow_offset;
                pw32.m_pkt_offset = lpPkt->m_pkt_offset;
                pw32.m_val_offset = (int32_t)lpPkt->m_add_value;
                m_instructions.add_command(&pw32,sizeof(pw32));
            }

            if (op_size == 8) {
                StreamDPOpPktWr64 pw64;
                pw64.m_op = StreamDPVmInstructions::itPKT_WR64;
                pw64.m_flags =flags;
                pw64.m_offset =flow_offset;
                pw64.m_pkt_offset = lpPkt->m_pkt_offset;
                pw64.m_val_offset = (int64_t)lpPkt->m_add_value;
                m_instructions.add_command(&pw64,sizeof(pw64));
            }

        }

        if (ins_type == StreamVmInstruction::itPKT_WR_MASK) {
            StreamVmInstructionWriteMaskToPkt *lpPkt =(StreamVmInstructionWriteMaskToPkt *)inst;

            VmFlowVarRec var;

            uint8_t cast_size = lpPkt->m_pkt_cast_size;
            if (!((cast_size==4)||(cast_size==2)||(cast_size==1))){
                std::stringstream ss;
                ss << "instruction id '" << ins_id << " cast size should be 1,2,4 it is "<<lpPkt->m_pkt_cast_size;
                err(ss.str());
            }

            if ( var_lookup(lpPkt->m_flow_var_name ,var) == false){

                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' packet write with no valid flow varible name '" << lpPkt->m_flow_var_name << "'" ;
                err(ss.str());
            }

            if (lpPkt->m_pkt_offset + lpPkt->m_pkt_cast_size > m_pkt_size ) {
                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' packet write with packet_offset   " << (lpPkt->m_pkt_offset + lpPkt->m_pkt_cast_size)  << "   bigger than packet size   "<< m_pkt_size;
                err(ss.str());
            }


            add_field_cnt(lpPkt->m_pkt_offset + lpPkt->m_pkt_cast_size);


            uint8_t       op_size = var.m_size_bytes;
            bool is_big           = lpPkt->m_is_big_endian;
            uint8_t       flags   = (is_big?StreamDPOpPktWrMask::MASK_PKT_WR_IS_BIG:0);
            uint8_t       flow_offset = get_var_offset(lpPkt->m_flow_var_name);

            /* read LSB in case of 64bit varible */
            if (op_size == 8) {
                op_size = 4;
                if ( is_big ) {
                    flow_offset +=4;
                }
            }

            StreamDPOpPktWrMask pmask;
            pmask.m_op = StreamDPVmInstructions::itPKT_WR_MASK;
            pmask.m_flags      =   flags;
            pmask.m_var_offset =   flow_offset;
            pmask.m_shift      =   lpPkt->m_shift;
            pmask.m_add_value  =   lpPkt->m_add_value;
            pmask.m_pkt_cast_size =   cast_size;
            pmask.m_flowv_cast_size = op_size;
            pmask.m_pkt_offset      = lpPkt->m_pkt_offset;
            pmask.m_mask            = lpPkt->m_mask;

            m_instructions.add_command(&pmask,sizeof(pmask));
        }


        if (ins_type == StreamVmInstruction::itFLOW_CLIENT) {
            var_cnt++;
            StreamVmInstructionFlowClient *lpMan =(StreamVmInstructionFlowClient *)inst;

            if ( lpMan->is_unlimited_flows() ){
                StreamDPOpClientsUnLimit  client_cmd;
                client_cmd.m_op =  StreamDPVmInstructions::itCLIENT_VAR_UNLIMIT;

                client_cmd.m_flow_offset = get_var_offset(lpMan->m_var_name+".ip"); /* start offset */
                client_cmd.m_flags       = 0; /* not used */
                client_cmd.m_pad         = 0;
                client_cmd.m_min_ip      = lpMan->m_client_min;
                client_cmd.m_max_ip      = lpMan->m_client_max;
                m_instructions.add_command(&client_cmd,sizeof(client_cmd));

            }else{
                StreamDPOpClientsLimit  client_cmd;
                client_cmd.m_op =  StreamDPVmInstructions::itCLIENT_VAR;

                client_cmd.m_flow_offset = get_var_offset(lpMan->m_var_name+".ip"); /* start offset */
                client_cmd.m_flags       = 0; /* not used */
                client_cmd.m_pad         = 0;
                client_cmd.m_min_port    = lpMan->m_port_min;
                client_cmd.m_max_port    = lpMan->m_port_max;
                client_cmd.m_min_ip      = lpMan->m_client_min;
                client_cmd.m_max_ip      = lpMan->m_client_max;
                client_cmd.m_limit_flows = lpMan->m_limit_num_flows;
                m_instructions.add_command(&client_cmd,sizeof(client_cmd));
            }
        }


        if (ins_type == StreamVmInstruction::itPKT_SIZE_CHANGE ) {
            StreamVmInstructionChangePktSize *lpPkt =(StreamVmInstructionChangePktSize *)inst;

            VmFlowVarRec var;
            if ( var_lookup(lpPkt->m_flow_var_name ,var) == false){

                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' packet size with no valid flow varible name '" << lpPkt->m_flow_var_name << "'" ;
                err(ss.str());
            }

            if ( var.m_size_bytes != 2 ) {
                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' packet size change should point to a flow varible with size 2  ";
                err(ss.str());
            }

            uint8_t       flow_offset = get_var_offset(lpPkt->m_flow_var_name);

            StreamDPOpPktSizeChange pkt_size_ch;
            pkt_size_ch.m_op =StreamDPVmInstructions::itPKT_SIZE_CHANGE;
            pkt_size_ch.m_flow_offset =  flow_offset;
            m_instructions.add_command(&pkt_size_ch,sizeof(pkt_size_ch));
        }

        ins_id++;
    }


    if ( var_cnt ==0 ){
        std::stringstream ss;
        ss << "It is not valid to have a VM program without a variable  or tuple generator ";
        err(ss.str());
    }
}
Пример #12
0
void StreamVm::build_flow_var_table() {

    var_clear_table();
    m_cur_var_offset=0;
    uint32_t ins_id=0;

    /* scan all flow var instruction and build */

    /* if we found allocate BSS +4 bytes */
    if ( m_is_random_var ){
        VmFlowVarRec var;

        var.m_offset = m_cur_var_offset;
        var.m_ins.m_ins_flowv = NULL;
        var.m_size_bytes = sizeof(uint32_t);
        var_add("___random___",var);
        m_cur_var_offset += sizeof(uint32_t);
    }

    for (auto inst : m_inst_list) {
        if ( inst->get_instruction_type() == StreamVmInstruction::itFLOW_MAN ){

            StreamVmInstructionFlowMan * ins_man=(StreamVmInstructionFlowMan *)inst;

            /* check that instruction is valid */
            ins_man->sanity_check(ins_id,this);

            VmFlowVarRec var;
            /* if this is the first time */ 
            if ( var_lookup( ins_man->m_var_name,var) == true){
                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' flow variable name " << ins_man->m_var_name << " already exists";
                err(ss.str());
            }else{

                var.m_offset=m_cur_var_offset;
                var.m_ins.m_ins_flowv = ins_man;
                var.m_size_bytes = ins_man->m_size_bytes;
                var_add(ins_man->m_var_name,var);
                m_cur_var_offset += ins_man->m_size_bytes;

            }
        }

        if ( inst->get_instruction_type() == StreamVmInstruction::itFLOW_CLIENT ){
            StreamVmInstructionFlowClient * ins_man=(StreamVmInstructionFlowClient *)inst;

            VmFlowVarRec var;
            /* if this is the first time */ 
            if ( var_lookup( ins_man->m_var_name+".ip",var) == true){
                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' client variable name " << ins_man->m_var_name << " already exists";
                err(ss.str());
            }
            if ( var_lookup( ins_man->m_var_name+".port",var) == true){
                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' client variable name " << ins_man->m_var_name << " already exists";
                err(ss.str());
            }

            if ( var_lookup( ins_man->m_var_name+".flow_limit",var) == true){
                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' client variable name " << ins_man->m_var_name << " already exists";
                err(ss.str());
            }

            var.m_offset = m_cur_var_offset;
            var.m_ins.m_ins_flow_client = ins_man;
            var.m_size_bytes =4;

            VmFlowVarRec var_port;

            var_port.m_offset = m_cur_var_offset+4;
            var_port.m_ins.m_ins_flow_client = ins_man;
            var_port.m_size_bytes =2;

            VmFlowVarRec var_flow_limit;

            var_flow_limit.m_offset = m_cur_var_offset+6;
            var_flow_limit.m_ins.m_ins_flow_client = ins_man;
            var_flow_limit.m_size_bytes =4;


            var_add(ins_man->m_var_name+".ip",var);
            var_add(ins_man->m_var_name+".port",var_port);
            var_add(ins_man->m_var_name+".flow_limit",var_flow_limit);

            m_cur_var_offset += StreamVmInstructionFlowClient::get_flow_var_size(); 

            assert(sizeof(StreamDPFlowClient)==StreamVmInstructionFlowClient::get_flow_var_size());
        }

        /* limit the flow var size */
        if (m_cur_var_offset > StreamVm::svMAX_FLOW_VAR ) {
            std::stringstream ss;
            ss << "too many flow varibles current size is :" << m_cur_var_offset << " maximum support is " << StreamVm::svMAX_FLOW_VAR;
            err(ss.str());
        }
        ins_id++;
    }


    ins_id=0;

    /* second interation for sanity check and fixups*/
    for (auto inst : m_inst_list) {


        if (inst->get_instruction_type() == StreamVmInstruction::itPKT_SIZE_CHANGE ) {
            StreamVmInstructionChangePktSize *lpPkt =(StreamVmInstructionChangePktSize *)inst;

            VmFlowVarRec var;
            if ( var_lookup(lpPkt->m_flow_var_name ,var) == false){

                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' packet size with no valid flow varible name '" << lpPkt->m_flow_var_name << "'" ;
                err(ss.str());
            }

            if ( var.m_size_bytes != 2 ) {
                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' packet size change should point to a flow varible with size 2  ";
                err(ss.str());
            }

            if ( var.m_ins.m_ins_flowv->m_max_value >  m_pkt_size) {
                var.m_ins.m_ins_flowv->m_max_value =m_pkt_size;
            }

            if (var.m_ins.m_ins_flowv->m_min_value > m_pkt_size) {
                var.m_ins.m_ins_flowv->m_min_value = m_pkt_size;
            }


            if ( var.m_ins.m_ins_flowv->m_min_value >= var.m_ins.m_ins_flowv->m_max_value  ) {
                std::stringstream ss;
                ss << "instruction id '" << ins_id << "' min packet size " << var.m_ins.m_ins_flowv->m_min_value << " is bigger or eq to max packet size " << var.m_ins.m_ins_flowv->m_max_value;
                err(ss.str());
            }

            if ( var.m_ins.m_ins_flowv->m_min_value < 60) {
                var.m_ins.m_ins_flowv->m_min_value =60;
            }

            m_expected_pkt_size = (var.m_ins.m_ins_flowv->m_min_value + var.m_ins.m_ins_flowv->m_max_value) / 2;
        }
    }/* for */

}
Пример #13
0
uint16_t StreamVm::get_var_offset(const std::string &var_name){
    VmFlowVarRec var;
    bool res=var_lookup(var_name,var);
    assert(res);
    return (var.m_offset);
}