144099b7bSPaul Traina /* 244099b7bSPaul Traina * dumptab.c - handles dumping the database 344099b7bSPaul Traina */ 444099b7bSPaul Traina 544099b7bSPaul Traina #include <sys/types.h> 644099b7bSPaul Traina #include <netinet/in.h> 744099b7bSPaul Traina #include <arpa/inet.h> /* inet_ntoa */ 844099b7bSPaul Traina 944099b7bSPaul Traina #include <stdio.h> 1044099b7bSPaul Traina #include <stdlib.h> 1144099b7bSPaul Traina #include <syslog.h> 1244099b7bSPaul Traina #include <time.h> 1344099b7bSPaul Traina 1444099b7bSPaul Traina #ifndef USE_BFUNCS 1544099b7bSPaul Traina #include <memory.h> 1644099b7bSPaul Traina /* Yes, memcpy is OK here (no overlapped copies). */ 1744099b7bSPaul Traina #define bcopy(a,b,c) memcpy(b,a,c) 1844099b7bSPaul Traina #define bzero(p,l) memset(p,0,l) 1944099b7bSPaul Traina #define bcmp(a,b,c) memcmp(a,b,c) 2044099b7bSPaul Traina #endif 2144099b7bSPaul Traina 2244099b7bSPaul Traina #include "bootp.h" 2344099b7bSPaul Traina #include "hash.h" 2444099b7bSPaul Traina #include "hwaddr.h" 2544099b7bSPaul Traina #include "report.h" 2644099b7bSPaul Traina #include "patchlevel.h" 2744099b7bSPaul Traina #include "bootpd.h" 2844099b7bSPaul Traina 2944099b7bSPaul Traina #ifdef __STDC__ 3044099b7bSPaul Traina #define P(args) args 3144099b7bSPaul Traina #else 3244099b7bSPaul Traina #define P(args) () 3344099b7bSPaul Traina #endif 3444099b7bSPaul Traina 3544099b7bSPaul Traina static void dump_generic P((FILE *, struct shared_bindata *)); 3644099b7bSPaul Traina static void dump_host P((FILE *, struct host *)); 3744099b7bSPaul Traina static void list_ipaddresses P((FILE *, struct in_addr_list *)); 3844099b7bSPaul Traina 3944099b7bSPaul Traina #undef P 4044099b7bSPaul Traina 4144099b7bSPaul Traina #ifndef DEBUG 4244099b7bSPaul Traina void 4344099b7bSPaul Traina dumptab(filename) 4444099b7bSPaul Traina char *filename; 4544099b7bSPaul Traina { 4644099b7bSPaul Traina report(LOG_INFO, "No dumptab support!"); 4744099b7bSPaul Traina } 4844099b7bSPaul Traina 4944099b7bSPaul Traina #else /* DEBUG */ 5044099b7bSPaul Traina 5144099b7bSPaul Traina /* 5244099b7bSPaul Traina * Dump the internal memory database to bootpd_dump. 5344099b7bSPaul Traina */ 5444099b7bSPaul Traina 5544099b7bSPaul Traina void 5644099b7bSPaul Traina dumptab(filename) 5744099b7bSPaul Traina char *filename; 5844099b7bSPaul Traina { 5944099b7bSPaul Traina int n; 6044099b7bSPaul Traina struct host *hp; 6144099b7bSPaul Traina FILE *fp; 6244099b7bSPaul Traina long t; 6344099b7bSPaul Traina /* Print symbols in alphabetical order for reader's convenience. */ 6444099b7bSPaul Traina static char legend[] = "#\n# Legend:\t(see bootptab.5)\n\ 6544099b7bSPaul Traina #\tfirst field -- hostname (not indented)\n\ 6644099b7bSPaul Traina #\tbf -- bootfile\n\ 6744099b7bSPaul Traina #\tbs -- bootfile size in 512-octet blocks\n\ 6844099b7bSPaul Traina #\tcs -- cookie servers\n\ 6944099b7bSPaul Traina #\tdf -- dump file name\n\ 7044099b7bSPaul Traina #\tdn -- domain name\n\ 7144099b7bSPaul Traina #\tds -- domain name servers\n\ 7244099b7bSPaul Traina #\tef -- extension file\n\ 7344099b7bSPaul Traina #\tex -- exec file (YORK_EX_OPTION)\n\ 7444099b7bSPaul Traina #\tgw -- gateways\n\ 7544099b7bSPaul Traina #\tha -- hardware address\n\ 7644099b7bSPaul Traina #\thd -- home directory for bootfiles\n\ 7744099b7bSPaul Traina #\thn -- host name set for client\n\ 7844099b7bSPaul Traina #\tht -- hardware type\n\ 7944099b7bSPaul Traina #\tim -- impress servers\n\ 8044099b7bSPaul Traina #\tip -- host IP address\n\ 8144099b7bSPaul Traina #\tlg -- log servers\n\ 8244099b7bSPaul Traina #\tlp -- LPR servers\n\ 8344099b7bSPaul Traina #\tms -- message size\n\ 8444099b7bSPaul Traina #\tmw -- min wait (secs)\n\ 8544099b7bSPaul Traina #\tns -- IEN-116 name servers\n\ 8644099b7bSPaul Traina #\tnt -- NTP servers (RFC 1129)\n\ 8744099b7bSPaul Traina #\tra -- reply address override\n\ 8844099b7bSPaul Traina #\trl -- resource location protocol servers\n\ 8944099b7bSPaul Traina #\trp -- root path\n\ 9044099b7bSPaul Traina #\tsa -- boot server address\n\ 9144099b7bSPaul Traina #\tsm -- subnet mask\n\ 9244099b7bSPaul Traina #\tsw -- swap server\n\ 9344099b7bSPaul Traina #\ttc -- template host (points to similar host entry)\n\ 9444099b7bSPaul Traina #\ttd -- TFTP directory\n\ 9544099b7bSPaul Traina #\tto -- time offset (seconds)\n\ 9644099b7bSPaul Traina #\tts -- time servers\n\ 9744099b7bSPaul Traina #\tvm -- vendor magic number\n\ 9844099b7bSPaul Traina #\tyd -- YP (NIS) domain\n\ 9944099b7bSPaul Traina #\tys -- YP (NIS) servers\n\ 10044099b7bSPaul Traina #\tTn -- generic option tag n\n\ 10144099b7bSPaul Traina \n"; 10244099b7bSPaul Traina 10344099b7bSPaul Traina /* 10444099b7bSPaul Traina * Open bootpd.dump file. 10544099b7bSPaul Traina */ 10644099b7bSPaul Traina if ((fp = fopen(filename, "w")) == NULL) { 10744099b7bSPaul Traina report(LOG_ERR, "error opening \"%s\": %s", 10844099b7bSPaul Traina filename, get_errmsg()); 10944099b7bSPaul Traina exit(1); 11044099b7bSPaul Traina } 11144099b7bSPaul Traina t = time(NULL); 11244099b7bSPaul Traina fprintf(fp, "\n# %s %s.%d\n", progname, VERSION, PATCHLEVEL); 11344099b7bSPaul Traina fprintf(fp, "# %s: dump of bootp server database.\n", filename); 11444099b7bSPaul Traina fprintf(fp, "# Dump taken %s", ctime(&t)); 11544099b7bSPaul Traina fwrite(legend, 1, sizeof(legend) - 1, fp); 11644099b7bSPaul Traina 11744099b7bSPaul Traina n = 0; 11844099b7bSPaul Traina for (hp = (struct host *) hash_FirstEntry(nmhashtable); hp != NULL; 11944099b7bSPaul Traina hp = (struct host *) hash_NextEntry(nmhashtable)) { 12044099b7bSPaul Traina dump_host(fp, hp); 12144099b7bSPaul Traina fprintf(fp, "\n"); 12244099b7bSPaul Traina n++; 12344099b7bSPaul Traina } 12444099b7bSPaul Traina fclose(fp); 12544099b7bSPaul Traina 12644099b7bSPaul Traina report(LOG_INFO, "dumped %d entries to \"%s\".", n, filename); 12744099b7bSPaul Traina } 12844099b7bSPaul Traina 12944099b7bSPaul Traina 13044099b7bSPaul Traina 13144099b7bSPaul Traina /* 13244099b7bSPaul Traina * Dump all the available information on the host pointed to by "hp". 13344099b7bSPaul Traina * The output is sent to the file pointed to by "fp". 13444099b7bSPaul Traina */ 13544099b7bSPaul Traina 13644099b7bSPaul Traina static void 13744099b7bSPaul Traina dump_host(fp, hp) 13844099b7bSPaul Traina FILE *fp; 13944099b7bSPaul Traina struct host *hp; 14044099b7bSPaul Traina { 14144099b7bSPaul Traina /* Print symbols in alphabetical order for reader's convenience. */ 14244099b7bSPaul Traina if (hp) { 14344099b7bSPaul Traina fprintf(fp, "%s:", (hp->hostname ? 14444099b7bSPaul Traina hp->hostname->string : "?")); 14544099b7bSPaul Traina if (hp->flags.bootfile) { 14644099b7bSPaul Traina fprintf(fp, "\\\n\t:bf=%s:", hp->bootfile->string); 14744099b7bSPaul Traina } 14844099b7bSPaul Traina if (hp->flags.bootsize) { 14944099b7bSPaul Traina fprintf(fp, "\\\n\t:bs="); 15044099b7bSPaul Traina if (hp->flags.bootsize_auto) { 15144099b7bSPaul Traina fprintf(fp, "auto:"); 15244099b7bSPaul Traina } else { 15344099b7bSPaul Traina fprintf(fp, "%d:", hp->bootsize); 15444099b7bSPaul Traina } 15544099b7bSPaul Traina } 15644099b7bSPaul Traina if (hp->flags.cookie_server) { 15744099b7bSPaul Traina fprintf(fp, "\\\n\t:cs="); 15844099b7bSPaul Traina list_ipaddresses(fp, hp->cookie_server); 15944099b7bSPaul Traina fprintf(fp, ":"); 16044099b7bSPaul Traina } 16144099b7bSPaul Traina if (hp->flags.dump_file) { 16244099b7bSPaul Traina fprintf(fp, "\\\n\t:df=%s:", hp->dump_file->string); 16344099b7bSPaul Traina } 16444099b7bSPaul Traina if (hp->flags.domain_name) { 16544099b7bSPaul Traina fprintf(fp, "\\\n\t:dn=%s:", hp->domain_name->string); 16644099b7bSPaul Traina } 16744099b7bSPaul Traina if (hp->flags.domain_server) { 16844099b7bSPaul Traina fprintf(fp, "\\\n\t:ds="); 16944099b7bSPaul Traina list_ipaddresses(fp, hp->domain_server); 17044099b7bSPaul Traina fprintf(fp, ":"); 17144099b7bSPaul Traina } 17244099b7bSPaul Traina if (hp->flags.exten_file) { 17344099b7bSPaul Traina fprintf(fp, "\\\n\t:ef=%s:", hp->exten_file->string); 17444099b7bSPaul Traina } 17544099b7bSPaul Traina if (hp->flags.exec_file) { 17644099b7bSPaul Traina fprintf(fp, "\\\n\t:ex=%s:", hp->exec_file->string); 17744099b7bSPaul Traina } 17844099b7bSPaul Traina if (hp->flags.gateway) { 17944099b7bSPaul Traina fprintf(fp, "\\\n\t:gw="); 18044099b7bSPaul Traina list_ipaddresses(fp, hp->gateway); 18144099b7bSPaul Traina fprintf(fp, ":"); 18244099b7bSPaul Traina } 18344099b7bSPaul Traina /* FdC: swap_server (see below) */ 18444099b7bSPaul Traina if (hp->flags.homedir) { 18544099b7bSPaul Traina fprintf(fp, "\\\n\t:hd=%s:", hp->homedir->string); 18644099b7bSPaul Traina } 18744099b7bSPaul Traina /* FdC: dump_file (see above) */ 18844099b7bSPaul Traina /* FdC: domain_name (see above) */ 18944099b7bSPaul Traina /* FdC: root_path (see below) */ 19044099b7bSPaul Traina if (hp->flags.name_switch && hp->flags.send_name) { 19144099b7bSPaul Traina fprintf(fp, "\\\n\t:hn:"); 19244099b7bSPaul Traina } 19344099b7bSPaul Traina if (hp->flags.htype) { 19444099b7bSPaul Traina int hlen = haddrlength(hp->htype); 19544099b7bSPaul Traina fprintf(fp, "\\\n\t:ht=%u:", (unsigned) hp->htype); 19644099b7bSPaul Traina if (hp->flags.haddr) { 19744099b7bSPaul Traina fprintf(fp, "ha=\"%s\":", 19844099b7bSPaul Traina haddrtoa(hp->haddr, hlen)); 19944099b7bSPaul Traina } 20044099b7bSPaul Traina } 20144099b7bSPaul Traina if (hp->flags.impress_server) { 20244099b7bSPaul Traina fprintf(fp, "\\\n\t:im="); 20344099b7bSPaul Traina list_ipaddresses(fp, hp->impress_server); 20444099b7bSPaul Traina fprintf(fp, ":"); 20544099b7bSPaul Traina } 20644099b7bSPaul Traina /* NetBSD: swap_server (see below) */ 20744099b7bSPaul Traina if (hp->flags.iaddr) { 20844099b7bSPaul Traina fprintf(fp, "\\\n\t:ip=%s:", inet_ntoa(hp->iaddr)); 20944099b7bSPaul Traina } 21044099b7bSPaul Traina if (hp->flags.log_server) { 21144099b7bSPaul Traina fprintf(fp, "\\\n\t:lg="); 21244099b7bSPaul Traina list_ipaddresses(fp, hp->log_server); 21344099b7bSPaul Traina fprintf(fp, ":"); 21444099b7bSPaul Traina } 21544099b7bSPaul Traina if (hp->flags.lpr_server) { 21644099b7bSPaul Traina fprintf(fp, "\\\n\t:lp="); 21744099b7bSPaul Traina list_ipaddresses(fp, hp->lpr_server); 21844099b7bSPaul Traina fprintf(fp, ":"); 21944099b7bSPaul Traina } 22044099b7bSPaul Traina if (hp->flags.msg_size) { 22144099b7bSPaul Traina fprintf(fp, "\\\n\t:ms=%d:", hp->msg_size); 22244099b7bSPaul Traina } 22344099b7bSPaul Traina if (hp->flags.min_wait) { 22444099b7bSPaul Traina fprintf(fp, "\\\n\t:mw=%d:", hp->min_wait); 22544099b7bSPaul Traina } 22644099b7bSPaul Traina if (hp->flags.name_server) { 22744099b7bSPaul Traina fprintf(fp, "\\\n\t:ns="); 22844099b7bSPaul Traina list_ipaddresses(fp, hp->name_server); 22944099b7bSPaul Traina fprintf(fp, ":"); 23044099b7bSPaul Traina } 23144099b7bSPaul Traina if (hp->flags.ntp_server) { 23244099b7bSPaul Traina fprintf(fp, "\\\n\t:nt="); 23344099b7bSPaul Traina list_ipaddresses(fp, hp->ntp_server); 23444099b7bSPaul Traina fprintf(fp, ":"); 23544099b7bSPaul Traina } 23644099b7bSPaul Traina if (hp->flags.reply_addr) { 23744099b7bSPaul Traina fprintf(fp, "\\\n\t:ra=%s:", inet_ntoa(hp->reply_addr)); 23844099b7bSPaul Traina } 23944099b7bSPaul Traina if (hp->flags.rlp_server) { 24044099b7bSPaul Traina fprintf(fp, "\\\n\t:rl="); 24144099b7bSPaul Traina list_ipaddresses(fp, hp->rlp_server); 24244099b7bSPaul Traina fprintf(fp, ":"); 24344099b7bSPaul Traina } 24444099b7bSPaul Traina if (hp->flags.root_path) { 24544099b7bSPaul Traina fprintf(fp, "\\\n\t:rp=%s:", hp->root_path->string); 24644099b7bSPaul Traina } 24744099b7bSPaul Traina if (hp->flags.bootserver) { 24844099b7bSPaul Traina fprintf(fp, "\\\n\t:sa=%s:", inet_ntoa(hp->bootserver)); 24944099b7bSPaul Traina } 25044099b7bSPaul Traina if (hp->flags.subnet_mask) { 25144099b7bSPaul Traina fprintf(fp, "\\\n\t:sm=%s:", inet_ntoa(hp->subnet_mask)); 25244099b7bSPaul Traina } 25344099b7bSPaul Traina if (hp->flags.swap_server) { 25444099b7bSPaul Traina fprintf(fp, "\\\n\t:sw=%s:", inet_ntoa(hp->subnet_mask)); 25544099b7bSPaul Traina } 25644099b7bSPaul Traina if (hp->flags.tftpdir) { 25744099b7bSPaul Traina fprintf(fp, "\\\n\t:td=%s:", hp->tftpdir->string); 25844099b7bSPaul Traina } 25944099b7bSPaul Traina /* NetBSD: rootpath (see above) */ 26044099b7bSPaul Traina /* NetBSD: domainname (see above) */ 26144099b7bSPaul Traina /* NetBSD: dumpfile (see above) */ 26244099b7bSPaul Traina if (hp->flags.time_offset) { 26344099b7bSPaul Traina fprintf(fp, "\\\n\t:to=%ld:", hp->time_offset); 26444099b7bSPaul Traina } 26544099b7bSPaul Traina if (hp->flags.time_server) { 26644099b7bSPaul Traina fprintf(fp, "\\\n\t:ts="); 26744099b7bSPaul Traina list_ipaddresses(fp, hp->time_server); 26844099b7bSPaul Traina fprintf(fp, ":"); 26944099b7bSPaul Traina } 27044099b7bSPaul Traina if (hp->flags.vm_cookie) { 27144099b7bSPaul Traina fprintf(fp, "\\\n\t:vm="); 27244099b7bSPaul Traina if (!bcmp(hp->vm_cookie, vm_rfc1048, 4)) { 27344099b7bSPaul Traina fprintf(fp, "rfc1048:"); 27444099b7bSPaul Traina } else if (!bcmp(hp->vm_cookie, vm_cmu, 4)) { 27544099b7bSPaul Traina fprintf(fp, "cmu:"); 27644099b7bSPaul Traina } else { 27744099b7bSPaul Traina fprintf(fp, "%d.%d.%d.%d:", 27844099b7bSPaul Traina (int) ((hp->vm_cookie)[0]), 27944099b7bSPaul Traina (int) ((hp->vm_cookie)[1]), 28044099b7bSPaul Traina (int) ((hp->vm_cookie)[2]), 28144099b7bSPaul Traina (int) ((hp->vm_cookie)[3])); 28244099b7bSPaul Traina } 28344099b7bSPaul Traina } 28444099b7bSPaul Traina if (hp->flags.nis_domain) { 28544099b7bSPaul Traina fprintf(fp, "\\\n\t:yd=%s:", 28644099b7bSPaul Traina hp->nis_domain->string); 28744099b7bSPaul Traina } 28844099b7bSPaul Traina if (hp->flags.nis_server) { 28944099b7bSPaul Traina fprintf(fp, "\\\n\t:ys="); 29044099b7bSPaul Traina list_ipaddresses(fp, hp->nis_server); 29144099b7bSPaul Traina fprintf(fp, ":"); 29244099b7bSPaul Traina } 29344099b7bSPaul Traina /* 29444099b7bSPaul Traina * XXX - Add new tags here (or above, 29544099b7bSPaul Traina * so they print in alphabetical order). 29644099b7bSPaul Traina */ 29744099b7bSPaul Traina 29844099b7bSPaul Traina if (hp->flags.generic) { 29944099b7bSPaul Traina dump_generic(fp, hp->generic); 30044099b7bSPaul Traina } 30144099b7bSPaul Traina } 30244099b7bSPaul Traina } 30344099b7bSPaul Traina 30444099b7bSPaul Traina 30544099b7bSPaul Traina static void 30644099b7bSPaul Traina dump_generic(fp, generic) 30744099b7bSPaul Traina FILE *fp; 30844099b7bSPaul Traina struct shared_bindata *generic; 30944099b7bSPaul Traina { 31044099b7bSPaul Traina u_char *bp = generic->data; 31144099b7bSPaul Traina u_char *ep = bp + generic->length; 31244099b7bSPaul Traina u_char tag; 31344099b7bSPaul Traina int len; 31444099b7bSPaul Traina 31544099b7bSPaul Traina while (bp < ep) { 31644099b7bSPaul Traina tag = *bp++; 31744099b7bSPaul Traina if (tag == TAG_PAD) 31844099b7bSPaul Traina continue; 31944099b7bSPaul Traina if (tag == TAG_END) 32044099b7bSPaul Traina return; 32144099b7bSPaul Traina len = *bp++; 32244099b7bSPaul Traina if (bp + len > ep) { 32344099b7bSPaul Traina fprintf(fp, " #junk in generic! :"); 32444099b7bSPaul Traina return; 32544099b7bSPaul Traina } 32644099b7bSPaul Traina fprintf(fp, "\\\n\t:T%d=", tag); 32744099b7bSPaul Traina while (len) { 32844099b7bSPaul Traina fprintf(fp, "%02X", *bp); 32944099b7bSPaul Traina bp++; 33044099b7bSPaul Traina len--; 33144099b7bSPaul Traina if (len) 33244099b7bSPaul Traina fprintf(fp, "."); 33344099b7bSPaul Traina } 33444099b7bSPaul Traina fprintf(fp, ":"); 33544099b7bSPaul Traina } 33644099b7bSPaul Traina } 33744099b7bSPaul Traina 33844099b7bSPaul Traina 33944099b7bSPaul Traina 34044099b7bSPaul Traina /* 34144099b7bSPaul Traina * Dump an entire struct in_addr_list of IP addresses to the indicated file. 34244099b7bSPaul Traina * 34344099b7bSPaul Traina * The addresses are printed in standard ASCII "dot" notation and separated 34444099b7bSPaul Traina * from one another by a single space. A single leading space is also 34544099b7bSPaul Traina * printed before the first adddress. 34644099b7bSPaul Traina * 34744099b7bSPaul Traina * Null lists produce no output (and no error). 34844099b7bSPaul Traina */ 34944099b7bSPaul Traina 35044099b7bSPaul Traina static void 35144099b7bSPaul Traina list_ipaddresses(fp, ipptr) 35244099b7bSPaul Traina FILE *fp; 35344099b7bSPaul Traina struct in_addr_list *ipptr; 35444099b7bSPaul Traina { 35544099b7bSPaul Traina unsigned count; 35644099b7bSPaul Traina struct in_addr *addrptr; 35744099b7bSPaul Traina 35844099b7bSPaul Traina if (ipptr) { 35944099b7bSPaul Traina count = ipptr->addrcount; 36044099b7bSPaul Traina addrptr = ipptr->addr; 36144099b7bSPaul Traina while (count > 0) { 36244099b7bSPaul Traina fprintf(fp, "%s", inet_ntoa(*addrptr++)); 36344099b7bSPaul Traina count--; 36444099b7bSPaul Traina if (count) 36544099b7bSPaul Traina fprintf(fp, ", "); 36644099b7bSPaul Traina } 36744099b7bSPaul Traina } 36844099b7bSPaul Traina } 36944099b7bSPaul Traina 37044099b7bSPaul Traina #endif /* DEBUG */ 37144099b7bSPaul Traina 37244099b7bSPaul Traina /* 37344099b7bSPaul Traina * Local Variables: 37444099b7bSPaul Traina * tab-width: 4 37544099b7bSPaul Traina * c-indent-level: 4 37644099b7bSPaul Traina * c-argdecl-indent: 4 37744099b7bSPaul Traina * c-continued-statement-offset: 4 37844099b7bSPaul Traina * c-continued-brace-offset: -4 37944099b7bSPaul Traina * c-label-offset: -4 38044099b7bSPaul Traina * c-brace-offset: 0 38144099b7bSPaul Traina * End: 38244099b7bSPaul Traina */ 383