📄 name.c
字号:
* The names of these booleans are misleading in this case. * This empty name is not necessarily from the root node of * the DNS root zone, nor is a final dot going to be included. * They need to be set this way, though, to keep the "@" * from being trounced. */ saw_root = ISC_TRUE; omit_final_dot = ISC_FALSE; *tdata++ = '@'; trem--; /* * Skip the while() loop. */ nlen = 0; } else if (nlen == 1 && labels == 1 && *ndata == '\0') { /* * Special handling for the root label. */ if (trem == 0) return (ISC_R_NOSPACE); saw_root = ISC_TRUE; omit_final_dot = ISC_FALSE; *tdata++ = '.'; trem--; /* * Skip the while() loop. */ nlen = 0; } while (labels > 0 && nlen > 0 && trem > 0) { labels--; count = *ndata++; nlen--; if (count == 0) { saw_root = ISC_TRUE; break; } if (count < 64) { INSIST(nlen >= count); while (count > 0) { c = *ndata; switch (c) { case 0x22: /* '"' */ case 0x28: /* '(' */ case 0x29: /* ')' */ case 0x2E: /* '.' */ case 0x3B: /* ';' */ case 0x5C: /* '\\' */ /* Special modifiers in zone files. */ case 0x40: /* '@' */ case 0x24: /* '$' */ if (trem < 2) return (ISC_R_NOSPACE); *tdata++ = '\\'; CONVERTFROMASCII(c); *tdata++ = c; ndata++; trem -= 2; nlen--; break; default: if (c > 0x20 && c < 0x7f) { if (trem == 0) return (ISC_R_NOSPACE); CONVERTFROMASCII(c); *tdata++ = c; ndata++; trem--; nlen--; } else { if (trem < 4) return (ISC_R_NOSPACE); sprintf(tdata, "\\%03u", c); tdata += 4; trem -= 4; ndata++; nlen--; } } count--; } } else if (count == DNS_LABELTYPE_BITSTRING) { if (trem < 3) return (ISC_R_NOSPACE); *tdata++ = '\\'; *tdata++ = '['; *tdata++ = 'x'; trem -= 3; INSIST(nlen > 0); count = *ndata++; if (count == 0) count = 256; nlen--; len = sprintf(num, "%u", count); /* XXX */ INSIST(len <= 4U); bytes = count / 8; if (count % 8 != 0) bytes++; INSIST(nlen >= bytes); nibbles = count / 4; if (count % 4 != 0) nibbles++; if (trem < nibbles) return (ISC_R_NOSPACE); trem -= nibbles; nlen -= bytes; while (nibbles > 0) { c = *ndata++; *tdata++ = hexdigits[(c >> 4)]; nibbles--; if (nibbles != 0) { *tdata++ = hexdigits[c & 0xf]; nibbles--; } } if (trem < 2 + len) return (ISC_R_NOSPACE); *tdata++ = '/'; for (i = 0; i < len; i++) *tdata++ = num[i]; *tdata++ = ']'; trem -= 2 + len; } else { FATAL_ERROR(__FILE__, __LINE__, "Unexpected label type %02x", count); /* NOTREACHED */ } /* * The following assumes names are absolute. If not, we * fix things up later. Note that this means that in some * cases one more byte of text buffer is required than is * needed in the final output. */ if (trem == 0) return (ISC_R_NOSPACE); *tdata++ = '.'; trem--; } if (nlen != 0 && trem == 0) return (ISC_R_NOSPACE); if (!saw_root || omit_final_dot) trem++; isc_buffer_add(target, tlen - trem); return (ISC_R_SUCCESS);}isc_result_tdns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot, isc_buffer_t *target){ unsigned char *ndata; char *tdata; unsigned int nlen, tlen; unsigned char c; unsigned int trem, count; unsigned int bytes, nibbles; size_t i, len; unsigned int labels; char num[4]; /* * This function assumes the name is in proper uncompressed * wire format. */ REQUIRE(VALID_NAME(name)); REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0); REQUIRE(ISC_BUFFER_VALID(target)); ndata = name->ndata; nlen = name->length; labels = name->labels; tdata = isc_buffer_used(target); tlen = isc_buffer_availablelength(target); trem = tlen; if (nlen == 1 && labels == 1 && *ndata == '\0') { /* * Special handling for the root label. */ if (trem == 0) return (ISC_R_NOSPACE); omit_final_dot = ISC_FALSE; *tdata++ = '.'; trem--; /* * Skip the while() loop. */ nlen = 0; } while (labels > 0 && nlen > 0 && trem > 0) { labels--; count = *ndata++; nlen--; if (count == 0) break; if (count < 64) { INSIST(nlen >= count); while (count > 0) { c = *ndata; if ((c >= 0x30 && c <= 0x39) || /* digit */ (c >= 0x41 && c <= 0x5A) || /* uppercase */ (c >= 0x61 && c <= 0x7A) || /* lowercase */ c == 0x2D || /* hyphen */ c == 0x5F) /* underscore */ { if (trem == 0) return (ISC_R_NOSPACE); /* downcase */ if (c >= 0x41 && c <= 0x5A) c += 0x20; CONVERTFROMASCII(c); *tdata++ = c; ndata++; trem--; nlen--; } else { if (trem < 3) return (ISC_R_NOSPACE); sprintf(tdata, "%%%02X", c); tdata += 3; trem -= 3; ndata++; nlen--; } count--; } } else if (count == DNS_LABELTYPE_BITSTRING) { if (trem < 3) return (ISC_R_NOSPACE); *tdata++ = '%'; *tdata++ = 'x'; trem -= 2; INSIST(nlen > 0); count = *ndata++; if (count == 0) count = 256; nlen--; len = sprintf(num, "%u", count); /* XXX */ INSIST(len <= 4U); bytes = count / 8; if (count % 8 != 0) bytes++; INSIST(nlen >= bytes); nibbles = count / 4; if (count % 4 != 0) nibbles++; if (trem < nibbles) return (ISC_R_NOSPACE); trem -= nibbles; nlen -= bytes; while (nibbles > 0) { c = *ndata++; *tdata++ = hexdigits[(c >> 4)]; nibbles--; if (nibbles != 0) { *tdata++ = hexdigits[c & 0xf]; i++; nibbles--; } } if (trem < 2 + len) return (ISC_R_NOSPACE); *tdata++ = '%'; for (i = 0; i < len; i++) *tdata++ = num[i]; *tdata++ = '%'; trem -= 2 + len; } else { FATAL_ERROR(__FILE__, __LINE__, "Unexpected label type %02x", count); /* NOTREACHED */ } /* * The following assumes names are absolute. If not, we * fix things up later. Note that this means that in some * cases one more byte of text buffer is required than is * needed in the final output. */ if (trem == 0) return (ISC_R_NOSPACE); *tdata++ = '.'; trem--; } if (nlen != 0 && trem == 0) return (ISC_R_NOSPACE); if (omit_final_dot) trem++; isc_buffer_add(target, tlen - trem); return (ISC_R_SUCCESS);}isc_result_tdns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target) { unsigned char *sndata, *ndata; unsigned int nlen, count, bytes, labels; isc_buffer_t buffer; /* * Downcase 'source'. */ REQUIRE(VALID_NAME(source)); REQUIRE(VALID_NAME(name)); if (source == name) { REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0); isc_buffer_init(&buffer, source->ndata, source->length); target = &buffer; ndata = source->ndata; } else { REQUIRE(BINDABLE(name)); REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || (target == NULL && ISC_BUFFER_VALID(name->buffer))); if (target == NULL) { target = name->buffer; isc_buffer_clear(name->buffer); } ndata = (unsigned char *)target->base + target->used; name->ndata = ndata; } sndata = source->ndata; nlen = source->length; labels = source->labels; if (nlen > (target->length - target->used)) { MAKE_EMPTY(name); return (ISC_R_NOSPACE); } while (labels > 0 && nlen > 0) { labels--; count = *sndata++; *ndata++ = count; nlen--; if (count < 64) { INSIST(nlen >= count); while (count > 0) { *ndata++ = maptolower[(*sndata++)]; nlen--; count--; } } else if (count == DNS_LABELTYPE_BITSTRING) { INSIST(nlen > 0); count = *sndata++; *ndata++ = count; if (count == 0) count = 256; nlen--; bytes = count / 8; if (count % 8 != 0) bytes++; INSIST(nlen >= bytes); nlen -= bytes; while (bytes > 0) { *ndata++ = *sndata++; bytes--; } } else { FATAL_ERROR(__FILE__, __LINE__, "Unexpected label type %02x", count); /* Does not return. */ } } if (source != name) { name->labels = source->labels; name->length = source->length; if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) name->attributes = DNS_NAMEATTR_ABSOLUTE; else name->attributes = 0; if (name->labels > 0 && name->offsets != NULL) set_offsets(name, name->offsets, NULL); } isc_buffer_add(target, name->length); return (ISC_R_SUCCESS);}static voidset_offsets(const dns_name_t *name, unsigned char *offsets, dns_name_t *set_name){ unsigned int offset, count, length, nlabels, n; unsigned char *ndata; isc_boolean_t absolute; ndata = name->ndata; length = name->length; offset = 0; nlabels = 0; absolute = ISC_FALSE; while (offset != length) { INSIST(nlabels < 128); offsets[nlabels++] = offset; count = *ndata++; offset++; if (count <= 63) { offset += count; ndata += count; INSIST(offset <= length); if (count == 0) { absolute = ISC_TRUE; break; } } else { INSIST(count == DNS_LABELTYPE_BITSTRING); n = *ndata++; offset++; if (n == 0) n = 256; count = n / 8; if (n % 8 != 0) count++; offset += count; ndata += count; INSIST(offset <= length); } } if (set_name != NULL) { INSIST(set_name == name); set_name->labels = nlabels; set_name->length = offset; if (absolute) set_name->attributes |= DNS_NAMEATTR_ABSOLUTE; else set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; } INSIST(nlabels == name->labels); INSIST(offset == name->length);}static voidcompact(dns_name_t *name, unsigned char *offsets) { unsigned char *head, *curr, *last; unsigned int count, n, bit; unsigned int headbits, currbits, tailbits, newbits; unsigned int headrem, newrem; unsigned int headindex, currindex, tailindex, newindex; unsigned char tail[32]; /* * The caller MUST ensure that all bitstrings are correctly formatted * and that the offsets table is valid. */ again: memset(tail, 0, sizeof tail); INSIST(name->labels != 0); n = name->labels - 1; while (n > 0) { head = &name->ndata[offsets[n]]; if (head[0] == DNS_LABELTYPE_BITSTRING && head[1] != 0) { if (n != 0) { n--; curr = &name->ndata[offsets[n]]; if (curr[0] != DNS_LABELTYPE_BITSTRING) continue; /* * We have consecutive bitstrings labels, and * the more significant label ('head') has * space. */ currbits = curr[1]; if (currbits == 0) currbits = 256; currindex = 0; headbits = head[1]; if (headbits == 0) headbits = 256; headindex = headbits; count = 256 - headbits; if (count > currbits) count = currbits; headrem = headbits % 8; if (headrem != 0) headrem = 8 - headrem; if (headrem != 0) { if (headrem > count) headrem = count; do { bit = get_bit(&curr[2], currindex); set_bit(&head[2], headindex, bit); currindex++; headindex++; headbits++; count--; headrem--; } while (headrem != 0); } tailindex = 0; tailbits = 0; while (count > 0) { bit = get_bit(&curr[2], currindex); set_bit(tail, tailindex, bit); currindex++; tailindex++; tailbits++; count--; } newbits = 0; newindex = 0; if (currindex < currbits) { while (currindex < currbits) { bit = get_bit(&curr[2], currindex); set_bit(&curr[2], newindex, bit); currindex++; newindex++; newbits++; } INSIST(newbits < 256); curr[1] = newbits; count = newbits / 8; newrem = newbits % 8; /* Zero remaining pad bits, if any. */ if (newrem != 0) { count++; newrem = 8 - newrem; while (newrem > 0) { set_bit(&curr[2], newindex, 0); newrem--; newindex++; } } curr += count + 2; } else { /* We got rid of curr. */ name->labels--; } /* copy head, then tail, then rest to curr. */ count = headbits + tailbits; INSIST(count <= 256); curr[0] = DNS_LABELTYPE_BITSTRING; if (count == 256) curr[1] = 0; else curr[1] = count; curr += 2; head += 2; count = headbits / 8; if (headbits % 8 != 0) count++; while (count > 0) { *curr++ = *head++; count--;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -