1 #ifndef lint 2 static char sccsid[] = "@(#)htable.c 4.3 (Berkeley) 05/04/83"; 3 #endif 4 5 /* 6 * htable - convert NIC host table into a UNIX format. 7 * NIC format is described in RFC 810, 1 March 1982. 8 */ 9 #include <stdio.h> 10 #include <ctype.h> 11 #include <errno.h> 12 #include <netdb.h> 13 #include <sys/socket.h> 14 15 #include "htable.h" /* includes <sys/types.h> */ 16 17 #include <netinet/in.h> 18 19 #define INTERNET 10 /* gag */ 20 21 FILE *hf; /* hosts file */ 22 FILE *gf; /* gateways file */ 23 FILE *nf; /* networks file */ 24 25 main(argc, argv) 26 int argc; 27 char *argv[]; 28 { 29 if (argc > 2) { 30 fprintf(stderr, "usage: %s [ input-file ]\n", 31 argv[0]); 32 exit(1); 33 } 34 infile = "(stdin)"; 35 if (argc == 2) { 36 infile = argv[1]; 37 if (freopen(infile, "r", stdin) == NULL) { 38 perror(infile); 39 exit(1); 40 } 41 } 42 hf = fopen("hosts", "w"); 43 if (hf == NULL) { 44 perror("hosts"); 45 exit(1); 46 } 47 copylocal(hf, "localhosts"); 48 gf = fopen("gateways", "w"); 49 if (gf == NULL) { 50 perror("gateways"); 51 exit(1); 52 } 53 copylocal(gf, "localgateways"); 54 nf = fopen("networks", "w"); 55 if (nf == NULL) { 56 perror("networks"); 57 exit(1); 58 } 59 copylocal(nf, "localnetworks"); 60 exit(yyparse()); 61 } 62 63 struct name * 64 newname(str) 65 char *str; 66 { 67 char *p; 68 struct name *nm; 69 70 p = malloc(strlen(str) + 1); 71 strcpy(p, str); 72 nm = (struct name *)malloc(sizeof (struct name)); 73 nm->name_val = p; 74 nm->name_link = NONAME; 75 return (nm); 76 } 77 78 char * 79 lower(str) 80 char *str; 81 { 82 register char *cp = str; 83 84 while (*cp) { 85 if (isupper(*cp)) 86 *cp = tolower(*cp); 87 cp++; 88 } 89 return (str); 90 } 91 92 do_entry(keyword, addrlist, namelist, cputype, opsys, protos) 93 int keyword; 94 struct addr *addrlist; 95 struct name *namelist, *cputype, *opsys, *protos; 96 { 97 register struct addr *al, *al2; 98 register struct name *nl; 99 struct addr *inetal; 100 int count; 101 102 switch (keyword) { 103 104 case KW_NET: 105 nl = namelist; 106 if (nl == NONAME) { 107 fprintf(stderr, "htable: net"); 108 putnet(stderr, addrlist->addr_val); 109 fprintf(stderr, " missing names.\n"); 110 break; 111 } 112 fprintf(nf, "%-16.16s", lower(nl->name_val)); 113 al2 = addrlist; 114 while (al = al2) { 115 char *cp; 116 117 putnet(nf, al->addr_val); 118 cp = "\t%s"; 119 while (nl = nl->name_link) { 120 fprintf(nf, cp, lower(nl->name_val)); 121 cp = " %s"; 122 } 123 putc('\n', nf); 124 al2 = al->addr_link; 125 free((char *)al); 126 } 127 goto alreadyfree; 128 129 case KW_GATEWAY: 130 /* 131 * Kludge here: take only gateways directly connected to 132 * the Internet. Should really calculate closure on 133 * connectivity matrix to identify gateways to all networks 134 * described in data base, but that's real work. 135 */ 136 /* locate Internet address, if one */ 137 for (al = addrlist; al; al = al->addr_link) 138 if (inet_netof(al->addr_val) == INTERNET) 139 break; 140 if (al == NULL) 141 break; 142 inetal = al; 143 for (count = 0, al = al->addr_link; al; al = al->addr_link) { 144 register int net; 145 register struct netent *np; 146 147 if (al == inetal) 148 continue; 149 /* suppress duplicates -- not optimal */ 150 net = inet_netof(al->addr_val); 151 if (checkgateway(net)) 152 break; 153 count++; 154 fprintf(gf, "net "); 155 np = getnetbyaddr(net, AF_INET); 156 if (np) 157 fprintf(gf, "%s", np->n_name); 158 else 159 putnet(gf, net); 160 /* this is a kludge */ 161 fprintf(gf, " gateway %s metric 1 passive\n", 162 lower(namelist->name_val)); 163 savegateway(net); 164 } 165 if (count > 0) { 166 putaddr(hf, inetal->addr_val); 167 fprintf(hf, "%s\t# gateway\n", 168 lower(namelist->name_val)); 169 } 170 break; 171 172 case KW_HOST: 173 al2 = addrlist; 174 while (al = al2) { 175 if (inet_netof(al->addr_val) != LOCALNET) { 176 char *cp; 177 178 putaddr(hf, al->addr_val); 179 cp = "%s"; 180 for (nl = namelist; nl; nl = nl->name_link) { 181 fprintf(hf, cp, lower(nl->name_val)); 182 cp = " %s"; 183 } 184 putc('\n', hf); 185 } 186 al2 = al->addr_link; 187 free((char *)al); 188 } 189 goto alreadyfree; 190 191 default: 192 fprintf(stderr, "Unknown keyword: %d.\n", keyword); 193 } 194 al2 = addrlist; 195 while (al = al2) 196 al2 = al->addr_link, free((char *)al); 197 alreadyfree: 198 freenames(namelist); 199 freenames(protos); 200 } 201 202 copylocal(f, filename) 203 FILE *f; 204 char *filename; 205 { 206 register FILE *lhf; 207 register cc; 208 char buf[BUFSIZ]; 209 extern int errno; 210 211 lhf = fopen(filename, "r"); 212 if (lhf == NULL) { 213 if (errno != ENOENT) { 214 perror(filename); 215 exit(1); 216 } 217 fprintf(stderr, "Warning, no %s file.\n", filename); 218 return; 219 } 220 while (cc = fread(buf, 1, sizeof(buf), lhf)) 221 fwrite(buf, 1, cc, f); 222 fclose(lhf); 223 } 224 225 #define UC(b) (((int)(b))&0xff) 226 227 putnet(f, v) 228 FILE *f; 229 u_long v; 230 { 231 register char *a = (char *)&v; 232 233 if (UC(a[0]&0x80) == 0) 234 fprintf(f, "%d", UC(a[0])); 235 else if ((UC(a[0])&0x40) == 0) 236 fprintf(f, "%d.%d", UC(a[0]), UC(a[1])); 237 else 238 fprintf(f, "%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2])); 239 } 240 241 putaddr(f, v) 242 FILE *f; 243 u_long v; 244 { 245 register char *a = (char *)&v; 246 char buf[32]; 247 248 sprintf(buf,"%d.%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3])); 249 fprintf(f, "%-16.16s", buf); 250 } 251 252 freenames(list) 253 struct name *list; 254 { 255 register struct name *nl, *nl2; 256 257 nl2 = list; 258 while (nl = nl2) { 259 nl2 = nl->name_link; 260 free(nl->name_val); 261 free((char *)nl); 262 } 263 } 264 struct gateway { 265 struct gateway *g_link; 266 int g_net; 267 }; 268 269 struct gateway *gateways = 0; 270 271 checkgateway(net) 272 register int net; 273 { 274 register struct gateway *gp; 275 276 for (gp = gateways; gp; gp = gp->g_link) 277 if (gp->g_net == net) 278 return (1); 279 return (0); 280 } 281 282 savegateway(net) 283 int net; 284 { 285 register struct gateway *gp; 286 287 gp = (struct gateway *)malloc(sizeof (struct gateway)); 288 if (gp == 0) { 289 fprintf(stderr, "htable: out of memory\n"); 290 exit(1); 291 } 292 gp->g_link = gateways; 293 gp->g_net = net; 294 gateways = gp; 295 } 296 297