Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/RMerl/asuswrt-merlin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2016-12-09 22:39:14 +0300
committerVladislav Grishenko <themiron@mail.ru>2016-12-10 03:31:56 +0300
commit09189229357e31efac4079d45df2b572ce65b656 (patch)
tree9a83be4d3da71d7587282c8b80872306bc78593f
parent06d2399b113ebad7ba2cb1256abed1c803928178 (diff)
busybox: ping: add -M to specify Path MTU strategy
-rw-r--r--release/src/router/busybox/networking/ping.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/release/src/router/busybox/networking/ping.c b/release/src/router/busybox/networking/ping.c
index ba244d2ed2..6f107f4cbf 100644
--- a/release/src/router/busybox/networking/ping.c
+++ b/release/src/router/busybox/networking/ping.c
@@ -97,6 +97,7 @@
//usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)"
//usage: "\n -t TTL Set TTL"
//usage: "\n -I IFACE/IP Use interface or IP address as source"
+//usage: "\n -M hint Path MTU Discovery strategy [do|want|dont]"
//usage: "\n -W SEC Seconds to wait for the first response (default:10)"
//usage: "\n (after all -c CNT packets are sent)"
//usage: "\n -w SEC Seconds until ping exits (default:infinite)"
@@ -113,6 +114,7 @@
//usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)"
//usage: "\n -t HL Set Hop Limit"
//usage: "\n -I IFACE/IP Use interface or IP address as source"
+//usage: "\n -M hint Path MTU Discovery strategy [do|want|dont]"
//usage: "\n -q Quiet, only display output at start"
//usage: "\n and when finished"
//usage: "\n -p Pattern to use for payload"
@@ -144,6 +146,11 @@
# undef IPV6_HOPLIMIT
# define IPV6_HOPLIMIT IPV6_2292HOPLIMIT
# endif
+# if IPV6_PMTUDISC_DONT != IP_PMTUDISC_DONT || \
+ IPV6_PMTUDISC_WANT != IP_PMTUDISC_WANT || \
+ IPV6_PMTUDISC_DO != IP_PMTUDISC_DO
+# error IPV6_PMTUDISC_* & IP_PMTUDISC_* constants mismatch
+# endif
#endif
enum {
@@ -334,7 +341,7 @@ static int common_ping_main(sa_family_t af, char **argv)
/* Full(er) version */
-#define OPT_STRING ("qvc:s:t:w:W:I:np:4" IF_PING6("6"))
+#define OPT_STRING ("qvc:s:t:w:W:I:np:M:4" IF_PING6("6"))
enum {
OPT_QUIET = 1 << 0,
OPT_VERBOSE = 1 << 1,
@@ -346,8 +353,9 @@ enum {
OPT_I = 1 << 7,
/*OPT_n = 1 << 8, - ignored */
OPT_p = 1 << 9,
- OPT_IPV4 = 1 << 10,
- OPT_IPV6 = (1 << 11) * ENABLE_PING6,
+ OPT_M = 1 << 10,
+ OPT_IPV4 = 1 << 11,
+ OPT_IPV6 = (1 << 12) * ENABLE_PING6,
};
@@ -361,6 +369,7 @@ struct globals {
unsigned long ntransmitted, nreceived, nrepeats;
uint16_t myid;
uint8_t pattern;
+ int pmtudisc;
unsigned tmin, tmax; /* in us */
unsigned long long tsum; /* in us, sum of all times */
unsigned deadline;
@@ -388,6 +397,7 @@ struct globals {
#define pingcount (G.pingcount )
#define opt_ttl (G.opt_ttl )
#define myid (G.myid )
+#define pmtudisc (G.pmtudisc )
#define tmin (G.tmin )
#define tmax (G.tmax )
#define tsum (G.tsum )
@@ -401,6 +411,7 @@ struct globals {
#define INIT_G() do { \
setup_common_bufsiz(); \
BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
+ pmtudisc = -1; \
datalen = DEFDATALEN; \
timeout = MAXWAIT; \
tmin = UINT_MAX; \
@@ -709,6 +720,15 @@ static void ping4(len_and_sockaddr *lsa)
setsockopt_int(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, opt_ttl);
}
+ if (IN_MULTICAST(ntohl(pingaddr.sin.sin_addr.s_addr))) {
+ if (myid && pmtudisc >= 0 && pmtudisc != IP_PMTUDISC_DO)
+ bb_error_msg_and_die("multicast ping does not fragment");
+ if (pmtudisc < 0)
+ pmtudisc = IP_PMTUDISC_DO;
+ }
+ if (pmtudisc >= 0)
+ setsockopt_int(pingsock, SOL_IP, IP_MTU_DISCOVER, pmtudisc);
+
signal(SIGINT, print_stats_and_exit);
/* start the ping's going ... */
@@ -783,6 +803,15 @@ static void ping6(len_and_sockaddr *lsa)
if (if_index)
pingaddr.sin6.sin6_scope_id = if_index;
+ if ((pingaddr.sin6.sin6_addr.s6_addr16[0] & htons(0xff00)) == htons(0xff00)) {
+ if (myid && pmtudisc >= 0 && pmtudisc != IPV6_PMTUDISC_DO)
+ bb_error_msg_and_die("multicast ping does not fragment");
+ if (pmtudisc < 0)
+ pmtudisc = IPV6_PMTUDISC_DO;
+ }
+ if (pmtudisc >= 0)
+ setsockopt_int(pingsock, SOL_IPV6, IPV6_MTU_DISCOVER, pmtudisc);
+
signal(SIGINT, print_stats_and_exit);
/* start the ping's going ... */
@@ -858,13 +887,13 @@ static void ping(len_and_sockaddr *lsa)
static int common_ping_main(int opt, char **argv)
{
len_and_sockaddr *lsa;
- char *str_s, *str_p;
+ char *str_s, *str_p, *str_M;
INIT_G();
/* exactly one argument needed; -v and -q don't mix; -c NUM, -t NUM, -w NUM, -W NUM */
opt_complementary = "=1:q--v:v--q:c+:t+:w+:W+";
- opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p);
+ opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I, &str_p, &str_M);
if (opt & OPT_s)
datalen = xatou16(str_s); // -s
if (opt & OPT_I) { // -I
@@ -877,6 +906,16 @@ static int common_ping_main(int opt, char **argv)
}
if (opt & OPT_p)
G.pattern = xstrtou_range(str_p, 16, 0, 255);
+ if (opt & OPT_M) { // -M
+ if (strcmp(str_M, "do") == 0)
+ pmtudisc = IP_PMTUDISC_DO;
+ else if (strcmp(str_M, "dont") == 0)
+ pmtudisc = IP_PMTUDISC_DONT;
+ else if (strcmp(str_M, "want") == 0)
+ pmtudisc = IP_PMTUDISC_WANT;
+ else
+ bb_show_usage();
+ }
myid = (uint16_t) getpid();
hostname = argv[optind];