diff options
author | rwatson <rwatson@FreeBSD.org> | 2008-05-25 22:11:40 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2008-05-25 22:11:40 +0000 |
commit | a3623cb733d4a3ddcf8ba280724b8ce3f19a7a58 (patch) | |
tree | afe56b8f23cfc7884850445d064a110b6ac85c9e /sys/netatm/uni/unisig_msg.c | |
parent | 2f956b205ca6c855f85983809448ddc387407d46 (diff) | |
download | FreeBSD-src-a3623cb733d4a3ddcf8ba280724b8ce3f19a7a58.zip FreeBSD-src-a3623cb733d4a3ddcf8ba280724b8ce3f19a7a58.tar.gz |
Remove netatm from HEAD as it is not MPSAFE and relies on the now removed
NET_NEEDS_GIANT. netatm has been disconnected from the build for ten
months in HEAD/RELENG_7. Specifics:
- netatm include files
- netatm command line management tools
- libatm
- ATM parts in rescue and sysinstall
- sample configuration files and documents
- kernel support as a module or in NOTES
- netgraph wrapper nodes for netatm
- ctags data for netatm.
- netatm-specific device drivers.
MFC after: 3 weeks
Reviewed by: bz
Discussed with: bms, bz, harti
Diffstat (limited to 'sys/netatm/uni/unisig_msg.c')
-rw-r--r-- | sys/netatm/uni/unisig_msg.c | 1010 |
1 files changed, 0 insertions, 1010 deletions
diff --git a/sys/netatm/uni/unisig_msg.c b/sys/netatm/uni/unisig_msg.c deleted file mode 100644 index 806102b..0000000 --- a/sys/netatm/uni/unisig_msg.c +++ /dev/null @@ -1,1010 +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 handling module - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/errno.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/kernel.h> -#include <sys/sysctl.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_print.h> - -#include <vm/uma.h> - -/* - * Local functions - */ -static void unisig_rcv_restart(struct unisig *, struct unisig_msg *); -static void unisig_rcv_setup(struct unisig *, struct unisig_msg *); - - -/* - * net.harp.uni.unisig_print_msg - * - * 0 - disable - * 1 - dump UNI message - * 2 - dump UNI message + print decoded form - */ -static int unisig_print_msg = 0; -SYSCTL_INT(_net_harp_uni, OID_AUTO, unisig_print_msg, CTLFLAG_RW, - &unisig_print_msg, 0, "dump UNI messages"); - -/* - * Set a Cause IE based on information in an ATM attribute block - * - * Arguments: - * iep pointer to a cause IE - * aap pointer to attribute block - * - * Returns: - * 0 message sent OK - * errno error encountered - * - */ -void -unisig_cause_from_attr(iep, aap) - struct ie_generic *iep; - Atm_attributes *aap; -{ - /* - * Copy cause info from attribute block to IE - */ - iep->ie_ident = UNI_IE_CAUS; - iep->ie_coding = aap->cause.v.coding_standard; - iep->ie_caus_loc = aap->cause.v.location; - iep->ie_caus_cause = aap->cause.v.cause_value; -} - - -/* - * Set a Cause IE based on information in a UNI signalling message - * - * Arguments: - * iep pointer to a cause IE - * msg pointer to message - * cause cause code for the error - * - * Returns: - * 0 message sent OK - * errno error encountered - * - */ -void -unisig_cause_from_msg(iep, msg, cause) - struct ie_generic *iep; - struct unisig_msg *msg; - int cause; -{ - struct ie_generic *ie1; - int i; - - /* - * Fill out the cause IE fixed fields - */ - iep->ie_ident = UNI_IE_CAUS; - iep->ie_caus_loc = UNI_IE_CAUS_LOC_USER; - iep->ie_caus_cause = cause; - - /* - * Set diagnostics if indicated - */ - switch(cause) { - case UNI_IE_CAUS_IECONTENT: - iep->ie_caus_diag_len = 0; - for (i = 0, ie1 = msg->msg_ie_err; - ie1 && i < UNI_IE_CAUS_MAX_ID; - ie1 = ie1->ie_next) { - if (ie1->ie_err_cause == UNI_IE_CAUS_IECONTENT) { - iep->ie_caus_diagnostic[i] = - ie1->ie_ident; - iep->ie_caus_diag_len++; - i++; - } - } - break; - case UNI_IE_CAUS_REJECT: - iep->ie_caus_diag_len = 2; - iep->ie_caus_diagnostic[0] = UNI_IE_EXT_BIT + - (UNI_IE_CAUS_RR_USER << UNI_IE_CAUS_RR_SHIFT) + - UNI_IE_CAUS_RC_TRANS; - iep->ie_caus_diagnostic[1] = 0; - break; - case UNI_IE_CAUS_MISSING: - iep->ie_caus_diag_len = 0; - for (i = 0, ie1 = msg->msg_ie_err; - ie1 && i < UNI_IE_CAUS_MAX_ID; - ie1 = ie1->ie_next) { - if (ie1->ie_err_cause == UNI_IE_CAUS_MISSING) { - iep->ie_caus_diagnostic[i] = - ie1->ie_ident; - iep->ie_caus_diag_len++; - i++; - } - } - } -} - - -/* - * Send a UNISIG signalling message - * - * Called to send a Q.2931 message. This routine encodes the message - * and hands it to SSCF for transmission. - * - * Arguments: - * usp pointer to UNISIG protocol instance block - * msg pointer to message - * - * Returns: - * 0 message sent OK - * errno error encountered - * - */ -int -unisig_send_msg(usp, msg) - struct unisig *usp; - struct unisig_msg *msg; -{ - int err = 0; - struct usfmt usf; - - ATM_DEBUG2("unisig_send_msg: msg=%p, type=%d\n", msg, - msg->msg_type); - - /* - * Make sure the network is up - */ - if (usp->us_state != UNISIG_ACTIVE) - return(ENETDOWN); - - /* - * Print the message we're sending. - */ - if (unisig_print_msg) - usp_print_msg(msg, UNISIG_MSG_OUT); - - /* - * Convert message to network order - */ - err = usf_init(&usf, usp, (KBuffer *) 0, USF_ENCODE, - usp->us_headout); - if (err) - return(err); - - err = usf_enc_msg(&usf, msg); - if (err) { - ATM_DEBUG1("unisig_send_msg: encode failed with %d\n", - err); - KB_FREEALL(usf.usf_m_base); - return(EIO); - } - - /* - * Print the converted message - */ - if (unisig_print_msg > 1) - unisig_print_mbuf(usf.usf_m_base); - - /* - * Send the message - */ - err = atm_cm_saal_data(usp->us_conn, usf.usf_m_base); - if (err) - KB_FREEALL(usf.usf_m_base); - - return(err); -} - - -/* - * Send a SETUP request - * - * Build and send a Q.2931 SETUP message. - * - * Arguments: - * usp pointer to UNISIG protocol instance block - * uvp pointer to VCCB for which the request is being sent - * - * Returns: - * none - * - */ -int -unisig_send_setup(usp, uvp) - struct unisig *usp; - struct unisig_vccb *uvp; -{ - int err = 0; - struct unisig_msg *setup; - Atm_attributes *ap = &uvp->uv_connvc->cvc_attr; - - ATM_DEBUG1("unisig_send_setup: uvp=%p\n", uvp); - - /* - * Make sure required connection attriutes are set - */ - if (ap->aal.tag != T_ATM_PRESENT || - ap->traffic.tag != T_ATM_PRESENT || - ap->bearer.tag != T_ATM_PRESENT || - ap->called.tag != T_ATM_PRESENT || - ap->qos.tag != T_ATM_PRESENT) { - err = EINVAL; - setup = NULL; - goto done; - } - - /* - * Get memory for a SETUP message - */ - setup = uma_zalloc(unisig_msg_zone, M_ZERO | M_NOWAIT); - if (setup == NULL) { - err = ENOMEM; - goto done; - } - - /* - * Fill in the SETUP message - */ - if (!uvp->uv_call_ref) - uvp->uv_call_ref = unisig_alloc_call_ref(usp); - setup->msg_call_ref = uvp->uv_call_ref; - setup->msg_type = UNI_MSG_SETU; - - /* - * Set IEs from connection attributes - */ - err = unisig_set_attrs(usp, setup, ap); - if (err) - goto done; - - /* - * Attach a Calling Party Number IE if the user didn't - * specify one in the attribute block - */ - if (ap->calling.tag != T_ATM_PRESENT) { - setup->msg_ie_cgad = uma_zalloc(unisig_ie_zone, M_NOWAIT); - if (setup->msg_ie_cgad == NULL) { - err = ENOMEM; - goto done; - } - setup->msg_ie_cgad->ie_ident = UNI_IE_CGAD; - ATM_ADDR_COPY(&usp->us_addr, - &setup->msg_ie_cgad->ie_cgad_addr); - ATM_ADDR_SEL_COPY(&usp->us_addr, - uvp->uv_nif ? uvp->uv_nif->nif_sel : 0, - &setup->msg_ie_cgad->ie_cgad_addr); - } - - /* - * Send the SETUP message - */ - err = unisig_send_msg(usp, setup); - -done: - if (setup) - unisig_free_msg(setup); - - return(err); -} - - -/* - * Send a RELEASE message - * - * Arguments: - * usp pointer to UNISIG protocol instance block - * uvp pointer to VCCB for which the RELEASE is being sent - * msg pointer to UNI signalling message that the RELEASE - * responds to (may be NULL) - * cause the reason for the RELEASE; a value of - * T_ATM_ABSENT indicates that the cause code is - * in the VCC's ATM attributes block - * - * Returns: - * none - * - */ -int -unisig_send_release(usp, uvp, msg, cause) - struct unisig *usp; - struct unisig_vccb *uvp; - struct unisig_msg *msg; - int cause; -{ - int err = 0; - struct unisig_msg *rls_msg; - struct ie_generic *cause_ie; - - ATM_DEBUG2("unisig_send_release: usp=%p, uvp=%p\n", - usp, uvp); - - /* - * Get memory for a RELEASE message - */ - rls_msg = uma_zalloc(unisig_msg_zone, M_ZERO | M_NOWAIT); - if (rls_msg == NULL) { - return(ENOMEM); - } - cause_ie = uma_zalloc(unisig_ie_zone, M_ZERO | M_NOWAIT); - if (cause_ie == NULL) { - uma_zfree(unisig_msg_zone, rls_msg); - return(ENOMEM); - } - - /* - * Fill in the RELEASE message - */ - rls_msg->msg_call_ref = uvp->uv_call_ref; - rls_msg->msg_type = UNI_MSG_RLSE; - rls_msg->msg_type_flag = 0; - rls_msg->msg_type_action = 0; - rls_msg->msg_ie_caus = cause_ie; - - /* - * Fill out the cause IE - */ - cause_ie->ie_ident = UNI_IE_CAUS; - if (cause == T_ATM_ABSENT) { - unisig_cause_from_attr(cause_ie, - &uvp->uv_connvc->cvc_attr); - } else { - cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER; - unisig_cause_from_msg(cause_ie, msg, cause); - } - - /* - * Send the RELEASE - */ - err = unisig_send_msg(usp, rls_msg); - unisig_free_msg(rls_msg); - - return(err); -} - - -/* - * Send a RELEASE COMPLETE message - * - * Arguments: - * usp pointer to UNISIG protocol instance block - * uvp pointer to VCCB for which the RELEASE is being sent. - * NULL indicates that a VCCB wasn't found for a call - * reference value. - * msg pointer to the message which triggered the send - * cause the cause code for the message; a value of - * T_ATM_ABSENT indicates that the cause code is - * in the VCC's ATM attributes block - * - * Returns: - * 0 success - * errno error encountered - * - */ -int -unisig_send_release_complete(usp, uvp, msg, cause) - struct unisig *usp; - struct unisig_vccb *uvp; - struct unisig_msg *msg; - int cause; -{ - int err = 0; - struct unisig_msg *rls_cmp; - struct ie_generic *cause_ie; - - ATM_DEBUG4("unisig_send_release_complete usp=%p, uvp=%p, msg=%p, cause=%d\n", - usp, uvp, msg, cause); - - /* - * Get memory for a RELEASE COMPLETE message - */ - rls_cmp = uma_zalloc(unisig_msg_zone, M_ZERO | M_NOWAIT); - if (rls_cmp == NULL) { - return(ENOMEM); - } - cause_ie = uma_zalloc(unisig_ie_zone, M_ZERO | M_NOWAIT); - if (cause_ie == NULL) { - uma_zfree(unisig_msg_zone, rls_cmp); - return(ENOMEM); - } - - /* - * Fill in the RELEASE COMPLETE message - */ - if (uvp) { - rls_cmp->msg_call_ref = uvp->uv_call_ref; - } else if (msg) { - rls_cmp->msg_call_ref = EXTRACT_CREF(msg->msg_call_ref); - } else { - rls_cmp->msg_call_ref = UNI_MSG_CALL_REF_GLOBAL; - } - rls_cmp->msg_type = UNI_MSG_RLSC; - rls_cmp->msg_type_flag = 0; - rls_cmp->msg_type_action = 0; - rls_cmp->msg_ie_caus = cause_ie; - - /* - * Fill out the cause IE - */ - cause_ie->ie_ident = UNI_IE_CAUS; - if (cause == T_ATM_ABSENT) { - unisig_cause_from_attr(cause_ie, - &uvp->uv_connvc->cvc_attr); - } else { - cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER; - unisig_cause_from_msg(cause_ie, msg, cause); - } - - /* - * Send the RELEASE COMPLETE - */ - err = unisig_send_msg(usp, rls_cmp); - unisig_free_msg(rls_cmp); - - return(err); -} - - -/* - * Send a STATUS message - * - * Arguments: - * usp pointer to UNISIG protocol instance block - * uvp pointer to VCCB for which the STATUS is being sent. - * NULL indicates that a VCCB wasn't found for a call - * reference value. - * msg pointer to the message which triggered the send - * cause the cause code to include in the message - * - * Returns: - * none - * - */ -int -unisig_send_status(usp, uvp, msg, cause) - struct unisig *usp; - struct unisig_vccb *uvp; - struct unisig_msg *msg; - int cause; -{ - int err = 0, i; - struct unisig_msg *stat_msg; - struct ie_generic *cause_ie, *clst_ie, *iep; - - ATM_DEBUG4("unisig_send_status: usp=%p, uvp=%p, msg=%p, cause=%d\n", - usp, uvp, msg, cause); - - /* - * Get memory for a STATUS message - */ - stat_msg = uma_zalloc(unisig_msg_zone, M_ZERO | M_NOWAIT); - if (stat_msg == NULL) { - return(ENOMEM); - } - cause_ie = uma_zalloc(unisig_ie_zone, M_ZERO | M_NOWAIT); - if (cause_ie == NULL) { - uma_zfree(unisig_msg_zone, stat_msg); - return(ENOMEM); - } - clst_ie = uma_zalloc(unisig_ie_zone, M_ZERO | M_NOWAIT); - if (clst_ie == NULL) { - uma_zfree(unisig_msg_zone, stat_msg); - uma_zfree(unisig_ie_zone, cause_ie); - return(ENOMEM); - } - - /* - * Fill in the STATUS message - */ - if (uvp) { - stat_msg->msg_call_ref = uvp->uv_call_ref; - } else if (msg) { - stat_msg->msg_call_ref = - EXTRACT_CREF(msg->msg_call_ref); - } else { - stat_msg->msg_call_ref = UNI_MSG_CALL_REF_GLOBAL; - } - stat_msg->msg_type = UNI_MSG_STAT; - stat_msg->msg_type_flag = 0; - stat_msg->msg_type_action = 0; - stat_msg->msg_ie_clst = clst_ie; - stat_msg->msg_ie_caus = cause_ie; - - /* - * Fill out the call state IE - */ - clst_ie->ie_ident = UNI_IE_CLST; - clst_ie->ie_coding = 0; - clst_ie->ie_flag = 0; - clst_ie->ie_action = 0; - if (uvp) { - clst_ie->ie_clst_state = uvp->uv_sstate; - } else { - clst_ie->ie_clst_state = UNI_NULL; - } - - /* - * Fill out the cause IE - */ - cause_ie->ie_ident = UNI_IE_CAUS; - cause_ie->ie_coding = 0; - cause_ie->ie_flag = 0; - cause_ie->ie_action = 0; - cause_ie->ie_caus_loc = UNI_IE_CAUS_LOC_USER; - cause_ie->ie_caus_cause = cause; - switch (cause) { - case UNI_IE_CAUS_MTEXIST: - case UNI_IE_CAUS_STATE: - if (msg) { - cause_ie->ie_caus_diagnostic[0] = msg->msg_type; - } - break; - case UNI_IE_CAUS_MISSING: - case UNI_IE_CAUS_IECONTENT: - case UNI_IE_CAUS_IEEXIST: - for (i=0, iep=msg->msg_ie_err; - iep && i<UNI_MSG_IE_CNT; - i++, iep = iep->ie_next) { - if (iep->ie_err_cause == cause) { - cause_ie->ie_caus_diagnostic[i] = - iep->ie_ident; - } - } - } - - /* - * Send the STATUS message - */ - err = unisig_send_msg(usp, stat_msg); - unisig_free_msg(stat_msg); - - return(err); -} - - -/* - * Process a RESTART message - * - * Arguments: - * usp pointer to UNISIG protocol instance block - * msg pointer to the RESTART message - * - * Returns: - * none - * - */ -static void -unisig_rcv_restart(usp, msg) - struct unisig *usp; - struct unisig_msg *msg; -{ - struct unisig_vccb *uvp, *uvnext; - struct unisig_msg *rsta_msg; - int s; - - ATM_DEBUG2("unisig_rcv_restart: usp=%p, msg=%p\n", - usp, msg); - - /* - * Check what class of VCCs we're supposed to restart - */ - if (msg->msg_ie_rsti->ie_rsti_class == UNI_IE_RSTI_IND_VC) { - /* - * Just restart the indicated VCC - */ - if (msg->msg_ie_cnid) { - uvp = unisig_find_vpvc(usp, - msg->msg_ie_cnid->ie_cnid_vpci, - msg->msg_ie_cnid->ie_cnid_vci, - 0); - if (uvp && uvp->uv_type & VCC_SVC) { - (void) unisig_clear_vcc(usp, uvp, - T_ATM_CAUSE_NORMAL_CALL_CLEARING); - } - } - } else { - /* - * Restart all VCCs - */ - s = splnet(); - for (uvp=Q_HEAD(usp->us_vccq, struct unisig_vccb); uvp; - uvp=uvnext) { - uvnext = Q_NEXT(uvp, struct unisig_vccb, - uv_sigelem); - if (uvp->uv_type & VCC_SVC) { - (void) unisig_clear_vcc(usp, uvp, - T_ATM_CAUSE_NORMAL_CALL_CLEARING); - } - } - (void) splx(s); - } - - /* - * Get memory for a RESTART ACKNOWLEDGE message - */ - rsta_msg = uma_zalloc(unisig_msg_zone, M_NOWAIT); - if (rsta_msg == NULL) { - return; - } - - /* - * Fill out the message - */ - rsta_msg->msg_call_ref = EXTRACT_CREF(msg->msg_call_ref); - rsta_msg->msg_type = UNI_MSG_RSTA; - rsta_msg->msg_type_flag = 0; - rsta_msg->msg_type_action = 0; - rsta_msg->msg_ie_rsti = msg->msg_ie_rsti; - if (msg->msg_ie_cnid) { - rsta_msg->msg_ie_cnid = msg->msg_ie_cnid; - } - - /* - * Send the message - */ - (void) unisig_send_msg(usp, rsta_msg); - rsta_msg->msg_ie_rsti = NULL; - rsta_msg->msg_ie_cnid = NULL; - unisig_free_msg(rsta_msg); - - return; -} - - -/* - * Process a SETUP message - * - * Arguments: - * usp pointer to UNISIG protocol instance block - * msg pointer to the SETUP message - * - * Returns: - * none - * - */ -static void -unisig_rcv_setup(usp, msg) - struct unisig *usp; - struct unisig_msg *msg; -{ - struct unisig_vccb *uvp = NULL; - struct ie_generic *iep; - - ATM_DEBUG2("unisig_rcv_setup: usp=%p, msg=%p\n", usp, msg); - - /* - * If we already have a VCC with the call reference, - * ignore the SETUP message - */ - uvp = unisig_find_conn(usp, EXTRACT_CREF(msg->msg_call_ref)); - if (uvp) - return; - - /* - * If the call reference flag is incorrectly set, - * ignore the SETUP message - */ - if (msg->msg_call_ref & UNI_MSG_CALL_REF_RMT) - return; - - /* - * If there are missing mandatory IEs, send a - * RELEASE COMPLETE message and ignore the SETUP - */ - for (iep = msg->msg_ie_err; iep; iep = iep->ie_next) { - if (iep->ie_err_cause == UNI_IE_CAUS_MISSING) { - (void) unisig_send_release_complete(usp, - uvp, msg, UNI_IE_CAUS_MISSING); - return; - } - } - - /* - * If there are mandatory IEs with invalid content, send a - * RELEASE COMPLETE message and ignore the SETUP - */ - for (iep = msg->msg_ie_err; iep; iep = iep->ie_next) { - if (iep->ie_err_cause == UNI_IE_CAUS_IECONTENT) { - (void) unisig_send_release_complete(usp, - uvp, msg, - UNI_IE_CAUS_IECONTENT); - return; - } - } - - /* - * Get a new VCCB for the connection - */ - uvp = uma_zalloc(unisig_vc_zone, M_ZERO | M_NOWAIT); - if (uvp == NULL) { - return; - } - - /* - * Put the VCCB on the UNISIG queue - */ - ENQUEUE(uvp, struct unisig_vccb, uv_sigelem, usp->us_vccq); - - /* - * Set the state and call reference value - */ - uvp->uv_sstate = UNI_NULL; - uvp->uv_call_ref = EXTRACT_CREF(msg->msg_call_ref); - - /* - * Pass the VCCB and message to the VC state machine - */ - (void) unisig_vc_state(usp, uvp, UNI_VC_SETUP_MSG, msg); - - /* - * If the VCCB state is NULL, the open failed and the - * VCCB should be released - */ - if (uvp->uv_sstate == UNI_NULL) { - DEQUEUE(uvp, struct unisig_vccb, uv_sigelem, - usp->us_vccq); - uma_zfree(unisig_vc_zone, uvp); - } - return; -} - - -/* - * Process a UNISIG signalling message - * - * Called when a UNISIG message is received. The message is decoded - * and passed to the UNISIG state machine. Unrecognized and - * unexpected messages are logged. - * - * Arguments: - * usp pointer to UNISIG protocol instance block - * m pointer to a buffer chain containing the UNISIG message - * - * Returns: - * none - * - */ -int -unisig_rcv_msg(usp, m) - struct unisig *usp; - KBuffer *m; -{ - int err; - u_int cref; - struct usfmt usf; - struct unisig_msg *msg = 0; - struct unisig_vccb *uvp = 0; - struct ie_generic *iep; - - ATM_DEBUG2("unisig_rcv_msg: bfr=%p, len=%d\n", m, KB_LEN(m)); - -#ifdef NOTDEF - unisig_print_mbuf(m); -#endif - - /* - * Get storage for the message - */ - msg = uma_zalloc(unisig_msg_zone, M_ZERO | M_NOWAIT); - if (msg == NULL) { - err = ENOMEM; - goto done; - } - - /* - * Convert the message from network order to internal format - */ - err = usf_init(&usf, usp, m, USF_DECODE, 0); - if (err) { - if (err == EINVAL) - panic("unisig_rcv_msg: invalid parameter\n"); - ATM_DEBUG1("unisig_rcv_msg: decode init failed with %d\n", - err); - goto done; - } - - err = usf_dec_msg(&usf, msg); - if (err) { - ATM_DEBUG1("unisig_rcv_msg: decode failed with %d\n", - err); - goto done; - } - - /* - * Debug--print some information about the message - */ - if (unisig_print_msg) - usp_print_msg(msg, UNISIG_MSG_IN); - - /* - * Get the call reference value - */ - cref = EXTRACT_CREF(msg->msg_call_ref); - - /* - * Any message with the global call reference value except - * RESTART, RESTART ACK, or STATUS is in error - */ - if (GLOBAL_CREF(cref) && - msg->msg_type != UNI_MSG_RSTR && - msg->msg_type != UNI_MSG_RSTA && - msg->msg_type != UNI_MSG_STAT) { - /* - * Send STATUS message indicating the error - */ - err = unisig_send_status(usp, (struct unisig_vccb *) 0, - msg, UNI_IE_CAUS_CREF); - goto done; - } - - /* - * Check for missing mandatory IEs. Checks for SETUP, - * RELEASE, and RELEASE COMPLETE are handled elsewhere. - */ - if (msg->msg_type != UNI_MSG_SETU && - msg->msg_type != UNI_MSG_RLSE && - msg->msg_type != UNI_MSG_RLSC) { - for (iep = msg->msg_ie_err; iep; iep = iep->ie_next) { - if (iep->ie_err_cause == UNI_IE_CAUS_MISSING) { - err = unisig_send_status(usp, - uvp, msg, - UNI_IE_CAUS_MISSING); - goto done; - } - } - } - - /* - * Find the VCCB associated with the message - */ - uvp = unisig_find_conn(usp, cref); - - /* - * Process the message based on its type - */ - switch(msg->msg_type) { - case UNI_MSG_CALP: - (void) unisig_vc_state(usp, uvp, - UNI_VC_CALLP_MSG, msg); - break; - case UNI_MSG_CONN: - (void) unisig_vc_state(usp, uvp, - UNI_VC_CONNECT_MSG, msg); - break; - case UNI_MSG_CACK: - (void) unisig_vc_state(usp, uvp, - UNI_VC_CNCTACK_MSG, msg); - break; - case UNI_MSG_SETU: - unisig_rcv_setup(usp, msg); - break; - case UNI_MSG_RLSE: - (void) unisig_vc_state(usp, uvp, - UNI_VC_RELEASE_MSG, msg); - break; - case UNI_MSG_RLSC: - /* - * Ignore a RELEASE COMPLETE with an unrecognized - * call reference value - */ - if (uvp) { - (void) unisig_vc_state(usp, uvp, - UNI_VC_RLSCMP_MSG, msg); - } - break; - case UNI_MSG_RSTR: - unisig_rcv_restart(usp, msg); - break; - case UNI_MSG_RSTA: - break; - case UNI_MSG_STAT: - (void) unisig_vc_state(usp, uvp, - UNI_VC_STATUS_MSG, msg); - break; - case UNI_MSG_SENQ: - (void) unisig_vc_state(usp, uvp, - UNI_VC_STATUSENQ_MSG, msg); - break; - case UNI_MSG_ADDP: - (void) unisig_vc_state(usp, uvp, - UNI_VC_ADDP_MSG, msg); - break; - case UNI_MSG_ADPA: - (void) unisig_vc_state(usp, uvp, - UNI_VC_ADDPACK_MSG, msg); - break; - case UNI_MSG_ADPR: - (void) unisig_vc_state(usp, uvp, - UNI_VC_ADDPREJ_MSG, msg); - break; - case UNI_MSG_DRPP: - (void) unisig_vc_state(usp, uvp, - UNI_VC_DROP_MSG, msg); - break; - case UNI_MSG_DRPA: - (void) unisig_vc_state(usp, uvp, - UNI_VC_DROPACK_MSG, msg); - break; - default: - /* - * Message size didn't match size received - */ - err = unisig_send_status(usp, uvp, msg, - UNI_IE_CAUS_MTEXIST); - } - -done: - /* - * Handle message errors that require a response - */ - switch(err) { - case EMSGSIZE: - /* - * Message size didn't match size received - */ - err = unisig_send_status(usp, uvp, msg, - UNI_IE_CAUS_LEN); - break; - } - - /* - * Free the incoming message (both buffer and internal format) - * if necessary. - */ - if (msg) - unisig_free_msg(msg); - if (m) - KB_FREEALL(m); - - return (err); -} |