16751Swpaul/*
26751Swpaul
38857SrgrimesThis code is not copyright, and is placed in the public domain. Feel free to
46751Swpauluse and modify. Please send modifications and/or suggestions + bug fixes to
56751Swpaul
66751Swpaul        Klas Heggemann <klas@nada.kth.se>
76751Swpaul
829102Scharnier*/
96751Swpaul
1029102Scharnier#ifndef lint
1129102Scharnierstatic const char rcsid[] =
1250479Speter  "$FreeBSD$";
1329102Scharnier#endif /* not lint */
146751Swpaul
1529102Scharnier#include <ctype.h>
1629102Scharnier#include <err.h>
1729102Scharnier#include <netdb.h>
189718Swpaul#include <stdio.h>
1929102Scharnier#include <stdlib.h>
209718Swpaul#include <string.h>
216751Swpaul#include <syslog.h>
2229102Scharnier#include <unistd.h>
2329102Scharnier#include <rpc/rpc.h>
2429102Scharnier#include <rpc/pmap_clnt.h>
256751Swpaul#include <sys/ioctl.h>
2629102Scharnier#include <sys/socket.h>
2729102Scharnier#include <sys/stat.h>
2829102Scharnier#include <sys/types.h>
2936917Speter#include <netinet/in.h>
3036917Speter#include <arpa/inet.h>
316751Swpaul#include "bootparam_prot.h"
326751Swpaul
336751Swpaulint debug = 0;
346751Swpaulint dolog = 0;
35175823Srinkin_addr_t route_addr = -1;
366751Swpaulstruct sockaddr_in my_addr;
376751Swpaulchar *bootpfile = "/etc/bootparams";
386751Swpaul
396751Swpaulextern  void bootparamprog_1();
40173412Skevlostatic void usage(void);
416751Swpaul
4229102Scharnierint
436751Swpaulmain(argc, argv)
446751Swpaulint argc;
456751Swpaulchar **argv;
466751Swpaul{
476751Swpaul	SVCXPRT *transp;
486751Swpaul	struct hostent *he;
496751Swpaul	struct stat buf;
50181125Scognet	int c;
516751Swpaul
5224428Simp	while ((c = getopt(argc, argv,"dsr:f:")) != -1)
53181143Scognet	  switch (c) {
546751Swpaul	  case 'd':
556751Swpaul	    debug = 1;
566751Swpaul	    break;
576751Swpaul	  case 'r':
58130243Sstefanf	      if (isdigit((unsigned char)*optarg)) {
596751Swpaul		route_addr = inet_addr(optarg);
606751Swpaul		break;
616751Swpaul	      } else {
626751Swpaul		he = gethostbyname(optarg);
636751Swpaul		if (he) {
646751Swpaul		   bcopy(he->h_addr, (char *)&route_addr, sizeof(route_addr));
656751Swpaul		   break;
6629102Scharnier		} else {
67130243Sstefanf		   errx(1, "no such host %s", optarg);
6829102Scharnier		}
696751Swpaul	      }
706751Swpaul	  case 'f':
716751Swpaul	    bootpfile = optarg;
726751Swpaul	    break;
736751Swpaul	  case 's':
746751Swpaul	    dolog = 1;
758857Srgrimes#ifndef LOG_DAEMON
7629102Scharnier	    openlog("bootparamd", 0 , 0);
776751Swpaul#else
7829102Scharnier	    openlog("bootparamd", 0 , LOG_DAEMON);
796751Swpaul	    setlogmask(LOG_UPTO(LOG_NOTICE));
806751Swpaul#endif
816751Swpaul	    break;
826751Swpaul	  default:
8329102Scharnier	    usage();
846751Swpaul	  }
856751Swpaul
8629102Scharnier	if ( stat(bootpfile, &buf ) )
8729102Scharnier	  err(1, "%s", bootpfile);
886751Swpaul
896751Swpaul	if (route_addr == -1) {
906751Swpaul	  get_myaddress(&my_addr);
916751Swpaul	  bcopy(&my_addr.sin_addr.s_addr, &route_addr, sizeof (route_addr));
926751Swpaul	}
936751Swpaul
946751Swpaul	if (!debug) {
9529102Scharnier	  if (daemon(0,0))
9629102Scharnier	    err(1, "fork");
976751Swpaul	}
986751Swpaul
998857Srgrimes
1006751Swpaul	(void)pmap_unset(BOOTPARAMPROG, BOOTPARAMVERS);
1016751Swpaul
1026751Swpaul	transp = svcudp_create(RPC_ANYSOCK);
10329102Scharnier	if (transp == NULL)
10429102Scharnier		errx(1, "cannot create udp service");
10529102Scharnier	if (!svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS, bootparamprog_1, IPPROTO_UDP))
10629102Scharnier		errx(1, "unable to register (BOOTPARAMPROG, BOOTPARAMVERS, udp)");
1076751Swpaul
1086751Swpaul	svc_run();
10929102Scharnier	errx(1, "svc_run returned");
11029102Scharnier}
11129102Scharnier
11229102Scharnierstatic void
11329102Scharnierusage()
11429102Scharnier{
11529102Scharnier	fprintf(stderr,
11629102Scharnier		"usage: bootparamd [-d] [-s] [-r router] [-f bootparmsfile]\n");
1176751Swpaul	exit(1);
1186751Swpaul}
119