ping6: Fix dnsdecode() bug introduced by r350859
Revision 350859 removed level of indirection that was needed for setting the caller's `cp' pointer. dnsdecode() uses return value to indicate error or success. It returns pointer to a buffer holding a decompressed DNS name or NULL. The caller uses that value only to find out the result, not for accessing the buffer. We use the return value to propagate the new value of `cp' pointer to the caller instead of using an output argument. Submitted by: Ján Sučan <sucanjan@gmail.com> MFC after: 2 weeks MFC-With: 350859 Sponsored by: Google, Inc (Google Summer of Code 2019) Differential Revision: https://reviews.freebsd.org/D21266
This commit is contained in:
parent
54e007d160
commit
60485fbc80
@ -279,7 +279,7 @@ static void pr_suptypes(struct icmp6_nodeinfo *, size_t);
|
||||
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 *,
|
||||
static const char *dnsdecode(const u_char *, const u_char *, const u_char *,
|
||||
char *, size_t);
|
||||
static void pr_pack(u_char *, int, struct msghdr *);
|
||||
static void pr_exthdrs(struct msghdr *);
|
||||
@ -1446,10 +1446,26 @@ mynireply(const struct icmp6_nodeinfo *nip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
/*
|
||||
* Decode a name from a DNS message.
|
||||
*
|
||||
* Format of the message is described in RFC 1035 subsection 4.1.4.
|
||||
*
|
||||
* Arguments:
|
||||
* sp - Pointer to a DNS pointer octet or to the first octet of a label
|
||||
* in the message.
|
||||
* ep - Pointer to the end of the message (one step past the last octet).
|
||||
* base - Pointer to the beginning of the message.
|
||||
* buf - Buffer into which the decoded name will be saved.
|
||||
* bufsiz - Size of the buffer 'buf'.
|
||||
*
|
||||
* Return value:
|
||||
* Pointer to an octet immediately following the ending zero octet
|
||||
* of the decoded label, or NULL if an error occured.
|
||||
*/
|
||||
static const char *
|
||||
dnsdecode(const u_char *sp, const u_char *ep, const u_char *base, char *buf,
|
||||
size_t bufsiz)
|
||||
/*base for compressed name*/
|
||||
{
|
||||
int i;
|
||||
const u_char *cp;
|
||||
@ -1502,8 +1518,7 @@ dnsdecode(const u_char *sp, const u_char *ep, const u_char *base, char *buf,
|
||||
if (i != 0)
|
||||
return NULL; /*not terminated*/
|
||||
cp++;
|
||||
sp = cp;
|
||||
return buf;
|
||||
return cp;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1523,7 +1538,8 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
|
||||
int hoplim;
|
||||
struct sockaddr *from;
|
||||
int fromlen;
|
||||
u_char *cp = NULL, *dp, *end = buf + cc;
|
||||
const u_char *cp = NULL;
|
||||
u_char *dp, *end = buf + cc;
|
||||
struct in6_pktinfo *pktinfo = NULL;
|
||||
struct timespec tv, tp;
|
||||
struct tv32 tpp;
|
||||
@ -1696,9 +1712,10 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
|
||||
} else {
|
||||
i = 0;
|
||||
while (cp < end) {
|
||||
if (dnsdecode((const u_char *)cp, end,
|
||||
cp = dnsdecode((const u_char *)cp, end,
|
||||
(const u_char *)(ni + 1), dnsname,
|
||||
sizeof(dnsname)) == NULL) {
|
||||
sizeof(dnsname));
|
||||
if (cp == NULL) {
|
||||
printf("???");
|
||||
break;
|
||||
}
|
||||
@ -2474,8 +2491,9 @@ pr_icmph(struct icmp6_hdr *icp, u_char *end)
|
||||
}
|
||||
printf(", subject=%s", niqcode[ni->ni_code]);
|
||||
cp = (const u_char *)(ni + 1);
|
||||
if (dnsdecode(cp, end, NULL, dnsname,
|
||||
sizeof(dnsname)) != NULL)
|
||||
cp = dnsdecode(cp, end, NULL, dnsname,
|
||||
sizeof(dnsname));
|
||||
if (cp != NULL)
|
||||
printf("(%s)", dnsname);
|
||||
else
|
||||
printf("(invalid)");
|
||||
|
Loading…
Reference in New Issue
Block a user