3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/spans/spans_util.c,v 1.5 1999/08/29 10:28:10 bde Exp $
31 * SPANS Signalling Manager
32 * ---------------------------
34 * SPANS-related utility routines.
38 #include <netatm/kern_include.h>
40 #include "spans_xdr.h"
41 #include <netatm/spans/spans_var.h>
44 __RCSID("@(#) $FreeBSD: src/sys/netatm/spans/spans_util.c,v 1.5 1999/08/29 10:28:10 bde Exp $");
49 /* XXX -- Remove all SAP checks? */
54 } sap_table[MAX_SAP_ENT] = {
55 {SPANS_SAP_IP, SAP_IP},
60 * Translate an internal SAP to a SPANS SAP
62 * Search the SAP table for the given SAP. Put the corresponding SPANS
63 * SAP into the indicated variable.
66 * lsap the value of the internal SAP
67 * ssap a pointer to the variable to receive the SPANS SAP value
70 * TRUE the SAP was found; *ssap is valid
71 * FALSE the SAP was not found; *ssap is not valid
75 spans_get_spans_sap(lsap, ssap)
82 * Search the SAP table for the given local SAP
84 for (i=0; i< MAX_SAP_ENT; i++) {
85 if (sap_table[i].local_sap == lsap) {
86 *ssap = sap_table[i].spans_sap;
95 * Translate a SPANS SAP to internal format
97 * Search the SAP table for the given SAP. Put the corresponding
98 * internal SAP into the indicated variable.
101 * ssap the value of the SPANS SAP
102 * lsap a pointer to the variable to receive the internal
106 * TRUE the SAP was found; *lsap is valid
107 * FALSE the SAP was not found; *lsap is not valid
111 spans_get_local_sap(ssap, lsap)
118 * Search the SAP table for the given SPANS SAP
120 for (i=0; i< MAX_SAP_ENT; i++) {
121 if (sap_table[i].spans_sap == ssap) {
122 *lsap = sap_table[i].local_sap;
132 * Allocate an ephemeral SPANS SAP
135 * spp pointer to SPANS protocol instance
138 * a SPANS ephemeral SAP number
142 spans_ephemeral_sap(spp)
145 return(SPANS_SAP_EPHEMERAL);
150 * Translate an internal AAL designator to a SPANS AAL type
153 * laal internal AAL designation
154 * saal a pointer to the variable to receive the SPANS AAL type
157 * TRUE the AAL was found; *saal is valid
158 * FALSE the AAL was not found; *saal is not valid
162 spans_get_spans_aal(laal, saal)
192 * Translate a SPANS AAL type to an internal AAL designator
195 * saal the SPANS AAL type
196 * laal a pointer to the variable to receive the internal
200 * TRUE the AAL was found; *laal is valid
201 * FALSE the AAL was not found; *laal is not valid
205 spans_get_local_aal(saal, laal)
238 * Search SPANS's VCCB queue to verify that a VCCB belongs to SPANS.
241 * spp pointer to SPANS protocol instance
242 * svp pointer to a VCCB
245 * TRUE the VCCB belongs to SPANS
246 * FALSE the VCCB doesn't belong to SPANS
250 spans_verify_vccb(spp, svp)
252 struct spans_vccb *svp;
255 struct spans_vccb *vcp, *vcnext;
257 for (vcp = Q_HEAD(spp->sp_vccq, struct spans_vccb);
259 vcnext = Q_NEXT(vcp, struct spans_vccb, sv_sigelem);
271 * Find a VCCB given the VPI and VCI.
274 * spp pointer to SPANS protocol instance
275 * vpi the VPI to search for
276 * vci the VCI to search for
277 * dir the direction of the VCC (VCC_IN, VCC_OUT, or both).
278 * If dir is set to zero, return the address of any VCCB
279 * with the given VPI/VCI, regardless of direction.
282 * 0 there is no such VCCB
283 * address the address of the VCCB
287 spans_find_vpvc(spp, vpi, vci, dir)
293 struct spans_vccb *svp, *svnext;
295 for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp;
297 svnext = Q_NEXT(svp, struct spans_vccb, sv_sigelem);
298 if (svp->sv_vpi == vpi &&
299 svp->sv_vci == vci &&
300 (svp->sv_type & dir) == dir)
310 * Find a VCCB given the connection structure.
313 * spp pointer to SPANS protocol instance
314 * p pointer to an spans_atm_conn structure
317 * 0 there is no such VCCB
318 * address the address of the VCCB
322 spans_find_conn(spp, p)
324 struct spans_atm_conn *p;
326 struct spans_vccb *svp, *svnext;
328 for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp; svp = svnext){
329 svnext = Q_NEXT(svp, struct spans_vccb, sv_sigelem);
330 if (!bcmp(p, &svp->sv_conn, sizeof (spans_atm_conn)))
338 * Allocate a VPI/VCI pair
340 * When we get an open request or indication from the network, we have
341 * allocate a VPI and VCI for the conection. This routine will allocate
342 * a VPI/VCI based on the next available VCI in the SPANS protocol block.
343 * The VPI/VCI chose must be within the range allowed by the interface and
344 * must not already be in use.
346 * Currently the Fore ATM interface only supports VPI 0, so this code only
349 * There's probably a more elegant way to do this.
352 * spp pointer to connection's SPANS protocol instance
355 * 0 no VPI/VCI available
356 * vpvc the VPI/VCI for the connection
360 spans_alloc_vpvc(spp)
366 * Loop through the allowable VCIs, starting with the curent one,
367 * to find one that's not in use.
369 while (spp->sp_alloc_vci <= spp->sp_max_vci) {
370 vpi = spp->sp_alloc_vpi;
371 vci = spp->sp_alloc_vci++;
372 if (!spans_find_vpvc(spp, vpi, vci, 0)) {
373 return(SPANS_PACK_VPIVCI(vpi, vci));
378 * Reset the VCI to the minimum
380 spp->sp_alloc_vci = spp->sp_min_vci;
383 * Try looping through again
385 while (spp->sp_alloc_vci <= spp->sp_max_vci) {
386 vpi = spp->sp_alloc_vpi;
387 vci = spp->sp_alloc_vci++;
388 if (!spans_find_vpvc(spp, vpi, vci, 0)) {
389 return(SPANS_PACK_VPIVCI(vpi, vci));
394 * All allowable VCIs are in use
401 * Print a SPANS address
403 * Convert a SPANS address into an ASCII string suitable for printing.
406 * p pointer to a struct spans_addr
409 * the address of a string with the ASCII representation of the
415 struct spans_addr *p;
417 static char strbuff[80];
425 * Clear the returned string
427 KM_ZERO(strbuff, sizeof(strbuff));
430 * Get address into integers
442 * Print and return the string
444 sprintf(strbuff, "%lx.%lx", (u_long)ntohl(u1.w), (u_long)ntohl(u2.w));
450 * Print a buffer chain
453 * m pointer to a buffer chain
466 printf("spans_dump_buffer:\n");
468 KB_DATASTART(m, cp, caddr_t);
469 for (i = 0; i < KB_LEN(m); i++) {
471 printf(" bfr=%p: ", m);
472 printf("%x ", (u_char)*cp++);
474 printf("<end_bfr>\n");