NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bin/49868: tftpd(8) doesn't play well with clients that return acknowledgements to the broadcast address



	Hello.  Here are  patches which implement Christos request, as well as
documenting the change.  Any reason I shouldn't commit these?

-thanks
-Brian

Index: tftpd.8
===================================================================
RCS file: /cvsroot/src/libexec/tftpd/tftpd.8,v
retrieving revision 1.28
diff -u -r1.28 tftpd.8
--- tftpd.8	29 Apr 2010 21:34:04 -0000	1.28
+++ tftpd.8	30 Apr 2015 18:57:10 -0000
@@ -1,4 +1,4 @@
-.\"	$NetBSD$
+.\"	$NetBSD: tftpd.8,v 1.28 2010/04/29 21:34:04 wiz Exp $
 .\"
 .\" Copyright (c) 1983, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -39,7 +39,7 @@
 Internet Trivial File Transfer Protocol server
 .Sh SYNOPSIS
 .Nm
-.Op Fl cdln
+.Op Fl bcdln
 .Op Fl g Ar group
 .Op Fl p Ar pathsep
 .Op Fl s Ar directory
@@ -95,6 +95,12 @@
 .Pp
 The options are:
 .Bl -tag -width "XsXdirectoryX"
+.It Fl b
+Allow clients which return acknowledgements to the broadcast address to
+communicate with the tftp server.
+Some tftp clients, notably ones resident in the ROMs of older Cisco
+equipment, return their acknowledgements to the broadcast address rather
+than the server's unicast address.  
 .It Fl c
 Allow unrestricted creation of new files.
 Without this flag, only existing publicly writable files can be overwritten.

Index: tftpd.c
===================================================================
RCS file: /cvsroot/src/libexec/tftpd/tftpd.c,v
retrieving revision 1.43
diff -u -r1.43 tftpd.c
--- tftpd.c	4 Oct 2013 07:51:48 -0000	1.43
+++ tftpd.c	30 Apr 2015 18:57:30 -0000
@@ -1,4 +1,4 @@
-/*	$NetBSD$	*/
+/*	$NetBSD: tftpd.c,v 1.31.4.1 2011/11/02 19:58:23 riz Exp $	*/
 
 /*
  * Copyright (c) 1983, 1993
@@ -36,7 +36,7 @@
 #if 0
 static char sccsid[] = "@(#)tftpd.c	8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD$");
+__RCSID("$NetBSD: tftpd.c,v 1.43 2013/10/04 07:51:48 jnemeth Exp $");
 #endif
 #endif /* not lint */
 
@@ -110,6 +110,7 @@
 static char	pathsep = '\0';
 static char	*securedir;
 static int	unrestricted_writes;    /* uploaded files don't have to exist */
+static int	broadcast_client = 0; /* Some clients ack to the broadcast address */
 
 struct formats;
 
@@ -142,7 +143,7 @@
 {
 
 	syslog(LOG_ERR,
-    "Usage: %s [-cdln] [-g group] [-p pathsep] [-s directory] [-u user] [directory ...]",
+    "Usage: %s [-bcdln] [-g group] [-p pathsep] [-s directory] [-u user] [directory ...]",
 		    getprogname());
 	exit(1);
 }
@@ -172,8 +173,11 @@
 	curuid = getuid();
 	curgid = getgid();
 
-	while ((ch = getopt(argc, argv, "cdg:lnp:s:u:")) != -1)
+	while ((ch = getopt(argc, argv, "bcdg:lnp:s:u:")) != -1)
 		switch (ch) {
+		case 'b':
+			broadcast_client = 1;
+			break;
 		case 'c':
 			unrestricted_writes = 1;
 			break;
@@ -393,14 +397,17 @@
 		syslog(LOG_ERR, "socket: %m");
 		exit(1);
 	}
+	if (broadcast_client) {
+		soopt = 1;
+		if (setsockopt(peer, SOL_SOCKET, SO_BROADCAST, (void *) &soopt, sizeof(soopt)) < 0) {
+			syslog(LOG_ERR, "set SO_BROADCAST: %m");
+			exit(1);
+		}
+	}
 	if (bind(peer, (struct sockaddr *)&me, me.ss_len) < 0) {
 		syslog(LOG_ERR, "bind: %m");
 		exit(1);
 	}
-	if (connect(peer, (struct sockaddr *)&from, from.ss_len) < 0) {
-		syslog(LOG_ERR, "connect: %m");
-		exit(1);
-	}
 	soopt = 65536;	/* larger than we'll ever need */
 	if (setsockopt(peer, SOL_SOCKET, SO_SNDBUF, (void *) &soopt, sizeof(soopt)) < 0) {
 		syslog(LOG_ERR, "set SNDBUF: %m");
@@ -955,7 +962,7 @@
 send_data:
 		if (!etftp && debug)
 			syslog(LOG_DEBUG, "Send DATA %u", block);
-		if ((n = send(peer, dp, size + 4, 0)) != size + 4) {
+		if ((n = sendto(peer, dp, size + 4, 0, (struct sockaddr *)&from, fromlen)) != size + 4) {
 			syslog(LOG_ERR, "tftpd: write: %m");
 			goto abort;
 		}
@@ -963,7 +970,8 @@
 			read_ahead(file, tftp_blksize, pf->f_convert);
 		for ( ; ; ) {
 			alarm(rexmtval);        /* read the ack */
-			n = recv(peer, ackbuf, tftp_blksize, 0);
+			n = recvfrom(peer, ackbuf, tftp_blksize, 0,(struct sockaddr
+			*)&from, &fromlen );
 			alarm(0);
 			if (n < 0) {
 				syslog(LOG_ERR, "tftpd: read: %m");
@@ -1049,14 +1057,15 @@
 		(void) setjmp(timeoutbuf);
 send_ack:
 		ap = (struct tftphdr *) (etftp ? oackbuf : ackbuf);
-		if (send(peer, ap, acklength, 0) != acklength) {
+		if (sendto(peer, ap, acklength, 0, (struct sockaddr *)&from, fromlen) != acklength) {
 			syslog(LOG_ERR, "tftpd: write: %m");
 			goto abort;
 		}
 		write_behind(file, pf->f_convert);
 		for ( ; ; ) {
 			alarm(rexmtval);
-			n = recv(peer, dp, tftp_blksize + 4, 0);
+			n = recvfrom(peer, dp, tftp_blksize + 4, 0, (struct sockaddr
+			*)&from, &fromlen);
 			alarm(0);
 			if (n < 0) {            /* really? */
 				syslog(LOG_ERR, "tftpd: read: %m");
@@ -1108,16 +1117,16 @@
 	ap->th_block = htons((u_short)(block));
 	if (debug)
 		syslog(LOG_DEBUG, "Send final ACK %u", block);
-	(void) send(peer, ackbuf, 4, 0);
+	(void) sendto(peer, ackbuf, 4, 0, (struct sockaddr *)&from, fromlen);
 
 	signal(SIGALRM, justquit);      /* just quit on timeout */
 	alarm(rexmtval);
-	n = recv(peer, buf, sizeof (buf), 0); /* normally times out and quits */
+	n = recvfrom(peer, buf, sizeof (buf), 0, (struct sockaddr *)&from, &fromlen); /* normally times out and quits */
 	alarm(0);
 	if (n >= 4 &&                   /* if read some data */
 	    dp->th_opcode == DATA &&    /* and got a data block */
 	    block == dp->th_block) {	/* then my last ack was lost */
-		(void) send(peer, ackbuf, 4, 0);     /* resend final ack */
+		(void) sendto(peer, ackbuf, 4, 0, (struct sockaddr *)&from, fromlen);     /* resend final ack */
 	}
 abort:
 	return;
@@ -1185,7 +1194,7 @@
 		syslog(LOG_DEBUG, "Send NACK %s", tp->th_msg);
 	length = strlen(tp->th_msg);
 	msglen = &tp->th_msg[length + 1] - buf;
-	if (send(peer, buf, msglen, 0) != (ssize_t)msglen)
+	if (sendto(peer, buf, msglen, 0, (struct sockaddr *)&from, fromlen) != (ssize_t)msglen)
 		syslog(LOG_ERR, "nak: %m");
 }
 


Home | Main Index | Thread Index | Old Index