dloader - Add user_scheduler kenv tuneable sample
[dragonfly.git] / lib / libatm / atm_addr.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/lib/libatm/atm_addr.c,v 1.4.2.1 2001/09/28 16:52:10 dillon Exp $
27  * $DragonFly: src/lib/libatm/atm_addr.c,v 1.4 2008/09/30 16:57:04 swildner Exp $
28  */
29
30 /*
31  * User Space Library Functions
32  * ----------------------------
33  *
34  * ATM address utility functions
35  *
36  */
37
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/socket.h>
41 #include <net/if.h>
42 #include <netinet/in.h>
43 #include <netatm/port.h>
44 #include <netatm/atm.h>
45 #include <netatm/atm_if.h>
46 #include <netatm/atm_sap.h>
47 #include <netatm/atm_sys.h>
48 #include <netatm/atm_ioctl.h>
49
50 #include <stdio.h>
51 #include <string.h>
52
53 #include "libatm.h"
54
55 extern char     *prog;
56
57
58 /*
59  * Get NSAP, NSAP prefix or MAC address
60  *
61  * Arguments:
62  *      in      pointer to an address in ASCII
63  *      out     pointer to a buffer for the converted address
64  *      len     the length of the output buffer
65  *
66  * Returns:
67  *      0       error in format
68  *      len     the length of the data in the output buffer
69  *
70  */
71 int
72 get_hex_atm_addr(char *in, u_char *out, int len)
73 {
74         int     c_type, c_value, i, out_len, state, val = 0;
75
76         /*
77          * Character table
78          */
79         static struct {
80                 char    c;
81                 int     type;
82                 int     value;
83         } char_table[] = {
84                 {'.',   0,      0},     /* Type 0 -- period */
85                 {':',   0,      0},     /* Type 0 -- colon */
86                 {'0',   1,      0},     /* Type 1 -- hex digit */
87                 {'1',   1,      1},
88                 {'2',   1,      2},
89                 {'3',   1,      3},
90                 {'4',   1,      4},
91                 {'5',   1,      5},
92                 {'6',   1,      6},
93                 {'7',   1,      7},
94                 {'8',   1,      8},
95                 {'9',   1,      9},
96                 {'a',   1,      10},
97                 {'b',   1,      11},
98                 {'c',   1,      12},
99                 {'d',   1,      13},
100                 {'e',   1,      14},
101                 {'f',   1,      15},
102                 {'A',   1,      10},
103                 {'B',   1,      11},
104                 {'C',   1,      12},
105                 {'D',   1,      13},
106                 {'E',   1,      14},
107                 {'F',   1,      15},
108                 {'\0',  2,      0},     /* Type 2 -- end of input */
109         };
110
111         /*
112          * State table
113          */
114         static struct {
115                 int     action;
116                 int     state;
117         } state_table[3][3] = {
118                 /* Period     Hex       End                     */
119                 { { 0, 0 }, { 1, 1 }, { 2, 0} },        /* Init */
120                 { { 4, 0 }, { 3, 2 }, { 4, 0} },        /* C1   */
121                 { { 0, 2 }, { 1, 1 }, { 2, 0} },        /* C2   */
122         };
123
124         /*
125          * Initialize
126          */
127         state = 0;
128         out_len = 0;
129         if (!strncasecmp(in, "0x", 2)) {
130                 in += 2;
131         }
132
133         /*
134          * Loop through input until state table says to return
135          */
136         while (1) {
137                 /*
138                  * Get the character type and value
139                  */
140                 for (i=0; char_table[i].c; i++)
141                         if (char_table[i].c == *in)
142                                 break;
143                 if (char_table[i].c != *in)
144                         return(0);
145                 c_type = char_table[i].type;
146                 c_value = char_table[i].value;
147
148                 /*
149                  * Process next character based on state and type
150                  */
151                 switch(state_table[state][c_type].action) {
152                 case 0:
153                         /*
154                          * Ignore the character
155                          */
156                         break;
157
158                 case 1:
159                         /*
160                          * Save the character's value
161                          */
162                         val = c_value;
163                         break;
164
165                 case 2:
166                         /*
167                          * Return the assembled NSAP
168                          */
169                         return(out_len);
170
171                 case 3:
172                         /*
173                          * Assemble and save the output byte
174                          */
175                         val = val << 4;
176                         val += c_value;
177                         out[out_len] = (u_char) val;
178                         out_len++;
179                         break;
180
181                 case 4:
182                         /*
183                          * Invalid input sequence
184                          */
185                         return(0);
186
187                 default:
188                         return(0);
189                 }
190
191                 /*
192                  * Set the next state and go on to the next character
193                  */
194                 state = state_table[state][c_type].state;
195                 in++;
196         }
197 }
198
199
200 /*
201  * Format an ATM address into a string
202  * 
203  * Arguments:
204  *      addr    pointer to an atm address
205  *
206  * Returns:
207  *      none
208  *
209  */
210 char *
211 format_atm_addr(Atm_addr *addr)
212 {
213         int             i;
214         char            *nsap_format;
215         Atm_addr_nsap   *atm_nsap;
216         Atm_addr_e164   *atm_e164;
217         Atm_addr_spans  *atm_spans;
218         Atm_addr_pvc    *atm_pvc;
219         static char     str[256];
220         union {
221                 int     w;
222                 char    c[4];
223         } u1, u2;
224
225         static char     nsap_format_DCC[] = "0x%02x.%02x%02x.%02x.%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x%02x%02x.%02x";
226         static char     nsap_format_ICD[] = "0x%02x.%02x%02x.%02x.%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x%02x%02x.%02x";
227         static char     nsap_format_E164[] = "0x%02x.%02x%02x%02x%02x%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x%02x%02x.%02x";
228
229         /*
230          * Clear the returned string
231          */
232         UM_ZERO(str, sizeof(str));
233         strlcpy(str, "-", sizeof(str));
234
235         /*
236          * Print format is determined by address type
237          */
238         switch (addr->address_format) {
239         case T_ATM_ENDSYS_ADDR:
240                 atm_nsap = (Atm_addr_nsap *)addr->address;
241                 switch(atm_nsap->aan_afi) {
242                 default:
243                 case AFI_DCC:
244                         nsap_format = nsap_format_DCC;
245                         break;
246                 case AFI_ICD:
247                         nsap_format = nsap_format_ICD;
248                         break;
249                 case AFI_E164:
250                         nsap_format = nsap_format_E164;
251                         break;
252                 }
253                 sprintf(str, nsap_format, 
254                                 atm_nsap->aan_afi,
255                                 atm_nsap->aan_afspec[0],
256                                 atm_nsap->aan_afspec[1],
257                                 atm_nsap->aan_afspec[2],
258                                 atm_nsap->aan_afspec[3],
259                                 atm_nsap->aan_afspec[4],
260                                 atm_nsap->aan_afspec[5],
261                                 atm_nsap->aan_afspec[6],
262                                 atm_nsap->aan_afspec[7],
263                                 atm_nsap->aan_afspec[8],
264                                 atm_nsap->aan_afspec[9],
265                                 atm_nsap->aan_afspec[10],
266                                 atm_nsap->aan_afspec[11],
267                                 atm_nsap->aan_esi[0],
268                                 atm_nsap->aan_esi[1],
269                                 atm_nsap->aan_esi[2],
270                                 atm_nsap->aan_esi[3],
271                                 atm_nsap->aan_esi[4],
272                                 atm_nsap->aan_esi[5],
273                                 atm_nsap->aan_sel);
274                 break;
275
276         case T_ATM_E164_ADDR:
277                 atm_e164 = (Atm_addr_e164 *)addr->address;
278                 for(i=0; i<addr->address_length; i++) {
279                         sprintf(&str[strlen(str)], "%c",
280                                         atm_e164->aae_addr[i]);
281                 }
282                 break;
283
284         case T_ATM_SPANS_ADDR:
285                 /*
286                  * Print SPANS address as two words, xxxx.yyyy
287                  */
288                 atm_spans = (Atm_addr_spans *)addr->address;
289                 u1.c[0] = atm_spans->aas_addr[0];
290                 u1.c[1] = atm_spans->aas_addr[1];
291                 u1.c[2] = atm_spans->aas_addr[2];
292                 u1.c[3] = atm_spans->aas_addr[3];
293
294                 u2.c[0] = atm_spans->aas_addr[4];
295                 u2.c[1] = atm_spans->aas_addr[5];
296                 u2.c[2] = atm_spans->aas_addr[6];
297                 u2.c[3] = atm_spans->aas_addr[7];
298
299                 if (!(u1.w == 0 && u2.w == 0))
300                         sprintf(str, "0x%08lx.%08lx", ntohl(u1.w), ntohl(u2.w));
301                 break;
302
303         case T_ATM_PVC_ADDR:
304                 /*
305                  * Print PVC as VPI, VCI
306                  */
307                 atm_pvc = (Atm_addr_pvc *)addr->address;
308                 sprintf(str, "%d, %d",
309                                 ATM_PVC_GET_VPI(atm_pvc),
310                                 ATM_PVC_GET_VCI(atm_pvc));
311                 break;
312
313         case T_ATM_ABSENT:
314         default:
315                 break;
316         }
317
318         return(str);
319 }