1 /*
2 
3 This code is not copyright, and is placed in the public domain. Feel free to
4 use and modify. Please send modifications and/or suggestions + bug fixes to
5 
6         Klas Heggemann <klas@nada.kth.se>
7 
8 */
9 
10 #include <sys/cdefs.h>
11 __FBSDID("$FreeBSD$");
12 
13 #include <ctype.h>
14 #include <err.h>
15 #include <netdb.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <syslog.h>
20 #include <unistd.h>
21 #include <rpc/rpc.h>
22 #include <rpc/pmap_clnt.h>
23 #include <sys/ioctl.h>
24 #include <sys/socket.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29 #include "bootparam_prot.h"
30 
31 extern int debug, dolog;
32 extern in_addr_t route_addr;
33 extern const char *bootpfile;
34 
35 int debug = 0;
36 int dolog = 0;
37 in_addr_t route_addr = -1;
38 const char *bootpfile = "/etc/bootparams";
39 
40 static struct sockaddr_in my_addr;
41 
42 static void usage(void);
43 
44 int
45 main(int argc, char **argv)
46 {
47 	SVCXPRT *transp;
48 	struct hostent *he;
49 	struct stat buf;
50 	int c;
51 
52 	while ((c = getopt(argc, argv,"dsr:f:")) != -1)
53 	  switch (c) {
54 	  case 'd':
55 	    debug = 1;
56 	    break;
57 	  case 'r':
58 	      if (isdigit((unsigned char)*optarg)) {
59 		route_addr = inet_addr(optarg);
60 		break;
61 	      } else {
62 		he = gethostbyname(optarg);
63 		if (he) {
64 		   bcopy(he->h_addr, (char *)&route_addr, sizeof(route_addr));
65 		   break;
66 		} else {
67 		   errx(1, "no such host %s", optarg);
68 		}
69 	      }
70 	  case 'f':
71 	    bootpfile = optarg;
72 	    break;
73 	  case 's':
74 	    dolog = 1;
75 #ifndef LOG_DAEMON
76 	    openlog("bootparamd", 0 , 0);
77 #else
78 	    openlog("bootparamd", 0 , LOG_DAEMON);
79 	    setlogmask(LOG_UPTO(LOG_NOTICE));
80 #endif
81 	    break;
82 	  default:
83 	    usage();
84 	  }
85 
86 	if ( stat(bootpfile, &buf ) )
87 	  err(1, "%s", bootpfile);
88 
89 	if (route_addr == INADDR_NONE) {
90 	  get_myaddress(&my_addr);
91 	  bcopy(&my_addr.sin_addr.s_addr, &route_addr, sizeof (route_addr));
92 	}
93 
94 	if (!debug) {
95 	  if (daemon(0,0))
96 	    err(1, "fork");
97 	}
98 
99 
100 	(void)pmap_unset(BOOTPARAMPROG, BOOTPARAMVERS);
101 
102 	transp = svcudp_create(RPC_ANYSOCK);
103 	if (transp == NULL)
104 		errx(1, "cannot create udp service");
105 	if (!svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS, bootparamprog_1, IPPROTO_UDP))
106 		errx(1, "unable to register (BOOTPARAMPROG, BOOTPARAMVERS, udp)");
107 
108 	svc_run();
109 	errx(1, "svc_run returned");
110 }
111 
112 static void
113 usage(void)
114 {
115 	fprintf(stderr,
116 		"usage: bootparamd [-d] [-s] [-r router] [-f bootparmsfile]\n");
117 	exit(1);
118 }
119