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