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); }
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); }
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); }
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); }
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); }
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); }