summaryrefslogtreecommitdiffstats
path: root/sbin/ping
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>1999-01-06 07:54:28 +0000
committerimp <imp@FreeBSD.org>1999-01-06 07:54:28 +0000
commit1eb0469a28ede5948a08d146e27a84ea0d435bf3 (patch)
treea13af5ec97e9e3c0dcccc1bf999d46c7857b28bb /sbin/ping
parentee59e7440da557819f0ca8c9e49eeccad2a6515f (diff)
downloadFreeBSD-src-1eb0469a28ede5948a08d146e27a84ea0d435bf3.zip
FreeBSD-src-1eb0469a28ede5948a08d146e27a84ea0d435bf3.tar.gz
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
Diffstat (limited to 'sbin/ping')
-rw-r--r--sbin/ping/ping.83
-rw-r--r--sbin/ping/ping.c55
2 files changed, 46 insertions, 12 deletions
diff --git a/sbin/ping/ping.8 b/sbin/ping/ping.8
index 2784289..50aeb08 100644
--- a/sbin/ping/ping.8
+++ b/sbin/ping/ping.8
@@ -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
diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c
index 4db695b..b1e20e8 100644
--- a/sbin/ping/ping.c
+++ b/sbin/ping/ping.c
@@ -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);
}
OpenPOWER on IntegriCloud