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 $
27 * @(#) $DragonFly: src/sys/netproto/atm/spans/spans_util.c,v 1.4 2003/08/07 21:54:34 dillon Exp $
31 * SPANS Signalling Manager
32 * ---------------------------
34 * SPANS-related utility routines.
38 #include <netproto/atm/kern_include.h>
40 #include "spans_xdr.h"
41 #include "spans_var.h"
44 /* XXX -- Remove all SAP checks? */
49 } sap_table[MAX_SAP_ENT] = {
50 {SPANS_SAP_IP, SAP_IP},
55 * Translate an internal SAP to a SPANS SAP
57 * Search the SAP table for the given SAP. Put the corresponding SPANS
58 * SAP into the indicated variable.
61 * lsap the value of the internal SAP
62 * ssap a pointer to the variable to receive the SPANS SAP value
65 * TRUE the SAP was found; *ssap is valid
66 * FALSE the SAP was not found; *ssap is not valid
70 spans_get_spans_sap(lsap, ssap)
77 * Search the SAP table for the given local SAP
79 for (i=0; i< MAX_SAP_ENT; i++) {
80 if (sap_table[i].local_sap == lsap) {
81 *ssap = sap_table[i].spans_sap;
90 * Translate a SPANS SAP to internal format
92 * Search the SAP table for the given SAP. Put the corresponding
93 * internal SAP into the indicated variable.
96 * ssap the value of the SPANS SAP
97 * lsap a pointer to the variable to receive the internal
101 * TRUE the SAP was found; *lsap is valid
102 * FALSE the SAP was not found; *lsap is not valid
106 spans_get_local_sap(ssap, lsap)
113 * Search the SAP table for the given SPANS SAP
115 for (i=0; i< MAX_SAP_ENT; i++) {
116 if (sap_table[i].spans_sap == ssap) {
117 *lsap = sap_table[i].local_sap;
127 * Allocate an ephemeral SPANS SAP
130 * spp pointer to SPANS protocol instance
133 * a SPANS ephemeral SAP number
137 spans_ephemeral_sap(spp)
140 return(SPANS_SAP_EPHEMERAL);
145 * Translate an internal AAL designator to a SPANS AAL type
148 * laal internal AAL designation
149 * saal a pointer to the variable to receive the SPANS AAL type
152 * TRUE the AAL was found; *saal is valid
153 * FALSE the AAL was not found; *saal is not valid
157 spans_get_spans_aal(laal, saal)
187 * Translate a SPANS AAL type to an internal AAL designator
190 * saal the SPANS AAL type
191 * laal a pointer to the variable to receive the internal
195 * TRUE the AAL was found; *laal is valid
196 * FALSE the AAL was not found; *laal is not valid
200 spans_get_local_aal(saal, laal)
233 * Search SPANS's VCCB queue to verify that a VCCB belongs to SPANS.
236 * spp pointer to SPANS protocol instance
237 * svp pointer to a VCCB
240 * TRUE the VCCB belongs to SPANS
241 * FALSE the VCCB doesn't belong to SPANS
245 spans_verify_vccb(spp, svp)
247 struct spans_vccb *svp;
250 struct spans_vccb *vcp, *vcnext;
252 for (vcp = Q_HEAD(spp->sp_vccq, struct spans_vccb);
254 vcnext = Q_NEXT(vcp, struct spans_vccb, sv_sigelem);
266 * Find a VCCB given the VPI and VCI.
269 * spp pointer to SPANS protocol instance
270 * vpi the VPI to search for
271 * vci the VCI to search for
272 * dir the direction of the VCC (VCC_IN, VCC_OUT, or both).
273 * If dir is set to zero, return the address of any VCCB
274 * with the given VPI/VCI, regardless of direction.
277 * 0 there is no such VCCB
278 * address the address of the VCCB
282 spans_find_vpvc(spp, vpi, vci, dir)
288 struct spans_vccb *svp, *svnext;
290 for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp;
292 svnext = Q_NEXT(svp, struct spans_vccb, sv_sigelem);
293 if (svp->sv_vpi == vpi &&
294 svp->sv_vci == vci &&
295 (svp->sv_type & dir) == dir)
305 * Find a VCCB given the connection structure.
308 * spp pointer to SPANS protocol instance
309 * p pointer to an spans_atm_conn structure
312 * 0 there is no such VCCB
313 * address the address of the VCCB
317 spans_find_conn(spp, p)
319 struct spans_atm_conn *p;
321 struct spans_vccb *svp, *svnext;
323 for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp; svp = svnext){
324 svnext = Q_NEXT(svp, struct spans_vccb, sv_sigelem);
325 if (!bcmp(p, &svp->sv_conn, sizeof (spans_atm_conn)))
333 * Allocate a VPI/VCI pair
335 * When we get an open request or indication from the network, we have
336 * allocate a VPI and VCI for the conection. This routine will allocate
337 * a VPI/VCI based on the next available VCI in the SPANS protocol block.
338 * The VPI/VCI chose must be within the range allowed by the interface and
339 * must not already be in use.
341 * Currently the Fore ATM interface only supports VPI 0, so this code only
344 * There's probably a more elegant way to do this.
347 * spp pointer to connection's SPANS protocol instance
350 * 0 no VPI/VCI available
351 * vpvc the VPI/VCI for the connection
355 spans_alloc_vpvc(spp)
361 * Loop through the allowable VCIs, starting with the curent one,
362 * to find one that's not in use.
364 while (spp->sp_alloc_vci <= spp->sp_max_vci) {
365 vpi = spp->sp_alloc_vpi;
366 vci = spp->sp_alloc_vci++;
367 if (!spans_find_vpvc(spp, vpi, vci, 0)) {
368 return(SPANS_PACK_VPIVCI(vpi, vci));
373 * Reset the VCI to the minimum
375 spp->sp_alloc_vci = spp->sp_min_vci;
378 * Try looping through again
380 while (spp->sp_alloc_vci <= spp->sp_max_vci) {
381 vpi = spp->sp_alloc_vpi;
382 vci = spp->sp_alloc_vci++;
383 if (!spans_find_vpvc(spp, vpi, vci, 0)) {
384 return(SPANS_PACK_VPIVCI(vpi, vci));
389 * All allowable VCIs are in use
396 * Print a SPANS address
398 * Convert a SPANS address into an ASCII string suitable for printing.
401 * p pointer to a struct spans_addr
404 * the address of a string with the ASCII representation of the
410 struct spans_addr *p;
412 static char strbuff[80];
420 * Clear the returned string
422 KM_ZERO(strbuff, sizeof(strbuff));
425 * Get address into integers
437 * Print and return the string
439 sprintf(strbuff, "%lx.%lx", (u_long)ntohl(u1.w), (u_long)ntohl(u2.w));
445 * Print a buffer chain
448 * m pointer to a buffer chain
461 printf("spans_dump_buffer:\n");
463 KB_DATASTART(m, cp, caddr_t);
464 for (i = 0; i < KB_LEN(m); i++) {
466 printf(" bfr=%p: ", m);
467 printf("%x ", (u_char)*cp++);
469 printf("<end_bfr>\n");