diff options
Diffstat (limited to 'sys/netatm/spans/spans_util.c')
-rw-r--r-- | sys/netatm/spans/spans_util.c | 477 |
1 files changed, 477 insertions, 0 deletions
diff --git a/sys/netatm/spans/spans_util.c b/sys/netatm/spans/spans_util.c new file mode 100644 index 0000000..6d470e1 --- /dev/null +++ b/sys/netatm/spans/spans_util.c @@ -0,0 +1,477 @@ +/* + * + * =================================== + * 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. + * + * @(#) $Id: spans_util.c,v 1.6 1998/08/26 23:29:10 mks Exp $ + * + */ + +/* + * SPANS Signalling Manager + * --------------------------- + * + * SPANS-related utility routines. + * + */ + +#ifndef lint +static char *RCSid = "@(#) $Id: spans_util.c,v 1.6 1998/08/26 23:29:10 mks Exp $"; +#endif + +#include <netatm/kern_include.h> + +#include "spans_xdr.h" +#include <netatm/spans/spans_var.h> + + +#ifdef NOTDEF +/* XXX -- Remove all SAP checks? */ +#define MAX_SAP_ENT 1 +static struct { + spans_sap spans_sap; + Sap_t local_sap; +} sap_table[MAX_SAP_ENT] = { + {SPANS_SAP_IP, SAP_IP}, +}; + + +/* + * Translate an internal SAP to a SPANS SAP + * + * Search the SAP table for the given SAP. Put the corresponding SPANS + * SAP into the indicated variable. + * + * Arguments: + * lsap the value of the internal SAP + * ssap a pointer to the variable to receive the SPANS SAP value + * + * Returns: + * TRUE the SAP was found; *ssap is valid + * FALSE the SAP was not found; *ssap is not valid + * + */ +int +spans_get_spans_sap(lsap, ssap) + Sap_t lsap; + spans_sap *ssap; +{ + int i; + + /* + * Search the SAP table for the given local SAP + */ + for (i=0; i< MAX_SAP_ENT; i++) { + if (sap_table[i].local_sap == lsap) { + *ssap = sap_table[i].spans_sap; + return(TRUE); + } + } + return(FALSE); +} + + +/* + * Translate a SPANS SAP to internal format + * + * Search the SAP table for the given SAP. Put the corresponding + * internal SAP into the indicated variable. + * + * Arguments: + * ssap the value of the SPANS SAP + * lsap a pointer to the variable to receive the internal + * SAP value + * + * Returns: + * TRUE the SAP was found; *lsap is valid + * FALSE the SAP was not found; *lsap is not valid + * + */ +int +spans_get_local_sap(ssap, lsap) + spans_sap ssap; + Sap_t *lsap; +{ + int i; + + /* + * Search the SAP table for the given SPANS SAP + */ + for (i=0; i< MAX_SAP_ENT; i++) { + if (sap_table[i].spans_sap == ssap) { + *lsap = sap_table[i].local_sap; + return(TRUE); + } + } + return(FALSE); +} +#endif + + +/* + * Allocate an ephemeral SPANS SAP + * + * Arguments: + * spp pointer to SPANS protocol instance + * + * Returns: + * a SPANS ephemeral SAP number + * + */ +int +spans_ephemeral_sap(spp) + struct spans *spp; +{ + return(SPANS_SAP_EPHEMERAL); +} + + +/* + * Translate an internal AAL designator to a SPANS AAL type + * + * Arguments: + * laal internal AAL designation + * saal a pointer to the variable to receive the SPANS AAL type + * + * Returns: + * TRUE the AAL was found; *saal is valid + * FALSE the AAL was not found; *saal is not valid + * + */ +int +spans_get_spans_aal(laal, saal) + Aal_t laal; + spans_aal *saal; +{ + /* + * + */ + switch (laal) { + case ATM_AAL0: + *saal = SPANS_AAL0; + return(TRUE); + case ATM_AAL1: + *saal = SPANS_AAL1; + return(TRUE); + case ATM_AAL2: + *saal = SPANS_AAL2; + return(TRUE); + case ATM_AAL3_4: + *saal = SPANS_AAL4; + return(TRUE); + case ATM_AAL5: + *saal = SPANS_AAL5; + return(TRUE); + default: + return(FALSE); + } +} + + +/* + * Translate a SPANS AAL type to an internal AAL designator + * + * Arguments: + * saal the SPANS AAL type + * laal a pointer to the variable to receive the internal + * AAL designation + * + * Returns: + * TRUE the AAL was found; *laal is valid + * FALSE the AAL was not found; *laal is not valid + * + */ +int +spans_get_local_aal(saal, laal) + spans_aal saal; + Aal_t *laal; +{ + /* + * + */ + switch (saal) { + case SPANS_AAL0: + *laal = ATM_AAL0; + return(TRUE); + case SPANS_AAL1: + *laal = ATM_AAL1; + return(TRUE); + case SPANS_AAL2: + *laal = ATM_AAL2; + return(TRUE); + case SPANS_AAL3: + case SPANS_AAL4: + *laal = ATM_AAL3_4; + return(TRUE); + case SPANS_AAL5: + *laal = ATM_AAL5; + return(TRUE); + default: + return(FALSE); + } +} + + +/* + * Verify a VCCB + * + * Search SPANS's VCCB queue to verify that a VCCB belongs to SPANS. + * + * Arguments: + * spp pointer to SPANS protocol instance + * svp pointer to a VCCB + * + * Returns: + * TRUE the VCCB belongs to SPANS + * FALSE the VCCB doesn't belong to SPANS + * + */ +int +spans_verify_vccb(spp, svp) + struct spans *spp; + struct spans_vccb *svp; + +{ + struct spans_vccb *vcp, *vcnext; + + for (vcp = Q_HEAD(spp->sp_vccq, struct spans_vccb); + vcp; vcp = vcnext){ + vcnext = Q_NEXT(vcp, struct spans_vccb, sv_sigelem); + if (svp == vcp) { + return(TRUE); + } + } + return(FALSE); +} + + +/* + * Find a VCCB + * + * Find a VCCB given the VPI and VCI. + * + * Arguments: + * spp pointer to SPANS protocol instance + * vpi the VPI to search for + * vci the VCI to search for + * dir the direction of the VCC (VCC_IN, VCC_OUT, or both). + * If dir is set to zero, return the address of any VCCB + * with the given VPI/VCI, regardless of direction. + * + * Returns: + * 0 there is no such VCCB + * address the address of the VCCB + * + */ +struct spans_vccb * +spans_find_vpvc(spp, vpi, vci, dir) + struct spans *spp; + int vpi, vci; + u_char dir; + +{ + struct spans_vccb *svp, *svnext; + + for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp; + svp = svnext){ + svnext = Q_NEXT(svp, struct spans_vccb, sv_sigelem); + if (svp->sv_vpi == vpi && + svp->sv_vci == vci && + (svp->sv_type & dir) == dir) + break; + } + return(svp); +} + + +/* + * Find a connection + * + * Find a VCCB given the connection structure. + * + * Arguments: + * spp pointer to SPANS protocol instance + * p pointer to an spans_atm_conn structure + * + * Returns: + * 0 there is no such VCCB + * address the address of the VCCB + * + */ +struct spans_vccb * +spans_find_conn(spp, p) + struct spans *spp; + struct spans_atm_conn *p; +{ + struct spans_vccb *svp, *svnext; + + for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp; svp = svnext){ + svnext = Q_NEXT(svp, struct spans_vccb, sv_sigelem); + if (!bcmp(p, &svp->sv_conn, sizeof (spans_atm_conn))) + break; + } + return(svp); +} + + +/* + * Allocate a VPI/VCI pair + * + * When we get an open request or indication from the network, we have + * allocate a VPI and VCI for the conection. This routine will allocate + * a VPI/VCI based on the next available VCI in the SPANS protocol block. + * The VPI/VCI chose must be within the range allowed by the interface and + * must not already be in use. + * + * Currently the Fore ATM interface only supports VPI 0, so this code only + * allocates a VCI. + * + * There's probably a more elegant way to do this. + * + * Arguments: + * spp pointer to connection's SPANS protocol instance + * + * Returns: + * 0 no VPI/VCI available + * vpvc the VPI/VCI for the connection + * + */ +spans_vpvc +spans_alloc_vpvc(spp) + struct spans *spp; +{ + int vpi, vci; + + /* + * Loop through the allowable VCIs, starting with the curent one, + * to find one that's not in use. + */ + while (spp->sp_alloc_vci <= spp->sp_max_vci) { + vpi = spp->sp_alloc_vpi; + vci = spp->sp_alloc_vci++; + if (!spans_find_vpvc(spp, vpi, vci, 0)) { + return(SPANS_PACK_VPIVCI(vpi, vci)); + } + } + + /* + * Reset the VCI to the minimum + */ + spp->sp_alloc_vci = spp->sp_min_vci; + + /* + * Try looping through again + */ + while (spp->sp_alloc_vci <= spp->sp_max_vci) { + vpi = spp->sp_alloc_vpi; + vci = spp->sp_alloc_vci++; + if (!spans_find_vpvc(spp, vpi, vci, 0)) { + return(SPANS_PACK_VPIVCI(vpi, vci)); + } + } + + /* + * All allowable VCIs are in use + */ + return(0); +} + + +/* + * Print a SPANS address + * + * Convert a SPANS address into an ASCII string suitable for printing. + * + * Arguments: + * p pointer to a struct spans_addr + * + * Returns: + * the address of a string with the ASCII representation of the + * address. + * + */ +char * +spans_addr_print(p) + struct spans_addr *p; +{ + static char strbuff[80]; + union { + int w; + char c[4]; + } u1, u2; + + + /* + * Clear the returned string + */ + KM_ZERO(strbuff, sizeof(strbuff)); + + /* + * Get address into integers + */ + u1.c[0] =p->addr[0]; + u1.c[1] =p->addr[1]; + u1.c[2] =p->addr[2]; + u1.c[3] =p->addr[3]; + u2.c[0] =p->addr[4]; + u2.c[1] =p->addr[5]; + u2.c[2] =p->addr[6]; + u2.c[3] =p->addr[7]; + + /* + * Print and return the string + */ + sprintf(strbuff, "%x.%x", ntohl(u1.w), ntohl(u2.w)); + return(strbuff); +} + + +/* + * Print a buffer chain + * + * Arguments: + * m pointer to a buffer chain + * + * Returns: + * none + * + */ +void +spans_dump_buffer(m) + KBuffer *m; +{ + int i; + caddr_t cp; + + printf("spans_dump_buffer:\n"); + while (m) { + KB_DATASTART(m, cp, caddr_t); + for (i = 0; i < KB_LEN(m); i++) { + if (i == 0) + printf(" bfr=0x%x: ", (int)m); + printf("%x ", (u_char)*cp++); + } + printf("<end_bfr>\n"); + m = KB_NEXT(m); + } +} |