2 * ===================================
3 * HARP | Host ATM Research Platform
4 * ===================================
7 * This Host ATM Research Platform ("HARP") file (the "Software") is
8 * made available by Network Computing Services, Inc. ("NetworkCS")
9 * "AS IS". NetworkCS does not provide maintenance, improvements or
10 * support of any kind.
12 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
13 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
14 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
15 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
16 * In no event shall NetworkCS be responsible for any damages, including
17 * but not limited to consequential damages, arising from or relating to
18 * any use of the Software or related support.
20 * Copyright 1994-1998 Network Computing Services, Inc.
22 * Copies of this Software may be made, however, the above copyright
23 * notice must be reproduced on all copies.
27 * SPANS Signalling Manager
28 * ---------------------------
30 * SPANS-related utility routines.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/types.h>
40 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <netatm/port.h>
44 #include <netatm/queue.h>
45 #include <netatm/atm.h>
46 #include <netatm/atm_sys.h>
47 #include <netatm/atm_sap.h>
48 #include <netatm/atm_cm.h>
49 #include <netatm/atm_vc.h>
50 #include <netatm/atm_sigmgr.h>
52 #include "spans_xdr.h"
53 #include <netatm/spans/spans_var.h>
56 /* XXX -- Remove all SAP checks? */
61 } sap_table[MAX_SAP_ENT] = {
62 {SPANS_SAP_IP, SAP_IP},
67 * Translate an internal SAP to a SPANS SAP
69 * Search the SAP table for the given SAP. Put the corresponding SPANS
70 * SAP into the indicated variable.
73 * lsap the value of the internal SAP
74 * ssap a pointer to the variable to receive the SPANS SAP value
77 * TRUE the SAP was found; *ssap is valid
78 * FALSE the SAP was not found; *ssap is not valid
82 spans_get_spans_sap(lsap, ssap)
89 * Search the SAP table for the given local SAP
91 for (i=0; i< MAX_SAP_ENT; i++) {
92 if (sap_table[i].local_sap == lsap) {
93 *ssap = sap_table[i].spans_sap;
102 * Translate a SPANS SAP to internal format
104 * Search the SAP table for the given SAP. Put the corresponding
105 * internal SAP into the indicated variable.
108 * ssap the value of the SPANS SAP
109 * lsap a pointer to the variable to receive the internal
113 * TRUE the SAP was found; *lsap is valid
114 * FALSE the SAP was not found; *lsap is not valid
118 spans_get_local_sap(ssap, lsap)
125 * Search the SAP table for the given SPANS SAP
127 for (i=0; i< MAX_SAP_ENT; i++) {
128 if (sap_table[i].spans_sap == ssap) {
129 *lsap = sap_table[i].local_sap;
139 * Allocate an ephemeral SPANS SAP
142 * spp pointer to SPANS protocol instance
145 * a SPANS ephemeral SAP number
149 spans_ephemeral_sap(spp)
152 return(SPANS_SAP_EPHEMERAL);
157 * Translate an internal AAL designator to a SPANS AAL type
160 * laal internal AAL designation
161 * saal a pointer to the variable to receive the SPANS AAL type
164 * TRUE the AAL was found; *saal is valid
165 * FALSE the AAL was not found; *saal is not valid
169 spans_get_spans_aal(laal, saal)
199 * Translate a SPANS AAL type to an internal AAL designator
202 * saal the SPANS AAL type
203 * laal a pointer to the variable to receive the internal
207 * TRUE the AAL was found; *laal is valid
208 * FALSE the AAL was not found; *laal is not valid
212 spans_get_local_aal(saal, laal)
245 * Search SPANS's VCCB queue to verify that a VCCB belongs to SPANS.
248 * spp pointer to SPANS protocol instance
249 * svp pointer to a VCCB
252 * TRUE the VCCB belongs to SPANS
253 * FALSE the VCCB doesn't belong to SPANS
257 spans_verify_vccb(spp, svp)
259 struct spans_vccb *svp;
262 struct spans_vccb *vcp, *vcnext;
264 for (vcp = Q_HEAD(spp->sp_vccq, struct spans_vccb);
266 vcnext = Q_NEXT(vcp, struct spans_vccb, sv_sigelem);
278 * Find a VCCB given the VPI and VCI.
281 * spp pointer to SPANS protocol instance
282 * vpi the VPI to search for
283 * vci the VCI to search for
284 * dir the direction of the VCC (VCC_IN, VCC_OUT, or both).
285 * If dir is set to zero, return the address of any VCCB
286 * with the given VPI/VCI, regardless of direction.
289 * 0 there is no such VCCB
290 * address the address of the VCCB
294 spans_find_vpvc(spp, vpi, vci, dir)
300 struct spans_vccb *svp, *svnext;
302 for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp;
304 svnext = Q_NEXT(svp, struct spans_vccb, sv_sigelem);
305 if (svp->sv_vpi == vpi &&
306 svp->sv_vci == vci &&
307 (svp->sv_type & dir) == dir)
317 * Find a VCCB given the connection structure.
320 * spp pointer to SPANS protocol instance
321 * p pointer to a spans_atm_conn structure
324 * 0 there is no such VCCB
325 * address the address of the VCCB
329 spans_find_conn(spp, p)
331 struct spans_atm_conn *p;
333 struct spans_vccb *svp, *svnext;
335 for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp; svp = svnext){
336 svnext = Q_NEXT(svp, struct spans_vccb, sv_sigelem);
337 if (!bcmp(p, &svp->sv_conn, sizeof (spans_atm_conn)))
345 * Allocate a VPI/VCI pair
347 * When we get an open request or indication from the network, we have
348 * allocate a VPI and VCI for the conection. This routine will allocate
349 * a VPI/VCI based on the next available VCI in the SPANS protocol block.
350 * The VPI/VCI chose must be within the range allowed by the interface and
351 * must not already be in use.
353 * Currently the Fore ATM interface only supports VPI 0, so this code only
356 * There's probably a more elegant way to do this.
359 * spp pointer to connection's SPANS protocol instance
362 * 0 no VPI/VCI available
363 * vpvc the VPI/VCI for the connection
367 spans_alloc_vpvc(spp)
373 * Loop through the allowable VCIs, starting with the curent one,
374 * to find one that's not in use.
376 while (spp->sp_alloc_vci <= spp->sp_max_vci) {
377 vpi = spp->sp_alloc_vpi;
378 vci = spp->sp_alloc_vci++;
379 if (!spans_find_vpvc(spp, vpi, vci, 0)) {
380 return(SPANS_PACK_VPIVCI(vpi, vci));
385 * Reset the VCI to the minimum
387 spp->sp_alloc_vci = spp->sp_min_vci;
390 * Try looping through again
392 while (spp->sp_alloc_vci <= spp->sp_max_vci) {
393 vpi = spp->sp_alloc_vpi;
394 vci = spp->sp_alloc_vci++;
395 if (!spans_find_vpvc(spp, vpi, vci, 0)) {
396 return(SPANS_PACK_VPIVCI(vpi, vci));
401 * All allowable VCIs are in use
408 * Print a SPANS address
410 * Convert a SPANS address into an ASCII string suitable for printing.
413 * p pointer to a struct spans_addr
416 * the address of a string with the ASCII representation of the
422 struct spans_addr *p;
424 static char strbuff[80];
432 * Clear the returned string
434 bzero(strbuff, sizeof(strbuff));
437 * Get address into integers
449 * Print and return the string
451 sprintf(strbuff, "%lx.%lx", (u_long)ntohl(u1.w), (u_long)ntohl(u2.w));
457 * Print a buffer chain
460 * m pointer to a buffer chain
473 printf("spans_dump_buffer:\n");
475 KB_DATASTART(m, cp, caddr_t);
476 for (i = 0; i < KB_LEN(m); i++) {
478 printf(" bfr=%p: ", m);
479 printf("%x ", (u_char)*cp++);
481 printf("<end_bfr>\n");