]> git.saurik.com Git - apple/libc.git/blob - net.subproj/ns_addr.c
Libc-167.tar.gz
[apple/libc.git] / net.subproj / ns_addr.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * Copyright (c) 1986, 1993
24 * The Regents of the University of California. All rights reserved.
25 *
26 * This code is derived from software contributed to Berkeley by
27 * J.Q. Johnson.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 */
57
58
59 #include <sys/param.h>
60 #include <netns/ns.h>
61 #include <stdio.h>
62 #include <string.h>
63
64 static struct ns_addr addr, zero_addr;
65
66 static void Field(), cvtbase();
67
68 struct ns_addr
69 ns_addr(name)
70 const char *name;
71 {
72 char separator;
73 char *hostname, *socketname, *cp;
74 char buf[50];
75
76 (void)strncpy(buf, name, sizeof(buf) - 1);
77 buf[sizeof(buf) - 1] = '\0';
78
79 /*
80 * First, figure out what he intends as a field separtor.
81 * Despite the way this routine is written, the prefered
82 * form 2-272.AA001234H.01777, i.e. XDE standard.
83 * Great efforts are made to insure backward compatability.
84 */
85 if (hostname = strchr(buf, '#'))
86 separator = '#';
87 else {
88 hostname = strchr(buf, '.');
89 if ((cp = strchr(buf, ':')) &&
90 ((hostname && cp < hostname) || (hostname == 0))) {
91 hostname = cp;
92 separator = ':';
93 } else
94 separator = '.';
95 }
96 if (hostname)
97 *hostname++ = 0;
98
99 addr = zero_addr;
100 Field(buf, addr.x_net.c_net, 4);
101 if (hostname == 0)
102 return (addr); /* No separator means net only */
103
104 socketname = strchr(hostname, separator);
105 if (socketname) {
106 *socketname++ = 0;
107 Field(socketname, (u_char *)&addr.x_port, 2);
108 }
109
110 Field(hostname, addr.x_host.c_host, 6);
111
112 return (addr);
113 }
114
115 static void
116 Field(buf, out, len)
117 char *buf;
118 u_char *out;
119 int len;
120 {
121 register char *bp = buf;
122 int i, ibase, base16 = 0, base10 = 0, clen = 0;
123 int hb[6], *hp;
124 char *fmt;
125
126 /*
127 * first try 2-273#2-852-151-014#socket
128 */
129 if ((*buf != '-') &&
130 (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
131 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
132 cvtbase(1000L, 256, hb, i, out, len);
133 return;
134 }
135 /*
136 * try form 8E1#0.0.AA.0.5E.E6#socket
137 */
138 if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
139 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
140 cvtbase(256L, 256, hb, i, out, len);
141 return;
142 }
143 /*
144 * try form 8E1#0:0:AA:0:5E:E6#socket
145 */
146 if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
147 &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
148 cvtbase(256L, 256, hb, i, out, len);
149 return;
150 }
151 /*
152 * This is REALLY stretching it but there was a
153 * comma notation separting shorts -- definitely non standard
154 */
155 if (1 < (i = sscanf(buf,"%x,%x,%x",
156 &hb[0], &hb[1], &hb[2]))) {
157 hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
158 hb[2] = htons(hb[2]);
159 cvtbase(65536L, 256, hb, i, out, len);
160 return;
161 }
162
163 /* Need to decide if base 10, 16 or 8 */
164 while (*bp) switch (*bp++) {
165
166 case '0': case '1': case '2': case '3': case '4': case '5':
167 case '6': case '7': case '-':
168 break;
169
170 case '8': case '9':
171 base10 = 1;
172 break;
173
174 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
175 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
176 base16 = 1;
177 break;
178
179 case 'x': case 'X':
180 *--bp = '0';
181 base16 = 1;
182 break;
183
184 case 'h': case 'H':
185 base16 = 1;
186 /* fall into */
187
188 default:
189 *--bp = 0; /* Ends Loop */
190 }
191 if (base16) {
192 fmt = "%3x";
193 ibase = 4096;
194 } else if (base10 == 0 && *buf == '0') {
195 fmt = "%3o";
196 ibase = 512;
197 } else {
198 fmt = "%3d";
199 ibase = 1000;
200 }
201
202 for (bp = buf; *bp++; ) clen++;
203 if (clen == 0) clen++;
204 if (clen > 18) clen = 18;
205 i = ((clen - 1) / 3) + 1;
206 bp = clen + buf - 3;
207 hp = hb + i - 1;
208
209 while (hp > hb) {
210 (void)sscanf(bp, fmt, hp);
211 bp[0] = 0;
212 hp--;
213 bp -= 3;
214 }
215 (void)sscanf(buf, fmt, hp);
216 cvtbase((long)ibase, 256, hb, i, out, len);
217 }
218
219 static void
220 cvtbase(oldbase,newbase,input,inlen,result,reslen)
221 long oldbase;
222 int newbase;
223 int input[];
224 int inlen;
225 unsigned char result[];
226 int reslen;
227 {
228 int d, e;
229 long sum;
230
231 e = 1;
232 while (e > 0 && reslen > 0) {
233 d = 0; e = 0; sum = 0;
234 /* long division: input=input/newbase */
235 while (d < inlen) {
236 sum = sum*oldbase + (long) input[d];
237 e += (sum > 0);
238 input[d++] = sum / newbase;
239 sum %= newbase;
240 }
241 result[--reslen] = sum; /* accumulate remainder */
242 }
243 for (d=0; d < reslen; d++)
244 result[d] = 0;
245 }