xref: /csrg-svn/lib/libc/net/ns_addr.c (revision 62540)
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