xref: /csrg-svn/lib/libc/net/ns_addr.c (revision 35361)
125986Ssklower /*
225986Ssklower  * Copyright (c) 1986 Regents of the University of California.
3*35361Sbostic  * All rights reserved.
425986Ssklower  *
5*35361Sbostic  * Redistribution and use in source and binary forms are permitted
6*35361Sbostic  * provided that the above copyright notice and this paragraph are
7*35361Sbostic  * duplicated in all such forms and that any documentation,
8*35361Sbostic  * advertising materials, and other materials related to such
9*35361Sbostic  * distribution and use acknowledge that the software was developed
10*35361Sbostic  * by the University of California, Berkeley.  The name of the
11*35361Sbostic  * University may not be used to endorse or promote products derived
12*35361Sbostic  * from this software without specific prior written permission.
13*35361Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*35361Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*35361Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16*35361Sbostic  *
17*35361Sbostic  * This code is derived from software contributed to Berkeley by
18*35361Sbostic  * J.Q. Johnson at Cornell University.
1925986Ssklower  */
2025986Ssklower 
2126637Sdonn #if defined(LIBC_SCCS) && !defined(lint)
22*35361Sbostic static char sccsid[] = "@(#)ns_addr.c	6.4 (Berkeley) 08/12/88";
23*35361Sbostic #endif /* LIBC_SCCS and not lint */
2425986Ssklower 
2525986Ssklower #include <sys/types.h>
2625986Ssklower #include <netns/ns.h>
2725986Ssklower 
2825986Ssklower static struct ns_addr addr, zero_addr;
2925986Ssklower 
3025986Ssklower struct ns_addr
3125986Ssklower ns_addr(name)
3225986Ssklower 	char *name;
3325986Ssklower {
3425986Ssklower 	char separator = '.';
3525986Ssklower 	char *hostname, *socketname, *cp;
3625986Ssklower 	char buf[50];
3725986Ssklower 	extern char *index();
3825986Ssklower 
3925986Ssklower 	addr = zero_addr;
4032297Sbostic 	(void)strncpy(buf, name, 49);
4125986Ssklower 
4225986Ssklower 	/*
4325986Ssklower 	 * First, figure out what he intends as a field separtor.
4425986Ssklower 	 * Despite the way this routine is written, the prefered
4525986Ssklower 	 * form  2-272.AA001234H.01777, i.e. XDE standard.
4625986Ssklower 	 * Great efforts are made to insure backward compatability.
4725986Ssklower 	 */
4825986Ssklower 	if (hostname = index(buf, '#'))
4925986Ssklower 		separator = '#';
5025986Ssklower 	else {
5125986Ssklower 		hostname = index(buf, '.');
5225986Ssklower 		if ((cp = index(buf, ':')) &&
5325986Ssklower 		    ( (hostname && cp < hostname) || (hostname == 0))) {
5425986Ssklower 			hostname = cp;
5525986Ssklower 			separator = ':';
5625986Ssklower 		}
5725986Ssklower 	}
5825986Ssklower 	if (hostname)
5925986Ssklower 		*hostname++ = 0;
6025986Ssklower 	Field(buf, addr.x_net.c_net, 4);
6125986Ssklower 	if (hostname == 0)
6225986Ssklower 		return (addr);  /* No separator means net only */
6325986Ssklower 
6425986Ssklower 	socketname = index(hostname, separator);
6525986Ssklower 	if (socketname) {
6625986Ssklower 		*socketname++ = 0;
6732297Sbostic 		Field(socketname, (u_char *)&addr.x_port, 2);
6825986Ssklower 	}
6925986Ssklower 
7025986Ssklower 	Field(hostname, addr.x_host.c_host, 6);
7125986Ssklower 
7225986Ssklower 	return (addr);
7325986Ssklower }
7425986Ssklower 
7525986Ssklower static
7625986Ssklower Field(buf, out, len)
7725986Ssklower char *buf;
7825986Ssklower u_char *out;
7925986Ssklower int len;
8025986Ssklower {
8125986Ssklower 	register char *bp = buf;
8225986Ssklower 	int i, ibase, base16 = 0, base10 = 0, clen = 0;
8325986Ssklower 	int hb[6], *hp;
8425986Ssklower 	char *fmt;
8525986Ssklower 
8625986Ssklower 	/*
8725986Ssklower 	 * first try 2-273#2-852-151-014#socket
8825986Ssklower 	 */
8925986Ssklower 	if ((*buf != '-') &&
9025986Ssklower 	    (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
9125986Ssklower 			&hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
9232297Sbostic 		cvtbase(1000L, 256, hb, i, out, len);
9325986Ssklower 		return;
9425986Ssklower 	}
9525986Ssklower 	/*
9625986Ssklower 	 * try form 8E1#0.0.AA.0.5E.E6#socket
9725986Ssklower 	 */
9825986Ssklower 	if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
9925986Ssklower 			&hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
10032297Sbostic 		cvtbase(256L, 256, hb, i, out, len);
10125986Ssklower 		return;
10225986Ssklower 	}
10325986Ssklower 	/*
10425986Ssklower 	 * try form 8E1#0:0:AA:0:5E:E6#socket
10525986Ssklower 	 */
10625986Ssklower 	if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
10725986Ssklower 			&hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
10832297Sbostic 		cvtbase(256L, 256, hb, i, out, len);
10925986Ssklower 		return;
11025986Ssklower 	}
11125986Ssklower 	/*
11225986Ssklower 	 * This is REALLY stretching it but there was a
11325986Ssklower 	 * comma notation separting shorts -- definitely non standard
11425986Ssklower 	 */
11525986Ssklower 	if (1 < (i = sscanf(buf,"%x,%x,%x",
11625986Ssklower 			&hb[0], &hb[1], &hb[2]))) {
11725986Ssklower 		hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
11825986Ssklower 		hb[2] = htons(hb[2]);
11932297Sbostic 		cvtbase(65536L, 256, hb, i, out, len);
12025986Ssklower 		return;
12125986Ssklower 	}
12225986Ssklower 
12325986Ssklower 	/* Need to decide if base 10, 16 or 8 */
12425986Ssklower 	while (*bp) switch (*bp++) {
12525986Ssklower 
12625986Ssklower 	case '0': case '1': case '2': case '3': case '4': case '5':
12725986Ssklower 	case '6': case '7': case '-':
12825986Ssklower 		break;
12925986Ssklower 
13025986Ssklower 	case '8': case '9':
13125986Ssklower 		base10 = 1;
13225986Ssklower 		break;
13325986Ssklower 
13425986Ssklower 	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
13525986Ssklower 	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
13625986Ssklower 		base16 = 1;
13725986Ssklower 		break;
13825986Ssklower 
13925986Ssklower 	case 'x': case 'X':
14025986Ssklower 		*--bp = '0';
14125986Ssklower 		base16 = 1;
14225986Ssklower 		break;
14325986Ssklower 
14425986Ssklower 	case 'h': case 'H':
14525986Ssklower 		base16 = 1;
14625986Ssklower 		/* fall into */
14725986Ssklower 
14825986Ssklower 	default:
14925986Ssklower 		*--bp = 0; /* Ends Loop */
15025986Ssklower 	}
15125986Ssklower 	if (base16) {
15225986Ssklower 		fmt = "%3x";
15325986Ssklower 		ibase = 4096;
15425986Ssklower 	} else if (base10 == 0 && *buf == '0') {
15525986Ssklower 		fmt = "%3o";
15625986Ssklower 		ibase = 512;
15725986Ssklower 	} else {
15825986Ssklower 		fmt = "%3d";
15925986Ssklower 		ibase = 1000;
16025986Ssklower 	}
16125986Ssklower 
16225986Ssklower 	for (bp = buf; *bp++; ) clen++;
16325986Ssklower 	if (clen == 0) clen++;
16425986Ssklower 	if (clen > 18) clen = 18;
16525986Ssklower 	i = ((clen - 1) / 3) + 1;
16625986Ssklower 	bp = clen + buf - 3;
16725986Ssklower 	hp = hb + i - 1;
16825986Ssklower 
16925986Ssklower 	while (hp > hb) {
17032297Sbostic 		(void)sscanf(bp, fmt, hp);
17125986Ssklower 		bp[0] = 0;
17225986Ssklower 		hp--;
17325986Ssklower 		bp -= 3;
17425986Ssklower 	}
17532297Sbostic 	(void)sscanf(buf, fmt, hp);
17632297Sbostic 	cvtbase((long)ibase, 256, hb, i, out, len);
17725986Ssklower }
17825986Ssklower 
17925986Ssklower static
18025986Ssklower cvtbase(oldbase,newbase,input,inlen,result,reslen)
18132297Sbostic 	long oldbase;
18232297Sbostic 	int newbase;
18325986Ssklower 	int input[];
18425986Ssklower 	int inlen;
18525986Ssklower 	unsigned char result[];
18625986Ssklower 	int reslen;
18725986Ssklower {
18825986Ssklower 	int d, e;
18925986Ssklower 	long sum;
19025986Ssklower 
19125986Ssklower 	e = 1;
19225986Ssklower 	while (e > 0 && reslen > 0) {
19325986Ssklower 		d = 0; e = 0; sum = 0;
19425986Ssklower 		/* long division: input=input/newbase */
19525986Ssklower 		while (d < inlen) {
19625986Ssklower 			sum = sum*oldbase + (long) input[d];
19725986Ssklower 			e += (sum > 0);
19825986Ssklower 			input[d++] = sum / newbase;
19925986Ssklower 			sum %= newbase;
20025986Ssklower 		}
20125986Ssklower 		result[--reslen] = sum;	/* accumulate remainder */
20225986Ssklower 	}
20325986Ssklower 	for (d=0; d < reslen; d++)
20425986Ssklower 		result[d] = 0;
20525986Ssklower }
206