summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSami Kerola <kerolasa@iki.fi>2019-08-28 20:50:00 +0100
committerSami Kerola <kerolasa@iki.fi>2019-08-28 22:01:58 +0100
commite88c3c1ac1ce7dbd4834fdddbeefaa066d60da10 (patch)
tree0a703ee8205e9a3f0f297ec95580c3e373ae6b2e
parent18f14be80466ddc8fb17a400be82764a779c8dcd (diff)
downloadiputils-bugfix-210.tar.gz
ping: allow any package size to be defined by userbugfix-210
If size is too large operating system will inform things did not work out. Addresses: https://github.com/iputils/iputils/issues/210 Signed-off-by: Sami Kerola <kerolasa@iki.fi>
-rw-r--r--ping.c21
-rw-r--r--ping.h7
-rw-r--r--ping6_common.c2
-rw-r--r--ping_common.c22
4 files changed, 30 insertions, 22 deletions
diff --git a/ping.c b/ping.c
index 95b782e..daef749 100644
--- a/ping.c
+++ b/ping.c
@@ -272,6 +272,7 @@ main(int argc, char **argv)
socket_st sock4 = { .fd = -1 };
socket_st sock6 = { .fd = -1 };
char *target;
+ char *outpack_fill = NULL;
atexit(close_stdout);
limit_capabilities();
@@ -430,7 +431,9 @@ main(int argc, char **argv)
break;
case 'p':
options |= F_PINGFILLED;
- fill(optarg, outpack, sizeof(outpack));
+ outpack_fill = strdup(optarg);
+ if (!outpack_fill)
+ error(2, errno, _("memory allocation failed"));
break;
case 'q':
options |= F_QUIET;
@@ -443,7 +446,7 @@ main(int argc, char **argv)
options |= F_SO_DONTROUTE;
break;
case 's':
- datalen = strtol_or_err(optarg, _("invalid argument"), 0, MAXPACKET - 8);
+ datalen = strtol_or_err(optarg, _("invalid argument"), 0, INT_MAX);
break;
case 'S':
sndbuf = strtol_or_err(optarg, _("invalid argument"), 1, INT_MAX);
@@ -489,6 +492,12 @@ main(int argc, char **argv)
target = argv[argc - 1];
+ outpack = malloc(datalen + 28);
+ if (!outpack)
+ error(2, errno, _("memory allocation failed"));
+ if (outpack_fill)
+ fill(outpack_fill, outpack, datalen);
+
/* Create sockets */
enable_capability_raw();
if (hints.ai_family != AF_INET6)
@@ -539,6 +548,8 @@ main(int argc, char **argv)
}
freeaddrinfo(result);
+ free(outpack);
+ free(outpack_fill);
return ret_val;
}
@@ -864,10 +875,6 @@ int ping4_run(int argc, char **argv, struct addrinfo *ai, socket_st *sock)
error(2, errno, _("cannot set unicast time-to-live"));
}
- if (datalen > 0xFFFF - 8 - optlen - 20)
- error(2, 0, _("packet size %d is too large. Maximum is %d"),
- datalen, 0xFFFF - 8 - 20 - optlen);
-
if (datalen >= (int)sizeof(struct timeval)) /* can we time transfer */
timing = 1;
packlen = datalen + MAXIPLEN + MAXICMPLEN;
@@ -877,7 +884,7 @@ int ping4_run(int argc, char **argv, struct addrinfo *ai, socket_st *sock)
printf(_("PING %s (%s) "), hostname, inet_ntoa(whereto.sin_addr));
if (device || (options & F_STRICTSOURCE))
printf(_("from %s %s: "), inet_ntoa(source.sin_addr), device ? device : "");
- printf(_("%d(%d) bytes of data.\n"), datalen, datalen + 8 + optlen + 20);
+ printf(_("%zu(%zu) bytes of data.\n"), datalen, datalen + 8 + optlen + 20);
setup(sock);
diff --git a/ping.h b/ping.h
index 1d015ad..bf675bf 100644
--- a/ping.h
+++ b/ping.h
@@ -139,7 +139,7 @@ static inline bitmap_t rcvd_test(uint16_t seq)
return A(bit) & B(bit);
}
-extern int datalen;
+extern size_t datalen;
extern char *hostname;
extern int uid;
extern int ident; /* process id to identify our packets */
@@ -298,7 +298,6 @@ typedef struct ping_func_set_st {
void (*install_filter)(socket_st *);
} ping_func_set_st;
-#define MAXPACKET 128000 /* max packet size */
extern ping_func_set_st ping4_func_set;
extern int pinger(ping_func_set_st *fset, socket_st *sock);
@@ -314,10 +313,10 @@ extern int gather_statistics(uint8_t *ptr, int icmplen,
int csfailed, struct timeval *tv, char *from,
void (*pr_reply)(uint8_t *ptr, int cc), int multicast);
extern void print_timestamp(void);
-void fill(char *patp, unsigned char *packet, unsigned packet_size);
+void fill(char *patp, unsigned char *packet, size_t packet_size);
extern int mark;
-extern unsigned char outpack[MAXPACKET];
+extern unsigned char *outpack;
/* IPv6 */
diff --git a/ping6_common.c b/ping6_common.c
index adce865..a38218c 100644
--- a/ping6_common.c
+++ b/ping6_common.c
@@ -837,7 +837,7 @@ int ping6_run(int argc, char **argv, struct addrinfo *ai, struct socket_st *sock
printf(_("from %s %s: "), pr_addr(&source6, sizeof source6), device ? device : "");
options = saved_options;
}
- printf(_("%d data bytes\n"), datalen);
+ printf(_("%zu data bytes\n"), datalen);
setup(sock);
diff --git a/ping_common.c b/ping_common.c
index e91d15c..7a1a3bf 100644
--- a/ping_common.c
+++ b/ping_common.c
@@ -45,7 +45,7 @@ int rtt;
int rtt_addend;
uint16_t acked;
-unsigned char outpack[MAXPACKET];
+unsigned char *outpack;
struct rcvd_table rcvd_tbl;
/* counters */
@@ -84,7 +84,7 @@ double tsum; /* sum of all times, for doing average */
double tsum2;
int pipesize = -1;
-int datalen = DEFDATALEN;
+size_t datalen = DEFDATALEN;
char *hostname;
int uid;
@@ -249,7 +249,7 @@ void drop_capabilities(void)
/* Fills all the outpack, excluding ICMP header, but _including_
* timestamp area with supplied pattern.
*/
-void fill(char *patp, unsigned char *packet, unsigned packet_size)
+void fill(char *patp, unsigned char *packet, size_t packet_size)
{
int ii, jj;
unsigned int pat[16];
@@ -271,8 +271,10 @@ void fill(char *patp, unsigned char *packet, unsigned packet_size)
&pat[12], &pat[13], &pat[14], &pat[15]);
if (ii > 0) {
- unsigned kk;
- for (kk = 0; kk <= packet_size - (8 + ii); kk += ii)
+ size_t kk;
+ size_t max = packet_size < (size_t)(8 + ii) ? 0 : packet_size - (8 + ii);
+
+ for (kk = 0; kk <= max; kk += ii)
for (jj = 0; jj < ii; ++jj)
bp[jj + kk] = pat[jj];
}
@@ -567,7 +569,7 @@ void setup(socket_st *sock)
options |= F_FLOOD_POLL;
if (!(options & F_PINGFILLED)) {
- int i;
+ size_t i;
unsigned char *p = outpack + 8;
/* Do not forget about case of small datalen, fill timestamp area too! */
@@ -612,7 +614,7 @@ void setup(socket_st *sock)
*/
int contains_pattern_in_payload(uint8_t *ptr)
{
- int i;
+ size_t i;
uint8_t *cp, *dp;
/* check the data */
@@ -845,7 +847,7 @@ restamp:
else
write_stdout("\bC", 2);
} else {
- int i;
+ size_t i;
uint8_t *cp, *dp;
print_timestamp();
@@ -884,12 +886,12 @@ restamp:
dp = &outpack[8 + sizeof(struct timeval)];
for (i = sizeof(struct timeval); i < datalen; ++i, ++cp, ++dp) {
if (*cp != *dp) {
- printf(_("\nwrong data byte #%d should be 0x%x but was 0x%x"),
+ printf(_("\nwrong data byte #%zu should be 0x%x but was 0x%x"),
i, *dp, *cp);
cp = (unsigned char *)ptr + sizeof(struct timeval);
for (i = sizeof(struct timeval); i < datalen; ++i, ++cp) {
if ((i % 32) == sizeof(struct timeval))
- printf("\n#%d\t", i);
+ printf("\n#%zu\t", i);
printf("%x ", *cp);
}
break;