static void dissect_nmpi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *nmpi_tree = NULL; proto_item *ti; int offset = 0; guint8 opcode; guint8 nmpi_name_type; char name[(NETBIOS_NAME_LEN - 1)*4 + 1]; int name_type; char node_name[(NETBIOS_NAME_LEN - 1)*4 + 1]; int node_name_type = 0; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NMPI"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { ti = proto_tree_add_item(tree, proto_nmpi, tvb, offset, 68, FALSE); nmpi_tree = proto_item_add_subtree(ti, ett_nmpi); add_routers(nmpi_tree, tvb, offset); } offset += 32; /* * XXX - we don't use "node_name" or "node_name_type". */ opcode = tvb_get_guint8(tvb, offset); nmpi_name_type = tvb_get_guint8(tvb, offset+1); name_type = get_netbios_name(tvb, offset+4, name, (NETBIOS_NAME_LEN - 1)*4 + 1); node_name_type = get_netbios_name(tvb, offset+20, node_name, (NETBIOS_NAME_LEN - 1)*4 + 1); if (check_col(pinfo->cinfo, COL_INFO)) { switch (opcode) { case INAME_CLAIM: col_add_fstr(pinfo->cinfo, COL_INFO, "Claim name %s<%02x>", name, name_type); break; case INAME_DELETE: col_add_fstr(pinfo->cinfo, COL_INFO, "Delete name %s<%02x>", name, name_type); break; case INAME_QUERY: col_add_fstr(pinfo->cinfo, COL_INFO, "Query name %s<%02x>", name, name_type); break; case INAME_FOUND: col_add_fstr(pinfo->cinfo, COL_INFO, "Name %s<%02x> found", name, name_type); break; case IMSG_HANGUP: col_add_fstr(pinfo->cinfo, COL_INFO, "Messenger hangup on %s<%02x>", name, name_type); break; case IMSLOT_SEND: col_add_fstr(pinfo->cinfo, COL_INFO, "Mailslot write to %s<%02x>", name, name_type); break; case IMSLOT_FIND: col_add_fstr(pinfo->cinfo, COL_INFO, "Find mailslot name %s<%02x>", name, name_type); break; case IMSLOT_NAME: col_add_fstr(pinfo->cinfo, COL_INFO, "Mailslot name %s<%02x> found", name, name_type); break; default: col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown NMPI op 0x%02x: name %s<%02x>", opcode, name, name_type); break; } } if (tree) { proto_tree_add_text(nmpi_tree, tvb, offset, 1, "Opcode: %s (0x%02x)", val_to_str(opcode, nmpi_opcode_vals, "Unknown"), opcode); proto_tree_add_text(nmpi_tree, tvb, offset+1, 1, "Name Type: %s (0x%02x)", val_to_str(nmpi_name_type, nmpi_name_type_vals, "Unknown"), nmpi_name_type); proto_tree_add_text(nmpi_tree, tvb, offset+2, 2, "Message ID: 0x%04x", tvb_get_letohs(tvb, offset+2)); netbios_add_name("Requested name", tvb, offset+4, nmpi_tree); netbios_add_name("Source name", tvb, offset+20, nmpi_tree); } offset += 1 + 1 + 2 + NETBIOS_NAME_LEN + NETBIOS_NAME_LEN; if (opcode == IMSLOT_SEND && tvb_offset_exists(tvb, offset)) { next_tvb = tvb_new_subset_remaining(tvb, offset); dissect_netbios_payload(next_tvb, pinfo, tree); } }
static int dissect_nbipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { gboolean has_routes; proto_tree *nbipx_tree = NULL; proto_item *ti = NULL; int offset = 0; guint8 packet_type; proto_tree *name_type_flag_tree; proto_item *tf; char name[(NETBIOS_NAME_LEN - 1)*4 + 1]; int name_type; gboolean has_payload; tvbuff_t *next_tvb; ipxhdr_t *ipxh; /* Reject the packet if data is NULL */ if (data == NULL) return 0; ipxh = (ipxhdr_t*)data; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBIPX"); col_clear(pinfo->cinfo, COL_INFO); if (ipxh->ipx_type == IPX_PACKET_TYPE_WANBCAST) { /* * This is a WAN Broadcast packet; we assume it will have * 8 IPX addresses at the beginning. */ has_routes = TRUE; } else { /* * This isn't a WAN Broadcast packet, but it still might * have the 8 addresses. * * If it's the right length for a name operation, * and, if we assume it has routes, the packet type * is a name operation, assume it has routes. * * NOTE: this will throw an exception if the byte that * would be the packet type byte if this has the 8 * addresses isn't present; if that's the case, we don't * know how to interpret this packet, so we can't dissect * it anyway. */ has_routes = FALSE; /* start out assuming it doesn't */ if (tvb_reported_length(tvb) == 50) { packet_type = tvb_get_guint8(tvb, offset + 32 + 1); switch (packet_type) { case NBIPX_FIND_NAME: case NBIPX_NAME_RECOGNIZED: case NBIPX_CHECK_NAME: case NBIPX_NAME_IN_USE: case NBIPX_DEREGISTER_NAME: has_routes = TRUE; break; } } } if (tree) { ti = proto_tree_add_item(tree, proto_nbipx, tvb, 0, -1, ENC_NA); nbipx_tree = proto_item_add_subtree(ti, ett_nbipx); } if (has_routes) { if (tree) add_routers(nbipx_tree, tvb, 0); offset += 32; } packet_type = tvb_get_guint8(tvb, offset + 1); switch (packet_type) { case NBIPX_FIND_NAME: case NBIPX_NAME_RECOGNIZED: case NBIPX_CHECK_NAME: case NBIPX_NAME_IN_USE: case NBIPX_DEREGISTER_NAME: name_type = get_netbios_name(tvb, offset+2, name, (NETBIOS_NAME_LEN - 1)*4 + 1); col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s<%02x>", val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown"), name, name_type); if (nbipx_tree) { tf = proto_tree_add_item(nbipx_tree, hf_nbipx_name_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN); name_type_flag_tree = proto_item_add_subtree(tf, ett_nbipx_name_type_flags); proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_group, tvb, offset, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_in_use, tvb, offset, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_registered, tvb, offset, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_duplicated, tvb, offset, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_deregistered, tvb, offset, 1, ENC_LITTLE_ENDIAN); } offset += 1; proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type); offset += 1; if (nbipx_tree) netbios_add_name("Name", tvb, offset, nbipx_tree); offset += NETBIOS_NAME_LEN; /* * No payload to be interpreted by another protocol. */ has_payload = FALSE; break; case NBIPX_SESSION_DATA: case NBIPX_SESSION_END: case NBIPX_SESSION_END_ACK: col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown")); dissect_conn_control(tvb, offset, nbipx_tree); offset += 1; proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type); offset += 1; proto_tree_add_item(nbipx_tree, hf_nbipx_session_src_conn_id, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(nbipx_tree, hf_nbipx_session_dest_conn_id, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(nbipx_tree, hf_nbipx_session_send_seq_number, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(nbipx_tree, hf_nbipx_session_total_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(nbipx_tree, hf_nbipx_session_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(nbipx_tree, hf_nbipx_session_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(nbipx_tree, hf_nbipx_session_recv_seq_number, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(nbipx_tree, hf_nbipx_session_bytes_received, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; /* * We may have payload to dissect. */ has_payload = TRUE; break; case NBIPX_DIRECTED_DATAGRAM: col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown")); dissect_conn_control(tvb, offset, nbipx_tree); offset += 1; proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type); offset += 1; if (nbipx_tree) netbios_add_name("Receiver's Name", tvb, offset, nbipx_tree); offset += NETBIOS_NAME_LEN; if (nbipx_tree) netbios_add_name("Sender's Name", tvb, offset, nbipx_tree); offset += NETBIOS_NAME_LEN; /* * We may have payload to dissect. */ has_payload = TRUE; break; default: col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown")); /* * We don't know what the first byte is. */ offset += 1; /* * The second byte is a data stream type byte. */ proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type); offset += 1; /* * We don't know what the rest of the packet is. */ has_payload = FALSE; } /* * Set the length of the NBIPX tree item. */ if (ti != NULL) proto_item_set_len(ti, offset); if (has_payload && tvb_offset_exists(tvb, offset)) { next_tvb = tvb_new_subset_remaining(tvb, offset); dissect_netbios_payload(next_tvb, pinfo, tree); } return tvb_captured_length(tvb); }
static void dissect_nbipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gboolean has_routes; proto_tree *nbipx_tree = NULL; proto_item *ti = NULL; int offset = 0; guint8 packet_type; guint8 name_type_flag; proto_tree *name_type_flag_tree; proto_item *tf; char name[(NETBIOS_NAME_LEN - 1)*4 + 1]; int name_type; gboolean has_payload; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBIPX"); col_clear(pinfo->cinfo, COL_INFO); if (pinfo->ipxptype == IPX_PACKET_TYPE_WANBCAST) { /* * This is a WAN Broadcast packet; we assume it will have * 8 IPX addresses at the beginning. */ has_routes = TRUE; } else { /* * This isn't a WAN Broadcast packet, but it still might * have the 8 addresses. * * If it's the right length for a name operation, * and, if we assume it has routes, the packet type * is a name operation, assume it has routes. * * NOTE: this will throw an exception if the byte that * would be the packet type byte if this has the 8 * addresses isn't present; if that's the case, we don't * know how to interpret this packet, so we can't dissect * it anyway. */ has_routes = FALSE; /* start out assuming it doesn't */ if (tvb_reported_length(tvb) == 50) { packet_type = tvb_get_guint8(tvb, offset + 32 + 1); switch (packet_type) { case NBIPX_FIND_NAME: case NBIPX_NAME_RECOGNIZED: case NBIPX_CHECK_NAME: case NBIPX_NAME_IN_USE: case NBIPX_DEREGISTER_NAME: has_routes = TRUE; break; } } } if (tree) { ti = proto_tree_add_item(tree, proto_nbipx, tvb, 0, -1, FALSE); nbipx_tree = proto_item_add_subtree(ti, ett_nbipx); } if (has_routes) { if (tree) add_routers(nbipx_tree, tvb, 0); offset += 32; } packet_type = tvb_get_guint8(tvb, offset + 1); switch (packet_type) { case NBIPX_FIND_NAME: case NBIPX_NAME_RECOGNIZED: case NBIPX_CHECK_NAME: case NBIPX_NAME_IN_USE: case NBIPX_DEREGISTER_NAME: name_type_flag = tvb_get_guint8(tvb, offset); name_type = get_netbios_name(tvb, offset+2, name, (NETBIOS_NAME_LEN - 1)*4 + 1); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s<%02x>", val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"), name, name_type); } if (nbipx_tree) { tf = proto_tree_add_text(nbipx_tree, tvb, offset, 1, "Name type flag: 0x%02x", name_type_flag); name_type_flag_tree = proto_item_add_subtree(tf, ett_nbipx_name_type_flags); proto_tree_add_text(name_type_flag_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(name_type_flag, 0x80, 8, "Group name", "Unique name")); proto_tree_add_text(name_type_flag_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(name_type_flag, 0x40, 8, "Name in use", "Name not used")); proto_tree_add_text(name_type_flag_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(name_type_flag, 0x04, 8, "Name registered", "Name not registered")); proto_tree_add_text(name_type_flag_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(name_type_flag, 0x02, 8, "Name duplicated", "Name not duplicated")); proto_tree_add_text(name_type_flag_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(name_type_flag, 0x01, 8, "Name deregistered", "Name not deregistered")); } offset += 1; dissect_packet_type(tvb, offset, packet_type, nbipx_tree); offset += 1; if (nbipx_tree) netbios_add_name("Name", tvb, offset, nbipx_tree); offset += NETBIOS_NAME_LEN; /* * No payload to be interpreted by another protocol. */ has_payload = FALSE; break; case NBIPX_SESSION_DATA: case NBIPX_SESSION_END: case NBIPX_SESSION_END_ACK: if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown")); } dissect_conn_control(tvb, offset, nbipx_tree); offset += 1; dissect_packet_type(tvb, offset, packet_type, nbipx_tree); offset += 1; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Source connection ID: 0x%04X", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Destination connection ID: 0x%04X", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Send sequence number: %u", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Total data length: %u", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Offset: %u", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Data length: %u", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Receive sequence number: %u", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Bytes received: %u", tvb_get_letohs(tvb, offset)); } offset += 2; /* * We may have payload to dissect. */ has_payload = TRUE; break; case NBIPX_DIRECTED_DATAGRAM: if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown")); } dissect_conn_control(tvb, offset, nbipx_tree); offset += 1; dissect_packet_type(tvb, offset, packet_type, nbipx_tree); offset += 1; if (nbipx_tree) netbios_add_name("Receiver's Name", tvb, offset, nbipx_tree); offset += NETBIOS_NAME_LEN; if (nbipx_tree) netbios_add_name("Sender's Name", tvb, offset, nbipx_tree); offset += NETBIOS_NAME_LEN; /* * We may have payload to dissect. */ has_payload = TRUE; break; default: if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown")); } /* * We don't know what the first byte is. */ offset += 1; /* * The second byte is a data stream type byte. */ dissect_packet_type(tvb, offset, packet_type, nbipx_tree); offset += 1; /* * We don't know what the rest of the packet is. */ has_payload = FALSE; } /* * Set the length of the NBIPX tree item. */ if (ti != NULL) proto_item_set_len(ti, offset); if (has_payload && tvb_offset_exists(tvb, offset)) { next_tvb = tvb_new_subset_remaining(tvb, offset); dissect_netbios_payload(next_tvb, pinfo, tree); } }