125986Ssklower /*
2*62540Sbostic * Copyright (c) 1986, 1993
3*62540Sbostic * The Regents of the University of California. All rights reserved.
425986Ssklower *
542953Sbostic * This code is derived from software contributed to Berkeley by
642953Sbostic * J.Q. Johnson.
742953Sbostic *
842626Sbostic * %sccs.include.redist.c%
925986Ssklower */
1025986Ssklower
1126637Sdonn #if defined(LIBC_SCCS) && !defined(lint)
12*62540Sbostic static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 06/07/93";
1335361Sbostic #endif /* LIBC_SCCS and not lint */
1425986Ssklower
1546604Sbostic #include <sys/param.h>
1625986Ssklower #include <netns/ns.h>
1746604Sbostic #include <stdio.h>
1846604Sbostic #include <string.h>
1925986Ssklower
2025986Ssklower static struct ns_addr addr, zero_addr;
2125986Ssklower
2246604Sbostic static void Field(), cvtbase();
2346604Sbostic
2425986Ssklower struct ns_addr
ns_addr(name)2525986Ssklower ns_addr(name)
2646604Sbostic const char *name;
2725986Ssklower {
2846604Sbostic char separator;
2925986Ssklower char *hostname, *socketname, *cp;
3025986Ssklower char buf[50];
3125986Ssklower
3250385Ssklower (void)strncpy(buf, name, sizeof(buf) - 1);
3350385Ssklower buf[sizeof(buf) - 1] = '\0';
3425986Ssklower
3525986Ssklower /*
3625986Ssklower * First, figure out what he intends as a field separtor.
3725986Ssklower * Despite the way this routine is written, the prefered
3825986Ssklower * form 2-272.AA001234H.01777, i.e. XDE standard.
3925986Ssklower * Great efforts are made to insure backward compatability.
4025986Ssklower */
4162539Sbostic if (hostname = strchr(buf, '#'))
4225986Ssklower separator = '#';
4325986Ssklower else {
4462539Sbostic hostname = strchr(buf, '.');
4562539Sbostic if ((cp = strchr(buf, ':')) &&
4646604Sbostic ((hostname && cp < hostname) || (hostname == 0))) {
4725986Ssklower hostname = cp;
4825986Ssklower separator = ':';
4946604Sbostic } else
5046604Sbostic separator = '.';
5125986Ssklower }
5225986Ssklower if (hostname)
5325986Ssklower *hostname++ = 0;
5446604Sbostic
5546604Sbostic addr = zero_addr;
5625986Ssklower Field(buf, addr.x_net.c_net, 4);
5725986Ssklower if (hostname == 0)
5825986Ssklower return (addr); /* No separator means net only */
5925986Ssklower
6062539Sbostic socketname = strchr(hostname, separator);
6125986Ssklower if (socketname) {
6225986Ssklower *socketname++ = 0;
6332297Sbostic Field(socketname, (u_char *)&addr.x_port, 2);
6425986Ssklower }
6525986Ssklower
6625986Ssklower Field(hostname, addr.x_host.c_host, 6);
6725986Ssklower
6825986Ssklower return (addr);
6925986Ssklower }
7025986Ssklower
7146604Sbostic static void
Field(buf,out,len)7225986Ssklower Field(buf, out, len)
7346604Sbostic char *buf;
7446604Sbostic u_char *out;
7546604Sbostic int len;
7625986Ssklower {
7725986Ssklower register char *bp = buf;
7825986Ssklower int i, ibase, base16 = 0, base10 = 0, clen = 0;
7925986Ssklower int hb[6], *hp;
8025986Ssklower char *fmt;
8125986Ssklower
8225986Ssklower /*
8325986Ssklower * first try 2-273#2-852-151-014#socket
8425986Ssklower */
8525986Ssklower if ((*buf != '-') &&
8625986Ssklower (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
8725986Ssklower &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
8832297Sbostic cvtbase(1000L, 256, hb, i, out, len);
8925986Ssklower return;
9025986Ssklower }
9125986Ssklower /*
9225986Ssklower * try form 8E1#0.0.AA.0.5E.E6#socket
9325986Ssklower */
9425986Ssklower if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
9525986Ssklower &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
9632297Sbostic cvtbase(256L, 256, hb, i, out, len);
9725986Ssklower return;
9825986Ssklower }
9925986Ssklower /*
10025986Ssklower * try form 8E1#0:0:AA:0:5E:E6#socket
10125986Ssklower */
10225986Ssklower if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
10325986Ssklower &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
10432297Sbostic cvtbase(256L, 256, hb, i, out, len);
10525986Ssklower return;
10625986Ssklower }
10725986Ssklower /*
10825986Ssklower * This is REALLY stretching it but there was a
10925986Ssklower * comma notation separting shorts -- definitely non standard
11025986Ssklower */
11125986Ssklower if (1 < (i = sscanf(buf,"%x,%x,%x",
11225986Ssklower &hb[0], &hb[1], &hb[2]))) {
11325986Ssklower hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
11425986Ssklower hb[2] = htons(hb[2]);
11532297Sbostic cvtbase(65536L, 256, hb, i, out, len);
11625986Ssklower return;
11725986Ssklower }
11825986Ssklower
11925986Ssklower /* Need to decide if base 10, 16 or 8 */
12025986Ssklower while (*bp) switch (*bp++) {
12125986Ssklower
12225986Ssklower case '0': case '1': case '2': case '3': case '4': case '5':
12325986Ssklower case '6': case '7': case '-':
12425986Ssklower break;
12525986Ssklower
12625986Ssklower case '8': case '9':
12725986Ssklower base10 = 1;
12825986Ssklower break;
12925986Ssklower
13025986Ssklower case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
13125986Ssklower case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
13225986Ssklower base16 = 1;
13325986Ssklower break;
13425986Ssklower
13525986Ssklower case 'x': case 'X':
13625986Ssklower *--bp = '0';
13725986Ssklower base16 = 1;
13825986Ssklower break;
13925986Ssklower
14025986Ssklower case 'h': case 'H':
14125986Ssklower base16 = 1;
14225986Ssklower /* fall into */
14325986Ssklower
14425986Ssklower default:
14525986Ssklower *--bp = 0; /* Ends Loop */
14625986Ssklower }
14725986Ssklower if (base16) {
14825986Ssklower fmt = "%3x";
14925986Ssklower ibase = 4096;
15025986Ssklower } else if (base10 == 0 && *buf == '0') {
15125986Ssklower fmt = "%3o";
15225986Ssklower ibase = 512;
15325986Ssklower } else {
15425986Ssklower fmt = "%3d";
15525986Ssklower ibase = 1000;
15625986Ssklower }
15725986Ssklower
15825986Ssklower for (bp = buf; *bp++; ) clen++;
15925986Ssklower if (clen == 0) clen++;
16025986Ssklower if (clen > 18) clen = 18;
16125986Ssklower i = ((clen - 1) / 3) + 1;
16225986Ssklower bp = clen + buf - 3;
16325986Ssklower hp = hb + i - 1;
16425986Ssklower
16525986Ssklower while (hp > hb) {
16632297Sbostic (void)sscanf(bp, fmt, hp);
16725986Ssklower bp[0] = 0;
16825986Ssklower hp--;
16925986Ssklower bp -= 3;
17025986Ssklower }
17132297Sbostic (void)sscanf(buf, fmt, hp);
17232297Sbostic cvtbase((long)ibase, 256, hb, i, out, len);
17325986Ssklower }
17425986Ssklower
17546604Sbostic static void
cvtbase(oldbase,newbase,input,inlen,result,reslen)17625986Ssklower cvtbase(oldbase,newbase,input,inlen,result,reslen)
17732297Sbostic long oldbase;
17832297Sbostic int newbase;
17925986Ssklower int input[];
18025986Ssklower int inlen;
18125986Ssklower unsigned char result[];
18225986Ssklower int reslen;
18325986Ssklower {
18425986Ssklower int d, e;
18525986Ssklower long sum;
18625986Ssklower
18725986Ssklower e = 1;
18825986Ssklower while (e > 0 && reslen > 0) {
18925986Ssklower d = 0; e = 0; sum = 0;
19025986Ssklower /* long division: input=input/newbase */
19125986Ssklower while (d < inlen) {
19225986Ssklower sum = sum*oldbase + (long) input[d];
19325986Ssklower e += (sum > 0);
19425986Ssklower input[d++] = sum / newbase;
19525986Ssklower sum %= newbase;
19625986Ssklower }
19725986Ssklower result[--reslen] = sum; /* accumulate remainder */
19825986Ssklower }
19925986Ssklower for (d=0; d < reslen; d++)
20025986Ssklower result[d] = 0;
20125986Ssklower }
202