diff options
Diffstat (limited to 'sys/netatm/uni/unisig_encode.c')
-rw-r--r-- | sys/netatm/uni/unisig_encode.c | 1693 |
1 files changed, 0 insertions, 1693 deletions
diff --git a/sys/netatm/uni/unisig_encode.c b/sys/netatm/uni/unisig_encode.c deleted file mode 100644 index 666a3ec946cd..000000000000 --- a/sys/netatm/uni/unisig_encode.c +++ /dev/null @@ -1,1693 +0,0 @@ -/*- - * =================================== - * HARP | Host ATM Research Platform - * =================================== - * - * - * This Host ATM Research Platform ("HARP") file (the "Software") is - * made available by Network Computing Services, Inc. ("NetworkCS") - * "AS IS". NetworkCS does not provide maintenance, improvements or - * support of any kind. - * - * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED, - * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE - * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE. - * In no event shall NetworkCS be responsible for any damages, including - * but not limited to consequential damages, arising from or relating to - * any use of the Software or related support. - * - * Copyright 1994-1998 Network Computing Services, Inc. - * - * Copies of this Software may be made, however, the above copyright - * notice must be reproduced on all copies. - */ - -/* - * ATM Forum UNI 3.0/3.1 Signalling Manager - * ---------------------------------------- - * - * Message formatting module - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/systm.h> -#include <sys/errno.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/syslog.h> -#include <net/if.h> -#include <netatm/port.h> -#include <netatm/queue.h> -#include <netatm/atm.h> -#include <netatm/atm_sys.h> -#include <netatm/atm_sap.h> -#include <netatm/atm_cm.h> -#include <netatm/atm_if.h> -#include <netatm/atm_vc.h> -#include <netatm/atm_sigmgr.h> -#include <netatm/atm_stack.h> -#include <netatm/atm_pcb.h> -#include <netatm/atm_var.h> - -#include <netatm/uni/unisig_var.h> -#include <netatm/uni/unisig_msg.h> -#include <netatm/uni/unisig_mbuf.h> -#include <netatm/uni/unisig_decode.h> - -/* - * Local functions - */ -static int usf_enc_ie(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_aalp(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_clrt(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_bbcp(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_bhli(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_blli(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_clst(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_cdad(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_cdsa(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_cgad(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_cgsa(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_caus(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_cnid(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_qosp(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_brpi(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_rsti(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_bsdc(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_trnt(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_uimp(struct usfmt *, struct ie_generic *); -static int usf_enc_ie_ident(struct usfmt *, struct ie_generic *, - struct ie_decode_tbl *); -static int usf_enc_atm_addr(struct usfmt *, Atm_addr *); - - -/* - * Local variables - */ -static struct { - u_char ident; /* IE identifier */ - int (*encode)(struct usfmt *, struct ie_generic *); - /* Encoding function */ -} ie_table[] = { - { UNI_IE_AALP, usf_enc_ie_aalp }, - { UNI_IE_CLRT, usf_enc_ie_clrt }, - { UNI_IE_BBCP, usf_enc_ie_bbcp }, - { UNI_IE_BHLI, usf_enc_ie_bhli }, - { UNI_IE_BLLI, usf_enc_ie_blli }, - { UNI_IE_CLST, usf_enc_ie_clst }, - { UNI_IE_CDAD, usf_enc_ie_cdad }, - { UNI_IE_CDSA, usf_enc_ie_cdsa }, - { UNI_IE_CGAD, usf_enc_ie_cgad }, - { UNI_IE_CGSA, usf_enc_ie_cgsa }, - { UNI_IE_CAUS, usf_enc_ie_caus }, - { UNI_IE_CNID, usf_enc_ie_cnid }, - { UNI_IE_QOSP, usf_enc_ie_qosp }, - { UNI_IE_BRPI, usf_enc_ie_brpi }, - { UNI_IE_RSTI, usf_enc_ie_rsti }, - { UNI_IE_BLSH, usf_enc_ie_uimp }, - { UNI_IE_BNSH, usf_enc_ie_uimp }, - { UNI_IE_BSDC, usf_enc_ie_bsdc }, - { UNI_IE_TRNT, usf_enc_ie_trnt }, - { UNI_IE_EPRF, usf_enc_ie_uimp }, - { UNI_IE_EPST, usf_enc_ie_uimp }, - { 0, 0 } -}; - -extern struct ie_decode_tbl ie_aal1_tbl[]; -extern struct ie_decode_tbl ie_aal4_tbl_30[]; -extern struct ie_decode_tbl ie_aal4_tbl_31[]; -extern struct ie_decode_tbl ie_aal5_tbl_30[]; -extern struct ie_decode_tbl ie_aal5_tbl_31[]; -extern struct ie_decode_tbl ie_clrt_tbl[]; - - -/* - * Encode a UNI signalling message - * - * Arguments: - * usf pointer to a unisig formatting structure - * msg pointer to a signalling message structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -usf_enc_msg(usf, msg) - struct usfmt *usf; - struct unisig_msg *msg; -{ - int i, len, rc; - u_char c; - u_char *lp0, *lp1; - struct ie_generic *ie; - - union { - short s; - u_char sb[sizeof(short)]; - } su; - - ATM_DEBUG2("usf_enc_msg: usf=%p, msg=%p\n", - usf, msg); - - /* - * Encode the protocol discriminator - */ - c = UNI_MSG_DISC_Q93B; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - /* - * Encode the call reference length - */ - c = 3; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - /* - * Encode the call reference - */ - rc = usf_int3(usf, &msg->msg_call_ref); - if (rc) - return(rc); - - /* - * Encode the message type - */ - rc = usf_byte(usf, &msg->msg_type); - if (rc) - return(rc); - - /* - * Encode the message type extension - */ - c = ((msg->msg_type_flag & UNI_MSG_TYPE_FLAG_MASK) << - UNI_MSG_TYPE_FLAG_SHIFT) + - (msg->msg_type_action & UNI_MSG_TYPE_ACT_MASK) + - UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - /* - * Save the location of the message length and encode a length - * of zero for now. We'll fix the length up at the end. - */ - su.s = 0; - rc = usf_byte_mark(usf, &su.sb[sizeof(short)-2], &lp0); - if (rc) - return(rc); - rc = usf_byte_mark(usf, &su.sb[sizeof(short)-1], &lp1); - if (rc) - return(rc); - - /* - * Process information elements - */ - len = 0; - for (i=0; i<UNI_MSG_IE_CNT; i++) { - ie = msg->msg_ie_vec[i]; - while (ie) { - rc = usf_enc_ie(usf, ie); - if (rc) - return(rc); - len += (ie->ie_length + UNI_IE_HDR_LEN); - ie = ie->ie_next; - } - } - - /* - * Fix the message length in the encoded message - */ - su.s = htons((u_short)len); - *lp0 = su.sb[sizeof(short)-2]; - *lp1 = su.sb[sizeof(short)-1]; - - return(0); -} - - -/* - * Encode an information element - * - * Arguments: - * usf pointer to a UNISIG formatting structure - * msg pointer to a UNISIG message structure - * ie pointer to a generic IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, rc; - u_char c; - u_char *lp0, *lp1; - - union { - short s; - u_char sb[sizeof(short)]; - } su; - - ATM_DEBUG2("usf_enc_ie: usf=%p, ie=%p\n", - usf, ie); - - /* - * Encode the IE identifier - */ - rc = usf_byte(usf, &ie->ie_ident); - if (rc) - return(rc); - - /* - * Encode the extended type - */ - c = ((ie->ie_coding & UNI_IE_CODE_MASK) << UNI_IE_CODE_SHIFT) + - ((ie->ie_flag & UNI_IE_FLAG_MASK) << - UNI_IE_FLAG_SHIFT) + - (ie->ie_action & UNI_IE_ACT_MASK) + - UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - /* - * Mark the current location in the output stream. Encode a - * length of zero for now; we'll come back and fix it up at - * the end. - */ - su.s = 0; - rc = usf_byte_mark(usf, &su.sb[sizeof(short)-2], &lp0); - if (rc) - return(rc); - rc = usf_byte_mark(usf, &su.sb[sizeof(short)-1], &lp1); - if (rc) - return(rc); - - /* - * Look up the information element in the table - */ - for (i=0; (ie->ie_ident != ie_table[i].ident) && - (ie_table[i].encode != NULL); i++) { - } - if (ie_table[i].encode == NULL) { - /* - * Unrecognized IE - */ - return(EINVAL); - } - - /* - * Process the IE by calling the function indicated - * in the IE table - */ - rc = ie_table[i].encode(usf, ie); - if (rc) - return(rc); - - /* - * Set the length in the output stream - */ - su.s = htons((u_short)ie->ie_length); - *lp0 = su.sb[sizeof(short)-2]; - *lp1 = su.sb[sizeof(short)-1]; - - return(0); -} - - -/* - * Encode an AAL parameters information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to an AAL parms IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_aalp(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, rc = 0; - - ATM_DEBUG2("usf_enc_ie_aalp: usf=%p, ie=%p\n", - usf, ie); - - ie->ie_length = 0; - - /* - * Encode the AAL type - */ - if (ie->ie_aalp_aal_type == T_ATM_ABSENT) - return(0); - rc = usf_byte(usf, &ie->ie_aalp_aal_type); - if (rc) - return(rc); - - /* - * Process based on AAL type - */ - switch (ie->ie_aalp_aal_type) { - case UNI_IE_AALP_AT_AAL1: - rc = usf_enc_ie_ident(usf, ie, ie_aal1_tbl); - break; - case UNI_IE_AALP_AT_AAL3: - if (usf->usf_sig->us_proto == ATM_SIG_UNI30) - rc = usf_enc_ie_ident(usf, ie, ie_aal4_tbl_30); - else - rc = usf_enc_ie_ident(usf, ie, ie_aal4_tbl_31); - break; - case UNI_IE_AALP_AT_AAL5: - if (usf->usf_sig->us_proto == ATM_SIG_UNI30) - rc = usf_enc_ie_ident(usf, ie, ie_aal5_tbl_30); - else - rc = usf_enc_ie_ident(usf, ie, ie_aal5_tbl_31); - break; - case UNI_IE_AALP_AT_AALU: - /* - * Encode the user data - */ - i = 0; - while (i < sizeof(ie->ie_aalp_user_info)) { - rc = usf_byte(usf, &ie->ie_aalp_user_info[i]); - if (rc) - break; - i++; - ie->ie_length++; - } - break; - default: - return(EINVAL); - } - - ie->ie_length++; - return(rc); -} - - -/* - * Encode a user cell rate information element - * - * This routine just encodes the parameters required for best - * effort service. - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_clrt(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - - ATM_DEBUG2("usf_enc_ie_clrt: usf=%p, ie=%p\n", - usf, ie); - -#ifdef NOTDEF - /* - * Encode Peak Cell Rate Forward CLP = 0 + 1 - */ - c = UNI_IE_CLRT_FWD_PEAK_01_ID; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - rc = usf_int3(usf, &ie->ie_clrt_fwd_peak_01); - if (rc) - return(rc); - - /* - * Encode Peak Cell Rate Backward CLP = 0 + 1 - */ - c = UNI_IE_CLRT_BKWD_PEAK_01_ID; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - rc = usf_int3(usf, &ie->ie_clrt_bkwd_peak_01); - if (rc) - return(rc); - - /* - * Encode Best Effort Flag - */ - c = UNI_IE_CLRT_BEST_EFFORT_ID; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - /* - * Set IE length - */ - ie->ie_length = 9; -#endif - - /* - * Encode the user cell rate IE using the table - */ - ie->ie_length = 0; - rc = usf_enc_ie_ident(usf, ie, ie_clrt_tbl); - - return(rc); -} - - -/* - * Encode a broadband bearer capability information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_bbcp(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - ATM_DEBUG2("usf_enc_ie_bbcp: usf=%p, ie=%p\n", - usf, ie); - - ie->ie_length = 0; - - /* - * Encode the broadband bearer class - */ - if (ie->ie_bbcp_bearer_class == T_ATM_ABSENT) - return(0); - c = ie->ie_bbcp_bearer_class & UNI_IE_BBCP_BC_MASK; - if (ie->ie_bbcp_bearer_class != UNI_IE_BBCP_BC_BCOB_X) - c |= UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - - /* - * If the broadband bearer class was X, the next - * byte has the traffic type and timing requirements - */ - if (ie->ie_bbcp_bearer_class == UNI_IE_BBCP_BC_BCOB_X) { - c = ((ie->ie_bbcp_traffic_type & UNI_IE_BBCP_TT_MASK) << - UNI_IE_BBCP_TT_SHIFT) + - (ie->ie_bbcp_timing_req & - UNI_IE_BBCP_TR_MASK) + - UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - } - - /* - * Encode the clipping and user plane connection configuration - */ - c = ((ie->ie_bbcp_clipping & UNI_IE_BBCP_SC_MASK) << - UNI_IE_BBCP_SC_SHIFT) + - (ie->ie_bbcp_conn_config & - UNI_IE_BBCP_CC_MASK) + - UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - - return(0); -} - - -/* - * Encode a broadband high layer information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_bhli(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, rc; - u_int type; - - ATM_DEBUG2("usf_enc_ie_bhli: usf=%p, ie=%p\n", - usf, ie); - - ie->ie_length = 0; - - /* - * Encode the high layer information type - */ - if (ie->ie_bhli_type == T_ATM_ABSENT) - return(0); - type = ie->ie_bhli_type | UNI_IE_EXT_BIT; - rc = usf_ext(usf, &type); - if (rc) - return(rc); - ie->ie_length++; - - /* - * What comes next depends on the type - */ - switch (ie->ie_bhli_type) { - case UNI_IE_BHLI_TYPE_ISO: - case UNI_IE_BHLI_TYPE_USER: - /* - * ISO or user-specified parameters -- take the - * length of information from the IE length - */ - for (i=0; i<ie->ie_length-1; i++) { - rc = usf_byte(usf, &ie->ie_bhli_info[i]); - if (rc) - return(rc); - ie->ie_length++; - } - break; - case UNI_IE_BHLI_TYPE_HLP: - /* - * Make sure the IE is long enough for the high - * layer profile information, then get it - */ - if (usf->usf_sig->us_proto != ATM_SIG_UNI30) - return (EINVAL); - for (i=0; i<UNI_IE_BHLI_HLP_LEN; i++) { - rc = usf_byte(usf, &ie->ie_bhli_info[i]); - if (rc) - return(rc); - ie->ie_length++; - } - break; - case UNI_IE_BHLI_TYPE_VSA: - /* - * Make sure the IE is long enough for the vendor- - * specific application information, then get it - */ - for (i=0; i<UNI_IE_BHLI_VSA_LEN; i++) { - rc = usf_byte(usf, &ie->ie_bhli_info[i]); - if (rc) - return(rc); - ie->ie_length++; - } - break; - default: - return(EINVAL); - } - - return(0); -} - - -/* - * Encode a broadband low layer information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_blli(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - u_char c; - int rc; - u_int ipi; - - ATM_DEBUG2("usf_enc_ie_blli: usf=%p, ie=%p\n", - usf, ie); - - ie->ie_length = 0; - - /* - * Encode paramteters for whichever protocol layers the - * user specified - */ - - /* - * Layer 1 information - */ - if (ie->ie_blli_l1_id && ie->ie_blli_l1_id != T_ATM_ABSENT) { - c = (UNI_IE_BLLI_L1_ID << UNI_IE_BLLI_LID_SHIFT) + - (ie->ie_blli_l1_id & - UNI_IE_BLLI_LP_MASK) + - UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - } - - /* - * Layer 2 information - */ - if (ie->ie_blli_l2_id && ie->ie_blli_l2_id != T_ATM_ABSENT) { - c = (UNI_IE_BLLI_L2_ID << UNI_IE_BLLI_LID_SHIFT) + - (ie->ie_blli_l2_id & - UNI_IE_BLLI_LP_MASK); - - switch (ie->ie_blli_l2_id) { - case UNI_IE_BLLI_L2P_X25L: - case UNI_IE_BLLI_L2P_X25M: - case UNI_IE_BLLI_L2P_HDLC1: - case UNI_IE_BLLI_L2P_HDLC2: - case UNI_IE_BLLI_L2P_HDLC3: - case UNI_IE_BLLI_L2P_Q922: - case UNI_IE_BLLI_L2P_ISO7776: - /* - * Write the Layer 2 type - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - - /* - * Encode the Layer 2 mode - */ - if (ie->ie_blli_l2_mode) { - c = (ie->ie_blli_l2_mode & - UNI_IE_BLLI_L2MODE_MASK) << - UNI_IE_BLLI_L2MODE_SHIFT; - if (!ie->ie_blli_l2_window) - c |= UNI_IE_EXT_BIT; - - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - } - - /* - * Encode the Layer 2 window size - */ - if (ie->ie_blli_l2_window) { - c = (ie->ie_blli_l2_window & - UNI_IE_EXT_MASK) + - UNI_IE_EXT_BIT; - - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - } - break; - case UNI_IE_BLLI_L2P_USER: - /* - * Write the Layer 2 type - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - - /* - * Encode the user-specified layer 2 info - */ - c = (ie->ie_blli_l2_user_proto & - UNI_IE_EXT_MASK) + - UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - break; - default: - /* - * Write the Layer 2 type - */ - c |= UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - break; - } - } - - /* - * Layer 3 information - */ - if (ie->ie_blli_l3_id && ie->ie_blli_l3_id != T_ATM_ABSENT) { - /* - * Encode the layer 3 protocol ID - */ - c = (UNI_IE_BLLI_L3_ID << UNI_IE_BLLI_LID_SHIFT) + - (ie->ie_blli_l3_id & - UNI_IE_BLLI_LP_MASK); - - /* - * Process other fields based on protocol ID - */ - switch(ie->ie_blli_l3_id) { - case UNI_IE_BLLI_L3P_X25: - case UNI_IE_BLLI_L3P_ISO8208: - case UNI_IE_BLLI_L3P_ISO8878: - /* - * Write the protocol ID - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - - if (ie->ie_blli_l3_mode || - ie->ie_blli_l3_packet_size || - ie->ie_blli_l3_window) { - c = (ie->ie_blli_l3_mode & - UNI_IE_BLLI_L3MODE_MASK) << - UNI_IE_BLLI_L3MODE_SHIFT; - if (!ie->ie_blli_l3_packet_size && - !ie->ie_blli_l3_window) - c |= UNI_IE_EXT_BIT; - - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - } - - if (ie->ie_blli_l3_packet_size || - ie->ie_blli_l3_window) { - c = ie->ie_blli_l3_packet_size & - UNI_IE_BLLI_L3PS_MASK; - if (!ie->ie_blli_l3_window) - c |= UNI_IE_EXT_BIT; - - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - } - - if (ie->ie_blli_l3_window) { - c = (ie->ie_blli_l3_window & - UNI_IE_EXT_MASK) + - UNI_IE_EXT_BIT; - - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - } - break; - case UNI_IE_BLLI_L3P_USER: - /* - * Write the protocol ID - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - - /* - * Encode the user-specified protocol info - */ - c = (ie->ie_blli_l3_user_proto & - UNI_IE_EXT_MASK) + - UNI_IE_EXT_BIT; - - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - break; - case UNI_IE_BLLI_L3P_ISO9577: - /* - * Write the protocol ID - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - - /* - * Encode the IPI - */ - ipi = ie->ie_blli_l3_ipi << - UNI_IE_BLLI_L3IPI_SHIFT; - rc = usf_ext(usf, &ipi); - if (rc) - return(rc); - ie->ie_length += 2; - - if (ie->ie_blli_l3_ipi == - UNI_IE_BLLI_L3IPI_SNAP) { - c = UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - rc = usf_byte(usf, - &ie->ie_blli_l3_oui[0]); - if (rc) - return(rc); - - rc = usf_byte(usf, - &ie->ie_blli_l3_oui[1]); - if (rc) - return(rc); - - rc = usf_byte(usf, - &ie->ie_blli_l3_oui[2]); - if (rc) - return(rc); - - rc = usf_byte(usf, - &ie->ie_blli_l3_pid[0]); - if (rc) - return(rc); - - rc = usf_byte(usf, - &ie->ie_blli_l3_pid[1]); - if (rc) - return(rc); - - ie->ie_length += 6; - } - break; - default: - /* - * Write the layer 3 protocol ID - */ - c |= UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - break; - } - } - - return(0); -} - - -/* - * Encode a call state information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_clst(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - ATM_DEBUG2("usf_enc_ie_clst: usf=%p, ie=%p\n", - usf, ie); - - c = ie->ie_clst_state & UNI_IE_CLST_STATE_MASK; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length = 1; - - return(0); -} - - -/* - * Encode a called party number information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_cdad(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - u_char c; - int rc; - - ATM_DEBUG2("usf_enc_ie_cdad: usf=%p, ie=%p\n", - usf, ie); - - /* - * Encode the numbering plan - */ - switch(ie->ie_cdad_addr.address_format) { - case T_ATM_E164_ADDR: - c = UNI_IE_CDAD_PLAN_E164 + - (UNI_IE_CDAD_TYPE_INTL - << UNI_IE_CDAD_TYPE_SHIFT); - ie->ie_length = sizeof(Atm_addr_e164) + 1; - break; - case T_ATM_ENDSYS_ADDR: - c = UNI_IE_CDAD_PLAN_NSAP + - (UNI_IE_CDAD_TYPE_UNK - << UNI_IE_CDAD_TYPE_SHIFT); - ie->ie_length = sizeof(Atm_addr_nsap) + 1; - break; - default: - return(EINVAL); - } - c |= UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - /* - * Encode the ATM address - */ - rc = usf_enc_atm_addr(usf, &ie->ie_cdad_addr); - - return(rc); -} - - -/* - * Encode a called party subaddress information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_cdsa(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - u_char c; - int rc; - - /* - * Encode the subaddress type - */ - switch(ie->ie_cdsa_addr.address_format) { - case T_ATM_ENDSYS_ADDR: - c = UNI_IE_CDSA_TYPE_AESA << UNI_IE_CDSA_TYPE_SHIFT; - ie->ie_length = sizeof(Atm_addr_nsap) + 1; - break; - default: - return(EINVAL); - } - c |= UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - /* - * Encode the ATM address - */ - rc = usf_enc_atm_addr(usf, &ie->ie_cdsa_addr); - - return(rc); -} - - -/* - * Encode a calling party number information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_cgad(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - u_char c; - int rc; - - ATM_DEBUG2("usf_enc_ie_cgad: usf=%p, ie=%p\n", - usf, ie); - - /* - * Encode the numbering plan - */ - switch(ie->ie_cgad_addr.address_format) { - case T_ATM_E164_ADDR: - c = UNI_IE_CGAD_PLAN_E164 + - (UNI_IE_CGAD_TYPE_INTL - << UNI_IE_CGAD_TYPE_SHIFT) + - UNI_IE_EXT_BIT; - ie->ie_length = sizeof(Atm_addr_e164) + 1; - break; - case T_ATM_ENDSYS_ADDR: - c = UNI_IE_CGAD_PLAN_NSAP + - (UNI_IE_CGAD_TYPE_UNK - << UNI_IE_CGAD_TYPE_SHIFT) + - UNI_IE_EXT_BIT; - ie->ie_length = sizeof(Atm_addr_nsap) + 1; - break; - default: - return(EINVAL); - } - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - /* - * Encode the presentation and screening indicators - */ -#ifdef NOTDEF - c = ((ie->ie_cgad_pres_ind & UNI_IE_CGAD_PRES_MASK) - << UNI_IE_CGAD_PRES_SHIFT) + - (ie->ie_cgad_screen_ind & - UNI_IE_CGAD_SCR_MASK) + - UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); -#endif - - - /* - * Encode the ATM address - */ - rc = usf_enc_atm_addr(usf, &ie->ie_cgad_addr); - - return(rc); -} - - -/* - * Encode a calling party subaddress information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_cgsa(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - u_char c; - int rc; - - /* - * Encode the subaddress type - */ - switch(ie->ie_cgsa_addr.address_format) { - case T_ATM_ENDSYS_ADDR: - c = UNI_IE_CGSA_TYPE_AESA << UNI_IE_CGSA_TYPE_SHIFT; - ie->ie_length = sizeof(Atm_addr_nsap) + 1; - break; - default: - return(EINVAL); - } - c |= UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - /* - * Encode the ATM address - */ - rc = usf_enc_atm_addr(usf, &ie->ie_cgsa_addr); - - return(rc); -} - - -/* - * Encode a cause information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_caus(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, rc; - u_char c; - - ATM_DEBUG2("usf_enc_ie_caus: usf=%p, ie=%p\n", - usf, ie); - - ie->ie_length = 0; - - /* - * Encode the cause location - */ - c = (ie->ie_caus_loc & UNI_IE_CAUS_LOC_MASK) | UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - - /* - * Encode the cause value - */ - c = ie->ie_caus_cause | UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length++; - - /* - * Encode any included diagnostics - */ - for (i = 0; i < ie->ie_caus_diag_len && - i < sizeof(ie->ie_caus_diagnostic); - i++) { - rc = usf_byte(usf, &ie->ie_caus_diagnostic[i]); - if (rc) - return(rc); - ie->ie_length++; - } - - return(0); -} - - -/* - * Encode a conection identifier information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_cnid(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - ATM_DEBUG2("usf_enc_ie_cnid: usf=%p, ie=%p\n", - usf, ie); - - c = ((ie->ie_cnid_vp_sig & UNI_IE_CNID_VPSIG_MASK) - << UNI_IE_CNID_VPSIG_SHIFT) + - (ie->ie_cnid_pref_excl & UNI_IE_CNID_PREX_MASK) + - UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - rc = usf_short(usf, &ie->ie_cnid_vpci); - if (rc) - return(rc); - rc = usf_short(usf, &ie->ie_cnid_vci); - if (rc) - return(rc); - - ie->ie_length = 5; - return(0); -} - - -/* - * Encode a quality of service parameters information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_qosp(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - - ATM_DEBUG2("usf_enc_ie_qosp: usf=%p, ie=%p\n", - usf, ie); - - /* - * Encode forward QoS class - */ - if (ie->ie_qosp_fwd_class == T_ATM_ABSENT || - ie->ie_qosp_bkwd_class == T_ATM_ABSENT) - return(0); - rc = usf_byte(usf, &ie->ie_qosp_fwd_class); - if (rc) - return(rc); - - /* - * Encode backward QoS class - */ - rc = usf_byte(usf, &ie->ie_qosp_bkwd_class); - - ie->ie_length = 2; - return(rc); -} - - -/* - * Encode a broadband repeat indicator information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_brpi(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - ATM_DEBUG2("usf_enc_ie_brpi: usf=%p, ie=%p\n", - usf, ie); - - /* - * Encode the repeat indicator - */ - c = ie->ie_brpi_ind + UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - - return(rc); -} - - -/* - * Encode a restart indicator information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_rsti(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - ATM_DEBUG2("usf_enc_ie_rsti: usf=%p, ie=%p\n", - usf, ie); - - /* - * Encode the restart class - */ - c = (ie->ie_rsti_class & UNI_IE_RSTI_CLASS_MASK) | - UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - ie->ie_length = 1; - - return(rc); -} - - -/* - * Encode a broadband sending complete information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a broadband sending complete IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_bsdc(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - ATM_DEBUG2("usf_enc_ie_bsdc: usf=%p, ie=%p\n", - usf, ie); - - /* - * Encode the sending complete indicator - */ - c = UNI_IE_BSDC_IND | UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - ie->ie_length = 1; - - return(rc); -} - - -/* - * Encode a transit network selection information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a transit network selection rate IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_trnt(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, rc; - u_char c; - - ATM_DEBUG2("usf_enc_ie_trnt: usf=%p, ie=%p\n", - usf, ie); - - /* - * Encode the sending complete indicator - */ - c = ((ie->ie_trnt_id_type & UNI_IE_TRNT_IDT_MASK) << - UNI_IE_TRNT_IDT_SHIFT) + - (ie->ie_trnt_id_plan & UNI_IE_TRNT_IDP_MASK) + - UNI_IE_EXT_BIT; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_length = 1; - - /* - * Encode the network identification - */ - for (i=0; i<ie->ie_trnt_id_len; i++) { - rc = usf_byte(usf, &ie->ie_trnt_id[i]); - if (rc) - return(rc); - ie->ie_length++; - } - - return(rc); -} - - -/* - * Encode an unsupported IE type - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to an IE structure - * - * Returns: - * 0 success - * - */ -static int -usf_enc_ie_uimp(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - return(0); -} - - -/* - * Encode an information element using field identifiers - * - * The AAL parameters and ATM user cell rate IEs are formatted - * with a one-byte identifier preceding each field. The routine - * encodes these IEs by using a table which relates the field - * identifiers with the fields in the appropriate IE structure. - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a cell rate IE structure - * tbl pointer to an IE decoding table - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_ie_ident(usf, ie, tbl) - struct usfmt *usf; - struct ie_generic *ie; - struct ie_decode_tbl *tbl; -{ - int i, len, rc; - char *cp; - u_int8_t cv; - u_int16_t sv; - u_int32_t iv; - - ATM_DEBUG3("usf_enc_ie_ident: usf=%p, ie=%p, tbl=%p\n", - usf, ie, tbl); - - /* - * Scan through the IE table - */ - len = 0; - for (i=0; tbl[i].ident; i++) { - /* - * Check whether to send the field - */ - cp = (char *) ((intptr_t)ie + tbl[i].f_offs); - if (tbl[i].len == 0) { - if ((*cp == T_NO || *(int8_t *)cp == T_ATM_ABSENT)) - continue; - } else { - switch (tbl[i].f_size) { - case 1: - if (*(int8_t *)cp == T_ATM_ABSENT) - continue; - break; - case 2: - if (*(int16_t *)cp == T_ATM_ABSENT) - continue; - break; - case 4: - if (*(int32_t *)cp == T_ATM_ABSENT) - continue; - break; - default: -badtbl: - log(LOG_ERR, - "uni encode: id=%d,len=%d,off=%d,size=%d\n", - tbl[i].ident, tbl[i].len, - tbl[i].f_offs, tbl[i].f_size); - return (EFAULT); - } - } - - /* - * Encode the field identifier - */ - rc = usf_byte(usf, &tbl[i].ident); - if (rc) - return(rc); - len++; - - /* - * Encode the field value - */ - switch (tbl[i].len) { - case 0: - break; - case 1: - switch (tbl[i].f_size) { - case 1: - cv = *(u_int8_t *)cp; - break; - case 2: - cv = *(u_int16_t *)cp; - break; - case 4: - cv = *(u_int32_t *)cp; - break; - default: - goto badtbl; - } - rc = usf_byte(usf, &cv); - break; - - case 2: - switch (tbl[i].f_size) { - case 2: - sv = *(u_int16_t *)cp; - break; - case 4: - sv = *(u_int32_t *)cp; - break; - default: - goto badtbl; - } - rc = usf_short(usf, &sv); - break; - - case 3: - switch (tbl[i].f_size) { - case 4: - iv = *(u_int32_t *)cp; - break; - default: - goto badtbl; - } - rc = usf_int3(usf, &iv); - break; - - case 4: - switch (tbl[i].f_size) { - case 4: - iv = *(u_int32_t *)cp; - break; - default: - goto badtbl; - } - rc = usf_int(usf, &iv); - break; - - default: - goto badtbl; - } - - len += tbl[i].len; - - if (rc) - return(rc); - } - - ie->ie_length = len; - return(0); -} - - -/* - * Encode an ATM address - * - * Arguments: - * usf pointer to a unisig formatting structure - * addr pointer to an ATM address structure. The address - * type must already be set correctly. - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_enc_atm_addr(usf, addr) - struct usfmt *usf; - Atm_addr *addr; -{ - int len, rc; - u_char *cp; - - /* - * Check the address type - */ - switch (addr->address_format) { - case T_ATM_E164_ADDR: - cp = (u_char *) addr->address; - len = sizeof(Atm_addr_e164); - break; - case T_ATM_ENDSYS_ADDR: - cp = (u_char *) addr->address; - len = sizeof(Atm_addr_nsap); - break; - default: - return(EINVAL); - } - - /* - * Get the address bytes - */ - while (len) { - rc = usf_byte(usf, cp); - if (rc) - return(rc); - len--; - cp++; - } - - return(0); -} |