/*
* Defines for handling compressed domain names, EDNS0 labels, etc.
*/
-#define INDIR_MASK 0xc0 /* 11.... */
-#define EDNS0_MASK 0x40 /* 01.... */
+#define TYPE_MASK 0xc0 /* mask for the type bits of the item */
+#define TYPE_INDIR 0xc0 /* 11.... - pointer */
+#define TYPE_RESERVED 0x80 /* 10.... - reserved */
+#define TYPE_EDNS0 0x40 /* 01.... - EDNS(0) label */
+#define TYPE_LABEL 0x00 /* 00.... - regular label */
# define EDNS0_ELT_BITLABEL 0x01
#endif /* !_NAMESER_H_ */
i = GET_U_1(cp);
cp++;
while (i) {
- if ((i & INDIR_MASK) == INDIR_MASK)
+ switch (i & TYPE_MASK) {
+
+ case TYPE_INDIR:
return (cp + 1);
- if ((i & INDIR_MASK) == EDNS0_MASK) {
+
+ case TYPE_EDNS0: {
int bitlen, bytelen;
- if ((i & ~INDIR_MASK) != EDNS0_ELT_BITLABEL)
+ if ((i & ~TYPE_MASK) != EDNS0_ELT_BITLABEL)
return(NULL); /* unknown ELT */
if (!ND_TTEST_1(cp))
return (NULL);
cp++;
bytelen = (bitlen + 7) / 8;
cp += bytelen;
- } else
+ }
+ break;
+
+ case TYPE_RESERVED:
+ return (NULL);
+
+ case TYPE_LABEL:
cp += i;
+ break;
+ }
if (!ND_TTEST_1(cp))
return (NULL);
i = GET_U_1(cp);
if (!ND_TTEST_1(cp))
return(-1);
i = GET_U_1(cp);
- if ((i & INDIR_MASK) == EDNS0_MASK) {
+ switch (i & TYPE_MASK) {
+
+ case TYPE_EDNS0: {
u_int bitlen, elt;
- if ((elt = (i & ~INDIR_MASK)) != EDNS0_ELT_BITLABEL) {
+ if ((elt = (i & ~TYPE_MASK)) != EDNS0_ELT_BITLABEL) {
ND_PRINT("<ELT %d>", elt);
return(-1);
}
if ((bitlen = GET_U_1(cp + 1)) == 0)
bitlen = 256;
return(((bitlen + 7) / 8) + 1);
- } else
+ }
+
+ case TYPE_INDIR:
+ case TYPE_LABEL:
return(i);
+
+ default:
+ /*
+ * TYPE_RESERVED, but we use default to suppress compiler
+ * warnings about falling out of the switch statement.
+ */
+ ND_PRINT("<BAD LABEL TYPE>");
+ return(-1);
+ }
}
/* print a <domain-name> */
int compress = 0;
u_int elt;
u_int offset, max_offset;
+ u_int name_chars = 0;
if ((l = labellen(ndo, cp)) == (u_int)-1)
return(NULL);
max_offset = (u_int)(cp - bp);
i = GET_U_1(cp);
cp++;
- if ((i & INDIR_MASK) != INDIR_MASK) {
+ if ((i & TYPE_MASK) != TYPE_INDIR) {
compress = 0;
rp = cp + l;
}
- if (i != 0)
+ if (i != 0) {
while (i && cp < ndo->ndo_snapend) {
- if ((i & INDIR_MASK) == INDIR_MASK) {
+ switch (i & TYPE_MASK) {
+
+ case TYPE_INDIR:
if (!compress) {
rp = cp + 1;
compress = 1;
}
max_offset = offset;
cp = bp + offset;
- if ((l = labellen(ndo, cp)) == (u_int)-1)
- return(NULL);
if (!ND_TTEST_1(cp))
return(NULL);
i = GET_U_1(cp);
+ if ((l = labellen(ndo, cp)) == (u_int)-1)
+ return(NULL);
cp++;
continue;
- }
- if ((i & INDIR_MASK) == EDNS0_MASK) {
- elt = (i & ~INDIR_MASK);
+
+ case TYPE_EDNS0:
+ elt = (i & ~TYPE_MASK);
switch(elt) {
case EDNS0_ELT_BITLABEL:
if (blabel_print(ndo, cp) == NULL)
ND_PRINT("<ELT %u>", elt);
return(NULL);
}
- } else {
- if (nd_printn(ndo, cp, l, ndo->ndo_snapend))
- return(NULL);
+ break;
+
+ case TYPE_RESERVED:
+ ND_PRINT("<BAD LABEL TYPE>");
+ return(NULL);
+
+ case TYPE_LABEL:
+ if (name_chars + l <= MAXCDNAME) {
+ if (nd_printn(ndo, cp, l, ndo->ndo_snapend))
+ return(NULL);
+ } else if (name_chars < MAXCDNAME) {
+ if (nd_printn(ndo, cp,
+ MAXCDNAME - name_chars, ndo->ndo_snapend))
+ return(NULL);
+ }
+ name_chars += l;
+ break;
}
cp += l;
- ND_PRINT(".");
- if ((l = labellen(ndo, cp)) == (u_int)-1)
- return(NULL);
+ if (name_chars <= MAXCDNAME)
+ ND_PRINT(".");
+ name_chars++;
if (!ND_TTEST_1(cp))
return(NULL);
i = GET_U_1(cp);
+ if ((l = labellen(ndo, cp)) == (u_int)-1)
+ return(NULL);
cp++;
if (!compress)
rp += l + 1;
}
- else
+ if (name_chars > MAXCDNAME)
+ ND_PRINT("<DOMAIN NAME TOO LONG>");
+ } else
ND_PRINT(".");
return (rp);
}