Subject: bin/1014: ping should allow specification of source interfaces
To: None <gnats-admin@sun-lamp.cs.berkeley.edu>
From: John Hawkinson <jhawk@MIT.EDU>
List: netbsd-bugs
Date: 05/02/1995 21:05:05
>Number: 1014
>Category: bin
>Synopsis: ping should allow specification of source interfaces
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Tue May 2 21:05:03 1995
>Originator: John Hawkinson
>Organization:
MIT SIPB
>Release: Tue May 2 23:53:23 EDT 1995
>Environment:
System: NetBSD quiche-lorraine 1.0A NetBSD 1.0A (ATHENA-AHA) #8: Wed Apr 26 20:19:45 EDT 1995 jhawk@lola-granola:/afs/sipb.mit.edu/project/netbsd/dev/current-source/src/sys/arch/i386/compile/ATHENA-AHA i386
>Description:
ping, unlike traceroute doesn't allow the user to specify
the source address for unicast pings. For multicast pings,
the -I option allows it.
This patch causes ping to bind to the address specified in the
-S option, in order to mandate a specific source address.
It would be nice if -I and -S weren't seperate options, but I
suspect there's not much that can be done about that.
>How-To-Repeat:
Stare at your machine and wonder why it doesn't work?
Note that this code is useless under 1.0 due to the rip_output.c
bug...
>Fix:
*** ping.c.orig Tue May 2 23:50:58 1995
--- ping.c Tue May 2 23:51:47 1995
***************
*** 114,119 ****
--- 114,120 ----
#define F_SO_DEBUG 0x040
#define F_SO_DONTROUTE 0x080
#define F_VERBOSE 0x100
+ #define F_SADDR 0x200
/* multicast options */
int moptions;
***************
*** 131,136 ****
--- 132,138 ----
char rcvd_tbl[MAX_DUP_CHK / 8];
struct sockaddr whereto; /* who to ping */
+ struct sockaddr_in whence; /* Which interface we come from */
int datalen = DEFDATALEN;
int s; /* socket file descriptor */
u_char outpack[MAXPACKET];
***************
*** 173,179 ****
struct hostent *hp;
struct sockaddr_in *to;
struct protoent *proto;
! struct in_addr ifaddr;
register int i;
int ch, fdmask, hold, packlen, preload;
u_char *datap, *packet;
--- 175,181 ----
struct hostent *hp;
struct sockaddr_in *to;
struct protoent *proto;
! struct in_addr ifaddr, saddr;
register int i;
int ch, fdmask, hold, packlen, preload;
u_char *datap, *packet;
***************
*** 185,191 ****
preload = 0;
datap = &outpack[8 + sizeof(struct timeval)];
! while ((ch = getopt(argc, argv, "I:LRc:dfh:i:l:np:qrs:t:v")) != EOF)
switch(ch) {
case 'c':
npackets = atoi(optarg);
--- 187,193 ----
preload = 0;
datap = &outpack[8 + sizeof(struct timeval)];
! while ((ch = getopt(argc, argv, "I:LRS:c:dfh:i:l:np:qrs:t:v")) != EOF)
switch(ch) {
case 'c':
npackets = atoi(optarg);
***************
*** 238,243 ****
--- 240,253 ----
case 'r':
options |= F_SO_DONTROUTE;
break;
+ case 'S':
+ if (inet_aton(optarg,&saddr)==0) {
+ if ((hp = gethostbyname(optarg))==0)
+ errx(1, "bad interface address: %s", optarg);
+ memcpy(&saddr, hp->h_addr, sizeof(saddr));
+ }
+ options |= F_SADDR;
+ break;
case 's': /* size of packet to send */
datalen = atoi(optarg);
if (datalen <= 0)
***************
*** 300,305 ****
--- 310,326 ----
if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0)
err(1, "socket");
hold = 1;
+
+ if (options & F_SADDR) {
+ memset(&whence, 0, sizeof(whence));
+ whence.sin_len = sizeof(whence);
+ whence.sin_family = AF_INET;
+ memcpy(&whence.sin_addr.s_addr, &saddr, sizeof(saddr));
+ if (bind(s, (struct sockaddr*)&whence, sizeof(whence))
+ < 0)
+ err(1, "bind");
+ }
+
if (options & F_SO_DEBUG)
(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
sizeof(hold));
***************
*** 996,1000 ****
{
(void)fprintf(stderr,
"usage: ping [-dfLnqRrv] [-c count] [-I ifaddr] [-i wait] [-l preload]\n\t[-p pattern] [-s packetsize] [-t ttl] host\n");
! exit(1);
}
--- 1017,1021 ----
{
(void)fprintf(stderr,
"usage: ping [-dfLnqRrv] [-c count] [-I ifaddr] [-i wait] [-l preload]\n\t[-p pattern] [-s packetsize] [-t ttl] host\n");
! "usage: ping [-dfLnqRrv] [-c count] [-I ifaddr] [ -S ifaddr ] [-i wait]\n\t[-l preload] [-p pattern] [-s packetsize] [-t ttl] [-w maxwait] host\n");
}
*** ping.8.orig Tue May 2 23:50:58 1995
--- ping.8 Tue May 2 23:51:28 1995
***************
*** 49,54 ****
--- 49,55 ----
.Op Fl i Ar wait
.Op Fl l Ar preload
.Op Fl p Ar pattern
+ .Op Fl S Ar ifaddr
.Op Fl s Ar packetsize
.Op Fl t Ar ttl
.Ar host
***************
*** 141,146 ****
--- 142,150 ----
This option can be used to ping a local host through an interface
that has no route through it (e.g., after the interface was dropped by
.Xr routed 8 ) .
+ .It Fl S Ar ifaddr
+ Specify the interface to transmit from on machines with multiple
+ interfaces. For unicast pings.
.It Fl s Ar packetsize
Specifies the number of data bytes to be sent.
The default is 56, which translates into 64
>Audit-Trail:
>Unformatted: