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) 03/09/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 int oldbase, 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