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

#ifndef	_SYS_TSOL_TNDB_H
#define	_SYS_TSOL_TNDB_H

#pragma ident	"@(#)tndb.h	7.29	01/05/02 SMI; TSOL 2.x"

#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/socket.h>
#include <sys/tiuser.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/route.h>
#ifdef _KERNEL
#include <c2/audit.h>
#else /* !_KERNEL */
#include <bsm/audit.h>
#endif /* _KERNEL */
#include <sys/tsol/priv.h>
#include <sys/tsol/label.h>

#ifndef _KERNEL
#include <stdio.h>
#endif /* _KERNEL */

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Network Port Type
 */
typedef enum tsol_ptype {
	UNTYPED = 0,	/* untyped port */
	SLP = 1,	/* single-level port */
	MLP = 2		/* multi-level port */
} tsol_ptype_t;

typedef union tnaddr_in {
	struct in_addr		in_addr_v4;
	struct in6_addr		in_addr_v6;
} tnaddr_in_t;

typedef union tnaddr {
	struct sockaddr_in	ip_addr_v4;
	struct sockaddr_in6	ip_addr_v6;
	struct {
		uint32_t	ta_alen;	/* length of abuf */
		char		*ta_abuf;	/* the addr itself */
	} tl_addr;
} tnaddr_t;

typedef union {
	uchar_t d_un_c[4];
	uint32_t d_un_i;
} tsol_doi_t;

#define	ta_family	ip_addr_v4.sin_family
#define	ta_addr_v4	ip_addr_v4.sin_addr
#define	ta_addr_v6	ip_addr_v6.sin6_addr
#define	ta_port_v4	ip_addr_v4.sin_port
#define	ta_port_v6	ip_addr_v6.sin6_port

#define	TNADDR_EQ(addr1, addr2) \
	(((addr1)->ta_family == AF_INET && (addr2)->ta_family == AF_INET && \
	(addr1)->ta_addr_v4.s_addr == (addr2)->ta_addr_v4.s_addr) || \
	((addr1)->ta_family == AF_INET6 && (addr2)->ta_family == AF_INET6 && \
	IN6_ARE_ADDR_EQUAL(&(addr1)->ta_addr_v6, &(addr2)->ta_addr_v6)))

#define	TNADDR_ALL_EQ(addr1, addr2) \
	(((addr1)->ta_family == AF_INET && (addr2)->ta_family == AF_INET && \
	(addr1)->ta_addr_v4.s_addr == (addr2)->ta_addr_v4.s_addr && \
	(addr1)->ta_port_v4 == (addr2)->ta_port_v4) || \
	((addr1)->ta_family == AF_INET6 && (addr2)->ta_family == AF_INET6 && \
	IN6_ARE_ADDR_EQUAL(&(addr1)->ta_addr_v6, &(addr2)->ta_addr_v6) && \
	(addr1)->ta_port_v6 == (addr2)->ta_port_v6))

#define	IRE_TNADDR_EQ(ire, addr) \
	(((ire)->ire_ipversion == IPV4_VERSION && (addr)->ta_family == \
	AF_INET && \
	(ire)->ire_addr == (addr)->ta_addr_v4.s_addr) || \
	((ire)->ire_ipversion == AF_INET6 && (addr)->ta_family == AF_INET6 && \
	IN6_ARE_ADDR_EQUAL(&(ire)->ire_addr_v6, &(addr)->ta_addr_v6)))

#ifdef _BIG_ENDIAN
#define	DOI_EQUAL(d1, d2) \
	((d1)[0] == (d2)[0] && \
	(d1)[1] == (d2)[1] && \
	(d1)[2] == (d2)[2] && \
	(d1)[3] == (d2)[3])
#else /* _BIG_ENDIAN */
#define	DOI_EQUAL(d1, d2) \
	((d1)[0] == (d2)[3] && \
	(d1)[1] == (d2)[2] && \
	(d1)[2] == (d2)[1] && \
	(d1)[3] == (d2)[0])
#endif /* _BIG_ENDIAN */

/*
 * structure for TN database access routines and TN system calls
 */

/*
 * For tntime access library routine: tsol_gettimebyname()
 */
typedef struct tsol_timeent {
	char		db_name[6]; /* tnrhtp or tnrhdb */
	time_t		last_mod_time; /* last modification time */
} tsol_timeent_t;

/*
 * For tnidb access library routines and tnif(2TSOl)
 */

typedef struct tsol_ifent {
	char		name[IFNAMSIZ];	/* interface name */
	brange_t	sl_range;	/* sensitivity label min/man range */
	bclabel_t	def_label;	/* default label */
	bclear_t	def_cl;		/* default clearance */
	priv_set_t	forced_priv;	/* default effective privileges */
} tsol_ifent_t;

typedef enum tsol_dbops {
	TNDB_NOOP = 0,
	TNDB_LOAD = 1,
	TNDB_DELETE = 2,
	RELOAD_BEGIN = 3,
	RELOAD_END = 4,
	TNDB_GET = 5,
	BCAST_ADD = 6,
	BCAST_DEL = 7,
	TNDB_DOOR = 8
} tsol_dbops_t;

#define	TNTNAMSIZ 	32	/* template name size */
#define	IP_STR_SIZE 	200	/* string ip address size */

/*
 * For tnrhdb access library routines and tnrh(2TSOL)
 */
typedef struct tsol_rhent {
	struct netbuf addr; 		/* address */
	char template_name[TNTNAMSIZ];	/* template name */
	short prefix_len;
} tsol_rhent_t;

#ifdef _SYSCALL32
/*
 * This is an ILP32 tsol_rhent data structure used when a LP64 kernel
 * receives tsol_rhent data structure from a 32-bit program.
 */
typedef struct tsol_rhent32 {
	struct netbuf32 addr;		/* address */
	char template_name[TNTNAMSIZ];	/* template name */
	short prefix_len;
} tsol_rhent32_t;
#endif /* _SYSCALL32 */

/*
 * host types recognized by tsol hosts
 */
typedef enum {
	UNLABELED	= 1,
	SUN_TSOL	= 2,
	SUN_RIPSO	= 3,
	SUN_CIPSO	= 4,
	SUN_TSIX	= 5,
	SUN_MSIX	= 6
} tsol_host_type_t;

typedef enum {
	OPT_NONE	= 0,
	OPT_RIPSO	= 1,
	OPT_CIPSO	= 2
} tsol_ip_label_t;

/*
 * template types
 */
typedef enum {
	TMPL_NORMAL	= 0,
	TMPL_INTERNAL	= 1
} tmpl_type_t;

/*
 * system call chstate op types
 */
typedef enum {
	STATE_UNLABELED	= 1,
	STATE_LABELED	= 2
} tsol_chstateop_t;

/*
 * SRI AND operation result
 */
typedef enum {
	SRI_AND_FAIL = -1,
	SRI_AND_OK = 0,
	SRI_AND_NULL = 1
} sri_and_status;

typedef struct ripso_option {
	uchar_t	ripso_type;		/* Type of option (130) */
	uchar_t	ripso_length;		/* Length of option */
	uchar_t	ripso_class;		/* Classification Level */
	uchar_t	ripso_prot_auth[1];	/* Protection Authority Flags */
} ripso_option_t;

typedef struct cipso_tag_type_1 {
	uchar_t	tag_type;		/* Tag Type (1) */
	uchar_t	tag_length;		/* Length of Tag */
	uchar_t	tag_align;		/* Alignment Octet */
	uchar_t	tag_sl;			/* Sensitivity Level */
	uchar_t	tag_cat[1];		/* Categories */
} cipso_tag_type_1_t;

#define	IP_MAX_OPT_LENGTH 40

#define	TSOL_CIPSO_MIN_LENGTH 6
#define	TSOL_CIPSO_MAX_LENGTH 40
#define	TSOL_TT1_MIN_LENGTH 4
#define	TSOL_TT1_MAX_LENGTH 34

#define	TSOL_CIPSO_DOI_OFFSET 2
#define	TSOL_CIPSO_TAG_OFFSET 6
#define	TSOL_RIPSO_LABEL_OFFSET 2

#define	TSOL_RIPSO_MIN_LENGTH 3
#define	TSOL_RIPSO_MAX_LENGTH 40
#define	TSOL_RIPSO_MAX_PAF_LENGTH 37

#define	IP_OPTION_REQUIRED(t) \
	((t)->host_type == SUN_RIPSO || (t)->host_type == SUN_CIPSO)

typedef struct cipso_option {
	uchar_t	cipso_type;		/* Type of option (134) */
	uchar_t	cipso_length;		/* Length of option */
	uchar_t	cipso_doi[4];		/* Domain of Interpretation */
	uchar_t	cipso_tag_type[1];	/* variable length */
} cipso_option_t;

#define	PAF_BYTES	4

/*
 * RIPSO - BSO only
 */
typedef struct tsol_ripso_bso {
	uchar_t ripso_class;
	uchar_t prot_auth[PAF_BYTES]; /* variable length */
} ripso_label_t;

typedef uchar_t ripso_error_t;

/*
 * RIPSO classifications
 */
#define	TSOL_CL_TOP_SECRET 0x3d
#define	TSOL_CL_SECRET 0x5a
#define	TSOL_CL_CONFIDENTIAL 0x96
#define	TSOL_CL_UNCLASSIFIED 0xab

/*
 * RIPSO protection authorities
 */
#define	TSOL_PA_GENSER 0x80
#define	TSOL_PA_SIOP_ESI 0x40
#define	TSOL_PA_SCI 0x20
#define	TSOL_PA_NSA 0x10
#define	TSOL_PA_DOE 0x08

/*
 * this mask is only used for tndb structures, and is different
 * from t6mask_t bits definitions
 */
typedef unsigned int tnmask_t;

/*
 * unlabeled host structure for the tnrhtp template
 */
struct tsol_unl {
	tnmask_t mask; /* tells which attributes are returned by the library */
	bclabel_t def_label;	/* default label */
	bclear_t def_cl;	/* default clearance */
	priv_set_t forced_priv;	/* forced effective privileges */
	brange_t gw_sl_range;	/* for routing only */
	tsol_ip_label_t ip_label; /* packet relabeling */
	ripso_label_t ripso_label; /* RIPSO label */
	ripso_error_t ripso_error[PAF_BYTES]; /* variable length */
};
#ifdef _SYSCALL32
/*
 * This is an ILP32 tsol_unl data structure used when a LP64 kernel
 * receives tsol_unl data structure from a 32-bit program.
 */
struct tsol_unl32 {
	tnmask_t mask; /* tells which attributes are returned by the library */
	bclabel_t def_label;	/* default label */
	bclear_t def_cl;	/* default clearance */
	priv_set_t forced_priv;	/* forced effective privileges */
	brange_t gw_sl_range;	/* for routing only */
	tsol_ip_label_t ip_label; /* packet relabeling */
	ripso_label_t ripso_label; /* RIPSO label */
	ripso_error_t ripso_error[PAF_BYTES]; /* variable length */
};
#endif /* _SYSCALL32 */

/*
 * sun_tsol host structure for the tnrhtp template
 */
struct tsol_tsol {
	tnmask_t mask; /* tells which attributes are returned by the library */
	brange_t sl_range;	/* min/max SL range */
	priv_set_t allowed_priv; /* privileges allowed by the host */
	tsol_ip_label_t ip_label; /* tells which (or no) IP labeling is used */
	ripso_label_t ripso_label; /* RIPSO label */
	ripso_error_t ripso_error[PAF_BYTES]; /* variable length */
};
#ifdef _SYSCALL32
/*
 * This is an ILP32 tsol_tsol data structure used when a LP64 kernel
 * receives tsol_tsol data structure from a 32-bit program.
 */
struct tsol_tsol32 {
	tnmask_t mask; /* tells which attributes are returned by the library */
	brange_t sl_range;	/* min/max SL range */
	priv_set_t allowed_priv; /* privileges allowed by the host */
	tsol_ip_label_t ip_label; /* tells which (or no) IP labeling is used */
	ripso_label_t ripso_label; /* RIPSO label */
	ripso_error_t ripso_error[PAF_BYTES]; /* variable length */
};
#endif /* _SYSCALL32 */

/*
 * RIPSO host structure for the tnrhtp template
 */
struct tsol_ripso {
	tnmask_t mask; /* tells which attributes are returned by the library */
	bclabel_t def_label;	/* default label */
	bclear_t def_cl;	/* default clearance */
	priv_set_t forced_priv;	/* forced effective privileges */
	ripso_label_t ripso_label; /* RIPSO label */
	ripso_error_t ripso_error[PAF_BYTES]; /* variable length */
	brange_t gw_sl_range;	/* for routing only */
};
#ifdef _SYSCALL32
/*
 * This is an ILP32 tsol_ripso data structure used when a LP64 kernel
 * receives tsol_ripso data structure from a 32-bit program.
 */
struct tsol_ripso32 {
	tnmask_t mask; /* tells which attributes are returned by the library */
	bclabel_t def_label;	/* default label */
	bclear_t def_cl;	/* default clearance */
	priv_set_t forced_priv;	/* forced effective privileges */
	ripso_label_t ripso_label; /* RIPSO label */
	ripso_error_t ripso_error[PAF_BYTES]; /* variable length */
	brange_t gw_sl_range;	/* for routing only */
};
#endif /* _SYSCALL32 */

/*
 * CIPSO host structure for the tnrhtp template
 */
struct tsol_cipso {
	tnmask_t mask; /* tells which attributes are returned by the library */
	bclear_t def_cl;	/* default clearance */
	priv_set_t forced_priv;	/* forced effective privileges */
	brange_t sl_range;	/* min/max SL range */
};
#ifdef _SYSCALL32
/*
 * This is an ILP32 tsol_cipso data structure used when a LP64 kernel
 * receives tsol_cipso data structure from a 32-bit program.
 */
struct tsol_cipso32 {
	tnmask_t mask; /* tells which attributes are returned by the library */
	bclear_t def_cl;	/* default clearance */
	priv_set_t forced_priv;	/* forced effective privileges */
	brange_t sl_range;	/* min/max SL range */
};
#endif /* _SYSCALL32 */

/*
 * TSIX host structure for the tnrhtp template
 */
struct tsol_tsix {
	tnmask_t mask; /* tells which attributes are returned by the library */
	brange_t sl_range;	/* min/max SL range */
	priv_set_t allowed_priv; /* privileges allowed by the host */
	priv_set_t forced_priv;	/* forced effective privileges */
	bclabel_t def_label;	/* default label */
	bclear_t def_cl;	/* default clearance */
	tsol_ip_label_t ip_label; /* tells which (or no) IP labeling is used */
	ripso_label_t ripso_label; /* RIPSO label */
	ripso_error_t ripso_error[PAF_BYTES]; /* variable length */
};
#ifdef _SYSCALL32
/*
 * This is an ILP32 tsol_tsix data structure used when a LP64 kernel
 * receives tsol_tsix data structure from a 32-bit program.
 */
struct tsol_tsix32 {
	tnmask_t mask; /* tells which attributes are returned by the library */
	brange_t sl_range;	/* min/max SL range */
	priv_set_t allowed_priv; /* privileges allowed by the host */
	priv_set_t forced_priv;	/* forced effective privileges */
	bclabel_t def_label;	/* default label */
	bclear_t def_cl;	/* default clearance */
	tsol_ip_label_t ip_label; /* tells which (or no) IP labeling is used */
	ripso_label_t ripso_label; /* RIPSO label */
	ripso_error_t ripso_error[PAF_BYTES]; /* variable length */
};
#endif /* _SYSCALL32 */

/*
 * For tnrhtp access library routines and tnrhtp(2TSOL)
 */
typedef struct tsol_tpent {
	char name[TNTNAMSIZ]; /* template name */
	tsol_host_type_t host_type; /* specifies host type */
	tmpl_type_t tmpl_type; /* template type: TMPL_NORMAL or TMPL_INTERNAL */
	int tp_doi;		/* Domain of Interpretation */
#define	tp_cipso_doi_unl	tp_doi
#define	tp_cipso_doi		tp_doi
#define	tp_cipso_doi_cipso	tp_doi
#define	tp_cipso_doi_tsix	tp_doi
	union {
		struct tsol_unl unl; /* template for unlabeled */
#define	tp_mask_unl		un.unl.mask
#define	tp_def_label		un.unl.def_label
#define	tp_def_cl		un.unl.def_cl
#define	tp_forced_priv		un.unl.forced_priv
#define	tp_gw_sl_range		un.unl.gw_sl_range
#define	tp_ip_label_unl		un.unl.ip_label
#define	tp_ripso_label_unl	un.unl.ripso_label
#define	tp_ripso_error_unl	un.unl.ripso_error
		struct tsol_tsol tsol; /* template for sun_tsol */
#define	tp_mask_tsol		un.tsol.mask
#define	tp_sl_range_tsol	un.tsol.sl_range
#define	tp_allowed_priv		un.tsol.allowed_priv
#define	tp_ip_label		un.tsol.ip_label
#define	tp_ripso_label		un.tsol.ripso_label
#define	tp_ripso_error		un.tsol.ripso_error
		struct tsol_ripso ripso; /* template for RIPSO */
#define	tp_mask_ripso		un.ripso.mask
#define	tp_def_label_ripso	un.ripso.def_label
#define	tp_def_cl_ripso		un.ripso.def_cl
#define	tp_forced_priv_ripso	un.ripso.forced_priv
#define	tp_ripso_label_ripso	un.ripso.ripso_label
#define	tp_ripso_error_ripso	un.ripso.ripso_error
#define	tp_gw_sl_range_ripso	un.ripso.gw_sl_range
		struct tsol_cipso cipso; /* template for CIPSO */
#define	tp_mask_cipso		un.cipso.mask
#define	tp_def_cl_cipso		un.cipso.def_cl
#define	tp_forced_priv_cipso	un.cipso.forced_priv
#define	tp_sl_range_cipso	un.cipso.sl_range
		struct tsol_tsix tsix; /* template for TSIX */
#define	tp_mask_tsix		un.tsix.mask
#define	tp_sl_range_tsix	un.tsix.sl_range
#define	tp_allowed_priv_tsix	un.tsix.allowed_priv
#define	tp_forced_priv_tsix	un.tsix.forced_priv
#define	tp_ip_label_tsix	un.tsix.ip_label
#define	tp_ripso_label_tsix	un.tsix.ripso_label
#define	tp_ripso_error_tsix	un.tsix.ripso_error
#define	tp_def_label_tsix	un.tsix.def_label
#define	tp_def_cl_tsix		un.tsix.def_cl
	} un;
} tsol_tpent_t;
#ifdef _SYSCALL32
/*
 * This is an ILP32 tsol_tpent data structure used when a LP64 kernel
 * receives tsol_tpent data structure from a 32-bit program.
 */
typedef struct tsol_tpent32 {
	char name[TNTNAMSIZ]; /* template name */
	tsol_host_type_t host_type; /* specifies host type */
	tmpl_type_t tmpl_type; /* template type: TMPL_NORMAL or TMPL_INTERNAL */
	int tp_doi;		/* Domain of Interpretation */
	union {
		struct tsol_unl32 unl; /* template for unlabeled */
		struct tsol_tsol32 tsol; /* template for sun_tsol */
		struct tsol_ripso32 ripso; /* template for RIPSO */
		struct tsol_cipso32 cipso; /* template for CIPSO */
		struct tsol_tsix32 tsix; /* template for TSIX */
	} un;
} tsol_tpent32_t;
#endif /* _SYSCALL32 */

typedef enum accred_flag {
	CHECK_NONE = 0,			/* make no check */
	CHECK_ACCRED = 1,		/* make accreditation check */
	CHECK_GATEWAY = 2,
	CHECK_DISKLESS = 4		/* make PAF_DISKLESS_BOOT check */
} accred_flag_t;

typedef struct tsol_ifc {
	struct tsol_ifc 	*ifc_next;	/* link to next entry */
	kmutex_t		ifc_lock;	/* lock for structure */
	accred_flag_t		ifc_flag;	/* bypass or check */
	struct tsol_ifent	ifc_tnif;	/* tnidb info */
} tsol_ifc_t;

typedef struct tsol_tpc {
	struct tsol_tpc 	*tpc_next;	/* link to next entry */
	kmutex_t		tpc_lock;	/* lock for structure */
	struct tsol_tpent	tpc_tp;		/* template */
} tsol_tpc_t;

typedef struct tsol_tnrhc {
	struct tsol_tnrhc 	*rhc_next;	/* link to next entry */
	kmutex_t		rhc_lock;	/* lock for structure */
	tnaddr_t		rhc_host;	/* IPv4/IPv6 host address */
	tsol_tpent_t		*rhc_tp;	/* pointer to template */
	accred_flag_t		rhc_flag;	/* bypass or check */
	int			rhc_refcnt;	/* Number of references */
	char			rhc_invalid;	/* out-of-date rhc */
	char			rhc_isbcast;	/* broadcast address */
	char			rhc_local;	/* loopback or local interace */
} tsol_tnrhc_t;

#ifdef	_KERNEL
#define	TNRHC_HOLD(a)	{						\
	if (a != NULL) {						\
		mutex_enter(&(a->rhc_lock));				\
		a->rhc_refcnt++;					\
		ASSERT(a->rhc_refcnt > 0);				\
		mutex_exit(&(a->rhc_lock));				\
	}								\
}
#define	TNRHC_RELE(a)	{						\
	if (a != NULL) {						\
		mutex_enter(&((a)->rhc_lock));				\
		ASSERT(a->rhc_refcnt > 0);				\
		a->rhc_refcnt--;					\
		if (a->rhc_refcnt <= 0)					\
			tnrhc_free(a);					\
		else							\
			mutex_exit(&(a->rhc_lock));			\
	}								\
}
#endif	/* _KERNEL */

/*
 * The next two hashing macros are copied from macros in ip_ire.h.
 */
#define	TSOL_ADDR_HASH(addr, table_size)				\
	(((((addr) >> 16) ^ (addr)) ^ ((((addr) >> 16) ^ (addr))>> 8))	\
	% (table_size))

#define	TSOL_ADDR_HASH_V6(addr, table_size)				\
	(((addr).s6_addr8[8] ^ (addr).s6_addr8[9] ^			\
	(addr).s6_addr8[10] ^ (addr).s6_addr8[13] ^			\
	(addr).s6_addr8[14] ^ (addr).s6_addr8[15]) % (table_size))

/* for tninfo -k */
typedef struct tsol_tnkstat {
	uint_t host_accred;	/* fails host accreditation */
	uint_t if_accred;	/* fails interface accreditation */
	uint_t seccom_alloc;	/* number of seccom structures allocated */
	uint_t seccom_reclaim;	/* memory reclaimed */
	uint_t sc_tp;		/* number of times sc_tp is used */
	uint_t find_rh;		/* number of times find_rh() is used */
	uint_t tta_alloc;	/* number of times tsol_tta_entry allocated */
	uint_t tta_dealloc;	/* number of times tsol_tta_entry deallocated */
} tsol_tnkstat_t;

/* for tninfo -c */
typedef struct tsol_tncstat {
	int norhent;		/* can't find rhent in cache */
} tsol_tncstat_t;

/*
 * Constants used for getting the mask value in struct tsol_tpent
 */
enum {
	TNT_DEF_LABEL,
	TNT_DEF_CL,
	TNT_UID,
	TNT_GID,
	TNT_FORCED_PRIV,
	TNT_SL_RANGE_TSOL,
	TNT_ALLOWED_PRIV,
	TNT_IP_LABEL,
	TNT_RIPSO_LABEL,
	TNT_RIPSO_ERROR,
	TNT_CIPSO_DOI,
	TNT_DEF_IL,
	TNT_DEF_AUID,
	TNT_DEF_AUDIT_MASK,
	TNT_DEF_AUDIT_TERMID,
	TNT_DEF_ASID
};

typedef enum tsol_tokops {
	MSIX_FLUSH = 1,
	TOKMAP_DOOR		/* set door for kernel upcall to tokenmapper */
} tsol_tokops_t;

/*
 * mask definitions
 */
#define	tsol_tntmask(value) ((short)(1<<(value)))

#define	TSOL_MSK_DEF_LABEL tsol_tntmask(TNT_DEF_LABEL)
#define	TSOL_MSK_DEF_CL tsol_tntmask(TNT_DEF_CL)
#define	TSOL_MSK_FORCED_PRIV tsol_tntmask(TNT_FORCED_PRIV)
#define	TSOL_MSK_SL_RANGE_TSOL tsol_tntmask(TNT_SL_RANGE_TSOL)
#define	TSOL_MSK_ALLOWED_PRIV tsol_tntmask(TNT_ALLOWED_PRIV)
#define	TSOL_MSK_IP_LABEL tsol_tntmask(TNT_IP_LABEL)
#define	TSOL_MSK_RIPSO_LABEL tsol_tntmask(TNT_RIPSO_LABEL)
#define	TSOL_MSK_RIPSO_ERROR tsol_tntmask(TNT_RIPSO_ERROR)
#define	TSOL_MSK_CIPSO_DOI tsol_tntmask(TNT_CIPSO_DOI)

/*
 * TN errors
 */
#define	TSOL_PARSE_ERANGE 1 /* result buffer not allocated */
#define	TSOL_NOT_SUPPORTED 2 /* address family not supported */
#define	TSOL_NOT_FOUND 3 /* search by * routines target not found */

/*
 * net db standard paths
 */
#define	TNRHTP_PATH "/etc/security/tsol/tnrhtp"
#define	TNRHDB_PATH "/etc/security/tsol/tnrhdb"
#define	TNIDB_PATH "/etc/security/tsol/tnidb"

/*
 * Secure Routing Information
 *
 * 1) The validity of sl_range, cipso_doi, ripso_label and ripso_error
 *    is determined by the "on" bits in mask.
 * 2) The sri_lock protects sri_refcnt; COW is performed.
 *
 */
typedef struct sri {
	struct sri	*sri_forw;	/* for hash table */
	struct sri	**sri_back;	/* for hash table */
#ifdef _KERNEL
	kmutex_t	sri_lock;
#endif
	int		sri_refcnt;
	int		mask;		/* defined below */
	brange_t	sl_range;
	int		cipso_doi;
	ripso_label_t	ripso_label;
	ripso_error_t	ripso_error[PAF_BYTES];
} sri_t;

/* Definition for mask */
#define	SRI_SL_MIN		0x1
#define	SRI_SL_MAX		0x2
#define	SRI_DOI			0x4
#define	SRI_RIPSO_LABEL		0x8
#define	SRI_RIPSO_ERROR		0x10
#define	SRI_CIPSO_ONLY		0x20
#define	SRI_RIPSO_ONLY		0x40
#define	SRI_MSIX_ONLY		0x80

/*
 * Extended Metric (a set of extended metric)
 */
typedef struct emetric {
	struct emetric	*emetric_next;	/* next element in the set */
	uint_t		metric;
	struct sri	*sri;
	int		flags;		/* used in in.routed */
} emetric_t;

/*
 * The following structures are used in tsol_rtentry.
 */
typedef struct rt_sri {
	int		mask;		/* defined above */
	brange_t	sl_range;
	int		cipso_doi;
	ripso_label_t	ripso_label;
	ripso_error_t	ripso_error[PAF_BYTES];
} rt_sri_t;

typedef struct rt_emetric {
	uint_t		metric;
	struct rt_sri	sri;
} rt_emetric_t;

/*
 * Structure used to hold a list of IP addresses.
 */
typedef struct tsol_address {
	struct tsol_address	*next;
	uint_t			ip_address;
} tsol_address_t;

extern struct tsol_tnkstat tsol_tnkstat;

/* Kernel routine prototypes */
#ifdef __STDC__
extern char *rtmsg_to_tsol_info(rt_msghdr_t *);
extern emetric_t *emetric_and(emetric_t *, emetric_t *, sri_and_status *);
extern emetric_t *emetric_dup(emetric_t *);
extern emetric_t *rt_emetric_to_emetric(rt_emetric_t *, int);
extern int check_emetrics(struct rt_emetric *, int);
extern int chstate_unlabeled(struct netbuf *, int, boolean_t);
extern int emetric_getnum(emetric_t *);
extern int rtmsg_to_rt_emetrics(rt_msghdr_t *, struct rt_emetric **);
extern int tsol_load_tmp_tnif(char *, int);
extern struct tsol_ifc *find_ifc(char *, int);
extern tsol_tpent_t *find_rh(void *, uchar_t, accred_flag_t *);
extern void emetric_free(emetric_t *);
extern void tcache_init(void);
extern void tsol_create_i_tnrh(struct netbuf *, int);
#else
extern char *rtmsg_to_tsol_info(/* rt_msghdr_t * */);
extern emetric_t *emetric_and(/* emetric_t *, emetric_t *, sri_and_status * */);
extern emetric_t *emetric_dup(/* emetric_t * */);
extern emetric_t *rt_emetric_to_emetric(/* rt_emetric_t *, int */);
extern int check_emetrics(/* struct rt_emetric *, int */);
extern int chstate_unlabeled(/* struct netbuf *, int, boolean_t */);
extern int emetric_getnum(/* emetric_t * */);
extern int rtmsg_to_rt_emetrics(/* rt_msghdr_t *, struct rt_emetric ** */);
extern int tsol_load_tmp_tnif(/* char *, int */);
extern struct tsol_ifc *find_ifc(/* char *, int */);
extern tsol_tpent_t *find_rh(/* void *, uchar_t, accred_flag_t * */);
extern void emetric_free(/* emetric_t * */);
extern void tcache_init(/* void */);
extern void tsol_create_i_tnrh(/* struct netbuf *, int */);
#endif /* __STDC__ */

#ifdef _KERNEL
#ifdef __STDC__
extern int tsol_valid_ripso(unsigned char *, intptr_t *);
extern int tsol_valid_cipso(unsigned char *, intptr_t *);
extern int tsol_label_icmp(mblk_t *, uchar_t **, uchar_t *);
extern struct tsol_tnrhc *tsol_get_rhctbl(int *);
extern struct tsol_tpc *tsol_get_rhtplist(void);
extern int tnrh_setup_timer(queue_t *, queue_t *,  mblk_t *);
#else
extern int tsol_valid_ripso(/* unsigned char *, intptr_t */);
extern int tsol_valid_cipso(/* unsigned char *, intptr_t */);
extern int tsol_label_icmp(/* mblk_t *, uchar_t **, uchar_t * */);
extern struct tsol_tnrhc *tsol_get_rhctbl(/* int * */);
extern struct tsol_tpc *tsol_get_rhtplist(/* void */);
extern int tnrh_setup_timer(/* queue_t *, queue_t *,  mblk_t * */);
#endif /* __STDC__ */
#endif /* _KERNEL */

#ifndef _KERNEL
/* TN function prototypes */
#ifdef __STDC__

extern struct tsol_tpent *tsol_gettpbyname(const char *, struct tsol_tpent *,
    int *);
extern struct tsol_tpent *tsol_gettpent(struct tsol_tpent *, int *);
extern void tsol_settpent(int);
extern void tsol_endtpent(void);
extern struct tsol_tpent *tsol_fgettpent(const FILE *, struct tsol_tpent *,
    int *);

extern struct tsol_rhent *tsol_getrhbyaddr(const struct netbuf *, const int,
    struct tsol_rhent *, int *);
extern struct tsol_rhent *tsol_getrhent(struct tsol_rhent *, int *);

extern void tsol_setrhent(int);
extern void tsol_endrhent(void);
extern struct tsol_rhent *tsol_fgetrhent(const FILE *, struct tsol_rhent *,
    int *);

extern struct tsol_ifent *tsol_getifbyname(const char *, struct tsol_ifent *,
    int *);
extern struct tsol_ifent *tsol_getifent(struct tsol_ifent *, int *);
extern void tsol_setifent(int);
extern void tsol_endifent(void);
extern struct tsol_ifent *tsol_fgetifent(const FILE *, struct tsol_ifent *,
    int *);
extern int tnif(int, struct tsol_ifent *);
extern int tnrhtp(int, struct tsol_tpent *);
extern int tnrh(int, struct tsol_rhent *);
extern int tokmapper(tsol_tokops_t, void *);
extern int chstate(int, struct netbuf *);
extern int tn_getpeertp(int, tsol_tpent_t *);
extern int tn_gettp(struct netbuf *, tsol_tpent_t *);

extern struct tsol_timeent *tsol_gettimebyname(const char *,
    struct tsol_timeent *, int *);
extern struct tsol_timeent *tsol_gettimeent(struct tsol_timeent *, int *);
extern void tsol_settimeent(int);
extern void tsol_endtimeent(void);
extern sri_t *get_sri_fromtp(tsol_tpent_t *, int);
extern rt_emetric_t *emetric_to_rt_emetric(emetric_t *, int *);
extern void print_emetric_t(FILE *, emetric_t *);
extern void print_rt_emetric_t(FILE *, rt_emetric_t *);
extern int parse_emetric(char *, emetric_t **, FILE *);
extern char *ripso_label_to_str(ripso_label_t *, char *);
extern char *ripso_error_to_str(ripso_error_t *, char *);

#else /* Non ANSI */
extern struct tsol_tpent *tsol_gettpbyname(
	/* const char *, struct tsol_tpent *, int * */);
extern struct tsol_tpent *tsol_gettpent(/* struct tsol_tpent *, int * */);
extern void tsol_settpent(/* int */);
extern void tsol_endtpent(/* void */);
extern struct tsol_tpent *tsol_fgettpent(
	/* const FILE *, struct tsol_tpent *, int * */);

extern struct tsol_rhent *tsol_getrhbyaddr(
	/* const struct netbuf *, const int, struct tsol_rhent *, int * */);
extern struct tsol_rhent *tsol_getrhent(/* struct tsol_rhent *, int * */);

extern void tsol_setrhent(/* int */);
extern void tsol_endrhent(/* void */);
extern struct tsol_rhent *tsol_fgetrhent(
	/* const FILE *, struct tsol_rhent *, int * */);

extern struct tsol_ifent *tsol_getifbyname(
	/* const char *, struct tsol_ifent *, int * */);
extern struct tsol_ifent *tsol_getifent(/* struct tsol_ifent *, int * */);
extern void tsol_setifent(/* int */);
extern void tsol_endifent(/* void */);
extern struct tsol_ifent *tsol_fgetifent(
	/* const FILE *, struct tsol_ifent *, int * */);

extern struct tsol_timeent *tsol_gettimebyname(
	/* char *, struct tsol_timeent *, int * */);
extern struct tsol_timeent *tsol_gettimeent(/* struct tsol_timeent *, int * */);
extern void tsol_settimeent(/* int */);
extern void tsol_endtimeent(/* void */);

extern int tnif(/* int, struct tsol_ifent * */);
extern int tnrhtp(/* int, struct tsol_tpent * */);
extern int tnrh(/* int, struct tsol_rhent * */);
extern int tokmapper(/* tsol_tokops_t, void * */);
extern int chstate(/* int, struct netbuf * */);
extern int tn_getpeertp(/* int, tsol_tpent_t * */);
extern int tn_gettp(/* struct netbuf *, tsol_tpent_t * */);
extern sri_t *get_sri_fromtp(/* tsol_tpent_t *, int */);
extern rt_emetric_t *emetric_to_rt_emetric(/* emetric_t *, int * */);
extern void print_emetric_t(/* FILE *, emetric_t * */);
extern void print_rt_emetric_t(/* FILE *, rt_emetric_t * */);
extern int parse_emetric(/* char *, emetric_t **, FILE * */);
extern char *ripso_label_to_str(/* ripso_label_t *, char * */);
extern char *ripso_error_to_str(/* ripso_error_t *, char * */);
#endif /* __STDC__ */
#endif /* !_KERNEL */


#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_TSOL_TNDB_H */
