summaryrefslogtreecommitdiff
path: root/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c')
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c b/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c
index 2a4ff60d57..d851dce613 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c
@@ -159,6 +159,7 @@ static int moptions; /* multicast options */
int npackets; /* number of packets to send */
static ushort_t tos; /* type-of-service value */
static int hoplimit = -1; /* time-to-live value */
+static int dontfrag; /* IP*_DONTFRAG */
static int timeout = TIMEOUT; /* timeout value (sec) for probes */
static struct if_entry out_if; /* interface argument */
int ident; /* ID for this ping run */
@@ -268,7 +269,7 @@ main(int argc, char *argv[])
setbuf(stdout, (char *)0);
while ((c = getopt(argc, argv,
- "abA:c:dF:G:g:I:i:LlnN:P:p:rRSsTt:UvX:x:Y0123?")) != -1) {
+ "abA:c:dDF:G:g:I:i:LlnN:P:p:rRSsTt:UvX:x:Y0123?")) != -1) {
switch ((char)c) {
case 'A':
if (strcmp(optarg, "inet") == 0) {
@@ -301,6 +302,10 @@ main(int argc, char *argv[])
options |= SO_DEBUG;
break;
+ case 'D':
+ dontfrag = 1;
+ break;
+
case 'b':
bypass = _B_TRUE;
break;
@@ -1303,8 +1308,6 @@ setup_socket(int family, int *send_sockp, int *recv_sockp, int *if_index,
}
}
- if (nexthop != NULL && !use_udp)
- set_nexthop(family, ai_nexthop, recv_sock);
/*
* We always receive on raw icmp socket. But the sending socket can be
* raw icmp or udp, depending on the use of -U flag.
@@ -1332,9 +1335,6 @@ setup_socket(int family, int *send_sockp, int *recv_sockp, int *if_index,
}
}
- if (nexthop != NULL)
- set_nexthop(family, ai_nexthop, send_sock);
-
/*
* In order to distinguish replies to our UDP probes from
* other pings', we need to know our source port number.
@@ -1368,6 +1368,9 @@ setup_socket(int family, int *send_sockp, int *recv_sockp, int *if_index,
send_sock = recv_sock;
}
+ if (nexthop != NULL)
+ set_nexthop(family, ai_nexthop, send_sock);
+
int_op = 48 * 1024;
if (int_op < datalen)
int_op = datalen;
@@ -1431,6 +1434,7 @@ setup_socket(int family, int *send_sockp, int *recv_sockp, int *if_index,
if (moptions & MULTICAST_TTL) {
char_op = hoplimit;
+ /* Applies to unicast and multicast. */
if (family == AF_INET) {
if (setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL,
(char *)&char_op, sizeof (char)) == -1) {
@@ -1454,7 +1458,10 @@ setup_socket(int family, int *send_sockp, int *recv_sockp, int *if_index,
*/
}
- /* did the user specify an interface? */
+ /*
+ * did the user specify an interface?
+ * Applies to unicast, broadcast and multicast.
+ */
if (moptions & MULTICAST_IF) {
struct ifaddrlist *al = NULL; /* interface list */
struct ifaddrlist *my_if;
@@ -1496,6 +1503,8 @@ setup_socket(int family, int *send_sockp, int *recv_sockp, int *if_index,
}
if (family == AF_INET) {
+ struct in_pktinfo pktinfo;
+
if (setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_IF,
(char *)&my_if->addr.addr,
sizeof (struct in_addr)) == -1) {
@@ -1504,6 +1513,15 @@ setup_socket(int family, int *send_sockp, int *recv_sockp, int *if_index,
strerror(errno));
exit(EXIT_FAILURE);
}
+ bzero(&pktinfo, sizeof (pktinfo));
+ pktinfo.ipi_ifindex = my_if->index;
+ if (setsockopt(send_sock, IPPROTO_IP, IP_PKTINFO,
+ (char *)&pktinfo, sizeof (pktinfo)) == -1) {
+ Fprintf(stderr, "%s: setsockopt "
+ "IP_PKTINFO %s\n", progname,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
} else {
/*
* the outgoing interface is set in set_ancillary_data()
@@ -1525,6 +1543,23 @@ setup_socket(int family, int *send_sockp, int *recv_sockp, int *if_index,
}
}
+ /* We enable or disable to not depend on the kernel default */
+ if (family == AF_INET) {
+ if (setsockopt(send_sock, IPPROTO_IP, IP_DONTFRAG,
+ (char *)&dontfrag, sizeof (dontfrag)) == -1) {
+ Fprintf(stderr, "%s: setsockopt IP_DONTFRAG %s\n",
+ progname, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ if (setsockopt(send_sock, IPPROTO_IPV6, IPV6_DONTFRAG,
+ (char *)&dontfrag, sizeof (dontfrag)) == -1) {
+ Fprintf(stderr, "%s: setsockopt IPV6_DONTFRAG %s\n",
+ progname, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ }
+
/* receiving IPv6 extension headers in verbose mode */
if (verbose && family == AF_INET6) {
if (setsockopt(recv_sock, IPPROTO_IPV6, IPV6_RECVHOPOPTS,
@@ -2336,7 +2371,7 @@ usage(char *cmdname)
Fprintf(stderr, "usage: %s host [timeout]\n", cmdname);
Fprintf(stderr,
/* CSTYLED */
-"usage: %s -s [-l | U] [abdLnRrv] [-A addr_family] [-c traffic_class]\n\t"
+"usage: %s -s [-l | U] [abdDLnRrv] [-A addr_family] [-c traffic_class]\n\t"
"[-g gateway [-g gateway ...]] [-N nexthop] [-F flow_label] [-I interval]\n\t"
"[-i interface] [-P tos] [-p port] [-t ttl] host [data_size] [npackets]\n",
cmdname);