/*
 * Copyright (c) 1996-2001 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef	_T6KERNEL_H
#define	_T6KERNEL_H

#pragma ident	"@(#)t6kernel.h	7.8	01/01/10 SMI; TSOL 2.x"

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/tsol/tndb.h>

#ifdef _KERNEL
#include <c2/audit.h>
#else /* !_KERNEL */
#include <bsm/audit.h>
#endif /* _KERNEL */

/*
 * ============================================================
 * Kernel Requests to TOKMAPD
 * ============================================================
 */

#define	KERNEL_MAP_TOKEN_TO_IR	150
#define	KERNEL_MAP_IR_TO_TOKEN	151
#define	KERNEL_GET_INFO		152
#define	KERNEL_MSIX_TOKEN_TO_IR	153
#define	KERNEL_MSIX_IR_TO_TOKEN	154
#define	KERNEL_REQ_MIN		150
#define	KERNEL_REQ_MAX		154

#define	VARIABLE_LENGTH 1

typedef	char nr_t;	/* Network Representation */

/* structures found within kernel requests and responses */

typedef	struct {
	uint16_t attr_type;
	uint16_t pad;	/* for alignment */
	uint32_t mid;
	uint32_t token;
} k_token_t;

typedef struct {
	uint16_t attr_type;
	uint16_t attr_value_length;	 /* must be multiple of 4 */
	uint32_t mid;
	uint32_t token;
	nr_t attr_value[VARIABLE_LENGTH];
} k_attr_t;

/* structures for KERNEL_MAP_TOKEN_TO_IR request and response */

typedef struct {
	uint8_t request_type;	/* = KERNEL_MAP_TOKEN_TO_IR */
	uint32_t hostid;		/* zero if local tokens */
	uint32_t generation;
	uint32_t request_id;
	uint16_t token_count;
	k_token_t tokens[VARIABLE_LENGTH];
} kernel_map_token_request_t;

typedef struct {
	uint8_t request_type;	/*  = KERNEL_MAP_TOKEN_TO_IR */
	uint16_t status; /* satmp status codes are used */
	uint32_t hostid;	/* zero if local tokens */
	uint32_t generation;
	uint16_t attr_count;
	k_attr_t attrs[VARIABLE_LENGTH];
} kernel_map_token_response_t;

/* structures for KERNEL_MAP_IR_TO_TOKEN request and response */

typedef struct {
	uint8_t request_type;	/*  = KERNEL_MAP_IR_TO_TOKEN */
	uint32_t request_id;
	uint32_t hostid;
	uint16_t attr_count;
	k_attr_t attrs[VARIABLE_LENGTH];
} kernel_map_ir_request_t;

typedef struct {
	uint8_t request_type;	/*  = KERNEL_MAP_IR_TO_TOKEN */
	uint16_t status; /* satmp status codes are used */
	uint32_t generation;
	uint16_t token_count;
	k_token_t tokens[VARIABLE_LENGTH];
} kernel_map_ir_response_t;

typedef struct {
	uint8_t request_type;	/* KERNEL_GET_INFO */
	uint32_t hostid;
} kernel_get_info_request_t;

typedef struct {
	uint8_t request_type;	/* KERNEL_GET_INFO */
	uint16_t status;
	uint16_t mask;
} kernel_get_info_response_t;

#define	TSOL_MAP_ATTR_MESSAGE_SIZE	500
#define	TSOL_MAP_TOKEN_MESSAGE_SIZE	500
#define	TSOL_GET_INFO_MESSAGE_SIZE	10

/*
 * T6_DAC_IDS is defined here rather than in t6attrs.h because
 * it is not part of the t6 API.
 */
#define	T6_DAC_IDS	10
#define	T6M_DAC_IDS	t6_mask(T6_DAC_IDS)

enum tokmapd_response {
	OKAY	= 0,
	FAIL	= 1,
	AGAIN	= 2,
	FLUSH	= 3
};

enum map_token_response {
	MAP_TOKEN_OKAY	= 0,
	MAP_TOKEN_FAIL	= 1,
	MAP_TOKEN_AGAIN	= 2,
	NO_MAP_TOKENS	= 3
};

enum tsol_return_status {
	TSOL_OKAY	= 0,
	TSOL_FAIL	= 1,
	TSOL_AGAIN	= 2
};

/* For those times when a pointer to the attribute will do. */
typedef struct {
	uint16_t attr_type;
	uint16_t attr_value_length;	 /* must be multiple of 4 */
	uint32_t token;
	nr_t *attr_value;
} k_attr_with_pointer_t;

/* Format of IDS passed between kernel and tokmapd (from trans.h) */
typedef struct {
	uid_t uid;
	gid_t gid;
	int ngroups;
	gid_t sgid[VARIABLE_LENGTH];
} ids_ir_t;

/* TSIX SAMP Header */
struct t6samp_header {
	uint16_t samp_type;
	uint16_t samp_version;
	uint_t samp_length;
	struct t6samp_attr_spec {
		uint8_t attr_type;
		uint8_t attr_length;
		uint8_t reserved[4];
		uint8_t token_type;
		uint8_t token_generation[3];
		uint16_t token_mask;
		uint_t tokens[VARIABLE_LENGTH];
	} samp_attributes;
};

#define	samp_tokens	samp_attributes.tokens
#define	samp_token_mask	samp_attributes.token_mask

#define	TSIX_ATTR_LENGTH_PULLUP 10
#define	TSIX_ATTR_LENGTH_OFFSET	9
#define	TSIX_TVL_SIZE		8

#define	T6_MIN_SAMP_ATTR_LEN	6
#define	T6_MIN_SAMP_LEN		14
#define	T6_MAX_SAMP_ATTR_LEN	76
#define	T6_MAX_SAMP_LEN		T6_MAX_SAMP_ATTR_LEN + TSIX_TVL_SIZE

#define	T6_ATTR_TYPE		134
#define	T6_TOKEN_TYPE		3

#define	T6_NOMAP_TOKENS		1
#define	T6_MAP_TOKENS		2

#ifdef _KERNEL
/* Attribute-To-Token Cache Entry */
struct tsol_att_entry {
	struct tsol_att_entry *next;
	uint32_t token;
	uint16_t type;
	uint16_t size;
	char attr[VARIABLE_LENGTH];
};

/* Token-To-Attribute Cache Entry */
struct tsol_tok_entry {
	uint32_t token;
	uint16_t type;
	nr_t *attr_value;
};

/* Token-To-Attribute Statistics Structure */
struct tsol_tta_stat {
	uint32_t hits;
	uint32_t misses;
};

/* Token-To-Attribute Info Structure */
struct tsol_tta_entry {
	struct tsol_tta_entry *next;
	uint_t addr;
	uint16_t flags;
	uint16_t attrs_in_common;
	clock_t last_access;
	uint32_t generation;
	uint_t count;
	uint_t token_cache_size;
	struct tsol_tta_stat stat;
	struct tsol_tok_entry *tokens;
};

struct tsol_generation {
	kmutex_t lock;
	uint32_t generation;
};

struct t6_tcp {
	int t6_token_mapping;		/* waiting for reply from tokmapd */
	int t6_samp_offset;		/* offset of next SAMP header */
	struct t6samp_header *t6_samp;	/* pointer to aligned buffer */
	mblk_t *t6_mapping_done;	/* for reassembly of segment data */
	int t6_partial_len;		/* for reassembly of segment data */
	caddr_t t6_interface;		/* pointer to interface template */
	mblk_t *t6_saved_samp_mp;	/* saved local variable */
	int t6_saved_samp_offset;	/* saved local variable */
	int t6_seg_len;			/* saved local variable */
	uint_t t6_flags;		/* saved local variable */
	int t6_isput;			/* saved local variable */
};

extern kmutex_t tsol_tta_cache_lock;

#define	BITSPERBYTE	8

#define	VALID_ATTRS_IN_COMMON_MASK 0x0001

#define	TSOL_ATT_HASH_SIZE	64
#define	TSOL_TTA_HASH_SIZE	64

/*
 * Maximum number of attributes or tokens that can be mapped by tokmapd.
 */
#define	TSOL_MAX_TOKMAPD_COUNT	5

#define	TOKEN_CACHE_INITIAL_SIZE	(64  * sizeof (struct tsol_tok_entry))
#define	TOKEN_CACHE_MAX_SIZE		(256 * sizeof (struct tsol_tok_entry))

#define	TSOL_ATTR_EQUAL(m, e) \
	((m->attr_type == e->type && m->attr_value_length == e->size && \
	(bcmp(m->attr_value, e->attr, e->size) == 0)) ? 1 : 0)

#define	ALL_TSOL_ATTRS (T6M_SL | \
			T6M_IL | \
			T6M_CLEARANCE | \
			T6M_PRIVILEGES | \
			T6M_PID | \
			T6M_UID | \
			T6M_GID | \
			T6M_GROUPS | \
			T6M_PROC_ATTR | \
			T6M_AUDIT_ID | \
			T6M_AUDIT_INFO)

#define	ALL_TSIX_ATTRS (T6M_SL | \
			T6M_IL | \
			T6M_CLEARANCE | \
			T6M_PRIVILEGES | \
			T6M_PID | \
			T6M_DAC_IDS | \
			T6M_PROC_ATTR | \
			T6M_SESSION_ID)

#ifdef TSOL
#ifdef DEBUG

#define	TSOL_TSIX_DEBUG(l, x)	if (tsol_tsix_debug == l) printf x
#define	TSOL_TSIX_XDUMP(l, x)	if (tsol_tsix_debug == l) hexdump x

#else /* !DEBUG */

#define	TSOL_TSIX_DEBUG(l, x)
#define	TSOL_TSIX_XDUMP(l, x)

#endif /* DEBUG */
#endif /* TSOL */

/* Function Prototypes */

void	tsixinit(void);
int	tsol_att_get_token(k_attr_with_pointer_t *);
int	tsol_get_attrs_in_common_mask(void *, uchar_t, uint16_t *);
int	tsol_tta_get_attribute(uint_t, struct tsol_tok_entry *);
int	tsol_bits_in_mask(uint16_t);
int	valid_samp(struct t6samp_header *, uint_t);
int	tsol_valid_samp(mblk_t *);
uint32_t	get_local_generation(void);
void	set_local_generation(uint32_t);
void	tsol2tsix_samp(caddr_t, uint32_t, uint16_t);

enum map_token_response	tsix_samp2tsol(mblk_t *,
	    caddr_t, uint_t, tsol_strattr_t **);

enum tsol_return_status	tsol_tsix_map_attrs(mblk_t *mp, void *ire);

struct tsol_att_entry	**att_hash(uint16_t, uint16_t, char *);
struct tsol_tta_entry	** tta_hash(uint_t);
ids_ir_t	*pack_ids(cred_t *, uint16_t *);
void	unpack_ids(ids_ir_t *, cred_t *);
void	tta_add_from_mblk(k_attr_t *, uint_t);
enum tokmapd_response	valid_map_ir_response(kernel_map_ir_response_t *);
enum tokmapd_response	valid_map_token_response(kernel_map_token_response_t *);
int	flush_tta_cache(queue_t *, uint_t);
int	add_mappings_to_tta_cache(uint_t, kernel_map_token_response_t *);
k_attr_t	*alloc_mapping(uint16_t, tsol_host_type_t);
void	free_mapping(k_attr_t *mapping);
tsol_ip_label_t	tsol_get_option(mblk_t *, uint8_t **);
int	tsol_add_timer(queue_t *, mblk_t *, mblk_t *);
void	tsol_remove_timer(queue_t *, mblk_t *);
void	tsol_remove_all_timers(caddr_t);
int	get_generation(uint_t, uint32_t *);
int	set_generation(uint_t, uint32_t);
void	tta_flush(uint_t);
enum tsol_return_status	tsol_tnfs_map_tokens(struct tsol_tok_entry *, uint_t);
enum tsol_return_status	tsol_tnfs_map_attrs(k_attr_with_pointer_t *);
/*
 * token mapping daemon interfaces
 */
void	tokmap_init(void);
int	tokmap_door(struct vnode *);
int	tokmap_canmap(void);
enum tsol_return_status	tokmap_getmapping(void *, int);
void	*tokmap_message_alloc(int);
void	tokmap_message_free(void *);

#endif /* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _T6KERNEL_H */
