Merge from vendor branch BINUTILS:
[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.2 2003/06/17 04:26:41 dillon 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(in, out, len)
73         char    *in;
74         u_char  *out;
75         int     len;
76 {
77         int     c_type, c_value, i, out_len, state, val = 0;
78
79         /*
80          * Character table
81          */
82         static struct {
83                 char    c;
84                 int     type;
85                 int     value;
86         } char_table[] = {
87                 {'.',   0,      0},     /* Type 0 -- period */
88                 {':',   0,      0},     /* Type 0 -- colon */
89                 {'0',   1,      0},     /* Type 1 -- hex digit */
90                 {'1',   1,      1},
91                 {'2',   1,      2},
92                 {'3',   1,      3},
93                 {'4',   1,      4},
94                 {'5',   1,      5},
95                 {'6',   1,      6},
96                 {'7',   1,      7},
97                 {'8',   1,      8},
98                 {'9',   1,      9},
99                 {'a',   1,      10},
100                 {'b',   1,      11},
101                 {'c',   1,      12},
102                 {'d',   1,      13},
103                 {'e',   1,      14},
104                 {'f',   1,      15},
105                 {'A',   1,      10},
106                 {'B',   1,      11},
107                 {'C',   1,      12},
108                 {'D',   1,      13},
109                 {'E',   1,      14},
110                 {'F',   1,      15},
111                 {'\0',  2,      0},     /* Type 2 -- end of input */
112         };
113
114         /*
115          * State table
116          */
117         static struct {
118                 int     action;
119                 int     state;
120         } state_table[3][3] = {
121                 /* Period     Hex       End                     */
122                 { { 0, 0 }, { 1, 1 }, { 2, 0} },        /* Init */
123                 { { 4, 0 }, { 3, 2 }, { 4, 0} },        /* C1   */
124                 { { 0, 2 }, { 1, 1 }, { 2, 0} },        /* C2   */
125         };
126
127         /*
128          * Initialize
129          */
130         state = 0;
131         out_len = 0;
132         if (!strncasecmp(in, "0x", 2)) {
133                 in += 2;
134         }
135
136         /*
137          * Loop through input until state table says to return
138          */
139         while (1) {
140                 /*
141                  * Get the character type and value
142                  */
143                 for (i=0; char_table[i].c; i++)
144                         if (char_table[i].c == *in)
145                                 break;
146                 if (char_table[i].c != *in)
147                         return(0);
148                 c_type = char_table[i].type;
149                 c_value = char_table[i].value;
150
151                 /*
152                  * Process next character based on state and type
153                  */
154                 switch(state_table[state][c_type].action) {
155                 case 0:
156                         /*
157                          * Ignore the character
158                          */
159                         break;
160
161                 case 1:
162                         /*
163                          * Save the character's value
164                          */
165                         val = c_value;
166                         break;
167
168                 case 2:
169                         /*
170                          * Return the assembled NSAP
171                          */
172                         return(out_len);
173
174                 case 3:
175                         /*
176                          * Assemble and save the output byte
177                          */
178                         val = val << 4;
179                         val += c_value;
180                         out[out_len] = (u_char) val;
181                         out_len++;
182                         break;
183
184                 case 4:
185                         /*
186                          * Invalid input sequence
187                          */
188                         return(0);
189
190                 default:
191                         return(0);
192                 }
193
194                 /*
195                  * Set the next state and go on to the next character
196                  */
197                 state = state_table[state][c_type].state;
198                 in++;
199         }
200 }
201
202
203 /*
204  * Format an ATM address into a string
205  * 
206  * Arguments:
207  *      addr    pointer to an atm address
208  *
209  * Returns:
210  *      none
211  *
212  */
213 char *
214 format_atm_addr(addr)
215         Atm_addr *addr;
216 {
217         int             i;
218         char            *nsap_format;
219         Atm_addr_nsap   *atm_nsap;
220         Atm_addr_e164   *atm_e164;
221         Atm_addr_spans  *atm_spans;
222         Atm_addr_pvc    *atm_pvc;
223         static char     str[256];
224         union {
225                 int     w;
226                 char    c[4];
227         } u1, u2;
228
229         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";
230         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";
231         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";
232
233         /*
234          * Clear the returned string
235          */
236         UM_ZERO(str, sizeof(str));
237         strcpy(str, "-");
238
239         /*
240          * Print format is determined by address type
241          */
242         switch (addr->address_format) {
243         case T_ATM_ENDSYS_ADDR:
244                 atm_nsap = (Atm_addr_nsap *)addr->address;
245                 switch(atm_nsap->aan_afi) {
246                 default:
247                 case AFI_DCC:
248                         nsap_format = nsap_format_DCC;
249                         break;
250                 case AFI_ICD:
251                         nsap_format = nsap_format_ICD;
252                         break;
253                 case AFI_E164:
254                         nsap_format = nsap_format_E164;
255                         break;
256                 }
257                 sprintf(str, nsap_format, 
258                                 atm_nsap->aan_afi,
259                                 atm_nsap->aan_afspec[0],
260                                 atm_nsap->aan_afspec[1],
261                                 atm_nsap->aan_afspec[2],
262                                 atm_nsap->aan_afspec[3],
263                                 atm_nsap->aan_afspec[4],
264                                 atm_nsap->aan_afspec[5],
265                                 atm_nsap->aan_afspec[6],
266                                 atm_nsap->aan_afspec[7],
267                                 atm_nsap->aan_afspec[8],
268                                 atm_nsap->aan_afspec[9],
269                                 atm_nsap->aan_afspec[10],
270                                 atm_nsap->aan_afspec[11],
271                                 atm_nsap->aan_esi[0],
272                                 atm_nsap->aan_esi[1],
273                                 atm_nsap->aan_esi[2],
274                                 atm_nsap->aan_esi[3],
275                                 atm_nsap->aan_esi[4],
276                                 atm_nsap->aan_esi[5],
277                                 atm_nsap->aan_sel);
278                 break;
279
280         case T_ATM_E164_ADDR:
281                 atm_e164 = (Atm_addr_e164 *)addr->address;
282                 for(i=0; i<addr->address_length; i++) {
283                         sprintf(&str[strlen(str)], "%c",
284                                         atm_e164->aae_addr[i]);
285                 }
286                 break;
287
288         case T_ATM_SPANS_ADDR:
289                 /*
290                  * Print SPANS address as two words, xxxx.yyyy
291                  */
292                 atm_spans = (Atm_addr_spans *)addr->address;
293                 u1.c[0] = atm_spans->aas_addr[0];
294                 u1.c[1] = atm_spans->aas_addr[1];
295                 u1.c[2] = atm_spans->aas_addr[2];
296                 u1.c[3] = atm_spans->aas_addr[3];
297
298                 u2.c[0] = atm_spans->aas_addr[4];
299                 u2.c[1] = atm_spans->aas_addr[5];
300                 u2.c[2] = atm_spans->aas_addr[6];
301                 u2.c[3] = atm_spans->aas_addr[7];
302
303                 if (!(u1.w == 0 && u2.w == 0))
304                         sprintf(str, "0x%08lx.%08lx", ntohl(u1.w), ntohl(u2.w));
305                 break;
306
307         case T_ATM_PVC_ADDR:
308                 /*
309                  * Print PVC as VPI, VCI
310                  */
311                 atm_pvc = (Atm_addr_pvc *)addr->address;
312                 sprintf(str, "%d, %d",
313                                 ATM_PVC_GET_VPI(atm_pvc),
314                                 ATM_PVC_GET_VCI(atm_pvc));
315                 break;
316
317         case T_ATM_ABSENT:
318         default:
319                 break;
320         }
321
322         return(str);
323 }