Esempio n. 1
0
int
__bro_id_write(BroID *id, BroConn *bc)
{
  D_ENTER;

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

  if (! __bro_object_write((BroObject *) id, bc))
    D_RETURN_(FALSE);
  
  if (! __bro_buf_write_string(bc->tx_buf, &id->name))
    D_RETURN_(FALSE);

  if (! __bro_buf_write_char(bc->tx_buf, id->scope))
    D_RETURN_(FALSE);

  if (! __bro_buf_write_char(bc->tx_buf, id->is_export))
    D_RETURN_(FALSE);
  if (! __bro_buf_write_int(bc->tx_buf, id->is_const))
    D_RETURN_(FALSE);
  if (! __bro_buf_write_int(bc->tx_buf, id->is_enum_const))
    D_RETURN_(FALSE);
  if (! __bro_buf_write_int(bc->tx_buf, id->is_type))
    D_RETURN_(FALSE);

  if (! __bro_buf_write_int(bc->tx_buf, id->offset))
    D_RETURN_(FALSE);
  
  if (! __bro_buf_write_char(bc->tx_buf, id->infer_return_type))
    D_RETURN_(FALSE);
  if (! __bro_buf_write_char(bc->tx_buf, id->weak_ref))
    D_RETURN_(FALSE);
  
  if (! __bro_sobject_serialize((BroSObject *) id->type, bc))
    D_RETURN_(FALSE);

  if (! __bro_buf_write_char(bc->tx_buf, id->attrs ? 1 : 0))
    D_RETURN_(FALSE);
  if (id->attrs && ! __bro_sobject_serialize((BroSObject *) id->attrs, bc))
    D_RETURN_(FALSE);

  if (! __bro_buf_write_char(bc->tx_buf, id->val ? 1 : 0))
    D_RETURN_(FALSE);
  if (id->attrs && ! __bro_sobject_serialize((BroSObject *) id->val, bc))
    D_RETURN_(FALSE);
  
  D_RETURN_(TRUE);
}
Esempio n. 2
0
static int
__bro_list_val_write(BroListVal *lv, BroConn *bc)
{
  BroList *l;

  D_ENTER;

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

  if (! __bro_buf_write_char(bc->tx_buf, lv->type_tag))
    D_RETURN_(FALSE);

  if (! __bro_buf_write_int(bc->tx_buf, lv->len))
    D_RETURN_(FALSE);

  for (l = lv->list; l; l = __bro_list_next(l))
    {
      BroVal *val = __bro_list_data(l);

      if (! __bro_sobject_serialize((BroSObject *) val, bc))
	D_RETURN_(FALSE);
    }

  D_RETURN_(TRUE);
}
Esempio n. 3
0
int
__bro_sobject_serialize(BroSObject *obj, BroConn *bc)
{
  char full_obj;

  D_ENTER;

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

  /* Special case for types: they indicate at the very beginning
   * whether they're transferred in their entirety or just via
   * their name (in which case we can't do much at the moment).
   */
  if ( (obj->type_id & SER_TYPE_MASK) == SER_IS_TYPE)
    {      
      BroType *type = (BroType *) obj;
      
      D(("Serializing type %X as type\n", obj->type_id));

      if (! __bro_buf_write_char(bc->tx_buf, type->is_complete))
	D_RETURN_(FALSE);
      
      if (! type->is_complete)
	{
	  if (! __bro_buf_write_string(bc->tx_buf, &type->type_name))
	    D_RETURN_(FALSE);
	  
	  D(("Type sent by type-name '%s' only.\n", bro_string_get_data(&type->type_name)));
	  D_RETURN_(TRUE);
	}
    }
  
  /* FIXME: for now we never use the serialization cache when sending. */
  full_obj = 1;
  
  if (! __bro_buf_write_char(bc->tx_buf, full_obj))
    D_RETURN_(FALSE);
  if (! __bro_buf_write_int(bc->tx_buf, obj->perm_id))
    D_RETURN_(FALSE);

  if (! obj->write(obj, bc))
    D_RETURN_(FALSE);
  
  D_RETURN_(TRUE);
}
Esempio n. 4
0
static int
__bro_record_val_write(BroRecordVal *rv, BroConn *bc)
{
  BroList *l;
  BroVal *val;
  int i;

  D_ENTER;

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

  if (! __bro_buf_write_int(bc->tx_buf, rv->rec->val_len))
    D_RETURN_(FALSE);

  if (! rv->rec && rv->rec->val_len > 0)
    D_RETURN_(FALSE);

  D(("Writing out %i vals in record %p.\n", rv->rec->val_len, rv->rec));

  for (i = 0, l = rv->rec->val_list; l; i++, l = __bro_list_next(l))
    {
      val = __bro_list_data(l);

      D(("Val %i/%p's type: %p\n", i, val, val->val_type));

      if (! __bro_buf_write_char(bc->tx_buf, (val->val_type ? 1 :0)))
	D_RETURN_(FALSE);

      if (val->val_type)
	{
	  if (! __bro_sobject_serialize((BroSObject *) val, bc))
	    D_RETURN_(FALSE);
	}
    }

  D_RETURN_(TRUE);
}
Esempio n. 5
0
static int      
io_msg_fill_tx(BroConn *bc, BroMsg *msg)
{
  int result = TRUE;

  D_ENTER;

  if (!bc || !msg)
    {
      D(("Input error.\n"));
      D_RETURN_(FALSE);
    }

  /* Check if anything is still left in the input buffer. In that case,
   * we don't fill anything in but return right away, so the message
   * gets queued.
   */
  if (__bro_buf_get_used_size(bc->tx_buf) > 0)
    {
      D(("Buffer not empty; not filling!\n"));
      D_RETURN_(FALSE);
    }
  
  D((">>> Attempting write of %s\n", msg_type_2_str(msg->msg_header.hdr_type)));

  /* We will collect the message chunk in the connection's tx buffer.
   * We append stuff to it as we go along and at the end write it out.
   * When being sent, he buffer has the amount of octets to send at
   * the beginning, so the reader knows how much is coming.
   */
  __bro_buf_reset(bc->tx_buf);

  msg->msg_header_size = sizeof(BroMsgHeader);
  
  if (! __bro_buf_write_int(bc->tx_buf, msg->msg_header_size))
    {
      __bro_buf_reset(bc->tx_buf);
      D_RETURN_(FALSE);
    }
  
  /* Hook in the Bro message header */
  if (! io_fill_msg_header(bc->tx_buf, &msg->msg_header))
    {
      __bro_buf_reset(bc->tx_buf);
      D_RETURN_(FALSE);
    }
  
  if (msg->msg_cont_type != BRO_MSG_CONT_NONE)
    {
      uint32 msg_size_pos, msg_size_end;

      /* This starts another chunk of data (in Bro protocol speak),
       * but here we cannot yet know how big the chunk will be.
       * We save the offset in the buffer and return to it later,
       * overwriting the value with the then correct one.
       */
      msg_size_pos = __bro_buf_get_used_size(bc->tx_buf);
      if (! __bro_buf_write_int(bc->tx_buf, msg->msg_size))
	{
	  __bro_buf_reset(bc->tx_buf);
	  D_RETURN_(FALSE);
	}
      
      /* Gather the payload of the message we are about
       * to send into the buffer BUF.
       */
      switch (msg->msg_cont_type)
	{
	case BRO_MSG_CONT_RAW:
	  D(("Filling raw data into buffer\n"));
	  if (! io_fill_raw(bc->tx_buf, msg->msg_cont_raw))
	    {
	      __bro_buf_reset(bc->tx_buf);
	      D_RETURN_(FALSE);
	    }
	  break;
	  
	case BRO_MSG_CONT_EVENT:
	  /* Check if the peer actually requested the event, and if not,
	   * drop it silently (i.e., still return success).
	   */
	  if (! __bro_ht_get(bc->ev_mask, msg->msg_cont_ev->name.str_val))
	    {
	      D(("Event '%s' not requested by peer -- dropping.\n",
		 msg->msg_cont_ev->name.str_val));
	      __bro_buf_reset(bc->tx_buf);

	      /* This is not an error but a silent drop, so we
	       * return success.
	       */
	      D_RETURN_(TRUE);
	    }
	  
	  D(("Filling event into buffer\n"));
	  
	  if (! __bro_event_serialize(msg->msg_cont_ev, bc))
	    {
	      D(("Error during serialization.\n"));
	      __bro_buf_reset(bc->tx_buf);
	      D_RETURN_(FALSE);	
	    }
	  break;
	  
	case BRO_MSG_CONT_REQUEST:
	  D(("Filling request into buffer\n"));
	  if (! io_fill_request(bc->tx_buf, msg->msg_cont_req))
	    {
	      __bro_buf_reset(bc->tx_buf);
	      D_RETURN_(FALSE);	
	    }
	  break;

#ifdef BRO_PCAP_SUPPORT	  
	case BRO_MSG_CONT_PACKET:
	  if (! __bro_packet_serialize(msg->msg_cont_packet, bc))
	    {
	      __bro_buf_reset(bc->tx_buf);	      
	      D_RETURN_(FALSE);
	    }
	  break;
#endif
	default:
	  D(("ERROR -- invalid message content code %i\n", msg->msg_cont_type));
	  break;
	}
      
      /* Now calculate length of entire transmission --
       * we know where we wrote the uint32 containing the
       * size of the chunk, and we know where we are now,
       * so the length is their difference, minus the uint32
       * itself.
       */
      msg_size_end = __bro_buf_get_used_size(bc->tx_buf);
      msg->msg_size = msg_size_end - msg_size_pos - sizeof(uint32);
      D(("Serialized message sized %i bytes.\n", msg->msg_size));
      
      if (! __bro_buf_ptr_seek(bc->tx_buf, msg_size_pos, SEEK_SET))
	{
	  D(("Cannot seek to position %u -- we're screwed.\n", msg_size_pos));
	  __bro_buf_reset(bc->tx_buf);
	  D_RETURN_(FALSE);
	}
      
      if (! __bro_buf_write_int(bc->tx_buf, msg->msg_size))
	{
	  __bro_buf_reset(bc->tx_buf);
	  D_RETURN_(FALSE);
	}
    }
  
  D_RETURN_(result);
}
Esempio n. 6
0
static int
__bro_val_write(BroVal *val, BroConn *bc)
{
  BroType *type;
  BroSObject *obj;
  int i;

  D_ENTER;

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

  /* We need to make sure that the BroSObject at the root has the
   * correct type_id (a SER_xxx value). This depends on the type object
   * so map the type tag of that object to a SER_xxx value:
   */
  if (! val->val_type)
    {
      D(("Val %p doesn't have a type.\n", val));
      D_RETURN_(FALSE);
    }

  type = (BroType *) val->val_type;
  obj  = (BroSObject *) val;

  switch (type->tag)
    {
    case BRO_TYPE_BOOL:
    case BRO_TYPE_INT:
    case BRO_TYPE_COUNT:
    case BRO_TYPE_COUNTER:
    case BRO_TYPE_STRING:
    case BRO_TYPE_DOUBLE:
    case BRO_TYPE_TIME:
      obj->type_id = SER_VAL;
      break;

    case BRO_TYPE_ENUM:
      obj->type_id = SER_ENUM_VAL;
      break;

    case BRO_TYPE_PORT:
      obj->type_id = SER_PORT_VAL;
      break;

    case BRO_TYPE_INTERVAL:
      obj->type_id = SER_INTERVAL_VAL;
      break;

    case BRO_TYPE_IPADDR:
      obj->type_id = SER_ADDR_VAL;
      break;

    case BRO_TYPE_SUBNET:
      obj->type_id = SER_SUBNET_VAL;
      break;

    case BRO_TYPE_RECORD:
      obj->type_id = SER_RECORD_VAL;
      break;

    default:
      D(("Val %p's type unhandled: type tag is %i.\n", val, type->tag));
      D_RETURN_(FALSE);
    }

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

  if (! __bro_sobject_serialize((BroSObject *) val->val_type, bc))
    D_RETURN_(FALSE);

  if (! __bro_buf_write_char(bc->tx_buf, val->val_attrs ? 1 : 0))
    D_RETURN_(FALSE);

  if (val->val_attrs && ! __bro_sobject_serialize((BroSObject *) val->val_attrs, 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 = val->val_port.port_num;

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

	  if (! __bro_buf_write_int64(bc->tx_buf, tmp))
	    D_RETURN_(FALSE);
	}
      else
	{
	  if (! __bro_buf_write_int64(bc->tx_buf, val->val_int64))
	    D_RETURN_(FALSE);
	}
      break;

    case BRO_INTTYPE_DOUBLE:
      if (! __bro_buf_write_double(bc->tx_buf, val->val_double))
	D_RETURN_(FALSE);
      break;

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

    case BRO_INTTYPE_IPADDR:
		if ( __bro_util_is_v4_addr(&val->val_addr) )
			i = 1;
		else
			i = 4;

		if (! __bro_buf_write_int(bc->tx_buf, i))
			D_RETURN_(FALSE);

		for ( i = 4 - i; i < 4; ++i )
			if (! __bro_buf_write_int(bc->tx_buf, htonl(val->val_addr.addr[i])))
				D_RETURN_(FALSE);

		break;

    case BRO_INTTYPE_SUBNET:
		if ( __bro_util_is_v4_addr(&val->val_subnet.sn_net) )
			i = 1;
		else
			i = 4;

		if (! __bro_buf_write_int(bc->tx_buf, i))
			D_RETURN_(FALSE);

		for ( i = 4 - i; i < 4; ++i )
			if (! __bro_buf_write_int(bc->tx_buf,
			                          htonl(val->val_subnet.sn_net.addr[i])))
				D_RETURN_(FALSE);

		if (! __bro_buf_write_int(bc->tx_buf, val->val_subnet.sn_width))
			D_RETURN_(FALSE);

      break;

    case BRO_INTTYPE_OTHER:
      /* That's fine, will be handled in derived classes
       * like __bro_record_val_write().
       */
      break;

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

  D_RETURN_(TRUE);
}