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