Page MenuHomeFreeBSD

D38490.id116942.diff
No OneTemporary

D38490.id116942.diff

diff --git a/sbin/ping/ping.8 b/sbin/ping/ping.8
--- a/sbin/ping/ping.8
+++ b/sbin/ping/ping.8
@@ -28,7 +28,7 @@
.\" @(#)ping.8 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
-.Dd November 20, 2022
+.Dd January 10, 2023
.Dt PING 8
.Os
.Sh NAME
@@ -429,6 +429,20 @@
This flag only applies if the ping destination is a multicast address.
.It Fl z Ar tos
Use the specified type of service.
+.Ar tos
+may be given as one of
+.Ar critical ,
+.Ar inetcontrol ,
+.Ar lowdelay ,
+.Ar netcontrol ,
+.Ar throughput ,
+.Ar reliability ,
+or one of the DiffServ Code Points:
+.Ar ef ,
+.Ar va ,
+.Ar af11 No ... Ar af43 ,
+.Ar cs0 No ... Ar cs7 ;
+or as either hex or decimal.
.It Ar IPv4-host
hostname or IPv4 address of the final destination node.
.It Ar IPv4-mcast-group
diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c
--- a/sbin/ping/ping.c
+++ b/sbin/ping/ping.c
@@ -128,6 +128,11 @@
int32_t tv32_nsec;
};
+struct keywords {
+ const char *k_name;
+ int k_val;
+};
+
/* various options */
static int options;
#define F_FLOOD 0x0001
@@ -226,6 +231,8 @@
static char *pr_ntime(n_time);
static void pr_icmph(struct icmp *, struct ip *, const u_char *const);
static void pr_iph(struct ip *);
+static int kw_casecmp(const void *, const void *);
+static int map_tos(char *string, int *);
static void pr_pack(char *, ssize_t, struct sockaddr_in *, struct timespec *);
static void pr_retip(struct ip *, const u_char *);
static void status(int);
@@ -544,8 +551,15 @@
break;
case 'z':
options |= F_HDRINCL;
- ltmp = strtol(optarg, &ep, 0);
- if (*ep || ep == optarg || ltmp > MAXTOS || ltmp < 0)
+ if (map_tos(optarg, &tos))
+ break;
+ if (strlen(optarg) > 1 && optarg[0] == '0' &&
+ optarg[1] == 'x')
+ ltmp = strtol(optarg, &ep, 16);
+ else
+ ltmp = strtonum(optarg, 0, MAXTOS, &errstr);
+ if (*ep || ep == optarg || ltmp > MAXTOS || ltmp < 0 ||
+ errstr || errno)
errx(EX_USAGE, "invalid TOS: `%s'", optarg);
tos = ltmp;
break;
@@ -1737,6 +1751,58 @@
(*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
}
+static int
+kw_casecmp(const void *k, const void *e)
+{
+ return (strcasecmp(k, ((const struct keywords *)e)->k_name));
+}
+
+static int
+map_tos(char *s, int *val)
+{
+ /* DiffServ Codepoints and other TOS mappings */
+ const struct keywords toswords[] = {
+ { "af11", IPTOS_DSCP_AF11 },
+ { "af12", IPTOS_DSCP_AF12 },
+ { "af13", IPTOS_DSCP_AF13 },
+ { "af21", IPTOS_DSCP_AF21 },
+ { "af22", IPTOS_DSCP_AF22 },
+ { "af23", IPTOS_DSCP_AF23 },
+ { "af31", IPTOS_DSCP_AF31 },
+ { "af32", IPTOS_DSCP_AF32 },
+ { "af33", IPTOS_DSCP_AF33 },
+ { "af41", IPTOS_DSCP_AF41 },
+ { "af42", IPTOS_DSCP_AF42 },
+ { "af43", IPTOS_DSCP_AF43 },
+ { "critical", IPTOS_PREC_CRITIC_ECP },
+ { "cs0", IPTOS_DSCP_CS0 },
+ { "cs1", IPTOS_DSCP_CS1 },
+ { "cs2", IPTOS_DSCP_CS2 },
+ { "cs3", IPTOS_DSCP_CS3 },
+ { "cs4", IPTOS_DSCP_CS4 },
+ { "cs5", IPTOS_DSCP_CS5 },
+ { "cs6", IPTOS_DSCP_CS6 },
+ { "cs7", IPTOS_DSCP_CS7 },
+ { "ef", IPTOS_DSCP_EF },
+ { "inetcontrol", IPTOS_PREC_INTERNETCONTROL },
+ { "lowdelay", IPTOS_LOWDELAY },
+ { "netcontrol", IPTOS_PREC_NETCONTROL },
+ { "reliability", IPTOS_RELIABILITY },
+ { "throughput", IPTOS_THROUGHPUT },
+ { "va", IPTOS_DSCP_VA },
+ };
+ const struct keywords *p;
+
+ p = bsearch(s, toswords, nitems(toswords), sizeof(toswords[0]),
+ kw_casecmp);
+
+ if (p) {
+ *val = p->k_val;
+ return (1);
+ }
+ return (0);
+}
+
static char *
pr_ntime(n_time timestamp)
{
diff --git a/sbin/ping/tests/test_ping.py b/sbin/ping/tests/test_ping.py
--- a/sbin/ping/tests/test_ping.py
+++ b/sbin/ping/tests/test_ping.py
@@ -698,6 +698,63 @@
},
id="_q_c3_2001_db8__2",
),
+ pytest.param(
+ {
+ "args": "ping -4 -zx localhost",
+ "returncode": os.EX_USAGE,
+ "stdout": "",
+ "stderr": "ping: invalid TOS: `x'\n",
+ },
+ id="_4_zx_localhost",
+ ),
+ pytest.param(
+ {
+ "args": "ping -4 -c1 -z48 localhost",
+ "returncode": 0,
+ "stdout": """\
+PING localhost: 56 data bytes
+64 bytes from: icmp_seq=0 ttl= time= ms
+
+--- localhost ping statistics ---
+1 packets transmitted, 1 packets received, 0.0% packet loss
+round-trip min/avg/max/stddev = /// ms
+""",
+ "stderr": "",
+ },
+ id="_4_c1_z48_localhost",
+ ),
+ pytest.param(
+ {
+ "args": "ping -4 -c1 -z0x30 localhost",
+ "returncode": 0,
+ "stdout": """\
+PING localhost: 56 data bytes
+64 bytes from: icmp_seq=0 ttl= time= ms
+
+--- localhost ping statistics ---
+1 packets transmitted, 1 packets received, 0.0% packet loss
+round-trip min/avg/max/stddev = /// ms
+""",
+ "stderr": "",
+ },
+ id="_4_c1_z0x30_localhost",
+ ),
+ pytest.param(
+ {
+ "args": "ping -4 -c1 -zinetcontrol localhost",
+ "returncode": 0,
+ "stdout": """\
+PING localhost: 56 data bytes
+64 bytes from: icmp_seq=0 ttl= time= ms
+
+--- localhost ping statistics ---
+1 packets transmitted, 1 packets received, 0.0% packet loss
+round-trip min/avg/max/stddev = /// ms
+""",
+ "stderr": "",
+ },
+ id="_4_c1_zinetcontrol_localhost",
+ ),
]
@pytest.mark.parametrize("expected", testdata)

File Metadata

Mime Type
text/plain
Expires
Thu, May 14, 8:19 PM (10 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33058436
Default Alt Text
D38490.id116942.diff (5 KB)

Event Timeline