xref: /freebsd/usr.sbin/inetd/inetd.c (revision 5b31cc94b10d4bb7109c6b27940a0fc76a44a331)
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1983, 1991, 1993, 1994
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __COPYRIGHT("@(#) Copyright (c) 1983, 1991, 1993, 1994\n\
35 	The Regents of the University of California.  All rights reserved.\n");
36 #endif /* not lint */
37 
38 #ifndef lint
39 #endif /* not lint */
40 
41 /*
42  * Inetd - Internet super-server
43  *
44  * This program invokes all internet services as needed.  Connection-oriented
45  * services are invoked each time a connection is made, by creating a process.
46  * This process is passed the connection as file descriptor 0 and is expected
47  * to do a getpeername to find out the source host and port.
48  *
49  * Datagram oriented services are invoked when a datagram
50  * arrives; a process is created and passed a pending message
51  * on file descriptor 0.  Datagram servers may either connect
52  * to their peer, freeing up the original socket for inetd
53  * to receive further messages on, or ``take over the socket'',
54  * processing all arriving datagrams and, eventually, timing
55  * out.	 The first type of server is said to be ``multi-threaded'';
56  * the second type of server ``single-threaded''.
57  *
58  * Inetd uses a configuration file which is read at startup
59  * and, possibly, at some later time in response to a hangup signal.
60  * The configuration file is ``free format'' with fields given in the
61  * order shown below.  Continuation lines for an entry must begin with
62  * a space or tab.  All fields must be present in each entry.
63  *
64  *	service name			must be in /etc/services
65  *					or name a tcpmux service
66  *					or specify a unix domain socket
67  *	socket type			stream/dgram/raw/rdm/seqpacket
68  *	protocol			tcp[4][6], udp[4][6], unix
69  *	wait/nowait			single-threaded/multi-threaded
70  *	user[:group][/login-class]	user/group/login-class to run daemon as
71  *	server program			full path name
72  *	server program arguments	maximum of MAXARGS (20)
73  *
74  * TCP services without official port numbers are handled with the
75  * RFC1078-based tcpmux internal service. Tcpmux listens on port 1 for
76  * requests. When a connection is made from a foreign host, the service
77  * requested is passed to tcpmux, which looks it up in the servtab list
78  * and returns the proper entry for the service. Tcpmux returns a
79  * negative reply if the service doesn't exist, otherwise the invoked
80  * server is expected to return the positive reply if the service type in
81  * inetd.conf file has the prefix "tcpmux/". If the service type has the
82  * prefix "tcpmux/+", tcpmux will return the positive reply for the
83  * process; this is for compatibility with older server code, and also
84  * allows you to invoke programs that use stdin/stdout without putting any
85  * special server code in them. Services that use tcpmux are "nowait"
86  * because they do not have a well-known port and hence cannot listen
87  * for new requests.
88  *
89  * For RPC services
90  *	service name/version		must be in /etc/rpc
91  *	socket type			stream/dgram/raw/rdm/seqpacket
92  *	protocol			rpc/tcp[4][6], rpc/udp[4][6]
93  *	wait/nowait			single-threaded/multi-threaded
94  *	user[:group][/login-class]	user/group/login-class to run daemon as
95  *	server program			full path name
96  *	server program arguments	maximum of MAXARGS
97  *
98  * Comment lines are indicated by a `#' in column 1.
99  *
100  * #ifdef IPSEC
101  * Comment lines that start with "#@" denote IPsec policy string, as described
102  * in ipsec_set_policy(3).  This will affect all the following items in
103  * inetd.conf(8).  To reset the policy, just use "#@" line.  By default,
104  * there's no IPsec policy.
105  * #endif
106  */
107 #include <sys/param.h>
108 #include <sys/ioctl.h>
109 #include <sys/mman.h>
110 #include <sys/wait.h>
111 #include <sys/time.h>
112 #include <sys/resource.h>
113 #include <sys/stat.h>
114 #include <sys/un.h>
115 
116 #include <netinet/in.h>
117 #include <netinet/tcp.h>
118 #include <arpa/inet.h>
119 #include <rpc/rpc.h>
120 #include <rpc/pmap_clnt.h>
121 
122 #include <ctype.h>
123 #include <errno.h>
124 #include <err.h>
125 #include <fcntl.h>
126 #include <grp.h>
127 #include <libutil.h>
128 #include <limits.h>
129 #include <netdb.h>
130 #include <pwd.h>
131 #include <signal.h>
132 #include <stdio.h>
133 #include <stdlib.h>
134 #include <string.h>
135 #include <sysexits.h>
136 #include <syslog.h>
137 #ifdef LIBWRAP
138 #include <tcpd.h>
139 #endif
140 #include <unistd.h>
141 
142 #include "inetd.h"
143 #include "pathnames.h"
144 
145 #ifdef IPSEC
146 #include <netipsec/ipsec.h>
147 #ifndef IPSEC_POLICY_IPSEC	/* no ipsec support on old ipsec */
148 #undef IPSEC
149 #endif
150 #endif
151 
152 #ifndef LIBWRAP_ALLOW_FACILITY
153 # define LIBWRAP_ALLOW_FACILITY LOG_AUTH
154 #endif
155 #ifndef LIBWRAP_ALLOW_SEVERITY
156 # define LIBWRAP_ALLOW_SEVERITY LOG_INFO
157 #endif
158 #ifndef LIBWRAP_DENY_FACILITY
159 # define LIBWRAP_DENY_FACILITY LOG_AUTH
160 #endif
161 #ifndef LIBWRAP_DENY_SEVERITY
162 # define LIBWRAP_DENY_SEVERITY LOG_WARNING
163 #endif
164 
165 #define ISWRAP(sep)	\
166 	   ( ((wrap_ex && !(sep)->se_bi) || (wrap_bi && (sep)->se_bi)) \
167 	&& (sep->se_family == AF_INET || sep->se_family == AF_INET6) \
168 	&& ( ((sep)->se_accept && (sep)->se_socktype == SOCK_STREAM) \
169 	    || (sep)->se_socktype == SOCK_DGRAM))
170 
171 #ifdef LOGIN_CAP
172 #include <login_cap.h>
173 
174 /* see init.c */
175 #define RESOURCE_RC "daemon"
176 
177 #endif
178 
179 #ifndef	MAXCHILD
180 #define	MAXCHILD	-1		/* maximum number of this service
181 					   < 0 = no limit */
182 #endif
183 
184 #ifndef	MAXCPM
185 #define	MAXCPM		-1		/* rate limit invocations from a
186 					   single remote address,
187 					   < 0 = no limit */
188 #endif
189 
190 #ifndef	MAXPERIP
191 #define	MAXPERIP	-1		/* maximum number of this service
192 					   from a single remote address,
193 					   < 0 = no limit */
194 #endif
195 
196 #ifndef TOOMANY
197 #define	TOOMANY		256		/* don't start more than TOOMANY */
198 #endif
199 #define	CNT_INTVL	60		/* servers in CNT_INTVL sec. */
200 #define	RETRYTIME	(60*10)		/* retry after bind or server fail */
201 #define MAX_MAXCHLD	32767		/* max allowable max children */
202 
203 #define	SIGBLOCK	(sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM))
204 
205 #define	satosin(sa)	((struct sockaddr_in *)(void *)sa)
206 #define	csatosin(sa)	((const struct sockaddr_in *)(const void *)sa)
207 #ifdef INET6
208 #define	satosin6(sa)	((struct sockaddr_in6 *)(void *)sa)
209 #define	csatosin6(sa)	((const struct sockaddr_in6 *)(const void *)sa)
210 #endif
211 static void	close_sep(struct servtab *);
212 static void	flag_signal(int);
213 static void	config(void);
214 static int	cpmip(const struct servtab *, int);
215 static void	endconfig(void);
216 static struct servtab *enter(struct servtab *);
217 static void	freeconfig(struct servtab *);
218 static struct servtab *getconfigent(void);
219 static int	matchservent(const char *, const char *, const char *);
220 static char	*nextline(FILE *);
221 static void	addchild(struct servtab *, int);
222 static void	reapchild(void);
223 static void	enable(struct servtab *);
224 static void	disable(struct servtab *);
225 static void	retry(void);
226 static int	setconfig(void);
227 static void	setup(struct servtab *);
228 #ifdef IPSEC
229 static void	ipsecsetup(struct servtab *);
230 #endif
231 static void	unregisterrpc(register struct servtab *sep);
232 static struct conninfo *search_conn(struct servtab *sep, int ctrl);
233 static int	room_conn(struct servtab *sep, struct conninfo *conn);
234 static void	addchild_conn(struct conninfo *conn, pid_t pid);
235 static void	reapchild_conn(pid_t pid);
236 static void	free_conn(struct conninfo *conn);
237 static void	resize_conn(struct servtab *sep, int maxperip);
238 static void	free_connlist(struct servtab *sep);
239 static void	free_proc(struct procinfo *);
240 static struct procinfo *search_proc(pid_t pid, int add);
241 static int	hashval(char *p, int len);
242 static char	*skip(char **);
243 static char	*sskip(char **);
244 static char	*newstr(const char *);
245 static void	print_service(const char *, const struct servtab *);
246 
247 #ifdef LIBWRAP
248 /* tcpd.h */
249 int	allow_severity;
250 int	deny_severity;
251 #endif
252 
253 static int	wrap_ex = 0;
254 static int	wrap_bi = 0;
255 int	debug = 0;
256 static int	dolog = 0;
257 static int	maxsock;		/* highest-numbered descriptor */
258 static fd_set	allsock;
259 static int	options;
260 static int	timingout;
261 static int	toomany = TOOMANY;
262 static int	maxchild = MAXCHILD;
263 static int	maxcpm = MAXCPM;
264 static int	maxperip = MAXPERIP;
265 static struct	servent *sp;
266 static struct	rpcent *rpc;
267 static char	*hostname = NULL;
268 static struct	sockaddr_in *bind_sa4;
269 static int	v4bind_ok = 0;
270 #ifdef INET6
271 static struct	sockaddr_in6 *bind_sa6;
272 static int	v6bind_ok = 0;
273 #endif
274 static int	signalpipe[2];
275 #ifdef SANITY_CHECK
276 static int	nsock;
277 #endif
278 static uid_t	euid;
279 static gid_t	egid;
280 static mode_t	mask;
281 
282 struct servtab *servtab;
283 
284 static const char	*CONFIG = _PATH_INETDCONF;
285 static const char	*pid_file = _PATH_INETDPID;
286 static struct pidfh	*pfh = NULL;
287 
288 static struct netconfig *udpconf, *tcpconf, *udp6conf, *tcp6conf;
289 
290 static LIST_HEAD(, procinfo) proctable[PERIPSIZE];
291 
292 static int
293 getvalue(const char *arg, int *value, const char *whine)
294 {
295 	int  tmp;
296 	char *p;
297 
298 	tmp = strtol(arg, &p, 0);
299 	if (tmp < 0 || *p) {
300 		syslog(LOG_ERR, whine, arg);
301 		return 1;			/* failure */
302 	}
303 	*value = tmp;
304 	return 0;				/* success */
305 }
306 
307 #ifdef LIBWRAP
308 static sa_family_t
309 whichaf(struct request_info *req)
310 {
311 	struct sockaddr *sa;
312 
313 	sa = (struct sockaddr *)req->client->sin;
314 	if (sa == NULL)
315 		return AF_UNSPEC;
316 #ifdef INET6
317 	if (sa->sa_family == AF_INET6 &&
318 	    IN6_IS_ADDR_V4MAPPED(&satosin6(sa)->sin6_addr))
319 		return AF_INET;
320 #endif
321 	return sa->sa_family;
322 }
323 #endif
324 
325 int
326 main(int argc, char **argv)
327 {
328 	struct servtab *sep;
329 	struct passwd *pwd;
330 	struct group *grp;
331 	struct sigaction sa, saalrm, sachld, sahup, sapipe;
332 	int ch, dofork;
333 	pid_t pid;
334 	char buf[50];
335 #ifdef LOGIN_CAP
336 	login_cap_t *lc = NULL;
337 #endif
338 #ifdef LIBWRAP
339 	struct request_info req;
340 	int denied;
341 	char *service = NULL;
342 #endif
343 	struct sockaddr_storage peer;
344 	int i;
345 	struct addrinfo hints, *res;
346 	const char *servname;
347 	int error;
348 	struct conninfo *conn;
349 
350 	openlog("inetd", LOG_PID | LOG_NOWAIT | LOG_PERROR, LOG_DAEMON);
351 
352 	while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:s:")) != -1)
353 		switch(ch) {
354 		case 'd':
355 			debug = 1;
356 			options |= SO_DEBUG;
357 			break;
358 		case 'l':
359 			dolog = 1;
360 			break;
361 		case 'R':
362 			getvalue(optarg, &toomany,
363 				"-R %s: bad value for service invocation rate");
364 			break;
365 		case 'c':
366 			getvalue(optarg, &maxchild,
367 				"-c %s: bad value for maximum children");
368 			break;
369 		case 'C':
370 			getvalue(optarg, &maxcpm,
371 				"-C %s: bad value for maximum children/minute");
372 			break;
373 		case 'a':
374 			hostname = optarg;
375 			break;
376 		case 'p':
377 			pid_file = optarg;
378 			break;
379 		case 's':
380 			getvalue(optarg, &maxperip,
381 				"-s %s: bad value for maximum children per source address");
382 			break;
383 		case 'w':
384 			wrap_ex++;
385 			break;
386 		case 'W':
387 			wrap_bi++;
388 			break;
389 		case '?':
390 		default:
391 			syslog(LOG_ERR,
392 				"usage: inetd [-dlWw] [-a address] [-C rate]"
393 				" [-c maximum] [-p filename] [-R rate]"
394 				" [-s maximum] [configuration_file]");
395 			exit(EX_USAGE);
396 		}
397 	/*
398 	 * Initialize Bind Addrs.
399 	 *   When hostname is NULL, wild card bind addrs are obtained from
400 	 *   getaddrinfo(). But getaddrinfo() requires at least one of
401 	 *   hostname or servname is non NULL.
402 	 *   So when hostname is NULL, set dummy value to servname.
403 	 *   Since getaddrinfo() doesn't accept numeric servname, and
404 	 *   we doesn't use ai_socktype of struct addrinfo returned
405 	 *   from getaddrinfo(), we set dummy value to ai_socktype.
406 	 */
407 	servname = (hostname == NULL) ? "0" /* dummy */ : NULL;
408 
409 	memset(&hints, 0, sizeof(struct addrinfo));
410 	hints.ai_flags = AI_PASSIVE;
411 	hints.ai_family = AF_UNSPEC;
412 	hints.ai_socktype = SOCK_STREAM;	/* dummy */
413 	error = getaddrinfo(hostname, servname, &hints, &res);
414 	if (error != 0) {
415 		syslog(LOG_ERR, "-a %s: %s", hostname, gai_strerror(error));
416 		if (error == EAI_SYSTEM)
417 			syslog(LOG_ERR, "%s", strerror(errno));
418 		exit(EX_USAGE);
419 	}
420 	do {
421 		if (res->ai_addr == NULL) {
422 			syslog(LOG_ERR, "-a %s: getaddrinfo failed", hostname);
423 			exit(EX_USAGE);
424 		}
425 		switch (res->ai_addr->sa_family) {
426 		case AF_INET:
427 			if (v4bind_ok)
428 				continue;
429 			bind_sa4 = satosin(res->ai_addr);
430 			/* init port num in case servname is dummy */
431 			bind_sa4->sin_port = 0;
432 			v4bind_ok = 1;
433 			continue;
434 #ifdef INET6
435 		case AF_INET6:
436 			if (v6bind_ok)
437 				continue;
438 			bind_sa6 = satosin6(res->ai_addr);
439 			/* init port num in case servname is dummy */
440 			bind_sa6->sin6_port = 0;
441 			v6bind_ok = 1;
442 			continue;
443 #endif
444 		}
445 		if (v4bind_ok
446 #ifdef INET6
447 		    && v6bind_ok
448 #endif
449 		    )
450 			break;
451 	} while ((res = res->ai_next) != NULL);
452 	if (!v4bind_ok
453 #ifdef INET6
454 	    && !v6bind_ok
455 #endif
456 	    ) {
457 		syslog(LOG_ERR, "-a %s: unknown address family", hostname);
458 		exit(EX_USAGE);
459 	}
460 
461 	euid = geteuid();
462 	egid = getegid();
463 	umask(mask = umask(0777));
464 
465 	argc -= optind;
466 	argv += optind;
467 
468 	if (argc > 0)
469 		CONFIG = argv[0];
470 	if (access(CONFIG, R_OK) < 0)
471 		syslog(LOG_ERR, "Accessing %s: %m, continuing anyway.", CONFIG);
472 	if (debug == 0) {
473 		pid_t otherpid;
474 
475 		pfh = pidfile_open(pid_file, 0600, &otherpid);
476 		if (pfh == NULL) {
477 			if (errno == EEXIST) {
478 				syslog(LOG_ERR, "%s already running, pid: %d",
479 				    getprogname(), otherpid);
480 				exit(EX_OSERR);
481 			}
482 			syslog(LOG_WARNING, "pidfile_open() failed: %m");
483 		}
484 
485 		if (daemon(0, 0) < 0) {
486 			syslog(LOG_WARNING, "daemon(0,0) failed: %m");
487 		}
488 		/* From now on we don't want syslog messages going to stderr. */
489 		closelog();
490 		openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
491 		/*
492 		 * In case somebody has started inetd manually, we need to
493 		 * clear the logname, so that old servers run as root do not
494 		 * get the user's logname..
495 		 */
496 		if (setlogin("") < 0) {
497 			syslog(LOG_WARNING, "cannot clear logname: %m");
498 			/* no big deal if it fails.. */
499 		}
500 		if (pfh != NULL && pidfile_write(pfh) == -1) {
501 			syslog(LOG_WARNING, "pidfile_write(): %m");
502 		}
503 	}
504 
505 	if (madvise(NULL, 0, MADV_PROTECT) != 0)
506 		syslog(LOG_WARNING, "madvise() failed: %s", strerror(errno));
507 
508 	for (i = 0; i < PERIPSIZE; ++i)
509 		LIST_INIT(&proctable[i]);
510 
511 	if (v4bind_ok) {
512 		udpconf = getnetconfigent("udp");
513 		tcpconf = getnetconfigent("tcp");
514 		if (udpconf == NULL || tcpconf == NULL) {
515 			syslog(LOG_ERR, "unknown rpc/udp or rpc/tcp");
516 			exit(EX_USAGE);
517 		}
518 	}
519 #ifdef INET6
520 	if (v6bind_ok) {
521 		udp6conf = getnetconfigent("udp6");
522 		tcp6conf = getnetconfigent("tcp6");
523 		if (udp6conf == NULL || tcp6conf == NULL) {
524 			syslog(LOG_ERR, "unknown rpc/udp6 or rpc/tcp6");
525 			exit(EX_USAGE);
526 		}
527 	}
528 #endif
529 
530 	sa = (struct sigaction){
531 	    .sa_flags = 0,
532 	    .sa_handler = flag_signal,
533 	};
534 	sigemptyset(&sa.sa_mask);
535 	sigaddset(&sa.sa_mask, SIGALRM);
536 	sigaddset(&sa.sa_mask, SIGCHLD);
537 	sigaddset(&sa.sa_mask, SIGHUP);
538 	sigaction(SIGALRM, &sa, &saalrm);
539 	config();
540 	sigaction(SIGHUP, &sa, &sahup);
541 	sigaction(SIGCHLD, &sa, &sachld);
542 	sa.sa_handler = SIG_IGN;
543 	sigaction(SIGPIPE, &sa, &sapipe);
544 
545 	{
546 		/* space for daemons to overwrite environment for ps */
547 #define	DUMMYSIZE	100
548 		char dummy[DUMMYSIZE];
549 
550 		(void)memset(dummy, 'x', DUMMYSIZE - 1);
551 		dummy[DUMMYSIZE - 1] = '\0';
552 		(void)setenv("inetd_dummy", dummy, 1);
553 	}
554 
555 	if (pipe2(signalpipe, O_CLOEXEC) != 0) {
556 		syslog(LOG_ERR, "pipe: %m");
557 		exit(EX_OSERR);
558 	}
559 	FD_SET(signalpipe[0], &allsock);
560 #ifdef SANITY_CHECK
561 	nsock++;
562 #endif
563 	maxsock = MAX(MAX(maxsock, signalpipe[0]), signalpipe[1]);
564 
565 	for (;;) {
566 	    int n, ctrl;
567 	    fd_set readable;
568 
569 #ifdef SANITY_CHECK
570 	    if (nsock == 0) {
571 		syslog(LOG_ERR, "%s: nsock=0", __func__);
572 		exit(EX_SOFTWARE);
573 	    }
574 #endif
575 	    readable = allsock;
576 	    if ((n = select(maxsock + 1, &readable, (fd_set *)0,
577 		(fd_set *)0, (struct timeval *)0)) <= 0) {
578 		    if (n < 0 && errno != EINTR) {
579 			syslog(LOG_WARNING, "select: %m");
580 			sleep(1);
581 		    }
582 		    continue;
583 	    }
584 	    /* handle any queued signal flags */
585 	    if (FD_ISSET(signalpipe[0], &readable)) {
586 		int nsig, signo;
587 
588 		if (ioctl(signalpipe[0], FIONREAD, &nsig) != 0) {
589 			syslog(LOG_ERR, "ioctl: %m");
590 			exit(EX_OSERR);
591 		}
592 		nsig /= sizeof(signo);
593 		while (--nsig >= 0) {
594 			size_t len;
595 
596 			len = read(signalpipe[0], &signo, sizeof(signo));
597 			if (len != sizeof(signo)) {
598 				syslog(LOG_ERR, "read: %m");
599 				exit(EX_OSERR);
600 			}
601 			if (debug)
602 				warnx("handling signal flag %d", signo);
603 			switch (signo) {
604 			case SIGALRM:
605 				retry();
606 				break;
607 			case SIGCHLD:
608 				reapchild();
609 				break;
610 			case SIGHUP:
611 				config();
612 				break;
613 			}
614 		}
615 	    }
616 	    for (sep = servtab; n && sep; sep = sep->se_next)
617 	        if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) {
618 		    n--;
619 		    if (debug)
620 			    warnx("someone wants %s", sep->se_service);
621 		    dofork = !sep->se_bi || sep->se_bi->bi_fork || ISWRAP(sep);
622 		    conn = NULL;
623 		    if (sep->se_accept && sep->se_socktype == SOCK_STREAM) {
624 			    i = 1;
625 			    if (ioctl(sep->se_fd, FIONBIO, &i) < 0)
626 				    syslog(LOG_ERR, "ioctl (FIONBIO, 1): %m");
627 			    ctrl = accept(sep->se_fd, (struct sockaddr *)0,
628 				(socklen_t *)0);
629 			    if (debug)
630 				    warnx("accept, ctrl %d", ctrl);
631 			    if (ctrl < 0) {
632 				    if (errno != EINTR)
633 					    syslog(LOG_WARNING,
634 						"accept (for %s): %m",
635 						sep->se_service);
636                                       if (sep->se_accept &&
637                                           sep->se_socktype == SOCK_STREAM)
638                                               close(ctrl);
639 				    continue;
640 			    }
641 			    i = 0;
642 			    if (ioctl(sep->se_fd, FIONBIO, &i) < 0)
643 				    syslog(LOG_ERR, "ioctl1(FIONBIO, 0): %m");
644 			    if (ioctl(ctrl, FIONBIO, &i) < 0)
645 				    syslog(LOG_ERR, "ioctl2(FIONBIO, 0): %m");
646 			    if (cpmip(sep, ctrl) < 0) {
647 				close(ctrl);
648 				continue;
649 			    }
650 			    if (dofork &&
651 				(conn = search_conn(sep, ctrl)) != NULL &&
652 				!room_conn(sep, conn)) {
653 				close(ctrl);
654 				continue;
655 			    }
656 		    } else
657 			    ctrl = sep->se_fd;
658 		    if (dolog && !ISWRAP(sep)) {
659 			    char pname[NI_MAXHOST] = "unknown";
660 			    socklen_t sl;
661 			    sl = sizeof(peer);
662 			    if (getpeername(ctrl, (struct sockaddr *)
663 					    &peer, &sl)) {
664 				    sl = sizeof(peer);
665 				    if (recvfrom(ctrl, buf, sizeof(buf),
666 					MSG_PEEK,
667 					(struct sockaddr *)&peer,
668 					&sl) >= 0) {
669 				      getnameinfo((struct sockaddr *)&peer,
670 						  peer.ss_len,
671 						  pname, sizeof(pname),
672 						  NULL, 0, NI_NUMERICHOST);
673 				    }
674 			    } else {
675 			            getnameinfo((struct sockaddr *)&peer,
676 						peer.ss_len,
677 						pname, sizeof(pname),
678 						NULL, 0, NI_NUMERICHOST);
679 			    }
680 			    syslog(LOG_INFO,"%s from %s", sep->se_service, pname);
681 		    }
682 		    (void) sigblock(SIGBLOCK);
683 		    pid = 0;
684 		    /*
685 		     * Fork for all external services, builtins which need to
686 		     * fork and anything we're wrapping (as wrapping might
687 		     * block or use hosts_options(5) twist).
688 		     */
689 		    if (dofork) {
690 			    if (sep->se_count++ == 0)
691 				(void)clock_gettime(CLOCK_MONOTONIC_FAST, &sep->se_time);
692 			    else if (toomany > 0 && sep->se_count >= toomany) {
693 				struct timespec now;
694 
695 				(void)clock_gettime(CLOCK_MONOTONIC_FAST, &now);
696 				if (now.tv_sec - sep->se_time.tv_sec >
697 				    CNT_INTVL) {
698 					sep->se_time = now;
699 					sep->se_count = 1;
700 				} else {
701 					syslog(LOG_ERR,
702 			"%s/%s server failing (looping), service terminated",
703 					    sep->se_service, sep->se_proto);
704 					if (sep->se_accept &&
705 					    sep->se_socktype == SOCK_STREAM)
706 						close(ctrl);
707 					close_sep(sep);
708 					free_conn(conn);
709 					sigsetmask(0L);
710 					if (!timingout) {
711 						timingout = 1;
712 						alarm(RETRYTIME);
713 					}
714 					continue;
715 				}
716 			    }
717 			    pid = fork();
718 		    }
719 		    if (pid < 0) {
720 			    syslog(LOG_ERR, "fork: %m");
721 			    if (sep->se_accept &&
722 				sep->se_socktype == SOCK_STREAM)
723 				    close(ctrl);
724 			    free_conn(conn);
725 			    sigsetmask(0L);
726 			    sleep(1);
727 			    continue;
728 		    }
729 		    if (pid) {
730 			addchild_conn(conn, pid);
731 			addchild(sep, pid);
732 		    }
733 		    sigsetmask(0L);
734 		    if (pid == 0) {
735 			    pidfile_close(pfh);
736 			    if (dofork) {
737 				sigaction(SIGALRM, &saalrm, (struct sigaction *)0);
738 				sigaction(SIGCHLD, &sachld, (struct sigaction *)0);
739 				sigaction(SIGHUP, &sahup, (struct sigaction *)0);
740 				/* SIGPIPE reset before exec */
741 			    }
742 			    /*
743 			     * Call tcpmux to find the real service to exec.
744 			     */
745 			    if (sep->se_bi &&
746 				sep->se_bi->bi_fn == (bi_fn_t *) tcpmux) {
747 				    sep = tcpmux(ctrl);
748 				    if (sep == NULL) {
749 					    close(ctrl);
750 					    _exit(0);
751 				    }
752 			    }
753 #ifdef LIBWRAP
754 			    if (ISWRAP(sep)) {
755 				inetd_setproctitle("wrapping", ctrl);
756 				service = sep->se_server_name ?
757 				    sep->se_server_name : sep->se_service;
758 				request_init(&req, RQ_DAEMON, service, RQ_FILE, ctrl, 0);
759 				fromhost(&req);
760 				deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY;
761 				allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY;
762 				denied = !hosts_access(&req);
763 				if (denied) {
764 				    syslog(deny_severity,
765 				        "refused connection from %.500s, service %s (%s%s)",
766 				        eval_client(&req), service, sep->se_proto,
767 					(whichaf(&req) == AF_INET6) ? "6" : "");
768 				    if (sep->se_socktype != SOCK_STREAM)
769 					recv(ctrl, buf, sizeof (buf), 0);
770 				    if (dofork) {
771 					sleep(1);
772 					_exit(0);
773 				    }
774 				}
775 				if (dolog) {
776 				    syslog(allow_severity,
777 				        "connection from %.500s, service %s (%s%s)",
778 					eval_client(&req), service, sep->se_proto,
779 					(whichaf(&req) == AF_INET6) ? "6" : "");
780 				}
781 			    }
782 #endif
783 			    if (sep->se_bi) {
784 				(*sep->se_bi->bi_fn)(ctrl, sep);
785 			    } else {
786 				if (debug)
787 					warnx("%d execl %s",
788 						getpid(), sep->se_server);
789 				/* Clear close-on-exec. */
790 				if (fcntl(ctrl, F_SETFD, 0) < 0) {
791 					syslog(LOG_ERR,
792 					    "%s/%s: fcntl (F_SETFD, 0): %m",
793 						sep->se_service, sep->se_proto);
794 					_exit(EX_OSERR);
795 				}
796 				if (ctrl != 0) {
797 					dup2(ctrl, 0);
798 					close(ctrl);
799 				}
800 				dup2(0, 1);
801 				dup2(0, 2);
802 				if ((pwd = getpwnam(sep->se_user)) == NULL) {
803 					syslog(LOG_ERR,
804 					    "%s/%s: %s: no such user",
805 						sep->se_service, sep->se_proto,
806 						sep->se_user);
807 					if (sep->se_socktype != SOCK_STREAM)
808 						recv(0, buf, sizeof (buf), 0);
809 					_exit(EX_NOUSER);
810 				}
811 				grp = NULL;
812 				if (   sep->se_group != NULL
813 				    && (grp = getgrnam(sep->se_group)) == NULL
814 				   ) {
815 					syslog(LOG_ERR,
816 					    "%s/%s: %s: no such group",
817 						sep->se_service, sep->se_proto,
818 						sep->se_group);
819 					if (sep->se_socktype != SOCK_STREAM)
820 						recv(0, buf, sizeof (buf), 0);
821 					_exit(EX_NOUSER);
822 				}
823 				if (grp != NULL)
824 					pwd->pw_gid = grp->gr_gid;
825 #ifdef LOGIN_CAP
826 				if ((lc = login_getclass(sep->se_class)) == NULL) {
827 					/* error syslogged by getclass */
828 					syslog(LOG_ERR,
829 					    "%s/%s: %s: login class error",
830 						sep->se_service, sep->se_proto,
831 						sep->se_class);
832 					if (sep->se_socktype != SOCK_STREAM)
833 						recv(0, buf, sizeof (buf), 0);
834 					_exit(EX_NOUSER);
835 				}
836 #endif
837 				if (setsid() < 0) {
838 					syslog(LOG_ERR,
839 						"%s: can't setsid(): %m",
840 						 sep->se_service);
841 					/* _exit(EX_OSERR); not fatal yet */
842 				}
843 #ifdef LOGIN_CAP
844 				if (setusercontext(lc, pwd, pwd->pw_uid,
845 				    LOGIN_SETALL & ~LOGIN_SETMAC)
846 				    != 0) {
847 					syslog(LOG_ERR,
848 					 "%s: can't setusercontext(..%s..): %m",
849 					 sep->se_service, sep->se_user);
850 					_exit(EX_OSERR);
851 				}
852 				login_close(lc);
853 #else
854 				if (pwd->pw_uid) {
855 					if (setlogin(sep->se_user) < 0) {
856 						syslog(LOG_ERR,
857 						 "%s: can't setlogin(%s): %m",
858 						 sep->se_service, sep->se_user);
859 						/* _exit(EX_OSERR); not yet */
860 					}
861 					if (setgid(pwd->pw_gid) < 0) {
862 						syslog(LOG_ERR,
863 						  "%s: can't set gid %d: %m",
864 						  sep->se_service, pwd->pw_gid);
865 						_exit(EX_OSERR);
866 					}
867 					(void) initgroups(pwd->pw_name,
868 							pwd->pw_gid);
869 					if (setuid(pwd->pw_uid) < 0) {
870 						syslog(LOG_ERR,
871 						  "%s: can't set uid %d: %m",
872 						  sep->se_service, pwd->pw_uid);
873 						_exit(EX_OSERR);
874 					}
875 				}
876 #endif
877 				sigaction(SIGPIPE, &sapipe,
878 				    (struct sigaction *)0);
879 				execv(sep->se_server, sep->se_argv);
880 				syslog(LOG_ERR,
881 				    "cannot execute %s: %m", sep->se_server);
882 				if (sep->se_socktype != SOCK_STREAM)
883 					recv(0, buf, sizeof (buf), 0);
884 			    }
885 			    if (dofork)
886 				_exit(0);
887 		    }
888 		    if (sep->se_accept && sep->se_socktype == SOCK_STREAM)
889 			    close(ctrl);
890 		}
891 	}
892 }
893 
894 /*
895  * Add a signal flag to the signal flag queue for later handling
896  */
897 
898 static void
899 flag_signal(int signo)
900 {
901 	size_t len;
902 
903 	len = write(signalpipe[1], &signo, sizeof(signo));
904 	if (len != sizeof(signo)) {
905 		syslog(LOG_ERR, "write: %m");
906 		_exit(EX_OSERR);
907 	}
908 }
909 
910 /*
911  * Record a new child pid for this service. If we've reached the
912  * limit on children, then stop accepting incoming requests.
913  */
914 
915 static void
916 addchild(struct servtab *sep, pid_t pid)
917 {
918 	struct stabchild *sc;
919 
920 #ifdef SANITY_CHECK
921 	if (SERVTAB_EXCEEDS_LIMIT(sep)) {
922 		syslog(LOG_ERR, "%s: %d >= %d",
923 		    __func__, sep->se_numchild, sep->se_maxchild);
924 		exit(EX_SOFTWARE);
925 	}
926 #endif
927 	sc = calloc(1, sizeof(*sc));
928 	if (sc == NULL) {
929 		syslog(LOG_ERR, "calloc: %m");
930 		exit(EX_OSERR);
931 	}
932 	sc->sc_pid = pid;
933 	LIST_INSERT_HEAD(&sep->se_children, sc, sc_link);
934 	++sep->se_numchild;
935 	if (SERVTAB_AT_LIMIT(sep))
936 		disable(sep);
937 }
938 
939 static void
940 reapchild(void)
941 {
942 	int status;
943 	pid_t pid;
944 	struct stabchild *sc;
945 	struct servtab *sep;
946 
947 	for (;;) {
948 		pid = wait3(&status, WNOHANG, (struct rusage *)0);
949 		if (pid <= 0)
950 			break;
951 		if (debug)
952 			warnx("%d reaped, %s %u", pid,
953 			    WIFEXITED(status) ? "status" : "signal",
954 			    WIFEXITED(status) ? WEXITSTATUS(status)
955 				: WTERMSIG(status));
956 		for (sep = servtab; sep; sep = sep->se_next) {
957 			LIST_FOREACH(sc, &sep->se_children, sc_link) {
958 				if (sc->sc_pid == pid)
959 					break;
960 			}
961 			if (sc == NULL)
962 				continue;
963 			if (SERVTAB_AT_LIMIT(sep))
964 				enable(sep);
965 			LIST_REMOVE(sc, sc_link);
966 			free(sc);
967 			--sep->se_numchild;
968 			if (WIFSIGNALED(status) || WEXITSTATUS(status))
969 				syslog(LOG_WARNING,
970 				    "%s[%d]: exited, %s %u",
971 				    sep->se_server, pid,
972 				    WIFEXITED(status) ? "status" : "signal",
973 				    WIFEXITED(status) ? WEXITSTATUS(status)
974 					: WTERMSIG(status));
975 			break;
976 		}
977 		reapchild_conn(pid);
978 	}
979 }
980 
981 static void
982 config(void)
983 {
984 	struct servtab *sep, *new, **sepp;
985 	long omask;
986 	int new_nomapped;
987 #ifdef LOGIN_CAP
988 	login_cap_t *lc = NULL;
989 #endif
990 
991 	if (!setconfig()) {
992 		syslog(LOG_ERR, "%s: %m", CONFIG);
993 		return;
994 	}
995 	for (sep = servtab; sep; sep = sep->se_next)
996 		sep->se_checked = 0;
997 	while ((new = getconfigent())) {
998 		if (getpwnam(new->se_user) == NULL) {
999 			syslog(LOG_ERR,
1000 				"%s/%s: no such user '%s', service ignored",
1001 				new->se_service, new->se_proto, new->se_user);
1002 			continue;
1003 		}
1004 		if (new->se_group && getgrnam(new->se_group) == NULL) {
1005 			syslog(LOG_ERR,
1006 				"%s/%s: no such group '%s', service ignored",
1007 				new->se_service, new->se_proto, new->se_group);
1008 			continue;
1009 		}
1010 #ifdef LOGIN_CAP
1011 		if ((lc = login_getclass(new->se_class)) == NULL) {
1012 			/* error syslogged by getclass */
1013 			syslog(LOG_ERR,
1014 				"%s/%s: %s: login class error, service ignored",
1015 				new->se_service, new->se_proto, new->se_class);
1016 			continue;
1017 		}
1018 		login_close(lc);
1019 #endif
1020 		new_nomapped = new->se_nomapped;
1021 		for (sep = servtab; sep; sep = sep->se_next)
1022 			if (strcmp(sep->se_service, new->se_service) == 0 &&
1023 			    strcmp(sep->se_proto, new->se_proto) == 0 &&
1024 			    sep->se_rpc == new->se_rpc &&
1025 			    sep->se_socktype == new->se_socktype &&
1026 			    sep->se_family == new->se_family)
1027 				break;
1028 		if (sep != 0) {
1029 			int i;
1030 
1031 #define SWAP(t,a, b) { t c = a; a = b; b = c; }
1032 			omask = sigblock(SIGBLOCK);
1033 			if (sep->se_nomapped != new->se_nomapped) {
1034 				/* for rpc keep old nommaped till unregister */
1035 				if (!sep->se_rpc)
1036 					sep->se_nomapped = new->se_nomapped;
1037 				sep->se_reset = 1;
1038 			}
1039 
1040 			/*
1041 			 * The children tracked remain; we want numchild to
1042 			 * still reflect how many jobs are running so we don't
1043 			 * throw off our accounting.
1044 			 */
1045 			sep->se_maxcpm = new->se_maxcpm;
1046 			sep->se_maxchild = new->se_maxchild;
1047 			resize_conn(sep, new->se_maxperip);
1048 			sep->se_maxperip = new->se_maxperip;
1049 			sep->se_bi = new->se_bi;
1050 			/* might need to turn on or off service now */
1051 			if (sep->se_fd >= 0) {
1052 			      if (SERVTAB_EXCEEDS_LIMIT(sep)) {
1053 				      if (FD_ISSET(sep->se_fd, &allsock))
1054 					  disable(sep);
1055 			      } else {
1056 				      if (!FD_ISSET(sep->se_fd, &allsock))
1057 					  enable(sep);
1058 			      }
1059 			}
1060 			sep->se_accept = new->se_accept;
1061 			SWAP(char *, sep->se_user, new->se_user);
1062 			SWAP(char *, sep->se_group, new->se_group);
1063 #ifdef LOGIN_CAP
1064 			SWAP(char *, sep->se_class, new->se_class);
1065 #endif
1066 			SWAP(char *, sep->se_server, new->se_server);
1067 			SWAP(char *, sep->se_server_name, new->se_server_name);
1068 			for (i = 0; i < MAXARGV; i++)
1069 				SWAP(char *, sep->se_argv[i], new->se_argv[i]);
1070 #ifdef IPSEC
1071 			SWAP(char *, sep->se_policy, new->se_policy);
1072 			ipsecsetup(sep);
1073 #endif
1074 			sigsetmask(omask);
1075 			freeconfig(new);
1076 			if (debug)
1077 				print_service("REDO", sep);
1078 		} else {
1079 			sep = enter(new);
1080 			if (debug)
1081 				print_service("ADD ", sep);
1082 		}
1083 		sep->se_checked = 1;
1084 		if (ISMUX(sep)) {
1085 			sep->se_fd = -1;
1086 			continue;
1087 		}
1088 		switch (sep->se_family) {
1089 		case AF_INET:
1090 			if (!v4bind_ok) {
1091 				sep->se_fd = -1;
1092 				continue;
1093 			}
1094 			break;
1095 #ifdef INET6
1096 		case AF_INET6:
1097 			if (!v6bind_ok) {
1098 				sep->se_fd = -1;
1099 				continue;
1100 			}
1101 			break;
1102 #endif
1103 		}
1104 		if (!sep->se_rpc) {
1105 			if (sep->se_family != AF_UNIX) {
1106 				sp = getservbyname(sep->se_service, sep->se_proto);
1107 				if (sp == 0) {
1108 					syslog(LOG_ERR, "%s/%s: unknown service",
1109 					sep->se_service, sep->se_proto);
1110 					sep->se_checked = 0;
1111 					continue;
1112 				}
1113 			}
1114 			switch (sep->se_family) {
1115 			case AF_INET:
1116 				if (sp->s_port != sep->se_ctrladdr4.sin_port) {
1117 					sep->se_ctrladdr4.sin_port =
1118 						sp->s_port;
1119 					sep->se_reset = 1;
1120 				}
1121 				break;
1122 #ifdef INET6
1123 			case AF_INET6:
1124 				if (sp->s_port !=
1125 				    sep->se_ctrladdr6.sin6_port) {
1126 					sep->se_ctrladdr6.sin6_port =
1127 						sp->s_port;
1128 					sep->se_reset = 1;
1129 				}
1130 				break;
1131 #endif
1132 			}
1133 			if (sep->se_reset != 0 && sep->se_fd >= 0)
1134 				close_sep(sep);
1135 		} else {
1136 			rpc = getrpcbyname(sep->se_service);
1137 			if (rpc == 0) {
1138 				syslog(LOG_ERR, "%s/%s unknown RPC service",
1139 					sep->se_service, sep->se_proto);
1140 				if (sep->se_fd != -1)
1141 					(void) close(sep->se_fd);
1142 				sep->se_fd = -1;
1143 					continue;
1144 			}
1145 			if (sep->se_reset != 0 ||
1146 			    rpc->r_number != sep->se_rpc_prog) {
1147 				if (sep->se_rpc_prog)
1148 					unregisterrpc(sep);
1149 				sep->se_rpc_prog = rpc->r_number;
1150 				if (sep->se_fd != -1)
1151 					(void) close(sep->se_fd);
1152 				sep->se_fd = -1;
1153 			}
1154 			sep->se_nomapped = new_nomapped;
1155 		}
1156 		sep->se_reset = 0;
1157 		if (sep->se_fd == -1)
1158 			setup(sep);
1159 	}
1160 	endconfig();
1161 	/*
1162 	 * Purge anything not looked at above.
1163 	 */
1164 	omask = sigblock(SIGBLOCK);
1165 	sepp = &servtab;
1166 	while ((sep = *sepp)) {
1167 		if (sep->se_checked) {
1168 			sepp = &sep->se_next;
1169 			continue;
1170 		}
1171 		*sepp = sep->se_next;
1172 		if (sep->se_fd >= 0)
1173 			close_sep(sep);
1174 		if (debug)
1175 			print_service("FREE", sep);
1176 		if (sep->se_rpc && sep->se_rpc_prog > 0)
1177 			unregisterrpc(sep);
1178 		freeconfig(sep);
1179 		free(sep);
1180 	}
1181 	(void) sigsetmask(omask);
1182 }
1183 
1184 static void
1185 unregisterrpc(struct servtab *sep)
1186 {
1187         u_int i;
1188         struct servtab *sepp;
1189 	long omask;
1190 	struct netconfig *netid4, *netid6;
1191 
1192 	omask = sigblock(SIGBLOCK);
1193 	netid4 = sep->se_socktype == SOCK_DGRAM ? udpconf : tcpconf;
1194 	netid6 = sep->se_socktype == SOCK_DGRAM ? udp6conf : tcp6conf;
1195 	if (sep->se_family == AF_INET)
1196 		netid6 = NULL;
1197 	else if (sep->se_nomapped)
1198 		netid4 = NULL;
1199 	/*
1200 	 * Conflict if same prog and protocol - In that case one should look
1201 	 * to versions, but it is not interesting: having separate servers for
1202 	 * different versions does not work well.
1203 	 * Therefore one do not unregister if there is a conflict.
1204 	 * There is also transport conflict if destroying INET when INET46
1205 	 * exists, or destroying INET46 when INET exists
1206 	 */
1207         for (sepp = servtab; sepp; sepp = sepp->se_next) {
1208                 if (sepp == sep)
1209                         continue;
1210 		if (sepp->se_checked == 0 ||
1211                     !sepp->se_rpc ||
1212 		    strcmp(sep->se_proto, sepp->se_proto) != 0 ||
1213                     sep->se_rpc_prog != sepp->se_rpc_prog)
1214 			continue;
1215 		if (sepp->se_family == AF_INET)
1216 			netid4 = NULL;
1217 		if (sepp->se_family == AF_INET6) {
1218 			netid6 = NULL;
1219 			if (!sep->se_nomapped)
1220 				netid4 = NULL;
1221 		}
1222 		if (netid4 == NULL && netid6 == NULL)
1223 			return;
1224         }
1225         if (debug)
1226                 print_service("UNREG", sep);
1227         for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) {
1228 		if (netid4)
1229 			rpcb_unset(sep->se_rpc_prog, i, netid4);
1230 		if (netid6)
1231 			rpcb_unset(sep->se_rpc_prog, i, netid6);
1232 	}
1233         if (sep->se_fd != -1)
1234                 (void) close(sep->se_fd);
1235         sep->se_fd = -1;
1236 	(void) sigsetmask(omask);
1237 }
1238 
1239 static void
1240 retry(void)
1241 {
1242 	struct servtab *sep;
1243 
1244 	timingout = 0;
1245 	for (sep = servtab; sep; sep = sep->se_next)
1246 		if (sep->se_fd == -1 && !ISMUX(sep))
1247 			setup(sep);
1248 }
1249 
1250 static void
1251 setup(struct servtab *sep)
1252 {
1253 	int on = 1;
1254 
1255 	/* Set all listening sockets to close-on-exec. */
1256 	if ((sep->se_fd = socket(sep->se_family,
1257 	    sep->se_socktype | SOCK_CLOEXEC, 0)) < 0) {
1258 		if (debug)
1259 			warn("socket failed on %s/%s",
1260 				sep->se_service, sep->se_proto);
1261 		syslog(LOG_ERR, "%s/%s: socket: %m",
1262 		    sep->se_service, sep->se_proto);
1263 		return;
1264 	}
1265 #define	turnon(fd, opt) \
1266 setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
1267 	if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) &&
1268 	    turnon(sep->se_fd, SO_DEBUG) < 0)
1269 		syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
1270 	if (turnon(sep->se_fd, SO_REUSEADDR) < 0)
1271 		syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m");
1272 #ifdef SO_PRIVSTATE
1273 	if (turnon(sep->se_fd, SO_PRIVSTATE) < 0)
1274 		syslog(LOG_ERR, "setsockopt (SO_PRIVSTATE): %m");
1275 #endif
1276 	/* tftpd opens a new connection then needs more infos */
1277 #ifdef INET6
1278 	if ((sep->se_family == AF_INET6) &&
1279 	    (strcmp(sep->se_proto, "udp") == 0) &&
1280 	    (sep->se_accept == 0) &&
1281 	    (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
1282 			(char *)&on, sizeof (on)) < 0))
1283 		syslog(LOG_ERR, "setsockopt (IPV6_RECVPKTINFO): %m");
1284 	if (sep->se_family == AF_INET6) {
1285 		int flag = sep->se_nomapped ? 1 : 0;
1286 		if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_V6ONLY,
1287 			       (char *)&flag, sizeof (flag)) < 0)
1288 			syslog(LOG_ERR, "setsockopt (IPV6_V6ONLY): %m");
1289 	}
1290 #endif
1291 #undef turnon
1292 #ifdef IPSEC
1293 	ipsecsetup(sep);
1294 #endif
1295 	if (sep->se_family == AF_UNIX) {
1296 		(void) unlink(sep->se_ctrladdr_un.sun_path);
1297 		umask(0777); /* Make socket with conservative permissions */
1298 	}
1299 	if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr,
1300 	    sep->se_ctrladdr_size) < 0) {
1301 		if (debug)
1302 			warn("bind failed on %s/%s",
1303 				sep->se_service, sep->se_proto);
1304 		syslog(LOG_ERR, "%s/%s: bind: %m",
1305 		    sep->se_service, sep->se_proto);
1306 		(void) close(sep->se_fd);
1307 		sep->se_fd = -1;
1308 		if (!timingout) {
1309 			timingout = 1;
1310 			alarm(RETRYTIME);
1311 		}
1312 		if (sep->se_family == AF_UNIX)
1313 			umask(mask);
1314 		return;
1315 	}
1316 	if (sep->se_family == AF_UNIX) {
1317 		/* Ick - fch{own,mod} don't work on Unix domain sockets */
1318 		if (chown(sep->se_service, sep->se_sockuid, sep->se_sockgid) < 0)
1319 			syslog(LOG_ERR, "chown socket: %m");
1320 		if (chmod(sep->se_service, sep->se_sockmode) < 0)
1321 			syslog(LOG_ERR, "chmod socket: %m");
1322 		umask(mask);
1323 	}
1324         if (sep->se_rpc) {
1325 		u_int i;
1326 		socklen_t len = sep->se_ctrladdr_size;
1327 		struct netconfig *netid, *netid2 = NULL;
1328 #ifdef INET6
1329 		struct sockaddr_in sock;
1330 #endif
1331 		struct netbuf nbuf, nbuf2;
1332 
1333                 if (getsockname(sep->se_fd,
1334 				(struct sockaddr*)&sep->se_ctrladdr, &len) < 0){
1335                         syslog(LOG_ERR, "%s/%s: getsockname: %m",
1336                                sep->se_service, sep->se_proto);
1337                         (void) close(sep->se_fd);
1338                         sep->se_fd = -1;
1339                         return;
1340                 }
1341 		nbuf.buf = &sep->se_ctrladdr;
1342 		nbuf.len = sep->se_ctrladdr.sa_len;
1343 		if (sep->se_family == AF_INET)
1344 			netid = sep->se_socktype==SOCK_DGRAM? udpconf:tcpconf;
1345 #ifdef INET6
1346 		else  {
1347 			netid = sep->se_socktype==SOCK_DGRAM? udp6conf:tcp6conf;
1348 			if (!sep->se_nomapped) { /* INET and INET6 */
1349 				netid2 = netid==udp6conf? udpconf:tcpconf;
1350 				memset(&sock, 0, sizeof sock);	/* ADDR_ANY */
1351 				nbuf2.buf = &sock;
1352 				nbuf2.len = sock.sin_len = sizeof sock;
1353 				sock.sin_family = AF_INET;
1354 				sock.sin_port = sep->se_ctrladdr6.sin6_port;
1355 			}
1356 		}
1357 #else
1358 		else {
1359 			syslog(LOG_ERR,
1360 			    "%s/%s: inetd compiled without inet6 support\n",
1361 			    sep->se_service, sep->se_proto);
1362 			(void) close(sep->se_fd);
1363 			sep->se_fd = -1;
1364 			return;
1365 		}
1366 #endif
1367                 if (debug)
1368                         print_service("REG ", sep);
1369                 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) {
1370 			rpcb_unset(sep->se_rpc_prog, i, netid);
1371 			rpcb_set(sep->se_rpc_prog, i, netid, &nbuf);
1372 			if (netid2) {
1373 				rpcb_unset(sep->se_rpc_prog, i, netid2);
1374 				rpcb_set(sep->se_rpc_prog, i, netid2, &nbuf2);
1375 			}
1376                 }
1377         }
1378 	if (sep->se_socktype == SOCK_STREAM)
1379 		listen(sep->se_fd, -1);
1380 	enable(sep);
1381 	if (debug) {
1382 		warnx("registered %s on %d",
1383 			sep->se_server, sep->se_fd);
1384 	}
1385 }
1386 
1387 #ifdef IPSEC
1388 static void
1389 ipsecsetup(struct servtab *sep)
1390 {
1391 	char *buf;
1392 	char *policy_in = NULL;
1393 	char *policy_out = NULL;
1394 	int level;
1395 	int opt;
1396 
1397 	switch (sep->se_family) {
1398 	case AF_INET:
1399 		level = IPPROTO_IP;
1400 		opt = IP_IPSEC_POLICY;
1401 		break;
1402 #ifdef INET6
1403 	case AF_INET6:
1404 		level = IPPROTO_IPV6;
1405 		opt = IPV6_IPSEC_POLICY;
1406 		break;
1407 #endif
1408 	default:
1409 		return;
1410 	}
1411 
1412 	if (!sep->se_policy || sep->se_policy[0] == '\0') {
1413 		static char def_in[] = "in entrust", def_out[] = "out entrust";
1414 		policy_in = def_in;
1415 		policy_out = def_out;
1416 	} else {
1417 		if (!strncmp("in", sep->se_policy, 2))
1418 			policy_in = sep->se_policy;
1419 		else if (!strncmp("out", sep->se_policy, 3))
1420 			policy_out = sep->se_policy;
1421 		else {
1422 			syslog(LOG_ERR, "invalid security policy \"%s\"",
1423 				sep->se_policy);
1424 			return;
1425 		}
1426 	}
1427 
1428 	if (policy_in != NULL) {
1429 		buf = ipsec_set_policy(policy_in, strlen(policy_in));
1430 		if (buf != NULL) {
1431 			if (setsockopt(sep->se_fd, level, opt,
1432 					buf, ipsec_get_policylen(buf)) < 0 &&
1433 			    debug != 0)
1434 				warnx("%s/%s: ipsec initialization failed; %s",
1435 				      sep->se_service, sep->se_proto,
1436 				      policy_in);
1437 			free(buf);
1438 		} else
1439 			syslog(LOG_ERR, "invalid security policy \"%s\"",
1440 				policy_in);
1441 	}
1442 	if (policy_out != NULL) {
1443 		buf = ipsec_set_policy(policy_out, strlen(policy_out));
1444 		if (buf != NULL) {
1445 			if (setsockopt(sep->se_fd, level, opt,
1446 					buf, ipsec_get_policylen(buf)) < 0 &&
1447 			    debug != 0)
1448 				warnx("%s/%s: ipsec initialization failed; %s",
1449 				      sep->se_service, sep->se_proto,
1450 				      policy_out);
1451 			free(buf);
1452 		} else
1453 			syslog(LOG_ERR, "invalid security policy \"%s\"",
1454 				policy_out);
1455 	}
1456 }
1457 #endif
1458 
1459 /*
1460  * Finish with a service and its socket.
1461  */
1462 static void
1463 close_sep(struct servtab *sep)
1464 {
1465 	if (sep->se_fd >= 0) {
1466 		if (FD_ISSET(sep->se_fd, &allsock))
1467 			disable(sep);
1468 		(void) close(sep->se_fd);
1469 		sep->se_fd = -1;
1470 	}
1471 	sep->se_count = 0;
1472 	sep->se_numchild = 0;	/* forget about any existing children */
1473 }
1474 
1475 static int
1476 matchservent(const char *name1, const char *name2, const char *proto)
1477 {
1478 	char **alias, *p;
1479 	struct servent *se;
1480 
1481 	if (strcmp(proto, "unix") == 0) {
1482 		if ((p = strrchr(name1, '/')) != NULL)
1483 			name1 = p + 1;
1484 		if ((p = strrchr(name2, '/')) != NULL)
1485 			name2 = p + 1;
1486 	}
1487 	if (strcmp(name1, name2) == 0)
1488 		return(1);
1489 	if ((se = getservbyname(name1, proto)) != NULL) {
1490 		if (strcmp(name2, se->s_name) == 0)
1491 			return(1);
1492 		for (alias = se->s_aliases; *alias; alias++)
1493 			if (strcmp(name2, *alias) == 0)
1494 				return(1);
1495 	}
1496 	return(0);
1497 }
1498 
1499 static struct servtab *
1500 enter(struct servtab *cp)
1501 {
1502 	struct servtab *sep;
1503 	long omask;
1504 
1505 	sep = malloc(sizeof(*sep));
1506 	if (sep == NULL) {
1507 		syslog(LOG_ERR, "malloc: %m");
1508 		exit(EX_OSERR);
1509 	}
1510 	*sep = *cp;
1511 	sep->se_fd = -1;
1512 	omask = sigblock(SIGBLOCK);
1513 	sep->se_next = servtab;
1514 	servtab = sep;
1515 	sigsetmask(omask);
1516 	return (sep);
1517 }
1518 
1519 static void
1520 enable(struct servtab *sep)
1521 {
1522 	if (debug)
1523 		warnx(
1524 		    "enabling %s, fd %d", sep->se_service, sep->se_fd);
1525 #ifdef SANITY_CHECK
1526 	if (sep->se_fd < 0) {
1527 		syslog(LOG_ERR,
1528 		    "%s: %s: bad fd", __func__, sep->se_service);
1529 		exit(EX_SOFTWARE);
1530 	}
1531 	if (ISMUX(sep)) {
1532 		syslog(LOG_ERR,
1533 		    "%s: %s: is mux", __func__, sep->se_service);
1534 		exit(EX_SOFTWARE);
1535 	}
1536 	if (FD_ISSET(sep->se_fd, &allsock)) {
1537 		syslog(LOG_ERR,
1538 		    "%s: %s: not off", __func__, sep->se_service);
1539 		exit(EX_SOFTWARE);
1540 	}
1541 	nsock++;
1542 #endif
1543 	FD_SET(sep->se_fd, &allsock);
1544 	maxsock = MAX(maxsock, sep->se_fd);
1545 }
1546 
1547 static void
1548 disable(struct servtab *sep)
1549 {
1550 	if (debug)
1551 		warnx(
1552 		    "disabling %s, fd %d", sep->se_service, sep->se_fd);
1553 #ifdef SANITY_CHECK
1554 	if (sep->se_fd < 0) {
1555 		syslog(LOG_ERR,
1556 		    "%s: %s: bad fd", __func__, sep->se_service);
1557 		exit(EX_SOFTWARE);
1558 	}
1559 	if (ISMUX(sep)) {
1560 		syslog(LOG_ERR,
1561 		    "%s: %s: is mux", __func__, sep->se_service);
1562 		exit(EX_SOFTWARE);
1563 	}
1564 	if (!FD_ISSET(sep->se_fd, &allsock)) {
1565 		syslog(LOG_ERR,
1566 		    "%s: %s: not on", __func__, sep->se_service);
1567 		exit(EX_SOFTWARE);
1568 	}
1569 	if (nsock == 0) {
1570 		syslog(LOG_ERR, "%s: nsock=0", __func__);
1571 		exit(EX_SOFTWARE);
1572 	}
1573 	nsock--;
1574 #endif
1575 	FD_CLR(sep->se_fd, &allsock);
1576 	if (sep->se_fd == maxsock)
1577 		maxsock--;
1578 }
1579 
1580 static FILE	*fconfig = NULL;
1581 static struct	servtab serv;
1582 static char	line[LINE_MAX];
1583 
1584 static int
1585 setconfig(void)
1586 {
1587 
1588 	if (fconfig != NULL) {
1589 		fseek(fconfig, 0L, SEEK_SET);
1590 		return (1);
1591 	}
1592 	fconfig = fopen(CONFIG, "r");
1593 	return (fconfig != NULL);
1594 }
1595 
1596 static void
1597 endconfig(void)
1598 {
1599 	if (fconfig) {
1600 		(void) fclose(fconfig);
1601 		fconfig = NULL;
1602 	}
1603 }
1604 
1605 static struct servtab *
1606 getconfigent(void)
1607 {
1608 	struct servtab *sep = &serv;
1609 	int argc;
1610 	char *cp, *arg, *s;
1611 	char *versp;
1612 	static char TCPMUX_TOKEN[] = "tcpmux/";
1613 #define MUX_LEN		(sizeof(TCPMUX_TOKEN)-1)
1614 #ifdef IPSEC
1615 	char *policy;
1616 #endif
1617 #ifdef INET6
1618 	int v4bind;
1619 	int v6bind;
1620 #endif
1621 	int i;
1622 
1623 #ifdef IPSEC
1624 	policy = NULL;
1625 #endif
1626 more:
1627 #ifdef INET6
1628 	v4bind = 0;
1629 	v6bind = 0;
1630 #endif
1631 	while ((cp = nextline(fconfig)) != NULL) {
1632 #ifdef IPSEC
1633 		/* lines starting with #@ is not a comment, but the policy */
1634 		if (cp[0] == '#' && cp[1] == '@') {
1635 			char *p;
1636 			for (p = cp + 2; p && *p && isspace(*p); p++)
1637 				;
1638 			if (*p == '\0') {
1639 				free(policy);
1640 				policy = NULL;
1641 			} else if (ipsec_get_policylen(p) >= 0) {
1642 				free(policy);
1643 				policy = newstr(p);
1644 			} else {
1645 				syslog(LOG_ERR,
1646 					"%s: invalid ipsec policy \"%s\"",
1647 					CONFIG, p);
1648 				exit(EX_CONFIG);
1649 			}
1650 		}
1651 #endif
1652 		if (*cp == '#' || *cp == '\0')
1653 			continue;
1654 		break;
1655 	}
1656 	if (cp == NULL) {
1657 #ifdef IPSEC
1658 		free(policy);
1659 #endif
1660 		return (NULL);
1661 	}
1662 
1663 	/*
1664 	 * clear the static buffer, since some fields (se_ctrladdr,
1665 	 * for example) don't get initialized here.
1666 	 */
1667 	memset(sep, 0, sizeof *sep);
1668 	arg = skip(&cp);
1669 	if (cp == NULL) {
1670 		/* got an empty line containing just blanks/tabs. */
1671 		goto more;
1672 	}
1673 	if (arg[0] == ':') { /* :user:group:perm: */
1674 		char *user, *group, *perm;
1675 		struct passwd *pw;
1676 		struct group *gr;
1677 		user = arg+1;
1678 		if ((group = strchr(user, ':')) == NULL) {
1679 			syslog(LOG_ERR, "no group after user '%s'", user);
1680 			goto more;
1681 		}
1682 		*group++ = '\0';
1683 		if ((perm = strchr(group, ':')) == NULL) {
1684 			syslog(LOG_ERR, "no mode after group '%s'", group);
1685 			goto more;
1686 		}
1687 		*perm++ = '\0';
1688 		if ((pw = getpwnam(user)) == NULL) {
1689 			syslog(LOG_ERR, "no such user '%s'", user);
1690 			goto more;
1691 		}
1692 		sep->se_sockuid = pw->pw_uid;
1693 		if ((gr = getgrnam(group)) == NULL) {
1694 			syslog(LOG_ERR, "no such user '%s'", group);
1695 			goto more;
1696 		}
1697 		sep->se_sockgid = gr->gr_gid;
1698 		sep->se_sockmode = strtol(perm, &arg, 8);
1699 		if (*arg != ':') {
1700 			syslog(LOG_ERR, "bad mode '%s'", perm);
1701 			goto more;
1702 		}
1703 		*arg++ = '\0';
1704 	} else {
1705 		sep->se_sockuid = euid;
1706 		sep->se_sockgid = egid;
1707 		sep->se_sockmode = 0200;
1708 	}
1709 	if (strncmp(arg, TCPMUX_TOKEN, MUX_LEN) == 0) {
1710 		char *c = arg + MUX_LEN;
1711 		if (*c == '+') {
1712 			sep->se_type = MUXPLUS_TYPE;
1713 			c++;
1714 		} else
1715 			sep->se_type = MUX_TYPE;
1716 		sep->se_service = newstr(c);
1717 	} else {
1718 		sep->se_service = newstr(arg);
1719 		sep->se_type = NORM_TYPE;
1720 	}
1721 	arg = sskip(&cp);
1722 	if (strcmp(arg, "stream") == 0)
1723 		sep->se_socktype = SOCK_STREAM;
1724 	else if (strcmp(arg, "dgram") == 0)
1725 		sep->se_socktype = SOCK_DGRAM;
1726 	else if (strcmp(arg, "rdm") == 0)
1727 		sep->se_socktype = SOCK_RDM;
1728 	else if (strcmp(arg, "seqpacket") == 0)
1729 		sep->se_socktype = SOCK_SEQPACKET;
1730 	else if (strcmp(arg, "raw") == 0)
1731 		sep->se_socktype = SOCK_RAW;
1732 	else
1733 		sep->se_socktype = -1;
1734 
1735 	arg = sskip(&cp);
1736 	if (strncmp(arg, "tcp", 3) == 0) {
1737 		sep->se_proto = newstr(strsep(&arg, "/"));
1738 		if (arg != NULL && (strcmp(arg, "faith") == 0)) {
1739 			syslog(LOG_ERR, "faith has been deprecated");
1740 			goto more;
1741 		}
1742 	} else {
1743 		if (sep->se_type == NORM_TYPE &&
1744 		    strncmp(arg, "faith/", 6) == 0) {
1745 			syslog(LOG_ERR, "faith has been deprecated");
1746 			goto more;
1747 		}
1748 		sep->se_proto = newstr(arg);
1749 	}
1750         if (strncmp(sep->se_proto, "rpc/", 4) == 0) {
1751                 memmove(sep->se_proto, sep->se_proto + 4,
1752                     strlen(sep->se_proto) + 1 - 4);
1753                 sep->se_rpc = 1;
1754                 sep->se_rpc_prog = sep->se_rpc_lowvers =
1755 			sep->se_rpc_highvers = 0;
1756                 if ((versp = strrchr(sep->se_service, '/'))) {
1757                         *versp++ = '\0';
1758                         switch (sscanf(versp, "%u-%u",
1759                                        &sep->se_rpc_lowvers,
1760                                        &sep->se_rpc_highvers)) {
1761                         case 2:
1762                                 break;
1763                         case 1:
1764                                 sep->se_rpc_highvers =
1765                                         sep->se_rpc_lowvers;
1766                                 break;
1767                         default:
1768                                 syslog(LOG_ERR,
1769 					"bad RPC version specifier; %s",
1770 					sep->se_service);
1771                                 freeconfig(sep);
1772                                 goto more;
1773                         }
1774                 }
1775                 else {
1776                         sep->se_rpc_lowvers =
1777                                 sep->se_rpc_highvers = 1;
1778                 }
1779         }
1780 	sep->se_nomapped = 0;
1781 	if (strcmp(sep->se_proto, "unix") == 0) {
1782 	        sep->se_family = AF_UNIX;
1783 	} else {
1784 		while (isdigit(sep->se_proto[strlen(sep->se_proto) - 1])) {
1785 #ifdef INET6
1786 			if (sep->se_proto[strlen(sep->se_proto) - 1] == '6') {
1787 				sep->se_proto[strlen(sep->se_proto) - 1] = '\0';
1788 				v6bind = 1;
1789 				continue;
1790 			}
1791 #endif
1792 			if (sep->se_proto[strlen(sep->se_proto) - 1] == '4') {
1793 				sep->se_proto[strlen(sep->se_proto) - 1] = '\0';
1794 #ifdef INET6
1795 				v4bind = 1;
1796 #endif
1797 				continue;
1798 			}
1799 			/* illegal version num */
1800 			syslog(LOG_ERR,	"bad IP version for %s", sep->se_proto);
1801 			freeconfig(sep);
1802 			goto more;
1803 		}
1804 #ifdef INET6
1805 		if (v6bind && !v6bind_ok) {
1806 			syslog(LOG_INFO, "IPv6 bind is ignored for %s",
1807 			       sep->se_service);
1808 			if (v4bind && v4bind_ok)
1809 				v6bind = 0;
1810 			else {
1811 				freeconfig(sep);
1812 				goto more;
1813 			}
1814 		}
1815 		if (v6bind) {
1816 			sep->se_family = AF_INET6;
1817 			if (!v4bind || !v4bind_ok)
1818 				sep->se_nomapped = 1;
1819 		} else
1820 #endif
1821 		{ /* default to v4 bind if not v6 bind */
1822 			if (!v4bind_ok) {
1823 				syslog(LOG_NOTICE, "IPv4 bind is ignored for %s",
1824 				       sep->se_service);
1825 				freeconfig(sep);
1826 				goto more;
1827 			}
1828 			sep->se_family = AF_INET;
1829 		}
1830 	}
1831 	/* init ctladdr */
1832 	switch(sep->se_family) {
1833 	case AF_INET:
1834 		memcpy(&sep->se_ctrladdr4, bind_sa4,
1835 		       sizeof(sep->se_ctrladdr4));
1836 		sep->se_ctrladdr_size =	sizeof(sep->se_ctrladdr4);
1837 		break;
1838 #ifdef INET6
1839 	case AF_INET6:
1840 		memcpy(&sep->se_ctrladdr6, bind_sa6,
1841 		       sizeof(sep->se_ctrladdr6));
1842 		sep->se_ctrladdr_size =	sizeof(sep->se_ctrladdr6);
1843 		break;
1844 #endif
1845 	case AF_UNIX:
1846 #define	SUN_PATH_MAXSIZE	sizeof(sep->se_ctrladdr_un.sun_path)
1847 		memset(&sep->se_ctrladdr, 0, sizeof(sep->se_ctrladdr));
1848 		sep->se_ctrladdr_un.sun_family = sep->se_family;
1849 		if (strlcpy(sep->se_ctrladdr_un.sun_path, sep->se_service,
1850 		    SUN_PATH_MAXSIZE) >= SUN_PATH_MAXSIZE) {
1851 			syslog(LOG_ERR,
1852 			    "domain socket pathname too long for service %s",
1853 			    sep->se_service);
1854 			goto more;
1855 		}
1856 #undef SUN_PATH_MAXSIZE
1857 		sep->se_ctrladdr_size = sep->se_ctrladdr_un.sun_len =
1858 		    SUN_LEN(&sep->se_ctrladdr_un);
1859 	}
1860 	arg = sskip(&cp);
1861 	if (!strncmp(arg, "wait", 4))
1862 		sep->se_accept = 0;
1863 	else if (!strncmp(arg, "nowait", 6))
1864 		sep->se_accept = 1;
1865 	else {
1866 		syslog(LOG_ERR,
1867 			"%s: bad wait/nowait for service %s",
1868 			CONFIG, sep->se_service);
1869 		goto more;
1870 	}
1871 	sep->se_maxchild = -1;
1872 	sep->se_maxcpm = -1;
1873 	sep->se_maxperip = -1;
1874 	if ((s = strchr(arg, '/')) != NULL) {
1875 		char *eptr;
1876 		u_long val;
1877 
1878 		val = strtoul(s + 1, &eptr, 10);
1879 		if (eptr == s + 1 || val > MAX_MAXCHLD) {
1880 			syslog(LOG_ERR,
1881 				"%s: bad max-child for service %s",
1882 				CONFIG, sep->se_service);
1883 			goto more;
1884 		}
1885 		if (debug)
1886 			if (!sep->se_accept && val != 1)
1887 				warnx("maxchild=%lu for wait service %s"
1888 				    " not recommended", val, sep->se_service);
1889 		sep->se_maxchild = val;
1890 		if (*eptr == '/')
1891 			sep->se_maxcpm = strtol(eptr + 1, &eptr, 10);
1892 		if (*eptr == '/')
1893 			sep->se_maxperip = strtol(eptr + 1, &eptr, 10);
1894 		/*
1895 		 * explicitly do not check for \0 for future expansion /
1896 		 * backwards compatibility
1897 		 */
1898 	}
1899 	if (ISMUX(sep)) {
1900 		/*
1901 		 * Silently enforce "nowait" mode for TCPMUX services
1902 		 * since they don't have an assigned port to listen on.
1903 		 */
1904 		sep->se_accept = 1;
1905 		if (strcmp(sep->se_proto, "tcp")) {
1906 			syslog(LOG_ERR,
1907 				"%s: bad protocol for tcpmux service %s",
1908 				CONFIG, sep->se_service);
1909 			goto more;
1910 		}
1911 		if (sep->se_socktype != SOCK_STREAM) {
1912 			syslog(LOG_ERR,
1913 				"%s: bad socket type for tcpmux service %s",
1914 				CONFIG, sep->se_service);
1915 			goto more;
1916 		}
1917 	}
1918 	sep->se_user = newstr(sskip(&cp));
1919 #ifdef LOGIN_CAP
1920 	if ((s = strrchr(sep->se_user, '/')) != NULL) {
1921 		*s = '\0';
1922 		sep->se_class = newstr(s + 1);
1923 	} else
1924 		sep->se_class = newstr(RESOURCE_RC);
1925 #endif
1926 	if ((s = strrchr(sep->se_user, ':')) != NULL) {
1927 		*s = '\0';
1928 		sep->se_group = newstr(s + 1);
1929 	} else
1930 		sep->se_group = NULL;
1931 	sep->se_server = newstr(sskip(&cp));
1932 	if ((sep->se_server_name = strrchr(sep->se_server, '/')))
1933 		sep->se_server_name++;
1934 	if (strcmp(sep->se_server, "internal") == 0) {
1935 		struct biltin *bi;
1936 
1937 		for (bi = biltins; bi->bi_service; bi++)
1938 			if (bi->bi_socktype == sep->se_socktype &&
1939 			    matchservent(bi->bi_service, sep->se_service,
1940 			    sep->se_proto))
1941 				break;
1942 		if (bi->bi_service == 0) {
1943 			syslog(LOG_ERR, "internal service %s unknown",
1944 				sep->se_service);
1945 			goto more;
1946 		}
1947 		sep->se_accept = 1;	/* force accept mode for built-ins */
1948 		sep->se_bi = bi;
1949 	} else
1950 		sep->se_bi = NULL;
1951 	if (sep->se_maxperip < 0)
1952 		sep->se_maxperip = maxperip;
1953 	if (sep->se_maxcpm < 0)
1954 		sep->se_maxcpm = maxcpm;
1955 	if (sep->se_maxchild < 0) {	/* apply default max-children */
1956 		if (sep->se_bi && sep->se_bi->bi_maxchild >= 0)
1957 			sep->se_maxchild = sep->se_bi->bi_maxchild;
1958 		else if (sep->se_accept)
1959 			sep->se_maxchild = MAX(maxchild, 0);
1960 		else
1961 			sep->se_maxchild = 1;
1962 	}
1963 	LIST_INIT(&sep->se_children);
1964 	argc = 0;
1965 	for (arg = skip(&cp); cp; arg = skip(&cp))
1966 		if (argc < MAXARGV) {
1967 			sep->se_argv[argc++] = newstr(arg);
1968 		} else {
1969 			syslog(LOG_ERR,
1970 				"%s: too many arguments for service %s",
1971 				CONFIG, sep->se_service);
1972 			goto more;
1973 		}
1974 	while (argc <= MAXARGV)
1975 		sep->se_argv[argc++] = NULL;
1976 	for (i = 0; i < PERIPSIZE; ++i)
1977 		LIST_INIT(&sep->se_conn[i]);
1978 #ifdef IPSEC
1979 	sep->se_policy = policy ? newstr(policy) : NULL;
1980 	free(policy);
1981 #endif
1982 	return (sep);
1983 }
1984 
1985 static void
1986 freeconfig(struct servtab *cp)
1987 {
1988 	struct stabchild *sc;
1989 	int i;
1990 
1991 	free(cp->se_service);
1992 	free(cp->se_proto);
1993 	free(cp->se_user);
1994 	free(cp->se_group);
1995 #ifdef LOGIN_CAP
1996 	free(cp->se_class);
1997 #endif
1998 	free(cp->se_server);
1999 	while (!LIST_EMPTY(&cp->se_children)) {
2000 		sc = LIST_FIRST(&cp->se_children);
2001 		LIST_REMOVE(sc, sc_link);
2002 		free(sc);
2003 	}
2004 	for (i = 0; i < MAXARGV; i++)
2005 		if (cp->se_argv[i])
2006 			free(cp->se_argv[i]);
2007 	free_connlist(cp);
2008 #ifdef IPSEC
2009 	free(cp->se_policy);
2010 #endif
2011 }
2012 
2013 
2014 /*
2015  * Safe skip - if skip returns null, log a syntax error in the
2016  * configuration file and exit.
2017  */
2018 static char *
2019 sskip(char **cpp)
2020 {
2021 	char *cp;
2022 
2023 	cp = skip(cpp);
2024 	if (cp == NULL) {
2025 		syslog(LOG_ERR, "%s: syntax error", CONFIG);
2026 		exit(EX_DATAERR);
2027 	}
2028 	return (cp);
2029 }
2030 
2031 static char *
2032 skip(char **cpp)
2033 {
2034 	char *cp = *cpp;
2035 	char *start;
2036 	char quote = '\0';
2037 
2038 again:
2039 	while (*cp == ' ' || *cp == '\t')
2040 		cp++;
2041 	if (*cp == '\0') {
2042 		int c;
2043 
2044 		c = getc(fconfig);
2045 		(void) ungetc(c, fconfig);
2046 		if (c == ' ' || c == '\t')
2047 			if ((cp = nextline(fconfig)))
2048 				goto again;
2049 		*cpp = (char *)0;
2050 		return ((char *)0);
2051 	}
2052 	if (*cp == '"' || *cp == '\'')
2053 		quote = *cp++;
2054 	start = cp;
2055 	if (quote)
2056 		while (*cp && *cp != quote)
2057 			cp++;
2058 	else
2059 		while (*cp && *cp != ' ' && *cp != '\t')
2060 			cp++;
2061 	if (*cp != '\0')
2062 		*cp++ = '\0';
2063 	*cpp = cp;
2064 	return (start);
2065 }
2066 
2067 static char *
2068 nextline(FILE *fd)
2069 {
2070 	char *cp;
2071 
2072 	if (fgets(line, sizeof (line), fd) == NULL)
2073 		return ((char *)0);
2074 	cp = strchr(line, '\n');
2075 	if (cp)
2076 		*cp = '\0';
2077 	return (line);
2078 }
2079 
2080 static char *
2081 newstr(const char *cp)
2082 {
2083 	char *cr;
2084 
2085 	if ((cr = strdup(cp != NULL ? cp : "")))
2086 		return (cr);
2087 	syslog(LOG_ERR, "strdup: %m");
2088 	exit(EX_OSERR);
2089 }
2090 
2091 void
2092 inetd_setproctitle(const char *a, int s)
2093 {
2094 	socklen_t size;
2095 	struct sockaddr_storage ss;
2096 	char buf[80], pbuf[NI_MAXHOST];
2097 
2098 	size = sizeof(ss);
2099 	if (getpeername(s, (struct sockaddr *)&ss, &size) == 0) {
2100 		getnameinfo((struct sockaddr *)&ss, size, pbuf, sizeof(pbuf),
2101 			    NULL, 0, NI_NUMERICHOST);
2102 		(void) sprintf(buf, "%s [%s]", a, pbuf);
2103 	} else
2104 		(void) sprintf(buf, "%s", a);
2105 	setproctitle("%s", buf);
2106 }
2107 
2108 int
2109 check_loop(const struct sockaddr *sa, const struct servtab *sep)
2110 {
2111 	struct servtab *se2;
2112 	char pname[NI_MAXHOST];
2113 
2114 	for (se2 = servtab; se2; se2 = se2->se_next) {
2115 		if (!se2->se_bi || se2->se_socktype != SOCK_DGRAM)
2116 			continue;
2117 
2118 		switch (se2->se_family) {
2119 		case AF_INET:
2120 			if (csatosin(sa)->sin_port ==
2121 			    se2->se_ctrladdr4.sin_port)
2122 				goto isloop;
2123 			continue;
2124 #ifdef INET6
2125 		case AF_INET6:
2126 			if (csatosin6(sa)->sin6_port ==
2127 			    se2->se_ctrladdr6.sin6_port)
2128 				goto isloop;
2129 			continue;
2130 #endif
2131 		default:
2132 			continue;
2133 		}
2134 	isloop:
2135 		getnameinfo(sa, sa->sa_len, pname, sizeof(pname), NULL, 0,
2136 			    NI_NUMERICHOST);
2137 		syslog(LOG_WARNING, "%s/%s:%s/%s loop request REFUSED from %s",
2138 		       sep->se_service, sep->se_proto,
2139 		       se2->se_service, se2->se_proto,
2140 		       pname);
2141 		return 1;
2142 	}
2143 	return 0;
2144 }
2145 
2146 /*
2147  * print_service:
2148  *	Dump relevant information to stderr
2149  */
2150 static void
2151 print_service(const char *action, const struct servtab *sep)
2152 {
2153 	fprintf(stderr,
2154 	    "%s: %s proto=%s accept=%d max=%d user=%s group=%s"
2155 #ifdef LOGIN_CAP
2156 	    "class=%s"
2157 #endif
2158 	    " builtin=%p server=%s"
2159 #ifdef IPSEC
2160 	    " policy=\"%s\""
2161 #endif
2162 	    "\n",
2163 	    action, sep->se_service, sep->se_proto,
2164 	    sep->se_accept, sep->se_maxchild, sep->se_user, sep->se_group,
2165 #ifdef LOGIN_CAP
2166 	    sep->se_class,
2167 #endif
2168 	    (void *) sep->se_bi, sep->se_server
2169 #ifdef IPSEC
2170 	    , (sep->se_policy ? sep->se_policy : "")
2171 #endif
2172 	    );
2173 }
2174 
2175 #define CPMHSIZE	256
2176 #define CPMHMASK	(CPMHSIZE-1)
2177 #define CHTGRAN		10
2178 #define CHTSIZE		6
2179 
2180 typedef struct CTime {
2181 	unsigned long 	ct_Ticks;
2182 	int		ct_Count;
2183 } CTime;
2184 
2185 typedef struct CHash {
2186 	union {
2187 		struct in_addr	c4_Addr;
2188 		struct in6_addr	c6_Addr;
2189 	} cu_Addr;
2190 #define	ch_Addr4	cu_Addr.c4_Addr
2191 #define	ch_Addr6	cu_Addr.c6_Addr
2192 	int		ch_Family;
2193 	time_t		ch_LTime;
2194 	char		*ch_Service;
2195 	CTime		ch_Times[CHTSIZE];
2196 } CHash;
2197 
2198 static CHash	CHashAry[CPMHSIZE];
2199 
2200 static int
2201 cpmip(const struct servtab *sep, int ctrl)
2202 {
2203 	struct sockaddr_storage rss;
2204 	socklen_t rssLen = sizeof(rss);
2205 	int r = 0;
2206 
2207 	/*
2208 	 * If getpeername() fails, just let it through (if logging is
2209 	 * enabled the condition is caught elsewhere)
2210 	 */
2211 
2212 	if (sep->se_maxcpm > 0 &&
2213 	   (sep->se_family == AF_INET || sep->se_family == AF_INET6) &&
2214 	    getpeername(ctrl, (struct sockaddr *)&rss, &rssLen) == 0 ) {
2215 		time_t t = time(NULL);
2216 		unsigned int hv = 0xABC3D20F;
2217 		int i;
2218 		int cnt = 0;
2219 		CHash *chBest = NULL;
2220 		unsigned int ticks = t / CHTGRAN;
2221 		struct sockaddr_in *sin4;
2222 #ifdef INET6
2223 		struct sockaddr_in6 *sin6;
2224 #endif
2225 
2226 		sin4 = (struct sockaddr_in *)&rss;
2227 #ifdef INET6
2228 		sin6 = (struct sockaddr_in6 *)&rss;
2229 #endif
2230 		{
2231 			char *p;
2232 			int addrlen;
2233 
2234 			switch (rss.ss_family) {
2235 			case AF_INET:
2236 				p = (char *)&sin4->sin_addr;
2237 				addrlen = sizeof(struct in_addr);
2238 				break;
2239 #ifdef INET6
2240 			case AF_INET6:
2241 				p = (char *)&sin6->sin6_addr;
2242 				addrlen = sizeof(struct in6_addr);
2243 				break;
2244 #endif
2245 			default:
2246 				/* should not happen */
2247 				return -1;
2248 			}
2249 
2250 			for (i = 0; i < addrlen; ++i, ++p) {
2251 				hv = (hv << 5) ^ (hv >> 23) ^ *p;
2252 			}
2253 			hv = (hv ^ (hv >> 16));
2254 		}
2255 		for (i = 0; i < 5; ++i) {
2256 			CHash *ch = &CHashAry[(hv + i) & CPMHMASK];
2257 
2258 			if (rss.ss_family == AF_INET &&
2259 			    ch->ch_Family == AF_INET &&
2260 			    sin4->sin_addr.s_addr == ch->ch_Addr4.s_addr &&
2261 			    ch->ch_Service && strcmp(sep->se_service,
2262 			    ch->ch_Service) == 0) {
2263 				chBest = ch;
2264 				break;
2265 			}
2266 #ifdef INET6
2267 			if (rss.ss_family == AF_INET6 &&
2268 			    ch->ch_Family == AF_INET6 &&
2269 			    IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
2270 					       &ch->ch_Addr6) != 0 &&
2271 			    ch->ch_Service && strcmp(sep->se_service,
2272 			    ch->ch_Service) == 0) {
2273 				chBest = ch;
2274 				break;
2275 			}
2276 #endif
2277 			if (chBest == NULL || ch->ch_LTime == 0 ||
2278 			    ch->ch_LTime < chBest->ch_LTime) {
2279 				chBest = ch;
2280 			}
2281 		}
2282 		if ((rss.ss_family == AF_INET &&
2283 		     (chBest->ch_Family != AF_INET ||
2284 		      sin4->sin_addr.s_addr != chBest->ch_Addr4.s_addr)) ||
2285 		    chBest->ch_Service == NULL ||
2286 		    strcmp(sep->se_service, chBest->ch_Service) != 0) {
2287 			chBest->ch_Family = sin4->sin_family;
2288 			chBest->ch_Addr4 = sin4->sin_addr;
2289 			free(chBest->ch_Service);
2290 			chBest->ch_Service = strdup(sep->se_service);
2291 			memset(chBest->ch_Times, 0, sizeof(chBest->ch_Times));
2292 		}
2293 #ifdef INET6
2294 		if ((rss.ss_family == AF_INET6 &&
2295 		     (chBest->ch_Family != AF_INET6 ||
2296 		      IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
2297 					 &chBest->ch_Addr6) == 0)) ||
2298 		    chBest->ch_Service == NULL ||
2299 		    strcmp(sep->se_service, chBest->ch_Service) != 0) {
2300 			chBest->ch_Family = sin6->sin6_family;
2301 			chBest->ch_Addr6 = sin6->sin6_addr;
2302 			free(chBest->ch_Service);
2303 			chBest->ch_Service = strdup(sep->se_service);
2304 			memset(chBest->ch_Times, 0, sizeof(chBest->ch_Times));
2305 		}
2306 #endif
2307 		chBest->ch_LTime = t;
2308 		{
2309 			CTime *ct = &chBest->ch_Times[ticks % CHTSIZE];
2310 			if (ct->ct_Ticks != ticks) {
2311 				ct->ct_Ticks = ticks;
2312 				ct->ct_Count = 0;
2313 			}
2314 			++ct->ct_Count;
2315 		}
2316 		for (i = 0; i < CHTSIZE; ++i) {
2317 			CTime *ct = &chBest->ch_Times[i];
2318 			if (ct->ct_Ticks <= ticks &&
2319 			    ct->ct_Ticks >= ticks - CHTSIZE) {
2320 				cnt += ct->ct_Count;
2321 			}
2322 		}
2323 		if ((cnt * 60) / (CHTSIZE * CHTGRAN) > sep->se_maxcpm) {
2324 			char pname[NI_MAXHOST];
2325 
2326 			getnameinfo((struct sockaddr *)&rss,
2327 				    ((struct sockaddr *)&rss)->sa_len,
2328 				    pname, sizeof(pname), NULL, 0,
2329 				    NI_NUMERICHOST);
2330 			r = -1;
2331 			syslog(LOG_ERR,
2332 			    "%s from %s exceeded counts/min (limit %d/min)",
2333 			    sep->se_service, pname,
2334 			    sep->se_maxcpm);
2335 		}
2336 	}
2337 	return(r);
2338 }
2339 
2340 static struct conninfo *
2341 search_conn(struct servtab *sep, int ctrl)
2342 {
2343 	struct sockaddr_storage ss;
2344 	socklen_t sslen = sizeof(ss);
2345 	struct conninfo *conn;
2346 	int hv;
2347 	char pname[NI_MAXHOST],  pname2[NI_MAXHOST];
2348 
2349 	if (sep->se_maxperip <= 0)
2350 		return NULL;
2351 
2352 	/*
2353 	 * If getpeername() fails, just let it through (if logging is
2354 	 * enabled the condition is caught elsewhere)
2355 	 */
2356 	if (getpeername(ctrl, (struct sockaddr *)&ss, &sslen) != 0)
2357 		return NULL;
2358 
2359 	switch (ss.ss_family) {
2360 	case AF_INET:
2361 		hv = hashval((char *)&((struct sockaddr_in *)&ss)->sin_addr,
2362 		    sizeof(struct in_addr));
2363 		break;
2364 #ifdef INET6
2365 	case AF_INET6:
2366 		hv = hashval((char *)&((struct sockaddr_in6 *)&ss)->sin6_addr,
2367 		    sizeof(struct in6_addr));
2368 		break;
2369 #endif
2370 	default:
2371 		/*
2372 		 * Since we only support AF_INET and AF_INET6, just
2373 		 * let other than AF_INET and AF_INET6 through.
2374 		 */
2375 		return NULL;
2376 	}
2377 
2378 	if (getnameinfo((struct sockaddr *)&ss, sslen, pname, sizeof(pname),
2379 	    NULL, 0, NI_NUMERICHOST) != 0)
2380 		return NULL;
2381 
2382 	LIST_FOREACH(conn, &sep->se_conn[hv], co_link) {
2383 		if (getnameinfo((struct sockaddr *)&conn->co_addr,
2384 		    conn->co_addr.ss_len, pname2, sizeof(pname2), NULL, 0,
2385 		    NI_NUMERICHOST) == 0 &&
2386 		    strcmp(pname, pname2) == 0)
2387 			break;
2388 	}
2389 
2390 	if (conn == NULL) {
2391 		if ((conn = malloc(sizeof(struct conninfo))) == NULL) {
2392 			syslog(LOG_ERR, "malloc: %m");
2393 			exit(EX_OSERR);
2394 		}
2395 		conn->co_proc = reallocarray(NULL, sep->se_maxperip,
2396 		    sizeof(*conn->co_proc));
2397 		if (conn->co_proc == NULL) {
2398 			syslog(LOG_ERR, "reallocarray: %m");
2399 			exit(EX_OSERR);
2400 		}
2401 		memcpy(&conn->co_addr, (struct sockaddr *)&ss, sslen);
2402 		conn->co_numchild = 0;
2403 		LIST_INSERT_HEAD(&sep->se_conn[hv], conn, co_link);
2404 	}
2405 
2406 	/*
2407 	 * Since a child process is not invoked yet, we cannot
2408 	 * determine a pid of a child.  So, co_proc and co_numchild
2409 	 * should be filled leter.
2410 	 */
2411 
2412 	return conn;
2413 }
2414 
2415 static int
2416 room_conn(struct servtab *sep, struct conninfo *conn)
2417 {
2418 	char pname[NI_MAXHOST];
2419 
2420 	if (conn->co_numchild >= sep->se_maxperip) {
2421 		getnameinfo((struct sockaddr *)&conn->co_addr,
2422 		    conn->co_addr.ss_len, pname, sizeof(pname), NULL, 0,
2423 		    NI_NUMERICHOST);
2424 		syslog(LOG_ERR, "%s from %s exceeded counts (limit %d)",
2425 		    sep->se_service, pname, sep->se_maxperip);
2426 		return 0;
2427 	}
2428 	return 1;
2429 }
2430 
2431 static void
2432 addchild_conn(struct conninfo *conn, pid_t pid)
2433 {
2434 	struct procinfo *proc;
2435 
2436 	if (conn == NULL)
2437 		return;
2438 
2439 	if ((proc = search_proc(pid, 1)) != NULL) {
2440 		if (proc->pr_conn != NULL) {
2441 			syslog(LOG_ERR,
2442 			    "addchild_conn: child already on process list");
2443 			exit(EX_OSERR);
2444 		}
2445 		proc->pr_conn = conn;
2446 	}
2447 
2448 	conn->co_proc[conn->co_numchild++] = proc;
2449 }
2450 
2451 static void
2452 reapchild_conn(pid_t pid)
2453 {
2454 	struct procinfo *proc;
2455 	struct conninfo *conn;
2456 	int i;
2457 
2458 	if ((proc = search_proc(pid, 0)) == NULL)
2459 		return;
2460 	if ((conn = proc->pr_conn) == NULL)
2461 		return;
2462 	for (i = 0; i < conn->co_numchild; ++i)
2463 		if (conn->co_proc[i] == proc) {
2464 			conn->co_proc[i] = conn->co_proc[--conn->co_numchild];
2465 			break;
2466 		}
2467 	free_proc(proc);
2468 	free_conn(conn);
2469 }
2470 
2471 static void
2472 resize_conn(struct servtab *sep, int maxpip)
2473 {
2474 	struct conninfo *conn;
2475 	int i, j;
2476 
2477 	if (sep->se_maxperip <= 0)
2478 		return;
2479 	if (maxpip <= 0) {
2480 		free_connlist(sep);
2481 		return;
2482 	}
2483 	for (i = 0; i < PERIPSIZE; ++i) {
2484 		LIST_FOREACH(conn, &sep->se_conn[i], co_link) {
2485 			for (j = maxpip; j < conn->co_numchild; ++j)
2486 				free_proc(conn->co_proc[j]);
2487 			conn->co_proc = reallocarray(conn->co_proc, maxpip,
2488 			    sizeof(*conn->co_proc));
2489 			if (conn->co_proc == NULL) {
2490 				syslog(LOG_ERR, "reallocarray: %m");
2491 				exit(EX_OSERR);
2492 			}
2493 			if (conn->co_numchild > maxpip)
2494 				conn->co_numchild = maxpip;
2495 		}
2496 	}
2497 }
2498 
2499 static void
2500 free_connlist(struct servtab *sep)
2501 {
2502 	struct conninfo *conn, *conn_temp;
2503 	int i, j;
2504 
2505 	for (i = 0; i < PERIPSIZE; ++i) {
2506 		LIST_FOREACH_SAFE(conn, &sep->se_conn[i], co_link, conn_temp) {
2507 			if (conn == NULL) {
2508 				LIST_REMOVE(conn, co_link);
2509 				continue;
2510 			}
2511 			for (j = 0; j < conn->co_numchild; ++j)
2512 				free_proc(conn->co_proc[j]);
2513 			conn->co_numchild = 0;
2514 			free_conn(conn);
2515 		}
2516 	}
2517 }
2518 
2519 static void
2520 free_conn(struct conninfo *conn)
2521 {
2522 	if (conn == NULL)
2523 		return;
2524 	if (conn->co_numchild <= 0) {
2525 		LIST_REMOVE(conn, co_link);
2526 		free(conn->co_proc);
2527 		free(conn);
2528 	}
2529 }
2530 
2531 static struct procinfo *
2532 search_proc(pid_t pid, int add)
2533 {
2534 	struct procinfo *proc;
2535 	int hv;
2536 
2537 	hv = hashval((char *)&pid, sizeof(pid));
2538 	LIST_FOREACH(proc, &proctable[hv], pr_link) {
2539 		if (proc->pr_pid == pid)
2540 			break;
2541 	}
2542 	if (proc == NULL && add) {
2543 		if ((proc = malloc(sizeof(struct procinfo))) == NULL) {
2544 			syslog(LOG_ERR, "malloc: %m");
2545 			exit(EX_OSERR);
2546 		}
2547 		proc->pr_pid = pid;
2548 		proc->pr_conn = NULL;
2549 		LIST_INSERT_HEAD(&proctable[hv], proc, pr_link);
2550 	}
2551 	return proc;
2552 }
2553 
2554 static void
2555 free_proc(struct procinfo *proc)
2556 {
2557 	if (proc == NULL)
2558 		return;
2559 	LIST_REMOVE(proc, pr_link);
2560 	free(proc);
2561 }
2562 
2563 static int
2564 hashval(char *p, int len)
2565 {
2566 	unsigned int hv = 0xABC3D20F;
2567 	int i;
2568 
2569 	for (i = 0; i < len; ++i, ++p)
2570 		hv = (hv << 5) ^ (hv >> 23) ^ *p;
2571 	hv = (hv ^ (hv >> 16)) & (PERIPSIZE - 1);
2572 	return hv;
2573 }
2574