From ru@ucb.crimea.ua  Tue Jun  2 06:47:04 1998
Received: from relay.ucb.crimea.ua (relay.ucb.crimea.ua [194.93.177.113])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id GAA26358
          for <FreeBSD-gnats-submit@freebsd.org>; Tue, 2 Jun 1998 06:46:10 -0700 (PDT)
          (envelope-from ru@ucb.crimea.ua)
Received: (from ru@localhost)
	by relay.ucb.crimea.ua (8.8.8/8.8.8) id QAA10870;
	Tue, 2 Jun 1998 16:45:31 +0300 (EEST)
	(envelope-from ru)
Message-Id: <199806021345.QAA10870@relay.ucb.crimea.ua>
Date: Tue, 2 Jun 1998 16:45:31 +0300 (EEST)
From: Ruslan Ermilov <ru@ucb.crimea.ua>
Reply-To: ru@ucb.crimea.ua
To: FreeBSD-gnats-submit@freebsd.org
Subject: [PATCH] Allows PINGing from any address on multihomed hosts
X-Send-Pr-Version: 3.2

>Number:         6832
>Category:       bin
>Synopsis:       [PATCH] Allows PINGing from any address on multihomed hosts
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    imp
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jun  2 06:50:00 PDT 1998
>Closed-Date:    Sat Mar 20 19:57:42 MST 1999
>Last-Modified:  Sat Mar 20 19:58:14 MST 1999
>Originator:     Ruslan Ermilov
>Release:        FreeBSD 2.2.6-STABLE i386
>Organization:
United Commercial Bank
>Environment:

	Fresh -stable

>Description:

	The patch below allows to ping from any address on the multihomed host.
	The man page is also updated, the text was cutted from traceroute(8).

>How-To-Repeat:


>Fix:
	
Index: ping.8
===================================================================
RCS file: /usr/FreeBSD-CVS/src/sbin/ping/ping.8,v
retrieving revision 1.3.2.6
diff -u -r1.3.2.6 ping.8
--- ping.8	1997/09/14 19:40:03	1.3.2.6
+++ ping.8	1998/06/02 13:15:12
@@ -48,6 +48,7 @@
 .Op Fl l Ar preload
 .Op Fl p Ar pattern
 .Op Fl s Ar packetsize
+.Op Fl S Ar src_addr
 .Bo
 .Ar host |
 .Op Fl L
@@ -194,6 +195,13 @@
 with the 8 bytes of
 .Tn ICMP
 header data.
+.It Fl S Ar src_addr
+Use the following IP address as the source address in outgoing packets.
+On hosts with more than one IP address, this option can be used to
+force the source address to be something other than the IP address
+of the interface the probe packet is sent on.  If the IP address
+is not one of this machine's interface addresses, an error is
+returned and nothing is sent.
 .It Fl T Ar ttl
 Set the IP Time To Live for multicasted packets.
 This flag only applies if the ping destination is a multicast address.
Index: ping.c
===================================================================
RCS file: /usr/FreeBSD-CVS/src/sbin/ping/ping.c,v
retrieving revision 1.8.2.16
diff -u -r1.8.2.16 ping.c
--- ping.c	1998/05/25 20:21:34	1.8.2.16
+++ ping.c	1998/06/02 12:25:05
@@ -184,14 +184,14 @@
 {
 	struct timeval last, intvl;
 	struct hostent *hp;
-	struct sockaddr_in *to;
+	struct sockaddr_in *to, sin;
 	struct termios ts;
 	register int i;
 	int ch, hold, packlen, preload, sockerrno, almost_done = 0;
 	struct in_addr ifaddr;
 	unsigned char ttl, loop;
 	u_char *datap, *packet;
-	char *target, hnamebuf[MAXHOSTNAMELEN];
+	char *source = NULL, *target, hnamebuf[MAXHOSTNAMELEN];
 	char *ep;
 	u_long ultmp;
 #ifdef IP_OPTIONS
@@ -217,7 +217,7 @@
 	preload = 0;
 
 	datap = &outpack[8 + sizeof(struct timeval)];
-	while ((ch = getopt(argc, argv, "I:LQRT:c:adfi:l:np:qrs:v")) != -1) {
+	while ((ch = getopt(argc, argv, "I:LQRS:T:c:adfi:l:np:qrs:v")) != -1) {
 		switch(ch) {
 		case 'a':
 			options |= F_AUDIBLE;
@@ -301,6 +301,9 @@
 				     optarg);
 			datalen = ultmp;
 			break;
+		case 'S':
+			source = optarg;
+			break;
 		case 'T':		/* multicast TTL */
 			ultmp = strtoul(optarg, &ep, 0);
 			if (*ep || ep == optarg || ultmp > 255)
@@ -322,6 +325,24 @@
 		usage(argv[0]);
 	target = argv[optind];
 
+	if (source) {
+		bzero((char *)&sin, sizeof(sin));
+		sin.sin_family = AF_INET;
+		if (inet_aton(source, &sin.sin_addr) == 0) {
+			hp = gethostbyname2(source, AF_INET);
+			if (!hp)
+				errx(EX_NOHOST, "cannot resolve %s: %s",
+				     source, hstrerror(h_errno));
+
+			sin.sin_len = sizeof sin;
+			if (hp->h_length > sizeof(sin.sin_addr))
+				errx(1,"gethostbyname2 returned an illegal address");
+			memcpy(&sin.sin_addr, hp->h_addr_list[0], sizeof sin.sin_addr);
+		}
+		if (bind(s, (struct sockaddr *)&sin, sizeof sin) == -1)
+			err(1, "bind");
+	}
+
 	bzero((char *)&whereto, sizeof(struct sockaddr));
 	to = (struct sockaddr_in *)&whereto;
 	to->sin_family = AF_INET;
@@ -1251,6 +1272,7 @@
 	fprintf(stderr,
 		"usage: %s [-QRadfnqrv] [-c count] [-i wait] [-l preload] "
 		"[-p pattern]\n       [-s packetsize] "
+		"[-S src_addr]\n       "
 		"[host | [-L] [-I iface] [-T ttl] mcast-group]\n",
 		argv0);
 	exit(EX_USAGE);
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->suspended 
State-Changed-By: phk 
State-Changed-When: Sat Jun 6 02:22:04 PDT 1998 
State-Changed-Why:  
awaiting committer 

From: Ruslan Ermilov <ru@ucb.crimea.ua>
To: freebsd-gnats-submit@freebsd.org, ru@ucb.crimea.ua
Cc:  Subject: Re: bin/6832: [PATCH] Allows PINGing from any address on multihomed hosts
Date: Mon, 27 Jul 1998 12:33:04 +0300

 Hi!
 
 I've slightly modified my patch, since the repository
 files were changed in RELENG_2_2 branch.
 
 Here is a new patch:
 
 Index: ping.c
 ===================================================================
 RCS file: /usr/FreeBSD-CVS/src/sbin/ping/ping.c,v
 retrieving revision 1.8.2.17
 diff -u -r1.8.2.17 ping.c
 --- ping.c	1998/07/17 20:13:45	1.8.2.17
 +++ ping.c	1998/07/27 08:56:25
 @@ -141,6 +141,7 @@
  char BSPACE = '\b';		/* characters written for flood */
  char DOT = '.';
  char *hostname;
 +char *shostname;
  int ident;			/* process id to identify our packets */
  int uid;			/* cached uid for micro-optimization */
  
 @@ -184,7 +185,7 @@
  {
  	struct timeval last, intvl;
  	struct hostent *hp;
 -	struct sockaddr_in *to;
 +	struct sockaddr_in *to, sin;
  	struct termios ts;
  	register int i;
  	int ch, hold, packlen, preload, sockerrno, almost_done = 0;
 @@ -192,6 +193,7 @@
  	unsigned char ttl, loop;
  	u_char *datap, *packet;
  	char *target, hnamebuf[MAXHOSTNAMELEN];
 +	char *source = NULL, snamebuf[MAXHOSTNAMELEN];
  	char *ep;
  	u_long ultmp;
  #ifdef IP_OPTIONS
 @@ -217,7 +219,7 @@
  	preload = 0;
  
  	datap = &outpack[8 + PHDR_LEN];
 -	while ((ch = getopt(argc, argv, "I:LQRT:c:adfi:l:np:qrs:v")) != -1) {
 +	while ((ch = getopt(argc, argv, "I:LQRS:T:c:adfi:l:np:qrs:v")) != -1) {
  		switch(ch) {
  		case 'a':
  			options |= F_AUDIBLE;
 @@ -301,6 +303,9 @@
  				     optarg);
  			datalen = ultmp;
  			break;
 +		case 'S':
 +			source = optarg;
 +			break;
  		case 'T':		/* multicast TTL */
  			ultmp = strtoul(optarg, &ep, 0);
  			if (*ep || ep == optarg || ultmp > 255)
 @@ -321,6 +326,29 @@
  		usage();
  	target = argv[optind];
  
 +	if (source) {
 +		bzero((char *)&sin, sizeof(sin));
 +		sin.sin_family = AF_INET;
 +		if (inet_aton(source, &sin.sin_addr) != 0) {
 +			shostname = source;
 +		} else {
 +			hp = gethostbyname2(source, AF_INET);
 +			if (!hp)
 +				errx(EX_NOHOST, "cannot resolve %s: %s",
 +				     source, hstrerror(h_errno));
 +
 +			sin.sin_len = sizeof sin;
 +			if (hp->h_length > sizeof(sin.sin_addr))
 +				errx(1,"gethostbyname2 returned an illegal address");
 +			memcpy(&sin.sin_addr, hp->h_addr_list[0], sizeof sin.sin_addr);
 +			(void)strncpy(snamebuf, hp->h_name, sizeof(snamebuf) - 1);
 +			snamebuf[sizeof(snamebuf) - 1] = '\0';
 +			shostname = snamebuf;
 +		}
 +		if (bind(s, (struct sockaddr *)&sin, sizeof sin) == -1)
 +			err(1, "bind");
 +	}
 +
  	bzero((char *)&whereto, sizeof(struct sockaddr));
  	to = (struct sockaddr_in *)&whereto;
  	to->sin_family = AF_INET;
 @@ -429,11 +457,13 @@
  	(void)setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
  	    sizeof(hold));
  
 -	if (to->sin_family == AF_INET)
 -		(void)printf("PING %s (%s): %d data bytes\n", hostname,
 -		    inet_ntoa(to->sin_addr),
 -		    datalen);
 -	else
 +	if (to->sin_family == AF_INET) {
 +		(void)printf("PING %s (%s)", hostname,
 +		    inet_ntoa(to->sin_addr));
 +		if (source)
 +			(void)printf(" from %s", shostname);
 +		(void)printf(": %d data bytes\n", datalen);
 +	} else
  		(void)printf("PING %s: %d data bytes\n", hostname, datalen);
  
  	/*
 @@ -1269,8 +1299,9 @@
  static void
  usage()
  {
 -	fprintf(stderr, "%s\n%s\n",
 +	fprintf(stderr, "%s\n%s\n%s\n",
  "usage: ping [-QRadfnqrv] [-c count] [-i wait] [-l preload] [-p pattern]",
 -"            [-s packetsize] [host | [-L] [-I iface] [-T ttl] mcast-group]");
 +"            [-s packetsize] [-S src_addr]",
 +"            [host | [-L] [-I iface] [-T ttl] mcast-group]");
  	exit(EX_USAGE);
  }
 Index: ping.8
 ===================================================================
 RCS file: /usr/FreeBSD-CVS/src/sbin/ping/ping.8,v
 retrieving revision 1.3.2.7
 diff -u -r1.3.2.7 ping.8
 --- ping.8	1998/07/17 20:13:44	1.3.2.7
 +++ ping.8	1998/07/27 08:15:20
 @@ -48,6 +48,7 @@
  .Op Fl l Ar preload
  .Op Fl p Ar pattern
  .Op Fl s Ar packetsize
 +.Op Fl S Ar src_addr
  .Bo
  .Ar host |
  .Op Fl L
 @@ -197,6 +198,13 @@
  with the 8 bytes of
  .Tn ICMP
  header data.
 +.It Fl S Ar src_addr
 +Use the following IP address as the source address in outgoing packets.
 +On hosts with more than one IP address, this option can be used to
 +force the source address to be something other than the IP address
 +of the interface the probe packet is sent on.  If the IP address
 +is not one of this machine's interface addresses, an error is
 +returned and nothing is sent.
  .It Fl T Ar ttl
  Set the IP Time To Live for multicasted packets.
  This flag only applies if the ping destination is a multicast address.
 
 
 Regards,
 -- 
 Ruslan Ermilov		Sysadmin and DBA of the
 ru@ucb.crimea.ua	United Commercial Bank
 +380.652.247.647	Simferopol, Ukraine
 
 http://www.FreeBSD.org	The Power To Serve
 http://www.oracle.com	Enabling The Information Age
Responsible-Changed-From-To: freebsd-bugs->imp 
Responsible-Changed-By: imp 
Responsible-Changed-When: Mon Jul 27 15:02:58 MDT 1998 
Responsible-Changed-Why:  
I'll fix this. 
State-Changed-From-To: suspended->closed 
State-Changed-By: imp 
State-Changed-When: Wed Jan 6 00:54:36 MST 1999 
State-Changed-Why:  
I've fixed this. 

From: Ruslan Ermilov <ru@ucb.crimea.ua>
To: Warner Losh <imp@FreeBSD.ORG>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/6832
Date: Wed, 6 Jan 1999 10:37:56 +0200

 On Tue, Jan 05, 1999 at 11:54:51PM -0800, Warner Losh wrote:
 > Synopsis: [PATCH] Allows PINGing from any address on multihomed hosts
 > 
 > State-Changed-From-To: suspended->closed
 > State-Changed-By: imp
 > State-Changed-When: Wed Jan 6 00:54:36 MST 1999
 > State-Changed-Why: 
 > I've fixed this.
 
 The ping.8 is only partially updated, compare
 the original patch and repository commit!
 
 And, will this patch come to RELENG_2_2 sometime?
 
 BR,
 -- 
 Ruslan Ermilov		Sysadmin and DBA of the
 ru@ucb.crimea.ua	United Commercial Bank
 +380.652.247.647	Simferopol, Ukraine
 
 http://www.FreeBSD.org	The Power To Serve
 http://www.oracle.com	Enabling The Information Age

From: Warner Losh <imp@village.org>
To: Ruslan Ermilov <ru@ucb.crimea.ua>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/6832 
Date: Wed, 06 Jan 1999 10:39:42 -0700

 In message <19990106103756.A26584@ucb.crimea.ua> Ruslan Ermilov writes:
 : The ping.8 is only partially updated, compare
 : the original patch and repository commit!
 
 Dang.  I thought I'd caught that.  Will do again.
 
 : And, will this patch come to RELENG_2_2 sometime?
 
 I hadn't planned on it, but since you asked specifically I'll do what
 I can to merge.  I'd ask that if you are running -stable to test it
 and let me know if i broke anything, since I no longer have any stable
 systems to test on.
 
 Warner
State-Changed-From-To: closed->feedback 
State-Changed-By: imp 
State-Changed-When: Wed Jan 6 10:52:20 MST 1999 
State-Changed-Why:  
Man page commit incomplete and a request to merge into 2.2.x. 

From: Ruslan Ermilov <ru@ucb.crimea.ua>
To: Warner Losh <imp@village.org>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/6832
Date: Sun, 10 Jan 1999 09:50:39 +0200

 On Wed, Jan 06, 1999 at 10:39:42AM -0700, Warner Losh wrote:
 > In message <19990106103756.A26584@ucb.crimea.ua> Ruslan Ermilov writes:
 > : The ping.8 is only partially updated, compare
 > : the original patch and repository commit!
 > 
 > Dang.  I thought I'd caught that.  Will do again.
 > 
 > : And, will this patch come to RELENG_2_2 sometime?
 > 
 > I hadn't planned on it, but since you asked specifically I'll do what
 > I can to merge.  I'd ask that if you are running -stable to test it
 > and let me know if i broke anything, since I no longer have any stable
 > systems to test on.
 > 
 > Warner
 
 I regularly upgrade my system (once per month), and I live with this
 patch for a 3+ months without having any problems.
 Currently, my `uname -r` says: 2.2.8-STABLE.
 
 Best regards,
 -- 
 Ruslan Ermilov		Sysadmin and DBA of the
 ru@ucb.crimea.ua	United Commercial Bank
 +380.652.247.647	Simferopol, Ukraine
 
 http://www.FreeBSD.org	The Power To Serve
 http://www.oracle.com	Enabling The Information Age
State-Changed-From-To: feedback->closed 
State-Changed-By: imp 
State-Changed-When: Sat Mar 20 19:57:42 MST 1999 
State-Changed-Why:  
I fixed this and the orignator sayid to close it :-) 
>Unformatted:
