Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/libexec/rpc.sprayd/sprayd.c
34914 views
1
/* $NetBSD: sprayd.c,v 1.15 2009/10/21 01:07:46 snj Exp $ */
2
3
/*-
4
* SPDX-License-Identifier: BSD-2-Clause
5
*
6
* Copyright (c) 1994 Christos Zoulas
7
* All rights reserved.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
11
* are met:
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
*
18
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
*/
29
30
#include <rpc/rpc.h>
31
#include <rpcsvc/spray.h>
32
#include <signal.h>
33
#include <stdio.h>
34
#include <stdlib.h>
35
#include <sys/time.h>
36
#include <sys/socket.h>
37
#include <syslog.h>
38
#include <unistd.h>
39
40
static void spray_service(struct svc_req *, SVCXPRT *);
41
42
static int from_inetd = 1;
43
44
#define timersub(tvp, uvp, vvp) \
45
do { \
46
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
47
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
48
if ((vvp)->tv_usec < 0) { \
49
(vvp)->tv_sec--; \
50
(vvp)->tv_usec += 1000000; \
51
} \
52
} while (0)
53
54
#define TIMEOUT 120
55
56
static void
57
cleanup(int sig __unused)
58
{
59
(void)rpcb_unset(SPRAYPROG, SPRAYVERS, NULL);
60
exit(0);
61
}
62
63
static void
64
die(int sig __unused)
65
{
66
exit(0);
67
}
68
69
int
70
main(int argc __unused, char *argv[] __unused)
71
{
72
SVCXPRT *transp;
73
int ok;
74
struct sockaddr_storage from;
75
socklen_t fromlen;
76
77
/*
78
* See if inetd started us
79
*/
80
fromlen = sizeof(from);
81
if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0) {
82
from_inetd = 0;
83
}
84
85
if (!from_inetd) {
86
daemon(0, 0);
87
88
(void)rpcb_unset(SPRAYPROG, SPRAYVERS, NULL);
89
90
(void)signal(SIGINT, cleanup);
91
(void)signal(SIGTERM, cleanup);
92
(void)signal(SIGHUP, cleanup);
93
} else {
94
(void)signal(SIGALRM, die);
95
alarm(TIMEOUT);
96
}
97
98
openlog("rpc.sprayd", LOG_PID, LOG_DAEMON);
99
100
if (from_inetd) {
101
transp = svc_tli_create(0, NULL, NULL, 0, 0);
102
if (transp == NULL) {
103
syslog(LOG_ERR, "cannot create udp service.");
104
exit(1);
105
}
106
ok = svc_reg(transp, SPRAYPROG, SPRAYVERS,
107
spray_service, NULL);
108
} else
109
ok = svc_create(spray_service,
110
SPRAYPROG, SPRAYVERS, "udp");
111
if (!ok) {
112
syslog(LOG_ERR,
113
"unable to register (SPRAYPROG, SPRAYVERS, %s)",
114
(!from_inetd)?"udp":"(inetd)");
115
exit(1);
116
}
117
118
svc_run();
119
syslog(LOG_ERR, "svc_run returned");
120
return 1;
121
}
122
123
124
static void
125
spray_service(struct svc_req *rqstp, SVCXPRT *transp)
126
{
127
static spraycumul scum;
128
static struct timeval clear, get;
129
130
switch (rqstp->rq_proc) {
131
case SPRAYPROC_CLEAR:
132
scum.counter = 0;
133
(void)gettimeofday(&clear, 0);
134
/*FALLTHROUGH*/
135
136
case NULLPROC:
137
(void)svc_sendreply(transp, (xdrproc_t)xdr_void, NULL);
138
return;
139
140
case SPRAYPROC_SPRAY:
141
scum.counter++;
142
return;
143
144
case SPRAYPROC_GET:
145
(void)gettimeofday(&get, 0);
146
timersub(&get, &clear, &get);
147
scum.clock.sec = get.tv_sec;
148
scum.clock.usec = get.tv_usec;
149
break;
150
151
default:
152
svcerr_noproc(transp);
153
return;
154
}
155
156
if (!svc_sendreply(transp, (xdrproc_t)xdr_spraycumul, &scum)) {
157
svcerr_systemerr(transp);
158
syslog(LOG_WARNING, "bad svc_sendreply");
159
}
160
}
161
162