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