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