dumptab.c revision 50476
13229Spst/* 23229Spst * dumptab.c - handles dumping the database 318471Swosch * 450476Speter * $FreeBSD: head/libexec/bootpd/dumptab.c 50476 1999-08-28 00:22:10Z peter $ 53229Spst */ 63229Spst 73229Spst#include <sys/types.h> 83229Spst#include <netinet/in.h> 93229Spst#include <arpa/inet.h> /* inet_ntoa */ 103229Spst 113229Spst#include <stdio.h> 123229Spst#include <stdlib.h> 133229Spst#include <syslog.h> 143229Spst#include <time.h> 153229Spst 163229Spst#ifndef USE_BFUNCS 173229Spst#include <memory.h> 183229Spst/* Yes, memcpy is OK here (no overlapped copies). */ 193229Spst#define bcopy(a,b,c) memcpy(b,a,c) 203229Spst#define bzero(p,l) memset(p,0,l) 213229Spst#define bcmp(a,b,c) memcmp(a,b,c) 223229Spst#endif 233229Spst 243229Spst#include "bootp.h" 253229Spst#include "hash.h" 263229Spst#include "hwaddr.h" 273229Spst#include "report.h" 283229Spst#include "patchlevel.h" 293229Spst#include "bootpd.h" 303229Spst 313229Spst#ifdef __STDC__ 323229Spst#define P(args) args 333229Spst#else 343229Spst#define P(args) () 353229Spst#endif 363229Spst 373229Spststatic void dump_generic P((FILE *, struct shared_bindata *)); 383229Spststatic void dump_host P((FILE *, struct host *)); 393229Spststatic void list_ipaddresses P((FILE *, struct in_addr_list *)); 403229Spst 413229Spst#undef P 423229Spst 433229Spst#ifndef DEBUG 443229Spstvoid 453229Spstdumptab(filename) 463229Spst char *filename; 473229Spst{ 483229Spst report(LOG_INFO, "No dumptab support!"); 493229Spst} 503229Spst 513229Spst#else /* DEBUG */ 523229Spst 533229Spst/* 543229Spst * Dump the internal memory database to bootpd_dump. 553229Spst */ 563229Spst 573229Spstvoid 583229Spstdumptab(filename) 593229Spst char *filename; 603229Spst{ 613229Spst int n; 623229Spst struct host *hp; 633229Spst FILE *fp; 6437261Sbde time_t t; 653229Spst /* Print symbols in alphabetical order for reader's convenience. */ 663229Spst static char legend[] = "#\n# Legend:\t(see bootptab.5)\n\ 673229Spst#\tfirst field -- hostname (not indented)\n\ 683229Spst#\tbf -- bootfile\n\ 693229Spst#\tbs -- bootfile size in 512-octet blocks\n\ 703229Spst#\tcs -- cookie servers\n\ 713229Spst#\tdf -- dump file name\n\ 723229Spst#\tdn -- domain name\n\ 733229Spst#\tds -- domain name servers\n\ 743229Spst#\tef -- extension file\n\ 753229Spst#\tex -- exec file (YORK_EX_OPTION)\n\ 763229Spst#\tgw -- gateways\n\ 773229Spst#\tha -- hardware address\n\ 783229Spst#\thd -- home directory for bootfiles\n\ 793229Spst#\thn -- host name set for client\n\ 803229Spst#\tht -- hardware type\n\ 813229Spst#\tim -- impress servers\n\ 823229Spst#\tip -- host IP address\n\ 833229Spst#\tlg -- log servers\n\ 843229Spst#\tlp -- LPR servers\n\ 853229Spst#\tms -- message size\n\ 863229Spst#\tmw -- min wait (secs)\n\ 873229Spst#\tns -- IEN-116 name servers\n\ 883229Spst#\tnt -- NTP servers (RFC 1129)\n\ 893229Spst#\tra -- reply address override\n\ 903229Spst#\trl -- resource location protocol servers\n\ 913229Spst#\trp -- root path\n\ 923229Spst#\tsa -- boot server address\n\ 933229Spst#\tsm -- subnet mask\n\ 943229Spst#\tsw -- swap server\n\ 953229Spst#\ttc -- template host (points to similar host entry)\n\ 963229Spst#\ttd -- TFTP directory\n\ 973229Spst#\tto -- time offset (seconds)\n\ 983229Spst#\tts -- time servers\n\ 993229Spst#\tvm -- vendor magic number\n\ 1003229Spst#\tyd -- YP (NIS) domain\n\ 1013229Spst#\tys -- YP (NIS) servers\n\ 1023229Spst#\tTn -- generic option tag n\n\ 1033229Spst\n"; 1043229Spst 1053229Spst /* 1063229Spst * Open bootpd.dump file. 1073229Spst */ 1083229Spst if ((fp = fopen(filename, "w")) == NULL) { 1093229Spst report(LOG_ERR, "error opening \"%s\": %s", 1103229Spst filename, get_errmsg()); 1113229Spst exit(1); 1123229Spst } 1133229Spst t = time(NULL); 1143229Spst fprintf(fp, "\n# %s %s.%d\n", progname, VERSION, PATCHLEVEL); 1153229Spst fprintf(fp, "# %s: dump of bootp server database.\n", filename); 1163229Spst fprintf(fp, "# Dump taken %s", ctime(&t)); 1173229Spst fwrite(legend, 1, sizeof(legend) - 1, fp); 1183229Spst 1193229Spst n = 0; 1203229Spst for (hp = (struct host *) hash_FirstEntry(nmhashtable); hp != NULL; 1213229Spst hp = (struct host *) hash_NextEntry(nmhashtable)) { 1223229Spst dump_host(fp, hp); 1233229Spst fprintf(fp, "\n"); 1243229Spst n++; 1253229Spst } 1263229Spst fclose(fp); 1273229Spst 1283229Spst report(LOG_INFO, "dumped %d entries to \"%s\".", n, filename); 1293229Spst} 1303229Spst 1313229Spst 1323229Spst 1333229Spst/* 1343229Spst * Dump all the available information on the host pointed to by "hp". 1353229Spst * The output is sent to the file pointed to by "fp". 1363229Spst */ 1373229Spst 1383229Spststatic void 1393229Spstdump_host(fp, hp) 1403229Spst FILE *fp; 1413229Spst struct host *hp; 1423229Spst{ 1433229Spst /* Print symbols in alphabetical order for reader's convenience. */ 1443229Spst if (hp) { 1453229Spst fprintf(fp, "%s:", (hp->hostname ? 1463229Spst hp->hostname->string : "?")); 1473229Spst if (hp->flags.bootfile) { 1483229Spst fprintf(fp, "\\\n\t:bf=%s:", hp->bootfile->string); 1493229Spst } 1503229Spst if (hp->flags.bootsize) { 1513229Spst fprintf(fp, "\\\n\t:bs="); 1523229Spst if (hp->flags.bootsize_auto) { 1533229Spst fprintf(fp, "auto:"); 1543229Spst } else { 15537261Sbde fprintf(fp, "%lu:", (u_long)hp->bootsize); 1563229Spst } 1573229Spst } 1583229Spst if (hp->flags.cookie_server) { 1593229Spst fprintf(fp, "\\\n\t:cs="); 1603229Spst list_ipaddresses(fp, hp->cookie_server); 1613229Spst fprintf(fp, ":"); 1623229Spst } 1633229Spst if (hp->flags.dump_file) { 1643229Spst fprintf(fp, "\\\n\t:df=%s:", hp->dump_file->string); 1653229Spst } 1663229Spst if (hp->flags.domain_name) { 1673229Spst fprintf(fp, "\\\n\t:dn=%s:", hp->domain_name->string); 1683229Spst } 1693229Spst if (hp->flags.domain_server) { 1703229Spst fprintf(fp, "\\\n\t:ds="); 1713229Spst list_ipaddresses(fp, hp->domain_server); 1723229Spst fprintf(fp, ":"); 1733229Spst } 1743229Spst if (hp->flags.exten_file) { 1753229Spst fprintf(fp, "\\\n\t:ef=%s:", hp->exten_file->string); 1763229Spst } 1773229Spst if (hp->flags.exec_file) { 1783229Spst fprintf(fp, "\\\n\t:ex=%s:", hp->exec_file->string); 1793229Spst } 1803229Spst if (hp->flags.gateway) { 1813229Spst fprintf(fp, "\\\n\t:gw="); 1823229Spst list_ipaddresses(fp, hp->gateway); 1833229Spst fprintf(fp, ":"); 1843229Spst } 1853229Spst /* FdC: swap_server (see below) */ 1863229Spst if (hp->flags.homedir) { 1873229Spst fprintf(fp, "\\\n\t:hd=%s:", hp->homedir->string); 1883229Spst } 1893229Spst /* FdC: dump_file (see above) */ 1903229Spst /* FdC: domain_name (see above) */ 1913229Spst /* FdC: root_path (see below) */ 1923229Spst if (hp->flags.name_switch && hp->flags.send_name) { 1933229Spst fprintf(fp, "\\\n\t:hn:"); 1943229Spst } 1953229Spst if (hp->flags.htype) { 1963229Spst int hlen = haddrlength(hp->htype); 1973229Spst fprintf(fp, "\\\n\t:ht=%u:", (unsigned) hp->htype); 1983229Spst if (hp->flags.haddr) { 1993229Spst fprintf(fp, "ha=\"%s\":", 2003229Spst haddrtoa(hp->haddr, hlen)); 2013229Spst } 2023229Spst } 2033229Spst if (hp->flags.impress_server) { 2043229Spst fprintf(fp, "\\\n\t:im="); 2053229Spst list_ipaddresses(fp, hp->impress_server); 2063229Spst fprintf(fp, ":"); 2073229Spst } 2083229Spst /* NetBSD: swap_server (see below) */ 2093229Spst if (hp->flags.iaddr) { 2103229Spst fprintf(fp, "\\\n\t:ip=%s:", inet_ntoa(hp->iaddr)); 2113229Spst } 2123229Spst if (hp->flags.log_server) { 2133229Spst fprintf(fp, "\\\n\t:lg="); 2143229Spst list_ipaddresses(fp, hp->log_server); 2153229Spst fprintf(fp, ":"); 2163229Spst } 2173229Spst if (hp->flags.lpr_server) { 2183229Spst fprintf(fp, "\\\n\t:lp="); 2193229Spst list_ipaddresses(fp, hp->lpr_server); 2203229Spst fprintf(fp, ":"); 2213229Spst } 2223229Spst if (hp->flags.msg_size) { 22337261Sbde fprintf(fp, "\\\n\t:ms=%lu:", (u_long)hp->msg_size); 2243229Spst } 2253229Spst if (hp->flags.min_wait) { 22637261Sbde fprintf(fp, "\\\n\t:mw=%lu:", (u_long)hp->min_wait); 2273229Spst } 2283229Spst if (hp->flags.name_server) { 2293229Spst fprintf(fp, "\\\n\t:ns="); 2303229Spst list_ipaddresses(fp, hp->name_server); 2313229Spst fprintf(fp, ":"); 2323229Spst } 2333229Spst if (hp->flags.ntp_server) { 2343229Spst fprintf(fp, "\\\n\t:nt="); 2353229Spst list_ipaddresses(fp, hp->ntp_server); 2363229Spst fprintf(fp, ":"); 2373229Spst } 2383229Spst if (hp->flags.reply_addr) { 2393229Spst fprintf(fp, "\\\n\t:ra=%s:", inet_ntoa(hp->reply_addr)); 2403229Spst } 2413229Spst if (hp->flags.rlp_server) { 2423229Spst fprintf(fp, "\\\n\t:rl="); 2433229Spst list_ipaddresses(fp, hp->rlp_server); 2443229Spst fprintf(fp, ":"); 2453229Spst } 2463229Spst if (hp->flags.root_path) { 2473229Spst fprintf(fp, "\\\n\t:rp=%s:", hp->root_path->string); 2483229Spst } 2493229Spst if (hp->flags.bootserver) { 2503229Spst fprintf(fp, "\\\n\t:sa=%s:", inet_ntoa(hp->bootserver)); 2513229Spst } 2523229Spst if (hp->flags.subnet_mask) { 2533229Spst fprintf(fp, "\\\n\t:sm=%s:", inet_ntoa(hp->subnet_mask)); 2543229Spst } 2553229Spst if (hp->flags.swap_server) { 2563229Spst fprintf(fp, "\\\n\t:sw=%s:", inet_ntoa(hp->subnet_mask)); 2573229Spst } 2583229Spst if (hp->flags.tftpdir) { 2593229Spst fprintf(fp, "\\\n\t:td=%s:", hp->tftpdir->string); 2603229Spst } 2613229Spst /* NetBSD: rootpath (see above) */ 2623229Spst /* NetBSD: domainname (see above) */ 2633229Spst /* NetBSD: dumpfile (see above) */ 2643229Spst if (hp->flags.time_offset) { 2653229Spst fprintf(fp, "\\\n\t:to=%ld:", hp->time_offset); 2663229Spst } 2673229Spst if (hp->flags.time_server) { 2683229Spst fprintf(fp, "\\\n\t:ts="); 2693229Spst list_ipaddresses(fp, hp->time_server); 2703229Spst fprintf(fp, ":"); 2713229Spst } 2723229Spst if (hp->flags.vm_cookie) { 2733229Spst fprintf(fp, "\\\n\t:vm="); 2743229Spst if (!bcmp(hp->vm_cookie, vm_rfc1048, 4)) { 2753229Spst fprintf(fp, "rfc1048:"); 2763229Spst } else if (!bcmp(hp->vm_cookie, vm_cmu, 4)) { 2773229Spst fprintf(fp, "cmu:"); 2783229Spst } else { 2793229Spst fprintf(fp, "%d.%d.%d.%d:", 2803229Spst (int) ((hp->vm_cookie)[0]), 2813229Spst (int) ((hp->vm_cookie)[1]), 2823229Spst (int) ((hp->vm_cookie)[2]), 2833229Spst (int) ((hp->vm_cookie)[3])); 2843229Spst } 2853229Spst } 2863229Spst if (hp->flags.nis_domain) { 2873229Spst fprintf(fp, "\\\n\t:yd=%s:", 2883229Spst hp->nis_domain->string); 2893229Spst } 2903229Spst if (hp->flags.nis_server) { 2913229Spst fprintf(fp, "\\\n\t:ys="); 2923229Spst list_ipaddresses(fp, hp->nis_server); 2933229Spst fprintf(fp, ":"); 2943229Spst } 2953229Spst /* 2963229Spst * XXX - Add new tags here (or above, 2973229Spst * so they print in alphabetical order). 2983229Spst */ 2993229Spst 3003229Spst if (hp->flags.generic) { 3013229Spst dump_generic(fp, hp->generic); 3023229Spst } 3033229Spst } 3043229Spst} 3053229Spst 3063229Spst 3073229Spststatic void 3083229Spstdump_generic(fp, generic) 3093229Spst FILE *fp; 3103229Spst struct shared_bindata *generic; 3113229Spst{ 3123229Spst u_char *bp = generic->data; 3133229Spst u_char *ep = bp + generic->length; 3143229Spst u_char tag; 3153229Spst int len; 3163229Spst 3173229Spst while (bp < ep) { 3183229Spst tag = *bp++; 3193229Spst if (tag == TAG_PAD) 3203229Spst continue; 3213229Spst if (tag == TAG_END) 3223229Spst return; 3233229Spst len = *bp++; 3243229Spst if (bp + len > ep) { 3253229Spst fprintf(fp, " #junk in generic! :"); 3263229Spst return; 3273229Spst } 3283229Spst fprintf(fp, "\\\n\t:T%d=", tag); 3293229Spst while (len) { 3303229Spst fprintf(fp, "%02X", *bp); 3313229Spst bp++; 3323229Spst len--; 3333229Spst if (len) 3343229Spst fprintf(fp, "."); 3353229Spst } 3363229Spst fprintf(fp, ":"); 3373229Spst } 3383229Spst} 3393229Spst 3403229Spst 3413229Spst 3423229Spst/* 3433229Spst * Dump an entire struct in_addr_list of IP addresses to the indicated file. 3443229Spst * 3453229Spst * The addresses are printed in standard ASCII "dot" notation and separated 3463229Spst * from one another by a single space. A single leading space is also 3473229Spst * printed before the first adddress. 3483229Spst * 3493229Spst * Null lists produce no output (and no error). 3503229Spst */ 3513229Spst 3523229Spststatic void 3533229Spstlist_ipaddresses(fp, ipptr) 3543229Spst FILE *fp; 3553229Spst struct in_addr_list *ipptr; 3563229Spst{ 3573229Spst unsigned count; 3583229Spst struct in_addr *addrptr; 3593229Spst 3603229Spst if (ipptr) { 3613229Spst count = ipptr->addrcount; 3623229Spst addrptr = ipptr->addr; 3633229Spst while (count > 0) { 3643229Spst fprintf(fp, "%s", inet_ntoa(*addrptr++)); 3653229Spst count--; 3663229Spst if (count) 3673229Spst fprintf(fp, ", "); 3683229Spst } 3693229Spst } 3703229Spst} 3713229Spst 3723229Spst#endif /* DEBUG */ 3733229Spst 3743229Spst/* 3753229Spst * Local Variables: 3763229Spst * tab-width: 4 3773229Spst * c-indent-level: 4 3783229Spst * c-argdecl-indent: 4 3793229Spst * c-continued-statement-offset: 4 3803229Spst * c-continued-brace-offset: -4 3813229Spst * c-label-offset: -4 3823229Spst * c-brace-offset: 0 3833229Spst * End: 3843229Spst */ 385