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