freebsd-nq/sys/netatm/spans/spans_util.c
Poul-Henning Kamp 1820df7a2d Add new files for HARP3
Host ATM Research Platform (HARP), Network Computing Services, Inc.
This software was developed with the support of the Defense Advanced
Research Projects Agency (DARPA).
1998-09-15 08:23:17 +00:00

478 lines
9.0 KiB
C

/*
*
* ===================================
* 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);
}
}