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