1: /* 2: * Copyright (c) 1986 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * Includes material written at Cornell University, by J. Q. Johnson. 7: * Used by permission. 8: */ 9: 10: #if defined(LIBC_SCCS) && !defined(lint) 11: static char sccsid[] = "@(#)ns_addr.c 6.2 (Berkeley) 3/9/86"; 12: #endif LIBC_SCCS and not lint 13: 14: #include <sys/types.h> 15: #include <netns/ns.h> 16: 17: static struct ns_addr addr, zero_addr; 18: 19: struct ns_addr 20: ns_addr(name) 21: char *name; 22: { 23: u_long net; 24: u_short socket; 25: char separator = '.'; 26: char *hostname, *socketname, *cp; 27: char buf[50]; 28: extern char *index(); 29: 30: addr = zero_addr; 31: strncpy(buf, name, 49); 32: 33: /* 34: * First, figure out what he intends as a field separtor. 35: * Despite the way this routine is written, the prefered 36: * form 2-272.AA001234H.01777, i.e. XDE standard. 37: * Great efforts are made to insure backward compatability. 38: */ 39: if (hostname = index(buf, '#')) 40: separator = '#'; 41: else { 42: hostname = index(buf, '.'); 43: if ((cp = index(buf, ':')) && 44: ( (hostname && cp < hostname) || (hostname == 0))) { 45: hostname = cp; 46: separator = ':'; 47: } 48: } 49: if (hostname) 50: *hostname++ = 0; 51: Field(buf, addr.x_net.c_net, 4); 52: if (hostname == 0) 53: return (addr); /* No separator means net only */ 54: 55: socketname = index(hostname, separator); 56: if (socketname) { 57: *socketname++ = 0; 58: Field(socketname, &addr.x_port, 2); 59: } 60: 61: Field(hostname, addr.x_host.c_host, 6); 62: 63: return (addr); 64: } 65: 66: static 67: Field(buf, out, len) 68: char *buf; 69: u_char *out; 70: int len; 71: { 72: register char *bp = buf; 73: int i, ibase, base16 = 0, base10 = 0, clen = 0; 74: int hb[6], *hp; 75: char *fmt; 76: 77: /* 78: * first try 2-273#2-852-151-014#socket 79: */ 80: if ((*buf != '-') && 81: (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d", 82: &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) { 83: cvtbase(1000, 256, hb, i, out, len); 84: return; 85: } 86: /* 87: * try form 8E1#0.0.AA.0.5E.E6#socket 88: */ 89: if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x", 90: &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { 91: cvtbase(256, 256, hb, i, out, len); 92: return; 93: } 94: /* 95: * try form 8E1#0:0:AA:0:5E:E6#socket 96: */ 97: if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x", 98: &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { 99: cvtbase(256, 256, hb, i, out, len); 100: return; 101: } 102: /* 103: * This is REALLY stretching it but there was a 104: * comma notation separting shorts -- definitely non standard 105: */ 106: if (1 < (i = sscanf(buf,"%x,%x,%x", 107: &hb[0], &hb[1], &hb[2]))) { 108: hb[0] = htons(hb[0]); hb[1] = htons(hb[1]); 109: hb[2] = htons(hb[2]); 110: cvtbase(65536, 256, hb, i, out, len); 111: return; 112: } 113: 114: /* Need to decide if base 10, 16 or 8 */ 115: while (*bp) switch (*bp++) { 116: 117: case '0': case '1': case '2': case '3': case '4': case '5': 118: case '6': case '7': case '-': 119: break; 120: 121: case '8': case '9': 122: base10 = 1; 123: break; 124: 125: case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 126: case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 127: base16 = 1; 128: break; 129: 130: case 'x': case 'X': 131: *--bp = '0'; 132: base16 = 1; 133: break; 134: 135: case 'h': case 'H': 136: base16 = 1; 137: /* fall into */ 138: 139: default: 140: *--bp = 0; /* Ends Loop */ 141: } 142: if (base16) { 143: fmt = "%3x"; 144: ibase = 4096; 145: } else if (base10 == 0 && *buf == '0') { 146: fmt = "%3o"; 147: ibase = 512; 148: } else { 149: fmt = "%3d"; 150: ibase = 1000; 151: } 152: 153: for (bp = buf; *bp++; ) clen++; 154: if (clen == 0) clen++; 155: if (clen > 18) clen = 18; 156: i = ((clen - 1) / 3) + 1; 157: bp = clen + buf - 3; 158: hp = hb + i - 1; 159: 160: while (hp > hb) { 161: sscanf(bp, fmt, hp); 162: bp[0] = 0; 163: hp--; 164: bp -= 3; 165: } 166: sscanf(buf, fmt, hp); 167: cvtbase(ibase, 256, hb, i, out, len); 168: } 169: 170: static 171: cvtbase(oldbase,newbase,input,inlen,result,reslen) 172: long oldbase; 173: int newbase; 174: int input[]; 175: int inlen; 176: unsigned char result[]; 177: int reslen; 178: { 179: int d, e; 180: long sum; 181: 182: e = 1; 183: while (e > 0 && reslen > 0) { 184: d = 0; e = 0; sum = 0; 185: /* long division: input=input/newbase */ 186: while (d < inlen) { 187: sum = sum*oldbase + (long) input[d]; 188: e += (sum > 0); 189: input[d++] = sum / newbase; 190: sum %= newbase; 191: } 192: result[--reslen] = sum; /* accumulate remainder */ 193: } 194: for (d=0; d < reslen; d++) 195: result[d] = 0; 196: }