int bvlc_message_decode(bvlc_message_t *message, buffer_t *buf) { uint8_t magic; uint8_t function; int ret = 1 && buffer_read_u8(buf, &magic) && magic == BVLC_MAGIC_BYTE && buffer_read_u8(buf, &function); message->function = function; if(ret) { switch(message->function) { case BVLC_FUNCTION_RESULT: ret = bvlc_result_decode(&message->result, buf); break; case BVLC_FUNCTION_WRITE_BDT: ret = bvlc_write_bdt_decode(&message->write_bdt, buf); break; case BVLC_FUNCTION_READ_BDT: ret = bvlc_read_bdt_decode(&message->read_bdt, buf); break; case BVLC_FUNCTION_READ_BDT_ACK: ret = bvlc_read_bdt_ack_decode(&message->read_bdt_ack, buf); break; case BVLC_FUNCTION_FORWARDED_NPDU: ret = bvlc_forwarded_npdu_decode(&message->forwarded_npdu, buf); break; case BVLC_FUNCTION_REGISTER_FD: ret = bvlc_register_fd_decode(&message->register_fd, buf); break; case BVLC_FUNCTION_READ_FDT: ret = bvlc_read_fdt_decode(&message->read_fdt, buf); break; case BVLC_FUNCTION_READ_FDT_ACK: ret = bvlc_read_fdt_ack_decode(&message->read_fdt_ack, buf); break; case BVLC_FUNCTION_DELETE_FDT_ENTRY: ret = bvlc_delete_fdt_entry_decode(&message->delete_fdt_entry, buf); break; case BVLC_FUNCTION_DISTRIBUTE_BROADCAST: ret = bvlc_distribute_broadcast_decode(&message->distribute_broadcast, buf); break; case BVLC_FUNCTION_ORIGINAL_UNICAST: ret = bvlc_original_unicast_decode(&message->original_unicast, buf); break; case BVLC_FUNCTION_ORIGINAL_BROADCAST: ret = bvlc_original_broadcast_decode(&message->original_broadcast, buf); break; } } return ret; }
int bacdl_connection_receive_msg(bacdl_connection_t *connection, bacdl_msg_t *msg) { int ret = 1; uint8_t magic; uint8_t code; uint16_t length; buffer_t *buf = &connection->rcv_buf; if(read(connection->socket, buf->bytes, 4) < 4) { warn("failed to read initial bytes of bacdl message"); ret = 0; goto done; } ret = 1 && buffer_read_u8(buf, &magic) && magic == BACDL_MAGIC_BYTE && buffer_read_u8(buf, &code) && buffer_read_u16(buf, &length); if(!ret) { warn("failed to read header info from bacdl message"); goto done; } if(read(connection->socket, buf->bytes + 4, length - 4) < length - 4) { warn("failed to read content of a bacdl message"); ret = 0; goto done; } buffer_reset(buf); if(!bacdl_msg_decode(msg, buf)) { warn("failed to decode bacdl message"); ret = 0; goto done; } done: if(!ret) { } buffer_reset(&connection->rcv_buf); return ret; }
static int rdata_apl_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* ATTR_UNUSED(rr)) { int result = 0; buffer_type packet; buffer_create_from( &packet, rdata_atom_data(rdata), rdata_atom_size(rdata)); if (buffer_available(&packet, 4)) { uint16_t address_family = buffer_read_u16(&packet); uint8_t prefix = buffer_read_u8(&packet); uint8_t length = buffer_read_u8(&packet); int negated = length & APL_NEGATION_MASK; int af = -1; length &= APL_LENGTH_MASK; switch (address_family) { case 1: af = AF_INET; break; case 2: af = AF_INET6; break; } if (af != -1 && buffer_available(&packet, length)) { char text_address[1000]; uint8_t address[128]; memset(address, 0, sizeof(address)); buffer_read(&packet, address, length); if (inet_ntop(af, address, text_address, sizeof(text_address))) { buffer_printf(output, "%s%d:%s/%d", negated ? "!" : "", (int) address_family, text_address, (int) prefix); result = 1; } } } return result; }
static int rdata_nsec_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* ATTR_UNUSED(rr)) { size_t saved_position = buffer_position(output); buffer_type packet; int insert_space = 0; buffer_create_from( &packet, rdata_atom_data(rdata), rdata_atom_size(rdata)); while (buffer_available(&packet, 2)) { uint8_t window = buffer_read_u8(&packet); uint8_t bitmap_size = buffer_read_u8(&packet); uint8_t *bitmap = buffer_current(&packet); int i; if (!buffer_available(&packet, bitmap_size)) { buffer_set_position(output, saved_position); return 0; } for (i = 0; i < bitmap_size * 8; ++i) { if (get_bit(bitmap, i)) { buffer_printf(output, "%s%s", insert_space ? " " : "", rrtype_to_string( window * 256 + i)); insert_space = 1; } } buffer_skip(&packet, bitmap_size); } return 1; }
int packet_skip_dname(buffer_type *packet) { while (1) { uint8_t label_size; if (!buffer_available(packet, 1)) return 0; label_size = buffer_read_u8(packet); if (label_size == 0) { return 1; } else if ((label_size & 0xc0) != 0) { if (!buffer_available(packet, 1)) return 0; buffer_skip(packet, 1); return 1; } else if (!buffer_available(packet, label_size)) { return 0; } else { buffer_skip(packet, label_size); } } }
static int rdata_services_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* ATTR_UNUSED(rr)) { int result = 0; buffer_type packet; buffer_create_from( &packet, rdata_atom_data(rdata), rdata_atom_size(rdata)); if (buffer_available(&packet, 1)) { uint8_t protocol_number = buffer_read_u8(&packet); ssize_t bitmap_size = buffer_remaining(&packet); uint8_t *bitmap = buffer_current(&packet); struct protoent *proto = getprotobynumber(protocol_number); if (proto) { int i; buffer_printf(output, "%s", proto->p_name); for (i = 0; i < bitmap_size * 8; ++i) { if (get_bit(bitmap, i)) { struct servent *service = getservbyport((int)htons(i), proto->p_name); if (service) { buffer_printf(output, " %s", service->s_name); } else { buffer_printf(output, " %d", i); } } } buffer_skip(&packet, bitmap_size); result = 1; } } return result; }
static int dns_name_from_wire(buffer_type* data, struct decompress_ctx *decompress, char* text_name) { char *q; u_int8_t *p, label_len; int length, off, saved = -1, i; if (data == NULL || text_name == NULL || decompress == NULL) return -1; p = buffer_current(data); q = text_name; length = 0; label_len = buffer_read_u8(data); if (label_len == 0) { *q = '.'; q++; } while (label_len != 0 && length < NAME_MAX_LENGTH) { if ((label_len & 0xc0) == 0xc0) { buffer_set_position(data, buffer_position(data) - 1); label_len = buffer_read_u16(data); off = label_len & ~0xc0; if (off >= buffer_limit(data) /*|| decompress->pos[off] != off*/) return -1; if (saved == -1) saved = buffer_position(data); buffer_set_position(data, off); label_len = buffer_read_u8(data); } else { if (!buffer_available(data, label_len)) return -1; for (i = 0; i < label_len; i++) { if (decompress->pos[i] == -1) decompress->pos[i] = buffer_position(data); } length += label_len; p = buffer_current(data); memcpy(q, p, label_len); buffer_skip(data, label_len); q += label_len; *q = '.'; q++; label_len = buffer_read_u8(data); } } if (label_len == 0) { *q = '\0'; if (saved > -1) buffer_set_position(data, saved); } else { log_msg("dns:domain not ends with \\0\n"); return -1; } return 0; }
static uint8_t unmarshal_u8(struct buffer* b) { return buffer_read_u8(b); }