125986Ssklower /* 225986Ssklower * Copyright (c) 1986 Regents of the University of California. 325986Ssklower * All rights reserved. The Berkeley software License Agreement 425986Ssklower * specifies the terms and conditions for redistribution. 525986Ssklower * 625986Ssklower * Includes material written at Cornell University, by J. Q. Johnson. 725986Ssklower * Used by permission. 825986Ssklower */ 925986Ssklower 1026637Sdonn #if defined(LIBC_SCCS) && !defined(lint) 11*32297Sbostic static char sccsid[] = "@(#)ns_addr.c 6.3 (Berkeley) 09/30/87"; 1226637Sdonn #endif LIBC_SCCS and not lint 1325986Ssklower 1425986Ssklower #include <sys/types.h> 1525986Ssklower #include <netns/ns.h> 1625986Ssklower 1725986Ssklower static struct ns_addr addr, zero_addr; 1825986Ssklower 1925986Ssklower struct ns_addr 2025986Ssklower ns_addr(name) 2125986Ssklower char *name; 2225986Ssklower { 2325986Ssklower char separator = '.'; 2425986Ssklower char *hostname, *socketname, *cp; 2525986Ssklower char buf[50]; 2625986Ssklower extern char *index(); 2725986Ssklower 2825986Ssklower addr = zero_addr; 29*32297Sbostic (void)strncpy(buf, name, 49); 3025986Ssklower 3125986Ssklower /* 3225986Ssklower * First, figure out what he intends as a field separtor. 3325986Ssklower * Despite the way this routine is written, the prefered 3425986Ssklower * form 2-272.AA001234H.01777, i.e. XDE standard. 3525986Ssklower * Great efforts are made to insure backward compatability. 3625986Ssklower */ 3725986Ssklower if (hostname = index(buf, '#')) 3825986Ssklower separator = '#'; 3925986Ssklower else { 4025986Ssklower hostname = index(buf, '.'); 4125986Ssklower if ((cp = index(buf, ':')) && 4225986Ssklower ( (hostname && cp < hostname) || (hostname == 0))) { 4325986Ssklower hostname = cp; 4425986Ssklower separator = ':'; 4525986Ssklower } 4625986Ssklower } 4725986Ssklower if (hostname) 4825986Ssklower *hostname++ = 0; 4925986Ssklower Field(buf, addr.x_net.c_net, 4); 5025986Ssklower if (hostname == 0) 5125986Ssklower return (addr); /* No separator means net only */ 5225986Ssklower 5325986Ssklower socketname = index(hostname, separator); 5425986Ssklower if (socketname) { 5525986Ssklower *socketname++ = 0; 56*32297Sbostic Field(socketname, (u_char *)&addr.x_port, 2); 5725986Ssklower } 5825986Ssklower 5925986Ssklower Field(hostname, addr.x_host.c_host, 6); 6025986Ssklower 6125986Ssklower return (addr); 6225986Ssklower } 6325986Ssklower 6425986Ssklower static 6525986Ssklower Field(buf, out, len) 6625986Ssklower char *buf; 6725986Ssklower u_char *out; 6825986Ssklower int len; 6925986Ssklower { 7025986Ssklower register char *bp = buf; 7125986Ssklower int i, ibase, base16 = 0, base10 = 0, clen = 0; 7225986Ssklower int hb[6], *hp; 7325986Ssklower char *fmt; 7425986Ssklower 7525986Ssklower /* 7625986Ssklower * first try 2-273#2-852-151-014#socket 7725986Ssklower */ 7825986Ssklower if ((*buf != '-') && 7925986Ssklower (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d", 8025986Ssklower &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) { 81*32297Sbostic cvtbase(1000L, 256, hb, i, out, len); 8225986Ssklower return; 8325986Ssklower } 8425986Ssklower /* 8525986Ssklower * try form 8E1#0.0.AA.0.5E.E6#socket 8625986Ssklower */ 8725986Ssklower if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x", 8825986Ssklower &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { 89*32297Sbostic cvtbase(256L, 256, hb, i, out, len); 9025986Ssklower return; 9125986Ssklower } 9225986Ssklower /* 9325986Ssklower * try form 8E1#0:0:AA:0:5E:E6#socket 9425986Ssklower */ 9525986Ssklower if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x", 9625986Ssklower &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { 97*32297Sbostic cvtbase(256L, 256, hb, i, out, len); 9825986Ssklower return; 9925986Ssklower } 10025986Ssklower /* 10125986Ssklower * This is REALLY stretching it but there was a 10225986Ssklower * comma notation separting shorts -- definitely non standard 10325986Ssklower */ 10425986Ssklower if (1 < (i = sscanf(buf,"%x,%x,%x", 10525986Ssklower &hb[0], &hb[1], &hb[2]))) { 10625986Ssklower hb[0] = htons(hb[0]); hb[1] = htons(hb[1]); 10725986Ssklower hb[2] = htons(hb[2]); 108*32297Sbostic cvtbase(65536L, 256, hb, i, out, len); 10925986Ssklower return; 11025986Ssklower } 11125986Ssklower 11225986Ssklower /* Need to decide if base 10, 16 or 8 */ 11325986Ssklower while (*bp) switch (*bp++) { 11425986Ssklower 11525986Ssklower case '0': case '1': case '2': case '3': case '4': case '5': 11625986Ssklower case '6': case '7': case '-': 11725986Ssklower break; 11825986Ssklower 11925986Ssklower case '8': case '9': 12025986Ssklower base10 = 1; 12125986Ssklower break; 12225986Ssklower 12325986Ssklower case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 12425986Ssklower case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 12525986Ssklower base16 = 1; 12625986Ssklower break; 12725986Ssklower 12825986Ssklower case 'x': case 'X': 12925986Ssklower *--bp = '0'; 13025986Ssklower base16 = 1; 13125986Ssklower break; 13225986Ssklower 13325986Ssklower case 'h': case 'H': 13425986Ssklower base16 = 1; 13525986Ssklower /* fall into */ 13625986Ssklower 13725986Ssklower default: 13825986Ssklower *--bp = 0; /* Ends Loop */ 13925986Ssklower } 14025986Ssklower if (base16) { 14125986Ssklower fmt = "%3x"; 14225986Ssklower ibase = 4096; 14325986Ssklower } else if (base10 == 0 && *buf == '0') { 14425986Ssklower fmt = "%3o"; 14525986Ssklower ibase = 512; 14625986Ssklower } else { 14725986Ssklower fmt = "%3d"; 14825986Ssklower ibase = 1000; 14925986Ssklower } 15025986Ssklower 15125986Ssklower for (bp = buf; *bp++; ) clen++; 15225986Ssklower if (clen == 0) clen++; 15325986Ssklower if (clen > 18) clen = 18; 15425986Ssklower i = ((clen - 1) / 3) + 1; 15525986Ssklower bp = clen + buf - 3; 15625986Ssklower hp = hb + i - 1; 15725986Ssklower 15825986Ssklower while (hp > hb) { 159*32297Sbostic (void)sscanf(bp, fmt, hp); 16025986Ssklower bp[0] = 0; 16125986Ssklower hp--; 16225986Ssklower bp -= 3; 16325986Ssklower } 164*32297Sbostic (void)sscanf(buf, fmt, hp); 165*32297Sbostic cvtbase((long)ibase, 256, hb, i, out, len); 16625986Ssklower } 16725986Ssklower 16825986Ssklower static 16925986Ssklower cvtbase(oldbase,newbase,input,inlen,result,reslen) 170*32297Sbostic long oldbase; 171*32297Sbostic int newbase; 17225986Ssklower int input[]; 17325986Ssklower int inlen; 17425986Ssklower unsigned char result[]; 17525986Ssklower int reslen; 17625986Ssklower { 17725986Ssklower int d, e; 17825986Ssklower long sum; 17925986Ssklower 18025986Ssklower e = 1; 18125986Ssklower while (e > 0 && reslen > 0) { 18225986Ssklower d = 0; e = 0; sum = 0; 18325986Ssklower /* long division: input=input/newbase */ 18425986Ssklower while (d < inlen) { 18525986Ssklower sum = sum*oldbase + (long) input[d]; 18625986Ssklower e += (sum > 0); 18725986Ssklower input[d++] = sum / newbase; 18825986Ssklower sum %= newbase; 18925986Ssklower } 19025986Ssklower result[--reslen] = sum; /* accumulate remainder */ 19125986Ssklower } 19225986Ssklower for (d=0; d < reslen; d++) 19325986Ssklower result[d] = 0; 19425986Ssklower } 195