diff options
Diffstat (limited to 'sys/netatm/uni/unisig_decode.c')
-rw-r--r-- | sys/netatm/uni/unisig_decode.c | 2486 |
1 files changed, 0 insertions, 2486 deletions
diff --git a/sys/netatm/uni/unisig_decode.c b/sys/netatm/uni/unisig_decode.c deleted file mode 100644 index e89f551..0000000 --- a/sys/netatm/uni/unisig_decode.c +++ /dev/null @@ -1,2486 +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/systm.h> -#include <sys/types.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> - -#define ALLOC_IE(ie) do { \ - (ie) = uma_zalloc(unisig_ie_zone, M_NOWAIT | M_ZERO); \ - if ((ie) == NULL) \ - return (ENOMEM); \ -} while (0) - -/* - * Local functions - */ -static int usf_dec_ie(struct usfmt *, struct unisig_msg *, struct ie_generic *); -static int usf_dec_ie_hdr(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_aalp(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_clrt(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_bbcp(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_bhli(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_blli(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_clst(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_cdad(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_cdsa(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_cgad(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_cgsa(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_caus(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_cnid(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_qosp(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_brpi(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_rsti(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_bsdc(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_trnt(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_uimp(struct usfmt *, struct ie_generic *); -static int usf_dec_ie_ident(struct usfmt *, struct ie_generic *, - struct ie_decode_tbl *); -static int usf_dec_atm_addr(struct usfmt *, Atm_addr *, int); - - -/* - * Table associating IE type with IE vector index - */ -u_char unisig_ie_ident_vec[] = { - UNI_IE_AALP, - UNI_IE_CLRT, - UNI_IE_BBCP, - UNI_IE_BHLI, - UNI_IE_BLLI, - UNI_IE_CLST, - UNI_IE_CDAD, - UNI_IE_CDSA, - UNI_IE_CGAD, - UNI_IE_CGSA, - UNI_IE_CAUS, - UNI_IE_CNID, - UNI_IE_QOSP, - UNI_IE_BRPI, - UNI_IE_RSTI, - UNI_IE_BLSH, - UNI_IE_BNSH, - UNI_IE_BSDC, - UNI_IE_TRNT, - UNI_IE_EPRF, - UNI_IE_EPST -}; - - -/* - * Tables specifying which IEs are mandatory, optional, and - * not allowed for each Q.2931 message type - */ -static u_char uni_calp_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_NA, /* Cause */ - IE_OPT, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_OPT, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_conn_ie_tbl[] = { - IE_OPT, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_OPT, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_NA, /* Cause */ - IE_OPT, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_OPT, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_cack_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_NA, /* Cause */ - IE_NA, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_NA, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_setu_ie_tbl[] = { - IE_MAND, /* ATM AAL Parameters (not required by - UNI 3.0) */ - IE_MAND, /* ATM User Cell Rate */ - IE_MAND, /* Broadband Bearer Capability */ - IE_OPT, /* Broadband High Layer Information */ - IE_MAND, /* Broadband Low Layer Information (not required by UNI 3.0 */ - IE_NA, /* Call State */ - IE_MAND, /* Called Party Number */ - IE_OPT, /* Called Party Subaddress */ - IE_OPT, /* Calling Party Number */ - IE_OPT, /* Calling Party Subaddress */ - IE_NA, /* Cause */ - IE_MAND, /* Connection Identifier */ - IE_MAND, /* Quality of Service Parameters */ - IE_OPT, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_OPT, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_OPT, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_rlse_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_MAND, /* Cause */ - IE_NA, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_NA, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_rlsc_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_MAND, /* Cause */ - IE_NA, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_NA, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_rstr_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_NA, /* Cause */ - IE_OPT, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_MAND, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_NA, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_rsta_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_NA, /* Cause */ - IE_OPT, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_MAND, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_NA, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_stat_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_MAND, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_MAND, /* Cause */ - IE_NA, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_OPT, /* Endpoint Reference */ - IE_OPT /* Endpoint State */ -}; - -static u_char uni_senq_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_NA, /* Cause */ - IE_NA, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_OPT, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_addp_ie_tbl[] = { - IE_OPT, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_OPT, /* Broadband High Layer Information */ - IE_OPT, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_MAND, /* Called Party Number */ - IE_OPT, /* Called Party Subaddress */ - IE_OPT, /* Calling Party Number */ - IE_OPT, /* Calling Party Subaddress */ - IE_NA, /* Cause */ - IE_NA, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_OPT, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_MAND, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_adpa_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_NA, /* Cause */ - IE_NA, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_MAND, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_adpr_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_MAND, /* Cause */ - IE_NA, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_MAND, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_drpp_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_MAND, /* Cause */ - IE_NA, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_MAND, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -static u_char uni_drpa_ie_tbl[] = { - IE_NA, /* ATM AAL Parameters */ - IE_NA, /* ATM User Cell Rate */ - IE_NA, /* Broadband Bearer Capability */ - IE_NA, /* Broadband High Layer Information */ - IE_NA, /* Broadband Low Layer Information */ - IE_NA, /* Call State */ - IE_NA, /* Called Party Number */ - IE_NA, /* Called Party Subaddress */ - IE_NA, /* Calling Party Number */ - IE_NA, /* Calling Party Subaddress */ - IE_OPT, /* Cause */ - IE_NA, /* Connection Identifier */ - IE_NA, /* Quality of Service Parameters */ - IE_NA, /* Broadband Repeat Indicator */ - IE_NA, /* Restart Indicator */ - IE_NA, /* Broadband Locking Shift */ - IE_NA, /* Broadband Non-locking Shift */ - IE_NA, /* Broadband Sending Complete */ - IE_NA, /* Transit Net */ - IE_MAND, /* Endpoint Reference */ - IE_NA /* Endpoint State */ -}; - -/* - * Table of Q.2931 message types - */ -static struct { - u_char msg_type; - u_char *msg_ie_tbl; -} uni_msg_types[] = { - { UNI_MSG_CALP, uni_calp_ie_tbl }, - { UNI_MSG_CONN, uni_conn_ie_tbl }, - { UNI_MSG_CACK, uni_cack_ie_tbl }, - { UNI_MSG_SETU, uni_setu_ie_tbl }, - { UNI_MSG_RLSE, uni_rlse_ie_tbl }, - { UNI_MSG_RLSC, uni_rlsc_ie_tbl }, - { UNI_MSG_RSTR, uni_rstr_ie_tbl }, - { UNI_MSG_RSTA, uni_rsta_ie_tbl }, - { UNI_MSG_STAT, uni_stat_ie_tbl }, - { UNI_MSG_SENQ, uni_senq_ie_tbl }, - { UNI_MSG_ADDP, uni_addp_ie_tbl }, - { UNI_MSG_ADPA, uni_adpa_ie_tbl }, - { UNI_MSG_ADPR, uni_adpr_ie_tbl }, - { UNI_MSG_DRPP, uni_drpp_ie_tbl }, - { UNI_MSG_DRPA, uni_drpa_ie_tbl }, -}; - - -/* - * Table of information elements - */ -static struct ie_ent ie_table[] = { - { UNI_IE_AALP, 5, 16, UNI_MSG_IE_AALP, usf_dec_ie_aalp }, - { UNI_IE_CLRT, 0, 26, UNI_MSG_IE_CLRT, usf_dec_ie_clrt }, - { UNI_IE_BBCP, 2, 3, UNI_MSG_IE_BBCP, usf_dec_ie_bbcp }, - { UNI_IE_BHLI, 1, 9, UNI_MSG_IE_BHLI, usf_dec_ie_bhli }, - { UNI_IE_BLLI, 0, 13, UNI_MSG_IE_BLLI, usf_dec_ie_blli }, - { UNI_IE_CLST, 1, 1, UNI_MSG_IE_CLST, usf_dec_ie_clst }, - { UNI_IE_CDAD, 1, 21, UNI_MSG_IE_CDAD, usf_dec_ie_cdad }, - { UNI_IE_CDSA, 1, 21, UNI_MSG_IE_CDSA, usf_dec_ie_cdsa }, - { UNI_IE_CGAD, 1, 22, UNI_MSG_IE_CGAD, usf_dec_ie_cgad }, - { UNI_IE_CGSA, 1, 21, UNI_MSG_IE_CGSA, usf_dec_ie_cgsa }, - { UNI_IE_CAUS, 2, 30, UNI_MSG_IE_CAUS, usf_dec_ie_caus }, - { UNI_IE_CNID, 5, 5, UNI_MSG_IE_CNID, usf_dec_ie_cnid }, - { UNI_IE_QOSP, 2, 2, UNI_MSG_IE_QOSP, usf_dec_ie_qosp }, - { UNI_IE_BRPI, 1, 1, UNI_MSG_IE_BRPI, usf_dec_ie_brpi }, - { UNI_IE_RSTI, 1, 1, UNI_MSG_IE_RSTI, usf_dec_ie_rsti }, - { UNI_IE_BLSH, 1, 1, UNI_MSG_IE_ERR, usf_dec_ie_uimp }, - { UNI_IE_BNSH, 1, 1, UNI_MSG_IE_ERR, usf_dec_ie_uimp }, - { UNI_IE_BSDC, 1, 1, UNI_MSG_IE_BSDC, usf_dec_ie_bsdc }, - { UNI_IE_TRNT, 1, 5, UNI_MSG_IE_TRNT, usf_dec_ie_trnt }, - { UNI_IE_EPRF, 3, 3, UNI_MSG_IE_ERR, usf_dec_ie_uimp }, - { UNI_IE_EPST, 1, 1, UNI_MSG_IE_ERR, usf_dec_ie_uimp }, - { 0, 0, 0, 0, 0 } -}; - -/* - * Decoding table for AAL 1 - */ -struct ie_decode_tbl ie_aal1_tbl[] = { - { 133, 1, IE_OFF_SIZE(ie_aalp_1_subtype) }, - { 134, 1, IE_OFF_SIZE(ie_aalp_1_cbr_rate) }, - { 135, 2, IE_OFF_SIZE(ie_aalp_1_multiplier) }, - { 136, 1, IE_OFF_SIZE(ie_aalp_1_clock_recovery) }, - { 137, 1, IE_OFF_SIZE(ie_aalp_1_error_correction) }, - { 138, 1, IE_OFF_SIZE(ie_aalp_1_struct_data_tran) }, - { 139, 1, IE_OFF_SIZE(ie_aalp_1_partial_cells) }, - { 0, 0, 0, 0 } -}; - -/* - * Decoding table for AAL 3/4 - */ -struct ie_decode_tbl ie_aal4_tbl_30[] = { - { 140, 2, IE_OFF_SIZE(ie_aalp_4_fwd_max_sdu) }, - { 129, 2, IE_OFF_SIZE(ie_aalp_4_bkwd_max_sdu) }, - { 130, 2, IE_OFF_SIZE(ie_aalp_4_mid_range) }, - { 131, 1, IE_OFF_SIZE(ie_aalp_4_mode) }, - { 132, 1, IE_OFF_SIZE(ie_aalp_4_sscs_type) }, - { 0, 0, 0, 0 } -}; -struct ie_decode_tbl ie_aal4_tbl_31[] = { - { 140, 2, IE_OFF_SIZE(ie_aalp_4_fwd_max_sdu) }, - { 129, 2, IE_OFF_SIZE(ie_aalp_4_bkwd_max_sdu) }, - { 130, 4, IE_OFF_SIZE(ie_aalp_4_mid_range) }, - { 132, 1, IE_OFF_SIZE(ie_aalp_4_sscs_type) }, - { 0, 0, 0, 0 } -}; - -/* - * Decoding table for AAL 5 - */ -struct ie_decode_tbl ie_aal5_tbl_30[] = { - { 140, 2, IE_OFF_SIZE(ie_aalp_5_fwd_max_sdu) }, - { 129, 2, IE_OFF_SIZE(ie_aalp_5_bkwd_max_sdu) }, - { 131, 1, IE_OFF_SIZE(ie_aalp_5_mode) }, - { 132, 1, IE_OFF_SIZE(ie_aalp_5_sscs_type) }, - { 0, 0, 0, 0 } -}; -struct ie_decode_tbl ie_aal5_tbl_31[] = { - { 140, 2, IE_OFF_SIZE(ie_aalp_5_fwd_max_sdu) }, - { 129, 2, IE_OFF_SIZE(ie_aalp_5_bkwd_max_sdu) }, - { 132, 1, IE_OFF_SIZE(ie_aalp_5_sscs_type) }, - { 0, 0, 0, 0 } -}; - -/* - * Decoding table for ATM user cell rate - */ -struct ie_decode_tbl ie_clrt_tbl[] = { - {UNI_IE_CLRT_FWD_PEAK_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_peak)}, - {UNI_IE_CLRT_BKWD_PEAK_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_peak)}, - {UNI_IE_CLRT_FWD_PEAK_01_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_peak_01)}, - {UNI_IE_CLRT_BKWD_PEAK_01_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_peak_01)}, - {UNI_IE_CLRT_FWD_SUST_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_sust)}, - {UNI_IE_CLRT_BKWD_SUST_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_sust)}, - {UNI_IE_CLRT_FWD_SUST_01_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_sust_01)}, - {UNI_IE_CLRT_BKWD_SUST_01_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_sust_01)}, - {UNI_IE_CLRT_FWD_BURST_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_burst)}, - {UNI_IE_CLRT_BKWD_BURST_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_burst)}, - {UNI_IE_CLRT_FWD_BURST_01_ID, 3, IE_OFF_SIZE(ie_clrt_fwd_burst_01)}, - {UNI_IE_CLRT_BKWD_BURST_01_ID, 3, IE_OFF_SIZE(ie_clrt_bkwd_burst_01)}, - {UNI_IE_CLRT_BEST_EFFORT_ID, 0, IE_OFF_SIZE(ie_clrt_best_effort)}, - {UNI_IE_CLRT_TM_OPTIONS_ID, 1, IE_OFF_SIZE(ie_clrt_tm_options)}, - {0, 0, 0, 0 } -}; - -/* - * IEs initialized to empty values - */ -struct ie_aalp ie_aalp_absent = { - T_ATM_ABSENT -}; - -struct ie_clrt ie_clrt_absent = { - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT -}; - -struct ie_bbcp ie_bbcp_absent = { - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT -}; - -struct ie_bhli ie_bhli_absent = { - T_ATM_ABSENT, - { 0, 0, 0, 0, 0, 0, 0, 0 } -}; - -struct ie_blli ie_blli_absent = { - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - { 0, 0, 0 }, - { 0, 0 } -}; - -struct ie_clst ie_clst_absent = { - T_ATM_ABSENT -}; - -struct ie_cdad ie_cdad_absent = { - T_ATM_ABSENT, - T_ATM_ABSENT, - { T_ATM_ABSENT, 0 } -}; - -struct ie_cdsa ie_cdsa_absent = { - { T_ATM_ABSENT, 0 } -}; - -struct ie_cgad ie_cgad_absent = { - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - { T_ATM_ABSENT, 0 } -}; - -struct ie_cgsa ie_cgsa_absent = { - { T_ATM_ABSENT, 0 } -}; - -struct ie_caus ie_caus_absent = { - T_ATM_ABSENT, - T_ATM_ABSENT, - 0 -}; - -struct ie_cnid ie_cnid_absent = { - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT, - T_ATM_ABSENT -}; - -struct ie_qosp ie_qosp_absent = { - T_ATM_ABSENT, - T_ATM_ABSENT -}; - -struct ie_brpi ie_brpi_absent = { - T_ATM_ABSENT -}; - -struct ie_rsti ie_rsti_absent = { - T_ATM_ABSENT -}; - -struct ie_blsh ie_blsh_absent = { - T_ATM_ABSENT -}; - -struct ie_bnsh ie_bnsh_absent = { - T_ATM_ABSENT -}; - -struct ie_bsdc ie_bsdc_absent = { - T_ATM_ABSENT -}; - -struct ie_trnt ie_trnt_absent = { - T_ATM_ABSENT, - T_ATM_ABSENT, - 0 -}; - -struct ie_eprf ie_eprf_absent = { - T_ATM_ABSENT, - T_ATM_ABSENT -}; - -struct ie_epst ie_epst_absent = { - T_ATM_ABSENT -}; - - -/* - * Decode 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_dec_msg(usf, msg) - struct usfmt *usf; - struct unisig_msg *msg; -{ - int i, len, rc; - short s; - u_char c, *ie_tbl; - struct ie_generic *ie; - - ATM_DEBUG2("usf_dec_msg: usf=%p, msg=%p\n", usf, msg); - - /* - * Check the total message length - */ - if (usf_count(usf) < UNI_MSG_MIN_LEN) { - return(EIO); - } - - /* - * Get and check the protocol discriminator - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - if (c != UNI_MSG_DISC_Q93B) - return(EIO); - - /* - * Get and check the call reference length - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - if (c != 3) - return(EIO); - - /* - * Get the call reference - */ - rc = usf_int3(usf, &msg->msg_call_ref); - if (rc) - return(rc); - - /* - * Get the message type - */ - rc = usf_byte(usf, &msg->msg_type); - if (rc) - return(rc); - - /* - * Get the message type extension - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - msg->msg_type_flag = (c >> UNI_MSG_TYPE_FLAG_SHIFT) & - UNI_MSG_TYPE_FLAG_MASK; - msg->msg_type_action = c & UNI_MSG_TYPE_ACT_MASK; - - /* - * Get the message length and make sure we actually have - * enough data for the whole message - */ - rc = usf_short(usf, &s); - if (rc) - return(rc); - msg->msg_length = s; - if (usf_count(usf) != msg->msg_length) { - return(EMSGSIZE); - } - - /* - * Process information elements - */ - len = msg->msg_length; - while (len) { - ALLOC_IE(ie); - rc = usf_dec_ie(usf, msg, ie); - if (rc) { - uma_zfree(unisig_ie_zone, ie); - return(rc); - } - len -= (ie->ie_length + UNI_IE_HDR_LEN); - } - - /* - * Make sure that mandatory IEs are included and - * unwanted ones aren't - */ - for (i=0; msg->msg_type!=uni_msg_types[i].msg_type && - uni_msg_types[i].msg_type!=0; i++) { - } - if (!uni_msg_types[i].msg_ie_tbl) - goto done; - - /* - * If the message type is in the table, check the IEs. - * If it isn't, the receive routine will catch the error. - */ - ie_tbl = uni_msg_types[i].msg_ie_tbl; - for (i=0; i<UNI_MSG_IE_CNT-1; i++) { - switch(ie_tbl[i]) { - case IE_MAND: - if (!msg->msg_ie_vec[i]) { - /* - * Mandatory IE missing - */ - ALLOC_IE(ie); - ie->ie_ident = unisig_ie_ident_vec[i]; - ie->ie_err_cause = UNI_IE_CAUS_MISSING; - MSG_IE_ADD(msg, ie, UNI_MSG_IE_ERR); - } - break; - case IE_NA: - if (msg->msg_ie_vec[i]) { - /* - * Disallowed IE present - */ - ie = msg->msg_ie_vec[i]; - msg->msg_ie_vec[i] = - (struct ie_generic *) 0; - MSG_IE_ADD(msg, ie, UNI_MSG_IE_ERR); - while (ie) { - ie->ie_err_cause = - UNI_IE_CAUS_IEEXIST; - ie = ie->ie_next; - } - } - break; - case IE_OPT: - break; - } - } - -done: - return(0); -} - - -/* - * Decode an information element - * - * This routine will be called repeatedly as long as there are - * information elements left to be decoded. It will decode the - * first part of the IE, look its type up in a table, and call - * the appropriate routine to decode the rest. After an IE is - * successfully decoded, it is linked into the UNI signalling - * message structure. If an error is discovered, the IE is linked - * into the IE error chain and an error cause is set in the header. - * - * 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_dec_ie(usf, msg, ie) - struct usfmt *usf; - struct unisig_msg *msg; - struct ie_generic *ie; -{ - int i, ie_index, rc; - - /* - * Decode the IE header (identifier, instruction field, - * and length) - */ - rc = usf_dec_ie_hdr(usf, ie); - if (rc) - return(rc); - /* - * Ignore the IE if it is of zero length. - */ - if (!ie->ie_length) { - uma_zfree(unisig_ie_zone, ie); - return(0); - } - - /* - * Look up the information element in the table - */ - for (i=0; (ie->ie_ident != ie_table[i].ident) && - (ie_table[i].decode != NULL); i++) { - } - if (ie_table[i].decode == NULL) { - /* - * Unrecognized IE - */ - ie_index = UNI_MSG_IE_ERR; - } else { - ie_index = ie_table[i].p_idx; - } - - /* - * Check for unimplemented or unrecognized IEs - */ - if (ie_index == UNI_MSG_IE_ERR) { - ie->ie_err_cause = UNI_IE_CAUS_IEEXIST; - - /* - * Skip over the invalid IE - */ - rc = usf_dec_ie_uimp(usf, ie); - if (rc) - return(rc); - goto done; - } - - /* - * Check the length against the IE table - */ - if (ie->ie_length < ie_table[i].min_len || - ie->ie_length > ie_table[i].max_len) { - ie_index = UNI_MSG_IE_ERR; - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - - /* - * Skip over the invalid IE - */ - rc = usf_dec_ie_uimp(usf, ie); - if (rc) - return(rc); - goto done; - } - - /* - * Process the IE by calling the function indicated - * in the IE table - */ - rc = ie_table[i].decode(usf, ie); - if (rc) - return(rc); - - /* - * Link the IE into the signalling message - */ -done: - if (ie->ie_err_cause) { - ie_index = UNI_MSG_IE_ERR; - } - MSG_IE_ADD(msg, ie, ie_index); - - return(0); -} - - -/* - * Decode an information element header - * - * Arguments: - * usf pointer to a UNISIG formatting structure - * ie pointer to a generic IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_dec_ie_hdr(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - u_char c; - short s; - int rc; - - /* - * Get the IE identifier - */ - rc = usf_byte(usf, &ie->ie_ident); - if (rc) - return(rc); - - /* - * Get the extended type - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_coding = (c >> UNI_IE_CODE_SHIFT) & UNI_IE_CODE_MASK; - ie->ie_flag = (c >> UNI_IE_FLAG_SHIFT) & UNI_IE_FLAG_MASK; - ie->ie_action = c & UNI_IE_ACT_MASK; - - /* - * Get the length. - */ - rc = usf_short(usf, &s); - if (rc) - return(rc); - ie->ie_length = s; - - return(0); -} - - -/* - * Decode 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_dec_ie_aalp(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, rc = 0; - - /* - * Clear the IE - */ - bcopy(&ie_aalp_absent, &ie->ie_u.ie_aalp, - sizeof(ie_aalp_absent)); - - /* - * Get the AAL type - */ - rc = usf_byte(usf, &ie->ie_aalp_aal_type); - if (rc) - return(rc); - - /* - * Subtract the length of the AAL type from the total. - * It will be readjusted after usf_dec_ie_ident is finished. - */ - ie->ie_length--; - - /* - * Process based on AAL type - */ - switch (ie->ie_aalp_aal_type) { - case UNI_IE_AALP_AT_AAL1: - /* - * Clear the AAL 1 subparameters - */ - ie->ie_aalp_1_subtype = T_ATM_ABSENT; - ie->ie_aalp_1_cbr_rate = T_ATM_ABSENT; - ie->ie_aalp_1_multiplier = T_ATM_ABSENT; - ie->ie_aalp_1_clock_recovery = T_ATM_ABSENT; - ie->ie_aalp_1_error_correction = T_ATM_ABSENT; - ie->ie_aalp_1_struct_data_tran = T_ATM_ABSENT; - ie->ie_aalp_1_partial_cells = T_ATM_ABSENT; - - /* - * Parse the AAL fields based on their IDs - */ - rc = usf_dec_ie_ident(usf, ie, ie_aal1_tbl); - break; - case UNI_IE_AALP_AT_AAL3: - /* - * Clear the AAL 3/4 subparameters - */ - ie->ie_aalp_4_fwd_max_sdu = T_ATM_ABSENT; - ie->ie_aalp_4_bkwd_max_sdu = T_ATM_ABSENT; - ie->ie_aalp_4_mid_range = T_ATM_ABSENT; - ie->ie_aalp_4_mode = T_ATM_ABSENT; - ie->ie_aalp_4_sscs_type = T_ATM_ABSENT; - - /* - * Parse the AAL fields based on their IDs - */ - if (usf->usf_sig->us_proto == ATM_SIG_UNI30) - rc = usf_dec_ie_ident(usf, ie, ie_aal4_tbl_30); - else - rc = usf_dec_ie_ident(usf, ie, ie_aal4_tbl_31); - - /* - * If either forward or backward maximum SDU - * size is specified, the other must also be - * specified. - */ - if ((ie->ie_aalp_4_fwd_max_sdu != T_ATM_ABSENT && - ie->ie_aalp_4_bkwd_max_sdu == T_ATM_ABSENT) || - (ie->ie_aalp_4_fwd_max_sdu == T_ATM_ABSENT && - ie->ie_aalp_4_bkwd_max_sdu != T_ATM_ABSENT)) { - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - } - break; - case UNI_IE_AALP_AT_AAL5: - /* - * Clear the AAL 5 subparameters - */ - ie->ie_aalp_5_fwd_max_sdu = T_ATM_ABSENT; - ie->ie_aalp_5_bkwd_max_sdu = T_ATM_ABSENT; - ie->ie_aalp_5_mode = T_ATM_ABSENT; - ie->ie_aalp_5_sscs_type = T_ATM_ABSENT; - - /* - * Parse the AAL fields based on their IDs - */ - if (usf->usf_sig->us_proto == ATM_SIG_UNI30) - rc = usf_dec_ie_ident(usf, ie, ie_aal5_tbl_30); - else - rc = usf_dec_ie_ident(usf, ie, ie_aal5_tbl_31); - - /* - * If either forward or backward maximum SDU - * size is specified, the other must also be - * specified. - */ - if ((ie->ie_aalp_5_fwd_max_sdu != T_ATM_ABSENT && - ie->ie_aalp_5_bkwd_max_sdu == T_ATM_ABSENT) || - (ie->ie_aalp_5_fwd_max_sdu == T_ATM_ABSENT && - ie->ie_aalp_5_bkwd_max_sdu != T_ATM_ABSENT)) { - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - } - break; - case UNI_IE_AALP_AT_AALU: - /* - * Check user parameter length - */ - if (ie->ie_length > - sizeof(ie->ie_aalp_user_info) + - 1) { - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - } - - /* - * Get the user data - */ - i = 0; - while (i < ie->ie_length - 2) { - rc = usf_byte(usf, &ie->ie_aalp_user_info[i]); - if (rc) - break; - i++; - } - break; - default: - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - } - ie->ie_length++; - - return(rc); -} - - -/* - * Decode a user cell rate 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_dec_ie_clrt(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - - /* - * Clear the IE - */ - bcopy(&ie_clrt_absent, &ie->ie_u.ie_clrt, - sizeof(ie_clrt_absent)); - - /* - * Parse the IE using field identifiers - */ - rc = usf_dec_ie_ident(usf, ie, ie_clrt_tbl); - return(rc); -} - - -/* - * Decode 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_dec_ie_bbcp(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_bbcp_absent, &ie->ie_u.ie_bbcp, - sizeof(ie_bbcp_absent)); - - /* - * Get the broadband bearer class - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_bbcp_bearer_class = c & UNI_IE_BBCP_BC_MASK; - - /* - * 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 & UNI_IE_EXT_BIT)) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_bbcp_traffic_type = (c >> UNI_IE_BBCP_TT_SHIFT) & - UNI_IE_BBCP_TT_MASK; - ie->ie_bbcp_timing_req = c & UNI_IE_BBCP_TR_MASK; - } - - /* - * Get the clipping and user plane connection configuration - */ - if (c & UNI_IE_EXT_BIT) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_bbcp_clipping = (c >> UNI_IE_BBCP_SC_SHIFT) & - UNI_IE_BBCP_SC_MASK; - ie->ie_bbcp_conn_config = c & UNI_IE_BBCP_CC_MASK; - } - - return(0); -} - - -/* - * Decode 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_dec_ie_bhli(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_bhli_absent, &ie->ie_u.ie_bhli, - sizeof(ie_bhli_absent)); - - /* - * Get the high layer information type - */ - rc = usf_ext(usf, &i); - ie->ie_bhli_type = i & UNI_IE_EXT_MASK; - if (rc) - return(rc); - - /* - * 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); - } - 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) - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - if (ie->ie_length < UNI_IE_BHLI_HLP_LEN+1) - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - for (i=0; i<ie->ie_length && - i<UNI_IE_BHLI_HLP_LEN; i++) { - rc = usf_byte(usf, &ie->ie_bhli_info[i]); - if (rc) - return(rc); - } - break; - case UNI_IE_BHLI_TYPE_VSA: - /* - * Make sure the IE is long enough for the vendor- - * specific application information, then get it - */ - if (ie->ie_length < UNI_IE_BHLI_VSA_LEN+1) - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - for (i=0; i<ie->ie_length && - i<UNI_IE_BHLI_VSA_LEN; i++) { - rc = usf_byte(usf, &ie->ie_bhli_info[i]); - if (rc) - return(rc); - } - break; - default: - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - for (i=0; i<ie->ie_length; i++) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - } - } - - return(0); -} - - -/* - * Decode 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_dec_ie_blli(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - u_char c, id; - int bc, i, rc; - u_int ipi; - - /* - * Clear the IE - */ - bcopy(&ie_blli_absent, &ie->ie_u.ie_blli, - sizeof(ie_blli_absent)); - - /* - * Get paramteters for the protocol layers as long as - * there is still information left in the IE - */ - bc = ie->ie_length; - while (bc) { - /* - * Get the type and process based on what it is - */ - rc = usf_byte(usf, &id); - if (rc) - return(rc); - switch (((id & UNI_IE_EXT_MASK) >> - UNI_IE_BLLI_LID_SHIFT) & - UNI_IE_BLLI_LID_MASK) { - case UNI_IE_BLLI_L1_ID: - /* - * Layer 1 info - */ - ie->ie_blli_l1_id = id & UNI_IE_BLLI_LP_MASK; - bc--; - break; - case UNI_IE_BLLI_L2_ID: - /* - * Layer 2 info--contents vary based on type - */ - ie->ie_blli_l2_id = id & UNI_IE_BLLI_LP_MASK; - bc--; - if (id & UNI_IE_EXT_BIT) - break; - 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: - rc = usf_byte(usf, &c); - if (rc) - return(rc); - bc--; - ie->ie_blli_l2_mode = (c >> - UNI_IE_BLLI_L2MODE_SHIFT) & - UNI_IE_BLLI_L2MODE_MASK; - if (!(c & UNI_IE_EXT_BIT)) - break; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - bc--; - ie->ie_blli_l2_window = - c & UNI_IE_EXT_MASK; - break; - case UNI_IE_BLLI_L2P_USER: - rc = usf_byte(usf, &c); - if (rc) - return(rc); - bc--; - ie->ie_blli_l2_user_proto = - c & UNI_IE_EXT_MASK; - break; - } - break; - case UNI_IE_BLLI_L3_ID: - /* - * Layer 3 info--contents vary based on type - */ - ie->ie_blli_l3_id = id & UNI_IE_BLLI_LP_MASK; - bc--; - switch (ie->ie_blli_l3_id) { - case UNI_IE_BLLI_L3P_X25: - case UNI_IE_BLLI_L3P_ISO8208: - case UNI_IE_BLLI_L3P_ISO8878: - rc = usf_byte(usf, &c); - if (rc) - return(rc); - bc--; - ie->ie_blli_l3_mode = (c >> - UNI_IE_BLLI_L3MODE_SHIFT) & - UNI_IE_BLLI_L3MODE_MASK; - if (!(c & UNI_IE_EXT_BIT)) - break; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - bc--; - ie->ie_blli_l3_packet_size = - c & UNI_IE_BLLI_L3PS_MASK; - if (!(c & UNI_IE_EXT_BIT)) - break; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - bc--; - ie->ie_blli_l3_window = - c & UNI_IE_EXT_MASK; - break; - case UNI_IE_BLLI_L3P_USER: - rc = usf_byte(usf, &c); - if (rc) - return(rc); - bc--; - ie->ie_blli_l3_mode = - c & UNI_IE_EXT_MASK; - break; - case UNI_IE_BLLI_L3P_ISO9577: - rc = usf_ext(usf, &ipi); - if (rc) - return(rc); - bc -= 2; - ie->ie_blli_l3_ipi = ipi >> - UNI_IE_BLLI_L3IPI_SHIFT; - if (ie->ie_blli_l3_ipi != - UNI_IE_BLLI_L3IPI_SNAP) - break; - - rc = usf_byte(usf, &c); - ie->ie_blli_l3_snap_id = c & UNI_IE_EXT_MASK; - if (rc) - return(rc); - bc --; - - 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); - bc -= 5; - break; - } - break; - default: - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - for (i=0; i<ie->ie_length; i++) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - } - } - } - - return(0); -} - - -/* - * Decode 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_dec_ie_clst(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_clst_absent, &ie->ie_u.ie_clst, - sizeof(ie_clst_absent)); - - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_clst_state = c & UNI_IE_CLST_STATE_MASK; - - return(0); -} - - -/* - * Decode 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_dec_ie_cdad(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int len, rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_cdad_absent, &ie->ie_u.ie_cdad, - sizeof(ie_cdad_absent)); - - /* - * Get and check the numbering plan - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_cdad_plan = c & UNI_IE_CDAD_PLAN_MASK; - len = ie->ie_length - 1; - switch (ie->ie_cdad_plan) { - case UNI_IE_CDAD_PLAN_E164: - ie->ie_cdad_addr.address_format = T_ATM_E164_ADDR; - break; - case UNI_IE_CDAD_PLAN_NSAP: - ie->ie_cdad_addr.address_format = T_ATM_ENDSYS_ADDR; - break; - default: - /* - * Invalid numbering plan - */ - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - while (len) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - len--; - } - - return(0); - } - - /* - * Get the ATM address - */ - rc = usf_dec_atm_addr(usf, &ie->ie_cdad_addr, len); - if (rc == EINVAL) { - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - rc = 0; - } - - return(rc); -} - - -/* - * Decode 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_dec_ie_cdsa(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int len, rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_cdsa_absent, &ie->ie_u.ie_cdsa, - sizeof(ie_cdsa_absent)); - - /* - * Get and check the subaddress type - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - len = ie->ie_length - 1; - if (((c >> UNI_IE_CDSA_TYPE_SHIFT) & UNI_IE_CDSA_TYPE_MASK) != - UNI_IE_CDSA_TYPE_AESA) { - /* - * Invalid subaddress type - */ - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - while (len) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - len--; - } - - return(0); - } - - /* - * Get the ATM address - */ - ie->ie_cdsa_addr.address_format = T_ATM_ENDSYS_ADDR; - rc = usf_dec_atm_addr(usf, &ie->ie_cdsa_addr, len); - if (rc == EINVAL) { - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - rc = 0; - } - - return(rc); -} - - -/* - * Decode 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_dec_ie_cgad(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int len, rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_cgad_absent, &ie->ie_u.ie_cgad, - sizeof(ie_cgad_absent)); - - /* - * Get and check the numbering plan - */ - len = ie->ie_length; - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_cgad_type = (c >> UNI_IE_CGAD_TYPE_SHIFT) & - UNI_IE_CGAD_TYPE_MASK; - ie->ie_cgad_plan = c & UNI_IE_CGAD_PLAN_MASK; - len--; - switch (ie->ie_cgad_plan) { - case UNI_IE_CGAD_PLAN_E164: - ie->ie_cgad_addr.address_format = T_ATM_E164_ADDR; - break; - case UNI_IE_CGAD_PLAN_NSAP: - ie->ie_cgad_addr.address_format = T_ATM_ENDSYS_ADDR; - break; - default: - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - while (len) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - len--; - } - - return(0); - } - - /* - * Get the presentation and screening indicators, if present - */ - if (!(c & UNI_IE_EXT_BIT)) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - len--; - ie->ie_cgad_pres_ind = (c >> UNI_IE_CGAD_PRES_SHIFT) & - UNI_IE_CGAD_PRES_MASK; - ie->ie_cgad_screen_ind = c & UNI_IE_CGAD_SCR_MASK; - } else { - ie->ie_cgad_pres_ind = 0; - ie->ie_cgad_screen_ind =0; - } - - /* - * Get the ATM address - */ - rc = usf_dec_atm_addr(usf, &ie->ie_cgad_addr, len); - if (rc == EINVAL) { - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - rc = 0; - } - - return(rc); -} - - -/* - * Decode 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_dec_ie_cgsa(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int len, rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_cgsa_absent, &ie->ie_u.ie_cgsa, - sizeof(ie_cgsa_absent)); - - /* - * Get and check the subaddress type - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - len = ie->ie_length - 1; - if (((c >> UNI_IE_CGSA_TYPE_SHIFT) & UNI_IE_CGSA_TYPE_MASK) != - UNI_IE_CGSA_TYPE_AESA) { - /* - * Invalid subaddress type - */ - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - while (len) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - len--; - } - - return(0); - } - - /* - * Get the ATM address - */ - ie->ie_cgsa_addr.address_format = T_ATM_ENDSYS_ADDR; - rc = usf_dec_atm_addr(usf, &ie->ie_cgsa_addr, len); - if (rc == EINVAL) { - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - rc = 0; - } - - return(rc); -} - - -/* - * Decode 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_dec_ie_caus(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, len, rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_caus_absent, &ie->ie_u.ie_caus, - sizeof(ie_caus_absent)); - - /* - * Get the cause location - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_caus_loc = c & UNI_IE_CAUS_LOC_MASK; - - /* - * Get the cause value - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_caus_cause = c & UNI_IE_EXT_MASK; - - /* - * Get any included diagnostics - */ - len = ie->ie_length - 2; - for (i = 0, ie->ie_caus_diag_len = 0; - len && i < sizeof(ie->ie_caus_diagnostic); - len--, i++, ie->ie_caus_diag_len++) { - rc = usf_byte(usf, &ie->ie_caus_diagnostic[i]); - if (rc) - return(rc); - } - - return(0); -} - - -/* - * Decode 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_dec_ie_cnid(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, rc; - - /* - * Clear the IE - */ - bcopy(&ie_cnid_absent, &ie->ie_u.ie_cnid, - sizeof(ie_cnid_absent)); - - rc = usf_ext(usf, &i); - if (rc) - return(rc); - ie->ie_cnid_vp_sig = (i >> UNI_IE_CNID_VPSIG_SHIFT) & - UNI_IE_CNID_VPSIG_MASK; - ie->ie_cnid_pref_excl = i & UNI_IE_CNID_PREX_MASK; - - rc = usf_short(usf, &ie->ie_cnid_vpci); - if (rc) - return(rc); - rc = usf_short(usf, &ie->ie_cnid_vci); - return(rc); -} - - -/* - * Decode 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_dec_ie_qosp(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - - /* - * Clear the IE - */ - bcopy(&ie_qosp_absent, &ie->ie_u.ie_qosp, - sizeof(ie_qosp_absent)); - - /* - * Get forward QoS class - */ - rc = usf_byte(usf, &ie->ie_qosp_fwd_class); - if (rc) - return(rc); - - /* - * Get backward QoS class - */ - rc = usf_byte(usf, &ie->ie_qosp_bkwd_class); - - return(rc); -} - - -/* - * Decode 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_dec_ie_brpi(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_brpi_absent, &ie->ie_u.ie_brpi, - sizeof(ie_brpi_absent)); - - /* - * Get the repeat indicator - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - ie->ie_brpi_ind = c & UNI_IE_BRPI_IND_MASK; - - return(0); -} - - -/* - * Decode 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_dec_ie_rsti(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_rsti_absent, &ie->ie_u.ie_rsti, - sizeof(ie_rsti_absent)); - - /* - * Get the restart class - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - ie->ie_rsti_class = c & UNI_IE_RSTI_CLASS_MASK; - - return(0); -} - - -/* - * Decode 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_dec_ie_bsdc(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_bsdc_absent, &ie->ie_u.ie_bsdc, - sizeof(ie_bsdc_absent)); - - /* - * Get the sending complete indicator - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - - /* - * Validate the indicator - */ - c &= UNI_IE_EXT_MASK; - if (c != UNI_IE_BSDC_IND) - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - ie->ie_bsdc_ind = c; - - return(0); -} - - -/* - * Decode a transit network selection information element - * - * Arguments: - * usf pointer to a unisig formatting structure - * ie pointer to a transit network selection IE structure - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_dec_ie_trnt(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, len, rc; - u_char c; - - /* - * Clear the IE - */ - bcopy(&ie_trnt_absent, &ie->ie_u.ie_trnt, - sizeof(ie_trnt_absent)); - - /* - * Get the network ID type and plan - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - ie->ie_trnt_id_type = (c >> UNI_IE_TRNT_IDT_SHIFT) & - UNI_IE_TRNT_IDT_MASK; - ie->ie_trnt_id_plan = c & UNI_IE_TRNT_IDP_MASK; - - /* - * Get the length of the network ID - */ - len = ie->ie_length - 1; - ie->ie_trnt_id_len = MIN(len, sizeof(ie->ie_trnt_id)); - - /* - * Get the network ID - */ - for (i=0; i<len; i++) { - if (i<sizeof(ie->ie_trnt_id)) - rc = usf_byte(usf, &ie->ie_trnt_id[i]); - else - rc = usf_byte(usf, &c); - if (rc) - return(rc); - } - - return(0); -} - - -/* - * Decode an unimplemented 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_dec_ie_uimp(usf, ie) - struct usfmt *usf; - struct ie_generic *ie; -{ - int i, rc; - u_char c; - - /* - * Skip over the IE contents - */ - for (i=0; i<ie->ie_length; i++) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - } - - return(0); -} - - -/* - * Decode 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 - * parses these IEs by using a table which relates the field - * identifiers with the fields in the appropriate IE structure. - * Field order in the received message is immaterial. - * - * 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_dec_ie_ident(usf, ie, tbl) - struct usfmt *usf; - struct ie_generic *ie; - struct ie_decode_tbl *tbl; -{ - int i, len, rc; - u_char c; - u_int8_t cv; - u_int16_t sv; - u_int32_t iv; - void *dest; - - /* - * Scan through the IE - */ - len = ie->ie_length; - while (len) { - /* - * Get the field identifier - */ - rc = usf_byte(usf, &c); - if (rc) - return(rc); - len--; - - /* - * Look up the field in the table - */ - for (i=0; (tbl[i].ident != c) && tbl[i].len; i++) { - } - if (tbl[i].ident == 0) { - /* - * Bad subfield identifier -- flag an - * error and skip over the rest of the IE - */ - ie->ie_err_cause = UNI_IE_CAUS_IECONTENT; - while (len) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - } - return(0); - } - - /* - * Save final destination address - */ - dest = (void *)((intptr_t)ie + tbl[i].f_offs); - - /* - * Get the field value - */ - switch (tbl[i].len) { - case 0: - cv = 1; - goto savec; - - case 1: - rc = usf_byte(usf, &cv); - if (rc) - break; -savec: - /* - * Save field value - */ - switch (tbl[i].f_size) { - case 1: - *(u_int8_t *)dest = cv; - break; - case 2: - *(u_int16_t *)dest = cv; - break; - case 4: - *(u_int32_t *)dest = cv; - break; - default: - goto badtbl; - } - break; - - case 2: - rc = usf_short(usf, &sv); - if (rc) - break; - - /* - * Save field value - */ - switch (tbl[i].f_size) { - case 2: - *(u_int16_t *)dest = sv; - break; - case 4: - *(u_int32_t *)dest = sv; - break; - default: - goto badtbl; - } - break; - - case 3: - rc = usf_int3(usf, &iv); - goto savei; - - case 4: - rc = usf_int(usf, &iv); -savei: - /* - * Save field value - */ - if (rc) - break; - switch (tbl[i].f_size) { - case 4: - *(u_int32_t *)dest = iv; - break; - default: - goto badtbl; - } - break; - - default: -badtbl: - log(LOG_ERR, - "uni decode: id=%d,len=%d,off=%d,size=%d\n", - tbl[i].ident, tbl[i].len, - tbl[i].f_offs, tbl[i].f_size); - rc = EFAULT; - break; - } - - if (rc) - return(rc); - - len -= tbl[i].len; - - } - - return(0); -} - - -/* - * Decode an ATM address - * - * Arguments: - * usf pointer to a unisig formatting structure - * addr pointer to an ATM address structure - * len length of data remainig in the IE - * - * Returns: - * 0 success - * errno error encountered - * - */ -static int -usf_dec_atm_addr(usf, addr, len) - struct usfmt *usf; - Atm_addr *addr; - int len; -{ - int rc; - u_char c, *cp; - - /* - * Check the address type - */ - addr->address_length = len; - switch (addr->address_format) { - case T_ATM_E164_ADDR: - if (len > sizeof(Atm_addr_e164)) { - goto flush; - } - cp = (u_char *) addr->address; - break; - case T_ATM_ENDSYS_ADDR: - if (len != sizeof(Atm_addr_nsap)) { - goto flush; - } - cp = (u_char *) addr->address; - break; - default: - /* Silence the compiler */ - cp = NULL; - } - - /* - * Get the ATM address - */ - while (len) { - rc = usf_byte(usf, cp); - if (rc) - return(rc); - len--; - cp++; - } - - return(0); - -flush: - while (len) { - rc = usf_byte(usf, &c); - if (rc) - return(rc); - len--; - } - - return(EINVAL); -} |