1 1.9 xtraeme /* $NetBSD: dumptab.c,v 1.9 2008/05/02 19:22:10 xtraeme Exp $ */ 2 1.5 lukem 3 1.5 lukem #include <sys/cdefs.h> 4 1.5 lukem #ifndef lint 5 1.9 xtraeme __RCSID("$NetBSD: dumptab.c,v 1.9 2008/05/02 19:22:10 xtraeme Exp $"); 6 1.5 lukem #endif 7 1.4 perry 8 1.1 gwr /* 9 1.1 gwr * dumptab.c - handles dumping the database 10 1.1 gwr */ 11 1.1 gwr 12 1.1 gwr #include <sys/types.h> 13 1.1 gwr #include <netinet/in.h> 14 1.1 gwr #include <arpa/inet.h> /* inet_ntoa */ 15 1.1 gwr 16 1.1 gwr #include <stdio.h> 17 1.1 gwr #include <stdlib.h> 18 1.8 tls #include <strings.h> 19 1.1 gwr #include <syslog.h> 20 1.1 gwr #include <time.h> 21 1.1 gwr 22 1.1 gwr #include "bootp.h" 23 1.1 gwr #include "hash.h" 24 1.1 gwr #include "hwaddr.h" 25 1.1 gwr #include "report.h" 26 1.1 gwr #include "patchlevel.h" 27 1.1 gwr #include "bootpd.h" 28 1.1 gwr 29 1.6 wiz static void dump_generic(FILE *, struct shared_bindata *); 30 1.6 wiz static void dump_host(FILE *, struct host *); 31 1.6 wiz static void list_ipaddresses(FILE *, struct in_addr_list *); 32 1.9 xtraeme void dumptab(const char *); 33 1.1 gwr 34 1.1 gwr #ifndef DEBUG 35 1.1 gwr void 36 1.9 xtraeme dumptab(const char *filename) 37 1.1 gwr { 38 1.1 gwr report(LOG_INFO, "No dumptab support!"); 39 1.1 gwr } 40 1.1 gwr 41 1.1 gwr #else /* DEBUG */ 42 1.1 gwr 43 1.1 gwr /* 44 1.1 gwr * Dump the internal memory database to bootpd_dump. 45 1.1 gwr */ 46 1.1 gwr 47 1.1 gwr void 48 1.9 xtraeme dumptab(const char *filename) 49 1.1 gwr { 50 1.1 gwr int n; 51 1.1 gwr struct host *hp; 52 1.1 gwr FILE *fp; 53 1.3 cgd time_t t; 54 1.1 gwr /* Print symbols in alphabetical order for reader's convenience. */ 55 1.1 gwr static char legend[] = "#\n# Legend:\t(see bootptab.5)\n\ 56 1.1 gwr #\tfirst field -- hostname (not indented)\n\ 57 1.1 gwr #\tbf -- bootfile\n\ 58 1.1 gwr #\tbs -- bootfile size in 512-octet blocks\n\ 59 1.1 gwr #\tcs -- cookie servers\n\ 60 1.1 gwr #\tdf -- dump file name\n\ 61 1.1 gwr #\tdn -- domain name\n\ 62 1.1 gwr #\tds -- domain name servers\n\ 63 1.1 gwr #\tef -- extension file\n\ 64 1.1 gwr #\tex -- exec file (YORK_EX_OPTION)\n\ 65 1.1 gwr #\tgw -- gateways\n\ 66 1.1 gwr #\tha -- hardware address\n\ 67 1.1 gwr #\thd -- home directory for bootfiles\n\ 68 1.1 gwr #\thn -- host name set for client\n\ 69 1.1 gwr #\tht -- hardware type\n\ 70 1.1 gwr #\tim -- impress servers\n\ 71 1.1 gwr #\tip -- host IP address\n\ 72 1.1 gwr #\tlg -- log servers\n\ 73 1.1 gwr #\tlp -- LPR servers\n\ 74 1.2 gwr #\tms -- message size\n\ 75 1.2 gwr #\tmw -- min wait (secs)\n\ 76 1.1 gwr #\tns -- IEN-116 name servers\n\ 77 1.1 gwr #\tnt -- NTP servers (RFC 1129)\n\ 78 1.1 gwr #\tra -- reply address override\n\ 79 1.1 gwr #\trl -- resource location protocol servers\n\ 80 1.1 gwr #\trp -- root path\n\ 81 1.1 gwr #\tsa -- boot server address\n\ 82 1.1 gwr #\tsm -- subnet mask\n\ 83 1.1 gwr #\tsw -- swap server\n\ 84 1.1 gwr #\ttc -- template host (points to similar host entry)\n\ 85 1.1 gwr #\ttd -- TFTP directory\n\ 86 1.1 gwr #\tto -- time offset (seconds)\n\ 87 1.1 gwr #\tts -- time servers\n\ 88 1.1 gwr #\tvm -- vendor magic number\n\ 89 1.1 gwr #\tyd -- YP (NIS) domain\n\ 90 1.1 gwr #\tys -- YP (NIS) servers\n\ 91 1.1 gwr #\tTn -- generic option tag n\n\ 92 1.1 gwr \n"; 93 1.1 gwr 94 1.1 gwr /* 95 1.1 gwr * Open bootpd.dump file. 96 1.1 gwr */ 97 1.1 gwr if ((fp = fopen(filename, "w")) == NULL) { 98 1.1 gwr report(LOG_ERR, "error opening \"%s\": %s", 99 1.1 gwr filename, get_errmsg()); 100 1.1 gwr exit(1); 101 1.1 gwr } 102 1.1 gwr t = time(NULL); 103 1.1 gwr fprintf(fp, "\n# %s %s.%d\n", progname, VERSION, PATCHLEVEL); 104 1.1 gwr fprintf(fp, "# %s: dump of bootp server database.\n", filename); 105 1.1 gwr fprintf(fp, "# Dump taken %s", ctime(&t)); 106 1.1 gwr fwrite(legend, 1, sizeof(legend) - 1, fp); 107 1.1 gwr 108 1.1 gwr n = 0; 109 1.1 gwr for (hp = (struct host *) hash_FirstEntry(nmhashtable); hp != NULL; 110 1.1 gwr hp = (struct host *) hash_NextEntry(nmhashtable)) { 111 1.1 gwr dump_host(fp, hp); 112 1.1 gwr fprintf(fp, "\n"); 113 1.1 gwr n++; 114 1.1 gwr } 115 1.1 gwr fclose(fp); 116 1.1 gwr 117 1.1 gwr report(LOG_INFO, "dumped %d entries to \"%s\".", n, filename); 118 1.1 gwr } 119 1.1 gwr 120 1.1 gwr 122 1.1 gwr 123 1.1 gwr /* 124 1.1 gwr * Dump all the available information on the host pointed to by "hp". 125 1.1 gwr * The output is sent to the file pointed to by "fp". 126 1.1 gwr */ 127 1.1 gwr 128 1.6 wiz static void 129 1.1 gwr dump_host(FILE *fp, struct host *hp) 130 1.1 gwr { 131 1.1 gwr /* Print symbols in alphabetical order for reader's convenience. */ 132 1.1 gwr if (hp) { 133 1.1 gwr fprintf(fp, "%s:", (hp->hostname ? 134 1.1 gwr hp->hostname->string : "?")); 135 1.1 gwr if (hp->flags.bootfile) { 136 1.1 gwr fprintf(fp, "\\\n\t:bf=%s:", hp->bootfile->string); 137 1.1 gwr } 138 1.1 gwr if (hp->flags.bootsize) { 139 1.1 gwr fprintf(fp, "\\\n\t:bs="); 140 1.1 gwr if (hp->flags.bootsize_auto) { 141 1.1 gwr fprintf(fp, "auto:"); 142 1.1 gwr } else { 143 1.1 gwr fprintf(fp, "%d:", hp->bootsize); 144 1.1 gwr } 145 1.1 gwr } 146 1.1 gwr if (hp->flags.cookie_server) { 147 1.1 gwr fprintf(fp, "\\\n\t:cs="); 148 1.1 gwr list_ipaddresses(fp, hp->cookie_server); 149 1.1 gwr fprintf(fp, ":"); 150 1.1 gwr } 151 1.1 gwr if (hp->flags.dump_file) { 152 1.1 gwr fprintf(fp, "\\\n\t:df=%s:", hp->dump_file->string); 153 1.1 gwr } 154 1.1 gwr if (hp->flags.domain_name) { 155 1.1 gwr fprintf(fp, "\\\n\t:dn=%s:", hp->domain_name->string); 156 1.1 gwr } 157 1.1 gwr if (hp->flags.domain_server) { 158 1.1 gwr fprintf(fp, "\\\n\t:ds="); 159 1.1 gwr list_ipaddresses(fp, hp->domain_server); 160 1.1 gwr fprintf(fp, ":"); 161 1.1 gwr } 162 1.1 gwr if (hp->flags.exten_file) { 163 1.1 gwr fprintf(fp, "\\\n\t:ef=%s:", hp->exten_file->string); 164 1.1 gwr } 165 1.1 gwr if (hp->flags.exec_file) { 166 1.1 gwr fprintf(fp, "\\\n\t:ex=%s:", hp->exec_file->string); 167 1.1 gwr } 168 1.1 gwr if (hp->flags.gateway) { 169 1.1 gwr fprintf(fp, "\\\n\t:gw="); 170 1.1 gwr list_ipaddresses(fp, hp->gateway); 171 1.1 gwr fprintf(fp, ":"); 172 1.1 gwr } 173 1.1 gwr /* FdC: swap_server (see below) */ 174 1.1 gwr if (hp->flags.homedir) { 175 1.1 gwr fprintf(fp, "\\\n\t:hd=%s:", hp->homedir->string); 176 1.1 gwr } 177 1.1 gwr /* FdC: dump_file (see above) */ 178 1.1 gwr /* FdC: domain_name (see above) */ 179 1.1 gwr /* FdC: root_path (see below) */ 180 1.1 gwr if (hp->flags.name_switch && hp->flags.send_name) { 181 1.1 gwr fprintf(fp, "\\\n\t:hn:"); 182 1.1 gwr } 183 1.1 gwr if (hp->flags.htype) { 184 1.1 gwr int hlen = haddrlength(hp->htype); 185 1.1 gwr fprintf(fp, "\\\n\t:ht=%u:", (unsigned) hp->htype); 186 1.1 gwr if (hp->flags.haddr) { 187 1.1 gwr fprintf(fp, "ha=\"%s\":", 188 1.1 gwr haddrtoa(hp->haddr, hlen)); 189 1.1 gwr } 190 1.1 gwr } 191 1.1 gwr if (hp->flags.impress_server) { 192 1.1 gwr fprintf(fp, "\\\n\t:im="); 193 1.1 gwr list_ipaddresses(fp, hp->impress_server); 194 1.1 gwr fprintf(fp, ":"); 195 1.1 gwr } 196 1.1 gwr /* NetBSD: swap_server (see below) */ 197 1.1 gwr if (hp->flags.iaddr) { 198 1.1 gwr fprintf(fp, "\\\n\t:ip=%s:", inet_ntoa(hp->iaddr)); 199 1.1 gwr } 200 1.1 gwr if (hp->flags.log_server) { 201 1.1 gwr fprintf(fp, "\\\n\t:lg="); 202 1.1 gwr list_ipaddresses(fp, hp->log_server); 203 1.1 gwr fprintf(fp, ":"); 204 1.1 gwr } 205 1.1 gwr if (hp->flags.lpr_server) { 206 1.1 gwr fprintf(fp, "\\\n\t:lp="); 207 1.1 gwr list_ipaddresses(fp, hp->lpr_server); 208 1.2 gwr fprintf(fp, ":"); 209 1.2 gwr } 210 1.2 gwr if (hp->flags.msg_size) { 211 1.2 gwr fprintf(fp, "\\\n\t:ms=%d:", hp->msg_size); 212 1.2 gwr } 213 1.2 gwr if (hp->flags.min_wait) { 214 1.1 gwr fprintf(fp, "\\\n\t:mw=%d:", hp->min_wait); 215 1.1 gwr } 216 1.1 gwr if (hp->flags.name_server) { 217 1.1 gwr fprintf(fp, "\\\n\t:ns="); 218 1.1 gwr list_ipaddresses(fp, hp->name_server); 219 1.1 gwr fprintf(fp, ":"); 220 1.1 gwr } 221 1.1 gwr if (hp->flags.ntp_server) { 222 1.1 gwr fprintf(fp, "\\\n\t:nt="); 223 1.1 gwr list_ipaddresses(fp, hp->ntp_server); 224 1.1 gwr fprintf(fp, ":"); 225 1.1 gwr } 226 1.1 gwr if (hp->flags.reply_addr) { 227 1.1 gwr fprintf(fp, "\\\n\t:ra=%s:", inet_ntoa(hp->reply_addr)); 228 1.1 gwr } 229 1.1 gwr if (hp->flags.rlp_server) { 230 1.1 gwr fprintf(fp, "\\\n\t:rl="); 231 1.1 gwr list_ipaddresses(fp, hp->rlp_server); 232 1.1 gwr fprintf(fp, ":"); 233 1.1 gwr } 234 1.1 gwr if (hp->flags.root_path) { 235 1.1 gwr fprintf(fp, "\\\n\t:rp=%s:", hp->root_path->string); 236 1.1 gwr } 237 1.1 gwr if (hp->flags.bootserver) { 238 1.1 gwr fprintf(fp, "\\\n\t:sa=%s:", inet_ntoa(hp->bootserver)); 239 1.1 gwr } 240 1.1 gwr if (hp->flags.subnet_mask) { 241 1.1 gwr fprintf(fp, "\\\n\t:sm=%s:", inet_ntoa(hp->subnet_mask)); 242 1.1 gwr } 243 1.1 gwr if (hp->flags.swap_server) { 244 1.1 gwr fprintf(fp, "\\\n\t:sw=%s:", inet_ntoa(hp->subnet_mask)); 245 1.1 gwr } 246 1.1 gwr if (hp->flags.tftpdir) { 247 1.1 gwr fprintf(fp, "\\\n\t:td=%s:", hp->tftpdir->string); 248 1.1 gwr } 249 1.1 gwr /* NetBSD: rootpath (see above) */ 250 1.1 gwr /* NetBSD: domainname (see above) */ 251 1.1 gwr /* NetBSD: dumpfile (see above) */ 252 1.5 lukem if (hp->flags.time_offset) { 253 1.1 gwr fprintf(fp, "\\\n\t:to=%ld:", (long)hp->time_offset); 254 1.1 gwr } 255 1.1 gwr if (hp->flags.time_server) { 256 1.1 gwr fprintf(fp, "\\\n\t:ts="); 257 1.1 gwr list_ipaddresses(fp, hp->time_server); 258 1.1 gwr fprintf(fp, ":"); 259 1.1 gwr } 260 1.1 gwr if (hp->flags.vm_cookie) { 261 1.1 gwr fprintf(fp, "\\\n\t:vm="); 262 1.1 gwr if (!bcmp(hp->vm_cookie, vm_rfc1048, 4)) { 263 1.1 gwr fprintf(fp, "rfc1048:"); 264 1.1 gwr } else if (!bcmp(hp->vm_cookie, vm_cmu, 4)) { 265 1.1 gwr fprintf(fp, "cmu:"); 266 1.1 gwr } else { 267 1.1 gwr fprintf(fp, "%d.%d.%d.%d:", 268 1.1 gwr (int) ((hp->vm_cookie)[0]), 269 1.1 gwr (int) ((hp->vm_cookie)[1]), 270 1.1 gwr (int) ((hp->vm_cookie)[2]), 271 1.1 gwr (int) ((hp->vm_cookie)[3])); 272 1.1 gwr } 273 1.1 gwr } 274 1.1 gwr if (hp->flags.nis_domain) { 275 1.1 gwr fprintf(fp, "\\\n\t:yd=%s:", 276 1.1 gwr hp->nis_domain->string); 277 1.1 gwr } 278 1.1 gwr if (hp->flags.nis_server) { 279 1.1 gwr fprintf(fp, "\\\n\t:ys="); 280 1.1 gwr list_ipaddresses(fp, hp->nis_server); 281 1.1 gwr fprintf(fp, ":"); 282 1.1 gwr } 283 1.1 gwr /* 284 1.1 gwr * XXX - Add new tags here (or above, 285 1.1 gwr * so they print in alphabetical order). 286 1.1 gwr */ 287 1.1 gwr 288 1.1 gwr if (hp->flags.generic) { 289 1.1 gwr dump_generic(fp, hp->generic); 290 1.1 gwr } 291 1.1 gwr } 292 1.1 gwr } 293 1.1 gwr 294 1.1 gwr 296 1.1 gwr static void 297 1.1 gwr dump_generic(FILE *fp, struct shared_bindata *generic) 298 1.1 gwr { 299 1.1 gwr u_char *bp = generic->data; 300 1.1 gwr u_char *ep = bp + generic->length; 301 1.1 gwr u_char tag; 302 1.1 gwr int len; 303 1.1 gwr 304 1.1 gwr while (bp < ep) { 305 1.1 gwr tag = *bp++; 306 1.1 gwr if (tag == TAG_PAD) 307 1.1 gwr continue; 308 1.1 gwr if (tag == TAG_END) 309 1.1 gwr return; 310 1.1 gwr len = *bp++; 311 1.1 gwr if (bp + len > ep) { 312 1.1 gwr fprintf(fp, " #junk in generic! :"); 313 1.1 gwr return; 314 1.1 gwr } 315 1.1 gwr fprintf(fp, "\\\n\t:T%d=", tag); 316 1.1 gwr while (len) { 317 1.1 gwr fprintf(fp, "%02X", *bp); 318 1.1 gwr bp++; 319 1.1 gwr len--; 320 1.1 gwr if (len) 321 1.1 gwr fprintf(fp, "."); 322 1.1 gwr } 323 1.1 gwr fprintf(fp, ":"); 324 1.1 gwr } 325 1.1 gwr } 326 1.1 gwr 327 1.1 gwr 329 1.1 gwr 330 1.1 gwr /* 331 1.1 gwr * Dump an entire struct in_addr_list of IP addresses to the indicated file. 332 1.7 wiz * 333 1.1 gwr * The addresses are printed in standard ASCII "dot" notation and separated 334 1.1 gwr * from one another by a single space. A single leading space is also 335 1.1 gwr * printed before the first address. 336 1.1 gwr * 337 1.1 gwr * Null lists produce no output (and no error). 338 1.6 wiz */ 339 1.1 gwr 340 1.1 gwr static void 341 1.1 gwr list_ipaddresses(FILE *fp, struct in_addr_list *ipptr) 342 1.1 gwr { 343 1.1 gwr unsigned count; 344 1.1 gwr struct in_addr *addrptr; 345 1.1 gwr 346 1.1 gwr if (ipptr) { 347 1.1 gwr count = ipptr->addrcount; 348 1.1 gwr addrptr = ipptr->addr; 349 1.1 gwr while (count > 0) { 350 1.1 gwr fprintf(fp, "%s", inet_ntoa(*addrptr++)); 351 1.1 gwr count--; 352 1.1 gwr if (count) 353 1.1 gwr fprintf(fp, ", "); 354 1.1 gwr } 355 1.1 gwr } 356 1.1 gwr } 357 1.1 gwr 358 1.1 gwr #endif /* DEBUG */ 359 1.1 gwr 360 1.1 gwr /* 361 1.1 gwr * Local Variables: 362 1.1 gwr * tab-width: 4 363 1.1 gwr * c-indent-level: 4 364 1.1 gwr * c-argdecl-indent: 4 365 1.1 gwr * c-continued-statement-offset: 4 366 1.1 gwr * c-continued-brace-offset: -4 367 1.1 gwr * c-label-offset: -4 368 * c-brace-offset: 0 369 * End: 370 */ 371