--- /tmp/td1.c	2008-11-10 09:28:49.000000000 -0800
+++ /tmp/td2.c	2008-11-10 09:29:07.000000000 -0800
@@ -74,9 +74,6 @@
    past (bf + len) then that IAC will be left unprocessed and *processed
    will be less than len.
 
-   FIXME - if we mean to send 0xFF to the terminal then it will be escaped,
-   what is the escape character?  We aren't handling that situation here.
-
    CR-LF ->'s CR mapping is also done here, for convenience.
 
    NB: may fail to remove iacs which wrap around buffer!
@@ -103,6 +100,14 @@
 			if (c == '\r' && ptr < end && (*ptr == '\n' || *ptr == '\0'))
 				ptr++;
 		} else {
+			if ((ptr+1) >= end)	// Need at least 2 bytes.
+				break;
+			if (ptr[1] == NOP)	// Ignore?  (Keepalive, etc.)
+				ptr += 2;
+			else if (ptr[1] == IAC){// Literal IAC?
+				*totty++ = ptr[1];
+				ptr += 2;
+			} else
 			/*
 			 * TELOPT_NAWS support!
 			 */
@@ -154,11 +159,29 @@
 		USE_FEATURE_TELNETD_STANDALONE(int sock)
 		SKIP_FEATURE_TELNETD_STANDALONE(void)
 ) {
-	const char *login_argv[2];
+	const char *login_argv[3];
 	struct termios termbuf;
 	int fd, pid;
 	char tty_name[GETPTY_BUFSIZE];
 	struct tsession *ts = xzalloc(sizeof(struct tsession) + BUFSIZE * 2);
+	struct sockaddr_in ir_sin;
+	socklen_t size;
+	char envBuf[32];
+
+	size = sizeof(ir_sin);
+
+	memset(envBuf,0, sizeof envBuf);
+
+	// grab the peer IP address before it's gone
+	if (getpeername(sock, (struct sockaddr *) &ir_sin, &size) < 0) {
+	   fprintf(stdout, "%s %d getsockname error\n\r",__FUNCTION__,__LINE__);
+	   bb_perror_msg("getsockname");
+	}
+	else
+	{
+	   //fprintf(stdout, "%s %d 0x%s\n\r",__FUNCTION__,__LINE__,inet_ntoa(ir_sin.sin_addr));
+	   snprintf(envBuf, sizeof envBuf - 1, "-h%s",inet_ntoa(ir_sin.sin_addr));
+	}
 
 	/*ts->buf1 = (char *)(ts + 1);*/
 	/*ts->buf2 = ts->buf1 + BUFSIZE;*/
@@ -256,7 +279,8 @@
 
 	/* Exec shell / login / whatever */
 	login_argv[0] = loginpath;
-	login_argv[1] = NULL;
+	login_argv[1] = envBuf;
+	login_argv[2] = NULL;
 	/* exec busybox applet (if PREFER_APPLETS=y), if that fails,
 	 * exec external program */
 	BB_EXECVP(loginpath, (char **)login_argv);
@@ -269,8 +293,9 @@
 enum {
 	OPT_WATCHCHILD = (1 << 2), /* -K */
 	OPT_INETD      = (1 << 3) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -i */
-	OPT_PORT       = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p */
-	OPT_FOREGROUND = (1 << 6) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -F */
+	OPT_NKEEPALIVE = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -n */
+	OPT_PORT       = (1 << 5) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p */
+	OPT_FOREGROUND = (1 << 7) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -F */
 };
 
 #if ENABLE_FEATURE_TELNETD_STANDALONE
@@ -373,7 +398,7 @@
 #endif
 	/* Even if !STANDALONE, we accept (and ignore) -i, thus people
 	 * don't need to guess whether it's ok to pass -i to us */
-	opt = getopt32(argv, "f:l:Ki" USE_FEATURE_TELNETD_STANDALONE("p:b:F"),
+	opt = getopt32(argv, "f:l:Kin" USE_FEATURE_TELNETD_STANDALONE("p:b:F"),
 			&issuefile, &loginpath
 			USE_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr));
 	if (!IS_INETD /*&& !re_execed*/) {
@@ -401,6 +426,9 @@
 
 #if ENABLE_FEATURE_TELNETD_STANDALONE
 	if (IS_INETD) {
+		if (!(opt & OPT_NKEEPALIVE))
+			setsockopt(0, SOL_SOCKET, SO_KEEPALIVE,
+			&const_int_1, sizeof(const_int_1));
 		sessions = make_new_session(0);
 		if (!sessions) /* pty opening or vfork problem, exit */
 			return 1; /* make_new_session prints error message */
@@ -409,6 +437,9 @@
 		xlisten(master_fd, 1);
 	}
 #else
+	if (!(opt & OPT_NKEEPALIVE))
+		setsockopt(0, SOL_SOCKET, SO_KEEPALIVE,
+		&const_int_1, sizeof(const_int_1));
 	sessions = make_new_session();
 	if (!sessions) /* pty opening or vfork problem, exit */
 		return 1; /* make_new_session prints error message */
@@ -489,6 +520,9 @@
 		if (fd < 0)
 			goto again;
 		/* Create a new session and link it into our active list */
+		if (!(opt & OPT_NKEEPALIVE))
+			setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
+			&const_int_1, sizeof(const_int_1));
 		new_ts = make_new_session(fd);
 		if (new_ts) {
 			new_ts->next = sessions;
