xref: /netbsd-src/libexec/rpc.sprayd/sprayd.c (revision 2b8aaed8cd498f784adff8b449eee3eb8e00c2a3)
1*2b8aaed8Splunky /*	$NetBSD: sprayd.c,v 1.18 2011/09/16 16:13:17 plunky Exp $	*/
252110e02Sthorpej 
343aa830eSderaadt /*
443aa830eSderaadt  * Copyright (c) 1994 Christos Zoulas
543aa830eSderaadt  * All rights reserved.
643aa830eSderaadt  *
743aa830eSderaadt  * Redistribution and use in source and binary forms, with or without
843aa830eSderaadt  * modification, are permitted provided that the following conditions
943aa830eSderaadt  * are met:
1043aa830eSderaadt  * 1. Redistributions of source code must retain the above copyright
1143aa830eSderaadt  *    notice, this list of conditions and the following disclaimer.
1243aa830eSderaadt  * 2. Redistributions in binary form must reproduce the above copyright
1343aa830eSderaadt  *    notice, this list of conditions and the following disclaimer in the
1443aa830eSderaadt  *    documentation and/or other materials provided with the distribution.
1543aa830eSderaadt  *
1643aa830eSderaadt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1743aa830eSderaadt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1843aa830eSderaadt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1943aa830eSderaadt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2043aa830eSderaadt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2143aa830eSderaadt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2243aa830eSderaadt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2343aa830eSderaadt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2443aa830eSderaadt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2543aa830eSderaadt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2643aa830eSderaadt  */
2743aa830eSderaadt 
28fa64ad7fSchristos #include <sys/cdefs.h>
2943aa830eSderaadt #ifndef lint
30*2b8aaed8Splunky __RCSID("$NetBSD: sprayd.c,v 1.18 2011/09/16 16:13:17 plunky Exp $");
3143aa830eSderaadt #endif /* not lint */
3243aa830eSderaadt 
3343aa830eSderaadt #include <stdio.h>
3443aa830eSderaadt #include <signal.h>
35fa64ad7fSchristos #include <stdlib.h>
36fa64ad7fSchristos #include <unistd.h>
3743aa830eSderaadt #include <syslog.h>
38fa64ad7fSchristos #include <sys/socket.h>
39fa64ad7fSchristos #include <sys/time.h>
40fa64ad7fSchristos #include <rpc/rpc.h>
4143aa830eSderaadt #include <rpcsvc/spray.h>
4243aa830eSderaadt 
439eba1e42Sjoerg __dead static void cleanup(int);
449eba1e42Sjoerg __dead static void die(int);
45aefb080fSfvdl static void spray_service(struct svc_req *, SVCXPRT *);
4643aa830eSderaadt 
4743aa830eSderaadt static int from_inetd = 1;
4843aa830eSderaadt 
4943aa830eSderaadt #define TIMEOUT 120
5043aa830eSderaadt 
51fa64ad7fSchristos static void
cleanup(int n)52aefb080fSfvdl cleanup(int n)
5343aa830eSderaadt {
5436407a95Smrg 
55aefb080fSfvdl 	(void)rpcb_unset(SPRAYPROG, SPRAYVERS, NULL);
5643aa830eSderaadt 	exit(0);
5743aa830eSderaadt }
5843aa830eSderaadt 
59fa64ad7fSchristos static void
die(int n)60aefb080fSfvdl die(int n)
618f6e962bSmycroft {
6236407a95Smrg 
638f6e962bSmycroft 	exit(0);
648f6e962bSmycroft }
6543aa830eSderaadt 
6643aa830eSderaadt int
main(int argc,char * argv[])67aefb080fSfvdl main(int argc, char *argv[])
6843aa830eSderaadt {
6943aa830eSderaadt 	SVCXPRT *transp;
70aefb080fSfvdl 	struct sockaddr_storage from;
710c37c63eSmrg 	socklen_t fromlen;
7243aa830eSderaadt 
7343aa830eSderaadt 	/*
7443aa830eSderaadt 	 * See if inetd started us
7543aa830eSderaadt 	 */
76002aa598Smycroft 	fromlen = sizeof(from);
77aefb080fSfvdl 	if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0)
7843aa830eSderaadt 		from_inetd = 0;
7943aa830eSderaadt 
8043aa830eSderaadt 	if (!from_inetd) {
8143aa830eSderaadt 		daemon(0, 0);
8243aa830eSderaadt 
83aefb080fSfvdl 		(void)rpcb_unset(SPRAYPROG, SPRAYVERS, NULL);
8443aa830eSderaadt 
8543aa830eSderaadt 		(void)signal(SIGINT, cleanup);
8643aa830eSderaadt 		(void)signal(SIGTERM, cleanup);
8743aa830eSderaadt 		(void)signal(SIGHUP, cleanup);
88f8bc7fb8Smycroft 	} else {
898f6e962bSmycroft 		(void)signal(SIGALRM, die);
90f8bc7fb8Smycroft 		alarm(TIMEOUT);
9143aa830eSderaadt 	}
9243aa830eSderaadt 
93f2130fd9Smrg 	openlog("rpc.sprayd", LOG_PID, LOG_DAEMON);
9443aa830eSderaadt 
95aefb080fSfvdl 	if (from_inetd) {
96aefb080fSfvdl 		transp = svc_dg_create(0, 0, 0);
9743aa830eSderaadt 		if (transp == NULL) {
9843aa830eSderaadt 			syslog(LOG_ERR, "cannot create udp service.");
99105b0380Slukem 			exit(1);
10043aa830eSderaadt 		}
101aefb080fSfvdl 		if (!svc_reg(transp, SPRAYPROG, SPRAYVERS, spray_service,
102aefb080fSfvdl 		    NULL)) {
10343aa830eSderaadt 			syslog(LOG_ERR,
104aefb080fSfvdl 			    "unable to register (SPRAYPROG, SPRAYVERS).");
105aefb080fSfvdl 			exit(1);
106aefb080fSfvdl 		}
107aefb080fSfvdl 	} else {
108aefb080fSfvdl 		if (!svc_create(spray_service, SPRAYPROG, SPRAYVERS, "udp")) {
109aefb080fSfvdl 			syslog(LOG_ERR,
110aefb080fSfvdl 			    "unable to register (SPRAYPROG, SPRAYVERS).");
111aefb080fSfvdl 			exit(1);
112aefb080fSfvdl 		}
11343aa830eSderaadt 	}
11443aa830eSderaadt 
11543aa830eSderaadt 	svc_run();
11643aa830eSderaadt 	syslog(LOG_ERR, "svc_run returned");
117105b0380Slukem 	exit(1);
11843aa830eSderaadt }
11943aa830eSderaadt 
12043aa830eSderaadt 
12143aa830eSderaadt static void
spray_service(struct svc_req * rqstp,SVCXPRT * transp)122aefb080fSfvdl spray_service(struct svc_req *rqstp, SVCXPRT *transp)
12343aa830eSderaadt {
12443aa830eSderaadt 	static spraycumul scum;
125f8bc7fb8Smycroft 	static struct timeval clear, get;
12643aa830eSderaadt 
12743aa830eSderaadt 	switch (rqstp->rq_proc) {
12843aa830eSderaadt 	case SPRAYPROC_CLEAR:
12943aa830eSderaadt 		scum.counter = 0;
13043aa830eSderaadt 		(void)gettimeofday(&clear, 0);
13143aa830eSderaadt 		/*FALLTHROUGH*/
13243aa830eSderaadt 
1335f5a0a3eSmycroft 	case NULLPROC:
134*2b8aaed8Splunky 		(void)svc_sendreply(transp, (xdrproc_t)xdr_void, NULL);
1355f5a0a3eSmycroft 		return;
1365f5a0a3eSmycroft 
13743aa830eSderaadt 	case SPRAYPROC_SPRAY:
13843aa830eSderaadt 		scum.counter++;
13943aa830eSderaadt 		return;
14043aa830eSderaadt 
14143aa830eSderaadt 	case SPRAYPROC_GET:
142f8bc7fb8Smycroft 		(void)gettimeofday(&get, 0);
143eb82f2b3Smycroft 		timersub(&get, &clear, &get);
144f8bc7fb8Smycroft 		scum.clock.sec = get.tv_sec;
145f8bc7fb8Smycroft 		scum.clock.usec = get.tv_usec;
14643aa830eSderaadt 		break;
14743aa830eSderaadt 
14843aa830eSderaadt 	default:
14943aa830eSderaadt 		svcerr_noproc(transp);
15043aa830eSderaadt 		return;
15143aa830eSderaadt 	}
15243aa830eSderaadt 
15387d4f607Splunky 	if (!svc_sendreply(transp, (xdrproc_t)xdr_spraycumul, (caddr_t)&scum)) {
15443aa830eSderaadt 		svcerr_systemerr(transp);
155105b0380Slukem 		syslog(LOG_WARNING, "bad svc_sendreply");
15643aa830eSderaadt 	}
15743aa830eSderaadt }
158