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