Home | History | Annotate | Line # | Download | only in bootpef
      1   1.1      gwr /************************************************************************
      2   1.1      gwr           Copyright 1988, 1991 by Carnegie Mellon University
      3   1.1      gwr 
      4   1.1      gwr                           All Rights Reserved
      5   1.1      gwr 
      6   1.1      gwr Permission to use, copy, modify, and distribute this software and its
      7   1.1      gwr documentation for any purpose and without fee is hereby granted, provided
      8   1.1      gwr that the above copyright notice appear in all copies and that both that
      9   1.1      gwr copyright notice and this permission notice appear in supporting
     10   1.1      gwr documentation, and that the name of Carnegie Mellon University not be used
     11   1.1      gwr in advertising or publicity pertaining to distribution of the software
     12   1.1      gwr without specific, written prior permission.
     13   1.1      gwr 
     14   1.1      gwr CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
     15   1.1      gwr SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
     16   1.1      gwr IN NO EVENT SHALL CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
     17   1.1      gwr DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
     18   1.1      gwr PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
     19   1.1      gwr ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     20   1.1      gwr SOFTWARE.
     21   1.1      gwr ************************************************************************/
     22   1.1      gwr 
     23   1.4    lukem #include <sys/cdefs.h>
     24   1.1      gwr #ifndef lint
     25  1.11    sevan __RCSID("$NetBSD: bootpef.c,v 1.11 2017/05/04 16:26:09 sevan Exp $");
     26   1.1      gwr #endif
     27   1.1      gwr 
     28   1.1      gwr 
     29   1.1      gwr /*
     30   1.1      gwr  * bootpef - BOOTP Extension File generator
     31   1.1      gwr  *	Makes an "Extension File" for each host entry that
     32   1.1      gwr  *	defines an and Extension File. (See RFC1497, tag 18.)
     33   1.1      gwr  *
     34   1.1      gwr  * HISTORY
     35   1.1      gwr  *	See ./Changes
     36   1.1      gwr  *
     37   1.1      gwr  * BUGS
     38   1.1      gwr  *	See ./ToDo
     39   1.1      gwr  */
     40   1.1      gwr 
     41   1.1      gwr 
     43   1.1      gwr 
     44   1.1      gwr #include <stdarg.h>
     45   1.1      gwr 
     46   1.1      gwr #include <sys/types.h>
     47   1.1      gwr #include <sys/time.h>
     48   1.1      gwr 
     49   1.1      gwr #include <netinet/in.h>
     50   1.1      gwr #include <arpa/inet.h>			/* inet_ntoa */
     51   1.1      gwr 
     52   1.1      gwr #ifndef	NO_UNISTD
     53   1.1      gwr #include <unistd.h>
     54   1.1      gwr #endif
     55   1.1      gwr #include <stdlib.h>
     56   1.1      gwr #include <stdio.h>
     57   1.7      tls #include <string.h>
     58   1.1      gwr #include <strings.h>
     59   1.1      gwr #include <errno.h>
     60   1.1      gwr #include <ctype.h>
     61   1.1      gwr #include <syslog.h>
     62   1.1      gwr 
     63   1.1      gwr #include "bootp.h"
     64   1.1      gwr #include "hash.h"
     65   1.1      gwr #include "hwaddr.h"
     66   1.1      gwr #include "bootpd.h"
     67   1.1      gwr #include "dovend.h"
     68   1.1      gwr #include "readfile.h"
     69   1.1      gwr #include "report.h"
     70   1.1      gwr #include "tzone.h"
     71   1.1      gwr #include "patchlevel.h"
     72   1.1      gwr 
     73   1.1      gwr #define	BUFFERSIZE   		0x4000
     74   1.1      gwr 
     75   1.1      gwr #ifndef CONFIG_FILE
     76   1.1      gwr #define CONFIG_FILE		"/etc/bootptab"
     77   1.1      gwr #endif
     78   1.1      gwr 
     79   1.1      gwr 
     81   1.1      gwr 
     82   1.1      gwr /*
     83   1.1      gwr  * Externals, forward declarations, and global variables
     84   1.5      wiz  */
     85  1.10    joerg 
     86   1.1      gwr static void mktagfile(struct host *);
     87   1.1      gwr __dead static void usage(void);
     88   1.1      gwr 
     89   1.1      gwr 
     90   1.1      gwr /*
     91   1.1      gwr  * General
     92   1.8  xtraeme  */
     93   1.1      gwr 
     94   1.1      gwr const char *progname;
     95   1.1      gwr char *chdir_path;
     96   1.1      gwr int debug = 0;					/* Debugging flag (level) */
     97   1.1      gwr byte *buffer;
     98   1.1      gwr 
     99   1.1      gwr /*
    100   1.1      gwr  * Globals below are associated with the bootp database file (bootptab).
    101   1.8  xtraeme  */
    102   1.1      gwr 
    103   1.1      gwr const char *bootptab = CONFIG_FILE;
    104   1.1      gwr 
    105   1.1      gwr 
    107   1.1      gwr /*
    108   1.5      wiz  * Print "usage" message and exit
    109   1.1      gwr  */
    110   1.1      gwr static void
    111   1.6     hira usage(void)
    112   1.6     hira {
    113   1.1      gwr 	fprintf(stderr,
    114   1.1      gwr 	    "usage: %s [-c chdir] [-d level] [-f configfile] [host ...]\n",
    115   1.1      gwr 	    getprogname());
    116   1.1      gwr 	fprintf(stderr, "\t -c n\tset current directory\n");
    117   1.1      gwr 	fprintf(stderr, "\t -d n\tset debug level\n");
    118   1.1      gwr 	fprintf(stderr, "\t -f n\tconfig file name\n");
    119   1.1      gwr 	exit(1);
    120   1.1      gwr }
    121   1.1      gwr 
    122   1.1      gwr 
    123   1.1      gwr /*
    124   1.4    lukem  * Initialization such as command-line processing is done and then the
    125   1.5      wiz  * main server loop is started.
    126   1.1      gwr  */
    127   1.1      gwr int
    128   1.1      gwr main(int argc, char **argv)
    129   1.1      gwr {
    130   1.1      gwr 	struct host *hp;
    131   1.1      gwr 	char *stmp;
    132   1.1      gwr 	int n;
    133   1.1      gwr 
    134   1.1      gwr 	progname = strrchr(argv[0], '/');
    135   1.1      gwr 	if (progname) progname++;
    136   1.1      gwr 	else progname = argv[0];
    137   1.1      gwr 
    138   1.1      gwr 	/* Get work space for making tag 18 files. */
    139   1.1      gwr 	buffer = (byte *) malloc(BUFFERSIZE);
    140   1.1      gwr 	if (!buffer) {
    141   1.1      gwr 		report(LOG_ERR, "malloc failed");
    142   1.1      gwr 		exit(1);
    143   1.1      gwr 	}
    144   1.1      gwr 	/*
    145   1.1      gwr 	 * Set defaults that might be changed by option switches.
    146   1.1      gwr 	 */
    147   1.1      gwr 	stmp = NULL;
    148   1.1      gwr 
    149   1.1      gwr 	/*
    150   1.1      gwr 	 * Read switches.
    151   1.1      gwr 	 */
    152   1.1      gwr 	for (argc--, argv++; argc > 0; argc--, argv++) {
    153   1.1      gwr 		if (argv[0][0] != '-')
    154   1.1      gwr 			break;
    155   1.1      gwr 		switch (argv[0][1]) {
    156   1.1      gwr 
    157   1.1      gwr 		case 'c':				/* chdir_path */
    158   1.1      gwr 			if (argv[0][2]) {
    159   1.1      gwr 				stmp = &(argv[0][2]);
    160   1.1      gwr 			} else {
    161   1.1      gwr 				argc--;
    162   1.1      gwr 				argv++;
    163   1.1      gwr 				stmp = argv[0];
    164   1.1      gwr 			}
    165   1.1      gwr 			if (!stmp || (stmp[0] != '/')) {
    166   1.1      gwr 				fprintf(stderr,
    167   1.1      gwr 						"bootpd: invalid chdir specification\n");
    168   1.1      gwr 				break;
    169   1.1      gwr 			}
    170   1.1      gwr 			chdir_path = stmp;
    171   1.1      gwr 			break;
    172   1.1      gwr 
    173   1.1      gwr 		case 'd':				/* debug */
    174   1.1      gwr 			if (argv[0][2]) {
    175   1.1      gwr 				stmp = &(argv[0][2]);
    176   1.1      gwr 			} else if (argv[1] && argv[1][0] == '-') {
    177   1.1      gwr 				/*
    178   1.1      gwr 				 * Backwards-compatible behavior:
    179   1.1      gwr 				 * no parameter, so just increment the debug flag.
    180   1.1      gwr 				 */
    181   1.1      gwr 				debug++;
    182   1.1      gwr 				break;
    183   1.1      gwr 			} else {
    184   1.1      gwr 				argc--;
    185   1.1      gwr 				argv++;
    186   1.1      gwr 				stmp = argv[0];
    187   1.1      gwr 			}
    188   1.1      gwr 			if (!stmp || (sscanf(stmp, "%d", &n) != 1) || (n < 0)) {
    189   1.1      gwr 				fprintf(stderr,
    190   1.1      gwr 						"bootpd: invalid debug level\n");
    191   1.1      gwr 				break;
    192   1.1      gwr 			}
    193   1.1      gwr 			debug = n;
    194   1.1      gwr 			break;
    195   1.1      gwr 
    196   1.1      gwr 		case 'f':				/* config file */
    197   1.1      gwr 			if (argv[0][2]) {
    198   1.1      gwr 				stmp = &(argv[0][2]);
    199   1.1      gwr 			} else {
    200   1.1      gwr 				argc--;
    201   1.1      gwr 				argv++;
    202   1.1      gwr 				stmp = argv[0];
    203   1.1      gwr 			}
    204   1.1      gwr 			bootptab = stmp;
    205   1.1      gwr 			break;
    206   1.1      gwr 
    207   1.1      gwr 		default:
    208   1.1      gwr 			fprintf(stderr, "bootpd: unknown switch: -%c\n",
    209   1.1      gwr 					argv[0][1]);
    210   1.1      gwr 			usage();
    211   1.1      gwr 			break;
    212   1.1      gwr 		}
    213   1.1      gwr 	}
    214   1.1      gwr 
    215   1.1      gwr 	/* Get the timezone. */
    216   1.1      gwr 	tzone_init();
    217   1.1      gwr 
    218   1.1      gwr 	/* Allocate hash tables. */
    219   1.1      gwr 	rdtab_init();
    220   1.1      gwr 
    221   1.1      gwr 	/*
    222   1.1      gwr 	 * Read the bootptab file.
    223   1.1      gwr 	 */
    224   1.1      gwr 	readtab(1);					/* force read */
    225   1.1      gwr 
    226   1.1      gwr 	/* Set the cwd (i.e. to /tftpboot) */
    227   1.1      gwr 	if (chdir_path) {
    228   1.1      gwr 		if (chdir(chdir_path) < 0)
    229   1.1      gwr 			report(LOG_ERR, "%s: chdir failed", chdir_path);
    230   1.1      gwr 	}
    231   1.1      gwr 	/* If there are host names on the command line, do only those. */
    232   1.1      gwr 	if (argc > 0) {
    233   1.1      gwr 		unsigned int tlen, hashcode;
    234   1.1      gwr 
    235   1.1      gwr 		while (argc) {
    236   1.1      gwr 			tlen = strlen(argv[0]);
    237   1.1      gwr 			hashcode = hash_HashFunction((u_char *)argv[0], tlen);
    238   1.1      gwr 			hp = (struct host *) hash_Lookup(nmhashtable,
    239   1.1      gwr 											 hashcode,
    240   1.1      gwr 											 nmcmp, argv[0]);
    241   1.1      gwr 			if (!hp) {
    242   1.1      gwr 				printf("%s: no matching entry\n", argv[0]);
    243   1.1      gwr 				exit(1);
    244   1.1      gwr 			}
    245   1.1      gwr 			if (!hp->flags.exten_file) {
    246   1.1      gwr 				printf("%s: no extension file\n", argv[0]);
    247   1.1      gwr 				exit(1);
    248   1.1      gwr 			}
    249   1.1      gwr 			mktagfile(hp);
    250   1.1      gwr 			argv++;
    251   1.1      gwr 			argc--;
    252   1.1      gwr 		}
    253   1.1      gwr 		exit(0);
    254   1.1      gwr 	}
    255   1.1      gwr 	/* No host names specified.  Do them all. */
    256   1.1      gwr 	hp = (struct host *) hash_FirstEntry(nmhashtable);
    257   1.1      gwr 	while (hp != NULL) {
    258   1.4    lukem 		mktagfile(hp);
    259   1.1      gwr 		hp = (struct host *) hash_NextEntry(nmhashtable);
    260   1.1      gwr 	}
    261   1.1      gwr 	exit(0);
    262   1.1      gwr }
    263   1.1      gwr 
    264   1.1      gwr 
    266   1.1      gwr 
    267   1.1      gwr /*
    268   1.1      gwr  * Make a "TAG 18" file for this host.
    269   1.5      wiz  * (Insert the RFC1497 options.)
    270   1.1      gwr  */
    271   1.1      gwr 
    272   1.1      gwr static void
    273   1.1      gwr mktagfile(struct host *hp)
    274   1.1      gwr {
    275   1.1      gwr 	FILE *fp;
    276   1.1      gwr 	int bytesleft, len;
    277   1.1      gwr 	byte *vp;
    278   1.1      gwr 
    279   1.1      gwr 	if (!hp->flags.exten_file)
    280   1.1      gwr 		return;
    281   1.1      gwr 
    282   1.1      gwr 	vp = buffer;
    283   1.1      gwr 	bytesleft = BUFFERSIZE;
    284   1.1      gwr 	bcopy(vm_rfc1048, vp, 4);	/* Copy in the magic cookie */
    285   1.1      gwr 	vp += 4;
    286   1.1      gwr 	bytesleft -= 4;
    287   1.1      gwr 
    288   1.1      gwr 	/*
    289   1.1      gwr 	 * The "extension file" options are appended by the following
    290   1.1      gwr 	 * function (which is shared with bootpd.c).
    291   1.1      gwr 	 */
    292   1.1      gwr 	len = dovend_rfc1497(hp, vp, bytesleft);
    293   1.1      gwr 	vp += len;
    294   1.1      gwr 	bytesleft -= len;
    295   1.1      gwr 
    296   1.1      gwr 	if (bytesleft < 1) {
    297   1.1      gwr 		report(LOG_ERR, "%s: too much option data",
    298   1.1      gwr 			   hp->exten_file->string);
    299   1.1      gwr 		return;
    300   1.1      gwr 	}
    301   1.1      gwr 	*vp++ = TAG_END;
    302   1.1      gwr 	bytesleft--;
    303   1.1      gwr 
    304   1.1      gwr 	/* Write the buffer to the extension file. */
    305   1.1      gwr 	printf("Updating \"%s\"\n", hp->exten_file->string);
    306   1.1      gwr 	if ((fp = fopen(hp->exten_file->string, "w")) == NULL) {
    307   1.1      gwr 		report(LOG_ERR, "error opening \"%s\": %s",
    308   1.9    lukem 			   hp->exten_file->string, get_errmsg());
    309   1.1      gwr 		return;
    310   1.1      gwr 	}
    311   1.1      gwr 	len = vp - buffer;
    312   1.1      gwr 	if ((size_t)len != fwrite(buffer, 1, len, fp)) {
    313   1.1      gwr 		report(LOG_ERR, "write failed on \"%s\" : %s",
    314   1.4    lukem 			   hp->exten_file->string, get_errmsg());
    315   1.1      gwr 	}
    316   1.1      gwr 	fclose(fp);
    317   1.1      gwr 
    318   1.1      gwr } /* mktagfile */
    319   1.1      gwr 
    320   1.1      gwr /*
    321   1.1      gwr  * Local Variables:
    322   1.1      gwr  * tab-width: 4
    323   1.1      gwr  * c-indent-level: 4
    324   1.1      gwr  * c-argdecl-indent: 4
    325   1.1      gwr  * c-continued-statement-offset: 4
    326   1.1      gwr  * c-continued-brace-offset: -4
    327                 * c-label-offset: -4
    328                 * c-brace-offset: 0
    329                 * End:
    330                 */
    331