Date: Mon, 20 Oct 2014 16:29:07 +0900 (JST) From: Hiroki Sato <hrs@FreeBSD.org> To: brde@optusnet.com.au Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r273295 - in head/sbin: ping ping6 Message-ID: <20141020.162907.106891462107570268.hrs@allbsd.org> In-Reply-To: <20141020140848.D935@besplex.bde.org> References: <201410200027.s9K0RegN062458@svn.freebsd.org> <20141020140848.D935@besplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
----Security_Multipart0(Mon_Oct_20_16_29_08_2014_920)--
Content-Type: Multipart/Mixed;
boundary="--Next_Part(Mon_Oct_20_16_29_07_2014_483)--"
Content-Transfer-Encoding: 7bit
----Next_Part(Mon_Oct_20_16_29_07_2014_483)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Hi Bruce,
Thank you for your review. I fixed lines you pointed out and
attached a patch candidate. I will show each change line by line in
this email, too:
Bruce Evans <brde@optusnet.com.au> wrote
in <20141020140848.D935@besplex.bde.org>:
br> > - if (cc - ICMP_MINLEN - phdr_len >= sizeof(tv1)) {
br> > + if ((size_t)(cc - ICMP_MINLEN - phdr_len) >=
br> > + sizeof(tv1)) {
br> > /* Copy to avoid alignment problems: */
br> > memcpy(&tv32, tp, sizeof(tv32));
br> > tv1.tv_sec = ntohl(tv32.tv32_sec);
br>
br> This breaks the warning, and breaks the code on exotic (unsupported)
br> where it used to work accidentally. The code was already broken on
br> non-exotic arches.
- if ((size_t)(cc - ICMP_MINLEN - phdr_len) >=
- sizeof(tv1)) {
+ if (cc - ICMP_MINLEN - phdr_len >= (int)sizeof(tv1)) {
br> > -struct sockaddr_in6 dst; /* who to ping6 */
br> > -struct sockaddr_in6 src; /* src addr of this packet */
br> > -socklen_t srclen;
br>
br> Old code like ping uses plain int for almost everything except where
br> the broken ABI requires an unsigned type like socklen_t.
-static socklen_t srclen;
-static size_t datalen = DEFDATALEN;
+static int srclen;
+static int datalen = DEFDATALEN;
br> > +static u_int8_t nonce[8]; /* nonce field for node information */
br>
br> This uses the deprecated nonstandard spelling of uint8_t.
s/u_int_{8,16,32}_t/uint_{8,16,32}_t/ in various places.
br> > -void pr_suptypes(struct icmp6_nodeinfo *, size_t);
s/size_t/int/
br> > - sockbufsize = lsockbufsize;
br> > + sockbufsize = (int)lsockbufsize;
br> > if (errno || !*optarg || *e ||
br> > - sockbufsize != lsockbufsize)
br> > + lsockbufsize > INT_MAX)
br> > errx(1, "invalid socket buffer size");
br> I don't like warnings about hackish but correct code like the previous
br> version of the above. Does the compiler actually complain about
br> comparing
br> ints with unsigned longs for equality?
Yes, this part caused the following warning:
/usr/src/head/sbin/ping6/ping6.c:395:20: error: comparison of integers of
different signs: 'int' and 'u_long' (aka 'unsigned long')
[-Werror,-Wsign-compare]
sockbufsize != lsockbufsize)
br> If you are going to change the range check, then rearrange the code.
br> It
br> was arranged to set sockbufsize before the value is known to fit so
br> that
br> non-fitting values can be checked. With range checking on the
br>
br> original
br> value, it is more natural to not do the assignment until after the
br> check has passed. Then the cast should be unnecessary since a smart
br> compiler would see from the range check that the assignment can't
br> overflow.
- lsockbufsize = strtoul(optarg, &e, 10);
- sockbufsize = (int)lsockbufsize;
- if (errno || !*optarg || *e ||
- lsockbufsize > INT_MAX)
+ ultmp = strtoul(optarg, &e, 10);
+ if (errno || !*optarg || *e || ultmp > INT_MAX)
errx(1, "invalid socket buffer size");
+ sockbufsize = ultmp;
br> > - if (l >= sizeof(cresult) || l < 0)
br> > + if ((size_t)l >= sizeof(cresult) || l < 0)
br>
br> The conversion is backwards.
br>
- if ((size_t)l >= sizeof(cresult) || l < 0)
+ if (l >= (int)sizeof(cresult) || l < 0)
br> > - if (end - (u_char *)ip6 < sizeof(*ip6)) {
br> > + if ((size_t)(end - (u_char *)ip6) < sizeof(*ip6)) {
br> > printf("IP6");
br> > goto trunc;
br> > }
br>
br> Backwards. The RHS should be cast to ptrdiff_t. Pointer difference
br> are only required to work up to 64K, but that is enough for the size
br> of small objects.
- if ((size_t)(end - (u_char *)ip6) < sizeof(*ip6)) {
+ if (end - (u_char *)ip6 < (ptrdiff_t)sizeof(*ip6)) {
br> > - kk <= MAXDATALEN - (8 + sizeof(struct tv32) + ii);
br> > + (size_t)kk <= MAXDATALEN - 8 + sizeof(struct tv32) + ii;
- (size_t)kk <= MAXDATALEN - 8 + sizeof(struct tv32) + ii;
+ kk <= MAXDATALEN - 8 + (int)sizeof(struct tv32) + ii;
-- Hiroki
----Next_Part(Mon_Oct_20_16_29_07_2014_483)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="ping6.c_20141020-1.diff"
Index: ping6.c
===================================================================
--- ping6.c (revision 273295)
+++ ping6.c (working copy)
@@ -122,6 +122,7 @@
#include <fcntl.h>
#include <math.h>
#include <signal.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -136,8 +137,8 @@
#include <md5.h>
struct tv32 {
- u_int32_t tv32_sec;
- u_int32_t tv32_usec;
+ uint32_t tv32_sec;
+ uint32_t tv32_usec;
};
#define MAXPACKETLEN 131072
@@ -210,8 +211,8 @@
static struct sockaddr_in6 dst; /* who to ping6 */
static struct sockaddr_in6 src; /* src addr of this packet */
-static socklen_t srclen;
-static size_t datalen = DEFDATALEN;
+static int srclen;
+static int datalen = DEFDATALEN;
static int s; /* socket file descriptor */
static u_char outpack[MAXPACKETLEN];
static char BSPACE = '\b'; /* characters written for flood */
@@ -219,7 +220,7 @@
static char DOT = '.';
static char *hostname;
static int ident; /* process id to identify our packets */
-static u_int8_t nonce[8]; /* nonce field for node information */
+static u_char nonce[8]; /* nonce field for node information */
static int hoplimit = -1; /* hoplimit */
static u_char *packet = NULL;
@@ -265,17 +266,17 @@
static const char *pr_addr(struct sockaddr *, int);
static void pr_icmph(struct icmp6_hdr *, u_char *);
static void pr_iph(struct ip6_hdr *);
-static void pr_suptypes(struct icmp6_nodeinfo *, size_t);
+static void pr_suptypes(struct icmp6_nodeinfo *, int);
static void pr_nodeaddr(struct icmp6_nodeinfo *, int);
static int myechoreply(const struct icmp6_hdr *);
static int mynireply(const struct icmp6_nodeinfo *);
static char *dnsdecode(const u_char **, const u_char *, const u_char *,
- char *, size_t);
+ char *, int);
static void pr_pack(u_char *, int, struct msghdr *);
static void pr_exthdrs(struct msghdr *);
-static void pr_ip6opt(void *, size_t);
-static void pr_rthdr(void *, size_t);
-static int pr_bitrange(u_int32_t, int, int);
+static void pr_ip6opt(void *, int);
+static void pr_rthdr(void *, int);
+static int pr_bitrange(uint32_t, int, int);
static void pr_retip(struct ip6_hdr *, u_char *);
static void summary(void);
static void tvsub(struct timeval *, struct timeval *);
@@ -303,7 +304,6 @@
/* For control (ancillary) data received from recvmsg() */
struct cmsghdr cm[CONTROLLEN];
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
- u_long lsockbufsize;
int sockbufsize = 0;
#endif
int usepktinfo = 0;
@@ -316,7 +316,7 @@
char *policy_out = NULL;
#endif
double t;
- u_long alarmtimeout;
+ u_long alarmtimeout, ultmp;
size_t rthlen;
#ifdef IPV6_USE_MIN_MTU
int mflag = 0;
@@ -388,11 +388,10 @@
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
errno = 0;
e = NULL;
- lsockbufsize = strtoul(optarg, &e, 10);
- sockbufsize = (int)lsockbufsize;
- if (errno || !*optarg || *e ||
- lsockbufsize > INT_MAX)
+ ultmp = strtoul(optarg, &e, 10);
+ if (errno || !*optarg || *e || ultmp > INT_MAX)
errx(1, "invalid socket buffer size");
+ sockbufsize = ultmp;
#else
errx(1,
"-b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported");
@@ -522,14 +521,15 @@
options |= F_SRCADDR;
break;
case 's': /* size of packet to send */
- datalen = strtol(optarg, &e, 10);
- if (datalen <= 0 || *optarg == '\0' || *e != '\0')
- errx(1, "illegal datalen value -- %s", optarg);
- if (datalen > MAXDATALEN) {
- errx(1,
- "datalen value too large, maximum is %d",
+ ultmp = strtoul(optarg, &e, 10);
+ if (*e || e == optarg)
+ errx(EX_USAGE, "invalid packet size: `%s'",
+ optarg);
+ if (ultmp > MAXDATALEN)
+ errx(EX_USAGE,
+ "packetsize too large, maximum is %d",
MAXDATALEN);
- }
+ datalen = ultmp;
break;
case 't':
options &= ~F_NOUSERDATA;
@@ -718,7 +718,7 @@
errx(1, "-f and -i incompatible options");
if ((options & F_NOUSERDATA) == 0) {
- if (datalen >= sizeof(struct tv32)) {
+ if (datalen >= (int)sizeof(struct tv32)) {
/* we can time transfer */
timing = 1;
} else
@@ -746,12 +746,12 @@
gettimeofday(&seed, NULL);
srand((unsigned int)(seed.tv_sec ^ seed.tv_usec ^ (long)ident));
memset(nonce, 0, sizeof(nonce));
- for (i = 0; i < sizeof(nonce); i += sizeof(int))
+ for (i = 0; i < (int)sizeof(nonce); i += sizeof(int))
*((int *)&nonce[i]) = rand();
#else
memset(nonce, 0, sizeof(nonce));
- for (i = 0; i < (int)sizeof(nonce); i += sizeof(u_int32_t))
- *((u_int32_t *)&nonce[i]) = arc4random();
+ for (i = 0; i < (int)sizeof(nonce); i += sizeof(uint32_t))
+ *((uint32_t *)&nonce[i]) = arc4random();
#endif
optval = 1;
if (options & F_DONTFRAG)
@@ -1008,7 +1008,7 @@
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
if (sockbufsize) {
- if (datalen > (size_t)sockbufsize)
+ if (datalen > sockbufsize)
warnx("you need -b to increase socket buffer size");
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
sizeof(sockbufsize)) < 0)
@@ -1292,7 +1292,7 @@
memcpy(nip->icmp6_ni_nonce, nonce,
sizeof(nip->icmp6_ni_nonce));
- *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+ *(uint16_t *)nip->icmp6_ni_nonce = ntohs(seq);
memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr,
sizeof(dst.sin6_addr));
@@ -1307,7 +1307,7 @@
memcpy(nip->icmp6_ni_nonce, nonce,
sizeof(nip->icmp6_ni_nonce));
- *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+ *(uint16_t *)nip->icmp6_ni_nonce = ntohs(seq);
cc = ICMP6_NIQLEN;
datalen = 0;
@@ -1319,7 +1319,7 @@
memcpy(nip->icmp6_ni_nonce, nonce,
sizeof(nip->icmp6_ni_nonce));
- *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+ *(uint16_t *)nip->icmp6_ni_nonce = ntohs(seq);
memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr,
sizeof(dst.sin6_addr));
@@ -1334,7 +1334,7 @@
memcpy(nip->icmp6_ni_nonce, nonce,
sizeof(nip->icmp6_ni_nonce));
- *(u_int16_t *)nip->icmp6_ni_nonce = ntohs(seq);
+ *(uint16_t *)nip->icmp6_ni_nonce = ntohs(seq);
cc = ICMP6_NIQLEN;
datalen = 0;
} else {
@@ -1392,9 +1392,9 @@
static int
mynireply(const struct icmp6_nodeinfo *nip)
{
- if (memcmp(nip->icmp6_ni_nonce + sizeof(u_int16_t),
- nonce + sizeof(u_int16_t),
- sizeof(nonce) - sizeof(u_int16_t)) == 0)
+ if (memcmp(nip->icmp6_ni_nonce + sizeof(uint16_t),
+ nonce + sizeof(uint16_t),
+ sizeof(nonce) - sizeof(uint16_t)) == 0)
return 1;
else
return 0;
@@ -1402,7 +1402,7 @@
static char *
dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf,
- size_t bufsiz)
+ int bufsiz)
/*base for compressed name*/
{
int i;
@@ -1419,7 +1419,7 @@
while (cp < ep) {
i = *cp;
if (i == 0 || cp != *sp) {
- if (strlcat((char *)buf, ".", bufsiz) >= bufsiz)
+ if ((int)strlcat((char *)buf, ".", bufsiz) >= bufsiz)
return NULL; /*result overrun*/
}
if (i == 0)
@@ -1435,7 +1435,7 @@
if (dnsdecode(&comp, cp, base, cresult,
sizeof(cresult)) == NULL)
return NULL;
- if (strlcat(buf, cresult, bufsiz) >= bufsiz)
+ if ((int)strlcat(buf, cresult, bufsiz) >= bufsiz)
return NULL; /*result overrun*/
break;
} else if ((i & 0x3f) == i) {
@@ -1444,9 +1444,10 @@
while (i-- > 0 && cp < ep) {
l = snprintf(cresult, sizeof(cresult),
isprint(*cp) ? "%c" : "\\%03o", *cp & 0xff);
- if ((size_t)l >= sizeof(cresult) || l < 0)
+ if (l >= (int)sizeof(cresult) || l < 0)
return NULL;
- if (strlcat(buf, cresult, bufsiz) >= bufsiz)
+ if ((int)strlcat(buf, cresult, bufsiz) >=
+ bufsiz)
return NULL; /*result overrun*/
cp++;
}
@@ -1485,7 +1486,7 @@
int dupflag;
size_t off;
int oldfqdn;
- u_int16_t seq;
+ uint16_t seq;
char dnsname[MAXDNAME + 1];
(void)gettimeofday(&tv, NULL);
@@ -1591,7 +1592,7 @@
}
}
} else if (icp->icmp6_type == ICMP6_NI_REPLY && mynireply(ni)) {
- seq = ntohs(*(u_int16_t *)ni->icmp6_ni_nonce);
+ seq = ntohs(*(uint16_t *)ni->icmp6_ni_nonce);
++nreceived;
if (TST(seq % mx_dup_ck)) {
++nrepeats;
@@ -1792,16 +1793,16 @@
#ifdef USE_RFC2292BIS
static void
-pr_ip6opt(void *extbuf, size_t bufsize)
+pr_ip6opt(void *extbuf, int bufsize)
{
struct ip6_hbh *ext;
int currentlen;
- u_int8_t type;
+ u_char type;
socklen_t extlen, len;
void *databuf;
size_t offset;
- u_int16_t value2;
- u_int32_t value4;
+ uint16_t value2;
+ uint32_t value4;
ext = (struct ip6_hbh *)extbuf;
extlen = (ext->ip6h_len + 1) * 8;
@@ -1812,7 +1813,7 @@
* Bounds checking on the ancillary data buffer:
* subtract the size of a cmsg structure from the buffer size.
*/
- if (bufsize < (extlen + CMSG_SPACE(0))) {
+ if (bufsize < (int)(extlen + CMSG_SPACE(0))) {
extlen = bufsize - CMSG_SPACE(0);
warnx("options truncated, showing only %u (total=%u)",
(unsigned int)(extlen / 8 - 1),
@@ -1835,7 +1836,7 @@
offset = inet6_opt_get_val(databuf, offset,
&value4, sizeof(value4));
printf(" Jumbo Payload Opt: Length %u\n",
- (u_int32_t)ntohl(value4));
+ (uint32_t)ntohl(value4));
break;
case IP6OPT_ROUTER_ALERT:
offset = 0;
@@ -1864,7 +1865,7 @@
#ifdef USE_RFC2292BIS
static void
-pr_rthdr(void *extbuf, size_t bufsize)
+pr_rthdr(void *extbuf, int bufsize)
{
struct in6_addr *in6;
char ntopbuf[INET6_ADDRSTRLEN];
@@ -1892,7 +1893,7 @@
* dividend is not evenly divisible by the divisor
*/
rthsize = (rh->ip6r_len + 1) * 8;
- if (bufsize < (rthsize + CMSG_SPACE(0))) {
+ if (bufsize < (int)(rthsize + CMSG_SPACE(0))) {
origsegs = segments;
size0 = inet6_rth_space(IPV6_RTHDR_TYPE_0, 0);
size1 = inet6_rth_space(IPV6_RTHDR_TYPE_0, 1);
@@ -1929,7 +1930,7 @@
#endif /* USE_RFC2292BIS */
static int
-pr_bitrange(u_int32_t v, int soff, int ii)
+pr_bitrange(uint32_t v, int soff, int ii)
{
int off;
int i;
@@ -1975,16 +1976,16 @@
}
static void
-pr_suptypes(struct icmp6_nodeinfo *ni, size_t nilen)
+pr_suptypes(struct icmp6_nodeinfo *ni, int nilen)
/* ni->qtype must be SUPTYPES */
{
size_t clen;
- u_int32_t v;
+ uint32_t v;
const u_char *cp, *end;
- u_int16_t cur;
+ uint16_t cur;
struct cbit {
- u_int16_t words; /*32bit count*/
- u_int16_t skip;
+ uint16_t words; /*32bit count*/
+ uint16_t skip;
} cbit;
#define MAXQTYPES (1 << 16)
size_t off;
@@ -2027,7 +2028,7 @@
for (off = 0; off < clen; off += sizeof(v)) {
memcpy(&v, cp + off, sizeof(v));
- v = (u_int32_t)ntohl(v);
+ v = (uint32_t)ntohl(v);
b = pr_bitrange(v, (int)(cur + off * 8), b);
}
/* flush the remaining bits */
@@ -2072,16 +2073,16 @@
* by the length of the data, but note that the detection algorithm
* is incomplete. We assume the latest draft by default.
*/
- if (nilen % (sizeof(u_int32_t) + sizeof(struct in6_addr)) == 0)
+ if (nilen % (sizeof(uint32_t) + sizeof(struct in6_addr)) == 0)
withttl = 1;
while (nilen > 0) {
- u_int32_t ttl;
+ uint32_t ttl;
if (withttl) {
/* XXX: alignment? */
- ttl = (u_int32_t)ntohl(*(u_int32_t *)cp);
- cp += sizeof(u_int32_t);
- nilen -= sizeof(u_int32_t);
+ ttl = (uint32_t)ntohl(*(uint32_t *)cp);
+ cp += sizeof(uint32_t);
+ nilen -= sizeof(uint32_t);
}
if (inet_ntop(AF_INET6, cp, ntop_buf, sizeof(ntop_buf)) ==
@@ -2358,7 +2359,7 @@
break;
}
(void)printf("pointer = 0x%02x\n",
- (u_int32_t)ntohl(icp->icmp6_pptr));
+ (uint32_t)ntohl(icp->icmp6_pptr));
pr_retip((struct ip6_hdr *)(icp + 1), end);
break;
case ICMP6_ECHO_REQUEST:
@@ -2517,8 +2518,8 @@
static void
pr_iph(struct ip6_hdr *ip6)
{
- u_int32_t flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
- u_int8_t tc;
+ uint32_t flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
+ u_char tc;
char ntop_buf[INET6_ADDRSTRLEN];
tc = *(&ip6->ip6_vfc + 1); /* XXX */
@@ -2527,7 +2528,7 @@
printf("Vr TC Flow Plen Nxt Hlim\n");
printf(" %1x %02x %05x %04x %02x %02x\n",
- (ip6->ip6_vfc & IPV6_VERSION_MASK) >> 4, tc, (u_int32_t)ntohl(flow),
+ (ip6->ip6_vfc & IPV6_VERSION_MASK) >> 4, tc, (uint32_t)ntohl(flow),
ntohs(ip6->ip6_plen), ip6->ip6_nxt, ip6->ip6_hlim);
if (!inet_ntop(AF_INET6, &ip6->ip6_src, ntop_buf, sizeof(ntop_buf)))
strlcpy(ntop_buf, "?", sizeof(ntop_buf));
@@ -2567,7 +2568,7 @@
u_char *cp = (u_char *)ip6, nh;
int hlen;
- if ((size_t)(end - (u_char *)ip6) < sizeof(*ip6)) {
+ if (end - (u_char *)ip6 < (ptrdiff_t)sizeof(*ip6)) {
printf("IP6");
goto trunc;
}
@@ -2660,7 +2661,7 @@
/* xxx */
if (ii > 0)
for (kk = 0;
- (size_t)kk <= MAXDATALEN - 8 + sizeof(struct tv32) + ii;
+ kk <= MAXDATALEN - 8 + (int)sizeof(struct tv32) + ii;
kk += ii)
for (jj = 0; jj < ii; ++jj)
bp[jj + kk] = pat[jj];
@@ -2701,8 +2702,8 @@
char *p;
char *q;
MD5_CTX ctxt;
- u_int8_t digest[16];
- u_int8_t c;
+ u_char digest[16];
+ u_char c;
size_t l;
char hbuf[NI_MAXHOST];
struct in6_addr in6;
----Next_Part(Mon_Oct_20_16_29_07_2014_483)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="ping.c_20141020-1.diff"
Index: ping.c
===================================================================
--- ping.c (revision 273295)
+++ ping.c (working copy)
@@ -1150,8 +1150,7 @@
#endif
tp = (const char *)tp + phdr_len;
- if ((size_t)(cc - ICMP_MINLEN - phdr_len) >=
- sizeof(tv1)) {
+ if (cc - ICMP_MINLEN - phdr_len >= (int)sizeof(tv1)) {
/* Copy to avoid alignment problems: */
memcpy(&tv32, tp, sizeof(tv32));
tv1.tv_sec = ntohl(tv32.tv32_sec);
----Next_Part(Mon_Oct_20_16_29_07_2014_483)----
----Security_Multipart0(Mon_Oct_20_16_29_08_2014_920)--
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iEYEABECAAYFAlREucQACgkQTyzT2CeTzy0jVgCdGyvQeygiqdT6YEwEeLjZNu3b
vlQAn0B5WipasyJUBlhUvaN+KfxKpgE5
=KA1u
-----END PGP SIGNATURE-----
----Security_Multipart0(Mon_Oct_20_16_29_08_2014_920)----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20141020.162907.106891462107570268.hrs>
