name.c revision c1bb41fa730c1ace908dadb7f808b279a0ae58ab
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson/*
a90aca78aa7847ba65d27def47f69339987869c8Automatic Updater * Copyright (C) 1998, 1999 Internet Software Consortium.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Permission to use, copy, modify, and distribute this software for any
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * purpose with or without fee is hereby granted, provided that the above
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson * copyright notice and this permission notice appear in all copies.
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * SOFTWARE.
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson */
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉#include <config.h>
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include <ctype.h>
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence#include <stdio.h>
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson#include <stdlib.h>
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson#include <string.h>
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
a5c077e40c784cf9e25c95a1ab94db2faab04ae9Brian Wellington#include <isc/assertions.h>
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson#include <isc/error.h>
cc0a5f714231709409b9e1b85f0f97ae50854451Mark Andrews
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉#include <dns/types.h>
6028d1ce0380d0ba7f6c6ecd1ad20b31ddd1becbDavid Lawrence#include <dns/result.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <dns/name.h>
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson#include <dns/compress.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉#define NAME_MAGIC 0x444E536EU /* DNSn. */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington#define VALID_NAME(n) ((n) != NULL && \
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson (n)->magic == NAME_MAGIC)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉typedef enum {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington ft_init = 0,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 ft_start,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 ft_ordinary,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 ft_initialescape,
5afa531442369eed0e93a8af14422b30f400bd89Mark Andrews ft_escape,
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews ft_escdecimal,
476386968b1f287a695f73c48862e961011af99bMark Andrews ft_bitstring,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson ft_binary,
9259fed3d8ac5d1efa9b5a647969e40c9c934484Andreas Gustafsson ft_octal,
3aca8e5bf3740bbcc3bb13dde242d7cc369abb27Mark Andrews ft_hex,
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington ft_dottedquad,
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson ft_dqdecimal,
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson ft_maybeslash,
62700b67eb8abb7d13f9c3c1bc4b60a1477d35d8Mark Andrews ft_finishbitstring,
9259fed3d8ac5d1efa9b5a647969e40c9c934484Andreas Gustafsson ft_bitlength,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson ft_eatdot,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt ft_at
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt} ft_state;
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunttypedef enum {
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt fw_start = 0,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt fw_ordinary,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt fw_copy,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt fw_bitstring,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt fw_newcurrent,
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson fw_local
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson} fw_state;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafssonstatic char digitvalue[256] = {
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson};
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafssonstatic char hexdigits[16] = {
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt '0', '1', '2', '3', '4', '5', '6', '7',
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington};
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Huntstatic unsigned char maptolower[] = {
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater};
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt#define CONVERTTOASCII(c)
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt#define CONVERTFROMASCII(c)
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt#define INIT_OFFSETS(name, var, default) \
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt if (name->offsets != NULL) \
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt var = name->offsets; \
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt else \
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt var = default;
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt#define SETUP_OFFSETS(name, var, default) \
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt if (name->offsets != NULL) \
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt var = name->offsets; \
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt else { \
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt var = default; \
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt set_offsets(name, var, ISC_FALSE, ISC_FALSE, ISC_FALSE); \
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Huntstatic struct dns_name root = {
cfd262045c23cadb8415f0111f56995258f17361Evan Hunt NAME_MAGIC,
cfd262045c23cadb8415f0111f56995258f17361Evan Hunt (unsigned char *)"", 1, 1, DNS_NAMEATTR_ABSOLUTE, NULL,
cfd262045c23cadb8415f0111f56995258f17361Evan Hunt {(void *)-1, (void *)-1},
cfd262045c23cadb8415f0111f56995258f17361Evan Hunt {NULL, NULL}
cfd262045c23cadb8415f0111f56995258f17361Evan Hunt};
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrewsdns_name_t *dns_rootname = &root;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellingtonstatic void set_offsets(dns_name_t *name, unsigned char *offsets,
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington isc_boolean_t set_labels, isc_boolean_t set_length,
3eef7eaba00e9bd468d8036c709a296a0e5b76f1Andreas Gustafsson isc_boolean_t set_absolute);
7b68fa6229f1edadac44c7ec459c9ed77a8368c8Mark Andrewsstatic void compact(dns_name_t *name, unsigned char *offsets);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington/*
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * Yes, get_bit and set_bit are lame. We define them here so they can
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * be inlined by smart compilers.
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson */
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafssonstatic unsigned int
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellingtonget_bit(unsigned char *array, unsigned int index) {
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt unsigned int byte, shift;
ad5bc22a819190839bdcc4d102d023782dc23660Mark Andrews
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt byte = array[index / 8];
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington shift = 7 - (index % 8);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt return ((byte >> shift) & 0x01);
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt}
11156f82bab19b2e7f5d4df6184ae0c99518442fAutomatic Updater
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Huntstatic void
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Huntset_bit(unsigned char *array, unsigned int index, unsigned int bit) {
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt unsigned int byte, shift, mask;
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington byte = array[index / 8];
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson shift = 7 - (index % 8);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson mask = 1 << shift;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (bit)
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson array[index / 8] |= mask;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington else
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt array[index / 8] &= (~mask & 0xFF);
77b8f88f144928eddcca144c348d6ef53e7d5c43Evan Hunt}
77b8f88f144928eddcca144c348d6ef53e7d5c43Evan Hunt
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrewsdns_labeltype_t
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrewsdns_label_type(dns_label_t *label) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /*
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * Get the type of 'label'.
3e12c54de2238dc90bae06a2e083e4976120bad5Automatic Updater */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(label != NULL);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(label->length > 0);
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt REQUIRE(label->base[0] <= 63 ||
08f860f800d32007a0c9bf456f6c35fbb2ecbc81Evan Hunt label->base[0] == DNS_LABELTYPE_BITSTRING);
a687a0592bbe3a582860eb5f03725bf80d7ac1d8Mark Andrews
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (label->base[0] <= 63)
a687a0592bbe3a582860eb5f03725bf80d7ac1d8Mark Andrews return (dns_labeltype_ordinary);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington else
3e12c54de2238dc90bae06a2e083e4976120bad5Automatic Updater return (dns_labeltype_bitstring);
3e12c54de2238dc90bae06a2e083e4976120bad5Automatic Updater}
3e12c54de2238dc90bae06a2e083e4976120bad5Automatic Updater
3e12c54de2238dc90bae06a2e083e4976120bad5Automatic Updaterunsigned int
3e12c54de2238dc90bae06a2e083e4976120bad5Automatic Updaterdns_label_countbits(dns_label_t *label) {
08f860f800d32007a0c9bf456f6c35fbb2ecbc81Evan Hunt unsigned int count;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /*
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * The number of bits in a bitstring label.
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(label != NULL);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(label->length > 2);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(label->base[0] == DNS_LABELTYPE_BITSTRING);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews count = label->base[1];
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews if (count == 0)
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews count = 256;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews return (count);
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews}
0015ab097438e041197b19b9de2ba48f6bfd1c6cDavid Lawrence
351b62535d4c4f89883bfdba025999dd32490266Evan Huntdns_bitlabel_t
0015ab097438e041197b19b9de2ba48f6bfd1c6cDavid Lawrencedns_label_getbit(dns_label_t *label, unsigned int n) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington unsigned int count, bit;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /*
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * The 'n'th most significant bit of 'label'.
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington *
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * Notes:
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * Numbering starts at 0.
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(label != NULL);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(label->length > 2);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(label->base[0] == DNS_LABELTYPE_BITSTRING);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington count = label->base[1];
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (count == 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington count = 256;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(n < count);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington bit = get_bit(&label->base[2], n);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (bit == 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (dns_bitlabel_0);
6e373c502584f9292e964378411d296c8259026bMark Andrews return (dns_bitlabel_1);
6e373c502584f9292e964378411d296c8259026bMark Andrews}
6e373c502584f9292e964378411d296c8259026bMark Andrews
6e373c502584f9292e964378411d296c8259026bMark Andrewsvoid
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsdns_name_init(dns_name_t *name, unsigned char *offsets) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews /*
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Make 'name' empty.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews name->magic = NAME_MAGIC;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews name->ndata = NULL;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews name->length = 0;
92f60809e854ccf5f115883c6347e370da048848Mark Andrews name->labels = 0;
92f60809e854ccf5f115883c6347e370da048848Mark Andrews name->attributes = 0;
92f60809e854ccf5f115883c6347e370da048848Mark Andrews name->offsets = offsets;
92f60809e854ccf5f115883c6347e370da048848Mark Andrews ISC_LINK_INIT(name, link);
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt ISC_LIST_INIT(name->list);
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt}
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt
351b62535d4c4f89883bfdba025999dd32490266Evan Huntvoid
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellingtondns_name_invalidate(dns_name_t *name) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /*
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * Make 'name' invalid.
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(VALID_NAME(name));
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 name->magic = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington name->ndata = NULL;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington name->length = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington name->labels = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington name->attributes = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington name->offsets = NULL;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington ISC_LINK_INIT(name, link);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington}
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt
351b62535d4c4f89883bfdba025999dd32490266Evan Huntisc_boolean_t
351b62535d4c4f89883bfdba025999dd32490266Evan Huntdns_name_isabsolute(dns_name_t *name) {
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt /*
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt * Does 'name' end in the root label?
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt */
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt REQUIRE(VALID_NAME(name));
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt REQUIRE(name->labels > 0);
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt return (ISC_TRUE);
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt return (ISC_FALSE);
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt}
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉
351b62535d4c4f89883bfdba025999dd32490266Evan Huntunsigned int
351b62535d4c4f89883bfdba025999dd32490266Evan Huntdns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt unsigned int length;
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt const unsigned char *s;
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt unsigned int h = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington unsigned int g;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington unsigned char c;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /*
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * Provide a hash value for 'name'.
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington REQUIRE(VALID_NAME(name));
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (name->labels == 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (0);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington length = name->length;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (length > 16)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington length = 16;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /*
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * P. J. Weinberger's hash function, adapted from p. 436 of
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * _Compilers: Principles, Techniques, and Tools_, Aho, Sethi
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * and Ullman, Addison-Wesley, 1986, ISBN 0-201-10088-6.
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington s = name->ndata;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (case_sensitive) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington while (length > 0) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington h = ( h << 4 ) + *s;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if ((g = ( h & 0xf0000000 )) != 0) {
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews h = h ^ (g >> 24);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington h = h ^ g;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington s++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington length--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington } else {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington while (length > 0) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington c = maptolower[*s];
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington h = ( h << 4 ) + c;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if ((g = ( h & 0xf0000000 )) != 0) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington h = h ^ (g >> 24);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington h = h ^ g;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington s++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington length--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (h);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington}
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellingtonint
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellingtondns_name_compare(dns_name_t *name1, dns_name_t *name2) {
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt unsigned int l1, l2, l, count1, count2, count;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington unsigned int b1, b2, n;
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt unsigned char c1, c2;
08f860f800d32007a0c9bf456f6c35fbb2ecbc81Evan Hunt int cdiff, ldiff;
08f860f800d32007a0c9bf456f6c35fbb2ecbc81Evan Hunt unsigned char *label1, *label2;
08f860f800d32007a0c9bf456f6c35fbb2ecbc81Evan Hunt unsigned char *offsets1, *offsets2;
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt dns_offsets_t odata1, odata2;
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt /*
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt * Determine the relative ordering under the DNSSEC order relation of
08f860f800d32007a0c9bf456f6c35fbb2ecbc81Evan Hunt * 'name1' and 'name2'.
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt */
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt REQUIRE(VALID_NAME(name1));
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt REQUIRE(name1->labels > 0);
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt REQUIRE(VALID_NAME(name2));
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt REQUIRE(name2->labels > 0);
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt SETUP_OFFSETS(name1, offsets1, odata1);
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt SETUP_OFFSETS(name2, offsets2, odata2);
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt
08f860f800d32007a0c9bf456f6c35fbb2ecbc81Evan Hunt l1 = name1->labels;
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt l2 = name2->labels;
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt if (l1 < l2) {
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt l = l1;
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt ldiff = -1;
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt } else {
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt l = l2;
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson if (l1 > l2)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington ldiff = 1;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington else
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington ldiff = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington while (l > 0) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington l--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington l1--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington l2--;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 label1 = &name1->ndata[offsets1[l1]];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 label2 = &name2->ndata[offsets2[l2]];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count1 = *label1++;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count2 = *label2++;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 <= 63 && count2 <= 63) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 < count2) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 cdiff = -1;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count = count1;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 } else {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count = count2;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 > count2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 cdiff = 1;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 else
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 cdiff = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 while (count > 0) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count--;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 c1 = maptolower[*label1++];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 c2 = maptolower[*label2++];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (c1 < c2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (-1);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 else if (c1 > c2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (1);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (cdiff != 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (cdiff);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 } else if (count1 == DNS_LABELTYPE_BITSTRING && count2 <= 63) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count2 == 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (1);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (-1);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 } else if (count2 == DNS_LABELTYPE_BITSTRING && count1 <= 63) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 == 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (-1);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (1);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 } else {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 INSIST(count1 == DNS_LABELTYPE_BITSTRING &&
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count2 == DNS_LABELTYPE_BITSTRING);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count1 = *label1++;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 == 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count1 = 256;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count2 = *label2++;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count2 == 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count2 = 256;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 < count2) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 cdiff = -1;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count = count1;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 } else {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count = count2;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 > count2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 cdiff = 1;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 else
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 cdiff = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /* Yes, this loop is really slow! */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 for (n = 0; n < count; n++) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 b1 = get_bit(label1, n);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 b2 = get_bit(label2, n);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (b1 < b2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (-1);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 else if (b1 > b2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (1);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (cdiff != 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (cdiff);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (ldiff);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉}
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉isc_boolean_t
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉dns_name_issubdomain(dns_name_t *name1, dns_name_t *name2) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned int l1, l2, count1, count2;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned int b1, b2, n;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned char c1, c2;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned char *label1, *label2;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned char *offsets1, *offsets2;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 dns_offsets_t odata1, odata2;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /*
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Is 'name1' a subdomain of 'name2'?
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 *
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Note: It makes no sense for one of the names to be relative and the
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * other absolute. If both names are relative, then to be meaningfully
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * compared the caller must ensure that they are both relative to the
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * same domain.
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(VALID_NAME(name1));
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(name1->labels > 0);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(VALID_NAME(name2));
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(name2->labels > 0);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 SETUP_OFFSETS(name1, offsets1, odata1);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 SETUP_OFFSETS(name2, offsets2, odata2);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /*
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Either name1 is absolute and name2 is absolute, or neither is.
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(((name1->ndata[offsets1[name1->labels - 1]] == 0 ? 1 : 0) ^
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 (name2->ndata[offsets2[name2->labels - 1]] == 0 ? 1 : 0))
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 == 0);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 l1 = name1->labels;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 l2 = name2->labels;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (l1 < l2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (ISC_FALSE);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 while (l2 > 0) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 l1--;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 l2--;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 label1 = &name1->ndata[offsets1[l1]];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 label2 = &name2->ndata[offsets2[l2]];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count1 = *label1++;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count2 = *label2++;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 <= 63 && count2 <= 63) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 != count2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (ISC_FALSE);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 while (count2 > 0) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count2--;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 c1 = maptolower[*label1++];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 c2 = maptolower[*label2++];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (c1 != c2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (ISC_FALSE);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 } else {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 != count2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (ISC_FALSE);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 INSIST(count1 == DNS_LABELTYPE_BITSTRING &&
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count2 == DNS_LABELTYPE_BITSTRING);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count1 = *label1++;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 == 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count1 = 256;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count2 = *label2++;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count2 == 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count2 = 256;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 < count2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (ISC_FALSE);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /* Yes, this loop is really slow! */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 for (n = 0; n < count2; n++) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 b1 = get_bit(label1, n);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 b2 = get_bit(label2, n);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (b1 != b2)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (ISC_FALSE);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (count1 != count2 && l2 != 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (ISC_FALSE);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (ISC_TRUE);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉}
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉unsigned int
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉dns_name_countlabels(dns_name_t *name) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /*
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * How many labels does 'name' have?
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(VALID_NAME(name));
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 ENSURE(name->labels <= 128);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 return (name->labels);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉}
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉void
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉dns_name_getlabel(dns_name_t *name, unsigned int n, dns_label_t *label) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned char *offsets;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 dns_offsets_t odata;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /*
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Make 'label' refer to the 'n'th least significant label of 'name'.
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(VALID_NAME(name));
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(name->labels > 0);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(n < name->labels);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(label != NULL);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 SETUP_OFFSETS(name, offsets, odata);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 label->base = &name->ndata[offsets[n]];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (n == name->labels - 1)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 label->length = name->length - offsets[n];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 else
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 label->length = offsets[n + 1] - offsets[n];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉}
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉void
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉dns_name_getlabelsequence(dns_name_t *source,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned int first, unsigned int n,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 dns_name_t *target)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉{
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned char *offsets;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 dns_offsets_t odata;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /*
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Make 'target' refer to the 'n' labels including and following
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * 'first' in 'source'.
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(VALID_NAME(source));
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(source->labels > 0);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(n > 0);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(first < source->labels);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(first + n <= source->labels);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE((target->attributes & DNS_NAMEATTR_READONLY) == 0);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 SETUP_OFFSETS(source, offsets, odata);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 target->ndata = &source->ndata[offsets[first]];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (first + n == source->labels) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 target->length = source->length - offsets[first];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 target->attributes |= DNS_NAMEATTR_ABSOLUTE;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 else
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 } else {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 target->length = offsets[first + n] - offsets[first];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 }
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 target->labels = n;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (target->offsets != NULL)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 set_offsets(target, target->offsets, ISC_FALSE, ISC_FALSE,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 ISC_FALSE);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉}
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉void
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉dns_name_fromregion(dns_name_t *name, isc_region_t *r) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned char *offsets;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 dns_offsets_t odata;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /*
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Make 'name' refer to region 'r'.
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(VALID_NAME(name));
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(r != NULL);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(r->length <= 255);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 INIT_OFFSETS(name, offsets, odata);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 name->ndata = r->base;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 name->length = r->length;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (r->length > 0)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 set_offsets(name, offsets, ISC_TRUE, ISC_TRUE, ISC_TRUE);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 else
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 name->labels = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉}
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉void
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉dns_name_toregion(dns_name_t *name, isc_region_t *r) {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /*
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Make 'r' refer to 'name'.
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(VALID_NAME(name));
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(r != NULL);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 r->base = name->ndata;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 r->length = name->length;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉}
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉dns_result_t
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 dns_name_t *origin, isc_boolean_t downcase,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 isc_buffer_t *target)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉{
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned char *ndata, *label;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 char *tdata;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 char c;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 ft_state state, kind;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned int value, count, tbcount, bitlength, maxlength;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned int n1, n2, vlen, tlen, nrem, nused, digits, labels, tused;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 isc_boolean_t done, saw_bitstring;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned char dqchars[4];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 unsigned char *offsets;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 dns_offsets_t odata;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /*
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Convert the textual representation of a DNS name at source
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * into uncompressed wire form stored in target.
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 *
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Notes:
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Relative domain names will have 'origin' appended to them
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * unless 'origin' is NULL, in which case relative domain names
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * will remain relative.
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(VALID_NAME(name));
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(isc_buffer_type(source) == ISC_BUFFERTYPE_TEXT);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 INIT_OFFSETS(name, offsets, odata);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 offsets[0] = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /*
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * Initialize things to make the compiler happy; they're not required.
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 */
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 n1 = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 n2 = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 vlen = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 label = NULL;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 digits = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 value = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 count = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 tbcount = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 bitlength = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 maxlength = 0;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 kind = ft_init;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /*
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * Invalidate 'name'.
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington */
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews name->magic = 0;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews name->ndata = NULL;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington name->length = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington name->labels = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington name->attributes = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /*
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson * Set up the state machine.
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein tdata = (char *)source->base + source->current;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson tlen = source->used - source->current;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson tused = 0;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson ndata = (unsigned char *)target->base + target->used;
d5e72d5dba7b77ae0036c53578bcabcf3af1f4b7Andreas Gustafsson nrem = target->length - target->used;
d5e72d5dba7b77ae0036c53578bcabcf3af1f4b7Andreas Gustafsson if (nrem > 255)
d5e72d5dba7b77ae0036c53578bcabcf3af1f4b7Andreas Gustafsson nrem = 255;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson nused = 0;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater labels = 0;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson done = ISC_FALSE;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson saw_bitstring = ISC_FALSE;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson state = ft_init;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson while (nrem > 0 && tlen > 0 && !done) {
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson c = *tdata++;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson tlen--;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson tused++;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson no_read:
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson switch (state) {
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson case ft_init:
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson /*
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson * Is this the root name?
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson */
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson if (c == '.') {
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson if (tlen != 0)
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson return (DNS_R_EMPTYLABEL);
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson labels++;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson *ndata++ = 0;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson nrem--;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson nused++;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson done = ISC_TRUE;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson break;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson }
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein if (c == '@' && tlen == 0) {
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson state = ft_at;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson break;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson }
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson /* FALLTHROUGH */
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson case ft_start:
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson label = ndata;
d5e72d5dba7b77ae0036c53578bcabcf3af1f4b7Andreas Gustafsson ndata++;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson nrem--;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson nused++;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson count = 0;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (c == '\\') {
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews state = ft_initialescape;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews break;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews kind = ft_ordinary;
1cf54d1966b3de8f6593e9e80eae9a80a1c011adMark Andrews state = ft_ordinary;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /* FALLTHROUGH */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews case ft_ordinary:
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (c == '.') {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (count == 0)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (DNS_R_EMPTYLABEL);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews *label = count;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews labels++;
1cf54d1966b3de8f6593e9e80eae9a80a1c011adMark Andrews INSIST(labels <= 127);
1cf54d1966b3de8f6593e9e80eae9a80a1c011adMark Andrews offsets[labels] = nused;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (tlen == 0) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews labels++;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff *ndata++ = 0;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews nrem--;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews nused++;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews done = ISC_TRUE;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson }
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson state = ft_start;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews } else if (c == '\\') {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington state = ft_escape;
de9833be77ef92c17b35c02d138a0ad8df34dd91Mark Andrews } else {
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews if (count >= 63)
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews return (DNS_R_LABELTOOLONG);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews count++;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews CONVERTTOASCII(c);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson if (downcase)
0015ab097438e041197b19b9de2ba48f6bfd1c6cDavid Lawrence c = maptolower[(int)c];
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington *ndata++ = c;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nrem--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nused++;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson }
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson break;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson case ft_initialescape:
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson if (c == '[') {
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson saw_bitstring = ISC_TRUE;
8dd4cf7fc6c025c547a473de5df7a72939d0cb2aDavid Lawrence kind = ft_bitstring;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington state = ft_bitstring;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington *label = DNS_LABELTYPE_BITSTRING;
cc0a5f714231709409b9e1b85f0f97ae50854451Mark Andrews label = ndata;
87f4715d6c0a22f3449eb3291c91aa45ba86c955Mark Andrews ndata++;
476386968b1f287a695f73c48862e961011af99bMark Andrews nrem--;
476386968b1f287a695f73c48862e961011af99bMark Andrews nused++;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews break;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews }
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews kind = ft_ordinary;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews state = ft_escape;
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉 /* FALLTHROUGH */
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews case ft_escape:
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews if (!isdigit(c)) {
b4dfb4747498ab22831a30c44607e81082fef962Michael Graff if (count >= 63)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (DNS_R_LABELTOOLONG);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington count++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington CONVERTTOASCII(c);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (downcase)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington c = maptolower[(int)c];
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington *ndata++ = c;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nrem--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nused++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington state = ft_ordinary;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington break;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington digits = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington value = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington state = ft_escdecimal;
de9833be77ef92c17b35c02d138a0ad8df34dd91Mark Andrews /* FALLTHROUGH */
de9833be77ef92c17b35c02d138a0ad8df34dd91Mark Andrews case ft_escdecimal:
de9833be77ef92c17b35c02d138a0ad8df34dd91Mark Andrews if (!isdigit(c))
de9833be77ef92c17b35c02d138a0ad8df34dd91Mark Andrews return (DNS_R_BADESCAPE);
de9833be77ef92c17b35c02d138a0ad8df34dd91Mark Andrews value *= 10;
de9833be77ef92c17b35c02d138a0ad8df34dd91Mark Andrews value += digitvalue[(int)c];
de9833be77ef92c17b35c02d138a0ad8df34dd91Mark Andrews digits++;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson if (digits == 3) {
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson if (value > 255)
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson return (DNS_R_BADESCAPE);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson if (count >= 63)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (DNS_R_LABELTOOLONG);
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson count++;
de9833be77ef92c17b35c02d138a0ad8df34dd91Mark Andrews if (downcase)
de9833be77ef92c17b35c02d138a0ad8df34dd91Mark Andrews value = maptolower[value];
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington *ndata++ = value;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson nrem--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nused++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington state = ft_ordinary;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington break;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington case ft_bitstring:
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /* count is zero */
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews tbcount = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington value = 0;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson if (c == 'b') {
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews vlen = 8;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews maxlength = 256;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews kind = ft_binary;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews state = ft_binary;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews } else if (c == 'o') {
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews vlen = 8;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews maxlength = 256;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews kind = ft_octal;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews state = ft_octal;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews } else if (c == 'x') {
8249eee42adc8c9c06c6ff9aaecc7437e259c687Mark Andrews vlen = 8;
8249eee42adc8c9c06c6ff9aaecc7437e259c687Mark Andrews maxlength = 256;
8249eee42adc8c9c06c6ff9aaecc7437e259c687Mark Andrews kind = ft_hex;
8249eee42adc8c9c06c6ff9aaecc7437e259c687Mark Andrews state = ft_hex;
8249eee42adc8c9c06c6ff9aaecc7437e259c687Mark Andrews } else if (isdigit(c)) {
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews vlen = 32;
886b96ebfd555cfeaf37ae46fc08421a41c61392Andreas Gustafsson maxlength = 32;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews n1 = 0;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews n2 = 0;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews digits = 0;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews kind = ft_dottedquad;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson state = ft_dqdecimal;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington goto no_read;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington } else
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (DNS_R_BADBITSTRING);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington break;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews case ft_binary:
86dcc4005887f91d23d970d4574a8f6afa7e28d2Evan Hunt if (c != '0' && c != '1') {
86dcc4005887f91d23d970d4574a8f6afa7e28d2Evan Hunt state = ft_maybeslash;
86dcc4005887f91d23d970d4574a8f6afa7e28d2Evan Hunt goto no_read;
86dcc4005887f91d23d970d4574a8f6afa7e28d2Evan Hunt }
c75523bcb30c2b8426ee7cb226d9b429c337325bMark Andrews value <<= 1;
c75523bcb30c2b8426ee7cb226d9b429c337325bMark Andrews if (c == '1')
c75523bcb30c2b8426ee7cb226d9b429c337325bMark Andrews value |= 1;
c75523bcb30c2b8426ee7cb226d9b429c337325bMark Andrews count++;
c75523bcb30c2b8426ee7cb226d9b429c337325bMark Andrews tbcount++;
c75523bcb30c2b8426ee7cb226d9b429c337325bMark Andrews if (tbcount > 256)
c75523bcb30c2b8426ee7cb226d9b429c337325bMark Andrews return (DNS_R_BITSTRINGTOOLONG);
86dcc4005887f91d23d970d4574a8f6afa7e28d2Evan Hunt if (count == 8) {
86dcc4005887f91d23d970d4574a8f6afa7e28d2Evan Hunt *ndata++ = value;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews nrem--;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews nused++;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews count = 0;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews break;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews case ft_octal:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (!isdigit(c) || c == '9') {
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews state = ft_maybeslash;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews goto no_read;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews value <<= 3;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews value += digitvalue[(int)c];
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews count += 3;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews tbcount += 3;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson if (tbcount > 256)
207f0a15bb486d8dc27cf5ff963fac6068ee2972Mark Andrews return (DNS_R_BITSTRINGTOOLONG);
207f0a15bb486d8dc27cf5ff963fac6068ee2972Mark Andrews if (count == 8) {
207f0a15bb486d8dc27cf5ff963fac6068ee2972Mark Andrews *ndata++ = value;
207f0a15bb486d8dc27cf5ff963fac6068ee2972Mark Andrews nrem--;
207f0a15bb486d8dc27cf5ff963fac6068ee2972Mark Andrews nused++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington count = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington } else if (count == 9) {
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt *ndata++ = (value >> 1);
8249eee42adc8c9c06c6ff9aaecc7437e259c687Mark Andrews nrem--;
8249eee42adc8c9c06c6ff9aaecc7437e259c687Mark Andrews nused++;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson value &= 1;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson count = 1;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson } else if (count == 10) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington *ndata++ = (value >> 2);
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt nrem--;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson nused++;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson value &= 3;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson count = 2;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington break;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington case ft_hex:
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (!isxdigit(c)) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington state = ft_maybeslash;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington goto no_read;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington value <<= 4;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington value += digitvalue[(int)c];
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews count += 4;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington tbcount += 4;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (tbcount > 256)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (DNS_R_BITSTRINGTOOLONG);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (count == 8) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington *ndata++ = value;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nrem--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nused++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington count = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington break;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington case ft_dottedquad:
dcd12febbd47f5846d6c75f6a4dcba8a873bc153Andreas Gustafsson if (c != '.' && n1 < 3)
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson return (DNS_R_BADDOTTEDQUAD);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington dqchars[n1] = value;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n2 *= 256;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n2 += value;
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews n1++;
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews if (n1 == 4) {
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews tbcount = 32;
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉 value = n2;
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉 state = ft_maybeslash;
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews goto no_read;
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews }
8907d8fa04fdaa65baf0bc6b01230b2ebde93106Mark Andrews value = 0;
d9059b0c38bd630c367d81424d72b1308cd74b04Tatuya JINMEI 神明達哉 digits = 0;
a3a11c4f3fc9ba972802b811c4d95a9884d6ff4aMichael Sawyer state = ft_dqdecimal;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson break;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson case ft_dqdecimal:
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson if (!isdigit(c)) {
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson if (digits == 0 || value > 255)
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson return (DNS_R_BADDOTTEDQUAD);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 state = ft_dottedquad;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington goto no_read;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington digits++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (digits > 3)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (DNS_R_BADDOTTEDQUAD);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington value *= 10;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington value += digitvalue[(int)c];
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington break;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington case ft_maybeslash:
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews bitlength = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (c == '/') {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington state = ft_bitlength;
3b1fce680f1dbe9467cd3b0ab3138ea52d5a976fMark Andrews break;
3b1fce680f1dbe9467cd3b0ab3138ea52d5a976fMark Andrews }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /* FALLTHROUGH */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington case ft_finishbitstring:
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (c == ']') {
ef653fbdb122e9e251bdfbdd4609d03a208bb79dMichael Graff if (tbcount == 0)
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson return (DNS_R_BADBITSTRING);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (count > 0) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n1 = count % 8;
7e0d7323d73f31ceb678879ad3aca873dc382483Brian Wellington if (n1 != 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington value <<= (8 - n1);
023dd2cfe0029002f5e5066ce0cc586b7b703376Mark Andrews *ndata++ = value;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nrem--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nused++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (bitlength != 0) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (bitlength > tbcount)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (DNS_R_BADBITSTRING);
023dd2cfe0029002f5e5066ce0cc586b7b703376Mark Andrews if (kind == ft_binary &&
7e0d7323d73f31ceb678879ad3aca873dc382483Brian Wellington bitlength != tbcount) {
7e0d7323d73f31ceb678879ad3aca873dc382483Brian Wellington return (DNS_R_BADBITSTRING);
7e0d7323d73f31ceb678879ad3aca873dc382483Brian Wellington } else if (kind == ft_octal) {
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson /*
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Figure out correct number
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * of octal digits for the
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * bitlength, and compare to
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * what was given.
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson */
62700b67eb8abb7d13f9c3c1bc4b60a1477d35d8Mark Andrews n1 = bitlength / 3;
dfd7798d8b870abf03795d8095297a4b982ab6e9Mark Andrews if (bitlength % 3 != 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n1++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n2 = tbcount / 3;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /* tbcount % 3 == 0 */
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson if (n1 != n2)
62700b67eb8abb7d13f9c3c1bc4b60a1477d35d8Mark Andrews return (DNS_R_BADBITSTRING);
dfd7798d8b870abf03795d8095297a4b982ab6e9Mark Andrews } else if (kind == ft_hex) {
ca84283333d22c64abfbcb87872dd5e6d9172c5aMark Andrews /*
ca84283333d22c64abfbcb87872dd5e6d9172c5aMark Andrews * Figure out correct number
ca84283333d22c64abfbcb87872dd5e6d9172c5aMark Andrews * of hex digits for the
ca84283333d22c64abfbcb87872dd5e6d9172c5aMark Andrews * bitlength, and compare to
ca84283333d22c64abfbcb87872dd5e6d9172c5aMark Andrews * what was given.
ca84283333d22c64abfbcb87872dd5e6d9172c5aMark Andrews */
3aca8e5bf3740bbcc3bb13dde242d7cc369abb27Mark Andrews n1 = bitlength / 4;
3aca8e5bf3740bbcc3bb13dde242d7cc369abb27Mark Andrews if (bitlength % 4 != 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n1++;
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt n2 = tbcount / 4;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson /* tbcount % 4 == 0 */
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson if (n1 != n2)
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson return (DNS_R_BADBITSTRING);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n1 = bitlength % vlen;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (n1 != 0) {
17dba29ba5db791976e505114baee53a1dde88aaBrian Wellington /*
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson * Are the pad bits in the
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * last 'vlen' bits zero?
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if ((value &
17dba29ba5db791976e505114baee53a1dde88aaBrian Wellington ~((~0) << (vlen-n1))) != 0)
cc0a5f714231709409b9e1b85f0f97ae50854451Mark Andrews return (DNS_R_BADBITSTRING);
cc0a5f714231709409b9e1b85f0f97ae50854451Mark Andrews }
cb8fd52bbeaf40c9166a0144541c4ff2bafc2dd6Andreas Gustafsson } else if (kind == ft_dottedquad)
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson bitlength = 32;
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson else
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson bitlength = tbcount;
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson if (kind == ft_dottedquad) {
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson n1 = bitlength / 8;
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson if (bitlength % 8 != 0)
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson n1++;
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson if (nrem < n1)
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson return (DNS_R_NOSPACE);
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson for (n2 = 0; n2 < n1; n2++) {
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson *ndata++ = dqchars[n2];
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson nrem--;
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson nused++;
76d9120dd696209fa1186ea289ea01cd4677782fAndreas Gustafsson }
76d9120dd696209fa1186ea289ea01cd4677782fAndreas Gustafsson }
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson if (bitlength == 256)
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson *label = 0;
cc0a5f714231709409b9e1b85f0f97ae50854451Mark Andrews else
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson *label = bitlength;
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson labels++;
687b7ef9989c9ab9040f4ccb5f1816b96fa4e43fAndreas Gustafsson INSIST(labels <= 127);
8cccaeaee13993c49009d3915806c1d0bd03743bAndreas Gustafsson offsets[labels] = nused;
8cccaeaee13993c49009d3915806c1d0bd03743bAndreas Gustafsson } else
8cccaeaee13993c49009d3915806c1d0bd03743bAndreas Gustafsson return (DNS_R_BADBITSTRING);
8cccaeaee13993c49009d3915806c1d0bd03743bAndreas Gustafsson state = ft_eatdot;
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews break;
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews case ft_bitlength:
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews if (!isdigit(c)) {
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews if (bitlength == 0)
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews return (DNS_R_BADBITSTRING);
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews state = ft_finishbitstring;
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews goto no_read;
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews }
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews bitlength *= 10;
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews bitlength += digitvalue[(int)c];
1672cff96d0b02badab6f94524e10285dde851fcMark Andrews if (bitlength > maxlength)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (DNS_R_BADBITSTRING);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews break;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews case ft_eatdot:
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (c != '.')
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (DNS_R_BADBITSTRING);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (tlen == 0) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews labels++;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews *ndata++ = 0;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews nrem--;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews nused++;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews done = ISC_TRUE;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews state = ft_start;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews break;
48f929d315bafeeffe0a37082ab4c9661a928c39Mark Andrews default:
48f929d315bafeeffe0a37082ab4c9661a928c39Mark Andrews FATAL_ERROR(__FILE__, __LINE__,
48f929d315bafeeffe0a37082ab4c9661a928c39Mark Andrews "Unexpected state %d", state);
48f929d315bafeeffe0a37082ab4c9661a928c39Mark Andrews /* Does not return. */
48f929d315bafeeffe0a37082ab4c9661a928c39Mark Andrews }
48f929d315bafeeffe0a37082ab4c9661a928c39Mark Andrews }
2c15fcdeac4c2402258867fbac24d7475ef98259Mark Andrews
2c15fcdeac4c2402258867fbac24d7475ef98259Mark Andrews if (!done) {
2c15fcdeac4c2402258867fbac24d7475ef98259Mark Andrews if (nrem == 0)
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater return (DNS_R_NOSPACE);
2c15fcdeac4c2402258867fbac24d7475ef98259Mark Andrews INSIST(tlen == 0);
a1bc94109313bf4ebb6e6ff655d71d45582d2e43Mark Andrews if (state != ft_ordinary && state != ft_eatdot &&
a1bc94109313bf4ebb6e6ff655d71d45582d2e43Mark Andrews state != ft_at)
a1bc94109313bf4ebb6e6ff655d71d45582d2e43Mark Andrews return (DNS_R_UNEXPECTEDEND);
a1bc94109313bf4ebb6e6ff655d71d45582d2e43Mark Andrews if (state == ft_ordinary) {
a1bc94109313bf4ebb6e6ff655d71d45582d2e43Mark Andrews INSIST(count != 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *label = count;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews labels++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(labels <= 127);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews offsets[labels] = nused;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (origin != NULL) {
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson if (nrem < origin->length)
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson return (DNS_R_NOSPACE);
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson label = origin->ndata;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson n1 = origin->length;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson nrem -= n1;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson while (n1 > 0) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n2 = *label++;
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson if (n2 <= 63) {
351b62535d4c4f89883bfdba025999dd32490266Evan Hunt *ndata++ = n2;
80dd46d7aab16c42a8c1acf6156c95406a9f20a4Mark Andrews n1 -= n2 + 1;
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt nused += n2 + 1;
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson while (n2 > 0) {
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson c = *label++;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater if (downcase)
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson c = maptolower[(int)c];
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson *ndata++ = c;
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson n2--;
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson }
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson } else {
9c566a852f31c3a5d0b9d6eaf11463114339c01dAndreas Gustafsson INSIST(n2 == DNS_LABELTYPE_BITSTRING);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington *ndata++ = n2;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater bitlength = *label++;
08f860f800d32007a0c9bf456f6c35fbb2ecbc81Evan Hunt *ndata++ = bitlength;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (bitlength == 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington bitlength = 256;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n2 = bitlength / 8;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (bitlength % 8 != 0)
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews n2++;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews n1 -= n2 + 2;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews nused += n2 + 2;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews while (n2 > 0) {
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews *ndata++ = *label++;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews n2--;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews }
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews }
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews labels++;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews if (n1 > 0) {
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews INSIST(labels <= 127);
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews offsets[labels] = nused;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews }
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews }
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews name->attributes |= DNS_NAMEATTR_ABSOLUTE;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews }
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews } else
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews name->attributes |= DNS_NAMEATTR_ABSOLUTE;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews
a5c077e40c784cf9e25c95a1ab94db2faab04ae9Brian Wellington name->magic = NAME_MAGIC;
a5c077e40c784cf9e25c95a1ab94db2faab04ae9Brian Wellington name->ndata = (unsigned char *)target->base + target->used;
a5c077e40c784cf9e25c95a1ab94db2faab04ae9Brian Wellington name->labels = labels;
a5c077e40c784cf9e25c95a1ab94db2faab04ae9Brian Wellington name->length = nused;
a5c077e40c784cf9e25c95a1ab94db2faab04ae9Brian Wellington
a5c077e40c784cf9e25c95a1ab94db2faab04ae9Brian Wellington if (saw_bitstring)
a5c077e40c784cf9e25c95a1ab94db2faab04ae9Brian Wellington compact(name, offsets);
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews isc_buffer_forward(source, tused);
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews isc_buffer_add(target, name->length);
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews return (DNS_R_SUCCESS);
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews}
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrewsdns_result_t
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrewsdns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews isc_buffer_t *target)
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews{
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews unsigned char *ndata;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews char *tdata;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews unsigned int nlen, tlen;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews unsigned char c;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews unsigned int trem, count;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews unsigned int bytes, nibbles;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews size_t i, len;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews unsigned int labels;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews isc_boolean_t saw_root = ISC_FALSE;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews char num[4];
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews
3727725bb7d63605b68a644060857013d563b67fEvan Hunt /*
8e4f3f1cbceef520ba889270c993de0ac376a2a7Evan Hunt * This function assumes the name is in proper uncompressed
3727725bb7d63605b68a644060857013d563b67fEvan Hunt * wire format.
3727725bb7d63605b68a644060857013d563b67fEvan Hunt */
3727725bb7d63605b68a644060857013d563b67fEvan Hunt REQUIRE(VALID_NAME(name));
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews REQUIRE(name->labels > 0);
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_TEXT);
5a17fe2916ce37793c12b243ab08c16095a59cf7Evan Hunt
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews ndata = name->ndata;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews nlen = name->length;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews labels = name->labels;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews tdata = (char *)target->base + target->used;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews tlen = target->length - target->used;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews trem = tlen;
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews
77b8f88f144928eddcca144c348d6ef53e7d5c43Evan Hunt /* Special handling for root label. */
77b8f88f144928eddcca144c348d6ef53e7d5c43Evan Hunt if (nlen == 1 && labels == 1 && *ndata == 0) {
77b8f88f144928eddcca144c348d6ef53e7d5c43Evan Hunt saw_root = ISC_TRUE;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews labels = 0;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews nlen = 0;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews if (trem == 0)
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews return (DNS_R_NOSPACE);
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews *tdata++ = '.';
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews trem--;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews }
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews while (labels > 0 && nlen > 0 && trem > 0) {
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews labels--;
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews count = *ndata++;
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews nlen--;
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews if (count == 0) {
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews saw_root = ISC_TRUE;
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews break;
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews }
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews if (count < 64) {
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews INSIST(nlen >= count);
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews while (count > 0) {
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews c = *ndata;
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews switch (c) {
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews case 0x22: /* '"' */
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews case 0x2E: /* '.' */
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews case 0x3B: /* ';' */
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews case 0x5C: /* '\\' */
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews /* Special modifiers in zone files. */
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews case 0x40: /* '@' */
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews case 0x24: /* '$' */
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews if (trem < 2)
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews return (DNS_R_NOSPACE);
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews *tdata++ = '\\';
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews *tdata++ = c;
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews ndata++;
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews trem -= 2;
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews nlen--;
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews break;
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews default:
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews if (c > 0x20 && c < 0x7f) {
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews if (trem == 0)
2c15fcdeac4c2402258867fbac24d7475ef98259Mark Andrews return (DNS_R_NOSPACE);
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews *tdata++ = c;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater ndata++;
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews trem--;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews nlen--;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews } else {
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews if (trem < 4)
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews return (DNS_R_NOSPACE);
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews sprintf(tdata, "\\%03u",
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews c);
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews tdata += 4;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews trem -= 4;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews ndata++;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews nlen--;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews }
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews }
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews count--;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews }
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews } else if (count == DNS_LABELTYPE_BITSTRING) {
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews if (trem < 3)
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews return (DNS_R_NOSPACE);
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews *tdata++ = '\\';
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews *tdata++ = '[';
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews *tdata++ = 'x';
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews trem -= 3;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews INSIST(nlen > 0);
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews count = *ndata++;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews if (count == 0)
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews count = 256;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews nlen--;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews len = sprintf(num, "%u", count); /* XXX */
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews INSIST(len <= 4);
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews bytes = count / 8;
dc6da18ccbb808d21f123cc6bda399b44ad11445Mark Andrews if (count % 8 != 0)
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews bytes++;
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews INSIST(nlen >= bytes);
8e4f3f1cbceef520ba889270c993de0ac376a2a7Evan Hunt nibbles = count / 4;
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews if (count % 4 != 0)
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews nibbles++;
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews if (trem < nibbles)
77b8f88f144928eddcca144c348d6ef53e7d5c43Evan Hunt return (DNS_R_NOSPACE);
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater trem -= nibbles;
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater nlen -= bytes;
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater while (nibbles > 0) {
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater c = *ndata++;
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater *tdata++ = hexdigits[(c >> 4)];
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater nibbles--;
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater if (nibbles != 0) {
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater *tdata++ = hexdigits[c & 0xf];
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater i++;
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater nibbles--;
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater }
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater }
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater if (trem < 2 + len)
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater return (DNS_R_NOSPACE);
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater *tdata++ = '/';
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater for (i = 0; i < len; i++)
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater *tdata++ = num[i];
97639003b0992b5f30ce82bdcc2fcd9d621ff09cAutomatic Updater *tdata++ = ']';
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson trem -= 2 + len;
6fcfd0c35d3fd6aea3d36ad002b68e59ac62fdc7Brian Wellington } else {
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson FATAL_ERROR(__FILE__, __LINE__,
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson "Unexpected label type %02x", count);
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson /* Does not return. */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington /*
2674e1a455d4f71de09b2b60e7a8304b9a305588Mark Andrews * The following assumes names are absolute. If not, we
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * fix things up later. Note that this means that in some
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * cases one more byte of text buffer is required than is
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington * needed in the final output.
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington */
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (trem == 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (DNS_R_NOSPACE);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington *tdata++ = '.';
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington trem--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (nlen != 0 && trem == 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington return (DNS_R_NOSPACE);
a12d9cfa59b5981c52e1aaafedf652d5128f3448Brian Wellington INSIST(nlen == 0);
6c7e680943ccdb75f23b050a7bc5ac0825e5244aMark Andrews if (!saw_root || omit_final_dot)
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson trem++;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
87f4715d6c0a22f3449eb3291c91aa45ba86c955Mark Andrews isc_buffer_add(target, tlen - trem);
87f4715d6c0a22f3449eb3291c91aa45ba86c955Mark Andrews
87f4715d6c0a22f3449eb3291c91aa45ba86c955Mark Andrews return (DNS_R_SUCCESS);
87f4715d6c0a22f3449eb3291c91aa45ba86c955Mark Andrews}
87f4715d6c0a22f3449eb3291c91aa45ba86c955Mark Andrews
87f4715d6c0a22f3449eb3291c91aa45ba86c955Mark Andrewsstatic void
87f4715d6c0a22f3449eb3291c91aa45ba86c955Mark Andrewsset_offsets(dns_name_t *name, unsigned char *offsets, isc_boolean_t set_labels,
87f4715d6c0a22f3449eb3291c91aa45ba86c955Mark Andrews isc_boolean_t set_length, isc_boolean_t set_absolute)
87f4715d6c0a22f3449eb3291c91aa45ba86c955Mark Andrews{
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington unsigned int offset, count, nlabels, nrem, n;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington unsigned char *ndata;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington isc_boolean_t absolute = ISC_FALSE;
17dba29ba5db791976e505114baee53a1dde88aaBrian Wellington
bb56f556f520621bcab33688c31d655953774adcAndreas Gustafsson ndata = name->ndata;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nrem = name->length;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington offset = 0;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nlabels = 0;
17dba29ba5db791976e505114baee53a1dde88aaBrian Wellington while (nrem > 0) {
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson INSIST(nlabels < 128);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington offsets[nlabels++] = offset;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington count = *ndata++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nrem--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington offset++;
cb9aa603ab2d019032e1b7b2d274e69adf0980f8Michael Graff if (count == 0) {
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington absolute = ISC_TRUE;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington break;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (count > 63) {
cb9aa603ab2d019032e1b7b2d274e69adf0980f8Michael Graff INSIST(count == DNS_LABELTYPE_BITSTRING);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington INSIST(nrem != 0);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n = *ndata++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington nrem--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington offset++;
cb9aa603ab2d019032e1b7b2d274e69adf0980f8Michael Graff if (n == 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington n = 256;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington count = n / 8;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (n % 8 != 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington count++;
cb9aa603ab2d019032e1b7b2d274e69adf0980f8Michael Graff }
bb60abb44549428414cd55a022f2b8cc4488f7adAndreas Gustafsson INSIST(nrem >= count);
bb60abb44549428414cd55a022f2b8cc4488f7adAndreas Gustafsson nrem -= count;
bb60abb44549428414cd55a022f2b8cc4488f7adAndreas Gustafsson offset += count;
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson ndata += count;
62700b67eb8abb7d13f9c3c1bc4b60a1477d35d8Mark Andrews }
bb60abb44549428414cd55a022f2b8cc4488f7adAndreas Gustafsson if (set_labels)
bb60abb44549428414cd55a022f2b8cc4488f7adAndreas Gustafsson name->labels = nlabels;
bb60abb44549428414cd55a022f2b8cc4488f7adAndreas Gustafsson if (set_length)
bb60abb44549428414cd55a022f2b8cc4488f7adAndreas Gustafsson name->length = offset;
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson if (set_absolute) {
62700b67eb8abb7d13f9c3c1bc4b60a1477d35d8Mark Andrews if (absolute)
bb60abb44549428414cd55a022f2b8cc4488f7adAndreas Gustafsson name->attributes |= DNS_NAMEATTR_ABSOLUTE;
476386968b1f287a695f73c48862e961011af99bMark Andrews else
b500de3be9ba5318da157364bf9fbbda5f88f203Mark Andrews name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
476386968b1f287a695f73c48862e961011af99bMark Andrews }
476386968b1f287a695f73c48862e961011af99bMark Andrews INSIST(nlabels == name->labels);
476386968b1f287a695f73c48862e961011af99bMark Andrews INSIST(offset == name->length);
476386968b1f287a695f73c48862e961011af99bMark Andrews}
476386968b1f287a695f73c48862e961011af99bMark Andrews
476386968b1f287a695f73c48862e961011af99bMark Andrewsstatic void
476386968b1f287a695f73c48862e961011af99bMark Andrewscompact(dns_name_t *name, unsigned char *offsets) {
476386968b1f287a695f73c48862e961011af99bMark Andrews unsigned char *head, *curr, *last;
476386968b1f287a695f73c48862e961011af99bMark Andrews unsigned int count, n, bit;
476386968b1f287a695f73c48862e961011af99bMark Andrews unsigned int headbits, currbits, tailbits, newbits;
476386968b1f287a695f73c48862e961011af99bMark Andrews unsigned int headrem, newrem;
476386968b1f287a695f73c48862e961011af99bMark Andrews unsigned int headindex, currindex, tailindex, newindex;
476386968b1f287a695f73c48862e961011af99bMark Andrews unsigned char tail[32];
ce28ea0f2f8a6fbbafb8944dbe86cd0b98689b84Tatuya JINMEI 神明達哉
476386968b1f287a695f73c48862e961011af99bMark Andrews /*
476386968b1f287a695f73c48862e961011af99bMark Andrews * The caller MUST ensure that all bitstrings are correctly formatted
476386968b1f287a695f73c48862e961011af99bMark Andrews * and that the offsets table is valid.
476386968b1f287a695f73c48862e961011af99bMark Andrews */
476386968b1f287a695f73c48862e961011af99bMark Andrews
476386968b1f287a695f73c48862e961011af99bMark Andrews again:
476386968b1f287a695f73c48862e961011af99bMark Andrews memset(tail, 0, sizeof tail);
476386968b1f287a695f73c48862e961011af99bMark Andrews INSIST(name->labels != 0);
476386968b1f287a695f73c48862e961011af99bMark Andrews n = name->labels - 1;
476386968b1f287a695f73c48862e961011af99bMark Andrews
a45a6ea2b03448751d7c44931e8ac7666e7cc2ceMark Andrews while (n > 0) {
a45a6ea2b03448751d7c44931e8ac7666e7cc2ceMark Andrews head = &name->ndata[offsets[n]];
a45a6ea2b03448751d7c44931e8ac7666e7cc2ceMark Andrews if (head[0] == DNS_LABELTYPE_BITSTRING && head[1] != 0) {
a45a6ea2b03448751d7c44931e8ac7666e7cc2ceMark Andrews if (n != 0) {
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson n--;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence curr = &name->ndata[offsets[n]];
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 if (curr[0] != DNS_LABELTYPE_BITSTRING)
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 break;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 /*
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * We have consecutive bitstrings labels, and
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 * the more significant label ('head') has
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson * space.
1adb2e87a20a480e640385609c9652dac04c7dffAndreas Gustafsson */
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson currbits = curr[1];
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson if (currbits == 0)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff currbits = 256;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson currindex = 0;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson headbits = head[1];
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson if (headbits == 0)
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews headbits = 256;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews headindex = headbits;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews count = 256 - headbits;
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson if (count > currbits)
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson count = currbits;
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson headrem = headbits % 8;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (headrem != 0)
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington headrem = 8 - headrem;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington if (headrem != 0) {
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson if (headrem > count)
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson headrem = count;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 do {
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 bit = get_bit(&curr[2],
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 currindex);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 set_bit(&head[2], headindex,
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 bit);
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 currindex++;
743bbdc18f839499862e4fb28ec32f607b1632dcTatuya JINMEI 神明達哉 headindex++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington headbits++;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington count--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington headrem--;
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington } while (headrem != 0);
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington }
90c099e88e9f16bfee9edee3ac1a51fc98843772Brian Wellington tailindex = 0;
8bba70c48d74a389a075b9c80837161b4ed91e88Andreas Gustafsson tailbits = 0;
ff4322d44f8404683b6fb6c86a38a2bc14f6c083Andreas Gustafsson while (count > 0) {
0cf9ce19cc05a60f85ec610106a983fe806ebb77Andreas Gustafsson bit = get_bit(&curr[2], currindex);
ff4322d44f8404683b6fb6c86a38a2bc14f6c083Andreas Gustafsson set_bit(tail, tailindex, bit);
ff4322d44f8404683b6fb6c86a38a2bc14f6c083Andreas Gustafsson currindex++;
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson tailindex++;
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson tailbits++;
6889d57aabc5f48eaee78894e20054215319b461Andreas Gustafsson 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--;
}
count = tailbits / 8;
if (tailbits % 8 != 0)
count++;
last = tail;
while (count > 0) {
*curr++ = *last++;
count--;
}
last = name->ndata + name->length;
while (head != last)
*curr++ = *head++;
name->length = (curr - name->ndata);
goto again;
}
}
n--;
}
}
dns_result_t
dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
dns_decompress_t *dctx, isc_boolean_t downcase,
isc_buffer_t *target)
{
unsigned char *cdata, *ndata;
unsigned int cused, hops, nrem, nused, labels, n;
unsigned int current, new_current, biggest_pointer;
isc_boolean_t saw_bitstring, done;
fw_state state = fw_start;
unsigned int c;
unsigned char *offsets;
dns_offsets_t odata;
/*
* Copy the possibly-compressed name at source into target,
* decompressing it.
*/
REQUIRE(VALID_NAME(name));
REQUIRE(isc_buffer_type(source) == ISC_BUFFERTYPE_BINARY);
REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY);
REQUIRE(dctx != NULL);
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
INIT_OFFSETS(name, offsets, odata);
/*
* Invalidate 'name'.
*/
name->magic = 0;
name->ndata = NULL;
name->length = 0;
name->labels = 0;
name->attributes = 0;
/*
* Initialize things to make the compiler happy; they're not required.
*/
n = 0;
new_current = 0;
/*
* Set up.
*/
labels = 0;
hops = 0;
saw_bitstring = ISC_FALSE;
done = ISC_FALSE;
ndata = (unsigned char *)target->base + target->used;
nrem = target->length - target->used;
if (nrem > 255)
nrem = 255;
nused = 0;
cdata = (unsigned char *)source->base + source->current;
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.
*/
while (current < source->used && !done) {
c = *cdata++;
current++;
if (hops == 0)
cused++;
switch (state) {
case fw_start:
if (c < 64) {
labels++;
if (nrem < c + 1)
return (DNS_R_NOSPACE);
nrem -= c + 1;
nused += c + 1;
*ndata++ = c;
if (c == 0)
done = ISC_TRUE;
n = c;
state = fw_ordinary;
} else if (c >= 192) {
/*
* Ordinary 14-bit pointer.
*/
if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) ==
0)
return (DNS_R_DISALLOWED);
new_current = c & 0x3F;
n = 1;
state = fw_newcurrent;
} else if (c == DNS_LABELTYPE_BITSTRING) {
labels++;
if (nrem == 0)
return (DNS_R_NOSPACE);
nrem--;
nused++;
*ndata++ = c;
saw_bitstring = ISC_TRUE;
state = fw_bitstring;
} else if (c == DNS_LABELTYPE_GLOBALCOMP16) {
/*
* 16-bit pointer.
*/
if ((dctx->allowed & DNS_COMPRESS_GLOBAL16) ==
0)
return (DNS_R_DISALLOWED);
new_current = 0;
n = 2;
state = fw_newcurrent;
} else if (c == DNS_LABELTYPE_LOCALCOMP) {
/*
* Local compression.
*/
if ((dctx->allowed & DNS_COMPRESS_GLOBAL16) ==
0)
return (DNS_R_DISALLOWED);
/* XXX */
return (DNS_R_NOTIMPLEMENTED);
} else
return (DNS_R_BADLABELTYPE);
break;
case fw_ordinary:
if (downcase)
c = maptolower[c];
/* FALLTHROUGH */
case fw_copy:
*ndata++ = c;
n--;
if (n == 0)
state = fw_start;
break;
case fw_bitstring:
if (nrem < c + 1)
return (DNS_R_NOSPACE);
nrem -= c + 1;
nused += c + 1;
*ndata++ = c;
if (c == 0)
c = 256;
n = c / 8;
if (c % 8 != 0)
n++;
state = fw_copy;
break;
case fw_newcurrent:
new_current *= 256;
new_current += c;
n--;
if (n == 0) {
if (new_current >= biggest_pointer)
return (DNS_R_BADPOINTER);
biggest_pointer = new_current;
current = new_current;
cdata = (unsigned char *)source->base +
current;
hops++;
if (hops > DNS_POINTER_MAXHOPS)
return (DNS_R_TOOMANYHOPS);
state = fw_start;
}
break;
default:
FATAL_ERROR(__FILE__, __LINE__,
"Unknown state %d", state);
/* Does not return. */
}
}
if (!done)
return (DNS_R_UNEXPECTEDEND);
name->magic = NAME_MAGIC;
name->ndata = (unsigned char *)target->base + target->used;
name->labels = labels;
name->length = nused;
name->attributes |= DNS_NAMEATTR_ABSOLUTE;
/*
* We should build the offsets table directly.
*/
if (name->offsets != NULL || saw_bitstring)
set_offsets(name, offsets, ISC_FALSE, ISC_FALSE, ISC_FALSE);
if (saw_bitstring)
compact(name, offsets);
isc_buffer_forward(source, cused);
isc_buffer_add(target, name->length);
return (DNS_R_SUCCESS);
}
dns_result_t
dns_name_towire(dns_name_t *name, dns_compress_t *cctx,
isc_buffer_t *target)
{
/*
* Convert 'name' into wire format, compressing it as specified by the
* compression context 'cctx', and storing the result in 'target'.
*/
REQUIRE(VALID_NAME(name));
REQUIRE(cctx != NULL);
REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY);
/*
* XXX We don't try to compress the name; we just copy the
* uncompressed version into the target buffer.
*/
if (target->length - target->used < name->length)
return (DNS_R_NOSPACE);
(void)memcpy((unsigned char *)target->base + target->used,
name->ndata, (size_t)name->length);
isc_buffer_add(target, name->length);
return (DNS_R_SUCCESS);
}