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