Example #1
0
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);
	}
}
Example #2
0
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);
}
Example #3
0
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);
	}
}