Ejemplo n.º 1
0
static void
__bro_val_free(BroVal *val)
{
  D_ENTER;

  /* If there is no type in the val, then it's unassigned and
   * hence there won't be anything to clean up anyway.
   */
  if (val->val_type)
    {
      switch (val->val_type->tag)
	{
	case BRO_TYPE_STRING:
	  bro_string_cleanup(&val->val_str);
	  break;

	default:
	  /* Nothing to do */
	  break;
	}
    }

  __bro_sobject_release((BroSObject *) val->val_type);
  __bro_object_free((BroObject *) val);

  D_RETURN;
}
Ejemplo n.º 2
0
static void
__bro_mutable_val_free(BroMutableVal *mv)
{
  D_ENTER;

  __bro_sobject_release((BroSObject *) mv->id);
  __bro_val_free((BroVal *) mv);

  D_RETURN;
}
Ejemplo n.º 3
0
void
__bro_id_free(BroID *id)
{
  D_ENTER;

  if (!id)
    D_RETURN;

  /* First clean up our stuff */
  bro_string_cleanup(&id->name);

  __bro_sobject_release((BroSObject *) id->type);
  __bro_sobject_release((BroSObject *) id->attrs);
  __bro_sobject_release((BroSObject *) id->val);
  
  /* Then clean up parent -- will eventually call free() */
  __bro_object_free((BroObject *) id);

  D_RETURN;
}
Ejemplo n.º 4
0
int
__bro_vector_set_nth_val(BroVector *vec, int num, BroVal *v)
	{
	BroVal *val;

	if ( ! vec || num < 0 || num >= vec->length || ! v )
		return FALSE;

	__bro_sobject_release((BroSObject*) vec->vector[num]);
	vec->vector[num] = v;
	return TRUE;
	}
Ejemplo n.º 5
0
void
__bro_vector_free(BroVector *vec)
	{
	int i;

	if ( ! vec )
		return;

	for ( i = 0; i < vec->length; ++i )
		__bro_sobject_release((BroSObject*) vec->vector[i]);

	free(vec->vector);
	free(vec);
	}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
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);
}
Ejemplo n.º 9
0
int
__bro_val_assign(BroVal *val, const void *data)
{
  D_ENTER;

  if (! val)
    {
      D(("Input error: (%p, %p)\n", val, data));
      D_RETURN_(FALSE);
    }

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

      D(("Marked val %p as unassigned.\n", val));
      D_RETURN_(TRUE);
    }


  /* If we intend to assign data to the val, it must have a type. */
  if (! val->val_type)
    {
      D(("Cannot assign to val without a type.\n"));
      D_RETURN_(FALSE);
    }

  switch (val->val_type->tag)
    {
    case BRO_TYPE_BOOL:
      {
	int tmp = *((int *) data);
	val->val.char_val = (tmp != 0 ? 1 : 0);
      }
      break;

    case BRO_TYPE_INT:
    case BRO_TYPE_COUNT:
    case BRO_TYPE_COUNTER:
    case BRO_TYPE_ENUM:
      val->val_int64 = *((uint64 *) data);
      break;

    case BRO_TYPE_DOUBLE:
    case BRO_TYPE_TIME:
    case BRO_TYPE_INTERVAL:
      val->val_double = *((double *) data);
      break;

    case BRO_TYPE_STRING:
      {
	BroString *str = (BroString *) data;
	bro_string_set_data(&val->val_str, str->str_val, str->str_len);
      }
      break;

    case BRO_TYPE_PORT:
      {
	BroPort *tmp = (BroPort *) data;

	if (tmp->port_proto != IPPROTO_TCP &&
	    tmp->port_proto != IPPROTO_UDP &&
	    tmp->port_proto != IPPROTO_ICMP)
	  {
	    __bro_sobject_release((BroSObject *) data);
	    D_RETURN_(FALSE);
	  }

	val->val_port = *tmp;
      }
      break;

    case BRO_TYPE_IPADDR:
      val->val_addr = *((BroAddr *) data);
      break;

    case BRO_TYPE_SUBNET:
      val->val_subnet = *((BroSubnet *) data);
      break;

    case BRO_TYPE_RECORD:
      {
	BroList *l;
	BroVal *tmp_val;
	BroRecordVal *rv = (BroRecordVal *) val;
	BroRecord *rec = (BroRecord *) data;

	if (rv->rec)
	  __bro_record_free(rv->rec);

	rv->rec = __bro_record_copy(rec);

	/* Record vals also have a record type, copy that: */
	for (l = rec->val_list; l; l = __bro_list_next(l))
	  {
	    char *field;

	    tmp_val = __bro_list_data(l);

	    if (! tmp_val->val_type)
	      {
		D(("Cannot create record type component from val without type.\n"));
		D_RETURN_(FALSE);
	      }

	    if (! (field = __bro_sobject_data_get((BroSObject *) tmp_val, "field")))
	      {
		D(("Val in record doesn't have field name associated with it.\n"));
		D_RETURN_(FALSE);
	      }

	    __bro_record_type_add_type((BroRecordType *) val->val_type, field, tmp_val->val_type);;
	  }
      }
      break;

    case BRO_TYPE_TABLE:
      {
	BroTableVal *tv = (BroTableVal *) val;
	BroTable *table = (BroTable *) data;

	if (tv->table)
	  __bro_table_free(tv->table);

	tv->table = __bro_table_copy(table);

	/* XXX need to create the appropriate content in (BroTableType*) val->val_type! */
      }
      break;

    case BRO_TYPE_PATTERN:
    case BRO_TYPE_TIMER:
    case BRO_TYPE_ANY:
    case BRO_TYPE_UNION:
    case BRO_TYPE_LIST:
    case BRO_TYPE_FUNC:
    case BRO_TYPE_FILE:
    case BRO_TYPE_VECTOR:
    case BRO_TYPE_ERROR:
      D(("Type %i currently unsupported.\n", val->val_type->tag));
      D_RETURN_(FALSE);

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

  D_RETURN_(TRUE);
}
Ejemplo n.º 10
0
BroSObject      *
__bro_sobject_unserialize(uint16 type_id_wanted, BroConn *bc)
{
  BroSObject *obj;
  char full_obj;
  uint32 perm_id;
  uint16 type_id;

  D_ENTER;

  if (! bc)
    D_RETURN_(NULL);
  
  /* Same special case for types as in __bro_sobject_serialize().
   */
  if ( (type_id_wanted & SER_TYPE_MASK) == SER_IS_TYPE)
    {
      D(("Unserializing a type, checking for name-only format.\n"));

      if (! __bro_buf_read_char(bc->rx_buf, &full_obj))
	D_RETURN_(NULL);

      if (! full_obj)
	{
	  BroString tmp;
	  bro_string_init(&tmp);
	  
	  /* We only get the name. */
	  if (! __bro_buf_read_string(bc->rx_buf, &tmp))
	    D_RETURN_(FALSE);
	  
	  /* We don't really have a namespace in which we can now
	   * look up the type, so there's not much we can do!
	   */
	  D(("Received name-only type '%s', reporting failure.\n",
	     bro_string_get_data(&tmp)));
	  D_RETURN_(FALSE);
	}
    }
  
  if (! __bro_buf_read_char(bc->rx_buf, &full_obj))
    D_RETURN_(NULL);
  
  if (! __bro_buf_read_int(bc->rx_buf, &perm_id))
    D_RETURN_(NULL);

  if (! full_obj)
    {
#ifdef BRO_DEBUG
      if (! (bc->conn_flags & BRO_CFLAG_CACHE))
	D(("WARNING: no caching requested, yet peer sends cached data.\n"));
#endif
      if (! (obj = __bro_ht_get(bc->io_cache, (void *) perm_id)))
	{
	  D(("Cache inconsistency: cache should contain object %i\n", perm_id));
	  D_RETURN_(NULL);
	}
      
      __bro_sobject_ref(obj);

      D(("Returning object %i/%p from cache.\n", perm_id, obj));
      D_RETURN_(obj);
    }
 
  if (! __bro_buf_read_short(bc->rx_buf, &type_id))
    D_RETURN_(NULL);
  
  /* Now check if the stuff that's arriving is actually an
   * instance of the type we'd like to see -- we can only do
   * primitive checking for inherited types (when we want to
   * know that it's a type, say, but we cannot know what exact
   * kind of type) -- so we just check whether all the bits set
   * in both type id's match:
   */
  if ((type_id_wanted & SER_TYPE_MASK) != (type_id & SER_TYPE_MASK))
    {
      D(("Type mismatch in serialization: wanted %04x, got %04x.\n",
	 type_id_wanted, type_id));
      D_RETURN_(NULL);
    }
  
  if (! (obj = __bro_sobject_create(type_id)))
    D_RETURN_(NULL);
  
  /* Polymorphism: depending on the constructor of the object,
   * this call will start from the bottom of the hierarchy and
   * read members in step by step, so by the time we return
   * from this function the object is fully unserialized.
   */
  if (! obj->read(obj, bc))
    {
      D(("Reading object %i of type 0x%04x FAILED.\n", perm_id, type_id));
      __bro_sobject_release(obj);
      D_RETURN_(NULL);
    }

  /* If we have asked the peer to use caching,
   * make sure the object is in the cache:
   */
  if ( (bc->conn_flags & BRO_CFLAG_CACHE) &&
      ! __bro_ht_get(bc->io_cache, (void *) perm_id))
    {
      D(("Storing object %i in cache.\n", perm_id));
      __bro_ht_add(bc->io_cache, (void *) perm_id, obj);
      obj->perm_id = perm_id;
      __bro_sobject_ref(obj);
    }

  D(("Object %i of type 0x%04x unserialized successfully.\n", perm_id, type_id));
  D_RETURN_(obj);
}