Allow PINGing from any address on multihomed hosts

In the words of the submitter:
"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)."

Submitted by: Ruslan Ermilov
PR: 6832
This commit is contained in:
Warner Losh 1999-01-06 07:54:28 +00:00
parent db23c94fff
commit 99490ede3a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=42337
2 changed files with 46 additions and 12 deletions

View File

@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)ping.8 8.2 (Berkeley) 12/11/93
.\" $Id: ping.8,v 1.17 1998/08/27 16:34:38 dillon Exp $
.\" $Id: ping.8,v 1.18 1998/11/29 13:20:04 bde Exp $
.\"
.Dd March 1, 1997
.Dt PING 8
@ -48,6 +48,7 @@ packets to network hosts
.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

View File

@ -45,7 +45,7 @@ static const char copyright[] =
static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93";
#endif
static const char rcsid[] =
"$Id: ping.c,v 1.40 1998/08/26 01:58:39 dillon Exp $";
"$Id: ping.c,v 1.41 1998/08/26 18:51:37 des Exp $";
#endif /* not lint */
/*
@ -141,6 +141,7 @@ u_char outpack[MAXPACKET];
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,14 +185,15 @@ main(argc, argv)
{
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 snamebuf[MAXHOSTNAMELEN];
char *ep;
u_long ultmp;
#ifdef IP_OPTIONS
@ -217,7 +219,7 @@ main(argc, argv)
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;
@ -316,6 +318,9 @@ main(argc, argv)
optarg);
datalen = ultmp;
break;
case 'S':
source = optarg;
break;
case 'T': /* multicast TTL */
ultmp = strtoul(optarg, &ep, 0);
if (*ep || ep == optarg || ultmp > 255)
@ -336,6 +341,31 @@ main(argc, argv)
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: 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;
@ -444,11 +474,13 @@ main(argc, argv)
(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);
/*
@ -1284,8 +1316,9 @@ fill(bp, patp)
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);
}