📄 name.c
字号:
return (DNS_R_LABELTOOLONG); count++; CONVERTTOASCII(c); if (downcase) c = maptolower[(int)c]; *ndata++ = c; nrem--; nused++; state = ft_ordinary; break; } digits = 0; value = 0; state = ft_escdecimal; /* FALLTHROUGH */ case ft_escdecimal: if (!isdigit(c & 0xff)) return (DNS_R_BADESCAPE); value *= 10; value += digitvalue[(int)c]; digits++; if (digits == 3) { if (value > 255) return (DNS_R_BADESCAPE); if (count >= 63) return (DNS_R_LABELTOOLONG); count++; if (downcase) value = maptolower[value]; *ndata++ = value; nrem--; nused++; state = ft_ordinary; } break; default: FATAL_ERROR(__FILE__, __LINE__, "Unexpected state %d", state); /* Does not return. */ } } if (!done) { if (nrem == 0) return (ISC_R_NOSPACE); INSIST(tlen == 0); if (state != ft_ordinary && state != ft_at) return (ISC_R_UNEXPECTEDEND); if (state == ft_ordinary) { INSIST(count != 0); *label = count; labels++; INSIST(labels <= 127); offsets[labels] = nused; } if (origin != NULL) { if (nrem < origin->length) return (ISC_R_NOSPACE); label = origin->ndata; n1 = origin->length; nrem -= n1; while (n1 > 0) { n2 = *label++; INSIST(n2 <= 63); /* no bitstring support */ *ndata++ = n2; n1 -= n2 + 1; nused += n2 + 1; while (n2 > 0) { c = *label++; if (downcase) c = maptolower[(int)c]; *ndata++ = c; n2--; } labels++; if (n1 > 0) { INSIST(labels <= 127); offsets[labels] = nused; } } if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) name->attributes |= DNS_NAMEATTR_ABSOLUTE; } } else name->attributes |= DNS_NAMEATTR_ABSOLUTE; name->ndata = (unsigned char *)target->base + target->used; name->labels = labels; name->length = nused; isc_buffer_forward(source, tused); isc_buffer_add(target, name->length); return (ISC_R_SUCCESS);}isc_result_tdns_name_totext(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 labels; isc_boolean_t saw_root = ISC_FALSE; /* * This function assumes the name is in proper uncompressed * wire format. */ REQUIRE(VALID_NAME(name)); 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 (labels == 0 && nlen == 0) { /* * Special handling for an empty name. */ if (trem == 0) return (ISC_R_NOSPACE); /* * 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 { char buf[5]; if (trem < 4) return (ISC_R_NOSPACE); snprintf(buf, sizeof(buf), "\\%03u", c); memcpy(tdata, buf, 4); tdata += 4; trem -= 4; ndata++; nlen--; } } count--; } } 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 labels; /* * 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 { 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, 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 { 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; 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++; INSIST(count <= 63); offset += count; ndata += count; INSIST(offset <= length); if (count == 0) { absolute = ISC_TRUE; break; } } 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);}isc_result_tdns_name_fromwire(dns_name_t *name, isc_buffer_t *source, dns_decompress_t *dctx, unsigned int options, isc_buffer_t *target){ unsigned char *cdata, *ndata; unsigned int cused; /* Bytes of compressed name data used */ unsigned int hops, nused, labels, n, nmax; unsigned int current, new_current, biggest_pointer; isc_boolean_t done; fw_state state = fw_start; unsigned int c; unsigned char *offsets; dns_offsets_t odata; isc_boolean_t downcase; /* * Copy the possibly-compressed name at source into target, * decompressing it. */ REQUIRE(VALID_NAME(name)); REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || (target == NULL && ISC_BUFFER_VALID(name->buffer))); downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0); if (target == NULL && name->buffer != NULL) { target = name->buffer; isc_buffer_clear(target); } REQUIRE(dctx != NULL); REQUIRE(BINDABLE(name)); INIT_OFFSETS(name, offsets, odata); /* * Make 'name' empty in case of failure. */ MAKE_EMPTY(name); /* * Initialize things to make the compiler happy; they're not required. */ n = 0; new_current = 0; /* * Set up. */ labels = 0; hops = 0; done = ISC_FALSE; ndata = isc_buffer_used(target); nused = 0; /* * Find the maximum number of uncompressed target name * bytes we are willing to generate. This is the smaller * of the available target buffer length and the * maximum legal domain name length (255). */ nmax = isc_buffer_availablelength(target); if (nmax > DNS_NAME_MAXWIRE) nmax = DNS_NAME_MAXWIRE; cdata = isc_buffer_current(source); cused = 0; current = source->current; biggest_pointer = current; /* * Note: The following code is not optimized for speed, but * rather for correctness. Speed will be addressed in the future. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -