📄 name.c
字号:
count = 0; tbcount = 0; bitlength = 0; maxlength = 0; kind = ft_init; /* * Make 'name' empty in case of failure. */ MAKE_EMPTY(name); /* * Set up the state machine. */ tdata = (char *)source->base + source->current; tlen = isc_buffer_remaininglength(source); tused = 0; ndata = isc_buffer_used(target); nrem = isc_buffer_availablelength(target); if (nrem > 255) nrem = 255; nused = 0; labels = 0; done = ISC_FALSE; saw_bitstring = ISC_FALSE; state = ft_init; while (nrem > 0 && tlen > 0 && !done) { c = *tdata++; tlen--; tused++; no_read: switch (state) { case ft_init: /* * Is this the root name? */ if (c == '.') { if (tlen != 0) return (DNS_R_EMPTYLABEL); labels++; *ndata++ = 0; nrem--; nused++; done = ISC_TRUE; break; } if (c == '@' && tlen == 0) { state = ft_at; break; } /* FALLTHROUGH */ case ft_start: label = ndata; ndata++; nrem--; nused++; count = 0; if (c == '\\') { state = ft_initialescape; break; } kind = ft_ordinary; state = ft_ordinary; if (nrem == 0) return (ISC_R_NOSPACE); /* FALLTHROUGH */ case ft_ordinary: if (c == '.') { if (count == 0) return (DNS_R_EMPTYLABEL); *label = count; labels++; INSIST(labels <= 127); offsets[labels] = nused; if (tlen == 0) { labels++; *ndata++ = 0; nrem--; nused++; done = ISC_TRUE; } state = ft_start; } else if (c == '\\') { state = ft_escape; } else { if (count >= 63) return (DNS_R_LABELTOOLONG); count++; CONVERTTOASCII(c); if (downcase) c = maptolower[(int)c]; *ndata++ = c; nrem--; nused++; } break; case ft_initialescape: if (c == '[') { saw_bitstring = ISC_TRUE; kind = ft_bitstring; state = ft_bitstring; *label = DNS_LABELTYPE_BITSTRING; label = ndata; ndata++; nrem--; nused++; break; } kind = ft_ordinary; state = ft_escape; /* FALLTHROUGH */ case ft_escape: if (!isdigit(c & 0xff)) { if (count >= 63) 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; case ft_bitstring: /* count is zero */ tbcount = 0; value = 0; if (c == 'b') { vlen = 8; maxlength = 256; kind = ft_binary; state = ft_binary; } else if (c == 'o') { vlen = 8; maxlength = 256; kind = ft_octal; state = ft_octal; } else if (c == 'x') { vlen = 8; maxlength = 256; kind = ft_hex; state = ft_hex; } else if (isdigit(c & 0xff)) { vlen = 32; maxlength = 32; n1 = 0; n2 = 0; digits = 0; kind = ft_dottedquad; state = ft_dqdecimal; goto no_read; } else return (DNS_R_BADBITSTRING); break; case ft_binary: if (c != '0' && c != '1') { state = ft_maybeslash; goto no_read; } value <<= 1; if (c == '1') value |= 1; count++; tbcount++; if (tbcount > 256) return (DNS_R_BITSTRINGTOOLONG); if (count == 8) { *ndata++ = value; nrem--; nused++; count = 0; } break; case ft_octal: if (!isdigit(c & 0xff) || c == '9' || c == '8') { state = ft_maybeslash; goto no_read; } value <<= 3; value += digitvalue[(int)c]; count += 3; tbcount += 3; /* * The total bit count is tested against 258 instead * of 256 because of the possibility that the bitstring * label is exactly 256 bits long; on the last octal * digit (which must be 4) tbcount is incremented * from 255 to 258. This case is adequately handled * later. */ if (tbcount > 258) return (DNS_R_BITSTRINGTOOLONG); if (count == 8) { *ndata++ = value; nrem--; nused++; count = 0; } else if (count == 9) { *ndata++ = (value >> 1); nrem--; nused++; value &= 1; count = 1; } else if (count == 10) { *ndata++ = (value >> 2); nrem--; nused++; value &= 3; count = 2; } break; case ft_hex: if (!isxdigit(c & 0xff)) { state = ft_maybeslash; goto no_read; } value <<= 4; value += digitvalue[(int)c]; count += 4; tbcount += 4; if (tbcount > 256) return (DNS_R_BITSTRINGTOOLONG); if (count == 8) { *ndata++ = value; nrem--; nused++; count = 0; } break; case ft_dottedquad: if (c != '.' && n1 < 3) return (DNS_R_BADDOTTEDQUAD); dqchars[n1] = value; n2 *= 256; n2 += value; n1++; if (n1 == 4) { tbcount = 32; value = n2; state = ft_maybeslash; goto no_read; } value = 0; digits = 0; state = ft_dqdecimal; break; case ft_dqdecimal: if (!isdigit(c & 0xff)) { if (digits == 0 || value > 255) return (DNS_R_BADDOTTEDQUAD); state = ft_dottedquad; goto no_read; } digits++; if (digits > 3) return (DNS_R_BADDOTTEDQUAD); value *= 10; value += digitvalue[(int)c]; break; case ft_maybeslash: bitlength = 0; if (c == '/') { state = ft_bitlength; break; } /* FALLTHROUGH */ case ft_finishbitstring: if (c == ']') { if (tbcount == 0) return (DNS_R_BADBITSTRING); if (count > 0) { n1 = count % 8; if (n1 != 0) value <<= (8 - n1); } if (bitlength != 0) { if (bitlength > tbcount) return (DNS_R_BADBITSTRING); if (kind == ft_binary && bitlength != tbcount) { return (DNS_R_BADBITSTRING); } else if (kind == ft_octal) { /* * Figure out correct number * of octal digits for the * bitlength, and compare to * what was given. */ n1 = bitlength / 3; if (bitlength % 3 != 0) n1++; n2 = tbcount / 3; /* tbcount % 3 == 0 */ if (n1 != n2) return (DNS_R_BADBITSTRING); /* * Check that no bits extend * past the end of the last * byte that is included in * the bitlength. Example: * \[o036/8] == \[b00001111], * which fits into just one * byte, but the three octal * digits actually specified * two bytes worth of data, * 9 bits, before the bitlength * limited it back to one byte. * * n1 is the number of bytes * necessary for the bitlength. * n2 is the number of bytes * encompassed by the octal * digits. If they are not * equal, then "value" holds * the excess bits, which * must be zero. If the bits * are zero, then "count" is * zero'ed to prevent the * addition of another byte * below. */ n1 = (bitlength - 1) / 8; n2 = (tbcount - 1) / 8; if (n1 != n2) { if (value != 0) return (DNS_R_BADBITSTRING); else count = 0; } } else if (kind == ft_hex) { /* * Figure out correct number * of hex digits for the * bitlength, and compare to * what was given. */ n1 = bitlength / 4; if (bitlength % 4 != 0) n1++; n2 = tbcount / 4; /* tbcount % 4 == 0 */ if (n1 != n2) return (DNS_R_BADBITSTRING); } n1 = bitlength % vlen; if (n1 != 0) { /* * Are the pad bits in the * last 'vlen' bits zero? */ if ((value & ~((~0) << (vlen-n1))) != 0) return (DNS_R_BADBITSTRING); } } else if (kind == ft_dottedquad) bitlength = 32; else if (tbcount > 256) /* * This can happen when an octal * bitstring label of 86 octal digits * is specified; tbcount will be 258. * This is not trapped above because * the bitstring label might be limited * by a "/256" modifier. */ return (DNS_R_BADBITSTRING); else bitlength = tbcount; if (count > 0) { *ndata++ = value; nrem--; nused++; } if (kind == ft_dottedquad) { n1 = bitlength / 8; if (bitlength % 8 != 0) n1++; if (nrem < n1) return (ISC_R_NOSPACE); for (n2 = 0; n2 < n1; n2++) { *ndata++ = dqchars[n2]; nrem--; nused++; } } if (bitlength == 256) *label = 0; else *label = bitlength; labels++; INSIST(labels <= 127); offsets[labels] = nused; } else return (DNS_R_BADBITSTRING); state = ft_eatdot; break; case ft_bitlength: if (!isdigit(c & 0xff)) { if (bitlength == 0) return (DNS_R_BADBITSTRING); state = ft_finishbitstring; goto no_read; } bitlength *= 10; bitlength += digitvalue[(int)c]; if (bitlength > maxlength) return (DNS_R_BADBITSTRING); break; case ft_eatdot: if (c != '.') return (DNS_R_BADBITSTRING); if (tlen == 0) { labels++; *ndata++ = 0; nrem--; nused++; done = ISC_TRUE; } state = ft_start; 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_eatdot && 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++; if (n2 <= 63) { *ndata++ = n2; n1 -= n2 + 1; nused += n2 + 1; while (n2 > 0) { c = *label++; if (downcase) c = maptolower[(int)c]; *ndata++ = c; n2--; } } else { INSIST(n2 == DNS_LABELTYPE_BITSTRING); *ndata++ = n2; bitlength = *label++; *ndata++ = bitlength; if (bitlength == 0) bitlength = 256; n2 = bitlength / 8; if (bitlength % 8 != 0) n2++; n1 -= n2 + 2; nused += n2 + 2; while (n2 > 0) { *ndata++ = *label++; 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; if (saw_bitstring) compact(name, offsets); 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 bytes, nibbles; size_t i, len; unsigned int labels; isc_boolean_t saw_root = ISC_FALSE; char num[4]; /* * 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); /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -