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.6 2006/12/20 18:14:43 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(Sap_t lsap, spans_sap *ssap)
75 * Search the SAP table for the given local SAP
77 for (i=0; i< MAX_SAP_ENT; i++) {
78 if (sap_table[i].local_sap == lsap) {
79 *ssap = sap_table[i].spans_sap;
88 * Translate a SPANS SAP to internal format
90 * Search the SAP table for the given SAP. Put the corresponding
91 * internal SAP into the indicated variable.
94 * ssap the value of the SPANS SAP
95 * lsap a pointer to the variable to receive the internal
99 * TRUE the SAP was found; *lsap is valid
100 * FALSE the SAP was not found; *lsap is not valid
104 spans_get_local_sap(spans_sap ssap, Sap_t *lsap)
109 * Search the SAP table for the given SPANS SAP
111 for (i=0; i< MAX_SAP_ENT; i++) {
112 if (sap_table[i].spans_sap == ssap) {
113 *lsap = sap_table[i].local_sap;
123 * Allocate an ephemeral SPANS SAP
126 * spp pointer to SPANS protocol instance
129 * a SPANS ephemeral SAP number
133 spans_ephemeral_sap(struct spans *spp)
135 return(SPANS_SAP_EPHEMERAL);
140 * Translate an internal AAL designator to a SPANS AAL type
143 * laal internal AAL designation
144 * saal a pointer to the variable to receive the SPANS AAL type
147 * TRUE the AAL was found; *saal is valid
148 * FALSE the AAL was not found; *saal is not valid
152 spans_get_spans_aal(Aal_t laal, spans_aal *saal)
180 * Translate a SPANS AAL type to an internal AAL designator
183 * saal the SPANS AAL type
184 * laal a pointer to the variable to receive the internal
188 * TRUE the AAL was found; *laal is valid
189 * FALSE the AAL was not found; *laal is not valid
193 spans_get_local_aal(spans_aal saal, Aal_t *laal)
224 * Search SPANS's VCCB queue to verify that a VCCB belongs to SPANS.
227 * spp pointer to SPANS protocol instance
228 * svp pointer to a VCCB
231 * TRUE the VCCB belongs to SPANS
232 * FALSE the VCCB doesn't belong to SPANS
236 spans_verify_vccb(struct spans *spp, struct spans_vccb *svp)
238 struct spans_vccb *vcp, *vcnext;
240 for (vcp = Q_HEAD(spp->sp_vccq, struct spans_vccb);
242 vcnext = Q_NEXT(vcp, struct spans_vccb, sv_sigelem);
254 * Find a VCCB given the VPI and VCI.
257 * spp pointer to SPANS protocol instance
258 * vpi the VPI to search for
259 * vci the VCI to search for
260 * dir the direction of the VCC (VCC_IN, VCC_OUT, or both).
261 * If dir is set to zero, return the address of any VCCB
262 * with the given VPI/VCI, regardless of direction.
265 * 0 there is no such VCCB
266 * address the address of the VCCB
270 spans_find_vpvc(struct spans *spp, int vpi, int vci, u_char dir)
272 struct spans_vccb *svp, *svnext;
274 for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp;
276 svnext = Q_NEXT(svp, struct spans_vccb, sv_sigelem);
277 if (svp->sv_vpi == vpi &&
278 svp->sv_vci == vci &&
279 (svp->sv_type & dir) == dir)
289 * Find a VCCB given the connection structure.
292 * spp pointer to SPANS protocol instance
293 * p pointer to an spans_atm_conn structure
296 * 0 there is no such VCCB
297 * address the address of the VCCB
301 spans_find_conn(struct spans *spp, struct spans_atm_conn *p)
303 struct spans_vccb *svp, *svnext;
305 for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp; svp = svnext){
306 svnext = Q_NEXT(svp, struct spans_vccb, sv_sigelem);
307 if (!bcmp(p, &svp->sv_conn, sizeof (spans_atm_conn)))
315 * Allocate a VPI/VCI pair
317 * When we get an open request or indication from the network, we have
318 * allocate a VPI and VCI for the conection. This routine will allocate
319 * a VPI/VCI based on the next available VCI in the SPANS protocol block.
320 * The VPI/VCI chose must be within the range allowed by the interface and
321 * must not already be in use.
323 * Currently the Fore ATM interface only supports VPI 0, so this code only
326 * There's probably a more elegant way to do this.
329 * spp pointer to connection's SPANS protocol instance
332 * 0 no VPI/VCI available
333 * vpvc the VPI/VCI for the connection
337 spans_alloc_vpvc(struct spans *spp)
342 * Loop through the allowable VCIs, starting with the curent one,
343 * to find one that's not in use.
345 while (spp->sp_alloc_vci <= spp->sp_max_vci) {
346 vpi = spp->sp_alloc_vpi;
347 vci = spp->sp_alloc_vci++;
348 if (!spans_find_vpvc(spp, vpi, vci, 0)) {
349 return(SPANS_PACK_VPIVCI(vpi, vci));
354 * Reset the VCI to the minimum
356 spp->sp_alloc_vci = spp->sp_min_vci;
359 * Try looping through again
361 while (spp->sp_alloc_vci <= spp->sp_max_vci) {
362 vpi = spp->sp_alloc_vpi;
363 vci = spp->sp_alloc_vci++;
364 if (!spans_find_vpvc(spp, vpi, vci, 0)) {
365 return(SPANS_PACK_VPIVCI(vpi, vci));
370 * All allowable VCIs are in use
377 * Print a SPANS address
379 * Convert a SPANS address into an ASCII string suitable for printing.
382 * p pointer to a struct spans_addr
385 * the address of a string with the ASCII representation of the
390 spans_addr_print(struct spans_addr *p)
392 static char strbuff[80];
400 * Clear the returned string
402 KM_ZERO(strbuff, sizeof(strbuff));
405 * Get address into integers
417 * Print and return the string
419 ksprintf(strbuff, "%lx.%lx", (u_long)ntohl(u1.w), (u_long)ntohl(u2.w));
425 * Print a buffer chain
428 * m pointer to a buffer chain
435 spans_dump_buffer(KBuffer *m)
440 printf("spans_dump_buffer:\n");
442 KB_DATASTART(m, cp, caddr_t);
443 for (i = 0; i < KB_LEN(m); i++) {
445 printf(" bfr=%p: ", m);
446 printf("%x ", (u_char)*cp++);
448 printf("<end_bfr>\n");