Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Mar 1999 10:47:36 -0800 (PST)
From:      Craig Spannring <cts@internetcds.com>
To:        freebsd-hackers@FreeBSD.ORG
Subject:   Proposed change to telnet(1).
Message-ID:  <199903041847.KAA27000@bangkok.office.cdsnet.net>

next in thread | raw e-mail | index | archive | help

Sometimes it would be nice to be able to specify which outbound
interface telnet should bind to.  I propose adding a '-I interface'
option to telnet.  It would work like-

   telnet -I 192.168.0.10 somehost.mydomain.net

That would make the telnet client bind to the outbound IP address of
192.168.0.10 provided of course the client has an interface configured
to that IP.

Here are patches that implement this feature.

>--- cut here ---<
diff -c -r telnet/commands.c telnet.new/commands.c
*** telnet/commands.c	Thu Mar  4 10:29:45 1999
--- telnet.new/commands.c	Thu Mar  4 10:26:51 1999
***************
*** 2100,2113 ****
      char *argv[];
  {
      register struct hostent *host = 0;
      struct sockaddr_in sin;
      struct servent *sp = 0;
      unsigned long temp;
  #if	defined(IP_OPTIONS) && defined(IPPROTO_IP)
      char *srp = 0, *strrchr();
      unsigned long sourceroute(), srlen;
  #endif
!     char *cmd, *hostp = 0, *portp = 0, *user = 0;
  
      /* clear the socket address prior to use */
      bzero((char *)&sin, sizeof(sin));
--- 2100,2115 ----
      char *argv[];
  {
      register struct hostent *host = 0;
+     struct hostent *interface;
      struct sockaddr_in sin;
+     struct sockaddr_in interface_sin;
      struct servent *sp = 0;
      unsigned long temp;
  #if	defined(IP_OPTIONS) && defined(IPPROTO_IP)
      char *srp = 0, *strrchr();
      unsigned long sourceroute(), srlen;
  #endif
!     char *cmd, *hostp = 0, *portp = 0, *user = 0, *interfacep = 0;
  
      /* clear the socket address prior to use */
      bzero((char *)&sin, sizeof(sin));
***************
*** 2143,2148 ****
--- 2145,2158 ----
  	    autologin = 1;
  	    continue;
  	}
+         if (strcmp(*argv, "-I") == 0) {
+ 	    --argc; ++argv;
+ 	    if (argc == 0)
+ 		goto usage;
+ 	    interfacep = *argv++;
+ 	    --argc;
+ 	    continue;
+         }           
  	if (hostp == 0) {
  	    hostp = *argv++;
  	    --argc;
***************
*** 2154,2160 ****
  	    continue;
  	}
      usage:
! 	printf("usage: telnet [-l user] [-a] host-name [port]\n");
  	setuid(getuid());
  	return 0;
      }
--- 2164,2170 ----
  	    continue;
  	}
      usage:
! 	printf("usage: telnet [-l user] [-a] [-I interface] host-name [port]\n");
  	setuid(getuid());
  	return 0;
      }
***************
*** 2284,2289 ****
--- 2294,2334 ----
  	if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) {
  		perror("setsockopt (SO_DEBUG)");
  	}
+ 
+         if (interfacep) {
+            bzero((char *)&interface_sin, sizeof(interface_sin));
+ 
+            temp = inet_addr(interfacep);
+            if (temp != INADDR_NONE) {
+               interface_sin.sin_addr.s_addr = temp;
+               interface_sin.sin_family = AF_INET;
+               interface_sin.sin_port = htons(0);
+            } else {
+               interface = gethostbyname(interfacep);
+               if (interface) {
+                  interface_sin.sin_family = interface->h_addrtype;
+ #if	defined(h_addr)		/* In 4.3, this is a #define */
+                  memmove((caddr_t)&interface_sin.sin_addr,
+                          interface->h_addr_list[0], 
+                          MIN(interface->h_length, sizeof(interface_sin.sin_addr)));
+ #else	/* defined(h_addr) */
+                  memmove((caddr_t)&interface_sin.sin_addr, interface->h_addr, 
+                          MIN(interface->h_length, sizeof(interface_sin.sin_addr)));
+ #endif	/* defined(h_addr) */
+                  interface_sin.sin_port = htons(0);
+               } else {
+                  herror(interfacep);
+                  setuid(getuid());
+                  return 0;
+               }
+            }
+            if (bind(net, (struct sockaddr *)&interface_sin, 
+                     sizeof (interface_sin)) == -1) {
+               perror("telnet: Unable to bind to specified interface");
+               return 0;
+            }
+         }
+ 
  
  	if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
  #if	defined(h_addr)		/* In 4.3, this is a #define */
diff -c -r telnet/main.c telnet.new/main.c
*** telnet/main.c	Thu Mar  4 10:29:46 1999
--- telnet.new/main.c	Tue Mar  2 18:53:33 1999
***************
*** 81,91 ****
  	fprintf(stderr, "Usage: %s %s%s%s%s\n",
  	    prompt,
  #ifdef	AUTHENTICATION
! 	    "[-8] [-E] [-K] [-L] [-S tos] [-X atype] [-a] [-c] [-d] [-e char]",
! 	    "\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] ",
  #else
! 	    "[-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
! 	    "\n\t[-n tracefile]",
  #endif
  #if defined(TN3270) && defined(unix)
  # ifdef AUTHENTICATION
--- 81,91 ----
  	fprintf(stderr, "Usage: %s %s%s%s%s\n",
  	    prompt,
  #ifdef	AUTHENTICATION
! 	    "[-8] [-E] [-I interface] [-K] [-L] [-S tos] [-X atype] [-a] [-c]",
! 	    "\n\t[-d] [-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
  #else
! 	    "[-8] [-E] [-I interface] [-L] [-S tos] [-a] [-c] [-d]",
! 	    "\n\t[-e char] [-l user] [-n tracefile]",
  #endif
  #if defined(TN3270) && defined(unix)
  # ifdef AUTHENTICATION
***************
*** 113,119 ****
  	extern char *optarg;
  	extern int optind;
  	int ch;
! 	char *user, *strrchr();
  #ifdef	FORWARD
  	extern int forward_flags;
  #endif	/* FORWARD */
--- 113,119 ----
  	extern char *optarg;
  	extern int optind;
  	int ch;
! 	char *user, *interface, *strrchr();
  #ifdef	FORWARD
  	extern int forward_flags;
  #endif	/* FORWARD */
***************
*** 131,141 ****
  		prompt = argv[0];
  
  	user = NULL;
  
  	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
  	autologin = -1;
  
! 	while ((ch = getopt(argc, argv, "8EKLNS:X:acde:fFk:l:n:rt:x")) != -1) {
  		switch(ch) {
  		case '8':
  			eight = 3;	/* binary output and input */
--- 131,142 ----
  		prompt = argv[0];
  
  	user = NULL;
+ 	interface = NULL;
  
  	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
  	autologin = -1;
  
! 	while ((ch = getopt(argc, argv, "8EI:KLNS:X:acde:fFk:l:n:rt:x")) != -1) {
  		switch(ch) {
  		case '8':
  			eight = 3;	/* binary output and input */
***************
*** 219,224 ****
--- 220,228 ----
  				prompt);
  #endif
  			break;
+ 		case 'I':
+ 			interface = optarg;
+ 			break;
  		case 'k':
  #if defined(AUTHENTICATION) && defined(KRB4)
  		    {
***************
*** 283,289 ****
  	argv += optind;
  
  	if (argc) {
! 		char *args[7], **argp = args;
  
  		if (argc > 2)
  			usage();
--- 287,293 ----
  	argv += optind;
  
  	if (argc) {
! 		char *args[8], **argp = args;
  
  		if (argc > 2)
  			usage();
***************
*** 291,296 ****
--- 295,304 ----
  		if (user) {
  			*argp++ = "-l";
  			*argp++ = user;
+ 		}
+ 		if (interface) {
+ 			*argp++ = "-I";
+                         *argp++ = interface;
  		}
  		*argp++ = argv[0];		/* host */
  		if (argc > 1)
diff -c -r telnet/telnet.1 telnet.new/telnet.1
*** telnet/telnet.1	Thu Mar  4 10:29:48 1999
--- telnet.new/telnet.1	Tue Mar  2 18:53:33 1999
***************
*** 30,36 ****
  .\" SUCH DAMAGE.
  .\"
  .\"	@(#)telnet.1	8.5 (Berkeley) 3/1/94
! .\"	$Id: telnet.1,v 1.10 1998/12/14 22:40:38 billf Exp $
  .\"
  .Dd March 1, 1994
  .Dt TELNET 1
--- 30,36 ----
  .\" SUCH DAMAGE.
  .\"
  .\"	@(#)telnet.1	8.5 (Berkeley) 3/1/94
! .\"	$Id: telnet.1,v 1.2 1999/03/03 02:53:33 cts Exp $
  .\"
  .Dd March 1, 1994
  .Dt TELNET 1
***************
*** 43,48 ****
--- 43,49 ----
  .Sh SYNOPSIS
  .Nm
  .Op Fl 8EFKLacdfrx
+ .Op Fl I Ar interface
  .Op Fl S Ar tos
  .Op Fl X Ar authtype
  .Op Fl e Ar escapechar
***************
*** 87,92 ****
--- 88,96 ----
  option allows the local credentials to be forwarded
  to the remote system, including any credentials that
  have already been forwarded into the local environment.
+ .It Fl I Ar interface
+ Specify the IP address of the interface to bind to for 
+ the outbound connection.
  .It Fl K
  Specifies no automatic login to the remote system.
  .It Fl L
>--- cut here ---<



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199903041847.KAA27000>