/*
 * iSNS protocol definitions
 *
 * Copyright (C) 2007 Olaf Kirch <olaf.kirch@oracle.com>
 */

#ifndef ISNS_PROTO_H
#define ISNS_PROTO_H

#include <stdint.h>

struct isns_hdr {
	uint16_t		i_version;
	uint16_t		i_function;
	uint16_t		i_length;
	uint16_t		i_flags;
	uint16_t		i_xid;
	uint16_t		i_seq;
};

#define ISNS_VERSION		0x0001
#define ISNS_MAX_PDU_SIZE	65535
#define ISNS_DEFAULT_PORT	3205

/*
 * Values for the i_flags field:
 */
#define ISNS_F_CLIENT		0x8000
#define ISNS_F_SERVER		0x4000
#define ISNS_F_AUTHBLK_PRESENT	0x2000
#define ISNS_F_REPLACE		0x1000
#define ISNS_F_LAST_PDU		0x0800
#define ISNS_F_FIRST_PDU	0x0400

/*
 * Function values
 */
enum isns_function {
	ISNS_DEVICE_ATTRIBUTE_REGISTER	= 1,
	ISNS_DEVICE_ATTRIBUTE_QUERY	= 2,
	ISNS_DEVICE_GET_NEXT		= 3,
	ISNS_DEVICE_DEREGISTER		= 4,
	ISNS_SCN_REGISTER		= 5,
	ISNS_SCN_DEREGISTER		= 6,
	ISNS_SCN_EVENT			= 7,
	ISNS_STATE_CHANGE_NOTIFICATION	= 8,
	ISNS_DD_REGISTER		= 9,
	ISNS_DD_DEREGISTER		= 10,
	ISNS_DDS_REGISTER		= 11,
	ISNS_DDS_DEREGISTER		= 12,
	ISNS_ENTITY_STATUS_INQUIRY	= 13,
	ISNS_HEARTBEAT			= 14,
};

/*
 * iSNS status codes:
 */
enum isns_status {
	ISNS_SUCCESS = 0,
	ISNS_UNKNOWN_ERROR,
	ISNS_MESSAGE_FORMAT_ERROR,
	ISNS_INVALID_REGISTRATION,
	__ISNS_RESERVED_STATUS,
	ISNS_INVALID_QUERY,
	ISNS_SOURCE_UNKNOWN,
	ISNS_SOURCE_ABSENT,
	ISNS_SOURCE_UNAUTHORIZED,
	ISNS_NO_SUCH_ENTRY,
	ISNS_VERSION_NOT_SUPPORTED,
	ISNS_INTERNAL_ERROR,
	ISNS_BUSY,
	ISNS_OPTION_NOT_UNDERSTOOD,
	ISNS_INVALID_UPDATE,
	ISNS_MESSAGE_NOT_SUPPORTED,
	ISNS_SCN_EVENT_REJECTED,
	ISNS_SCN_REGISTRATION_REJECTED,
	ISNS_ATTRIBUTE_NOT_IMPLEMENTED,
	ISNS_FC_DOMAIN_ID_NOT_AVAILABLE,
	ISNS_FC_DOMAIN_ID_NOT_ALLOCATED,
	ISNS_ESI_NOT_AVAILABLE,
	ISNS_INVALID_DEREGISTRATION,
	ISNS_REGISTRATION_FEATURE_NOT_SUPPORTED,
};

enum isns_tag {
	ISNS_TAG_DELIMITER		= 0,
	ISNS_TAG_ENTITY_IDENTIFIER	= 1,
	ISNS_TAG_ENTITY_PROTOCOL	= 2,
	ISNS_TAG_MGMT_IP_ADDRESS	= 3,
	ISNS_TAG_TIMESTAMP		= 4,
	ISNS_TAG_PROTOCOL_VERSION_RANGE	= 5,
	ISNS_TAG_REGISTRATION_PERIOD	= 6,
	ISNS_TAG_ENTITY_INDEX		= 7,
	ISNS_TAG_ENTITY_NEXT_INDEX	= 8,
	ISNS_TAG_ENTITY_ISAKMP_PHASE_1	= 11,
	ISNS_TAG_ENTITY_CERTIFICATE	= 12,
	ISNS_TAG_PORTAL_IP_ADDRESS	= 16,
	ISNS_TAG_PORTAL_TCP_UDP_PORT	= 17,
	ISNS_TAG_PORTAL_SYMBOLIC_NAME	= 18,
	ISNS_TAG_ESI_INTERVAL		= 19,
	ISNS_TAG_ESI_PORT		= 20,
	ISNS_TAG_PORTAL_INDEX		= 22,
	ISNS_TAG_SCN_PORT		= 23,
	ISNS_TAG_PORTAL_NEXT_INDEX	= 24,
	ISNS_TAG_PORTAL_SECURITY_BITMAP	= 27,
	ISNS_TAG_PORTAL_ISAKMP_PHASE_1	= 28,
	ISNS_TAG_PORTAL_ISAKMP_PHASE_2	= 29,
	ISNS_TAG_PORTAL_CERTIFICATE	= 31,
	ISNS_TAG_ISCSI_NAME		= 32,
	ISNS_TAG_ISCSI_NODE_TYPE	= 33,
	ISNS_TAG_ISCSI_ALIAS		= 34,
	ISNS_TAG_ISCSI_SCN_BITMAP	= 35,
	ISNS_TAG_ISCSI_NODE_INDEX	= 36,
	ISNS_TAG_WWNN_TOKEN		= 37,
	ISNS_TAG_ISCSI_NODE_NEXT_INDEX	= 38,
	ISNS_TAG_ISCSI_AUTHMETHOD	= 42,
	ISNS_TAG_PG_ISCSI_NAME		= 48,
	ISNS_TAG_PG_PORTAL_IP_ADDR	= 49,
	ISNS_TAG_PG_PORTAL_TCP_UDP_PORT	= 50,
	ISNS_TAG_PG_TAG			= 51,
	ISNS_TAG_PG_INDEX		= 52,
	ISNS_TAG_PG_NEXT_INDEX		= 53,
	ISNS_TAG_FC_PORT_NAME_WWPN	= 64,
	ISNS_TAG_PORT_ID		= 65,
	ISNS_TAG_FC_PORT_TYPE		= 66,
	ISNS_TAG_SYMBOLIC_PORT_NAME	= 67,
	ISNS_TAG_FABRIC_PORT_NAME	= 68,
	ISNS_TAG_HARD_ADDRESS		= 69,
	ISNS_TAG_PORT_IP_ADDRESS	= 70,
	ISNS_TAG_CLASS_OF_SERVICE	= 71,
	ISNS_TAG_FC4_TYPES		= 72,
	ISNS_TAG_FC4_DESCRIPTOR		= 73,
	ISNS_TAG_FC4_FEATURES		= 74,
	ISNS_TAG_IFCP_SCN_BITMAP	= 75,
	ISNS_TAG_PORT_ROLE		= 76,
	ISNS_TAG_PERMANENT_PORT_NAME	= 77,
	ISNS_TAG_FC4_TYPE_CODE		= 95,
	ISNS_TAG_FC_NODE_NAME_WWNN	= 96,
	ISNS_TAG_SYMBOLIC_NODE_NAME	= 97,
	ISNS_TAG_NODE_IP_ADDRESS	= 98,
	ISNS_TAG_NODE_IPA		= 99,
	ISNS_TAG_PROXY_ISCSI_NAME	= 101,
	ISNS_TAG_SWITCH_NAME		= 128,
	ISNS_TAG_PREFERRED_ID		= 129,
	ISNS_TAG_ASSIGNED_ID		= 130,
	ISNS_TAG_VIRTUAL_FABRIC_ID	= 131,
	ISNS_TAG_SERVER_VENDOR_OUI	= 256,
	ISNS_TAG_DD_SET_ID		= 2049,
	ISNS_TAG_DD_SET_SYMBOLIC_NAME	= 2050,
	ISNS_TAG_DD_SET_STATUS		= 2051,
	ISNS_TAG_DD_SET_NEXT_ID		= 2052,
	ISNS_TAG_DD_ID			= 2065,
	ISNS_TAG_DD_SYMBOLIC_NAME	= 2066,
	ISNS_TAG_DD_MEMBER_ISCSI_INDEX	= 2067,
	ISNS_TAG_DD_MEMBER_ISCSI_NAME	= 2068,
	ISNS_TAG_DD_MEMBER_FC_PORT_NAME	= 2069,
	ISNS_TAG_DD_MEMBER_PORTAL_INDEX	= 2070,
	ISNS_TAG_DD_MEMBER_PORTAL_IP_ADDR = 2071,
	ISNS_TAG_DD_MEMBER_PORTAL_TCP_UDP_PORT = 2072,
	ISNS_TAG_DD_FEATURES		= 2078,
	ISNS_TAG_DD_NEXT_ID		= 2079,

	__ISNS_TAG_MAX,

	ISNS_VENDOR_SPECIFIC_SERVER_BASE = 257,		/* end 384 */
	ISNS_VENDOR_SPECIFIC_ENTITY_BASE = 385,		/* end 512 */
	ISNS_VENDOR_SPECIFIC_PORTAL_BASE = 513,		/* end 640 */
	ISNS_VENDOR_SPECIFIC_NODE_BASE	= 641,		/* end 768 */
	ISNS_VENDOR_SPECIFIC_DD_BASE	= 1024,		/* end 1280 */
	ISNS_VENDOR_SPECIFIC_DDSET_BASE = 1281,		/* end 1536 */
	ISNS_VENDOR_SPECIFIC_OTHER_BASE = 1537,		/* end 2048 */
};

typedef enum isns_entity_protocol {
	ISNS_ENTITY_PROTOCOL_NONE = 1,
	ISNS_ENTITY_PROTOCOL_ISCSI = 2,
	ISNS_ENTITY_PROTOCOL_IFCP = 3,
} isns_entity_protocol_t;

enum isns_iscsi_node_type_bits {
	ISNS_ISCSI_NODE_TYPE_TARGET = 0,
	ISNS_ISCSI_NODE_TYPE_INITIATOR = 1,
	ISNS_ISCSI_NODE_TYPE_CONTROL = 2,
};
#define ISNS_ISCSI_INITIATOR_MASK	(1 << ISNS_ISCSI_NODE_TYPE_INITIATOR)
#define ISNS_ISCSI_TARGET_MASK		(1 << ISNS_ISCSI_NODE_TYPE_TARGET)
#define ISNS_ISCSI_CONTROL_MASK		(1 << ISNS_ISCSI_NODE_TYPE_CONTROL)

enum isns_portal_port_bits {
	ISNS_PORTAL_PORT_UDP = 16,
};
#define ISNS_PORTAL_PORT_UDP_MASK	(1 << ISNS_PORTAL_PORT_UDP)

enum isns_portal_security_bits {
	ISNS_PORTAL_SEC_BITMAP_VALID = 0,
	ISNS_PORTAL_SEC_IPSEC_ENABLED = 1,
	ISNS_PORTAL_SEC_MAIN_MODE_ENABLED = 2,
	ISNS_PORTAL_SEC_AGGR_MODE_ENABLED = 3,
	ISNS_PORTAL_SEC_PFS_ENABLED = 4,
	ISNS_PORTAL_SEC_TRANSPORT_MODE_PREFERRED = 5,
	ISNS_PORTAL_SEC_TUNNEL_MODE_PREFERRED = 6,
};
#define ISNS_PORTAL_SEC_BITMAP_VALID_MASK		(1 << ISNS_PORTAL_SEC_BITMAP_VALID)
#define ISNS_PORTAL_SEC_IPSEC_ENABLED_MASK		(1 << ISNS_PORTAL_SEC_IPSEC_ENABLED)
#define ISNS_PORTAL_SEC_MAIN_MODE_ENABLED_MASK		(1 << ISNS_PORTAL_SEC_MAIN_MODE_ENABLED)
#define ISNS_PORTAL_SEC_AGGR_MODE_ENABLED_MASK		(1 << ISNS_PORTAL_SEC_AGGR_MODE_ENABLED)
#define ISNS_PORTAL_SEC_PFS_ENABLED_MASK		(1 << ISNS_PORTAL_SEC_PFS_ENABLED)
#define ISNS_PORTAL_SEC_TRANSPORT_MODE_PREFERRED_MASK	(1 << ISNS_PORTAL_SEC_TRANSPORT_MODE_PREFERRED)
#define ISNS_PORTAL_SEC_TUNNEL_MODE_PREFERRED_MASK	(1 << ISNS_PORTAL_SEC_TUNNEL_MODE_PREFERRED)

enum isns_scn_bits {
	ISNS_SCN_DD_MEMBER_ADDED = 0,
	ISNS_SCN_DD_MEMBER_REMOVED = 1,
	ISNS_SCN_OBJECT_UPDATED = 2,
	ISNS_SCN_OBJECT_ADDED = 3,
	ISNS_SCN_OBJECT_REMOVED = 4,
	ISNS_SCN_MANAGEMENT_REGISTRATION = 5,
	ISNS_SCN_TARGET_AND_SELF_ONLY = 6,
	ISNS_SCN_INITIATOR_AND_SELF_ONLY = 7,
};
#define ISNS_SCN_DD_MEMBER_ADDED_MASK		(1 << ISNS_SCN_DD_MEMBER_ADDED)
#define ISNS_SCN_DD_MEMBER_REMOVED_MASK		(1 << ISNS_SCN_DD_MEMBER_REMOVED)
#define ISNS_SCN_OBJECT_UPDATED_MASK		(1 << ISNS_SCN_OBJECT_UPDATED)
#define ISNS_SCN_OBJECT_ADDED_MASK		(1 << ISNS_SCN_OBJECT_ADDED)
#define ISNS_SCN_OBJECT_REMOVED_MASK		(1 << ISNS_SCN_OBJECT_REMOVED)
#define ISNS_SCN_MANAGEMENT_REGISTRATION_MASK	(1 << ISNS_SCN_MANAGEMENT_REGISTRATION)
#define ISNS_SCN_TARGET_AND_SELF_ONLY_MASK	(1 << ISNS_SCN_TARGET_AND_SELF_ONLY)
#define ISNS_SCN_INITIATOR_AND_SELF_ONLY_MASK	(1 << ISNS_SCN_INITIATOR_AND_SELF_ONLY)

enum isns_dds_status_bits {
	ISNS_DDS_ENABLED = 0,
};
#define ISNS_DDS_ENABLED_MASK			(1 << ISNS_DDS_ENABLED)

enum isns_dd_feature_bits {
	ISNS_DD_BOOT_LIST_ENABLED = 0,
};
#define ISNS_DD_BOOT_LIST_ENABLED_MASK		(1 << ISN_BOOT_LIST_DDS_ENABLED)

#define ISNS_PAD(len)		(((len) + 3) & ~3UL)

/*
 * iSNS auth block
 */
#define ISNS_AUTHBLK_SIZE	20
struct isns_authblk {
	uint32_t		iab_bsd;		/* 16bit in SLP */
	uint32_t		iab_length;		/* 16bit in SLP */
	uint64_t		iab_timestamp;		/* 32bit in SLP */
	uint32_t		iab_spi_len;		/* 16bit in SLP */

	char *			iab_spi;
	void *			iab_sig;
	uint32_t		iab_sig_len;
} __attribute__((packed));

#define ISNS_AUTH_TYPE_SHA1_DSA	0x0002

#endif /* ISNS_PROTO_H */
