Customized ping

- Add -u option to send UDP packets
- Don't print dots when flooding
- Don't require root user
This commit is contained in:
Jan Schär 2022-05-28 19:53:14 +02:00
parent 9db9053c97
commit 1beb079cb0
3 changed files with 19 additions and 16 deletions

View File

@ -275,6 +275,7 @@ main(int argc, char **argv)
.tmin = LONG_MAX,
.pipesize = -1,
.datalen = DEFDATALEN,
.protocol = IPPROTO_ICMP,
.screen_width = INT_MAX,
#ifdef HAVE_LIBCAP
.cap_raw = CAP_NET_RAW,
@ -311,7 +312,7 @@ main(int argc, char **argv)
hints.ai_family = AF_INET6;
/* Parse command line options */
while ((ch = getopt(argc, argv, "h?" "4bRT:" "6F:N:" "aABc:dDfi:I:l:Lm:M:nOp:qQ:rs:S:t:UvVw:W:")) != EOF) {
while ((ch = getopt(argc, argv, "h?" "4bRT:" "6F:N:" "aABc:dDfi:I:l:Lm:M:nOp:qQ:rs:S:t:uUvVw:W:")) != EOF) {
switch(ch) {
/* IPv4 specific options */
case '4':
@ -398,8 +399,6 @@ main(int argc, char **argv)
break;
case 'l':
rts.preload = strtol_or_err(optarg, _("invalid argument"), 1, MAX_DUP_CHK);
if (rts.uid && rts.preload > 3)
error(2, 0, _("cannot set preload to value greater than 3: %d"), rts.preload);
break;
case 'L':
rts.opt_noloop = 1;
@ -456,6 +455,9 @@ main(int argc, char **argv)
rts.ttl = strtol_or_err(optarg, _("invalid argument"), 0, 255);
rts.opt_ttl = 1;
break;
case 'u':
rts.protocol = IPPROTO_UDP;
break;
case 'U':
rts.opt_latency = 1;
break;
@ -503,7 +505,7 @@ main(int argc, char **argv)
/* Create sockets */
enable_capability_raw();
if (hints.ai_family != AF_INET6)
create_socket(&rts, &sock4, AF_INET, hints.ai_socktype, IPPROTO_ICMP,
create_socket(&rts, &sock4, AF_INET, hints.ai_socktype, rts.protocol,
hints.ai_family == AF_INET);
if (hints.ai_family != AF_INET) {
create_socket(&rts, &sock6, AF_INET6, hints.ai_socktype, IPPROTO_ICMPV6, sock4.fd == -1);
@ -676,6 +678,7 @@ int ping4_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
argc--;
argv++;
}
rts->whereto.sin_port = htons(7);
if (rts->source.sin_addr.s_addr == 0) {
socklen_t alen;
@ -884,7 +887,9 @@ int ping4_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
printf(_("PING %s (%s) "), rts->hostname, inet_ntoa(rts->whereto.sin_addr));
if (rts->device || rts->opt_strictsource)
printf(_("from %s %s: "), inet_ntoa(rts->source.sin_addr), rts->device ? rts->device : "");
printf(_("%zu(%zu) bytes of data.\n"), rts->datalen, rts->datalen + 8 + rts->optlen + 20);
int extralen = 0;
if (rts->protocol == IPPROTO_UDP) extralen = 8;
printf(_("%zu(%zu) bytes of data.\n"), rts->datalen, rts->datalen + 8 + rts->optlen + 20 + extralen);
setup(rts, sock);
@ -1501,7 +1506,7 @@ int ping4_parse_reply(struct ping_rts *rts, struct socket_st *sock,
icp = (struct icmphdr *)(buf + hlen);
csfailed = in_cksum((unsigned short *)icp, cc, 0);
if (icp->type == ICMP_ECHOREPLY) {
if (icp->type == ICMP_ECHOREPLY || icp->type == ICMP_ECHO) {
if (!is_ours(rts, sock, icp->un.echo.id))
return 1; /* 'Twas not our ECHO */

View File

@ -145,6 +145,7 @@ struct ping_rts {
struct rcvd_table rcvd_tbl;
size_t datalen;
int protocol;
char *hostname;
uid_t uid;
int ident; /* random id to identify our packets */

View File

@ -356,9 +356,9 @@ resend:
if (!rts->opt_quiet && rts->opt_flood) {
/* Very silly, but without this output with
* high preload or pipe size is very confusing. */
if ((rts->preload < rts->screen_width && rts->pipesize < rts->screen_width) ||
in_flight(rts) < rts->screen_width)
write_stdout(".", 1);
// if ((rts->preload < rts->screen_width && rts->pipesize < rts->screen_width) ||
// in_flight(rts) < rts->screen_width)
// write_stdout(".", 1);
}
return rts->interval - tokens;
}
@ -476,9 +476,6 @@ void setup(struct ping_rts *rts, socket_st *sock)
if (rts->opt_flood && !rts->opt_interval)
rts->interval = 0;
if (rts->uid && rts->interval < MINUSERINTERVAL)
error(2, 0, _("cannot flood; minimal interval allowed for user is %dms"), MINUSERINTERVAL);
if (rts->interval >= INT_MAX / rts->preload)
error(2, 0, _("illegal preload and/or interval: %d"), rts->interval);
@ -777,10 +774,10 @@ restamp:
return 1;
if (rts->opt_flood) {
if (!csfailed)
write_stdout("\b \b", 3);
else
write_stdout("\bC", 2);
// if (!csfailed)
// write_stdout("\b \b", 3);
// else
// write_stdout("\bC", 2);
} else {
size_t i;
uint8_t *cp, *dp;