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); }
static int __bro_mutable_val_write(BroMutableVal *mv, BroConn *bc) { D_ENTER; if (! __bro_val_write((BroVal *) mv, bc)) D_RETURN_(FALSE); if (! __bro_buf_write_char(bc->tx_buf, mv->props)) D_RETURN_(FALSE); if (! __bro_buf_write_string(bc->tx_buf, (mv->id ? &mv->id->name : NULL))) D_RETURN_(FALSE); D_RETURN_(TRUE); }
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); }
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); }