xref: /titanic_52/usr/src/cmd/cmd-inet/usr.sbin/in.tftpd.c (revision b6c3f7863936abeae522e48a13887dddeb691a45)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  *
21  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
22  * Use is subject to license terms.
23  */
24 
25 /*
26  * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T
27  * All Rights Reserved.
28  */
29 
30 /*
31  * University Copyright- Copyright (c) 1982, 1986, 1988
32  * The Regents of the University of California.
33  * All Rights Reserved.
34  *
35  * University Acknowledgment- Portions of this document are derived from
36  * software developed by the University of California, Berkeley, and its
37  * contributors.
38  */
39 
40 #pragma ident	"%Z%%M%	%I%	%E% SMI"
41 
42 /*
43  * Trivial file transfer protocol server.  A top level process runs in
44  * an infinite loop fielding new TFTP requests.  A child process,
45  * communicating via a pipe with the top level process, sends delayed
46  * NAKs for those that we can't handle.  A new child process is created
47  * to service each request that we can handle.  The top level process
48  * exits after a period of time during which no new requests are
49  * received.
50  */
51 
52 #include <sys/types.h>
53 #include <sys/socket.h>
54 #include <sys/wait.h>
55 #include <sys/stat.h>
56 #include <sys/time.h>
57 
58 #include <netinet/in.h>
59 
60 #include <arpa/inet.h>
61 #include <dirent.h>
62 #include <signal.h>
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <unistd.h>
66 #include <errno.h>
67 #include <ctype.h>
68 #include <netdb.h>
69 #include <setjmp.h>
70 #include <syslog.h>
71 #include <sys/param.h>
72 #include <fcntl.h>
73 #include <pwd.h>
74 #include <string.h>
75 #include <priv_utils.h>
76 #include "tftpcommon.h"
77 
78 #define	TIMEOUT		5
79 #define	DELAY_SECS	3
80 #define	DALLYSECS 60
81 
82 #define	SYSLOG_MSG(message) \
83 	(syslog((((errno == ENETUNREACH) || (errno == EHOSTUNREACH) || \
84 		(errno == ECONNREFUSED)) ? LOG_WARNING : LOG_ERR), message))
85 
86 static int			rexmtval = TIMEOUT;
87 static int			maxtimeout = 5*TIMEOUT;
88 static int			securetftp;
89 static int			debug;
90 static int			disable_pnp;
91 static int			standalone;
92 static uid_t			uid_nobody = UID_NOBODY;
93 static uid_t			gid_nobody = GID_NOBODY;
94 static int			reqsock = -1;
95 				/* file descriptor of request socket */
96 static socklen_t		fromlen;
97 static socklen_t		fromplen;
98 static struct sockaddr_storage	client;
99 static struct sockaddr_in6 	*sin6_ptr;
100 static struct sockaddr_in	*sin_ptr;
101 static struct sockaddr_in6	*from6_ptr;
102 static struct sockaddr_in	*from_ptr;
103 static int			addrfmly;
104 static int			peer;
105 static off_t			tsize;
106 static tftpbuf			ackbuf;
107 static struct sockaddr_storage	from;
108 static boolean_t		tsize_set;
109 static pid_t			child;
110 				/* pid of child handling delayed replys */
111 static int			delay_fd [2];
112 				/* pipe for communicating with child */
113 static FILE			*file;
114 static char			*filename;
115 
116 static union {
117 	struct tftphdr	hdr;
118 	char		data[SEGSIZE + 4];
119 } buf;
120 
121 static union {
122 	struct tftphdr	hdr;
123 	char		data[SEGSIZE];
124 } oackbuf;
125 
126 struct	delay_info {
127 	long	timestamp;		/* time request received */
128 	int	ecode;			/* error code to return */
129 	struct	sockaddr_storage from;	/* address of client */
130 };
131 
132 int	blocksize = SEGSIZE;	/* Number of data bytes in a DATA packet */
133 
134 /*
135  * Default directory for unqualified names
136  * Used by TFTP boot procedures
137  */
138 static char	*homedir = "/tftpboot";
139 
140 struct formats {
141 	char	*f_mode;
142 	int	(*f_validate)(int);
143 	void	(*f_send)(struct formats *, int);
144 	void	(*f_recv)(struct formats *, int);
145 	int	f_convert;
146 };
147 
148 static void	delayed_responder(void);
149 static void	tftp(struct tftphdr *, int);
150 static int	validate_filename(int);
151 static void	tftpd_sendfile(struct formats *, int);
152 static void	tftpd_recvfile(struct formats *, int);
153 static void	nak(int);
154 static char	*blksize_handler(int, char *, int *);
155 static char	*timeout_handler(int, char *, int *);
156 static char	*tsize_handler(int, char *, int *);
157 
158 static struct formats formats[] = {
159 	{ "netascii",	validate_filename, tftpd_sendfile, tftpd_recvfile, 1 },
160 	{ "octet",	validate_filename, tftpd_sendfile, tftpd_recvfile, 0 },
161 	{ NULL }
162 };
163 
164 struct options {
165 	char	*opt_name;
166 	char	*(*opt_handler)(int, char *, int *);
167 };
168 
169 static struct options options[] = {
170 	{ "blksize",	blksize_handler },
171 	{ "timeout",	timeout_handler },
172 	{ "tsize",	tsize_handler },
173 	{ NULL }
174 };
175 
176 static char		optbuf[MAX_OPTVAL_LEN];
177 static int		timeout;
178 static sigjmp_buf	timeoutbuf;
179 
180 int
181 main(int argc, char **argv)
182 {
183 	struct tftphdr *tp;
184 	int n;
185 	int c;
186 	struct	passwd *pwd;		/* for "nobody" entry */
187 	struct in_addr ipv4addr;
188 	char abuf[INET6_ADDRSTRLEN];
189 	socklen_t addrlen;
190 
191 	openlog("tftpd", LOG_PID, LOG_DAEMON);
192 
193 	pwd = getpwnam("nobody");
194 	if (pwd != NULL) {
195 		uid_nobody = pwd->pw_uid;
196 		gid_nobody = pwd->pw_gid;
197 	}
198 
199 	(void) __init_daemon_priv(
200 	    PU_LIMITPRIVS,
201 	    uid_nobody, gid_nobody,
202 	    PRIV_PROC_FORK, PRIV_PROC_CHROOT, PRIV_NET_PRIVADDR, NULL);
203 
204 	/*
205 	 *  Limit set is still "all."  Trim it down to just what we need:
206 	 *  fork and chroot.
207 	 */
208 	(void) priv_set(PRIV_SET, PRIV_ALLSETS,
209 	    PRIV_PROC_FORK, PRIV_PROC_CHROOT, PRIV_NET_PRIVADDR, NULL);
210 	(void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL);
211 	(void) priv_set(PRIV_SET, PRIV_INHERITABLE, NULL);
212 
213 	while ((c = getopt(argc, argv, "dspS")) != EOF)
214 		switch (c) {
215 		case 'd':		/* enable debug */
216 			debug++;
217 			continue;
218 		case 's':		/* secure daemon */
219 			securetftp = 1;
220 			continue;
221 		case 'p':		/* disable name pnp mapping */
222 			disable_pnp = 1;
223 			continue;
224 		case 'S':
225 			standalone = 1;
226 			continue;
227 		case '?':
228 		default:
229 usage:
230 			(void) fprintf(stderr,
231 			    "usage:  %s [-spd] [home-directory]\n", argv[0]);
232 			for (; optind < argc; optind++)
233 				syslog(LOG_ERR, "bad argument %s",
234 				    argv[optind]);
235 			exit(1);
236 		}
237 
238 	if (optind < argc)
239 		if (optind == argc - 1 && *argv [optind] == '/')
240 			homedir = argv [optind];
241 		else
242 			goto usage;
243 
244 	if (pipe(delay_fd) < 0) {
245 		syslog(LOG_ERR, "pipe (main): %m");
246 		exit(1);
247 	}
248 
249 	(void) sigset(SIGCHLD, SIG_IGN); /* no zombies please */
250 
251 	if (standalone) {
252 		socklen_t clientlen;
253 
254 		sin6_ptr = (struct sockaddr_in6 *)&client;
255 		clientlen = sizeof (struct sockaddr_in6);
256 		reqsock = socket(AF_INET6, SOCK_DGRAM, 0);
257 		if (reqsock == -1) {
258 			perror("socket");
259 			exit(1);
260 		}
261 		(void) memset(&client, 0, clientlen);
262 		sin6_ptr->sin6_family = AF_INET6;
263 		sin6_ptr->sin6_port = htons(IPPORT_TFTP);
264 
265 		/* Enable privilege as tftp port is < 1024 */
266 		(void) priv_set(PRIV_SET,
267 		    PRIV_EFFECTIVE, PRIV_NET_PRIVADDR, NULL);
268 		if (bind(reqsock, (struct sockaddr *)&client,
269 		    clientlen) == -1) {
270 			perror("bind");
271 			exit(1);
272 		}
273 		(void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL);
274 
275 		if (debug)
276 			(void) puts("running in standalone mode...");
277 	} else {
278 		/* request socket passed on fd 0 by inetd */
279 		reqsock = 0;
280 	}
281 	if (debug) {
282 		int on = 1;
283 
284 		(void) setsockopt(reqsock, SOL_SOCKET, SO_DEBUG,
285 		    (char *)&on, sizeof (on));
286 	}
287 
288 	(void) chdir(homedir);
289 
290 	(void) priv_set(PRIV_SET, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
291 	if ((child = fork()) < 0) {
292 		syslog(LOG_ERR, "fork (main): %m");
293 		exit(1);
294 	}
295 	(void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL);
296 
297 	if (child == 0) {
298 		(void) priv_set(PRIV_SET, PRIV_ALLSETS, NULL);
299 		delayed_responder();
300 	} /* child */
301 
302 	/* close read side of pipe */
303 	(void) close(delay_fd[0]);
304 
305 
306 	/*
307 	 * Top level handling of incomming tftp requests.  Read a request
308 	 * and pass it off to be handled.  If request is valid, handling
309 	 * forks off and parent returns to this loop.  If no new requests
310 	 * are received for DALLYSECS, exit and return to inetd.
311 	 */
312 
313 	for (;;) {
314 		fd_set readfds;
315 		struct timeval dally;
316 
317 		FD_ZERO(&readfds);
318 		FD_SET(reqsock, &readfds);
319 		dally.tv_sec = DALLYSECS;
320 		dally.tv_usec = 0;
321 
322 		n = select(reqsock + 1, &readfds, NULL, NULL, &dally);
323 		if (n < 0) {
324 			if (errno == EINTR)
325 				continue;
326 			syslog(LOG_ERR, "select: %m");
327 			(void) kill(child, SIGKILL);
328 			exit(1);
329 		}
330 		if (n == 0) {
331 			/* Select timed out.  Its time to die. */
332 			if (standalone)
333 				continue;
334 			else {
335 				(void) kill(child, SIGKILL);
336 				exit(0);
337 			}
338 		}
339 		addrlen = sizeof (from);
340 		if (getsockname(reqsock, (struct sockaddr  *)&from,
341 		    &addrlen) < 0) {
342 			syslog(LOG_ERR, "getsockname: %m");
343 			exit(1);
344 		}
345 
346 		switch (from.ss_family) {
347 		case AF_INET:
348 			fromlen = (socklen_t)sizeof (struct sockaddr_in);
349 			break;
350 		case AF_INET6:
351 			fromlen = (socklen_t)sizeof (struct sockaddr_in6);
352 			break;
353 		default:
354 			syslog(LOG_ERR,
355 			    "Unknown address Family on peer connection %d",
356 			    from.ss_family);
357 			exit(1);
358 		}
359 
360 		n = recvfrom(reqsock, &buf, sizeof (buf), 0,
361 		    (struct sockaddr *)&from, &fromlen);
362 		if (n < 0) {
363 			if (errno == EINTR)
364 				continue;
365 			if (standalone)
366 				perror("recvfrom");
367 			else
368 				syslog(LOG_ERR, "recvfrom: %m");
369 			(void) kill(child, SIGKILL);
370 			exit(1);
371 		}
372 
373 		(void) alarm(0);
374 
375 		switch (from.ss_family) {
376 		case AF_INET:
377 			addrfmly = AF_INET;
378 			fromplen = sizeof (struct sockaddr_in);
379 			sin_ptr = (struct sockaddr_in *)&client;
380 			(void) memset(&client, 0, fromplen);
381 			sin_ptr->sin_family = AF_INET;
382 			break;
383 		case AF_INET6:
384 			addrfmly = AF_INET6;
385 			fromplen = sizeof (struct sockaddr_in6);
386 			sin6_ptr = (struct sockaddr_in6 *)&client;
387 			(void) memset(&client, 0, fromplen);
388 			sin6_ptr->sin6_family = AF_INET6;
389 			break;
390 		default:
391 			syslog(LOG_ERR,
392 			    "Unknown address Family on peer connection");
393 			exit(1);
394 		}
395 		peer = socket(addrfmly, SOCK_DGRAM, 0);
396 		if (peer < 0) {
397 			if (standalone)
398 				perror("socket (main)");
399 			else
400 				syslog(LOG_ERR, "socket (main): %m");
401 			(void) kill(child, SIGKILL);
402 			exit(1);
403 		}
404 		if (debug) {
405 			int on = 1;
406 
407 			(void) setsockopt(peer, SOL_SOCKET, SO_DEBUG,
408 			    (char *)&on, sizeof (on));
409 		}
410 
411 		if (bind(peer, (struct sockaddr *)&client, fromplen) < 0) {
412 			if (standalone)
413 				perror("bind (main)");
414 			else
415 				syslog(LOG_ERR, "bind (main): %m");
416 			(void) kill(child, SIGKILL);
417 			exit(1);
418 		}
419 		if (standalone && debug) {
420 			sin6_ptr = (struct sockaddr_in6 *)&client;
421 			from6_ptr = (struct sockaddr_in6 *)&from;
422 			if (IN6_IS_ADDR_V4MAPPED(&from6_ptr->sin6_addr)) {
423 				IN6_V4MAPPED_TO_INADDR(&from6_ptr->sin6_addr,
424 				    &ipv4addr);
425 				(void) inet_ntop(AF_INET, &ipv4addr, abuf,
426 				    sizeof (abuf));
427 			} else {
428 				(void) inet_ntop(AF_INET6,
429 				    &from6_ptr->sin6_addr, abuf,
430 				    sizeof (abuf));
431 			}
432 			/* get local port */
433 			if (getsockname(peer, (struct sockaddr *)&client,
434 			    &fromplen) < 0)
435 				perror("getsockname (main)");
436 			(void) fprintf(stderr,
437 			    "request from %s port %d; local port %d\n",
438 			    abuf, from6_ptr->sin6_port, sin6_ptr->sin6_port);
439 		}
440 		tp = &buf.hdr;
441 		tp->th_opcode = ntohs((ushort_t)tp->th_opcode);
442 		if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
443 			tftp(tp, n);
444 
445 		(void) close(peer);
446 		(void) fclose(file);
447 	}
448 
449 	/*NOTREACHED*/
450 	return (0);
451 }
452 
453 static void
454 delayed_responder(void)
455 {
456 	struct delay_info dinfo;
457 	long now;
458 
459 	/* we don't use the descriptors passed in to the parent */
460 	(void) close(0);
461 	(void) close(1);
462 	if (standalone)
463 		(void) close(reqsock);
464 
465 	/* close write side of pipe */
466 	(void) close(delay_fd[1]);
467 
468 	for (;;) {
469 		int n;
470 
471 		if ((n = read(delay_fd[0], &dinfo,
472 		    sizeof (dinfo))) != sizeof (dinfo)) {
473 			if (n < 0) {
474 				if (errno == EINTR)
475 					continue;
476 				if (standalone)
477 					perror("read from pipe "
478 					    "(delayed responder)");
479 				else
480 					syslog(LOG_ERR, "read from pipe: %m");
481 			}
482 			exit(1);
483 		}
484 		switch (dinfo.from.ss_family) {
485 		case AF_INET:
486 			addrfmly = AF_INET;
487 			fromplen = sizeof (struct sockaddr_in);
488 			sin_ptr = (struct sockaddr_in *)&client;
489 			(void) memset(&client, 0, fromplen);
490 			sin_ptr->sin_family = AF_INET;
491 			break;
492 		case AF_INET6:
493 			addrfmly = AF_INET6;
494 			fromplen = sizeof (struct sockaddr_in6);
495 			sin6_ptr = (struct sockaddr_in6 *)&client;
496 			(void) memset(&client, 0, fromplen);
497 			sin6_ptr->sin6_family = AF_INET6;
498 			break;
499 		}
500 		peer = socket(addrfmly, SOCK_DGRAM, 0);
501 		if (peer == -1) {
502 			if (standalone)
503 				perror("socket (delayed responder)");
504 			else
505 				syslog(LOG_ERR, "socket (delay): %m");
506 			exit(1);
507 		}
508 		if (debug) {
509 			int on = 1;
510 
511 			(void) setsockopt(peer, SOL_SOCKET, SO_DEBUG,
512 			    (char *)&on, sizeof (on));
513 		}
514 
515 		if (bind(peer, (struct sockaddr *)&client, fromplen) < 0) {
516 			if (standalone)
517 				perror("bind (delayed responder)");
518 			else
519 				syslog(LOG_ERR, "bind (delay): %m");
520 			exit(1);
521 		}
522 		if (client.ss_family == AF_INET) {
523 			from_ptr = (struct sockaddr_in *)&dinfo.from;
524 			from_ptr->sin_family = AF_INET;
525 		} else {
526 			from6_ptr = (struct sockaddr_in6 *)&dinfo.from;
527 			from6_ptr->sin6_family = AF_INET6;
528 		}
529 		/*
530 		 * Since a request hasn't been received from the client
531 		 * before the delayed responder process is forked, the
532 		 * from variable is uninitialized.  So set it to contain
533 		 * the client address.
534 		 */
535 		from = dinfo.from;
536 
537 		/*
538 		 * only sleep if DELAY_SECS has not elapsed since
539 		 * original request was received.  Ensure that `now'
540 		 * is not earlier than `dinfo.timestamp'
541 		 */
542 		now = time(0);
543 		if ((uint_t)(now - dinfo.timestamp) < DELAY_SECS)
544 			(void) sleep(DELAY_SECS - (now - dinfo.timestamp));
545 		nak(dinfo.ecode);
546 		(void) close(peer);
547 	} /* for */
548 
549 	/* NOTREACHED */
550 }
551 
552 /*
553  * Handle the Blocksize option.
554  * Return the blksize option value string to include in the OACK reply.
555  */
556 /*ARGSUSED*/
557 static char *
558 blksize_handler(int opcode, char *optval, int *errcode)
559 {
560 	char *endp;
561 	int value;
562 
563 	*errcode = -1;
564 	errno = 0;
565 	value = (int)strtol(optval, &endp, 10);
566 	if (errno != 0 || value < MIN_BLKSIZE || *endp != '\0')
567 		return (NULL);
568 	/*
569 	 * As the blksize value in the OACK reply can be less than the value
570 	 * requested, to support broken clients if the value requested is larger
571 	 * than allowed in the RFC, reply with the maximum value permitted.
572 	 */
573 	if (value > MAX_BLKSIZE)
574 		value = MAX_BLKSIZE;
575 
576 	blocksize = value;
577 	(void) snprintf(optbuf, sizeof (optbuf), "%d", blocksize);
578 	return (optbuf);
579 }
580 
581 /*
582  * Handle the Timeout Interval option.
583  * Return the timeout option value string to include in the OACK reply.
584  */
585 /*ARGSUSED*/
586 static char *
587 timeout_handler(int opcode, char *optval, int *errcode)
588 {
589 	char *endp;
590 	int value;
591 
592 	*errcode = -1;
593 	errno = 0;
594 	value = (int)strtol(optval, &endp, 10);
595 	if (errno != 0 || *endp != '\0')
596 		return (NULL);
597 	/*
598 	 * The timeout value in the OACK reply must match the value specified
599 	 * by the client, so if an invalid timeout is requested don't include
600 	 * the timeout option in the OACK reply.
601 	 */
602 	if (value < MIN_TIMEOUT || value > MAX_TIMEOUT)
603 		return (NULL);
604 
605 	rexmtval = value;
606 	maxtimeout = 5 * rexmtval;
607 	(void) snprintf(optbuf, sizeof (optbuf), "%d", rexmtval);
608 	return (optbuf);
609 }
610 
611 /*
612  * Handle the Transfer Size option.
613  * Return the tsize option value string to include in the OACK reply.
614  */
615 static char *
616 tsize_handler(int opcode, char *optval, int *errcode)
617 {
618 	char *endp;
619 	longlong_t value;
620 
621 	*errcode = -1;
622 	errno = 0;
623 	value = strtoll(optval, &endp, 10);
624 	if (errno != 0 || value < 0 || *endp != '\0')
625 		return (NULL);
626 
627 	if (opcode == RRQ) {
628 		if (tsize_set == B_FALSE)
629 			return (NULL);
630 		/*
631 		 * The tsize value should be 0 for a read request, but to
632 		 * support broken clients we don't check that it is.
633 		 */
634 	} else {
635 #if _FILE_OFFSET_BITS == 32
636 		if (value > MAXOFF_T) {
637 			*errcode = ENOSPACE;
638 			return (NULL);
639 		}
640 #endif
641 		tsize = value;
642 		tsize_set = B_TRUE;
643 	}
644 	(void) snprintf(optbuf, sizeof (optbuf), OFF_T_FMT, tsize);
645 	return (optbuf);
646 }
647 
648 /*
649  * Process any options included by the client in the request packet.
650  * Return the size of the OACK reply packet built or 0 for no OACK reply.
651  */
652 static int
653 process_options(int opcode, char *opts, char *endopts)
654 {
655 	char *cp, *optname, *optval, *ostr, *oackend;
656 	struct tftphdr *oackp;
657 	int i, errcode;
658 
659 	/*
660 	 * To continue to interoperate with broken TFTP clients, ignore
661 	 * null padding appended to requests which don't include options.
662 	 */
663 	cp = opts;
664 	while ((cp < endopts) && (*cp == '\0'))
665 		cp++;
666 	if (cp == endopts)
667 		return (0);
668 
669 	/*
670 	 * Construct an Option ACKnowledgement packet if any requested option
671 	 * is recognized.
672 	 */
673 	oackp = &oackbuf.hdr;
674 	oackend = oackbuf.data + sizeof (oackbuf.data);
675 	oackp->th_opcode = htons((ushort_t)OACK);
676 	cp = (char *)&oackp->th_stuff;
677 	while (opts < endopts) {
678 		optname = opts;
679 		if ((optval = next_field(optname, endopts)) == NULL) {
680 			nak(EOPTNEG);
681 			exit(1);
682 		}
683 		if ((opts = next_field(optval, endopts)) == NULL) {
684 			nak(EOPTNEG);
685 			exit(1);
686 		}
687 		for (i = 0; options[i].opt_name != NULL; i++) {
688 			if (strcasecmp(optname, options[i].opt_name) == 0)
689 				break;
690 		}
691 		if (options[i].opt_name != NULL) {
692 			ostr = options[i].opt_handler(opcode, optval, &errcode);
693 			if (ostr != NULL) {
694 				cp += strlcpy(cp, options[i].opt_name,
695 				    oackend - cp) + 1;
696 				if (cp <= oackend)
697 					cp += strlcpy(cp, ostr, oackend - cp)
698 					    + 1;
699 
700 				if (cp > oackend) {
701 					nak(EOPTNEG);
702 					exit(1);
703 				}
704 			} else if (errcode >= 0) {
705 				nak(errcode);
706 				exit(1);
707 			}
708 		}
709 	}
710 	if (cp != (char *)&oackp->th_stuff)
711 		return (cp - oackbuf.data);
712 	return (0);
713 }
714 
715 /*
716  * Handle access errors caused by client requests.
717  */
718 
719 static void
720 delay_exit(int ecode)
721 {
722 	struct delay_info dinfo;
723 
724 	/*
725 	 * The most likely cause of an error here is that
726 	 * someone has broadcast an RRQ packet because s/he's
727 	 * trying to boot and doesn't know who the server is.
728 	 * Rather then sending an ERROR packet immediately, we
729 	 * wait a while so that the real server has a better chance
730 	 * of getting through (in case client has lousy Ethernet
731 	 * interface).  We write to a child that handles delayed
732 	 * ERROR packets to avoid delaying service to new
733 	 * requests.  Of course, we would rather just not answer
734 	 * RRQ packets that are broadcasted, but there's no way
735 	 * for a user process to determine this.
736 	 */
737 
738 	dinfo.timestamp = time(0);
739 
740 	/*
741 	 * If running in secure mode, we map all errors to EACCESS
742 	 * so that the client gets no information about which files
743 	 * or directories exist.
744 	 */
745 	if (securetftp)
746 		dinfo.ecode = EACCESS;
747 	else
748 		dinfo.ecode = ecode;
749 
750 	dinfo.from = from;
751 	if (write(delay_fd[1], &dinfo, sizeof (dinfo)) !=
752 	    sizeof (dinfo)) {
753 		syslog(LOG_ERR, "delayed write failed.");
754 		(void) kill(child, SIGKILL);
755 		exit(1);
756 	}
757 	exit(0);
758 }
759 
760 /*
761  * Handle initial connection protocol.
762  */
763 static void
764 tftp(struct tftphdr *tp, int size)
765 {
766 	char *cp;
767 	int readmode, ecode;
768 	struct formats *pf;
769 	char *mode;
770 	int fd;
771 	static boolean_t firsttime = B_TRUE;
772 	int oacklen;
773 	struct stat statb;
774 
775 	readmode = (tp->th_opcode == RRQ);
776 	filename = (char *)&tp->th_stuff;
777 	mode = next_field(filename, &buf.data[size]);
778 	cp = (mode != NULL) ? next_field(mode, &buf.data[size]) : NULL;
779 	if (cp == NULL) {
780 		nak(EBADOP);
781 		exit(1);
782 	}
783 	if (debug && standalone) {
784 		(void) fprintf(stderr, "%s for %s %s ",
785 		    readmode ? "RRQ" : "WRQ", filename, mode);
786 		print_options(stderr, cp, size + buf.data - cp);
787 		(void) putc('\n', stderr);
788 	}
789 	for (pf = formats; pf->f_mode != NULL; pf++)
790 		if (strcasecmp(pf->f_mode, mode) == 0)
791 			break;
792 	if (pf->f_mode == NULL) {
793 		nak(EBADOP);
794 		exit(1);
795 	}
796 
797 	/*
798 	 * XXX fork a new process to handle this request before
799 	 * chroot(), otherwise the parent won't be able to create a
800 	 * new socket as that requires library access to system files
801 	 * and devices.
802 	 */
803 	(void) priv_set(PRIV_SET, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
804 	switch (fork()) {
805 	case -1:
806 		syslog(LOG_ERR, "fork (tftp): %m");
807 		(void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL);
808 		return;
809 	case 0:
810 		(void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL);
811 		break;
812 	default:
813 		(void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL);
814 		return;
815 	}
816 
817 	/*
818 	 * Try to see if we can access the file.  The access can still
819 	 * fail later if we are running in secure mode because of
820 	 * the chroot() call.  We only want to execute the chroot()  once.
821 	 */
822 	if (securetftp && firsttime) {
823 		(void) priv_set(
824 		    PRIV_SET, PRIV_EFFECTIVE, PRIV_PROC_CHROOT, NULL);
825 		if (chroot(homedir) == -1) {
826 			syslog(LOG_ERR,
827 			    "tftpd: cannot chroot to directory %s: %m\n",
828 			    homedir);
829 			delay_exit(EACCESS);
830 		}
831 		else
832 		{
833 			firsttime = B_FALSE;
834 		}
835 		(void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL);
836 		(void) chdir("/");  /* cd to  new root */
837 	}
838 	(void) priv_set(PRIV_SET, PRIV_ALLSETS, NULL);
839 
840 	ecode = (*pf->f_validate)(tp->th_opcode);
841 	if (ecode != 0)
842 		delay_exit(ecode);
843 
844 	/* we don't use the descriptors passed in to the parent */
845 	(void) close(STDIN_FILENO);
846 	(void) close(STDOUT_FILENO);
847 
848 	/*
849 	 * Try to open file as low-priv setuid/setgid.  Note that
850 	 * a chroot() has already been done.
851 	 */
852 	fd = open(filename,
853 	    (readmode ? O_RDONLY : (O_WRONLY|O_TRUNC)) | O_NONBLOCK);
854 	if ((fd < 0) || (fstat(fd, &statb) < 0))
855 		delay_exit((errno == ENOENT) ? ENOTFOUND : EACCESS);
856 
857 	if (((statb.st_mode & ((readmode) ? S_IROTH : S_IWOTH)) == 0) ||
858 	    ((statb.st_mode & S_IFMT) != S_IFREG))
859 		delay_exit(EACCESS);
860 
861 	file = fdopen(fd, readmode ? "r" : "w");
862 	if (file == NULL)
863 		delay_exit(errno + 100);
864 
865 	/* Don't know the size of transfers which involve conversion */
866 	tsize_set = (readmode && (pf->f_convert == 0));
867 	if (tsize_set)
868 		tsize = statb.st_size;
869 
870 	/* Deal with any options sent by the client */
871 	oacklen = process_options(tp->th_opcode, cp, buf.data + size);
872 
873 	if (tp->th_opcode == WRQ)
874 		(*pf->f_recv)(pf, oacklen);
875 	else
876 		(*pf->f_send)(pf, oacklen);
877 
878 	exit(0);
879 }
880 
881 /*
882  *	Maybe map filename into another one.
883  *
884  *	For PNP, we get TFTP boot requests for filenames like
885  *	<Unknown Hex IP Addr>.<Architecture Name>.   We must
886  *	map these to 'pnp.<Architecture Name>'.  Note that
887  *	uppercase is mapped to lowercase in the architecture names.
888  *
889  *	For names <Hex IP Addr> there are two cases.  First,
890  *	it may be a buggy prom that omits the architecture code.
891  *	So first check if <Hex IP Addr>.<arch> is on the filesystem.
892  *	Second, this is how most Sun3s work; assume <arch> is sun3.
893  */
894 
895 static char *
896 pnp_check(char *origname)
897 {
898 	static char buf [MAXNAMLEN + 1];
899 	char *arch, *s, *bufend;
900 	in_addr_t ipaddr;
901 	int len = (origname ? strlen(origname) : 0);
902 	DIR *dir;
903 	struct dirent *dp;
904 
905 	if (securetftp || disable_pnp || len < 8 || len > 14)
906 		return (NULL);
907 
908 	/*
909 	 * XXX see if this cable allows pnp; if not, return NULL
910 	 * Requires YP support for determining this!
911 	 */
912 
913 	ipaddr = htonl(strtol(origname, &arch, 16));
914 	if ((arch == NULL) || (len > 8 && *arch != '.'))
915 		return (NULL);
916 	if (len == 8)
917 		arch = "SUN3";
918 	else
919 		arch++;
920 
921 	/*
922 	 * Allow <Hex IP Addr>* filename request to to be
923 	 * satisfied by <Hex IP Addr><Any Suffix> rather
924 	 * than enforcing this to be Sun3 systems.  Also serves
925 	 * to make case of suffix a don't-care.
926 	 */
927 	if ((dir = opendir(homedir)) == NULL)
928 		return (NULL);
929 	while ((dp = readdir(dir)) != NULL) {
930 		if (strncmp(origname, dp->d_name, 8) == 0) {
931 			(void) strlcpy(buf, dp->d_name, sizeof (buf));
932 			(void) closedir(dir);
933 			return (buf);
934 		}
935 	}
936 	(void) closedir(dir);
937 
938 	/*
939 	 * XXX maybe call YP master for most current data iff
940 	 * pnp is enabled.
941 	 */
942 
943 	/*
944 	 * only do mapping PNP boot file name for machines that
945 	 * are not in the hosts database.
946 	 */
947 	if (gethostbyaddr((char *)&ipaddr, sizeof (ipaddr), AF_INET) != NULL)
948 		return (NULL);
949 
950 	s = buf + strlcpy(buf, "pnp.", sizeof (buf));
951 	bufend = &buf[sizeof (buf) - 1];
952 	while ((*arch != '\0') && (s < bufend))
953 		*s++ = tolower (*arch++);
954 	*s = '\0';
955 	return (buf);
956 }
957 
958 
959 /*
960  * Try to validate filename. If the filename doesn't exist try PNP mapping.
961  */
962 static int
963 validate_filename(int mode)
964 {
965 	struct stat stbuf;
966 	char *origfile;
967 
968 	if (stat(filename, &stbuf) < 0) {
969 		if (errno != ENOENT)
970 			return (EACCESS);
971 		if (mode == WRQ)
972 			return (ENOTFOUND);
973 
974 		/* try to map requested filename into a pnp filename */
975 		origfile = filename;
976 		filename = pnp_check(origfile);
977 		if (filename == NULL)
978 			return (ENOTFOUND);
979 
980 		if (stat(filename, &stbuf) < 0)
981 			return (errno == ENOENT ? ENOTFOUND : EACCESS);
982 		syslog(LOG_NOTICE, "%s -> %s\n", origfile, filename);
983 	}
984 
985 	return (0);
986 }
987 
988 /* ARGSUSED */
989 static void
990 timer(int signum)
991 {
992 	timeout += rexmtval;
993 	if (timeout >= maxtimeout)
994 		exit(1);
995 	siglongjmp(timeoutbuf, 1);
996 }
997 
998 /*
999  * Send the requested file.
1000  */
1001 static void
1002 tftpd_sendfile(struct formats *pf, int oacklen)
1003 {
1004 	struct tftphdr *dp;
1005 	volatile ushort_t block = 1;
1006 	int size, n, serrno;
1007 
1008 	if (oacklen != 0) {
1009 		(void) sigset(SIGALRM, timer);
1010 		timeout = 0;
1011 		(void) sigsetjmp(timeoutbuf, 1);
1012 		if (debug && standalone) {
1013 			(void) fputs("Sending OACK ", stderr);
1014 			print_options(stderr, (char *)&oackbuf.hdr.th_stuff,
1015 			    oacklen - 2);
1016 			(void) putc('\n', stderr);
1017 		}
1018 		if (sendto(peer, &oackbuf, oacklen, 0,
1019 		    (struct sockaddr *)&from, fromplen) != oacklen) {
1020 			if (debug && standalone) {
1021 				serrno = errno;
1022 				perror("sendto (oack)");
1023 				errno = serrno;
1024 			}
1025 			SYSLOG_MSG("sendto (oack): %m");
1026 			goto abort;
1027 		}
1028 		(void) alarm(rexmtval); /* read the ack */
1029 		for (;;) {
1030 			(void) sigrelse(SIGALRM);
1031 			n = recv(peer, &ackbuf, sizeof (ackbuf), 0);
1032 			(void) sighold(SIGALRM);
1033 			if (n < 0) {
1034 				if (errno == EINTR)
1035 					continue;
1036 				serrno = errno;
1037 				SYSLOG_MSG("recv (ack): %m");
1038 				if (debug && standalone) {
1039 					errno = serrno;
1040 					perror("recv (ack)");
1041 				}
1042 				goto abort;
1043 			}
1044 			ackbuf.tb_hdr.th_opcode =
1045 			    ntohs((ushort_t)ackbuf.tb_hdr.th_opcode);
1046 			ackbuf.tb_hdr.th_block =
1047 			    ntohs((ushort_t)ackbuf.tb_hdr.th_block);
1048 
1049 			if (ackbuf.tb_hdr.th_opcode == ERROR) {
1050 				if (debug && standalone) {
1051 					(void) fprintf(stderr,
1052 					    "received ERROR %d",
1053 					    ackbuf.tb_hdr.th_code);
1054 					if (n > 4)
1055 						(void) fprintf(stderr,
1056 						    " %.*s", n - 4,
1057 						    ackbuf.tb_hdr.th_msg);
1058 					(void) putc('\n', stderr);
1059 				}
1060 				goto abort;
1061 			}
1062 
1063 			if (ackbuf.tb_hdr.th_opcode == ACK) {
1064 				if (debug && standalone)
1065 					(void) fprintf(stderr,
1066 					    "received ACK for block %d\n",
1067 					    ackbuf.tb_hdr.th_block);
1068 				if (ackbuf.tb_hdr.th_block == 0)
1069 					break;
1070 				/*
1071 				 * Don't resend the OACK, avoids getting stuck
1072 				 * in an OACK/ACK loop if the client keeps
1073 				 * replying with a bad ACK. Client will either
1074 				 * send a good ACK or timeout sending bad ones.
1075 				 */
1076 			}
1077 		}
1078 		cancel_alarm();
1079 	}
1080 	dp = r_init();
1081 	do {
1082 		(void) sigset(SIGALRM, timer);
1083 		size = readit(file, &dp, pf->f_convert);
1084 		if (size < 0) {
1085 			nak(errno + 100);
1086 			goto abort;
1087 		}
1088 		dp->th_opcode = htons((ushort_t)DATA);
1089 		dp->th_block = htons((ushort_t)block);
1090 		timeout = 0;
1091 		(void) sigsetjmp(timeoutbuf, 1);
1092 		if (debug && standalone)
1093 			(void) fprintf(stderr, "Sending DATA block %d\n",
1094 			    block);
1095 		if (sendto(peer, dp, size + 4, 0,
1096 		    (struct sockaddr *)&from,  fromplen) != size + 4) {
1097 			if (debug && standalone) {
1098 				serrno = errno;
1099 				perror("sendto (data)");
1100 				errno = serrno;
1101 			}
1102 			SYSLOG_MSG("sendto (data): %m");
1103 			goto abort;
1104 		}
1105 		read_ahead(file, pf->f_convert);
1106 		(void) alarm(rexmtval); /* read the ack */
1107 		for (;;) {
1108 			(void) sigrelse(SIGALRM);
1109 			n = recv(peer, &ackbuf, sizeof (ackbuf), 0);
1110 			(void) sighold(SIGALRM);
1111 			if (n < 0) {
1112 				if (errno == EINTR)
1113 					continue;
1114 				serrno = errno;
1115 				SYSLOG_MSG("recv (ack): %m");
1116 				if (debug && standalone) {
1117 					errno = serrno;
1118 					perror("recv (ack)");
1119 				}
1120 				goto abort;
1121 			}
1122 			ackbuf.tb_hdr.th_opcode =
1123 			    ntohs((ushort_t)ackbuf.tb_hdr.th_opcode);
1124 			ackbuf.tb_hdr.th_block =
1125 			    ntohs((ushort_t)ackbuf.tb_hdr.th_block);
1126 
1127 			if (ackbuf.tb_hdr.th_opcode == ERROR) {
1128 				if (debug && standalone) {
1129 					(void) fprintf(stderr,
1130 					    "received ERROR %d",
1131 					    ackbuf.tb_hdr.th_code);
1132 					if (n > 4)
1133 						(void) fprintf(stderr,
1134 						    " %.*s", n - 4,
1135 						    ackbuf.tb_hdr.th_msg);
1136 					(void) putc('\n', stderr);
1137 				}
1138 				goto abort;
1139 			}
1140 
1141 			if (ackbuf.tb_hdr.th_opcode == ACK) {
1142 				if (debug && standalone)
1143 					(void) fprintf(stderr,
1144 					    "received ACK for block %d\n",
1145 					    ackbuf.tb_hdr.th_block);
1146 				if (ackbuf.tb_hdr.th_block == block) {
1147 					break;
1148 				}
1149 				/*
1150 				 * Never resend the current DATA packet on
1151 				 * receipt of a duplicate ACK, doing so would
1152 				 * cause the "Sorcerer's Apprentice Syndrome".
1153 				 */
1154 			}
1155 		}
1156 		cancel_alarm();
1157 		block++;
1158 	} while (size == blocksize);
1159 
1160 abort:
1161 	cancel_alarm();
1162 	(void) fclose(file);
1163 }
1164 
1165 /* ARGSUSED */
1166 static void
1167 justquit(int signum)
1168 {
1169 	exit(0);
1170 }
1171 
1172 /*
1173  * Receive a file.
1174  */
1175 static void
1176 tftpd_recvfile(struct formats *pf, int oacklen)
1177 {
1178 	struct tftphdr *dp;
1179 	struct tftphdr *ap;    /* ack buffer */
1180 	ushort_t block = 0;
1181 	int n, size, acklen, serrno;
1182 
1183 	dp = w_init();
1184 	ap = &ackbuf.tb_hdr;
1185 	do {
1186 		(void) sigset(SIGALRM, timer);
1187 		timeout = 0;
1188 		if (oacklen == 0) {
1189 			ap->th_opcode = htons((ushort_t)ACK);
1190 			ap->th_block = htons((ushort_t)block);
1191 			acklen = 4;
1192 		} else {
1193 			/* copy OACK packet to the ack buffer ready to send */
1194 			(void) memcpy(&ackbuf, &oackbuf, oacklen);
1195 			acklen = oacklen;
1196 			oacklen = 0;
1197 		}
1198 		block++;
1199 		(void) sigsetjmp(timeoutbuf, 1);
1200 send_ack:
1201 		if (debug && standalone) {
1202 			if (ap->th_opcode == htons((ushort_t)ACK)) {
1203 				(void) fprintf(stderr,
1204 				    "Sending ACK for block %d\n", block - 1);
1205 			} else {
1206 				(void) fprintf(stderr, "Sending OACK ");
1207 				print_options(stderr, (char *)&ap->th_stuff,
1208 				    acklen - 2);
1209 				(void) putc('\n', stderr);
1210 			}
1211 		}
1212 		if (sendto(peer, &ackbuf, acklen, 0, (struct sockaddr *)&from,
1213 		    fromplen) != acklen) {
1214 			if (ap->th_opcode == htons((ushort_t)ACK)) {
1215 				if (debug && standalone) {
1216 					serrno = errno;
1217 					perror("sendto (ack)");
1218 					errno = serrno;
1219 				}
1220 				syslog(LOG_ERR, "sendto (ack): %m\n");
1221 			} else {
1222 				if (debug && standalone) {
1223 					serrno = errno;
1224 					perror("sendto (oack)");
1225 					errno = serrno;
1226 				}
1227 				syslog(LOG_ERR, "sendto (oack): %m\n");
1228 			}
1229 			goto abort;
1230 		}
1231 		if (write_behind(file, pf->f_convert) < 0) {
1232 			nak(errno + 100);
1233 			goto abort;
1234 		}
1235 		(void) alarm(rexmtval);
1236 		for (;;) {
1237 			(void) sigrelse(SIGALRM);
1238 			n = recv(peer, dp, blocksize + 4, 0);
1239 			(void) sighold(SIGALRM);
1240 			if (n < 0) { /* really? */
1241 				if (errno == EINTR)
1242 					continue;
1243 				syslog(LOG_ERR, "recv (data): %m");
1244 				goto abort;
1245 			}
1246 			dp->th_opcode = ntohs((ushort_t)dp->th_opcode);
1247 			dp->th_block = ntohs((ushort_t)dp->th_block);
1248 			if (dp->th_opcode == ERROR) {
1249 				cancel_alarm();
1250 				if (debug && standalone) {
1251 					(void) fprintf(stderr,
1252 					    "received ERROR %d", dp->th_code);
1253 					if (n > 4)
1254 						(void) fprintf(stderr,
1255 						    " %.*s", n - 4, dp->th_msg);
1256 					(void) putc('\n', stderr);
1257 				}
1258 				return;
1259 			}
1260 			if (dp->th_opcode == DATA) {
1261 				if (debug && standalone)
1262 					(void) fprintf(stderr,
1263 					    "Received DATA block %d\n",
1264 					    dp->th_block);
1265 				if (dp->th_block == block) {
1266 					break;   /* normal */
1267 				}
1268 				/* Re-synchronize with the other side */
1269 				if (synchnet(peer) < 0) {
1270 					nak(errno + 100);
1271 					goto abort;
1272 				}
1273 				if (dp->th_block == (block-1))
1274 					goto send_ack; /* rexmit */
1275 			}
1276 		}
1277 		cancel_alarm();
1278 		/*  size = write(file, dp->th_data, n - 4); */
1279 		size = writeit(file, &dp, n - 4, pf->f_convert);
1280 		if (size != (n - 4)) {
1281 			nak((size < 0) ? (errno + 100) : ENOSPACE);
1282 			goto abort;
1283 		}
1284 	} while (size == blocksize);
1285 	if (write_behind(file, pf->f_convert) < 0) {
1286 		nak(errno + 100);
1287 		goto abort;
1288 	}
1289 	n = fclose(file);	/* close data file */
1290 	file = NULL;
1291 	if (n == EOF) {
1292 		nak(errno + 100);
1293 		goto abort;
1294 	}
1295 
1296 	ap->th_opcode = htons((ushort_t)ACK);    /* send the "final" ack */
1297 	ap->th_block = htons((ushort_t)(block));
1298 	if (debug && standalone)
1299 		(void) fprintf(stderr, "Sending ACK for block %d\n", block);
1300 	if (sendto(peer, &ackbuf, 4, 0, (struct sockaddr *)&from,
1301 	    fromplen) == -1) {
1302 		if (debug && standalone)
1303 			perror("sendto (ack)");
1304 	}
1305 	(void) sigset(SIGALRM, justquit); /* just quit on timeout */
1306 	(void) alarm(rexmtval);
1307 	/* normally times out and quits */
1308 	n = recv(peer, dp, blocksize + 4, 0);
1309 	(void) alarm(0);
1310 	dp->th_opcode = ntohs((ushort_t)dp->th_opcode);
1311 	dp->th_block = ntohs((ushort_t)dp->th_block);
1312 	if (n >= 4 &&		/* if read some data */
1313 	    dp->th_opcode == DATA && /* and got a data block */
1314 	    block == dp->th_block) {	/* then my last ack was lost */
1315 		if (debug && standalone) {
1316 			(void) fprintf(stderr, "Sending ACK for block %d\n",
1317 			    block);
1318 		}
1319 		/* resend final ack */
1320 		if (sendto(peer, &ackbuf, 4, 0, (struct sockaddr *)&from,
1321 		    fromplen) == -1) {
1322 			if (debug && standalone)
1323 				perror("sendto (last ack)");
1324 		}
1325 	}
1326 
1327 abort:
1328 	cancel_alarm();
1329 	if (file != NULL)
1330 		(void) fclose(file);
1331 }
1332 
1333 /*
1334  * Send a nak packet (error message).
1335  * Error code passed in is one of the
1336  * standard TFTP codes, or a UNIX errno
1337  * offset by 100.
1338  * Handles connected as well as unconnected peer.
1339  */
1340 static void
1341 nak(int error)
1342 {
1343 	struct tftphdr *tp;
1344 	int length;
1345 	struct errmsg *pe;
1346 	int ret;
1347 
1348 	tp = &buf.hdr;
1349 	tp->th_opcode = htons((ushort_t)ERROR);
1350 	tp->th_code = htons((ushort_t)error);
1351 	for (pe = errmsgs; pe->e_code >= 0; pe++)
1352 		if (pe->e_code == error)
1353 			break;
1354 	if (pe->e_code < 0) {
1355 		pe->e_msg = strerror(error - 100);
1356 		tp->th_code = EUNDEF;   /* set 'undef' errorcode */
1357 	}
1358 	(void) strlcpy(tp->th_msg, (pe->e_msg != NULL) ? pe->e_msg : "UNKNOWN",
1359 	    sizeof (buf) - sizeof (struct tftphdr));
1360 	length = strlen(tp->th_msg);
1361 	length += sizeof (struct tftphdr);
1362 	if (debug && standalone)
1363 		(void) fprintf(stderr, "Sending NAK: %s\n", tp->th_msg);
1364 
1365 	ret = sendto(peer, &buf, length, 0, (struct sockaddr *)&from,
1366 	    fromplen);
1367 	if (ret == -1 && errno == EISCONN) {
1368 		/* Try without an address */
1369 		ret = send(peer, &buf, length, 0);
1370 	}
1371 	if (ret == -1) {
1372 		if (standalone)
1373 			perror("sendto (nak)");
1374 		else
1375 			syslog(LOG_ERR, "tftpd: nak: %m\n");
1376 	} else if (ret != length) {
1377 		if (standalone)
1378 			perror("sendto (nak) lost data");
1379 		else
1380 			syslog(LOG_ERR, "tftpd: nak: %d lost\n", length - ret);
1381 	}
1382 }
1383