Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / netproto / atm / spans / spans_util.c
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
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.
12  *
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.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD: src/sys/netatm/spans/spans_util.c,v 1.5 1999/08/29 10:28:10 bde Exp $
27  *
28  */
29
30 /*
31  * SPANS Signalling Manager
32  * ---------------------------
33  *
34  * SPANS-related utility routines.
35  *
36  */
37
38 #include <netatm/kern_include.h>
39
40 #include "spans_xdr.h"
41 #include <netatm/spans/spans_var.h>
42
43 #ifndef lint
44 __RCSID("@(#) $FreeBSD: src/sys/netatm/spans/spans_util.c,v 1.5 1999/08/29 10:28:10 bde Exp $");
45 #endif
46
47
48 #ifdef NOTDEF
49 /* XXX -- Remove all SAP checks? */
50 #define MAX_SAP_ENT     1
51 static struct {
52         spans_sap       spans_sap;
53         Sap_t   local_sap;
54 } sap_table[MAX_SAP_ENT] = {
55         {SPANS_SAP_IP, SAP_IP},
56 };
57
58
59 /*
60  * Translate an internal SAP to a SPANS SAP
61  *
62  * Search the SAP table for the given SAP.  Put the corresponding SPANS
63  * SAP into the indicated variable.
64  *
65  * Arguments:
66  *      lsap    the value of the internal SAP
67  *      ssap    a pointer to the variable to receive the SPANS SAP value
68  *
69  * Returns:
70  *      TRUE    the SAP was found; *ssap is valid
71  *      FALSE   the SAP was not found; *ssap is not valid
72  *
73  */
74 int
75 spans_get_spans_sap(lsap, ssap)
76         Sap_t   lsap;
77         spans_sap       *ssap;
78 {
79         int i;
80
81         /*
82          * Search the SAP table for the given local SAP
83          */
84         for (i=0; i< MAX_SAP_ENT; i++) {
85                 if (sap_table[i].local_sap == lsap) {
86                         *ssap = sap_table[i].spans_sap;
87                         return(TRUE);
88                 }
89         }
90         return(FALSE);
91 }
92
93
94 /*
95  * Translate a SPANS SAP to internal format
96  *
97  * Search the SAP table for the given SAP.  Put the corresponding
98  * internal SAP into the indicated variable.
99  *
100  * Arguments:
101  *      ssap    the value of the SPANS SAP
102  *      lsap    a pointer to the variable to receive the internal
103  *              SAP value
104  *
105  * Returns:
106  *      TRUE    the SAP was found; *lsap is valid
107  *      FALSE   the SAP was not found; *lsap is not valid
108  *
109  */
110 int
111 spans_get_local_sap(ssap, lsap)
112         spans_sap       ssap;
113         Sap_t   *lsap;
114 {
115         int i;
116
117         /*
118          * Search the SAP table for the given SPANS SAP
119          */
120         for (i=0; i< MAX_SAP_ENT; i++) {
121                 if (sap_table[i].spans_sap == ssap) {
122                         *lsap = sap_table[i].local_sap;
123                         return(TRUE);
124                 }
125         }
126         return(FALSE);
127 }
128 #endif
129
130
131 /*
132  * Allocate an ephemeral SPANS SAP
133  *
134  * Arguments:
135  *      spp     pointer to SPANS protocol instance
136  *
137  * Returns:
138  *      a SPANS ephemeral SAP number
139  *
140  */
141 int
142 spans_ephemeral_sap(spp)
143         struct spans    *spp;
144 {
145         return(SPANS_SAP_EPHEMERAL);
146 }
147
148
149 /*
150  * Translate an internal AAL designator to a SPANS AAL type
151  *
152  * Arguments:
153  *      laal    internal AAL designation
154  *      saal    a pointer to the variable to receive the SPANS AAL type
155  *
156  * Returns:
157  *      TRUE    the AAL was found; *saal is valid
158  *      FALSE   the AAL was not found; *saal is not valid
159  *
160  */
161 int
162 spans_get_spans_aal(laal, saal)
163         Aal_t           laal;
164         spans_aal       *saal;
165 {
166         /*
167          *
168          */
169         switch (laal) {
170         case ATM_AAL0:
171                 *saal = SPANS_AAL0;
172                 return(TRUE);
173         case ATM_AAL1:
174                 *saal = SPANS_AAL1;
175                 return(TRUE);
176         case ATM_AAL2:
177                 *saal = SPANS_AAL2;
178                 return(TRUE);
179         case ATM_AAL3_4:
180                 *saal = SPANS_AAL4;
181                 return(TRUE);
182         case ATM_AAL5:
183                 *saal = SPANS_AAL5;
184                 return(TRUE);
185         default:
186                 return(FALSE);
187         }
188 }
189
190
191 /*
192  * Translate a SPANS AAL type to an internal AAL designator
193  *
194  * Arguments:
195  *      saal    the SPANS AAL type
196  *      laal    a pointer to the variable to receive the internal
197  *              AAL designation
198  *
199  * Returns:
200  *      TRUE    the AAL was found; *laal is valid
201  *      FALSE   the AAL was not found; *laal is not valid
202  *
203  */
204 int
205 spans_get_local_aal(saal, laal)
206         spans_aal       saal;
207         Aal_t           *laal;
208 {
209         /*
210          *
211          */
212         switch (saal) {
213         case SPANS_AAL0:
214                 *laal = ATM_AAL0;
215                 return(TRUE);
216         case SPANS_AAL1:
217                 *laal = ATM_AAL1;
218                 return(TRUE);
219         case SPANS_AAL2:
220                 *laal = ATM_AAL2;
221                 return(TRUE);
222         case SPANS_AAL3:
223         case SPANS_AAL4:
224                 *laal = ATM_AAL3_4;
225                 return(TRUE);
226         case SPANS_AAL5:
227                 *laal = ATM_AAL5;
228                 return(TRUE);
229         default:
230                 return(FALSE);
231         }
232 }
233
234
235 /*
236  * Verify a VCCB
237  *
238  * Search SPANS's VCCB queue to verify that a VCCB belongs to SPANS.
239  *
240  * Arguments:
241  *      spp     pointer to SPANS protocol instance
242  *      svp     pointer to a VCCB
243  *
244  * Returns:
245  *      TRUE    the VCCB belongs to SPANS
246  *      FALSE   the VCCB doesn't belong to SPANS
247  *
248  */
249 int
250 spans_verify_vccb(spp, svp)
251         struct spans            *spp;
252         struct spans_vccb       *svp;
253
254 {
255         struct spans_vccb       *vcp, *vcnext;
256
257         for (vcp = Q_HEAD(spp->sp_vccq, struct spans_vccb);
258                         vcp; vcp = vcnext){
259                 vcnext = Q_NEXT(vcp, struct spans_vccb, sv_sigelem);
260                 if (svp == vcp) {
261                         return(TRUE);
262                 }
263         }
264         return(FALSE);
265 }
266
267
268 /*
269  * Find a VCCB
270  *
271  * Find a VCCB given the VPI and VCI.
272  *
273  * Arguments:
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.
280  *
281  * Returns:
282  *      0       there is no such VCCB
283  *      address the address of the VCCB
284  *
285  */
286 struct spans_vccb *
287 spans_find_vpvc(spp, vpi, vci, dir)
288         struct spans    *spp;
289         int             vpi, vci;
290         u_char          dir;
291
292 {
293         struct spans_vccb       *svp, *svnext;
294
295         for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp;
296                         svp = svnext){
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)
301                         break;
302         }
303         return(svp);
304 }
305
306
307 /*
308  * Find a connection
309  *
310  * Find a VCCB given the connection structure.
311  *
312  * Arguments:
313  *      spp     pointer to SPANS protocol instance
314  *      p       pointer to an spans_atm_conn structure
315  *
316  * Returns:
317  *      0       there is no such VCCB
318  *      address the address of the VCCB
319  *
320  */
321 struct spans_vccb *
322 spans_find_conn(spp, p)
323         struct spans            *spp;
324         struct spans_atm_conn   *p;
325 {
326         struct spans_vccb       *svp, *svnext;
327
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)))
331                         break;
332         }
333         return(svp);
334 }
335
336
337 /*
338  * Allocate a VPI/VCI pair
339  *
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.
345  *
346  * Currently the Fore ATM interface only supports VPI 0, so this code only
347  * allocates a VCI.
348  *
349  * There's probably a more elegant way to do this.
350  *
351  * Arguments:
352  *      spp     pointer to connection's SPANS protocol instance
353  *
354  * Returns:
355  *      0       no VPI/VCI available
356  *      vpvc    the VPI/VCI for the connection
357  *
358  */
359 spans_vpvc
360 spans_alloc_vpvc(spp)
361         struct spans            *spp;
362 {
363         int     vpi, vci;
364
365         /*
366          * Loop through the allowable VCIs, starting with the curent one,
367          * to find one that's not in use.
368          */
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));
374                 }
375         }
376
377         /*
378          * Reset the VCI to the minimum
379          */
380         spp->sp_alloc_vci = spp->sp_min_vci;
381
382         /*
383          * Try looping through again
384          */
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));
390                 }
391         }
392
393         /*
394          * All allowable VCIs are in use
395          */
396         return(0);
397 }
398
399
400 /*
401  * Print a SPANS address
402  *
403  * Convert a SPANS address into an ASCII string suitable for printing.
404  *
405  * Arguments:
406  *      p       pointer to a struct spans_addr
407  *
408  * Returns:
409  *      the address of a string with the ASCII representation of the
410  *      address.
411  *
412  */
413 char *
414 spans_addr_print(p)
415         struct spans_addr       *p;
416 {
417         static char     strbuff[80];
418         union {
419                 int     w;
420                 char    c[4];
421         } u1, u2;
422
423
424         /*
425          * Clear the returned string
426          */
427         KM_ZERO(strbuff, sizeof(strbuff));
428
429         /*
430          * Get address into integers
431          */
432         u1.c[0] =p->addr[0];
433         u1.c[1] =p->addr[1];
434         u1.c[2] =p->addr[2];
435         u1.c[3] =p->addr[3];
436         u2.c[0] =p->addr[4];
437         u2.c[1] =p->addr[5];
438         u2.c[2] =p->addr[6];
439         u2.c[3] =p->addr[7];
440
441         /*
442          * Print and return the string
443          */
444         sprintf(strbuff, "%lx.%lx", (u_long)ntohl(u1.w), (u_long)ntohl(u2.w));
445         return(strbuff);
446 }
447
448
449 /*
450  * Print a buffer chain
451  *
452  * Arguments:
453  *      m       pointer to a buffer chain
454  *
455  * Returns:
456  *      none
457  *
458  */
459 void
460 spans_dump_buffer(m)
461         KBuffer         *m;
462 {
463         int             i;
464         caddr_t         cp;
465
466         printf("spans_dump_buffer:\n");
467         while (m) {
468                 KB_DATASTART(m, cp, caddr_t);
469                 for (i = 0; i < KB_LEN(m); i++) {
470                         if (i == 0)
471                                 printf("   bfr=%p: ", m);
472                         printf("%x ", (u_char)*cp++);
473                 }
474                 printf("<end_bfr>\n");
475                 m = KB_NEXT(m);
476         }
477 }