Example #1
0
static int
__bro_list_val_read(BroListVal *lv, BroConn *bc)
{
  int i;
  uint32 ui;

  D_ENTER;

  if (! __bro_val_read((BroVal *) lv, bc))
    D_RETURN_(FALSE);

  __bro_list_free(lv->list, (BroFunc) __bro_sobject_release);
  lv->list = NULL;

  if (! __bro_buf_read_char(bc->rx_buf, &lv->type_tag))
    goto error_return;
  if (! __bro_buf_read_int(bc->rx_buf, &ui))
    goto error_return;

  lv->len = (int) ui;

  for (i = 0; i < lv->len; i++)
    {
      BroVal *val;

      if (! (val = (BroVal *) __bro_sobject_unserialize(SER_IS_VAL, bc)))
	goto error_return;

      lv->list = __bro_list_append(lv->list, val);
    }

  D_RETURN_(TRUE);

 error_return:
  __bro_list_free(lv->list, (BroFunc) __bro_sobject_release);
  lv->list = NULL;
  D_RETURN_(FALSE);
}
Example #2
0
static int
io_process_serialization(BroConn *bc)
{
  BroVal vbuf;

  D_ENTER;

  if (! __bro_buf_read_char(bc->rx_buf, &vbuf.val_char))
    {
      D(("Couldn't read serialization type\n"));
      D_RETURN_(FALSE);
    }

  switch (vbuf.val_char)
    {
    case 'e':
      {
	BroEvent *ev;

	bc->rx_ev_start = (const char*) bro_buf_ptr_get(bc->rx_buf);

	D(("Processing serialized event.\n"));
	if (! (ev = __bro_event_unserialize(bc)))
	  {
	    bc->rx_ev_start = bc->rx_ev_end = NULL;
	    D_RETURN_(FALSE);
	  }

	bc->rx_ev_end = (const char*) bro_buf_ptr_get(bc->rx_buf);	
	__bro_event_reg_dispatch(bc, ev);
	__bro_event_free(ev);      
	bc->rx_ev_start = bc->rx_ev_end = NULL;
      }
      break;

    case 'i':
      {
	BroID *id;

	D(("Processing serialized ID.\n"));
	if (! (id = (BroID *) __bro_sobject_unserialize(SER_IS_ID, bc)))
	  D_RETURN_(FALSE);
	
	D(("ID read successfully.\n"));
	/* Except we don't do anything with it yet. :) */
	__bro_sobject_release((BroSObject *) id);
      }
      break;

    case 'p':
      {
#ifdef BRO_PCAP_SUPPORT
	BroPacket *packet;
	
	if (! (packet = __bro_packet_unserialize(bc)))
	  D_RETURN_(FALSE);
	
	D(("Packet read successfully.\n"));
	bro_packet_free(packet);
#else
	D_RETURN_(FALSE);
#endif
      }
      break;

    default:
      /* We do not handle anything else yet -- just say
       * we are happy and return.
       */
      D(("Unknown serialization of type %c\n", vbuf.val_char));
      D_RETURN_(FALSE);
    }

  /* After a complete unserialization, we enforce the size limit
   * of the cache. We can't do it on the go as a new object that
   * is unserialized may still contain references to previously
   * cached items which we might evict.
   */
  while (__bro_ht_get_size(bc->io_cache) > bc->io_cache_maxsize)
    __bro_ht_evict_oldest(bc->io_cache);
  
  D_RETURN_(TRUE);
}
Example #3
0
int
__bro_id_read(BroID *id, BroConn *bc)
{
  char opt;

  D_ENTER;

  if (! id || ! bc)
    D_RETURN_(FALSE);

  if (! __bro_object_read((BroObject *) id, bc))
    D_RETURN_(FALSE);

  if (! __bro_buf_read_string(bc->rx_buf, &id->name))
    D_RETURN_(FALSE);

  if (! __bro_buf_read_char(bc->rx_buf, &id->scope))
    D_RETURN_(FALSE);

  if (! __bro_buf_read_char(bc->rx_buf, &id->is_export))
    D_RETURN_(FALSE);
  if (! __bro_buf_read_int(bc->rx_buf, &id->is_const))
    D_RETURN_(FALSE);
  if (! __bro_buf_read_int(bc->rx_buf, &id->is_enum_const))
    D_RETURN_(FALSE);
  if (! __bro_buf_read_int(bc->rx_buf, &id->is_type))
    D_RETURN_(FALSE);

  if (! __bro_buf_read_int(bc->rx_buf, &id->offset))
    D_RETURN_(FALSE);
  
  if (! __bro_buf_read_char(bc->rx_buf, &id->infer_return_type))
    D_RETURN_(FALSE);
  if (! __bro_buf_read_char(bc->rx_buf, &id->weak_ref))
    D_RETURN_(FALSE);
  
  if (id->type)
    __bro_sobject_release((BroSObject*) id->type);
  if (! (id->type = (BroType *) __bro_sobject_unserialize(SER_IS_TYPE, bc)))
    D_RETURN_(FALSE);

  if (! __bro_buf_read_char(bc->rx_buf, &opt))
    D_RETURN_(FALSE);
  if (opt)
    {
      if (id->attrs)
	__bro_sobject_release((BroSObject *) id->attrs);

      if (! (id->attrs = (BroAttrs *) __bro_sobject_unserialize(SER_ATTRIBUTES, bc)))
	D_RETURN_(FALSE);
    }

  if (! __bro_buf_read_char(bc->rx_buf, &opt))
    D_RETURN_(FALSE);
  if (opt)
    {
      if (id->val)
	__bro_sobject_release((BroSObject *) id->val);

      if (! (id->val = (BroVal *) __bro_sobject_unserialize(SER_IS_VAL, bc)))
	D_RETURN_(FALSE);
    }
  
  D_RETURN_(TRUE);
}
Example #4
0
static int
__bro_val_read(BroVal *val, BroConn *bc)
{
  char opt;
  uint32 tmp;
  int i;

  D_ENTER;

  if (! val || !bc)
    D_RETURN_(FALSE);

  if (! __bro_object_read((BroObject *) val, bc))
    D_RETURN_(FALSE);

  /* Read type */

  if (val->val_type)
    {
      __bro_sobject_release((BroSObject *) val->val_type);
      val->val_type = NULL;
    }

  if (! (val->val_type = (BroType *) __bro_sobject_unserialize(SER_IS_TYPE, bc)))
    D_RETURN_(FALSE);

  D(("Type in val has type tags %i/%i\n",
     val->val_type->tag, val->val_type->internal_tag));

  /* Read optional Attributes */

  if (val->val_attrs)
    {
      __bro_sobject_release((BroSObject *) val->val_attrs);
      val->val_attrs = NULL;
    }

  if (! __bro_buf_read_char(bc->rx_buf, &opt))
    D_RETURN_(FALSE);
  if (opt)
    {
      if (! (val->val_attrs = (BroRecordVal *) __bro_sobject_unserialize(SER_RECORD_VAL, bc)))
	D_RETURN_(FALSE);
    }

  switch (val->val_type->internal_tag)
    {
    case BRO_INTTYPE_INT:
    case BRO_INTTYPE_UNSIGNED:
      /* Hack for ports */
      if (val->val_type->tag == BRO_TYPE_PORT)
	{
      uint64 tmp;
	  if (! __bro_buf_read_int64(bc->rx_buf, &tmp))
	    D_RETURN_(FALSE);

	  if ( (tmp & 0xf0000) == 0x10000 )
	    val->val_port.port_proto = IPPROTO_TCP;
	  else if ( (tmp & 0xf0000) == 0x20000 )
	    val->val_port.port_proto = IPPROTO_UDP;
	  else if ( (tmp & 0xf0000) == 0x30000 )
	    val->val_port.port_proto = IPPROTO_ICMP;

	  val->val_port.port_num = (tmp & 0xFFFF);
	}
      else
	{
	  if (! __bro_buf_read_int64(bc->rx_buf, &val->val_int64))
	    D_RETURN_(FALSE);
	}
      break;

    case BRO_INTTYPE_DOUBLE:
      if (! __bro_buf_read_double(bc->rx_buf, &val->val_double))
	D_RETURN_(FALSE);
      break;

    case BRO_INTTYPE_STRING:
      if (! __bro_buf_read_string(bc->rx_buf, &val->val_str))
	D_RETURN_(FALSE);
      break;

    case BRO_INTTYPE_IPADDR:
		if (! __bro_buf_read_int(bc->rx_buf, &tmp))
			D_RETURN_(FALSE);

		if (tmp != 1 && tmp != 4)
			{
			D(("Bad IP addresses word length: %d.\n", tmp));
			D_RETURN_(FALSE);
			}

		if ( tmp == 1 )
			{
			if (! __bro_buf_read_int(bc->rx_buf, &tmp))
				D_RETURN_(FALSE);
			__bro_util_fill_v4_addr(&val->val_addr, ntohl(tmp));
			}

		else
			{
			for ( i = 0; i < tmp; ++i )
				{
				if (! __bro_buf_read_int(bc->rx_buf, &val->val_addr.addr[i]))
					D_RETURN_(FALSE);

				val->val_addr.addr[i] = ntohl(val->val_addr.addr[i]);
				}
			}

		break;

    case BRO_INTTYPE_SUBNET:
		if (! __bro_buf_read_int(bc->rx_buf, &tmp))
			D_RETURN_(FALSE);

		if (tmp != 1 && tmp != 4)
			{
			D(("Bad IP addresses word length: %d.\n", tmp));
			D_RETURN_(FALSE);
			}

		if ( tmp == 1 )
			{
			if (! __bro_buf_read_int(bc->rx_buf, &tmp))
				D_RETURN_(FALSE);
			__bro_util_fill_v4_addr(&val->val_subnet.sn_net, ntohl(tmp));
			}

		else
			{
			for ( i = 0; i < tmp; ++i )
				{
				if (! __bro_buf_read_int(bc->rx_buf,
										 &val->val_subnet.sn_net.addr[i]))
					D_RETURN_(FALSE);

				val->val_subnet.sn_net.addr[i] =
					ntohl(val->val_subnet.sn_net.addr[i]);
				}
			}

		if (! __bro_buf_read_int(bc->rx_buf, &val->val_subnet.sn_width))
			D_RETURN_(FALSE);

		break;

    case BRO_INTTYPE_OTHER:
      /* See Val.cc around 165 -- these are handled by derived classes.
       * We only make sure here it's not functions and not files.
       */
      if (val->val_type->tag != BRO_TYPE_FUNC &&
	  val->val_type->tag != BRO_TYPE_FILE)
	break;

      /* Otherwise fall through to warning. */

    default:
      D(("Unsupported internal type tag: %i\n", val->val_type->internal_tag));
      D_RETURN_(FALSE);
    }

  D_RETURN_(TRUE);
}
Example #5
0
static int
__bro_table_val_read(BroTableVal *tbl, BroConn *bc)
{
  double d;
  char opt;
  int num_keys = 0, num_vals = 0;

  D_ENTER;

  if (! __bro_mutable_val_read((BroMutableVal *) tbl, bc))
    D_RETURN_(FALSE);

  /* Clean out old vals, if any */
  __bro_table_free(tbl->table);

  if (! (tbl->table = __bro_table_new()))
    D_RETURN_(FALSE);

  /* expire_time, currently unused */
  if (! __bro_buf_read_double(bc->rx_buf, &d))
    goto error_return;

  if (! __bro_buf_read_char(bc->rx_buf, &opt))
    goto error_return;
  if (opt)
    {
      if (! (tbl->attrs = (BroAttrs *) __bro_sobject_unserialize(SER_ATTRIBUTES, bc)))
	{
	  D(("WARNING -- unserializing table attributes failed.\n"));
	  goto error_return;
	}
    }

  if (! __bro_buf_read_char(bc->rx_buf, &opt))
    goto error_return;
  if (opt)
    {
      D(("WARNING -- cannot unserialize expression, try to use table without expiration expression.\n"));
      goto error_return;
    }

  /* Table entries are next: */
  for ( ; ; )
    {
      BroType *type;
      BroListVal *keys = NULL;
      BroVal *val = NULL;
      BroIndexType *itype = NULL;
      int i, len, key_type = 0, val_type = 0;
      double d;

      if (! __bro_buf_read_char(bc->rx_buf, &opt))
	goto error_return;

      /* End of set members is announced if opt is 0: */
      if (! opt)
	break;

      if (! (keys = (BroListVal *) __bro_sobject_unserialize(SER_LIST_VAL, bc)))
	goto error_return;

      /* If this isn't a set, we have a value associated with the keys too. */
      type = ((BroVal *) tbl)->val_type;
      itype = (BroIndexType*) type;
      num_vals++;

      if (itype->yield_type)
	{
	  if (! (val = (BroVal *) __bro_sobject_unserialize(SER_IS_VAL, bc)))
	    goto error_return;

	  val_type = val->val_type->tag;
	  num_keys++;
	}

      /* If the key is a composite, we report BRO_TYPE_LIST to the user,
       * so the user can access the individual values via a record. If
       * the key is atomic, we extract its type and use it directly.
       */

      if (keys->len > 1)
	key_type = BRO_TYPE_LIST;
      else if (keys->len == 1)
	key_type = __bro_list_val_get_front(keys)->val_type->tag;
      else
	goto error_return;

      if (tbl->table->tbl_key_type != BRO_TYPE_UNKNOWN &&
	  tbl->table->tbl_key_type != key_type)
	{
	  D(("Type mismatch when unserializing key of type %d, expecting %d\n",
	     key_type, tbl->table->tbl_key_type));
	  goto error_return;
	}

      tbl->table->tbl_key_type = key_type;

      if (tbl->table->tbl_val_type != BRO_TYPE_UNKNOWN &&
	  tbl->table->tbl_val_type != val_type)
	{
	  D(("Type mismatch when unserializing val of type %d, expecting %d\n",
	     val_type, tbl->table->tbl_val_type));
	  goto error_return;
	}

      tbl->table->tbl_val_type = val_type;

      /* Eat two doubles -- one for the last access time and
       * one for when the item is supposed to expire.
       * XXX: currently unimplemented.
       */
      if (! __bro_buf_read_double(bc->rx_buf, &d) ||
	  ! __bro_buf_read_double(bc->rx_buf, &d))
	goto error_return;

      /* The key type of a BroTable is always a BroListVal, even
       * though it might well have only a single element.
       *
       * Since we just unserialized it, we pass on ownership of
       * both key and value to the table.
       */
      __bro_table_insert(tbl->table, (BroVal*) keys, val);
    }

  D_RETURN_(TRUE);

 error_return:
  __bro_table_free(tbl->table);
  tbl->table = NULL;
  D_RETURN_(FALSE);
}
Example #6
0
static int
__bro_record_val_read(BroRecordVal *rv, BroConn *bc)
{
  char opt;
  uint32 i, len;
  BroVal *val;

  D_ENTER;

  if (! __bro_mutable_val_read((BroMutableVal *) rv, bc))
    D_RETURN_(FALSE);

  /* Clean out old vals, if any */
  __bro_record_free(rv->rec);

  if (! (rv->rec = __bro_record_new()))
    D_RETURN_(FALSE);

  /* Read in new vals */

  if (! __bro_buf_read_int(bc->rx_buf, &len))
    goto error_return;

  for (i = 0; i < len; i++)
    {
      const char *field_name;
      BroVal *rv_val   = (BroVal *) rv;
      BroType *rv_type = rv_val->val_type;

      D(("Reading val %i/%i into record %p of val %p\n",
	 i+1, len, rv->rec, rv));

      if (! __bro_buf_read_char(bc->rx_buf, &opt))
	goto error_return;

      if (opt)
	{
	  if (! (val = (BroVal *) __bro_sobject_unserialize(SER_IS_VAL, bc)))
	    {
	      D(("WARNING -- unserializing record element failed.\n"));
	      goto error_return;
	    }
	}
      else
	{
	  /* We need an empty val if none was given in order to maintain
	   * a chain of vals nonetheless -- the missing type in this new
	   * val indicates that it is an unassigned val.
	   */
	  D(("WARNING -- unassigned val.\n"));
	  if (! (val = __bro_val_new()))
	    goto error_return;
	}

      __bro_record_add_val(rv->rec, val);

      if (! (field_name = __bro_record_type_get_nth_field((BroRecordType *) rv_type, i)))
	{
	  D(("WARNING -- record type field %i has no name.\n", i));
	  goto error_return;
	}

      __bro_record_set_nth_name(rv->rec, i, field_name);
    }

  D_RETURN_(TRUE);

 error_return:
  __bro_record_free(rv->rec);
  rv->rec = NULL;
  D_RETURN_(FALSE);
}