code:
/*
 * Copyright (c) 1996-2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $Begemot: libunimsg/netnatm/msg/unistruct.h,v 1.7 2004/07/16 18:42:22 brandt Exp $
 *
 * This file defines all structures that are used by
 * API users.
 */
#ifndef _NETNATM_MSG_UNISTRUCT_H_
#define _NETNATM_MSG_UNISTRUCT_H_

#include <netnatm/msg/uni_config.h>

/*
 * define IE and MSG header
 */
#include <netnatm/msg/uni_hdr.h>

/*
 * define all IE's
 */
/*************************************************************************
 *
 * Free FORM IE
 */
struct uni_ie_unrec {
	struct uni_iehdr h;
	uint8_t id;		/* ID of this IE */
	u_int len;		/* data length */
	u_char data[128];	/* arbitrary maximum length */
};

/*************************************************************************
 *
 * ATM adaptation layer parameters information element
 */
enum {
	UNI_AAL_SUB_ID		= 0x85,
	UNI_AAL_CBR_ID		= 0x86,
	UNI_AAL_MULT_ID		= 0x87,
	UNI_AAL_SCREC_ID	= 0x88,
	UNI_AAL_ECM_ID		= 0x89,
	UNI_AAL_BSIZE_ID	= 0x8a,
	UNI_AAL_PART_ID		= 0x8b,
	UNI_AAL_FWDCPCS_ID	= 0x8c,
	UNI_AAL_BWDCPCS_ID	= 0x81,
	UNI_AAL_MID_ID		= 0x82,
	UNI_AAL_SSCS_ID		= 0x84,
};

enum uni_aal {
	UNI_AAL_0	= 0x00,	/* voice */
	UNI_AAL_1	= 0x01,
	UNI_AAL_2	= 0x02,
	UNI_AAL_4	= 0x03,	/* same as AAL 3 */
	UNI_AAL_5	= 0x05,
	UNI_AAL_USER	= 0x10,
};
enum uni_aal1_subtype {
	UNI_AAL1_SUB_NULL	= 0x00,
	UNI_AAL1_SUB_VOICE	= 0x01,
	UNI_AAL1_SUB_CIRCUIT	= 0x02,
	UNI_AAL1_SUB_HQAUDIO	= 0x04,
	UNI_AAL1_SUB_VIDEO	= 0x05,
};
enum uni_aal1_cbr {
	UNI_AAL1_CBR_64		= 0x01,
	UNI_AAL1_CBR_1544	= 0x04,
	UNI_AAL1_CBR_6312	= 0x05,
	UNI_AAL1_CBR_32064	= 0x06,
	UNI_AAL1_CBR_44736	= 0x07,
	UNI_AAL1_CBR_97728	= 0x08,
	UNI_AAL1_CBR_2048	= 0x10,
	UNI_AAL1_CBR_8448	= 0x11,
	UNI_AAL1_CBR_34368	= 0x12,
	UNI_AAL1_CBR_139264	= 0x13,
	UNI_AAL1_CBR_N64	= 0x40,
	UNI_AAL1_CBR_N8		= 0x41,
};
enum uni_aal1_screc {
	UNI_AAL1_SCREC_NULL	= 0x00,	/* synchr. circuit transport */
	UNI_AAL1_SCREC_SRTS	= 0x01,	/* synchr. residual timestamp */
	UNI_AAL1_SCREC_ACLK	= 0x02,	/* adaptive clock */
};
enum uni_aal1_ecm {
	UNI_AAL1_ECM_NULL	= 0x00,	/* no error correction */
	UNI_AAL1_ECM_LOSS	= 0x01,	/* for loss sensitive signals */
	UNI_AAL1_ECM_DELAY	= 0x02,	/* for delay sensitive signals */
};
enum uni_aal_sscs {
	UNI_AAL_SSCS_NULL	= 0x00,	/* Null */
	UNI_AAL_SSCS_SSCOPA	= 0x01,	/* assured SSCOP */
	UNI_AAL_SSCS_SSCOPU	= 0x02,	/* unassured SSCOP */
	UNI_AAL_SSCS_FRAME	= 0x04,	/* frame relay */
};

struct uni_ie_aal {
	struct uni_iehdr h;
	enum uni_aal	type;		/* aal type */

	union {
#define UNI_AAL1_MULT_P	0x01
#define UNI_AAL1_SCREC_P	0x02
#define UNI_AAL1_ECM_P		0x04
#define UNI_AAL1_BSIZE_P	0x08
#define UNI_AAL1_PART_P	0x10
	    struct {
		enum uni_aal1_subtype subtype;	/* AAL1 subtype */
		enum uni_aal1_cbr cbr_rate;	/* AAL1 CBR rate */
		u_int		mult;		/* AAL1 CBR mutliplier */
		enum uni_aal1_screc screc;	/* AAL1 source clock recovery */
		enum uni_aal1_ecm ecm;		/* AAL1 error correction */
		u_int	bsize;			/* AAL1 SDT blocksize */
		u_int	part;			/* AAL1 partial cell fill */
	    } aal1;

#define UNI_AAL4_CPCS_P	0x01
#define UNI_AAL4_MID_P		0x02
#define UNI_AAL4_SSCS_P	0x04
	    struct {
		u_int	fwd_cpcs;	/* max fwd cpcs blocksize */
		u_int	bwd_cpcs;	/* max bkw cpcs blocksize */
		u_int	mid_low;	/* MID low range */
		u_int	mid_high;	/* MID high range */
		enum uni_aal_sscs sscs;	/* sscs type */
	     } aal4;

#define UNI_AAL5_CPCS_P	0x01
#define UNI_AAL5_SSCS_P	0x02
	    struct {
		u_int	fwd_cpcs;	/* max fwd cpcs blocksize */
		u_int	bwd_cpcs;	/* max bkw cpcs blocksize */
		enum uni_aal_sscs sscs;	/* sscs type */
	     } aal5;

	    struct {
		u_int	len;		/* number of bytes */
		u_char	user[4];	/* user data */
	    } aalu;
	} u;
};

/*************************************************************************
 *
 * Called party number information element
 * Called party subaddress information element
 * Calling party number information element
 * Calling party subaddress information element
 * Q.2951/UNI4.0 Connected number information element
 * Q.2951/UNI4.0 Connected subaddress information element
 */
enum uni_addr_type {
	UNI_ADDR_UNKNOWN	= 0x0,
	UNI_ADDR_INTERNATIONAL	= 0x1,
	UNI_ADDR_NATIONAL	= 0x2,	/* not sup */
	UNI_ADDR_NETWORK	= 0x3,	/* not sup */
	UNI_ADDR_SUBSCR		= 0x4,	/* not sup */
	UNI_ADDR_ABBR		= 0x6,	/* not sup */
};
enum uni_addr_plan {
	/* UNI_ADDR_UNKNOWN	= 0x0, */	/* not sup */
	UNI_ADDR_E164		= 0x1,
	UNI_ADDR_ATME		= 0x2,
	UNI_ADDR_DATA		= 0x3,	/* not sup */
	UNI_ADDR_PRIVATE	= 0x9,	/* not sup */
};
enum uni_subaddr_type {
	UNI_SUBADDR_NSAP	= 0x0,
	UNI_SUBADDR_ATME	= 0x1,
	UNI_SUBADDR_USER	= 0x2,	/* not sup */
};
enum uni_addr_pres {
	UNI_ADDR_PRES		= 0x0,
	UNI_ADDR_RESTRICT	= 0x1,
	UNI_ADDR_NONUMBER	= 0x2,
};
enum uni_addr_screen {
	UNI_ADDR_SCREEN_NOT	= 0x0,
	UNI_ADDR_SCREEN_PASSED	= 0x1,
	UNI_ADDR_SCREEN_FAILED	= 0x2,
	UNI_ADDR_SCREEN_NET	= 0x3,
};

/* don't use bitfields to get a defined structure layout */
struct uni_addr {
	uint8_t			type;
	uint8_t			plan;
	uint8_t			len;
	u_char			addr[UNI_ADDR_MAXLEN];
};
struct uni_subaddr {
	enum uni_subaddr_type	type;
	u_int			len;
	u_char			addr[UNI_SUBADDR_MAXLEN];
};

struct uni_ie_called {
	struct uni_iehdr	h;
	struct uni_addr	addr;
};

struct uni_ie_calledsub {
	struct uni_iehdr	h;
	struct uni_subaddr	addr;
};

struct uni_ie_calling {
	struct uni_iehdr	h;
#define UNI_CALLING_SCREEN_P 0x0001

	struct uni_addr		addr;
	enum uni_addr_pres	pres;
	enum uni_addr_screen	screen;
};

struct uni_ie_callingsub {
	struct uni_iehdr	h;
	struct uni_subaddr	addr;
};

struct uni_ie_conned {
	struct uni_iehdr	h;
#define UNI_CONNED_SCREEN_P 0x0001

	struct uni_addr		addr;
	enum uni_addr_pres	pres;
	enum uni_addr_screen	screen;
};

struct uni_ie_connedsub {
	struct uni_iehdr	h;
	struct uni_subaddr	addr;
};

/*************************************************************************
 *
 * Broadband bearer capability descriptor
 * On reception of an old bearer descriptor, it is automatically
 * converted to a new, legal one.
 */
enum uni_bearer_class {
	UNI_BEARER_A		= 0x01,
	UNI_BEARER_C		= 0x03,
	UNI_BEARER_X		= 0x10,
	UNI_BEARER_TVP		= 0x30,
};

enum uni_bearer_atc {
	UNI_BEARER_ATC_CBR	= 0x05,
	UNI_BEARER_ATC_CBR1	= 0x07,
	UNI_BEARER_ATC_VBR	= 0x09,
	UNI_BEARER_ATC_VBR1	= 0x13,
	UNI_BEARER_ATC_NVBR	= 0x0a,
	UNI_BEARER_ATC_NVBR1	= 0x0b,
	UNI_BEARER_ATC_ABR	= 0x0c,

	UNI_BEARER_ATCX_0	= 0x00,
	UNI_BEARER_ATCX_1	= 0x01,
	UNI_BEARER_ATCX_2	= 0x02,
	UNI_BEARER_ATCX_4	= 0x04,
	UNI_BEARER_ATCX_6	= 0x06,
	UNI_BEARER_ATCX_8	= 0x08,
};

enum uni_bearer_clip {
	UNI_BEARER_NOCLIP	= 0x0,
	UNI_BEARER_CLIP		= 0x1,
};

enum uni_bearer_cfg {
	UNI_BEARER_P2P		= 0x0,
	UNI_BEARER_MP		= 0x1,
};

struct uni_ie_bearer {
	struct uni_iehdr	h;
#define UNI_BEARER_ATC_P	0x02

	enum uni_bearer_class	bclass;		/* bearer class */
	enum uni_bearer_atc	atc;		/* ATM transfer capability */
	enum uni_bearer_clip	clip;		/* suspectibility to clipping */
	enum uni_bearer_cfg	cfg;		/* u-plane configuration */
};

/*************************************************************************
 *
 * Broadband higher layer information element
 */
enum uni_bhli {
	UNI_BHLI_ISO	= 0x00,	/* IDO defined */
	UNI_BHLI_USER	= 0x01,	/* user specific */
	UNI_BHLI_VENDOR	= 0x03,	/* vendor specific */
};

struct uni_ie_bhli {
	struct uni_iehdr	h;
	enum uni_bhli		type;
	u_char			info[8];
	u_int			len;
};

/*************************************************************************
 *
 * Boradband lower layer information element
 */
enum {
	UNI_BLLI_L1_ID		= 0x1,
	UNI_BLLI_L2_ID		= 0x2,
	UNI_BLLI_L3_ID		= 0x3,
};

enum uni_blli_l2 {
	UNI_BLLI_L2_BASIC	= 0x01,
	UNI_BLLI_L2_Q921	= 0x02,
	UNI_BLLI_L2_X25LL	= 0x06,
	UNI_BLLI_L2_X25ML	= 0x07,
	UNI_BLLI_L2_LABP	= 0x08,
	UNI_BLLI_L2_HDLC_ARM	= 0x09,
	UNI_BLLI_L2_HDLC_NRM	= 0x0a,
	UNI_BLLI_L2_HDLC_ABM	= 0x0b,
	UNI_BLLI_L2_LAN		= 0x0c,
	UNI_BLLI_L2_X75		= 0x0d,
	UNI_BLLI_L2_Q922	= 0x0e,
	UNI_BLLI_L2_USER	= 0x10,
	UNI_BLLI_L2_ISO7776	= 0x11,
};

enum uni_blli_l2_mode {
	UNI_BLLI_L2NORM		= 0x1,
	UNI_BLLI_L2EXT		= 0x2,
};

enum uni_blli_l3 {
	UNI_BLLI_L3_X25		= 0x06,
	UNI_BLLI_L3_ISO8208	= 0x07,
	UNI_BLLI_L3_X223	= 0x08,
	UNI_BLLI_L3_CLMP	= 0x09,
	UNI_BLLI_L3_T70		= 0x0a,
	UNI_BLLI_L3_TR9577	= 0x0b,
	UNI_BLLI_L3_H310	= 0x0c,
	UNI_BLLI_L3_H321	= 0x0d,
	UNI_BLLI_L3_USER	= 0x10,
};

enum uni_blli_l3_mode {
	UNI_BLLI_L3NSEQ		= 0x1,	/* normal sequence numbering */
	UNI_BLLI_L3ESEQ		= 0x2,	/* extended sequence numbering */
};

enum uni_blli_l3_psiz {
	UNI_BLLI_L3_16		= 0x4,	/* 16 byte packets */
	UNI_BLLI_L3_32		= 0x5,	/* 32 byte packets */
	UNI_BLLI_L3_64		= 0x6,	/* 64 byte packets */
	UNI_BLLI_L3_128		= 0x7,	/* 128 byte packets */
	UNI_BLLI_L3_256		= 0x8,	/* 256 byte packets */
	UNI_BLLI_L3_512		= 0x9,	/* 512 byte packets */
	UNI_BLLI_L3_1024	= 0xa,	/* 1024 byte packets */
	UNI_BLLI_L3_2048	= 0xb,	/* 2048 byte packets */
	UNI_BLLI_L3_4096	= 0xc,	/* 4096 byte packets */
};

enum uni_blli_l3_ttype {
	UNI_BLLI_L3_TTYPE_RECV	= 0x1,	/* receive only */
	UNI_BLLI_L3_TTYPE_SEND	= 0x2,	/* send only */
	UNI_BLLI_L3_TTYPE_BOTH	= 0x3,	/* both */
};

enum uni_blli_l3_mux {
	UNI_BLLI_L3_MUX_NOMUX	= 0,	/* no multiplexing */
	UNI_BLLI_L3_MUX_TS	= 1,	/* transport stream */
	UNI_BLLI_L3_MUX_TSFEC	= 2,	/* transport stream with FEC */
	UNI_BLLI_L3_MUX_PS	= 3,	/* program stream */
	UNI_BLLI_L3_MUX_PSFEC	= 4,	/* program stream with FEC */
	UNI_BLLI_L3_MUX_H221	= 5,	/* H.221 */
};

enum uni_blli_l3_tcap {
	UNI_BLLI_L3_TCAP_NOIND	= 0,	/* no indication */
	UNI_BLLI_L3_TCAP_AAL1	= 1,	/* only AAL1 */
	UNI_BLLI_L3_TCAP_AAL5	= 2,	/* only AAL5 */
	UNI_BLLI_L3_TCAP_AAL15	= 3,	/* AAL1 and AAL5 */
};

/* Value for l3_ipi: */
enum {
	UNI_BLLI_L3_SNAP	= 0x80,	/* IEEE 802.1 SNAP */
};

struct uni_ie_blli {
	struct uni_iehdr	h;
#define UNI_BLLI_L1_P		0x0001
#define UNI_BLLI_L2_P		0x0002
#define UNI_BLLI_L2_Q933_P	0x0004
#define UNI_BLLI_L2_WSIZ_P	0x0008
#define UNI_BLLI_L2_USER_P	0x0010
#define UNI_BLLI_L3_P		0x0020
#define UNI_BLLI_L3_MODE_P	0x0040
#define UNI_BLLI_L3_PSIZ_P	0x0080
#define UNI_BLLI_L3_WSIZ_P	0x0100
#define UNI_BLLI_L3_USER_P	0x0200
#define UNI_BLLI_L3_IPI_P	0x0400
#define UNI_BLLI_L3_SNAP_P	0x0800
#define UNI_BLLI_L3_TTYPE_P	0x1000
#define UNI_BLLI_L3_MUX_P	0x2000

	u_int			l1:5;		/* layer 1 info */

	enum uni_blli_l2	l2;		/* layer 2 info */
	u_int			l2_q933:2;	/* layer 2 Q.933 use */
	enum uni_blli_l2_mode	l2_mode;	/* layer 2 HDLC mode */
	u_char			l2_user;	/* layer 2 user info */
	u_char			l2_wsiz;	/* layer 2 window size */

	enum uni_blli_l3	l3;		/* layer 3 info */
	enum uni_blli_l3_mode	l3_mode;	/* layer 3 mode */
	enum uni_blli_l3_psiz	l3_psiz;	/* layer 3 default packet size */
	u_char			l3_wsiz;	/* layer 3 window size */
	u_char			l3_user;	/* layer 3 user info */
	u_char			l3_ipi;		/* IPI byte */
	u_int			oui;		/* OUI bytes */
	u_int			pid;		/* PID bytes */
	enum uni_blli_l3_ttype	l3_ttype;	/* terminal bytes */
	enum uni_blli_l3_tcap	l3_tcap;	/* terminal capability */
	enum uni_blli_l3_mux	l3_fmux;	/* forward muxing */
	enum uni_blli_l3_mux	l3_bmux;	/* forward muxing */
};

/*************************************************************************
 *
 * Transit network selection IE
 */
struct uni_ie_tns {
	struct uni_iehdr h;
	u_char		net[UNI_TNS_MAXLEN];
	u_int		len;
};

/*************************************************************************
 *
 * Call state information element
 */
enum uni_callstate {
	UNI_CALLSTATE_U0	= 0x00,
	UNI_CALLSTATE_N0	= 0x00,
	UNI_CALLSTATE_NN0	= 0x00,

	UNI_CALLSTATE_U1	= 0x01,
	UNI_CALLSTATE_N1	= 0x01,
	UNI_CALLSTATE_NN1	= 0x01,

	UNI_CALLSTATE_U3	= 0x03,
	UNI_CALLSTATE_N3	= 0x03,
	UNI_CALLSTATE_NN3	= 0x03,

	UNI_CALLSTATE_U4	= 0x04,
	UNI_CALLSTATE_N4	= 0x04,
	UNI_CALLSTATE_NN4	= 0x04,

	UNI_CALLSTATE_U6	= 0x06,
	UNI_CALLSTATE_N6	= 0x06,
	UNI_CALLSTATE_NN6	= 0x06,

	UNI_CALLSTATE_U7	= 0x07,
	UNI_CALLSTATE_N7	= 0x07,
	UNI_CALLSTATE_NN7	= 0x07,

	UNI_CALLSTATE_U8	= 0x08,
	UNI_CALLSTATE_N8	= 0x08,

	UNI_CALLSTATE_U9	= 0x09,
	UNI_CALLSTATE_N9	= 0x09,
	UNI_CALLSTATE_NN9	= 0x09,

	UNI_CALLSTATE_U10	= 0x0a,
	UNI_CALLSTATE_N10	= 0x0a,
	UNI_CALLSTATE_NN10	= 0x0a,

	UNI_CALLSTATE_U11	= 0x0b,
	UNI_CALLSTATE_N11	= 0x0b,
	UNI_CALLSTATE_NN11	= 0x0b,

	UNI_CALLSTATE_U12	= 0x0c,
	UNI_CALLSTATE_N12	= 0x0c,
	UNI_CALLSTATE_NN12	= 0x0c,

	UNI_CALLSTATE_REST0	= 0x00,
	UNI_CALLSTATE_REST1	= 0x3d,
	UNI_CALLSTATE_REST2	= 0x3e,

	UNI_CALLSTATE_U13	= 0x0d,
	UNI_CALLSTATE_N13	= 0x0d,

	UNI_CALLSTATE_U14	= 0x0e,
	UNI_CALLSTATE_N14	= 0x0e,
};

struct uni_ie_callstate {
	struct uni_iehdr	h;
	enum uni_callstate	state;
};

/*************************************************************************
 *
 * Cause information element
 */
enum uni_cause_loc {
	UNI_CAUSE_LOC_USER	= 0x0,
	UNI_CAUSE_LOC_PRIVLOC	= 0x1,
	UNI_CAUSE_LOC_PUBLOC	= 0x2,
	UNI_CAUSE_LOC_TRANSIT	= 0x3,
	UNI_CAUSE_LOC_PUBREM	= 0x4,
	UNI_CAUSE_LOC_PRIVREM	= 0x5,
	UNI_CAUSE_LOC_INTERNAT	= 0x6,
	UNI_CAUSE_LOC_BEYOND	= 0x7,
};

#define UNI_DECLARE_CAUSE_VALUES \
D(UNALL_NUM,	0x01 /*  1*/, COND,	Q.850,	"Unallocated (unassigned) number") \
D(NOROUTE_NET,	0x02 /*  2*/, TNS,	Q.850,	"No route to specified transit network") \
D(NOROUTE,	0x03 /*  3*/, COND,	Q.850,	"No route to destination") \
D(SPTONE,	0x04 /*  4*/, NONE,	Q.850,	"Send special information tone") \
D(BADTRUNK,	0x05 /*  5*/, NONE,	Q.850,	"Misdialled trunk prefix") \
D(BADCHAN,	0x06 /*  6*/, NONE,	Q.850,	"Channel unacceptable") \
D(CALLAWARDED,	0x07 /*  7*/, NONE,	Q.850,	"Call awarded and being delivered in an established channel") \
D(PREEMPT,	0x08 /*  8*/, NONE,	Q.850,	"Preemption") \
D(PREEMPT_RES,	0x09 /*  9*/, NONE,	Q.850,	"Preemption - circuit reserved for reuse") \
D(CLEARING,	0x10 /* 16*/, COND,	Q.850,	"Normal call clearing") \
D(BUSY,		0x11 /* 17*/, CCBS,	Q.850,	"User busy") \
D(NO_RESPONSE,	0x12 /* 18*/, NONE,	Q.850,	"No user responding") \
D(NO_RESP_ALERT,0x13 /* 19*/, NONE,	Q.850,	"No answer from user (user alerted)") \
D(ABSENT,	0x14 /* 20*/, NONE,	Q.850,	"Subscriber absent") \
D(REJECTED,	0x15 /* 21*/, REJ,	Q.850,	"Call rejected") \
D(NUMCHG,	0x16 /* 22*/, NUMBER,	Q.850,	"Number changed") \
D(REDIR,	0x17 /* 23*/, NONE,	Q.850,	"Redirection to new destination") \
N(CLIR_REJECTED,0x17 /* 23*/, NONE,	UNI4.0,	"User rejects call with calling line identification restriction (CLIR)") \
D(EXCHG_ERR,	0x19 /* 25*/, NONE,	Q.850,	"Exchange routing error") \
D(NOSEL_CLEAR,	0x1a /* 26*/, NONE,	Q.850,	"Non-selected user clearing") \
D(DST_OOO,	0x1b /* 27*/, NONE,	Q.850,	"Destination out of order") \
D(INV_ADDR,	0x1c /* 28*/, NONE,	Q.850,	"Invalid number format (address incomplete)") \
D(FAC_REJ,	0x1d /* 29*/, FAC,	Q.850,	"Facility rejected") \
D(STATUS,	0x1e /* 30*/, NONE,	Q.850,	"Response to STATUS ENQUIRY") \
D(UNSPEC,	0x1f /* 31*/, NONE,	Q.850,	"Normal, unspecified") \
D(TMY_PARTY,	0x20 /* 32*/, NONE,	Q.2971,	"Too many pending add party requests") \
D(NOCHAN,	0x22 /* 34*/, CCBS,	Q.850,	"No circuit/channel available") \
N(SOFT_NAVL,	0x22 /* 34*/, NONE,	PNNI1.0,"Requested called party soft PVPC or PVCC not available")\
D(VPCI_NAVL,	0x23 /* 35*/, NONE,	Q.2610,	"Requested VPCI/VCI not available") \
D(VPCI_FAIL,	0x24 /* 36*/, NONE,	Q.2610,	"VPCI/VPI assignment failure") \
D(CRATE_NAVL,	0x25 /* 37*/, CRATE,	Q.2610,	"User cell rate not available") \
D(NET_OOO,	0x26 /* 38*/, NONE,	Q.850,	"Network out of order") \
D(FRAME_OOS,	0x27 /* 39*/, NONE,	Q.850,	"Permanent frame mode connection out of service") \
D(FRAME_OP,	0x28 /* 40*/, NONE,	Q.850,	"Permanent frame mode connection operational") \
D(TEMP,		0x29 /* 41*/, NONE,	Q.850,	"Temporary failure") \
D(CONG,		0x2a /* 42*/, NONE,	Q.850,	"Switching equipment congestion") \
D(ACC_DISC,	0x2b /* 43*/, IE,	Q.850,	"Access information discarded") \
D(REQNOCHAN,	0x2c /* 44*/, NONE,	Q.850,	"Requested circuit/channel not available") \
D(NOVPCI,	0x2d /* 45*/, NONE,	Q.2610,	"No VPCI/VCI available") \
D(PREC_BLOCK,	0x2e /* 46*/, NONE,	Q.850,	"Precedence call blocked") \
D(RESRC_NAVL,	0x2f /* 47*/, NONE,	Q.850,	"Resource unavailable, unspecified") \
D(QOS_NAVL,	0x31 /* 49*/, COND,	Q.850,	"Quality of service not available") \
D(FAC_NOTSUB,	0x32 /* 50*/, FAC,	Q.850,	"Requested facility not subscribed") \
D(OUT_CUG,	0x35 /* 53*/, NONE,	Q.850,	"Outgoing calls barred within CUG") \
N(PGL_CHG,	0x35 /* 53*/, NONE,	PNNI1.0,"Call cleared due to change in PGL") \
D(IN_CUG,	0x37 /* 55*/, NONE,	Q.850,	"Incoming call barred within CUG") \
D(BEARER_NAUTH,	0x39 /* 57*/, ATTR,	Q.850,	"Bearer capability not authorized") \
D(BEARER_NAVL,	0x3a /* 58*/, ATTR,	Q.850,	"Bearer capability not presently available") \
D(INCONS,	0x3e /* 62*/, NONE,	Q.850,	"Inconsistency in designated outgoing access information and subscriber class") \
D(OPT_NAVL,	0x3f /* 63*/, NONE,	Q.850,	"Service or option not available, unspecified") \
D(BEARER_NIMPL,	0x41 /* 65*/, ATTR,	Q.850,	"Bearer capability not implemented") \
D(CHANNEL_NIMPL,0x42 /* 66*/, CHANNEL,	Q.850,	"Channel type not implemented") \
D(FAC_NIMPL,	0x45 /* 69*/, FAC,	Q.850,	"Requested facility not implemented") \
D(RESTR_DIG,	0x46 /* 70*/, NONE,	Q.850,	"Only restricted digital information bearer capability is available") \
D(TRAFFIC_UNSUP,0x49 /* 73*/, NONE,	Q.2971,	"Unsupported combination of traffic parameters") \
N(AAL_UNSUP,	0x4c /* 78*/, NONE,	UNI3.1,	"AAL parameters cannot be supported") \
D(CREF_INV,	0x51 /* 81*/, NONE,	Q.850,	"Invalid call reference value") \
D(CHANNEL_NEX,	0x52 /* 82*/, CHANID,	Q.850,	"Identified channel does not exist") \
D(SUSPENDED,	0x53 /* 83*/, NONE,	Q.850,	"A suspended call exists, but this call identity does not") \
D(CID_INUSE,	0x54 /* 84*/, NONE,	Q.850,	"Call identity in use") \
D(NOTSUSP,	0x55 /* 85*/, NONE,	Q.850,	"No call suspended") \
D(CLEARED,	0x56 /* 86*/, CAUSE,	Q.850,	"Call having requested call identity has been cleared") \
D(NOT_MEMBER,	0x57 /* 87*/, NONE,	Q.850,	"User not member of CUG") \
D(INCOMP,	0x58 /* 88*/, PARAM,	Q.850,	"Incompatible destination") \
D(ENDP_INV,	0x59 /* 89*/, IE,	UNI3.1,	"Invalid endpoint reference") \
D(NEX_CUG,	0x5a /* 90*/, NONE,	Q.850,	"Non-existend CUG") \
D(TRANSIT_INV,	0x5b /* 91*/, NONE,	Q.850,	"Invalid transit network selection") \
D(AALNOTSUPP,	0x5d /* 93*/, NONE,	Q.2610,	"AAL parameters cannot be supported") \
D(INVMSG,	0x5f /* 95*/, NONE,	Q.850,	"Invalid message, unspecified") \
D(MANDAT,	0x60 /* 96*/, IE,	Q.850,	"Mandatory information element is missing") \
D(MTYPE_NIMPL,	0x61 /* 97*/, MTYPE,	Q.850,	"Message type non-existent or not implemented") \
D(MSG_NOTCOMP,	0x62 /* 98*/, MTYPE,	Q.850,	"Message not compatible with call state or message type non-existent or not implemented") \
D(IE_NIMPL,	0x63 /* 99*/, IE,	Q.850,	"Information element/parameter non-existent or not implemented") \
D(IE_INV,	0x64 /*100*/, IE,	Q.850,	"Invalid information element contents") \
D(MSG_INCOMP,	0x65 /*101*/, MTYPE,	Q.850,	"Message not compatible with call state") \
D(RECOVER,	0x66 /*102*/, TIMER,	Q.850,	"Recovery on timer expiry") \
D(PARAM_NEX,	0x67 /*103*/, PARAM,	Q.850,	"Parameter non-existent or not implemented, passed on") \
N(BAD_LENGTH,	0x68 /*104*/, NONE,	UNI3.1,	"Incorrect message length") \
D(PARAM_UNREC,	0x6e /*110*/, PARAM,	Q.850,	"Message with unrecognized parameter, discarded") \
D(PROTO,	0x6f /*111*/, NONE,	Q.850,	"Protocol error, unspecified") \
D(INTERWORKING,	0x7f /*127*/, NONE,	Q.850,	"Interworking, unspecified")

#define D(NAME,VAL,DIAG,STD,STR) UNI_CAUSE_##NAME = VAL,
#define N(NAME,VAL,DIAG,STD,STR) UNI_CAUSE_##NAME = VAL,

enum uni_cause {
UNI_DECLARE_CAUSE_VALUES
};

#undef D
#undef N

enum uni_cause_class {
	UNI_CAUSE_CLASS_NORM	= 0x0,
	UNI_CAUSE_CLASS_NORM1	= 0x1,
	UNI_CAUSE_CLASS_RES	= 0x2,
	UNI_CAUSE_CLASS_NAVL	= 0x3,
	UNI_CAUSE_CLASS_NIMPL	= 0x4,
	UNI_CAUSE_CLASS_INV	= 0x5,
	UNI_CAUSE_CLASS_PROTO	= 0x6,
	UNI_CAUSE_CLASS_INTER	= 0x7,
};
enum uni_cause_pu {
	UNI_CAUSE_PU_PROVIDER	= 0,
	UNI_CAUSE_PU_USER	= 1,
};
enum uni_cause_na {
	UNI_CAUSE_NA_NORMAL	= 0,
	UNI_CAUSE_NA_ABNORMAL	= 1,
};
enum uni_cause_cond {
	UNI_CAUSE_COND_UNKNOWN	= 0,
	UNI_CAUSE_COND_PERM	= 1,
	UNI_CAUSE_COND_TRANS	= 2,
};
enum uni_cause_reason {
	UNI_CAUSE_REASON_USER	= 0x00,
	UNI_CAUSE_REASON_IEMISS	= 0x01,
	UNI_CAUSE_REASON_IESUFF	= 0x02,
};

enum uni_diag {
	UNI_DIAG_NONE,		/* no diagnostics */

	UNI_DIAG_COND,		/* Condition */
	UNI_DIAG_TNS,		/* Transit Network Selector */
	UNI_DIAG_REJ,		/* Call Rejected */
	UNI_DIAG_NUMBER,	/* New Destination */
	UNI_DIAG_CRATE,		/* Traffic descriptor subfield */
	UNI_DIAG_ATTR,		/* Attribute idendity */
	UNI_DIAG_PARAM,		/* Parameter, same as one IE */
	UNI_DIAG_TIMER,		/* timer in ASCII */
	UNI_DIAG_MTYPE,		/* Message type */
	UNI_DIAG_IE,		/* Information element */
	UNI_DIAG_CHANID,	/* VPCI/VCI */

	UNI_DIAG_CAUSE = UNI_DIAG_NONE,		/* Not specified */
	UNI_DIAG_CHANNEL = UNI_DIAG_NONE,	/* For N-ISDN */
	UNI_DIAG_CCBS = UNI_DIAG_NONE,		/* Not used in Q.931 */
	UNI_DIAG_FAC = UNI_DIAG_NONE,		/* Not specified */
};

enum {
	UNI_CAUSE_TRAFFIC_N	= 34-6,
	UNI_CAUSE_IE_N		= 34-6,
	UNI_CAUSE_ATTR_N	= (34-6)/3,
};

struct uni_ie_cause {
	struct uni_iehdr	h;
#define UNI_CAUSE_COND_P	0x0001
#define UNI_CAUSE_REJ_P		0x0002
#define UNI_CAUSE_REJ_USER_P	0x0004
#define UNI_CAUSE_REJ_IE_P	0x0008
#define UNI_CAUSE_IE_P		0x0010
#define UNI_CAUSE_TRAFFIC_P	0x0020
#define UNI_CAUSE_VPCI_P	0x0040
#define UNI_CAUSE_MTYPE_P	0x0080
#define UNI_CAUSE_TIMER_P	0x0100
#define UNI_CAUSE_TNS_P		0x0200
#define UNI_CAUSE_NUMBER_P	0x0400
#define UNI_CAUSE_ATTR_P	0x0800
#define UNI_CAUSE_PARAM_P	0x1000

	enum uni_cause_loc	loc;
	enum uni_cause		cause;

	union {
	    struct {
		enum uni_cause_pu	pu;
		enum uni_cause_na	na;
		enum uni_cause_cond	cond;
	    } cond;
	    struct {
		enum uni_cause_reason	reason;
		enum uni_cause_cond	cond;
		u_int			user;
		uint8_t			ie;
	    } rej;
	    struct {
		uint8_t			ie[UNI_CAUSE_IE_N];
		u_int			len;
	    } ie;
	    struct {
		uint8_t			traffic[UNI_CAUSE_TRAFFIC_N];
		u_int			len;
	    } traffic;
	    struct {
		uint16_t		vpci;
		uint16_t		vci;
	    } vpci;
	    uint8_t			mtype;
	    u_char			timer[3];
	    struct uni_ie_tns		tns;
	    struct uni_ie_called	number;		/* TNS does not fit */
	    uint8_t			param;
	    struct {
		u_int			nattr;
	        u_char			attr[UNI_CAUSE_ATTR_N][3];
	    }				attr;
	} u;
};
enum uni_diag uni_diag(enum uni_cause, enum uni_coding);

/* return a string for the cause (NULL if the coding/cause are illegal) */
const char *uni_ie_cause2str(enum uni_coding, u_int);

/*************************************************************************
 *
 * Connection identifier information element
 */
enum uni_connid_type {
	UNI_CONNID_VCI		= 0,
	UNI_CONNID_ANYVCI	= 1,
	UNI_CONNID_NOVCI	= 4,
};
enum uni_connid_assoc {
	UNI_CONNID_ASSOC	= 0,
	UNI_CONNID_NONASSOC	= 1,
};
struct uni_ie_connid {
	struct uni_iehdr	h;
	enum uni_connid_assoc	assoc;
	enum uni_connid_type	type;
	u_int			vpci : 16;
	u_int			vci : 16;
};

/*************************************************************************
 *
 * End point reference IE
 */
struct uni_ie_epref {
	struct uni_iehdr	h;
	u_int			flag : 1;
	u_int			epref : 15;
};

/*************************************************************************
 *
 * End point state IE
 */
enum uni_epstate {
	UNI_EPSTATE_NULL	= 0x00,
	UNI_EPSTATE_ADD_INIT	= 0x01,
	UNI_EPSTATE_ALERT_DLVD	= 0x04,
	UNI_EPSTATE_ADD_RCVD	= 0x06,
	UNI_EPSTATE_ALERT_RCVD	= 0x07,
	UNI_EPSTATE_ACTIVE	= 0x0a,
	UNI_EPSTATE_DROP_INIT	= 0x0b,
	UNI_EPSTATE_DROP_RCVD	= 0x0c,
};

struct uni_ie_epstate {
	struct uni_iehdr h;
	enum uni_epstate state;
};

/*************************************************************************
 *
 * Q.2932 Facility IE
 */
enum {
	UNI_FACILITY_ROSE	= 0x11,

	UNI_FACILITY_MAXAPDU	= 128,
};

struct uni_ie_facility {
	struct uni_iehdr h;

	u_char		proto;
	u_char		apdu[UNI_FACILITY_MAXAPDU];
	u_int		len;
};

/*************************************************************************
 *
 * Notification indicator
 */
enum {
	UNI_NOTIFY_MAXLEN	= 128,	/* maximum info length */
};
struct uni_ie_notify {
	struct uni_iehdr h;
	u_int		len;
	u_char		notify[UNI_NOTIFY_MAXLEN];
};

/*************************************************************************
 *
 * QoS information element
 */
enum uni_qos {
	UNI_QOS_CLASS0	= 0x00,
	UNI_QOS_CLASS1	= 0x01,
	UNI_QOS_CLASS2	= 0x02,
	UNI_QOS_CLASS3	= 0x03,
	UNI_QOS_CLASS4	= 0x04,
};

struct uni_ie_qos {
	struct uni_iehdr h;
	enum uni_qos	fwd;
	enum uni_qos	bwd;
};

/*************************************************************************
 *
 * Broadband repeat indicator information element
 */
enum uni_repeat_type {
	UNI_REPEAT_PRIDESC	= 0x02,
	UNI_REPEAT_STACK	= 0x0a,		/* PNNI */
};

struct uni_ie_repeat {
	struct uni_iehdr h;
	enum uni_repeat_type type;
};

/*************************************************************************
 *
 * Restart indicator information element
 */
enum uni_restart_type {
	UNI_RESTART_CHANNEL	= 0x0,
	UNI_RESTART_PATH	= 0x1,
	UNI_RESTART_ALL		= 0x2,
};

struct uni_ie_restart {
	struct uni_iehdr h;
	enum uni_restart_type rclass;
};

/*************************************************************************
 *
 * Broadband sending complete indicator information element
 */
struct uni_ie_scompl {
	struct uni_iehdr h;
};

/*************************************************************************
 *
 * ATM traffic descriptor information element
 */
enum {
	UNI_TRAFFIC_FMDCR_ID	= 0x00,
	UNI_TRAFFIC_BMDCR_ID	= 0x02,
	UNI_TRAFFIC_FPCR0_ID	= 0x82,
	UNI_TRAFFIC_BPCR0_ID	= 0x83,
	UNI_TRAFFIC_FPCR1_ID	= 0x84,
	UNI_TRAFFIC_BPCR1_ID	= 0x85,
	UNI_TRAFFIC_FSCR0_ID	= 0x88,
	UNI_TRAFFIC_BSCR0_ID	= 0x89,
	UNI_TRAFFIC_FSCR1_ID	= 0x90,
	UNI_TRAFFIC_BSCR1_ID	= 0x91,
	UNI_TRAFFIC_FABR1_ID	= 0x92,
	UNI_TRAFFIC_BABR1_ID	= 0x93,
	UNI_TRAFFIC_FMBS0_ID	= 0xa0,
	UNI_TRAFFIC_BMBS0_ID	= 0xa1,
	UNI_TRAFFIC_FMBS1_ID	= 0xb0,
	UNI_TRAFFIC_BMBS1_ID	= 0xb1,
	UNI_TRAFFIC_BEST_ID	= 0xbe,
	UNI_TRAFFIC_MOPT_ID	= 0xbf,

	UNI_TRAFFIC_FTAG	= 0x01,
	UNI_TRAFFIC_BTAG	= 0x02,
	UNI_TRAFFIC_FDISC	= 0x80,
	UNI_TRAFFIC_BDISC	= 0x40,

	UNI_MINTRAFFIC_FPCR0_ID	= 0x82,
	UNI_MINTRAFFIC_BPCR0_ID	= 0x83,
	UNI_MINTRAFFIC_FPCR1_ID	= 0x84,
	UNI_MINTRAFFIC_BPCR1_ID	= 0x85,
	UNI_MINTRAFFIC_FABR1_ID	= 0x92,
	UNI_MINTRAFFIC_BABR1_ID	= 0x93,

	UNI_MDCR_ORIGIN_USER	= 0x00,
	UNI_MDCR_ORIGIN_NET	= 0x01,
};

#define UNI_TRAFFIC_FPCR0_P	0x0001
#define UNI_TRAFFIC_BPCR0_P	0x0002
#define UNI_TRAFFIC_FPCR1_P	0x0004
#define UNI_TRAFFIC_BPCR1_P	0x0008
#define UNI_TRAFFIC_FSCR0_P	0x0010
#define UNI_TRAFFIC_BSCR0_P	0x0020
#define UNI_TRAFFIC_FSCR1_P	0x0040
#define UNI_TRAFFIC_BSCR1_P	0x0080
#define UNI_TRAFFIC_FMBS0_P	0x0100
#define UNI_TRAFFIC_BMBS0_P	0x0200
#define UNI_TRAFFIC_FMBS1_P	0x0400
#define UNI_TRAFFIC_BMBS1_P	0x0800
#define UNI_TRAFFIC_BEST_P	0x1000
#define UNI_TRAFFIC_MOPT_P	0x2000
#define UNI_TRAFFIC_FABR1_P	0x4000
#define UNI_TRAFFIC_BABR1_P	0x8000
struct uni_xtraffic {
	u_int	fpcr0, bpcr0;
	u_int	fpcr1, bpcr1;
	u_int	fscr0, bscr0;
	u_int	fscr1, bscr1;
	u_int	fmbs0, bmbs0;
	u_int	fmbs1, bmbs1;
	u_int	fabr1, babr1;
	u_int	ftag, btag;
	u_int	fdisc, bdisc;
};

struct uni_ie_traffic {
	struct uni_iehdr h;
	struct uni_xtraffic t;
};
struct uni_ie_atraffic {
	struct uni_iehdr h;
	struct uni_xtraffic t;
};

/*
 * Q.2961 minimum traffic descriptor
 */
struct uni_ie_mintraffic {
	struct uni_iehdr h;
#define UNI_MINTRAFFIC_FPCR0_P	0x0001
#define UNI_MINTRAFFIC_BPCR0_P	0x0002
#define UNI_MINTRAFFIC_FPCR1_P	0x0004
#define UNI_MINTRAFFIC_BPCR1_P	0x0008
#define UNI_MINTRAFFIC_FABR1_P	0x0010
#define UNI_MINTRAFFIC_BABR1_P	0x0020

	u_int	fpcr0, bpcr0;
	u_int	fpcr1, bpcr1;
	u_int	fabr1, babr1;
};

/*
 * UNI4.0+ (af-cs-0147.000) Minimum Desired Cell Rate
 */
struct uni_ie_mdcr {
	struct uni_iehdr h;
	u_int	origin;
	u_int	fmdcr, bmdcr;
};

/*************************************************************************
 *
 * User-user information information element
 */
struct uni_ie_uu {
	struct uni_iehdr h;
	u_int		len;
	u_char		uu[UNI_UU_MAXLEN];
};

/*************************************************************************
 *
 * Generic identifier transport
 */
enum uni_git_std {
	UNI_GIT_STD_DSMCC	= 0x01,	/* DSM-CC */
	UNI_GIT_STD_H245	= 0x02,	/* H.245 */
};
enum uni_git_type {
	UNI_GIT_TYPE_SESS	= 0x01,	/* session id */
	UNI_GIT_TYPE_RES	= 0x02,	/* resource id */
};

enum {
	UNI_GIT_MAXSESS		= 20,	/* max session value length */
	UNI_GIT_MAXRES		= 4,	/* max resource value length */

	UNI_GIT_MAXVAL		= 20,	/* the maximum of the above */
	UNI_GIT_MAXSUB		= 2,	/* maximum number of og. 6 */
};

struct uni_ie_git {
	struct uni_iehdr	h;

	enum uni_git_std	std;	/* identifier related standard/application */
	u_int			numsub;
	struct {
		enum uni_git_type type;
		u_int		len;
		u_char		val[UNI_GIT_MAXVAL];
	}			sub[UNI_GIT_MAXSUB];
};

/*************************************************************************
 *
 * End-to-end transit delay
 */
enum {
	UNI_EETD_CTD_ID		= 0x01,	/* cumulative transit delay */
	UNI_EETD_MTD_ID		= 0x03,	/* maximum transit delay */
	UNI_EETD_NET_ID		= 0x0a,	/* network generated */
	UNI_EETD_PMTD_ID	= 0x0b,	/* PNNI acceptable forward maximum ctd */
	UNI_EETD_PCTD_ID	= 0x11,	/* PNNI cumulative forward maximum ctd */

	UNI_EETD_ANYMAX		= 0xffff,
	UNI_EETD_MAXVAL		= 0xffff,	/* maximum value */
};

struct uni_ie_eetd {
	struct uni_iehdr	h;
#define UNI_EETD_CUM_P		0x0001
#define UNI_EETD_MAX_P		0x0002
#define UNI_EETD_NET_P		0x0004	/* UNI4.0 9.1.2.1 */
#define UNI_EETD_PMTD_P		0x0008	/* PNNI1.0 6.4.5.24 */
#define UNI_EETD_PCTD_P		0x0010	/* PNNI1.0 6.4.5.24 */

	u_int	cumulative;
	u_int	maximum;
	u_int	pmtd;
	u_int	pctd;
};

/*************************************************************************
 *
 * Leaf-initiated-join call identifier
 */
enum uni_lij_idtype {
	UNI_LIJ_IDTYPE_ROOT	= 0x0,	/* root created */
};

struct uni_ie_lij_callid {
	struct uni_iehdr	h;

	enum uni_lij_idtype	type;
	u_int			callid;
};

/*
 * LIJ parameters
 */
enum uni_lij_screen {
	UNI_LIJ_SCREEN_NETJOIN	= 0x0,	/* without root notification */
};

struct uni_ie_lij_param {
	struct uni_iehdr	h;

	enum uni_lij_screen	screen;
};

/*
 * LIJ sequence number
 */
struct uni_ie_lij_seqno {
	struct uni_iehdr	h;

	u_int			seqno;
};

/*************************************************************************
 *
 * Locking/Non-locking shift not supported
 */
struct uni_ie_lshift {
	struct uni_iehdr h;
	u_int		set:3;
};

struct uni_ie_nlshift {
	struct uni_iehdr h;
	u_int		set:3;
};

/*************************************************************************
 *
 * Externded QoS information element
 */
enum {
	UNI_EXQOS_FACC_ID	= 0x94,
	UNI_EXQOS_BACC_ID	= 0x95,
	UNI_EXQOS_FCUM_ID	= 0x96,
	UNI_EXQOS_BCUM_ID	= 0x97,
	UNI_EXQOS_FCLR_ID	= 0xa2,
	UNI_EXQOS_BCLR_ID	= 0xa3,
};

enum uni_exqos_origin {
	UNI_EXQOS_USER	= 0,
	UNI_EXQOS_NET	= 1,
};

enum {
	UNI_EXQOS_ANY_CDV	= 0xffffff,
	UNI_EXQOS_ANY_CLR	= 0xff,
};

struct uni_ie_exqos {
	struct uni_iehdr	h;
#define UNI_EXQOS_FACC_P	0x0001
#define UNI_EXQOS_BACC_P	0x0002
#define UNI_EXQOS_FCUM_P	0x0004
#define UNI_EXQOS_BCUM_P	0x0008
#define UNI_EXQOS_FCLR_P	0x0010
#define UNI_EXQOS_BCLR_P	0x0020

	enum uni_exqos_origin	origin;
	u_int			facc;
	u_int			bacc;
	u_int			fcum;
	u_int			bcum;
	u_int			fclr;
	u_int			bclr;
};

/*************************************************************************
 *
 * Additional ABR parameters
 * ABR setup parameters
 */
enum {
	UNI_ABRADD_FADD_ID	= 0xc2,
	UNI_ABRADD_BADD_ID	= 0xc3,
	UNI_ABRSETUP_FICR_ID	= 0xc2,
	UNI_ABRSETUP_BICR_ID	= 0xc3,
	UNI_ABRSETUP_FTBE_ID	= 0xc4,
	UNI_ABRSETUP_BTBE_ID	= 0xc5,
	UNI_ABRSETUP_RMFRT_ID	= 0xc6,
	UNI_ABRSETUP_FRIF_ID	= 0xc8,
	UNI_ABRSETUP_BRIF_ID	= 0xc9,
	UNI_ABRSETUP_FRDF_ID	= 0xca,
	UNI_ABRSETUP_BRDF_ID	= 0xcb,
};

struct uni_abr_rec {
	u_int			present;
#define UNI_ABR_REC_NRM_P	0x80000000
#define UNI_ABR_REC_TRM_P	0x40000000
#define UNI_ABR_REC_CDF_P	0x20000000
#define UNI_ABR_REC_ADTF_P	0x10000000
	u_int		nrm:3;
	u_int		trm:3;
	u_int		cdf:3;
	u_int		adtf:10;
};

struct uni_ie_abradd {
	struct uni_iehdr	h;
	struct uni_abr_rec	fwd, bwd;
};

struct uni_ie_abrsetup {
	struct uni_iehdr	h;
#define UNI_ABRSETUP_FICR_P	0x0001
#define UNI_ABRSETUP_BICR_P	0x0002
#define UNI_ABRSETUP_FTBE_P	0x0004
#define UNI_ABRSETUP_BTBE_P	0x0008
#define UNI_ABRSETUP_FRIF_P	0x0010
#define UNI_ABRSETUP_BRIF_P	0x0020
#define UNI_ABRSETUP_FRDF_P	0x0040
#define UNI_ABRSETUP_BRDF_P	0x0080
#define UNI_ABRSETUP_RMFRT_P	0x0100

	u_int		ficr, bicr;
	u_int		ftbe, btbe;
	u_int		rmfrt;
	u_int		frif, brif;
	u_int		frdf, brdf;
};

/*************************************************************************
 *
 * Connection scope information element
 */
enum uni_cscope {
	UNI_CSCOPE_ORG	= 0x01,
};

enum {
	UNI_CSCOPE_ORG_LOC	= 0x01,
	UNI_CSCOPE_ORG_LOC_P1	= 0x02,
	UNI_CSCOPE_ORG_LOC_P2	= 0x03,
	UNI_CSCOPE_ORG_SITE_M1	= 0x04,
	UNI_CSCOPE_ORG_SITE	= 0x05,
	UNI_CSCOPE_ORG_SITE_P1	= 0x06,
	UNI_CSCOPE_ORG_ORG_M1	= 0x07,
	UNI_CSCOPE_ORG_ORG	= 0x08,
	UNI_CSCOPE_ORG_ORG_P1	= 0x09,
	UNI_CSCOPE_ORG_COMM_M1	= 0x0a,
	UNI_CSCOPE_ORG_COMM	= 0x0b,
	UNI_CSCOPE_ORG_COMM_P1	= 0x0c,
	UNI_CSCOPE_ORG_REG	= 0x0d,
	UNI_CSCOPE_ORG_INTER	= 0x0e,
	UNI_CSCOPE_ORG_GLOBAL	= 0x0f,
};

struct uni_ie_cscope {
	struct uni_iehdr	h;
	enum uni_cscope		type;
	u_int			scope:8;
};

/*************************************************************************
 *
 * Connection scope information element
 */
enum uni_report {
	UNI_REPORT_MODCONF	= 0x01,
	UNI_REPORT_CLOCK	= 0x02,
	UNI_REPORT_EEAVAIL	= 0x04,
	UNI_REPORT_EEREQ	= 0x05,
	UNI_REPORT_EECOMPL	= 0x06,
};

struct uni_ie_report {
	struct uni_iehdr h;
	enum uni_report	report;
};

/*************************************************************************
 *
 * PNNI Designated transit list information element
 */
enum {
	UNI_DTL_LOGNP	= 0x01,
	UNI_DTL_LOGNP_SIZE = 27,
};

struct uni_ie_dtl {
	struct uni_iehdr	h;
	u_int			ptr:16;
	u_int			num;
	struct {
	  u_char		node_level;
	  u_char		node_id[21];
	  u_int			port_id;
	}			dtl[UNI_DTL_MAXNUM];
};

/*************************************************************************
 *
 * PNNI Crankback information element
 */
enum uni_crankback {
	UNI_CRANKBACK_IF	= 0x02,
	UNI_CRANKBACK_NODE	= 0x03,
	UNI_CRANKBACK_LINK	= 0x04,
};

enum {
	UNI_CAUSE_NXNODE_UNREACH = 128,
	UNI_CAUSE_DTL_NOT_MY_ID	= 160,
};

struct uni_ie_crankback {
	struct uni_iehdr	h;
#define UNI_CRANKBACK_TOP_P	0x0001
#define UNI_CRANKBACK_TOPX_P	0x0002
#define UNI_CRANKBACK_QOS_P	0x0004
	u_int			level:8;
	enum uni_crankback	type;
	union {
	  struct {
	    u_char		level;
	    u_char		id[21];
	  }			node;
	  struct {
	    u_char		plevel;
	    u_char		pid[21];
	    u_int		port;
	    u_char		slevel;
	    u_char		sid[21];
	  }			link;
	}			id;
	u_int			cause:8;
	union {
	  struct {
	    u_int		dir:8;
	    u_int		port;
	    u_int		avcr;
	    u_int		crm;
	    u_int		vf;
	  }			top;
	  struct {
	    u_int		ctd:1;
	    u_int		cdv:1;
	    u_int		clr:1;
	    u_int		other:1;
	  }			qos;
	}			diag;
};

/*************************************************************************
 *
 * PNNI Call_ing/called party soft PVPC/PVCC information element
 */
enum uni_soft_sel {
	UNI_SOFT_SEL_ANY	= 0x00,
	UNI_SOFT_SEL_REQ	= 0x02,
	UNI_SOFT_SEL_ASS	= 0x04,
};

struct uni_ie_calling_soft {
	struct uni_iehdr h;
#define UNI_CALLING_SOFT_VCI_P	0x0001
	u_int		vpi:12;
	u_int		vci:16;
};
struct uni_ie_called_soft {
	struct uni_iehdr h;
#define UNI_CALLED_SOFT_VPI_P	0x0001
#define UNI_CALLED_SOFT_VCI_P	0x0002
	enum uni_soft_sel sel;
	u_int		vpi:12;
	u_int		vci:16;
};

/*************************************************************************/

#include <netnatm/msg/uni_ie.h>
#include <netnatm/msg/uni_msg.h>

struct uni_all {
	enum uni_msgtype	mtype;
	union uni_msgall	u;
};

struct uni_ie {
	enum uni_ietype		ietype;
	union uni_ieall		u;
};

#endif


code:
/*-
 * Copyright (c) 1996 Charles D. Cranor and Washington University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Charles D. Cranor and
 *      Washington University.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $NetBSD: natm.h,v 1.1 1996/07/04 03:20:12 chuck Exp $
 * $FreeBSD: release/9.0.0/sys/netnatm/natm.h 168776 2007-04-16 12:31:35Z pjd $
 */

/*
 * natm.h: native mode atm
 */

/*
 * supported protocols
 */
#define	PROTO_NATMAAL0		1
#define	PROTO_NATMAAL5		2

/*
 * sockaddr_natm
 */

struct sockaddr_natm {
	unsigned char	snatm_len;		/* length */
	sa_family_t	snatm_family;		/* AF_NATM */
	char		snatm_if[IFNAMSIZ];	/* interface name */
	u_int16_t	snatm_vci;		/* vci */
	u_int8_t	snatm_vpi;		/* vpi */
};

#ifdef _KERNEL

/*
 * natm protocol control block
 */
struct natmpcb {
	LIST_ENTRY(natmpcb) pcblist;	/* list pointers */
	u_int		npcb_inq;	/* # of our pkts in proto q */
	struct socket	*npcb_socket;	/* backpointer to socket */
	struct ifnet	*npcb_ifp;	/* pointer to hardware */
	struct in_addr	ipaddr;		/* remote IP address, if APCB_IP */
	u_int16_t	npcb_vci;	/* VCI */
	u_int8_t	npcb_vpi;	/* VPI */
	u_int8_t	npcb_flags;	/* flags */
};

/* flags */
#define	NPCB_FREE	0x01		/* free (not on any list) */
#define	NPCB_CONNECTED	0x02		/* connected */
#define	NPCB_IP		0x04		/* used by IP */
#define	NPCB_DRAIN	0x08		/* destroy as soon as inq == 0 */

/* flag arg to npcb_free */
#define	NPCB_REMOVE	0		/* remove from global list */
#define	NPCB_DESTROY	1		/* destroy and be free */

LIST_HEAD(npcblist, natmpcb);

/* global data structures */

extern struct mtx natm_mtx;		/* global netnatm lock */
extern struct npcblist natm_pcbs;	/* global list of pcbs */
#define	NATM_STAT
#ifdef NATM_STAT
extern	u_int	natm_sodropcnt;
extern	u_int	natm_sodropbytes;	/* account of droppage */
extern	u_int	natm_sookcnt;
extern	u_int	natm_sookbytes;		/* account of ok */
#endif

/* locking macros */
#define	NATM_LOCK_INIT()	mtx_init(&natm_mtx, "natm_mtx", NULL, MTX_DEF)
#define	NATM_LOCK()		mtx_lock(&natm_mtx)
#define	NATM_UNLOCK()		mtx_unlock(&natm_mtx)
#define	NATM_LOCK_ASSERT()	mtx_assert(&natm_mtx, MA_OWNED)

/* external functions */

/* natm_pcb.c */
struct	natmpcb *npcb_alloc(int);
void	npcb_free(struct natmpcb *, int);
struct	natmpcb *npcb_add(struct natmpcb *, struct ifnet *, uint16_t, uint8_t);

/* natm.c */
extern struct pr_usrreqs natm_usrreqs;

#ifdef SYSCTL_HANDLER_ARGS
int	natm0_sysctl(SYSCTL_HANDLER_ARGS);
int	natm5_sysctl(SYSCTL_HANDLER_ARGS);
#endif

void	natmintr(struct mbuf *);

#endif

repo_name: veiledmerc/mira

license: mit


code:
/*
 * Copyright (c) 1996-2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 *
 * $Begemot: libunimsg/netnatm/saal/sscfu.h,v 1.4 2004/07/08 08:22:15 brandt Exp $
 *
 * Public include file for UNI SSCF
 */
#ifndef _NETNATM_SAAL_SSCFU_H_
#define _NETNATM_SAAL_SSCFU_H_

#include <sys/types.h>
#include <netnatm/saal/sscopdef.h>
#include <netnatm/saal/sscfudef.h>

/*
 * Define how a buffer looks like.
 */
#ifdef _KERNEL
#ifdef __FreeBSD__
#define SSCFU_MBUF_T mbuf
#endif
#else
#define SSCFU_MBUF_T uni_msg
#endif

struct SSCFU_MBUF_T;
struct sscfu;

/* functions to be supplied by the SSCOP user */
struct sscfu_funcs {
	/* upper (SAAL) interface output */
	void	(*send_upper)(struct sscfu *, void *, enum saal_sig,
		    struct SSCFU_MBUF_T *);

	/* lower (SSCOP) interface output */
	void	(*send_lower)(struct sscfu *, void *, enum sscop_aasig,
		    struct SSCFU_MBUF_T *, u_int);

	/* function to move the SSCOP window */
	void	(*window)(struct sscfu *, void *, u_int);

	/* debugging function */
	void	(*verbose)(struct sscfu *, void *, const char *, ...)
		    __printflike(3, 4);
};

/* Function defined by the SSCF-UNI code */

/* allocate and initialize a new SSCF instance */
struct sscfu *sscfu_create(void *, const struct sscfu_funcs *);

/* destroy an SSCF instance and free all resources */
void sscfu_destroy(struct sscfu *);

/* reset the SSCF to the released state */
void sscfu_reset(struct sscfu *);

/* lower input interface (SSCOP signals) */
void sscfu_input(struct sscfu *, enum sscop_aasig, struct SSCFU_MBUF_T *, u_int);

/* upper input interface (SAAL) */
int sscfu_saalsig(struct sscfu *, enum saal_sig, struct SSCFU_MBUF_T *);

/* retrieve the current state */
enum sscfu_state sscfu_getstate(const struct sscfu *);

/* char'ify signals and states */
const char *sscfu_signame(enum saal_sig);
const char *sscfu_statename(enum sscfu_state);

/* retrieve the default set of parameters for SSCOP */
u_int sscfu_getdefparam(struct sscop_param *);

/* get/set debugging flags */
void sscfu_setdebug(struct sscfu *, u_int);
u_int sscfu_getdebug(const struct sscfu *);

#endif


code:
/*
 * Copyright (c) 1996-2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 *
 * $Begemot: libunimsg/netnatm/saal/sscfudef.h,v 1.4 2004/07/08 08:22:16 brandt Exp $
 *
 * Definitions of UNI SSCF constants.
 */
#ifndef _NETNATM_SAAL_SSCFUDEF_H_
#define _NETNATM_SAAL_SSCFUDEF_H_

/*
 * Signals at the upper boundary of the SSCF.
 */
enum saal_sig {
	SAAL_ESTABLISH_request,		/* U -> SAAL: (UU) */
	SAAL_ESTABLISH_indication,	/* SAAL -> U: (UU) */
	SAAL_ESTABLISH_confirm,		/* SAAL -> U: (UU) */
	SAAL_RELEASE_request,		/* U -> SAAL: (UU) */
	SAAL_RELEASE_confirm,		/* SAAL -> U: */
	SAAL_RELEASE_indication,	/* SAAL -> U: (UU) */
	SAAL_DATA_request,		/* U -> SAAL: (DATA) */
	SAAL_DATA_indication,		/* SAAL -> U: (DATA) */
	SAAL_UDATA_request,		/* U -> SAAL: (UDATA) */
	SAAL_UDATA_indication,		/* SAAL -> U: (UDATA) */
};

/*
 * States of the SSCF
 */
enum sscfu_state {
	SSCFU_RELEASED,			/* 1/1 */
	SSCFU_AWAITING_ESTABLISH,	/* 2/2 */
	SSCFU_AWAITING_RELEASE,		/* 4/10 */
	SSCFU_ESTABLISHED,		/* 3/4 */
	SSCFU_RESYNC,			/* 2/5 */
};

/*
 * Debugging flags
 */
enum {
	SSCFU_DBG_LSIG		= 0x01,
	SSCFU_DBG_ERR		= 0x02,
	SSCFU_DBG_STATE		= 0x04,
	SSCFU_DBG_EXEC		= 0x08,
};

#endif


code:
/*
 * Copyright (c) 1996-2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 *
 * $Begemot: libunimsg/netnatm/saal/sscop.h,v 1.4 2004/07/08 08:22:16 brandt Exp $
 *
 * External interface to sscop.
 */
#ifndef _NETNATM_SAAL_SSCOP_H_
#define _NETNATM_SAAL_SSCOP_H_

#include <netnatm/saal/sscopdef.h>

/*
 * Define how a buffer looks like.
 */
#ifdef _KERNEL
#ifdef __FreeBSD__
#define SSCOP_MBUF_T mbuf
#endif
#else
#define SSCOP_MBUF_T uni_msg
#endif

struct SSCOP_MBUF_T;
struct sscop;

/*
 * Vector for user functions
 */
struct sscop_funcs {
	/* management signal from SSCOP */
	void	(*send_manage)(struct sscop *, void *, enum sscop_maasig,
		    struct SSCOP_MBUF_T *, u_int, u_int);

	/* AAL signal from SSCOP */
	void	(*send_upper)(struct sscop *, void *, enum sscop_aasig,
		    struct SSCOP_MBUF_T *, u_int);

	/* send a PDU to the wire */
	void	(*send_lower)(struct sscop *, void *,
		    struct SSCOP_MBUF_T *);

	/* print a message */
	void	(*verbose)(struct sscop *, void *, const char *, ...)
		    __printflike(3,4);

#ifndef _KERNEL
	/* start a timer */
	void	*(*start_timer)(struct sscop *, void *, u_int,
		    void (*)(void *));

	/* stop a timer */
	void	(*stop_timer)(struct sscop *, void *, void *);
#endif
};

/* Function defined by the SSCOP code */

/* create a new SSCOP instance and initialize to default values */
struct sscop *sscop_create(void *, const struct sscop_funcs *);

/* destroy an SSCOP instance */
void sscop_destroy(struct sscop *);

/* get the current parameters of an SSCOP */
void sscop_getparam(const struct sscop *, struct sscop_param *);

/* set new parameters in an SSCOP */
int sscop_setparam(struct sscop *, struct sscop_param *, u_int *);

/* deliver an signal to the SSCOP */
int sscop_aasig(struct sscop *, enum sscop_aasig, struct SSCOP_MBUF_T *, u_int);

/* deliver an management signal to the SSCOP */
int sscop_maasig(struct sscop *, enum sscop_maasig, struct SSCOP_MBUF_T *);

/* SSCOP input function */
void sscop_input(struct sscop *, struct SSCOP_MBUF_T *);

/* Move the window by a given number of messages. Return the new window */
u_int sscop_window(struct sscop *, u_int);

/* declare the lower layer busy or not busy */
u_int sscop_setbusy(struct sscop *, int);

/* retrieve the state */
enum sscop_state sscop_getstate(const struct sscop *);

/* map signals to strings */
const char *sscop_msigname(enum sscop_maasig);
const char *sscop_signame(enum sscop_aasig);
const char *sscop_statename(enum sscop_state);

/* set/get debugging state */
void sscop_setdebug(struct sscop *, u_int);
u_int sscop_getdebug(const struct sscop *);

/* reset the instance */
void sscop_reset(struct sscop *);

#endif


code:
/*
 * Copyright (c) 1996-2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 *
 * $Begemot: libunimsg/netnatm/saal/sscopdef.h,v 1.4 2004/07/08 08:22:17 brandt Exp $
 *
 * Definitions of SSCOP constants and parameter blocks. This is seen by
 * the outside world.
 */
#ifndef _NETNATM_SAAL_SSCOPDEF_H_
#define _NETNATM_SAAL_SSCOPDEF_H_

#include <sys/types.h>
#ifdef _KERNEL
#include <sys/stdint.h>
#else
#include <stdint.h>
#endif

/*
 * AA-interface signals
 */
enum sscop_aasig {
	SSCOP_ESTABLISH_request,	/* <- UU, BR */
	SSCOP_ESTABLISH_indication,	/* -> UU */
	SSCOP_ESTABLISH_response,	/* <- UU, BR */
	SSCOP_ESTABLISH_confirm,	/* -> UU */

	SSCOP_RELEASE_request,		/* <- UU */
	SSCOP_RELEASE_indication,	/* -> UU, SRC */
	SSCOP_RELEASE_confirm,		/* -> */

	SSCOP_DATA_request,		/* <- MU */
	SSCOP_DATA_indication,		/* -> MU, SN */

	SSCOP_UDATA_request,		/* <- MU */
	SSCOP_UDATA_indication,		/* -> MU */

	SSCOP_RECOVER_indication,	/* -> */
	SSCOP_RECOVER_response,		/* <- */

	SSCOP_RESYNC_request,		/* <- UU */
	SSCOP_RESYNC_indication,	/* -> UU */
	SSCOP_RESYNC_response,		/* <- */
	SSCOP_RESYNC_confirm,		/* -> */

	SSCOP_RETRIEVE_request,		/* <- RN */
	SSCOP_RETRIEVE_indication,	/* -> MU */
	SSCOP_RETRIEVE_COMPL_indication,/* -> */
};

enum sscop_maasig {
	SSCOP_MDATA_request,		/* <- MU */
	SSCOP_MDATA_indication,		/* -> MU */
	SSCOP_MERROR_indication,	/* -> CODE, CNT */
};

/*
 * Values for retrieval. Numbers in SSCOP are 24bit, so
 * we can use the large values
 */
enum {
	SSCOP_MAXSEQNO		= 0xffffff,

	SSCOP_RETRIEVE_UNKNOWN	= SSCOP_MAXSEQNO + 1,
	SSCOP_RETRIEVE_TOTAL	= SSCOP_MAXSEQNO + 2,
};

/*
 * SSCOP states
 */
enum sscop_state {
	SSCOP_IDLE,		/* initial state */
	SSCOP_OUT_PEND,		/* outgoing connection pending */
	SSCOP_IN_PEND,		/* incoming connection pending */
	SSCOP_OUT_DIS_PEND,	/* outgoing disconnect pending */
	SSCOP_OUT_RESYNC_PEND,	/* outgoing resynchronisation pending */
	SSCOP_IN_RESYNC_PEND,	/* incoming resynchronisation pending */
	SSCOP_OUT_REC_PEND,	/* outgoing recovery pending */
	SSCOP_REC_PEND,		/* recovery response pending */
	SSCOP_IN_REC_PEND,	/* incoming recovery pending */
	SSCOP_READY,		/* data transfer ready */
};
#define SSCOP_NSTATES 10

struct sscop_param {
	uint32_t	timer_cc;	/* timer_cc in msec */
	uint32_t	timer_poll;	/* timer_poll im msec */
	uint32_t	timer_keep_alive;/* timer_keep_alive in msec */
	uint32_t	timer_no_response;/*timer_no_response in msec */
	uint32_t	timer_idle;	/* timer_idle in msec */
	uint32_t	maxk;		/* maximum user data in bytes */
	uint32_t	maxj;		/* maximum u-u info in bytes */
	uint32_t	maxcc;		/* max. retransmissions for control packets */
	uint32_t	maxpd;		/* max. vt(pd) before sending poll */
	uint32_t	maxstat;	/* max. number of elements in stat list */
	uint32_t	mr;		/* initial window */
	uint32_t	flags;		/* flags */
};
enum {
	SSCOP_ROBUST 	= 0x0001,	/* atmf/97-0216 robustness */
	SSCOP_POLLREX	= 0x0002,	/* send POLL after retransmit */
};

enum {
	SSCOP_SET_TCC		= 0x0001,
	SSCOP_SET_TPOLL		= 0x0002,
	SSCOP_SET_TKA		= 0x0004,
	SSCOP_SET_TNR		= 0x0008,
	SSCOP_SET_TIDLE		= 0x0010,
	SSCOP_SET_MAXK		= 0x0020,
	SSCOP_SET_MAXJ		= 0x0040,
	SSCOP_SET_MAXCC		= 0x0080,
	SSCOP_SET_MAXPD		= 0x0100,
	SSCOP_SET_MAXSTAT	= 0x0200,
	SSCOP_SET_MR		= 0x0400,
	SSCOP_SET_ROBUST	= 0x0800,
	SSCOP_SET_POLLREX	= 0x1000,

	SSCOP_SET_ALLMASK	= 0x1fff,
};

enum {
	SSCOP_DBG_USIG	= 0x0001,
	SSCOP_DBG_TIMER	= 0x0002,
	SSCOP_DBG_BUG	= 0x0004,
	SSCOP_DBG_INSIG	= 0x0008,
	SSCOP_DBG_STATE	= 0x0010,
	SSCOP_DBG_PDU	= 0x0020,
	SSCOP_DBG_ERR	= 0x0040,
	SSCOP_DBG_EXEC	= 0x0080,
	SSCOP_DBG_FLOW	= 0x0100,
};

#endif


code:
/*
 * Copyright (c) 2001-2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 *
 * $Begemot: libunimsg/netnatm/sig/uni.h,v 1.5 2004/07/08 08:22:24 brandt Exp $
 *
 * Public UNI interface
 */
#ifndef _NETNATM_SIG_UNI_H_
#define _NETNATM_SIG_UNI_H_

#include <netnatm/sig/unidef.h>

struct uni;

/* functions to be supplied by the user */
struct uni_funcs {
	/* output to the upper layer */
	void	(*uni_output)(struct uni *, void *, enum uni_sig,
		    uint32_t, struct uni_msg *);

	/* output to the SAAL */
	void	(*saal_output)(struct uni *, void *, enum saal_sig,
		    struct uni_msg *);

	/* verbosity */
	void	(*verbose)(struct uni *, void *, enum uni_verb,
		    const char *, ...) __printflike(4, 5);

	/* function to 'print' status */
	void	(*status)(struct uni *, void *, void *,
		    const char *, ...) __printflike(4, 5);

#ifndef _KERNEL
	/* start a timer */
	void	*(*start_timer)(struct uni *, void *, u_int,
		    void (*)(void *), void *);

	/* stop a timer */
	void	(*stop_timer)(struct uni *, void *, void *);
#endif
};

/* create a UNI instance */
struct uni *uni_create(void *, const struct uni_funcs *);

/* destroy a UNI instance, free all resources */
void uni_destroy(struct uni *);

/* generate a status report */
void uni_status(struct uni *, void *);

/* get current instance configuration */
void uni_get_config(const struct uni *, struct uni_config *);

/* set new instance configuration */
void uni_set_config(struct uni *, const struct uni_config *,
	uint32_t *, uint32_t *, uint32_t *);

/* input from the SAAL to the instance */
void  uni_saal_input(struct uni *, enum saal_sig, struct uni_msg *);

/* input from the upper layer to the instance */
void uni_uni_input(struct uni *, enum uni_sig, uint32_t, struct uni_msg *);

/* do work on pending signals */
void uni_work(struct uni *);

/* set debuging level */
void uni_set_debug(struct uni *, enum uni_verb, u_int level);
u_int uni_get_debug(const struct uni *, enum uni_verb);

/* reset a UNI instance */
void uni_reset(struct uni *);

/* states */
u_int uni_getcustate(const struct uni *);

/* return a reference to the coding/decoding context */
struct unicx *uni_context(struct uni *);

#endif


code:
/*
 * Copyright (c) 1996-2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 *
 * $Begemot: libunimsg/netnatm/sig/unidef.h,v 1.9 2004/07/08 08:22:24 brandt Exp $
 *
 * UNI public definitions.
 */
#ifndef _ATM_SIG_UNIDEF_H_
#define _ATM_SIG_UNIDEF_H_

#ifdef _KERNEL
#include <sys/stdint.h>
#else
#include <stdint.h>
#endif

/*
 * Debug facilities
 */
#define UNI_DEBUG_FACILITIES		\
	UNI_DEBUG_DEFINE(TIMEOUT)	\
	UNI_DEBUG_DEFINE(RESTART)	\
	UNI_DEBUG_DEFINE(SAAL)		\
	UNI_DEBUG_DEFINE(PARSE)		\
	UNI_DEBUG_DEFINE(CALL)		\
	UNI_DEBUG_DEFINE(WARN)		\
	UNI_DEBUG_DEFINE(COORD)		\
	UNI_DEBUG_DEFINE(API)		\
	UNI_DEBUG_DEFINE(MSG)		\
	UNI_DEBUG_DEFINE(ERR)		\
	UNI_DEBUG_DEFINE(VERIFY)	\

enum uni_verb {
#define UNI_DEBUG_DEFINE(D) UNI_FAC_##D,
	UNI_DEBUG_FACILITIES
#undef UNI_DEBUG_DEFINE

	UNI_MAXFACILITY,
};

/*
 * Default timer values and repeat counts
 */
#define UNI_T301_DEFAULT	180000
#define UNI_T303_DEFAULT	4000
#define UNI_T303_CNT_DEFAULT	2
#define UNI_T308_DEFAULT	30000
#define UNI_T308_CNT_DEFAULT	2
#define UNI_T309_DEFAULT	10000
#define UNI_T310U_DEFAULT	30000
#define UNI_T310N_DEFAULT	10000
#define UNI_T313_DEFAULT	4000
#define UNI_T316_DEFAULT	120000
#define UNI_T316_CNT_DEFAULT	2
#define UNI_T317_DEFAULT	90000
#define UNI_T322_DEFAULT	4000
#define UNI_T322_CNT_DEFAULT	2
#define UNI_T397_DEFAULT	UNI_T301_DEFAULT
#define UNI_T398_DEFAULT	4000
#define UNI_T399U_DEFAULT	(UNI_T303_DEFAULT + UNI_T310U_DEFAULT)
#define UNI_T399N_DEFAULT	(UNI_T303_DEFAULT + UNI_T310N_DEFAULT)

/*
 * Protocol support
 */
enum uni_proto {
	UNIPROTO_UNI40U,	/* UNI4.0 user side */
	UNIPROTO_UNI40N,	/* UNI4.0 network side */
	UNIPROTO_PNNI10,	/* PNNI1.0 */
};
enum uni_popt {
	UNIPROTO_GFP	= 0x0001,	/* enable GFP */
	UNIPROTO_SB_TB	= 0x0002,	/* Coincident Sb-Tb/Tb */

	UNIPROTO_ALLMASK = 0x0003,
};

/*
 * Other options
 */
enum uni_option {
	UNIOPT_GIT_HARD		= 0x0001,	/* harder check of GIT IE */
	UNIOPT_BEARER_HARD	= 0x0002,	/* harder check of BEARER IE */
	UNIOPT_CAUSE_HARD	= 0x0004,	/* harder check of CAUSE IE */

	UNIOPT_ALLMASK		= 0x0007,
};

/*
 * UNI configuration
 */
struct uni_config {
	uint32_t	proto;		/* which protocol */
	uint32_t	popt;		/* protocol option */
	uint32_t	option;		/* other options */
	uint32_t	timer301;	/* T301 */
	uint32_t	timer303;	/* T303 */
	uint32_t	init303;	/* T303 retransmission count */
	uint32_t	timer308;	/* T308 */
	uint32_t	init308;	/* T308 retransmission count */
	uint32_t	timer309;	/* T309 */
	uint32_t	timer310;	/* T310 */
	uint32_t	timer313;	/* T313 */
	uint32_t	timer316;	/* T316 */
	uint32_t	init316;	/* T316 retransmission count */
	uint32_t	timer317;	/* T317 */
	uint32_t	timer322;	/* T322 */
	uint32_t	init322;	/* T322 retransmission count */
	uint32_t	timer397;	/* T397 */
	uint32_t	timer398;	/* T398 */
	uint32_t	timer399;	/* T399 */
};
enum uni_config_mask {
	UNICFG_PROTO	= 0x00000001,
	UNICFG_TIMER301	= 0x00000002,
	UNICFG_TIMER303	= 0x00000004,
	UNICFG_INIT303	= 0x00000008,
	UNICFG_TIMER308	= 0x00000010,
	UNICFG_INIT308	= 0x00000020,
	UNICFG_TIMER309	= 0x00000040,
	UNICFG_TIMER310	= 0x00000080,
	UNICFG_TIMER313	= 0x00000100,
	UNICFG_TIMER316	= 0x00000200,
	UNICFG_INIT316	= 0x00000400,
	UNICFG_TIMER317	= 0x00000800,
	UNICFG_TIMER322	= 0x00001000,
	UNICFG_INIT322	= 0x00002000,
	UNICFG_TIMER397	= 0x00004000,
	UNICFG_TIMER398	= 0x00008000,
	UNICFG_TIMER399	= 0x00010000,

	UNICFG_ALLMASK	= 0x0001ffff,
};

/*
 * API signals
 */
enum uni_sig {
	UNIAPI_ERROR			= 0,	/* UNI -> API */

	UNIAPI_CALL_CREATED		= 1,	/* UNI -> API */
	UNIAPI_CALL_DESTROYED		= 2,	/* UNI -> API */
	UNIAPI_PARTY_CREATED		= 3,	/* UNI -> API */
	UNIAPI_PARTY_DESTROYED		= 4,	/* UNI -> API */

	UNIAPI_LINK_ESTABLISH_request	= 5,	/* API -> UNI */
	UNIAPI_LINK_ESTABLISH_confirm	= 6,	/* UNI -> API */
	UNIAPI_LINK_RELEASE_request	= 7,	/* API -> UNI */
	UNIAPI_LINK_RELEASE_confirm	= 8,	/* UNI -> API */

	UNIAPI_RESET_request		= 9,	/* API -> UNI */
	UNIAPI_RESET_confirm		= 10,	/* UNI -> API */
	UNIAPI_RESET_indication		= 11,	/* UNI -> API */
	UNIAPI_RESET_ERROR_indication	= 12,	/* UNI -> API */
	UNIAPI_RESET_response		= 13,	/* API -> UNI */
	UNIAPI_RESET_ERROR_response	= 14,	/* API -> UNI */
	UNIAPI_RESET_STATUS_indication	= 15,	/* UNI -> API */

	UNIAPI_SETUP_request		= 16,	/* API -> UNI */
	UNIAPI_SETUP_indication		= 17,	/* UNI -> API */
	UNIAPI_SETUP_response		= 18,	/* API -> UNI */
	UNIAPI_SETUP_confirm		= 19,	/* UNI -> API */
	UNIAPI_SETUP_COMPLETE_indication= 20,	/* U-UNI -> API */
	UNIAPI_SETUP_COMPLETE_request	= 46,	/* API -> N-UNI */
	UNIAPI_ALERTING_request		= 21,	/* API -> UNI */
	UNIAPI_ALERTING_indication	= 22,	/* UNI -> API */
	UNIAPI_PROCEEDING_request	= 23,	/* API -> UNI */
	UNIAPI_PROCEEDING_indication	= 24,	/* UNI -> API */
	UNIAPI_RELEASE_request		= 25,	/* API -> UNI */
	UNIAPI_RELEASE_indication	= 26,	/* UNI -> API */
	UNIAPI_RELEASE_response		= 27,	/* API -> UNI */
	UNIAPI_RELEASE_confirm		= 28,	/* UNI -> API */
	UNIAPI_NOTIFY_request		= 29,	/* API -> UNI */
	UNIAPI_NOTIFY_indication	= 30,	/* UNI -> API */
	UNIAPI_STATUS_indication	= 31,	/* UNI -> API */
	UNIAPI_STATUS_ENQUIRY_request	= 32,	/* API -> UNI */

	UNIAPI_ADD_PARTY_request	= 33,	/* API -> UNI */
	UNIAPI_ADD_PARTY_indication	= 34,	/* UNI -> API */
	UNIAPI_PARTY_ALERTING_request	= 35,	/* API -> UNI */
	UNIAPI_PARTY_ALERTING_indication= 36,	/* UNI -> API */
	UNIAPI_ADD_PARTY_ACK_request	= 37,	/* API -> UNI */
	UNIAPI_ADD_PARTY_ACK_indication	= 38,	/* UNI -> API */
	UNIAPI_ADD_PARTY_REJ_request	= 39,	/* API -> UNI */
	UNIAPI_ADD_PARTY_REJ_indication	= 40,	/* UNI -> API */
	UNIAPI_DROP_PARTY_request	= 41,	/* API -> UNI */
	UNIAPI_DROP_PARTY_indication	= 42,	/* UNI -> API */
	UNIAPI_DROP_PARTY_ACK_request	= 43,	/* API -> UNI */
	UNIAPI_DROP_PARTY_ACK_indication= 44,	/* UNI -> API */

	UNIAPI_ABORT_CALL_request	= 45,	/* API -> UNI */

	UNIAPI_MAXSIG = 47
};

struct uniapi_error {
	uint32_t	reason;
	uint32_t	state;
};
/* keep this in sync with atmapi.h:enum atmerr */

#define UNIAPI_DEF_ERRORS(MACRO)					\
	MACRO(OK, 0, "no error")					\
	MACRO(ERROR_BAD_SIGNAL,	1, "unknown signal")			\
	MACRO(ERROR_BADCU,	2, "signal in bad co-ordinator state")	\
	MACRO(ERROR_BAD_CALLSTATE, 3, "signal in bad call state")	\
	MACRO(ERROR_BAD_EPSTATE, 4, "signal in bad endpoint state")	\
	MACRO(ERROR_BAD_ARG,	5, "bad argument")			\
	MACRO(ERROR_BAD_CALL,	6, "unknown call reference")		\
	MACRO(ERROR_BAD_PARTY,	7, "unknown party")			\
	MACRO(ERROR_BAD_CTYPE,	8, "bad type of call for signal")	\
	MACRO(ERROR_BAD_IE,	9, "bad information element")		\
	MACRO(ERROR_EPREF_INUSE, 10, "endpoint reference already in use") \
	MACRO(ERROR_MISSING_IE,	11, "missing information element")	\
	MACRO(ERROR_ENCODING,	12, "error during message encoding")	\
	MACRO(ERROR_NOMEM,	13, "out of memory")			\
	MACRO(ERROR_BUSY,	14, "status enquiry busy")

enum {
#define DEF(NAME, VAL, STR) UNIAPI_##NAME = VAL,
UNIAPI_DEF_ERRORS(DEF)
#undef DEF
};

struct uniapi_call_created {
	struct uni_cref		cref;
};
struct uniapi_call_destroyed {
	struct uni_cref		cref;
};
struct uniapi_party_created {
	struct uni_cref		cref;
	struct uni_ie_epref	epref;
};
struct uniapi_party_destroyed {
	struct uni_cref		cref;
	struct uni_ie_epref	epref;
};
struct uniapi_abort_call_request {
	struct uni_cref		cref;
};

struct uniapi_reset_request {
	struct uni_ie_restart	restart;
	struct uni_ie_connid	connid;
};

struct uniapi_reset_confirm {
	struct uni_ie_restart	restart;
	struct uni_ie_connid	connid;
};

struct uniapi_reset_indication {
	struct uni_ie_restart	restart;
	struct uni_ie_connid	connid;

};
struct uniapi_reset_error_indication {
	uint32_t		source;		/* 0 - start, 1 - response */
	uint32_t		reason;
};

#define UNIAPI_DEF_RESET_ERRORS(MACRO)				\
	MACRO(UNIAPI_RESET_ERROR_NO_CONFIRM,		0,	\
	    "no confirmation")					\
	MACRO(UNIAPI_RESET_ERROR_NO_RESPONSE,		1,	\
	    "no response")					\
	MACRO(UNIAPI_RESET_ERROR_PEER_INCOMP_STATE,	2,	\
	    "incompatible state")
enum {
#define DEF(NAME, VALUE, STR) NAME = VALUE,
UNIAPI_DEF_RESET_ERRORS(DEF)
#undef DEF
};

struct uniapi_reset_response {
	struct uni_ie_restart	restart;
	struct uni_ie_connid	connid;
};

struct uniapi_reset_error_response {
	struct uni_ie_cause	cause;
};

struct uniapi_reset_status_indication {
	struct uni_cref		cref;		/* STATUS message CREF */
	struct uni_ie_callstate	callstate;
	struct uni_ie_cause	cause;
};

struct uniapi_setup_request {
	struct uni_setup	setup;
};
struct uniapi_setup_indication {
	struct uni_setup	setup;
};
struct uniapi_setup_response {
	struct uni_connect	connect;
};
struct uniapi_setup_confirm {
	struct uni_connect	connect;
};
struct uniapi_setup_complete_indication {
	struct uni_connect_ack	connect_ack;
};
struct uniapi_setup_complete_request {
	struct uni_connect_ack	connect_ack;
};

struct uniapi_alerting_request {
	struct uni_alerting	alerting;
};

struct uniapi_alerting_indication {
	struct uni_alerting	alerting;
};

struct uniapi_proceeding_request {
	struct uni_call_proc	call_proc;
};

struct uniapi_proceeding_indication {
	struct uni_call_proc	call_proc;
};

struct uniapi_release_request {
	struct uni_release	release;
};
struct uniapi_release_indication {
	struct uni_release	release;
};
struct uniapi_release_response {
	struct uni_release_compl release_compl;
};
/*
 * A release confirm can come from a RELEASE COMPLETE or a RELEASE.
 * Because the IEs in a RELEASE COMPLETE are a subset of a RELEASE,
 * use the RELEASE here.
 */
struct uniapi_release_confirm {
	struct uni_release	release;
};

struct uniapi_notify_request {
	struct uni_notify	notify;
};
struct uniapi_notify_indication {
	struct uni_notify	notify;
};

struct uniapi_status_indication {
	struct uni_cref		cref;
	enum uni_callstate	my_state;
	enum uni_cause		my_cause;
	struct uni_ie_callstate	his_state;
	struct uni_ie_cause	his_cause;
	struct uni_ie_epref	epref;
	struct uni_ie_epstate	epstate;
};
struct uniapi_status_enquiry_request {
	struct uni_cref		cref;
	struct uni_ie_epref	epref;
};

struct uniapi_add_party_request {
	struct uni_add_party	add;
};
struct uniapi_add_party_indication {
	struct uni_add_party	add;
};

struct uniapi_party_alerting_request {
	struct uni_party_alerting alert;
};
struct uniapi_party_alerting_indication {
	struct uni_party_alerting alert;
};

struct uniapi_add_party_ack_request {
	struct uni_add_party_ack ack;
};
struct uniapi_add_party_ack_indication {
	struct uni_add_party_ack ack;
};
struct uniapi_add_party_rej_request {
	struct uni_add_party_rej rej;
};
struct uniapi_add_party_rej_indication {
	struct uni_add_party_rej rej;
};

struct uniapi_drop_party_request {
	struct uni_drop_party	drop;
};
struct uniapi_drop_party_indication {
	struct uni_drop_party	drop;
	struct uni_ie_cause	my_cause;
};

struct uniapi_drop_party_ack_request {
	struct uni_drop_party_ack ack;
};
struct uniapi_drop_party_ack_indication {
	struct uni_drop_party	drop;
	struct uni_ie_crankback	crankback;
};

union uniapi_all {
	struct uniapi_error			error;
	struct uniapi_call_created		call_created;
	struct uniapi_call_destroyed		call_destroyed;
	struct uniapi_party_created		party_created;
	struct uniapi_party_destroyed		party_destroyed;
	struct uniapi_abort_call_request	abort_call_request;
	struct uniapi_reset_request		reset_request;
	struct uniapi_reset_confirm		reset_confirm;
	struct uniapi_reset_indication		reset_indication;
	struct uniapi_reset_error_indication	reset_error_indication;
	struct uniapi_reset_response		reset_response;
	struct uniapi_reset_error_response	reset_error_response;
	struct uniapi_reset_status_indication	reset_status_indication;
	struct uniapi_setup_request		setup_request;
	struct uniapi_setup_indication		setup_indication;
	struct uniapi_setup_response		setup_response;
	struct uniapi_setup_confirm		setup_confirm;
	struct uniapi_setup_complete_indication	setup_complete_indication;
	struct uniapi_setup_complete_request	setup_complete_request;
	struct uniapi_alerting_request		alerting_request;
	struct uniapi_alerting_indication	alerting_indication;
	struct uniapi_proceeding_request	proceeding_request;
	struct uniapi_proceeding_indication	proceeding_indication;
	struct uniapi_release_request		release_request;
	struct uniapi_release_indication	release_indication;
	struct uniapi_release_response		release_response;
	struct uniapi_release_confirm		release_confirm;
	struct uniapi_notify_request		notify_request;
	struct uniapi_notify_indication		notify_indication;
	struct uniapi_status_indication		status_indication;
	struct uniapi_status_enquiry_request	status_enquiry_request;
	struct uniapi_add_party_request		add_party_request;
	struct uniapi_add_party_indication	add_party_indication;
	struct uniapi_party_alerting_request	party_alerting_request;
	struct uniapi_party_alerting_indication	party_alerting_indication;
	struct uniapi_add_party_ack_request	add_party_ack_request;
	struct uniapi_add_party_ack_indication	add_party_ack_indication;
	struct uniapi_add_party_rej_request	add_party_rej_request;
	struct uniapi_add_party_rej_indication	add_party_rej_indication;
	struct uniapi_drop_party_request	drop_party_request;
	struct uniapi_drop_party_indication	drop_party_indication;
	struct uniapi_drop_party_ack_request	drop_party_ack_request;
	struct uniapi_drop_party_ack_indication	drop_party_ack_indication;
};

#endif


code:
/*
 * Copyright (c) 2001-2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 *
 * $Begemot: libunimsg/netnatm/sig/unisig.h,v 1.4 2004/07/08 08:22:26 brandt Exp $
 *
 * Utility functions for signalling stuff
 */
#ifndef _NETNATM_SIG_UNISIG_H_
#define _NETNATM_SIG_UNISIG_H_

#include <netnatm/sig/unidef.h>

/* names */
const char *uni_signame(enum uni_sig);
const char *uni_facname(enum uni_verb);

/* return a string for the error code */
const char *uni_strerr(u_int _err);

/* format an API message */
void uni_print_api(char *_buf, size_t _bufsiz, u_int _type, u_int _cookie,
    const void *_msg, struct unicx *_cx);

#endif


code:
/*
 * Copyright (c) 1996-2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $Begemot: libunimsg/netnatm/unimsg.h,v 1.4 2004/07/08 08:21:46 brandt Exp $
 *
 * This defines the structure of messages as handled by this library.
 */
#ifndef _NETNATM_UNIMSG_H_
#define _NETNATM_UNIMSG_H_

#include <sys/types.h>
#ifdef _KERNEL
#ifdef __FreeBSD__
#include <sys/systm.h>
#endif
#include <sys/stdint.h>
#else
#include <string.h>
#include <stdint.h>
#endif

struct uni_msg {
	u_char		*b_wptr;	/* tail pointer */
	u_char		*b_rptr;	/* head pointer */
	u_char		*b_buf;		/* data buffer */
	u_char		*b_lim;		/* end of data buffer */
};

/* return the current length of the message */
#define uni_msg_len(M)		((size_t)((M)->b_wptr - (M)->b_rptr))

/* return the number of space behind the message */
#define uni_msg_space(M)	((size_t)((M)->b_lim - (M)->b_wptr))

/* return the amount of leading free space */
#define uni_msg_leading(M)	((size_t)((M)->b_rptr - (M)->b_buf))

/* return the maximum size of the message (length plus free space) */
#define uni_msg_size(M)		((size_t)((M)->b_lim - (M)->b_buf));

/* ensure that there is space for another S bytes. If reallocation fails
 * free message and return -1 */
#define uni_msg_ensure(M, S)					\
	((uni_msg_space(M) >= (S)) ? 0 : uni_msg_extend(M, S))

int uni_msg_append(struct uni_msg *, void *, size_t);
int uni_msg_extend(struct uni_msg *, size_t);

#define uni_msg_rptr(MSG, TYPE) ((TYPE)(void *)(MSG)->b_rptr)
#define uni_msg_wptr(MSG, TYPE) ((TYPE)(void *)(MSG)->b_wptr)

int uni_msg_prepend(struct uni_msg *, size_t);

#ifndef _KERNEL

struct uni_msg *uni_msg_alloc(size_t);
struct uni_msg *uni_msg_build(void *, ...);
void uni_msg_destroy(struct uni_msg *);
u_int uni_msg_strip32(struct uni_msg *);
u_int uni_msg_get32(struct uni_msg *);
int uni_msg_append32(struct uni_msg *, u_int);
int uni_msg_append8(struct uni_msg *, u_int);
u_int uni_msg_trail32(const struct uni_msg *, int);
struct uni_msg *uni_msg_dup(const struct uni_msg *);

#endif /* _KERNEL */
#endif


code:
/*
 *  ncp.h
 */
/*-
 *  Copyright (C) 1995 by Volker Lendecke
 *  New version derived from original ncp.h, 1998 Boris Popov
 *
 * $FreeBSD: release/9.0.0/sys/netncp/ncp.h 139823 2005-01-07 01:45:51Z imp $
 */

#ifndef _NETNCP_NCP_H_
#define _NETNCP_NCP_H_

#define NCP_VERMAJ	1
#define NCP_VERMIN	3500
#define NCP_VERSION	(NCP_VERMAJ*100000 + NCP_VERMIN)

typedef u_int32_t	nwdirent;

typedef char		nstr8;
typedef	nstr8*		pnstr8;
typedef u_int8_t	nuint8;
typedef u_int8_t*	pnuint8;
typedef u_int16_t	nuint16;
typedef	nuint16*	pnuint16;
typedef u_int32_t	nuint32;
typedef	nuint32*	pnuint32;

#define NCP_DEFAULT_BUFSIZE 	1024
#define NCP_MAX_BUFSIZE		1024
#define NCP_MAX_PACKET_SIZE 	4070
#define	NCP_MAXUSERNAMELEN	255
#define	NCP_MAXPASSWORDLEN	255
#define NCP_MAXPATHLEN		255
#define NCP_MAX_FILENAME 	14
#define NCP_FILE_ID_LEN		6

#define NCP_BINDERY_USER	0x0001
#define NCP_BINDERY_UGROUP	0x0002
#define NCP_BINDERY_PQUEUE	0x0003
#define NCP_BINDERY_FSERVER	0x0004
#define NCP_BINDERY_PSERVER	0x0007
#define NCP_BINDERY_NAME_LEN	48

/* Handle Flags */
#define	NCP_HF_DIRSHORT		0		/* short directory handle */
#define	NCP_HF_DIRBASE		1		/* directory base */
#define	NCP_HF_NONE		0xff		/* no handle or dirbase */

/* Options to negotiate */
#define	NCP_IPX_CHECKSUM		1
#define	NCP_SECURITY_LEVEL_SIGN_HEADERS	2

#ifndef NWCONN_HANDLE
#define NWCONN_HANDLE   unsigned int
#define pNWCONN_HANDLE  (unsigned int*)
#define NWCONN_NUM      u_int16_t
#define NWCCODE         unsigned int
#define NWDIR_HANDLE    u_int8_t
#define NWFILE_HANDLE   int
#endif

struct ncp_fh_s {
	u_int16_t val1;
	union {
		u_int32_t val32;
		u_int16_t val16;
	} val;
} __packed;

typedef	struct ncp_fh_s ncp_fh;

typedef struct ncpfid_s {
	nwdirent	f_parent;
	nwdirent	f_id;
} ncpfid;

/* -- Bindery properties -- */
struct ncp_bindery_object {
	u_int32_t	object_id;
	u_int16_t	object_type;
	u_int8_t	object_name[NCP_BINDERY_NAME_LEN];
	u_int8_t	object_flags;
	u_int8_t	object_security;
	u_int8_t	object_has_prop;
};

struct nw_property {
	u_int8_t	value[128];
	u_int8_t	more_flag;
	u_int8_t	property_flag;
};

struct ncp_filesearch_info {
	u_int8_t	volume_number;
	u_int16_t	directory_id;
	u_int16_t	sequence_no;
	u_int8_t	access_rights;
};

struct ncp_file_info {
	u_int8_t	file_id[NCP_FILE_ID_LEN];
	char		file_name[NCP_MAX_FILENAME + 1];
	u_int8_t	file_attributes;
	u_int8_t	file_mode;
	u_int32_t	file_length;
	u_int16_t	creation_date;
	u_int16_t	access_date;
	u_int16_t	update_date;
	u_int16_t	update_time;
};

struct nw_queue_job_entry {
	u_int16_t	InUse;
	u_int32_t	prev;
	u_int32_t	next;
	u_int32_t	ClientStation;
	u_int32_t	ClientTask;
	u_int32_t	ClientObjectID;
	u_int32_t	TargetServerID;
	u_int8_t	TargetExecTime[6];
	u_int8_t	JobEntryTime[6];
	u_int32_t	JobNumber;
	u_int16_t	JobType;
	u_int16_t	JobPosition;
	u_int16_t	JobControlFlags;
	u_int8_t	FileNameLen;
	char		JobFileName[13];
	u_int32_t	JobFileHandle;
	u_int32_t	ServerStation;
	u_int32_t	ServerTaskNumber;
	u_int32_t	ServerObjectID;
	char		JobTextDescription[50];
	char		ClientRecordArea[152];
} __packed;

struct queue_job {
	struct nw_queue_job_entry j;
	ncp_fh file_handle;
};

#define QJE_OPER_HOLD	0x80
#define QJE_USER_HOLD	0x40
#define QJE_ENTRYOPEN	0x20
#define QJE_SERV_RESTART    0x10
#define QJE_SERV_AUTO	    0x08

/* ClientRecordArea for print jobs */

#define   KEEP_ON        0x0400
#define   NO_FORM_FEED   0x0800
#define   NOTIFICATION   0x1000
#define   DELETE_FILE    0x2000
#define   EXPAND_TABS    0x4000
#define   PRINT_BANNER   0x8000

struct print_job_record {
	u_int8_t	Version;
	u_int8_t	TabSize;
	u_int16_t	Copies;
	u_int16_t	CtrlFlags;
	u_int16_t	Lines;
	u_int16_t	Rows;
	char		FormName[16];
	u_int8_t	Reserved[6];
	char		BannerName[13];
	char		FnameBanner[13];
	char		FnameHeader[14];
	char		Path[80];
} __packed;

struct ncp_station_addr {
	u_int32_t	NetWork;
	u_int8_t	Node[6];
	u_int16_t	Socket;
} __packed;

struct ncp_prop_login_control {
	u_int8_t	AccountExpireDate[3];
	u_int8_t	Disabled;
	u_int8_t	PasswordExpireDate[3];
	u_int8_t	GraceLogins;
	u_int16_t	PasswordExpireInterval;
	u_int8_t	MaxGraceLogins;
	u_int8_t	MinPasswordLength;
	u_int16_t	MaxConnections;
	u_int8_t	ConnectionTimeMask[42];
	u_int8_t	LastLogin[6];
	u_int8_t	RestrictionMask;
	u_int8_t	reserved;
	u_int32_t	MaxDiskUsage;
	u_int16_t	BadLoginCount;
	u_int32_t	BadLoginCountDown;
	struct ncp_station_addr LastIntruder;
} __packed;

#define NCP_VOLNAME_LEN (16)
#define NCP_NUMBER_OF_VOLUMES (64)
struct ncp_volume_info {
	u_int32_t total_blocks;
	u_int32_t free_blocks;
	u_int32_t purgeable_blocks;
	u_int32_t not_yet_purgeable_blocks;
	u_int32_t total_dir_entries;
	u_int32_t available_dir_entries;
	u_int8_t sectors_per_block;
	char volume_name[NCP_VOLNAME_LEN + 1];
};
/*
 * Name space constants, taken from NDK
 */
#define aRONLY     (ntohl(0x01000000))
#define aHIDDEN    (ntohl(0x02000000))
#define aSYSTEM    (ntohl(0x04000000))
#define aEXECUTE   (ntohl(0x08000000))
#define aDIR       (ntohl(0x10000000))
#define aARCH      (ntohl(0x20000000))

/* Defines for Name Spaces */
#define NW_NS_DOS     0
#define NW_NS_MAC     1
#define NW_NS_NFS     2
#define NW_NS_FTAM    3
#define NW_NS_OS2     4

/* for _ScanNSEntryInfo */
#define	IM_NAME			0x00000001
#define	IM_SPACE_ALLOCATED	0x00000002
#define IM_ATTRIBUTES		0x00000004
#define IM_SIZE			0x00000008
#define IM_TOTAL_SIZE		0x00000010
#define IM_EA			0x00000020
#define IM_ARCHIVE		0x00000040
#define IM_MODIFY		0x00000080
#define IM_CREATION		0x00000100
#define IM_OWNING_NAMESPACE	0x00000200
#define IM_DIRECTORY		0x00000400
#define IM_RIGHTS		0x00000800
#define	IM_ALMOST_ALL		0x00000FED
#define IM_ALL			0x00000FFF
#define	IM_REFERENCE_ID		0x00001000
#define	IM_NS_ATTRIBUTES	0x00002000
#define IM_COMPRESSED_INFO	0x80000000UL

/* open/create modes */
#define OC_MODE_OPEN		0x01
#define OC_MODE_TRUNCATE	0x02
#define OC_MODE_REPLACE		0x02
#define OC_MODE_CREATE		0x08

/* open/create results */
#define OC_ACTION_NONE		0x00
#define OC_ACTION_OPEN		0x01
#define OC_ACTION_CREATE	0x02
#define OC_ACTION_TRUNCATE	0x04
#define OC_ACTION_REPLACE	0x04

/* renameFlag in NSRename */
#define	NW_TYPE_FILE		0x8000
#define	NW_TYPE_SUBDIR		0x0010

#define	NW_NAME_CONVERT		0x0003	/* don't report error and set comp mode */
#define	NW_NO_NAME_CONVERT	0x0004	/* only in specified name space */

/* search attributes */
#ifndef SA_HIDDEN
#define SA_NORMAL         0x0000
#define SA_HIDDEN         0x0002
#define SA_SYSTEM         0x0004
#define SA_SUBDIR_ONLY    0x0010
#define SA_SUBDIR_FILES   0x8000
#define SA_ALL            0x8006
#endif

/* access rights attributes */
#ifndef AR_READ
#define AR_READ			0x0001
#define AR_WRITE		0x0002
#define AR_READ_ONLY		0x0001
#define AR_WRITE_ONLY		0x0002
#define AR_DENY_READ		0x0004
#define AR_DENY_WRITE		0x0008
#define AR_COMPATIBILITY	0x0010
#define AR_WRITE_THROUGH	0x0040
#define AR_OPEN_COMPRESSED	0x0100
#endif

struct nw_entry_info {
	u_int32_t	spaceAlloc;
	u_int32_t	attributes;	/* LH */
	u_int16_t	flags;		/* internal */
	u_int32_t	dataStreamSize;
	u_int32_t	totalStreamSize;
	u_int16_t	numberOfStreams;
	u_int16_t	creationTime;	/* LH */
	u_int16_t	creationDate;	/* LH */
	u_int32_t	creatorID;	/* HL */
	u_int16_t	modifyTime;	/* LH */
	u_int16_t	modifyDate;	/* LH */
	u_int32_t	modifierID;	/* HL */
	u_int16_t	lastAccessDate;	/* LH */
	u_int16_t	archiveTime;	/* LH */
	u_int16_t	archiveDate;	/* LH */
	u_int32_t	archiverID;	/* HL */
	u_int16_t	inheritedRightsMask;	/* LH */
	u_int32_t	dirEntNum;
	u_int32_t	DosDirNum;
	u_int32_t	volNumber;
	u_int32_t	EADataSize;
	u_int32_t	EAKeyCount;
	u_int32_t	EAKeySize;
	u_int32_t	NSCreator;
	u_int8_t	nameLen;
	u_int8_t	entryName[256];
} __packed;

typedef struct nw_entry_info NW_ENTRY_INFO;

/* modify mask - use with MODIFY_DOS_INFO structure */
#define DM_ATTRIBUTES		0x0002L
#define DM_CREATE_DATE		0x0004L
#define DM_CREATE_TIME		0x0008L
#define DM_CREATOR_ID		0x0010L
#define DM_ARCHIVE_DATE		0x0020L
#define DM_ARCHIVE_TIME		0x0040L
#define DM_ARCHIVER_ID		0x0080L
#define DM_MODIFY_DATE		0x0100L
#define DM_MODIFY_TIME		0x0200L
#define DM_MODIFIER_ID		0x0400L
#define DM_LAST_ACCESS_DATE	0x0800L
#define DM_INHERITED_RIGHTS_MASK	0x1000L
#define DM_MAXIMUM_SPACE	0x2000L

struct nw_modify_dos_info {
	u_int32_t attributes;
	u_int16_t creationDate;
	u_int16_t creationTime;
	u_int32_t creatorID;
	u_int16_t modifyDate;
	u_int16_t modifyTime;
	u_int32_t modifierID;
	u_int16_t archiveDate;
	u_int16_t archiveTime;
	u_int32_t archiverID;
	u_int16_t lastAccessDate;
	u_int16_t inheritanceGrantMask;
	u_int16_t inheritanceRevokeMask;
	u_int32_t maximumSpace;
}  __packed;

struct nw_search_seq {
	u_int8_t	volNumber;
	u_int32_t	dirNumber;
	u_int32_t	searchDirNumber;
}  __packed;

typedef struct nw_search_seq SEARCH_SEQUENCE;

struct ncp_file_server_info {
	u_int8_t	ServerName[48];
	u_int8_t	FileServiceVersion;
	u_int8_t	FileServiceSubVersion;
	u_int16_t	MaximumServiceConnections;
	u_int16_t	ConnectionsInUse;
	u_int16_t	NumberMountedVolumes;
	u_int8_t	Revision;
	u_int8_t	SFTLevel;
	u_int8_t	TTSLevel;
	u_int16_t	MaxConnectionsEverUsed;
	u_int8_t	AccountVersion;
	u_int8_t	VAPVersion;
	u_int8_t	QueueVersion;
	u_int8_t	PrintVersion;
	u_int8_t	VirtualConsoleVersion;
	u_int8_t	RestrictionLevel;
	u_int8_t	InternetBridge;
	u_int8_t	Reserved[60];
} __packed;

struct nw_time_buffer {
	u_int8_t	year;
	u_int8_t	month;
	u_int8_t	day;
	u_int8_t	hour;
	u_int8_t	minute;
	u_int8_t	second;
	u_int8_t	wday;
} __packed;

#endif /*_NCP_H_ */


code:
/*
 * static configuration for libncp
 *
 * $FreeBSD: release/9.0.0/sys/netncp/ncp_cfg.h 52153 1999-10-12 11:56:41Z bp $
 */

#define NCP_NLS_KOI2CP866
#define NCP_NLS_DEFAULT NCP_NLS_KOI_866
#define NCP_PREFIX	""


code:
/*-
 * Copyright (c) 1999 Boris Popov
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netncp/ncp_conn.h 206361 2010-04-07 16:50:38Z joel $
 */
#ifndef _NETNCP_NCP_CONN_H_
#define _NETNCP_NCP_CONN_H_

#ifndef _NETINET_IN_H_
#include <netinet/in.h>
#endif

#ifndef _NETIPX_IPX_H_
#include <netipx/ipx.h>
#endif

#ifndef _SYS_SOCKET_H_
#include <sys/socket.h>
#endif

/* type of transport we use */
/*#define	NCP_ON_IPX	0
#define	NCP_ON_TCP	1*/

/* flags field in conn structure */
#define	NCPFL_SOCONN		0x0001	/* socket layer is up */
#define	NCPFL_ATTACHED		0x0002	/* ncp layer is up */
#define	NCPFL_LOGGED		0x0004	/* logged in to server */
#define NCPFL_INVALID		0x0008	/* last request was not completed */
#define	NCPFL_INTR		0x0010	/* interrupted call */
#define	NCPFL_RESTORING		0x0020	/* trying to reconnect */
#define	NCPFL_PERMANENT		0x0040	/* no way to kill conn, when this set */
#define	NCPFL_PRIMARY		0x0080	/* have meaning only for owner */
#define	NCPFL_WASATTACHED	0x0100	/* there was at least one successfull connect */
#define	NCPFL_WASLOGGED		0x0200	/* there was at least one successfull login */
#define	NCPFL_SIGNACTIVE	0x1000	/* packet signing active */
#define	NCPFL_SIGNWANTED	0x2000	/* signing should start */

/* access mode for connection */
#define	NCPM_READ		0400	/* able to fetch conn params */
#define	NCPM_WRITE		0200	/* modify/close */
#define	NCPM_EXECUTE		0100	/* run requests */

#define	NCP_DEFAULT_OWNER	((uid_t)-1)
#define	NCP_DEFAULT_GROUP	((uid_t)-1)

/* args used to create connection */
#define	ncp_conn_loginfo	ncp_conn_args
struct ncp_conn_args {
	int		opt;
#define	NCP_OPT_WDOG		1	/* need watch dog socket */
#define	NCP_OPT_MSG		2	/* need message socket */
#define	NCP_OPT_SIGN		4	/* signatures wanted */
#define NCP_OPT_BIND		8	/* force bindery login */
#define NCP_OPT_PERMANENT	0x10	/* only for refernce, completly ignored */
#define	NCP_OPT_NOUPCASEPASS	0x20	/* leave password as is */
	int		sig_level;	/* wanted signature level */
	char 		server[NCP_BINDERY_NAME_LEN+1];
	char		*user;
	char		*password;
	u_int32_t	objtype;
	union {
		struct sockaddr	addr;
		struct sockaddr_ipx ipxaddr;
		struct sockaddr_in inaddr;
	} addr;
	int	 	timeout;	/* ncp rq timeout */
	int	 	retry_count;	/* counts to give an error */
	uid_t		owner;		/* proposed owner of connection */
	gid_t		group;		/* proposed group of connection */
	mode_t		access_mode;	/* R/W - can do rq's, X - can see the conn */
};

#define ipxaddr		addr.ipxaddr
#define	inaddr		addr.inaddr
#define	saddr		addr.addr

/* user side structure to issue ncp calls */
struct ncp_buf {
	int	rqsize;			/* request size without ncp header */
	int	rpsize;			/* reply size minus ncp header */
	int	cc;			/* completion code */
	int	cs;			/* connection state */
	char	packet[NCP_MAX_PACKET_SIZE];/* Here we prepare requests and receive replies */
};

/*
 * Connection status, returned via sysctl(vfs.nwfs.connstat)
 */
struct ncp_conn_stat {
	struct ncp_conn_args li;
	int		connRef;
	int 		ref_cnt;
	int 		connid;
	int		buffer_size;
	int		flags;
	int 		sign_active;
	uid_t		owner;
	gid_t		group;
	char		user[NCP_MAXUSERNAMELEN+1];
};

#ifdef _KERNEL

#ifndef LK_SHARED
#include <sys/lock.h>
#include <sys/lockmgr.h>
#endif

struct socket;
struct u_cred;

SLIST_HEAD(ncp_conn_head,ncp_conn);

struct ncp_rq;
struct ncp_conn;

/*
 * External and internal processes can reference connection only by handle.
 * This gives us a freedom in maintance of underlying connections.
 */
struct ncp_handle {
	SLIST_ENTRY(ncp_handle)	nh_next;
	int		nh_id;		/* handle id */
	struct ncp_conn*nh_conn;	/* which conn we are refernce */
	struct thread *	nh_td;		/* who owns the handle	*/
	int		nh_ref;		/* one process can asquire many handles, but we return the one */
};

/*
 * Describes any connection to server
 */
struct ncp_conn {
	SLIST_ENTRY(ncp_conn) nc_next;
	struct ncp_conn_args li;
	struct ucred 	*nc_owner;
	gid_t		nc_group;
	int		flags;
	int		nc_id;
	struct socket 	*ncp_so;
	struct socket 	*wdg_so;
	struct socket	*msg_so;
	struct socket 	*bc_so;
	int 		ref_cnt;		/* how many handles leased */
	SLIST_HEAD(ncp_ref_hd,ncp_ref) ref_list;/* list of handles */
	struct lock	nc_lock;		/* excl locks */
	int		nc_lwant;		/* number of wanted locks */
	struct thread	*td;			/* pid currently operates */
	struct ucred	*ucred;			/* usr currently operates */
	/* Fields used to process ncp requests */
	int 		connid;			/* assigned by server */
	u_int8_t	seq;
	int		buffer_size;		/* Negotiated bufsize */
	/* Fields used to make packet signatures */
	u_int32_t	sign_root[2];
	u_int32_t	sign_state[4];		/* md4 state */
#ifdef NCPBURST
	/* Fields used for packet bursting */
	u_long		bc_pktseq;		/* raw packet sequence */
	u_short		bc_seq;			/* burst sequence */
	u_long		bc_locid;		/* local connection id */
	u_long		bc_remid;		/* remote connection id */
	u_long		bc_pktsize;		/* negotiated burst packet size */
#endif
};

int  ncp_conn_init(void);
int  ncp_conn_destroy(void);
int  ncp_conn_alloc(struct ncp_conn_args *cap,
	struct thread *td, struct ucred *cred, struct ncp_conn **connid);
int  ncp_conn_free(struct ncp_conn *conn);
int  ncp_conn_access(struct ncp_conn *conn,struct ucred *cred,mode_t mode);
int  ncp_conn_lock(struct ncp_conn *conn,struct thread *td, struct ucred *cred,int mode);
void ncp_conn_unlock(struct ncp_conn *conn,struct thread *td);
int  ncp_conn_assert_locked(struct ncp_conn *conn,const char *checker,struct thread *td);
void ncp_conn_invalidate(struct ncp_conn *ncp);
int  ncp_conn_invalid(struct ncp_conn *ncp);
/*int  ncp_conn_ref(struct ncp_conn *conn, pid_t pid);
int  ncp_conn_rm_ref(struct ncp_conn *conn, pid_t pid, int force);
void ncp_conn_list_rm_ref(pid_t pid);*/
int  ncp_conn_getbyref(int connRef,struct thread *td, struct ucred *cred, int mode,
	struct ncp_conn **connpp);
int  ncp_conn_getbyli(struct ncp_conn_loginfo *li,struct thread *td, struct ucred *cred,
	int mode, struct ncp_conn **connpp);
int  ncp_conn_setprimary(struct ncp_conn *conn, int on);
int  ncp_conn_locklist(int flags, struct thread *td);
void ncp_conn_unlocklist(struct thread *td);
int  ncp_conn_gethandle(struct ncp_conn *conn, struct thread *td, struct ncp_handle **handle);
int  ncp_conn_puthandle(struct ncp_handle *handle, struct thread *td, int force);
int  ncp_conn_findhandle(int connHandle, struct thread *td, struct ncp_handle **handle);
int  ncp_conn_getattached(struct ncp_conn_args *li,struct thread *td, struct ucred *cred,int mode, struct ncp_conn **connpp);
int  ncp_conn_putprochandles(struct thread *td);
int  ncp_conn_getinfo(struct ncp_conn *ncp, struct ncp_conn_stat *ncs);

int  ncp_conn_reconnect(struct ncp_conn *ncp);
int  ncp_conn_login(struct ncp_conn *conn, struct thread *td, struct ucred *cred);

extern struct ncp_conn_head conn_list;
extern int ncp_burst_enabled;

#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_NCPDATA);
#endif

#endif /* _KERNEL */
#endif /* _NCP_CONN_H_ */