diff options
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | Versions.def | 1 | ||||
-rw-r--r-- | include/arpa/nameser.h | 29 | ||||
-rw-r--r-- | include/resolv.h | 6 | ||||
-rw-r--r-- | resolv/Makefile | 5 | ||||
-rw-r--r-- | resolv/Versions | 13 | ||||
-rw-r--r-- | resolv/arpa/nameser.h | 397 | ||||
-rw-r--r-- | resolv/arpa/nameser_compat.h | 59 | ||||
-rw-r--r-- | resolv/ns_date.c | 121 | ||||
-rw-r--r-- | resolv/ns_name.c | 589 | ||||
-rw-r--r-- | resolv/ns_netint.c | 22 | ||||
-rw-r--r-- | resolv/ns_parse.c | 94 | ||||
-rw-r--r-- | resolv/ns_print.c | 203 | ||||
-rw-r--r-- | resolv/ns_samedomain.c | 65 | ||||
-rw-r--r-- | resolv/ns_ttl.c | 9 | ||||
-rw-r--r-- | resolv/nss_dns/dns-canon.c | 4 | ||||
-rw-r--r-- | resolv/nss_dns/dns-host.c | 16 | ||||
-rw-r--r-- | resolv/res_debug.c | 2 |
18 files changed, 1092 insertions, 570 deletions
@@ -1,5 +1,32 @@ 2008-08-01 Ulrich Drepper <drepper@redhat.com> + * Versions.def: Add GLIBC_2.9 to libresolv. + * include/resolv.h: Remove hidden proto declarations for __ns_* + functions. Add them for __dn_count_labels and __p_secstodate. + * include/arpa/nameser.h: Add a number of hidden proto declarations. + Define ns_msg_getflags macro here. + * resolv/res_debug.c: Add hidden definition for __dn_count_labels + and __p_secstodate. + * resolv/Versions: Export functions from <arpa/nameser.h> from + libresolv in version GLIBC_2.9. + * resolv/ns_name.c: Integrate changes from bind 9.5.0. Add necessary + hidden definitions. + * resolv/ns_netint.c: Likewise. + * resolv/ns_parse.c: Likewise. + * resolv/ns_print.c: Likewise. + * resolv/ns_samedomain.c: Likewise. + * resolv/ns_ttl.c: Likewise. + * resolv/arpa/nameser_compat.h: Likewise. + * resolv/arpa/nameser.h: Likewise. Remove macros which redirect + function calls. + * resolv/nss_dns/dns-canon.c (_nss_dns_getcanonname_r): Use __ns_get16 + instead of ns_get16. + * resolv/nss_dns/dns-host.c (getanswer_r): Use __ns_get16 and + __ns_get32 instead of ns_get16 and ns_get32 respectively. + (gaih_getanswer_slice): Likewise. + * resolv/Makefile (libresolv-routines): Add ns_date. + * resolv/ns_date.c: New file. + * elf/Makefile (check-localplt.out): Also check libresolv and libcrypt. diff --git a/Versions.def b/Versions.def index 5d98ad1933..856d878068 100644 --- a/Versions.def +++ b/Versions.def @@ -93,6 +93,7 @@ libresolv { GLIBC_2.0 GLIBC_2.2 GLIBC_2.3.2 + GLIBC_2.9 GLIBC_PRIVATE } librt { diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h index efbe956602..89ee6b031c 100644 --- a/include/arpa/nameser.h +++ b/include/arpa/nameser.h @@ -7,7 +7,7 @@ #include <stdint.h> #include <netinet/in.h> -extern struct _ns_flagdata _ns_flagdata[] attribute_hidden; +extern const struct _ns_flagdata _ns_flagdata[] attribute_hidden; #if _STRING_ARCH_unaligned @@ -44,3 +44,30 @@ extern struct _ns_flagdata _ns_flagdata[] attribute_hidden; } while (0) #endif + +extern u_int __ns_get16 (const u_char *) __THROW; +extern u_long __ns_get32 (const u_char *) __THROW; + +#define ns_msg_getflag(handle, flag) \ + (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift) + +libresolv_hidden_proto (ns_get16) +libresolv_hidden_proto (ns_get32) +libresolv_hidden_proto (ns_put16) +libresolv_hidden_proto (ns_put32) +libresolv_hidden_proto (ns_initparse) +libresolv_hidden_proto (ns_skiprr) +libresolv_hidden_proto (ns_parserr) +libresolv_hidden_proto (ns_name_ntop) +libresolv_hidden_proto (ns_name_pton) +libresolv_hidden_proto (ns_name_pack) +libresolv_hidden_proto (ns_name_skip) +libresolv_hidden_proto (ns_name_unpack) +libresolv_hidden_proto (ns_name_compress) +libresolv_hidden_proto (ns_name_uncompress) +libresolv_hidden_proto (ns_sprintrr) +libresolv_hidden_proto (ns_sprintrrf) +libresolv_hidden_proto (ns_samedomain) +libresolv_hidden_proto (ns_samename) +libresolv_hidden_proto (ns_makecanon) +libresolv_hidden_proto (ns_format_ttl) diff --git a/include/resolv.h b/include/resolv.h index 6dae0495b2..7ab7f8779d 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -98,11 +98,9 @@ libresolv_hidden_proto (__res_nameinquery) libresolv_hidden_proto (__res_queriesmatch) libresolv_hidden_proto (__res_nsend) libresolv_hidden_proto (__b64_ntop) -libresolv_hidden_proto (__ns_name_ntop) -libresolv_hidden_proto (__ns_name_unpack) -libresolv_hidden_proto (__ns_get16) -libresolv_hidden_proto (__ns_get32) libresolv_hidden_proto (__res_nopt) +libresolv_hidden_proto (__dn_count_labels) +libresolv_hidden_proto (__p_secstodate) extern const char *_res_opcodes[]; libresolv_hidden_proto (_res_opcodes) diff --git a/resolv/Makefile b/resolv/Makefile index 6ac226735a..42e3505646 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -1,5 +1,4 @@ -# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2003,2004,2007 -# Free Software Foundation, Inc. +# Copyright (C) 1994-2001,2003,2004,2007,2008 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -49,7 +48,7 @@ libresolv-routines := gethnamaddr res_comp res_debug \ res_data res_mkquery res_query res_send \ inet_net_ntop inet_net_pton inet_neta base64 \ ns_parse ns_name ns_netint ns_ttl ns_print \ - ns_samedomain + ns_samedomain ns_date libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \ getaddrinfo_a diff --git a/resolv/Versions b/resolv/Versions index 355d95d606..4b2e5e9dbc 100644 --- a/resolv/Versions +++ b/resolv/Versions @@ -74,6 +74,19 @@ libresolv { GLIBC_2.3.2 { __p_rcode; } + GLIBC_2.9 { + ns_msg_getflag; + ns_get16; ns_get32; ns_put16; ns_put32; + ns_initparse; ns_skiprr; ns_parserr; + ns_sprintrr; ns_sprintrrf; + ns_format_ttl; ns_parse_ttl; + ns_datetosecs; + ns_name_ntol; ns_name_ntop; ns_name_pton; + ns_name_unpack; ns_name_pack; + ns_name_uncompress; ns_name_compress; + ns_name_skip; ns_name_rollback; + ns_samedomain; ns_subdomain; ns_makecanon; ns_samename; + } GLIBC_PRIVATE { # Needed in libnss_dns. __ns_name_unpack; __ns_name_ntop; diff --git a/resolv/arpa/nameser.h b/resolv/arpa/nameser.h index a164221df4..7979b3d4dd 100644 --- a/resolv/arpa/nameser.h +++ b/resolv/arpa/nameser.h @@ -28,6 +28,7 @@ */ /* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -51,6 +52,8 @@ #ifndef _ARPA_NAMESER_H_ #define _ARPA_NAMESER_H_ +/*! \file */ + #define BIND_4_COMPAT #include <sys/param.h> @@ -61,7 +64,7 @@ #endif #include <sys/cdefs.h> -/* +/*% * Revision information. This is the release date in YYYYMMDD format. * It can change every day so the right thing to do with it is use it * in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not @@ -69,42 +72,41 @@ * contains a new enough lib/nameser/ to support the feature you need. */ -#define __NAMESER 19991006 /* New interface version stamp. */ - +#define __NAMESER 19991006 /*%< New interface version stamp. */ /* * Define constants based on RFC 883, RFC 1034, RFC 1035 */ -#define NS_PACKETSZ 512 /* maximum packet size */ -#define NS_MAXDNAME 1025 /* maximum domain name */ -#define NS_MAXCDNAME 255 /* maximum compressed domain name */ -#define NS_MAXLABEL 63 /* maximum length of domain label */ -#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */ -#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */ -#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ -#define NS_INT32SZ 4 /* #/bytes of data in a u_int32_t */ -#define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */ -#define NS_INT8SZ 1 /* #/bytes of data in a u_int8_t */ -#define NS_INADDRSZ 4 /* IPv4 T_A */ -#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */ -#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */ -#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */ - +#define NS_PACKETSZ 512 /*%< default UDP packet size */ +#define NS_MAXDNAME 1025 /*%< maximum domain name */ +#define NS_MAXMSG 65535 /*%< maximum message size */ +#define NS_MAXCDNAME 255 /*%< maximum compressed domain name */ +#define NS_MAXLABEL 63 /*%< maximum length of domain label */ +#define NS_HFIXEDSZ 12 /*%< #/bytes of fixed data in header */ +#define NS_QFIXEDSZ 4 /*%< #/bytes of fixed data in query */ +#define NS_RRFIXEDSZ 10 /*%< #/bytes of fixed data in r record */ +#define NS_INT32SZ 4 /*%< #/bytes of data in a u_int32_t */ +#define NS_INT16SZ 2 /*%< #/bytes of data in a u_int16_t */ +#define NS_INT8SZ 1 /*%< #/bytes of data in a u_int8_t */ +#define NS_INADDRSZ 4 /*%< IPv4 T_A */ +#define NS_IN6ADDRSZ 16 /*%< IPv6 T_AAAA */ +#define NS_CMPRSFLGS 0xc0 /*%< Flag bits indicating name compression. */ +#define NS_DEFAULTPORT 53 /*%< For both TCP and UDP. */ /* * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord() * in synch with it. */ typedef enum __ns_sect { - ns_s_qd = 0, /* Query: Question. */ - ns_s_zn = 0, /* Update: Zone. */ - ns_s_an = 1, /* Query: Answer. */ - ns_s_pr = 1, /* Update: Prerequisites. */ - ns_s_ns = 2, /* Query: Name servers. */ - ns_s_ud = 2, /* Update: Update. */ - ns_s_ar = 3, /* Query|Update: Additional records. */ + ns_s_qd = 0, /*%< Query: Question. */ + ns_s_zn = 0, /*%< Update: Zone. */ + ns_s_an = 1, /*%< Query: Answer. */ + ns_s_pr = 1, /*%< Update: Prerequisites. */ + ns_s_ns = 2, /*%< Query: Name servers. */ + ns_s_ud = 2, /*%< Update: Update. */ + ns_s_ar = 3, /*%< Query|Update: Additional records. */ ns_s_max = 4 } ns_sect; -/* +/*% * This is a message handle. It is caller allocated and has no dynamic data. * This structure is intended to be opaque to all but ns_parse.c, thus the * leading _'s on the member names. Use the accessor functions, not the _'s. @@ -115,25 +117,22 @@ typedef struct __ns_msg { const u_char *_sections[ns_s_max]; ns_sect _sect; int _rrnum; - const u_char *_ptr; + const u_char *_msg_ptr; } ns_msg; /* Private data structure - do not use from outside library. */ struct _ns_flagdata { int mask, shift; }; -extern struct _ns_flagdata _ns_flagdata[]; +extern const struct _ns_flagdata _ns_flagdata[]; /* Accessor macros - this is part of the public interface. */ -#define ns_msg_getflag(handle, flag) ( \ - ((handle)._flags & _ns_flagdata[flag].mask) \ - >> _ns_flagdata[flag].shift \ - ) + #define ns_msg_id(handle) ((handle)._id + 0) #define ns_msg_base(handle) ((handle)._msg + 0) #define ns_msg_end(handle) ((handle)._eom + 0) #define ns_msg_size(handle) ((handle)._eom - (handle)._msg) #define ns_msg_count(handle, section) ((handle)._counts[section] + 0) -/* +/*% * This is a parsed record. It is caller allocated and has no dynamic data. */ typedef struct __ns_rr { @@ -153,56 +152,58 @@ typedef struct __ns_rr { #define ns_rr_rdlen(rr) ((rr).rdlength + 0) #define ns_rr_rdata(rr) ((rr).rdata + 0) -/* +/*% * These don't have to be in the same order as in the packet flags word, * and they can even overlap in some cases, but they will need to be kept * in synch with ns_parse.c:ns_flagdata[]. */ typedef enum __ns_flag { - ns_f_qr, /* Question/Response. */ - ns_f_opcode, /* Operation code. */ - ns_f_aa, /* Authoritative Answer. */ - ns_f_tc, /* Truncation occurred. */ - ns_f_rd, /* Recursion Desired. */ - ns_f_ra, /* Recursion Available. */ - ns_f_z, /* MBZ. */ - ns_f_ad, /* Authentic Data (DNSSEC). */ - ns_f_cd, /* Checking Disabled (DNSSEC). */ - ns_f_rcode, /* Response code. */ + ns_f_qr, /*%< Question/Response. */ + ns_f_opcode, /*%< Operation code. */ + ns_f_aa, /*%< Authoritative Answer. */ + ns_f_tc, /*%< Truncation occurred. */ + ns_f_rd, /*%< Recursion Desired. */ + ns_f_ra, /*%< Recursion Available. */ + ns_f_z, /*%< MBZ. */ + ns_f_ad, /*%< Authentic Data (DNSSEC). */ + ns_f_cd, /*%< Checking Disabled (DNSSEC). */ + ns_f_rcode, /*%< Response code. */ ns_f_max } ns_flag; -/* +/*% * Currently defined opcodes. */ typedef enum __ns_opcode { - ns_o_query = 0, /* Standard query. */ - ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */ - ns_o_status = 2, /* Name server status query (unsupported). */ + ns_o_query = 0, /*%< Standard query. */ + ns_o_iquery = 1, /*%< Inverse query (deprecated/unsupported). */ + ns_o_status = 2, /*%< Name server status query (unsupported). */ /* Opcode 3 is undefined/reserved. */ - ns_o_notify = 4, /* Zone change notification. */ - ns_o_update = 5, /* Zone update message. */ + ns_o_notify = 4, /*%< Zone change notification. */ + ns_o_update = 5, /*%< Zone update message. */ ns_o_max = 6 } ns_opcode; -/* +/*% * Currently defined response codes. */ typedef enum __ns_rcode { - ns_r_noerror = 0, /* No error occurred. */ - ns_r_formerr = 1, /* Format error. */ - ns_r_servfail = 2, /* Server failure. */ - ns_r_nxdomain = 3, /* Name error. */ - ns_r_notimpl = 4, /* Unimplemented. */ - ns_r_refused = 5, /* Operation refused. */ + ns_r_noerror = 0, /*%< No error occurred. */ + ns_r_formerr = 1, /*%< Format error. */ + ns_r_servfail = 2, /*%< Server failure. */ + ns_r_nxdomain = 3, /*%< Name error. */ + ns_r_notimpl = 4, /*%< Unimplemented. */ + ns_r_refused = 5, /*%< Operation refused. */ /* these are for BIND_UPDATE */ - ns_r_yxdomain = 6, /* Name exists */ - ns_r_yxrrset = 7, /* RRset exists */ - ns_r_nxrrset = 8, /* RRset does not exist */ - ns_r_notauth = 9, /* Not authoritative for zone */ - ns_r_notzone = 10, /* Zone of record different from zone section */ + ns_r_yxdomain = 6, /*%< Name exists */ + ns_r_yxrrset = 7, /*%< RRset exists */ + ns_r_nxrrset = 8, /*%< RRset does not exist */ + ns_r_notauth = 9, /*%< Not authoritative for zone */ + ns_r_notzone = 10, /*%< Zone of record different from zone section */ ns_r_max = 11, - /* The following are TSIG extended errors */ + /* The following are EDNS extended rcodes */ + ns_r_badvers = 16, + /* The following are TSIG errors */ ns_r_badsig = 16, ns_r_badkey = 17, ns_r_badtime = 18 @@ -215,7 +216,7 @@ typedef enum __ns_update_operation { ns_uop_max = 2 } ns_update_operation; -/* +/*% * This structure is used for TSIG authenticated messages */ struct ns_tsig_key { @@ -225,7 +226,7 @@ struct ns_tsig_key { }; typedef struct ns_tsig_key ns_tsig_key; -/* +/*% * This structure is used for TSIG authenticated TCP messages */ struct ns_tcp_tsig_state { @@ -245,59 +246,61 @@ typedef struct ns_tcp_tsig_state ns_tcp_tsig_state; #define NS_TSIG_ERROR_NO_SPACE -11 #define NS_TSIG_ERROR_FORMERR -12 -/* +/*% * Currently defined type values for resources and queries. */ typedef enum __ns_type { - ns_t_invalid = 0, /* Cookie. */ - ns_t_a = 1, /* Host address. */ - ns_t_ns = 2, /* Authoritative server. */ - ns_t_md = 3, /* Mail destination. */ - ns_t_mf = 4, /* Mail forwarder. */ - ns_t_cname = 5, /* Canonical name. */ - ns_t_soa = 6, /* Start of authority zone. */ - ns_t_mb = 7, /* Mailbox domain name. */ - ns_t_mg = 8, /* Mail group member. */ - ns_t_mr = 9, /* Mail rename name. */ - ns_t_null = 10, /* Null resource record. */ - ns_t_wks = 11, /* Well known service. */ - ns_t_ptr = 12, /* Domain name pointer. */ - ns_t_hinfo = 13, /* Host information. */ - ns_t_minfo = 14, /* Mailbox information. */ - ns_t_mx = 15, /* Mail routing information. */ - ns_t_txt = 16, /* Text strings. */ - ns_t_rp = 17, /* Responsible person. */ - ns_t_afsdb = 18, /* AFS cell database. */ - ns_t_x25 = 19, /* X_25 calling address. */ - ns_t_isdn = 20, /* ISDN calling address. */ - ns_t_rt = 21, /* Router. */ - ns_t_nsap = 22, /* NSAP address. */ - ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */ - ns_t_sig = 24, /* Security signature. */ - ns_t_key = 25, /* Security key. */ - ns_t_px = 26, /* X.400 mail mapping. */ - ns_t_gpos = 27, /* Geographical position (withdrawn). */ - ns_t_aaaa = 28, /* Ip6 Address. */ - ns_t_loc = 29, /* Location Information. */ - ns_t_nxt = 30, /* Next domain (security). */ - ns_t_eid = 31, /* Endpoint identifier. */ - ns_t_nimloc = 32, /* Nimrod Locator. */ - ns_t_srv = 33, /* Server Selection. */ - ns_t_atma = 34, /* ATM Address */ - ns_t_naptr = 35, /* Naming Authority PoinTeR */ - ns_t_kx = 36, /* Key Exchange */ - ns_t_cert = 37, /* Certification record */ - ns_t_a6 = 38, /* IPv6 address (deprecated, use ns_t_aaaa) */ - ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */ - ns_t_sink = 40, /* Kitchen sink (experimentatl) */ - ns_t_opt = 41, /* EDNS0 option (meta-RR) */ - ns_t_tsig = 250, /* Transaction signature. */ - ns_t_ixfr = 251, /* Incremental zone transfer. */ - ns_t_axfr = 252, /* Transfer zone of authority. */ - ns_t_mailb = 253, /* Transfer mailbox records. */ - ns_t_maila = 254, /* Transfer mail agent records. */ - ns_t_any = 255, /* Wildcard match. */ - ns_t_zxfr = 256, /* BIND-specific, nonstandard. */ + ns_t_invalid = 0, /*%< Cookie. */ + ns_t_a = 1, /*%< Host address. */ + ns_t_ns = 2, /*%< Authoritative server. */ + ns_t_md = 3, /*%< Mail destination. */ + ns_t_mf = 4, /*%< Mail forwarder. */ + ns_t_cname = 5, /*%< Canonical name. */ + ns_t_soa = 6, /*%< Start of authority zone. */ + ns_t_mb = 7, /*%< Mailbox domain name. */ + ns_t_mg = 8, /*%< Mail group member. */ + ns_t_mr = 9, /*%< Mail rename name. */ + ns_t_null = 10, /*%< Null resource record. */ + ns_t_wks = 11, /*%< Well known service. */ + ns_t_ptr = 12, /*%< Domain name pointer. */ + ns_t_hinfo = 13, /*%< Host information. */ + ns_t_minfo = 14, /*%< Mailbox information. */ + ns_t_mx = 15, /*%< Mail routing information. */ + ns_t_txt = 16, /*%< Text strings. */ + ns_t_rp = 17, /*%< Responsible person. */ + ns_t_afsdb = 18, /*%< AFS cell database. */ + ns_t_x25 = 19, /*%< X_25 calling address. */ + ns_t_isdn = 20, /*%< ISDN calling address. */ + ns_t_rt = 21, /*%< Router. */ + ns_t_nsap = 22, /*%< NSAP address. */ + ns_t_nsap_ptr = 23, /*%< Reverse NSAP lookup (deprecated). */ + ns_t_sig = 24, /*%< Security signature. */ + ns_t_key = 25, /*%< Security key. */ + ns_t_px = 26, /*%< X.400 mail mapping. */ + ns_t_gpos = 27, /*%< Geographical position (withdrawn). */ + ns_t_aaaa = 28, /*%< Ip6 Address. */ + ns_t_loc = 29, /*%< Location Information. */ + ns_t_nxt = 30, /*%< Next domain (security). */ + ns_t_eid = 31, /*%< Endpoint identifier. */ + ns_t_nimloc = 32, /*%< Nimrod Locator. */ + ns_t_srv = 33, /*%< Server Selection. */ + ns_t_atma = 34, /*%< ATM Address */ + ns_t_naptr = 35, /*%< Naming Authority PoinTeR */ + ns_t_kx = 36, /*%< Key Exchange */ + ns_t_cert = 37, /*%< Certification record */ + ns_t_a6 = 38, /*%< IPv6 address (deprecated, use ns_t_aaaa) */ + ns_t_dname = 39, /*%< Non-terminal DNAME (for IPv6) */ + ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */ + ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */ + ns_t_apl = 42, /*%< Address prefix list (RFC3123) */ + ns_t_tkey = 249, /*%< Transaction key */ + ns_t_tsig = 250, /*%< Transaction signature. */ + ns_t_ixfr = 251, /*%< Incremental zone transfer. */ + ns_t_axfr = 252, /*%< Transfer zone of authority. */ + ns_t_mailb = 253, /*%< Transfer mailbox records. */ + ns_t_maila = 254, /*%< Transfer mail agent records. */ + ns_t_any = 255, /*%< Wildcard match. */ + ns_t_zxfr = 256, /*%< BIND-specific, nonstandard. */ ns_t_max = 65536 } ns_type; @@ -312,61 +315,61 @@ typedef enum __ns_type { #define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \ (t) == ns_t_zxfr) -/* +/*% * Values for class field */ typedef enum __ns_class { - ns_c_invalid = 0, /* Cookie. */ - ns_c_in = 1, /* Internet. */ - ns_c_2 = 2, /* unallocated/unsupported. */ - ns_c_chaos = 3, /* MIT Chaos-net. */ - ns_c_hs = 4, /* MIT Hesiod. */ + ns_c_invalid = 0, /*%< Cookie. */ + ns_c_in = 1, /*%< Internet. */ + ns_c_2 = 2, /*%< unallocated/unsupported. */ + ns_c_chaos = 3, /*%< MIT Chaos-net. */ + ns_c_hs = 4, /*%< MIT Hesiod. */ /* Query class values which do not appear in resource records */ - ns_c_none = 254, /* for prereq. sections in update requests */ - ns_c_any = 255, /* Wildcard match. */ + ns_c_none = 254, /*%< for prereq. sections in update requests */ + ns_c_any = 255, /*%< Wildcard match. */ ns_c_max = 65536 } ns_class; /* DNSSEC constants. */ typedef enum __ns_key_types { - ns_kt_rsa = 1, /* key type RSA/MD5 */ - ns_kt_dh = 2, /* Diffie Hellman */ - ns_kt_dsa = 3, /* Digital Signature Standard (MANDATORY) */ - ns_kt_private = 254 /* Private key type starts with OID */ + ns_kt_rsa = 1, /*%< key type RSA/MD5 */ + ns_kt_dh = 2, /*%< Diffie Hellman */ + ns_kt_dsa = 3, /*%< Digital Signature Standard (MANDATORY) */ + ns_kt_private = 254 /*%< Private key type starts with OID */ } ns_key_types; typedef enum __ns_cert_types { - cert_t_pkix = 1, /* PKIX (X.509v3) */ - cert_t_spki = 2, /* SPKI */ - cert_t_pgp = 3, /* PGP */ - cert_t_url = 253, /* URL private type */ - cert_t_oid = 254 /* OID private type */ + cert_t_pkix = 1, /*%< PKIX (X.509v3) */ + cert_t_spki = 2, /*%< SPKI */ + cert_t_pgp = 3, /*%< PGP */ + cert_t_url = 253, /*%< URL private type */ + cert_t_oid = 254 /*%< OID private type */ } ns_cert_types; /* Flags field of the KEY RR rdata. */ -#define NS_KEY_TYPEMASK 0xC000 /* Mask for "type" bits */ -#define NS_KEY_TYPE_AUTH_CONF 0x0000 /* Key usable for both */ -#define NS_KEY_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */ -#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */ -#define NS_KEY_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */ +#define NS_KEY_TYPEMASK 0xC000 /*%< Mask for "type" bits */ +#define NS_KEY_TYPE_AUTH_CONF 0x0000 /*%< Key usable for both */ +#define NS_KEY_TYPE_CONF_ONLY 0x8000 /*%< Key usable for confidentiality */ +#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /*%< Key usable for authentication */ +#define NS_KEY_TYPE_NO_KEY 0xC000 /*%< No key usable for either; no key */ /* The type bits can also be interpreted independently, as single bits: */ -#define NS_KEY_NO_AUTH 0x8000 /* Key unusable for authentication */ -#define NS_KEY_NO_CONF 0x4000 /* Key unusable for confidentiality */ +#define NS_KEY_NO_AUTH 0x8000 /*%< Key unusable for authentication */ +#define NS_KEY_NO_CONF 0x4000 /*%< Key unusable for confidentiality */ #define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */ -#define NS_KEY_EXTENDED_FLAGS 0x1000 /* reserved - must be zero */ -#define NS_KEY_RESERVED4 0x0800 /* reserved - must be zero */ -#define NS_KEY_RESERVED5 0x0400 /* reserved - must be zero */ -#define NS_KEY_NAME_TYPE 0x0300 /* these bits determine the type */ -#define NS_KEY_NAME_USER 0x0000 /* key is assoc. with user */ -#define NS_KEY_NAME_ENTITY 0x0200 /* key is assoc. with entity eg host */ -#define NS_KEY_NAME_ZONE 0x0100 /* key is zone key */ -#define NS_KEY_NAME_RESERVED 0x0300 /* reserved meaning */ -#define NS_KEY_RESERVED8 0x0080 /* reserved - must be zero */ -#define NS_KEY_RESERVED9 0x0040 /* reserved - must be zero */ -#define NS_KEY_RESERVED10 0x0020 /* reserved - must be zero */ -#define NS_KEY_RESERVED11 0x0010 /* reserved - must be zero */ -#define NS_KEY_SIGNATORYMASK 0x000F /* key can sign RR's of same name */ +#define NS_KEY_EXTENDED_FLAGS 0x1000 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED4 0x0800 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED5 0x0400 /*%< reserved - must be zero */ +#define NS_KEY_NAME_TYPE 0x0300 /*%< these bits determine the type */ +#define NS_KEY_NAME_USER 0x0000 /*%< key is assoc. with user */ +#define NS_KEY_NAME_ENTITY 0x0200 /*%< key is assoc. with entity eg host */ +#define NS_KEY_NAME_ZONE 0x0100 /*%< key is zone key */ +#define NS_KEY_NAME_RESERVED 0x0300 /*%< reserved meaning */ +#define NS_KEY_RESERVED8 0x0080 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED9 0x0040 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED10 0x0020 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED11 0x0010 /*%< reserved - must be zero */ +#define NS_KEY_SIGNATORYMASK 0x000F /*%< key can sign RR's of same name */ #define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \ NS_KEY_RESERVED4 | \ NS_KEY_RESERVED5 | \ @@ -374,16 +377,14 @@ typedef enum __ns_cert_types { NS_KEY_RESERVED9 | \ NS_KEY_RESERVED10 | \ NS_KEY_RESERVED11 ) -#define NS_KEY_RESERVED_BITMASK2 0xFFFF /* no bits defined here */ - +#define NS_KEY_RESERVED_BITMASK2 0xFFFF /*%< no bits defined here */ /* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ -#define NS_ALG_MD5RSA 1 /* MD5 with RSA */ -#define NS_ALG_DH 2 /* Diffie Hellman KEY */ -#define NS_ALG_DSA 3 /* DSA KEY */ +#define NS_ALG_MD5RSA 1 /*%< MD5 with RSA */ +#define NS_ALG_DH 2 /*%< Diffie Hellman KEY */ +#define NS_ALG_DSA 3 /*%< DSA KEY */ #define NS_ALG_DSS NS_ALG_DSA -#define NS_ALG_EXPIRE_ONLY 253 /* No alg, no security */ -#define NS_ALG_PRIVATE_OID 254 /* Key begins with OID giving alg */ - +#define NS_ALG_EXPIRE_ONLY 253 /*%< No alg, no security */ +#define NS_ALG_PRIVATE_OID 254 /*%< Key begins with OID giving alg */ /* Protocol values */ /* value 0 is reserved */ #define NS_KEY_PROT_TLS 1 @@ -393,8 +394,8 @@ typedef enum __ns_cert_types { #define NS_KEY_PROT_ANY 255 /* Signatures */ -#define NS_MD5RSA_MIN_BITS 512 /* Size of a mod or exp in bits */ -#define NS_MD5RSA_MAX_BITS 2552 +#define NS_MD5RSA_MIN_BITS 512 /*%< Size of a mod or exp in bits */ +#define NS_MD5RSA_MAX_BITS 4096 /* Total of binary mod and exp */ #define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3) /* Max length of text sig block */ @@ -407,15 +408,14 @@ typedef enum __ns_cert_types { #define NS_DSA_MAX_BYTES 405 /* Offsets into SIG record rdata to find various values */ -#define NS_SIG_TYPE 0 /* Type flags */ -#define NS_SIG_ALG 2 /* Algorithm */ -#define NS_SIG_LABELS 3 /* How many labels in name */ -#define NS_SIG_OTTL 4 /* Original TTL */ -#define NS_SIG_EXPIR 8 /* Expiration time */ -#define NS_SIG_SIGNED 12 /* Signature time */ -#define NS_SIG_FOOT 16 /* Key footprint */ -#define NS_SIG_SIGNER 18 /* Domain name of who signed it */ - +#define NS_SIG_TYPE 0 /*%< Type flags */ +#define NS_SIG_ALG 2 /*%< Algorithm */ +#define NS_SIG_LABELS 3 /*%< How many labels in name */ +#define NS_SIG_OTTL 4 /*%< Original TTL */ +#define NS_SIG_EXPIR 8 /*%< Expiration time */ +#define NS_SIG_SIGNED 12 /*%< Signature time */ +#define NS_SIG_FOOT 16 /*%< Key footprint */ +#define NS_SIG_SIGNER 18 /*%< Domain name of who signed it */ /* How RR types are represented as bit-flags in NXT records */ #define NS_NXT_BITS 8 #define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS))) @@ -423,16 +423,17 @@ typedef enum __ns_cert_types { #define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS))) #define NS_NXT_MAX 127 -/* - * EDNS0 extended flags, host order. +/*% + * EDNS0 extended flags and option codes, host order. */ #define NS_OPT_DNSSEC_OK 0x8000U +#define NS_OPT_NSID 3 -/* +/*% * Inline versions of get/put short/long. Pointer is advanced. */ #define NS_GET16(s, cp) do { \ - register u_char *t_cp = (u_char *)(cp); \ + register const u_char *t_cp = (const u_char *)(cp); \ (s) = ((u_int16_t)t_cp[0] << 8) \ | ((u_int16_t)t_cp[1]) \ ; \ @@ -440,7 +441,7 @@ typedef enum __ns_cert_types { } while (0) #define NS_GET32(l, cp) do { \ - register u_char *t_cp = (u_char *)(cp); \ + register const u_char *t_cp = (const u_char *)(cp); \ (l) = ((u_int32_t)t_cp[0] << 24) \ | ((u_int32_t)t_cp[1] << 16) \ | ((u_int32_t)t_cp[2] << 8) \ @@ -467,43 +468,8 @@ typedef enum __ns_cert_types { (cp) += NS_INT32SZ; \ } while (0) -/* - * ANSI C identifier hiding for bind's lib/nameser. - */ -#define ns_get16 __ns_get16 -#define ns_get32 __ns_get32 -#define ns_put16 __ns_put16 -#define ns_put32 __ns_put32 -#define ns_initparse __ns_initparse -#define ns_skiprr __ns_skiprr -#define ns_parserr __ns_parserr -#define ns_sprintrr __ns_sprintrr -#define ns_sprintrrf __ns_sprintrrf -#define ns_format_ttl __ns_format_ttl -#define ns_parse_ttl __ns_parse_ttl -#define ns_datetosecs __ns_datetosecs -#define ns_name_ntol __ns_name_ntol -#define ns_name_ntop __ns_name_ntop -#define ns_name_pton __ns_name_pton -#define ns_name_unpack __ns_name_unpack -#define ns_name_pack __ns_name_pack -#define ns_name_compress __ns_name_compress -#define ns_name_uncompress __ns_name_uncompress -#define ns_name_skip __ns_name_skip -#define ns_name_rollback __ns_name_rollback -#define ns_sign __ns_sign -#define ns_sign_tcp __ns_sign_tcp -#define ns_sign_tcp_init __ns_sign_tcp_init -#define ns_find_tsig __ns_find_tsig -#define ns_verify __ns_verify -#define ns_verify_tcp __ns_verify_tcp -#define ns_verify_tcp_init __ns_verify_tcp_init -#define ns_samedomain __ns_samedomain -#define ns_subdomain __ns_subdomain -#define ns_makecanon __ns_makecanon -#define ns_samename __ns_samename - __BEGIN_DECLS +int ns_msg_getflag (ns_msg, int) __THROW; u_int ns_get16 (const u_char *) __THROW; u_long ns_get32 (const u_char *) __THROW; void ns_put16 (u_int, u_char *) __THROW; @@ -538,8 +504,14 @@ void ns_name_rollback (const u_char *, const u_char **, const u_char **) __THROW; int ns_sign (u_char *, int *, int, int, void *, const u_char *, int, u_char *, int *, time_t) __THROW; +int ns_sign2 (u_char *, int *, int, int, void *, + const u_char *, int, u_char *, int *, time_t, + u_char **, u_char **) __THROW; int ns_sign_tcp (u_char *, int *, int, int, ns_tcp_tsig_state *, int) __THROW; +int ns_sign_tcp2 (u_char *, int *, int, int, + ns_tcp_tsig_state *, int, + u_char **, u_char **) __THROW; int ns_sign_tcp_init (void *, const u_char *, int, ns_tcp_tsig_state *) __THROW; u_char *ns_find_tsig (u_char *, u_char *) __THROW; @@ -560,3 +532,4 @@ __END_DECLS #endif #endif /* !_ARPA_NAMESER_H_ */ +/*! \file */ diff --git a/resolv/arpa/nameser_compat.h b/resolv/arpa/nameser_compat.h index 8bc6e913dc..d59c9e41b3 100644 --- a/resolv/arpa/nameser_compat.h +++ b/resolv/arpa/nameser_compat.h @@ -26,7 +26,7 @@ * SUCH DAMAGE. */ -/* +/*% * from nameser.h 8.1 (Berkeley) 6/2/93 * $BINDId: nameser_compat.h,v 8.11 1999/01/02 08:00:58 vixie Exp $ */ @@ -34,11 +34,11 @@ #ifndef _ARPA_NAMESER_COMPAT_ #define _ARPA_NAMESER_COMPAT_ -#define __BIND 19950621 /* (DEAD) interface version stamp. */ +#define __BIND 19950621 /*%< (DEAD) interface version stamp. */ #include <endian.h> -/* +/*% * Structure for query header. The order of the fields is machine- and * compiler-dependent, depending on the byte/bit order and the layout * of bit fields. We use bit fields only in int variables, as this @@ -46,40 +46,40 @@ */ typedef struct { - unsigned id :16; /* query identification number */ + unsigned id :16; /*%< query identification number */ #if BYTE_ORDER == BIG_ENDIAN /* fields in third byte */ - unsigned qr: 1; /* response flag */ - unsigned opcode: 4; /* purpose of message */ - unsigned aa: 1; /* authoritive answer */ - unsigned tc: 1; /* truncated message */ - unsigned rd: 1; /* recursion desired */ + unsigned qr: 1; /*%< response flag */ + unsigned opcode: 4; /*%< purpose of message */ + unsigned aa: 1; /*%< authoritive answer */ + unsigned tc: 1; /*%< truncated message */ + unsigned rd: 1; /*%< recursion desired */ /* fields in fourth byte */ - unsigned ra: 1; /* recursion available */ - unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ - unsigned ad: 1; /* authentic data from named */ - unsigned cd: 1; /* checking disabled by resolver */ - unsigned rcode :4; /* response code */ + unsigned ra: 1; /*%< recursion available */ + unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ + unsigned ad: 1; /*%< authentic data from named */ + unsigned cd: 1; /*%< checking disabled by resolver */ + unsigned rcode :4; /*%< response code */ #endif #if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN /* fields in third byte */ - unsigned rd :1; /* recursion desired */ - unsigned tc :1; /* truncated message */ - unsigned aa :1; /* authoritive answer */ - unsigned opcode :4; /* purpose of message */ - unsigned qr :1; /* response flag */ + unsigned rd :1; /*%< recursion desired */ + unsigned tc :1; /*%< truncated message */ + unsigned aa :1; /*%< authoritive answer */ + unsigned opcode :4; /*%< purpose of message */ + unsigned qr :1; /*%< response flag */ /* fields in fourth byte */ - unsigned rcode :4; /* response code */ - unsigned cd: 1; /* checking disabled by resolver */ - unsigned ad: 1; /* authentic data from named */ - unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ - unsigned ra :1; /* recursion available */ + unsigned rcode :4; /*%< response code */ + unsigned cd: 1; /*%< checking disabled by resolver */ + unsigned ad: 1; /*%< authentic data from named */ + unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ + unsigned ra :1; /*%< recursion available */ #endif /* remaining bytes */ - unsigned qdcount :16; /* number of question entries */ - unsigned ancount :16; /* number of answer entries */ - unsigned nscount :16; /* number of authority entries */ - unsigned arcount :16; /* number of resource entries */ + unsigned qdcount :16; /*%< number of question entries */ + unsigned ancount :16; /*%< number of answer entries */ + unsigned nscount :16; /*%< number of authority entries */ + unsigned arcount :16; /*%< number of resource entries */ } HEADER; #define PACKETSZ NS_PACKETSZ @@ -91,6 +91,7 @@ typedef struct { #define RRFIXEDSZ NS_RRFIXEDSZ #define INT32SZ NS_INT32SZ #define INT16SZ NS_INT16SZ +#define INT8SZ NS_INT8SZ #define INADDRSZ NS_INADDRSZ #define IN6ADDRSZ NS_IN6ADDRSZ #define INDIR_MASK NS_CMPRSFLGS @@ -161,6 +162,7 @@ typedef struct { #define T_SRV ns_t_srv #define T_ATMA ns_t_atma #define T_NAPTR ns_t_naptr +#define T_A6 ns_t_a6 #define T_DNAME ns_t_dname #define T_TSIG ns_t_tsig #define T_IXFR ns_t_ixfr @@ -182,3 +184,4 @@ typedef struct { #define PUTLONG NS_PUT32 #endif /* _ARPA_NAMESER_COMPAT_ */ +/*! \file */ diff --git a/resolv/ns_date.c b/resolv/ns_date.c new file mode 100644 index 0000000000..9801ac46d4 --- /dev/null +++ b/resolv/ns_date.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if !defined(_LIBC) && !defined(lint) +static const char rcsid[] = "$Id$"; +#endif + +/* Import. */ + +#include <arpa/nameser.h> + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <time.h> + +#define SPRINTF(x) ((size_t)sprintf x) + +/* Forward. */ + +static int datepart(const char *, int, int, int, int *); + +/* Public. */ + +/*% + * Convert a date in ASCII into the number of seconds since + * 1 January 1970 (GMT assumed). Format is yyyymmddhhmmss, all + * digits required, no spaces allowed. + */ + +u_int32_t +ns_datetosecs(const char *cp, int *errp) { + struct tm time; + u_int32_t result; + int mdays, i; + static const int days_per_month[12] = + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + if (strlen(cp) != 14U) { + *errp = 1; + return (0); + } + *errp = 0; + + memset(&time, 0, sizeof time); + time.tm_year = datepart(cp + 0, 4, 1990, 9999, errp) - 1900; + time.tm_mon = datepart(cp + 4, 2, 01, 12, errp) - 1; + time.tm_mday = datepart(cp + 6, 2, 01, 31, errp); + time.tm_hour = datepart(cp + 8, 2, 00, 23, errp); + time.tm_min = datepart(cp + 10, 2, 00, 59, errp); + time.tm_sec = datepart(cp + 12, 2, 00, 59, errp); + if (*errp) /*%< Any parse errors? */ + return (0); + + /* + * OK, now because timegm() is not available in all environments, + * we will do it by hand. Roll up sleeves, curse the gods, begin! + */ + +#define SECS_PER_DAY ((u_int32_t)24*60*60) +#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) + + result = time.tm_sec; /*%< Seconds */ + result += time.tm_min * 60; /*%< Minutes */ + result += time.tm_hour * (60*60); /*%< Hours */ + result += (time.tm_mday - 1) * SECS_PER_DAY; /*%< Days */ + /* Months are trickier. Look without leaping, then leap */ + mdays = 0; + for (i = 0; i < time.tm_mon; i++) + mdays += days_per_month[i]; + result += mdays * SECS_PER_DAY; /*%< Months */ + if (time.tm_mon > 1 && isleap(1900+time.tm_year)) + result += SECS_PER_DAY; /*%< Add leapday for this year */ + /* First figure years without leapdays, then add them in. */ + /* The loop is slow, FIXME, but simple and accurate. */ + result += (time.tm_year - 70) * (SECS_PER_DAY*365); /*%< Years */ + for (i = 70; i < time.tm_year; i++) + if (isleap(1900+i)) + result += SECS_PER_DAY; /*%< Add leapday for prev year */ + return (result); +} + +/* Private. */ + +/*% + * Parse part of a date. Set error flag if any error. + * Don't reset the flag if there is no error. + */ +static int +datepart(const char *buf, int size, int min, int max, int *errp) { + int result = 0; + int i; + + for (i = 0; i < size; i++) { + if (!isdigit((unsigned char)(buf[i]))) + *errp = 1; + result = (result * 10) + buf[i] - '0'; + } + if (result < min) + *errp = 1; + if (result > max) + *errp = 1; + return (result); +} + +/*! \file */ diff --git a/resolv/ns_name.c b/resolv/ns_name.c index ed361915d8..adf64bbd9a 100644 --- a/resolv/ns_name.c +++ b/resolv/ns_name.c @@ -1,18 +1,18 @@ /* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #if !defined(_LIBC) && !defined(lint) @@ -24,16 +24,41 @@ static const char rcsid[] = "$BINDId: ns_name.c,v 8.15 2000/03/30 22:53:46 vixie #include <netinet/in.h> #include <arpa/nameser.h> -#include <ctype.h> #include <errno.h> #include <resolv.h> #include <string.h> #include <ctype.h> +#include <stdlib.h> +#include <limits.h> + +# define SPRINTF(x) ((size_t)sprintf x) + +#define NS_TYPE_ELT 0x40 /*%< EDNS0 extended label type */ +#define DNS_LABELTYPE_BITSTRING 0x41 /* Data. */ static const char digits[] = "0123456789"; +static const char digitvalue[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/ + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/ + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/ +}; + /* Forward. */ static int special(int); @@ -41,31 +66,40 @@ static int printable(int); static int dn_find(const u_char *, const u_char *, const u_char * const *, const u_char * const *); +static int encode_bitstring(const char **, const char *, + unsigned char **, unsigned char **, + unsigned const char *); +static int labellen(const u_char *); +static int decode_bitstring(const unsigned char **, + char *, const char *); /* Public. */ -/* - * ns_name_ntop(src, dst, dstsiz) +/*% * Convert an encoded domain name to printable ascii as per RFC1035. + * return: - * Number of bytes written to buffer, or -1 (with errno set) + *\li Number of bytes written to buffer, or -1 (with errno set) + * * notes: - * The root is returned as "." - * All other domains are returned in non absolute form + *\li The root is returned as "." + *\li All other domains are returned in non absolute form */ int -ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) { +ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) +{ const u_char *cp; char *dn, *eom; u_char c; u_int n; + int l; cp = src; dn = dst; eom = dst + dstsiz; while ((n = *cp++) != 0) { - if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) { + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { /* Some kind of compression pointer. */ __set_errno (EMSGSIZE); return (-1); @@ -77,34 +111,31 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) { } *dn++ = '.'; } + if ((l = labellen(cp - 1)) < 0) { + __set_errno (EMSGSIZE); + return(-1); + } + if (dn + l >= eom) { + __set_errno (EMSGSIZE); + return (-1); + } + if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) { + int m; - if (n == 0x41) { - n = *cp++ / 8; - if (dn + n * 2 + 4 >= eom) { - __set_errno (EMSGSIZE); - return (-1); + if (n != DNS_LABELTYPE_BITSTRING) { + /* XXX: labellen should reject this case */ + __set_errno (EINVAL); + return(-1); } - *dn++ = '\\'; - *dn++ = '['; - *dn++ = 'x'; - - while (n-- > 0) { - c = *cp++; - unsigned u = c >> 4; - *dn++ = u > 9 ? 'a' + u - 10 : '0' + u; - u = c & 0xf; - *dn++ = u > 9 ? 'a' + u - 10 : '0' + u; + if ((m = decode_bitstring(&cp, dn, eom)) < 0) + { + __set_errno (EMSGSIZE); + return(-1); } - - *dn++ = ']'; + dn += m; continue; } - - if (dn + n >= eom) { - __set_errno (EMSGSIZE); - return (-1); - } - for ((void)NULL; n > 0; n--) { + for ((void)NULL; l > 0; l--) { c = *cp++; if (special(c)) { if (dn + 1 >= eom) { @@ -146,22 +177,26 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) { return (dn - dst); } libresolv_hidden_def (ns_name_ntop) +strong_alias (ns_name_ntop, __ns_name_ntop) -/* - * ns_name_pton(src, dst, dstsiz) +/*% * Convert a ascii string into an encoded domain name as per RFC1035. + * * return: - * -1 if it fails - * 1 if string was fully qualified - * 0 is string was not fully qualified + * + *\li -1 if it fails + *\li 1 if string was fully qualified + *\li 0 is string was not fully qualified + * * notes: - * Enforces label and domain length limits. + *\li Enforces label and domain length limits. */ int -ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { +ns_name_pton(const char *src, u_char *dst, size_t dstsiz) +{ u_char *label, *bp, *eom; - int c, n, escaped; + int c, n, escaped, e = 0; char *cp; escaped = 0; @@ -171,7 +206,28 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { while ((c = *src++) != 0) { if (escaped) { - if ((cp = strchr(digits, c)) != NULL) { + if (c == '[') { /*%< start a bit string label */ + if ((cp = strchr(src, ']')) == NULL) { + __set_errno (EINVAL); + return(-1); + } + if ((e = encode_bitstring(&src, cp + 2, + &label, &bp, eom)) + != 0) { + __set_errno (e); + return(-1); + } + escaped = 0; + label = bp++; + if ((c = *src++) == 0) + goto done; + else if (c != '.') { + __set_errno (EINVAL); + return(-1); + } + continue; + } + else if ((cp = strchr(digits, c)) != NULL) { n = (cp - digits) * 100; if ((c = *src++) == 0 || (cp = strchr(digits, c)) == NULL) { @@ -190,41 +246,6 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { return (-1); } c = n; - } else if (c == '[' && label == bp - 1 && *src == 'x') { - /* Theoretically we would have to handle \[o - as well but we do not since we do not need - it internally. */ - *label = 0x41; - label = bp++; - ++src; - while (isxdigit (*src)) { - n = *src > '9' ? *src - 'a' + 10 : *src - '0'; - ++src; - if (! isxdigit(*src)) { - __set_errno (EMSGSIZE); - return (-1); - } - n <<= 4; - n += *src > '9' ? *src - 'a' + 10 : *src - '0'; - if (bp + 1 >= eom) { - __set_errno (EMSGSIZE); - return (-1); - } - *bp++ = n; - ++src; - } - *label = (bp - label - 1) * 8; - if (*src++ != ']' || *src++ != '.') { - __set_errno (EMSGSIZE); - return (-1); - } - escaped = 0; - label = bp++; - if (bp >= eom) { - __set_errno (EMSGSIZE); - return (-1); - } - continue; } escaped = 0; } else if (c == '\\') { @@ -232,7 +253,7 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { continue; } else if (c == '.') { c = (bp - label - 1); - if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */ + if ((c & NS_CMPRSFLGS) != 0) { /*%< Label too big. */ __set_errno (EMSGSIZE); return (-1); } @@ -270,10 +291,11 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { *bp++ = (u_char)c; } c = (bp - label - 1); - if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */ + if ((c & NS_CMPRSFLGS) != 0) { /*%< Label too big. */ __set_errno (EMSGSIZE); return (-1); } + done: if (label >= eom) { __set_errno (EMSGSIZE); return (-1); @@ -286,45 +308,57 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { } *bp++ = 0; } - if ((bp - dst) > MAXCDNAME) { /* src too big */ + if ((bp - dst) > MAXCDNAME) { /*%< src too big */ __set_errno (EMSGSIZE); return (-1); } return (0); } +libresolv_hidden_def (ns_name_pton) -/* - * ns_name_ntol(src, dst, dstsiz) +/*% * Convert a network strings labels into all lowercase. + * * return: - * Number of bytes written to buffer, or -1 (with errno set) + *\li Number of bytes written to buffer, or -1 (with errno set) + * * notes: - * Enforces label and domain length limits. + *\li Enforces label and domain length limits. */ int -ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) { +ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) +{ const u_char *cp; u_char *dn, *eom; u_char c; u_int n; + int l; cp = src; dn = dst; eom = dst + dstsiz; + if (dn >= eom) { + __set_errno (EMSGSIZE); + return (-1); + } while ((n = *cp++) != 0) { - if ((n & NS_CMPRSFLGS) != 0) { + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { /* Some kind of compression pointer. */ __set_errno (EMSGSIZE); return (-1); } *dn++ = n; - if (dn + n >= eom) { + if ((l = labellen(cp - 1)) < 0) { __set_errno (EMSGSIZE); return (-1); } - for ((void)NULL; n > 0; n--) { + if (dn + l >= eom) { + __set_errno (EMSGSIZE); + return (-1); + } + for ((void)NULL; l > 0; l--) { c = *cp++; if (isupper(c)) *dn++ = tolower(c); @@ -336,11 +370,11 @@ ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) { return (dn - dst); } -/* - * ns_name_unpack(msg, eom, src, dst, dstsiz) +/*% * Unpack a domain name from a message, source may be compressed. + * * return: - * -1 if it fails, or consumed octets if it succeeds. + *\li -1 if it fails, or consumed octets if it succeeds. */ int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, @@ -348,7 +382,7 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, { const u_char *srcp, *dstlim; u_char *dstp; - int n, len, checked; + int n, len, checked, l; len = -1; checked = 0; @@ -363,29 +397,22 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, while ((n = *srcp++) != 0) { /* Check for indirection. */ switch (n & NS_CMPRSFLGS) { - case 0x40: - if (n == 0x41) { - if (dstp + 1 >= dstlim) { - __set_errno (EMSGSIZE); - return (-1); - } - *dstp++ = 0x41; - n = *srcp++ / 8; - ++checked; - } else { - __set_errno (EMSGSIZE); - return (-1); /* flag error */ - } - /* FALLTHROUGH */ case 0: + case NS_TYPE_ELT: /* Limit checks. */ - if (dstp + n + 1 >= dstlim || srcp + n >= eom) { + if ((l = labellen(srcp - 1)) < 0) { + __set_errno (EMSGSIZE); + return(-1); + } + if (dstp + l + 1 >= dstlim || srcp + l >= eom) { __set_errno (EMSGSIZE); return (-1); } - checked += n + 1; - dstp = mempcpy(dstp, srcp - 1, n + 1); - srcp += n; + checked += l + 1; + *dstp++ = n; + memcpy(dstp, srcp, l); + dstp += l; + srcp += l; break; case NS_CMPRSFLGS: @@ -396,7 +423,7 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, if (len < 0) len = srcp - src + 1; srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff)); - if (srcp < msg || srcp >= eom) { /* Out of range. */ + if (srcp < msg || srcp >= eom) { /*%< Out of range. */ __set_errno (EMSGSIZE); return (-1); } @@ -414,7 +441,7 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, default: __set_errno (EMSGSIZE); - return (-1); /* flag error */ + return (-1); /*%< flag error */ } } *dstp = '\0'; @@ -423,20 +450,23 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, return (len); } libresolv_hidden_def (ns_name_unpack) +strong_alias (ns_name_unpack, __ns_name_unpack) -/* - * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr) +/*% * Pack domain name 'domain' into 'comp_dn'. + * * return: - * Size of the compressed name, or -1. + *\li Size of the compressed name, or -1. + * * notes: - * 'dnptrs' is an array of pointers to previous compressed names. - * dnptrs[0] is a pointer to the beginning of the message. The array + *\li 'dnptrs' is an array of pointers to previous compressed names. + *\li dnptrs[0] is a pointer to the beginning of the message. The array * ends with NULL. - * 'lastdnptr' is a pointer to the end of the array pointed to + *\li 'lastdnptr' is a pointer to the end of the array pointed to * by 'dnptrs'. + * * Side effects: - * The list of pointers in dnptrs is updated for labels inserted into + *\li The list of pointers in dnptrs is updated for labels inserted into * the message as we compress the name. If 'dnptr' is NULL, we don't * try to compress names. If 'lastdnptr' is NULL, we don't update the * list. @@ -458,7 +488,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, if ((msg = *dnptrs++) != NULL) { for (cpp = dnptrs; *cpp != NULL; cpp++) (void)NULL; - lpp = cpp; /* end of list to search */ + lpp = cpp; /*%< end of list to search */ } } else msg = NULL; @@ -466,19 +496,23 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, /* make sure the domain we are about to add is legal */ l = 0; do { + int l0; + n = *srcp; - if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) { + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { __set_errno (EMSGSIZE); return (-1); } - if (n == 0x41) - n = *++srcp / 8; - l += n + 1; + if ((l0 = labellen(srcp)) < 0) { + __set_errno (EINVAL); + return(-1); + } + l += l0 + 1; if (l > MAXCDNAME) { __set_errno (EMSGSIZE); return (-1); } - srcp += n + 1; + srcp += l0 + 1; } while (n != 0); /* from here on we need to reset compression pointer array on error */ @@ -486,7 +520,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, do { /* Look to see if we can use pointers. */ n = *srcp; - if (n != 0 && n != 0x41 && msg != NULL) { + if (n != 0 && msg != NULL) { l = dn_find(srcp, msg, (const u_char * const *)dnptrs, (const u_char * const *)lpp); if (l >= 0) { @@ -506,15 +540,11 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, } } /* copy label to buffer */ - if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) { /* Should not happen. */ + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { + /* Should not happen. */ goto cleanup; } - if (n == 0x41) { - n = *++srcp / 8; - if (dstp + 1 >= eob) - goto cleanup; - *dstp++ = 0x41; - } + n = labellen(srcp); if (dstp + 1 + n >= eob) { goto cleanup; } @@ -532,14 +562,16 @@ cleanup: } return (dstp - dst); } +libresolv_hidden_def (ns_name_pack) -/* - * ns_name_uncompress(msg, eom, src, dst, dstsiz) +/*% * Expand compressed domain name to presentation format. + * * return: - * Number of bytes read out of `src', or -1 (with errno set). + *\li Number of bytes read out of `src', or -1 (with errno set). + * * note: - * Root domain returns as "." not "". + *\li Root domain returns as "." not "". */ int ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src, @@ -554,19 +586,21 @@ ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src, return (-1); return (n); } +libresolv_hidden_def (ns_name_uncompress) -/* - * ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr) +/*% * Compress a domain name into wire format, using compression pointers. + * * return: - * Number of bytes consumed in `dst' or -1 (with errno set). + *\li Number of bytes consumed in `dst' or -1 (with errno set). + * * notes: - * 'dnptrs' is an array of pointers to previous compressed names. - * dnptrs[0] is a pointer to the beginning of the message. - * The list ends with NULL. 'lastdnptr' is a pointer to the end of the + *\li 'dnptrs' is an array of pointers to previous compressed names. + *\li dnptrs[0] is a pointer to the beginning of the message. + *\li The list ends with NULL. 'lastdnptr' is a pointer to the end of the * array pointed to by 'dnptrs'. Side effect is to update the list of * pointers for labels inserted into the message as we compress the name. - * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' + *\li If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' * is NULL, we don't update the list. */ int @@ -579,8 +613,9 @@ ns_name_compress(const char *src, u_char *dst, size_t dstsiz, return (-1); return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr)); } +libresolv_hidden_def (ns_name_compress) -/* +/*% * Reset dnptrs so that there are no active references to pointers at or * after src. */ @@ -597,28 +632,37 @@ ns_name_rollback(const u_char *src, const u_char **dnptrs, } } -/* - * ns_name_skip(ptrptr, eom) +/*% * Advance *ptrptr to skip over the compressed name it points at. + * * return: - * 0 on success, -1 (with errno set) on failure. + *\li 0 on success, -1 (with errno set) on failure. */ int -ns_name_skip(const u_char **ptrptr, const u_char *eom) { +ns_name_skip(const u_char **ptrptr, const u_char *eom) +{ const u_char *cp; u_int n; + int l; cp = *ptrptr; while (cp < eom && (n = *cp++) != 0) { /* Check for indirection. */ switch (n & NS_CMPRSFLGS) { - case 0: /* normal case, n == len */ + case 0: /*%< normal case, n == len */ cp += n; continue; - case NS_CMPRSFLGS: /* indirection */ + case NS_TYPE_ELT: /*%< EDNS0 extended label */ + if ((l = labellen(cp - 1)) < 0) { + __set_errno (EMSGSIZE); + return(-1); + } + cp += l; + continue; + case NS_CMPRSFLGS: /*%< indirection */ cp++; break; - default: /* illegal type */ + default: /*%< illegal type */ __set_errno (EMSGSIZE); return (-1); } @@ -631,45 +675,48 @@ ns_name_skip(const u_char **ptrptr, const u_char *eom) { *ptrptr = cp; return (0); } +libresolv_hidden_def (ns_name_skip) /* Private. */ -/* - * special(ch) +/*% * Thinking in noninternationalized USASCII (per the DNS spec), * is this characted special ("in need of quoting") ? + * * return: - * boolean. + *\li boolean. */ static int special(int ch) { switch (ch) { - case 0x22: /* '"' */ - case 0x2E: /* '.' */ - case 0x3B: /* ';' */ - case 0x5C: /* '\\' */ + case 0x22: /*%< '"' */ + case 0x2E: /*%< '.' */ + case 0x3B: /*%< ';' */ + case 0x5C: /*%< '\\' */ + case 0x28: /*%< '(' */ + case 0x29: /*%< ')' */ /* Special modifiers in zone files. */ - case 0x40: /* '@' */ - case 0x24: /* '$' */ + case 0x40: /*%< '@' */ + case 0x24: /*%< '$' */ return (1); default: return (0); } } -/* - * printable(ch) +/*% * Thinking in noninternationalized USASCII (per the DNS spec), * is this character visible and not a space when printed ? + * * return: - * boolean. + *\li boolean. */ static int printable(int ch) { return (ch > 0x20 && ch < 0x7f); } -/* +/*% * Thinking in noninternationalized USASCII (per the DNS spec), * convert this character to lower case if it's upper case. */ @@ -680,14 +727,15 @@ mklower(int ch) { return (ch); } -/* - * dn_find(domain, msg, dnptrs, lastdnptr) +/*% * Search for the counted-label name in an array of compressed names. + * * return: - * offset from msg if found, or -1. + *\li offset from msg if found, or -1. + * * notes: - * dnptrs is the pointer to the first name on the list, - * not the pointer to the start of the message. + *\li dnptrs is the pointer to the first name on the list, + *\li not the pointer to the start of the message. */ static int dn_find(const u_char *domain, const u_char *msg, @@ -715,9 +763,11 @@ dn_find(const u_char *domain, const u_char *msg, * check for indirection */ switch (n & NS_CMPRSFLGS) { - case 0: /* normal case, n == len */ + case 0: /*%< normal case, n == len */ + n = labellen(cp - 1); /*%< XXX */ if (n != *dn++) goto next; + for ((void)NULL; n > 0; n--) if (mklower(*dn++) != mklower(*cp++)) @@ -728,20 +778,197 @@ dn_find(const u_char *domain, const u_char *msg, if (*dn) continue; goto next; - - case NS_CMPRSFLGS: /* indirection */ + case NS_CMPRSFLGS: /*%< indirection */ cp = msg + (((n & 0x3f) << 8) | *cp); break; - default: /* illegal type */ + default: /*%< illegal type */ __set_errno (EMSGSIZE); return (-1); } } - next: + next: ; sp += *sp + 1; } } __set_errno (ENOENT); return (-1); } + +static int +decode_bitstring(const unsigned char **cpp, char *dn, const char *eom) +{ + const unsigned char *cp = *cpp; + char *beg = dn, tc; + int b, blen, plen, i; + + if ((blen = (*cp & 0xff)) == 0) + blen = 256; + plen = (blen + 3) / 4; + plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1); + if (dn + plen >= eom) + return(-1); + + cp++; + i = SPRINTF((dn, "\\[x")); + if (i < 0) + return (-1); + dn += i; + for (b = blen; b > 7; b -= 8, cp++) { + i = SPRINTF((dn, "%02x", *cp & 0xff)); + if (i < 0) + return (-1); + dn += i; + } + if (b > 4) { + tc = *cp++; + i = SPRINTF((dn, "%02x", tc & (0xff << (8 - b)))); + if (i < 0) + return (-1); + dn += i; + } else if (b > 0) { + tc = *cp++; + i = SPRINTF((dn, "%1x", + ((tc >> 4) & 0x0f) & (0x0f << (4 - b)))); + if (i < 0) + return (-1); + dn += i; + } + i = SPRINTF((dn, "/%d]", blen)); + if (i < 0) + return (-1); + dn += i; + + *cpp = cp; + return(dn - beg); +} + +static int +encode_bitstring(const char **bp, const char *end, unsigned char **labelp, + unsigned char ** dst, unsigned const char *eom) +{ + int afterslash = 0; + const char *cp = *bp; + unsigned char *tp; + char c; + const char *beg_blen; + char *end_blen = NULL; + int value = 0, count = 0, tbcount = 0, blen = 0; + + beg_blen = end_blen = NULL; + + /* a bitstring must contain at least 2 characters */ + if (end - cp < 2) + return(EINVAL); + + /* XXX: currently, only hex strings are supported */ + if (*cp++ != 'x') + return(EINVAL); + if (!isxdigit((*cp) & 0xff)) /*%< reject '\[x/BLEN]' */ + return(EINVAL); + + for (tp = *dst + 1; cp < end && tp < eom; cp++) { + switch((c = *cp)) { + case ']': /*%< end of the bitstring */ + if (afterslash) { + if (beg_blen == NULL) + return(EINVAL); + blen = (int)strtol(beg_blen, &end_blen, 10); + if (*end_blen != ']') + return(EINVAL); + } + if (count) + *tp++ = ((value << 4) & 0xff); + cp++; /*%< skip ']' */ + goto done; + case '/': + afterslash = 1; + break; + default: + if (afterslash) { + if (!isdigit(c&0xff)) + return(EINVAL); + if (beg_blen == NULL) { + + if (c == '0') { + /* blen never begings with 0 */ + return(EINVAL); + } + beg_blen = cp; + } + } else { + if (!isxdigit(c&0xff)) + return(EINVAL); + value <<= 4; + value += digitvalue[(int)c]; + count += 4; + tbcount += 4; + if (tbcount > 256) + return(EINVAL); + if (count == 8) { + *tp++ = value; + count = 0; + } + } + break; + } + } + done: + if (cp >= end || tp >= eom) + return(EMSGSIZE); + + /* + * bit length validation: + * If a <length> is present, the number of digits in the <bit-data> + * MUST be just sufficient to contain the number of bits specified + * by the <length>. If there are insignificant bits in a final + * hexadecimal or octal digit, they MUST be zero. + * RFC2673, Section 3.2. + */ + if (blen > 0) { + int traillen; + + if (((blen + 3) & ~3) != tbcount) + return(EINVAL); + traillen = tbcount - blen; /*%< between 0 and 3 */ + if (((value << (8 - traillen)) & 0xff) != 0) + return(EINVAL); + } + else + blen = tbcount; + if (blen == 256) + blen = 0; + + /* encode the type and the significant bit fields */ + **labelp = DNS_LABELTYPE_BITSTRING; + **dst = blen; + + *bp = cp; + *dst = tp; + + return(0); +} + +static int +labellen(const u_char *lp) +{ + int bitlen; + u_char l = *lp; + + if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) { + /* should be avoided by the caller */ + return(-1); + } + + if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) { + if (l == DNS_LABELTYPE_BITSTRING) { + if ((bitlen = *(lp + 1)) == 0) + bitlen = 256; + return((bitlen + 7 ) / 8 + 1); + } + return(-1); /*%< unknwon ELT */ + } + return(l); +} + +/*! \file */ diff --git a/resolv/ns_netint.c b/resolv/ns_netint.c index 20ecf626d8..4318f18879 100644 --- a/resolv/ns_netint.c +++ b/resolv/ns_netint.c @@ -1,18 +1,18 @@ /* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #if !defined(_LIBC) && !defined(lint) @@ -34,6 +34,7 @@ ns_get16(const u_char *src) { return (dst); } libresolv_hidden_def (ns_get16) +strong_alias (ns_get16, __ns_get16) u_long ns_get32(const u_char *src) { @@ -43,13 +44,18 @@ ns_get32(const u_char *src) { return (dst); } libresolv_hidden_def (ns_get32) +strong_alias (ns_get32, __ns_get32) void ns_put16(u_int src, u_char *dst) { NS_PUT16(src, dst); } +libresolv_hidden_def (ns_put16) void ns_put32(u_long src, u_char *dst) { NS_PUT32(src, dst); } +libresolv_hidden_def (ns_put32) + +/*! \file */ diff --git a/resolv/ns_parse.c b/resolv/ns_parse.c index d305eae535..712469be1d 100644 --- a/resolv/ns_parse.c +++ b/resolv/ns_parse.c @@ -1,18 +1,18 @@ /* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #if !defined(_LIBC) && !defined(lint) @@ -41,25 +41,30 @@ static void setsection(ns_msg *msg, ns_sect sect); /* Public. */ /* These need to be in the same order as the nres.h:ns_flag enum. */ -struct _ns_flagdata _ns_flagdata[16] = { - { 0x8000, 15 }, /* qr. */ - { 0x7800, 11 }, /* opcode. */ - { 0x0400, 10 }, /* aa. */ - { 0x0200, 9 }, /* tc. */ - { 0x0100, 8 }, /* rd. */ - { 0x0080, 7 }, /* ra. */ - { 0x0040, 6 }, /* z. */ - { 0x0020, 5 }, /* ad. */ - { 0x0010, 4 }, /* cd. */ - { 0x000f, 0 }, /* rcode. */ - { 0x0000, 0 }, /* expansion (1/6). */ - { 0x0000, 0 }, /* expansion (2/6). */ - { 0x0000, 0 }, /* expansion (3/6). */ - { 0x0000, 0 }, /* expansion (4/6). */ - { 0x0000, 0 }, /* expansion (5/6). */ - { 0x0000, 0 }, /* expansion (6/6). */ +const struct _ns_flagdata _ns_flagdata[16] = { + { 0x8000, 15 }, /*%< qr. */ + { 0x7800, 11 }, /*%< opcode. */ + { 0x0400, 10 }, /*%< aa. */ + { 0x0200, 9 }, /*%< tc. */ + { 0x0100, 8 }, /*%< rd. */ + { 0x0080, 7 }, /*%< ra. */ + { 0x0040, 6 }, /*%< z. */ + { 0x0020, 5 }, /*%< ad. */ + { 0x0010, 4 }, /*%< cd. */ + { 0x000f, 0 }, /*%< rcode. */ + { 0x0000, 0 }, /*%< expansion (1/6). */ + { 0x0000, 0 }, /*%< expansion (2/6). */ + { 0x0000, 0 }, /*%< expansion (3/6). */ + { 0x0000, 0 }, /*%< expansion (4/6). */ + { 0x0000, 0 }, /*%< expansion (5/6). */ + { 0x0000, 0 }, /*%< expansion (6/6). */ }; +#undef ns_msg_getflag +int ns_msg_getflag(ns_msg handle, int flag) { + return(((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift); +} + int ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) { const u_char *optr = ptr; @@ -83,6 +88,7 @@ ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) { RETERR(EMSGSIZE); return (ptr - optr); } +libresolv_hidden_def (ns_skiprr) int ns_initparse(const u_char *msg, int msglen, ns_msg *handle) { @@ -120,13 +126,16 @@ ns_initparse(const u_char *msg, int msglen, ns_msg *handle) { setsection(handle, ns_s_max); return (0); } +libresolv_hidden_def (ns_initparse) int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) { int b; + int tmp; /* Make section right. */ - if (section < 0 || section >= ns_s_max) + tmp = section; + if (tmp < 0 || section >= ns_s_max) RETERR(ENODEV); if (section != handle->_sect) setsection(handle, section); @@ -139,38 +148,38 @@ ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) { if (rrnum < handle->_rrnum) setsection(handle, section); if (rrnum > handle->_rrnum) { - b = ns_skiprr(handle->_ptr, handle->_eom, section, + b = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum); if (b < 0) return (-1); - handle->_ptr += b; + handle->_msg_ptr += b; handle->_rrnum = rrnum; } /* Do the parse. */ b = dn_expand(handle->_msg, handle->_eom, - handle->_ptr, rr->name, NS_MAXDNAME); + handle->_msg_ptr, rr->name, NS_MAXDNAME); if (b < 0) return (-1); - handle->_ptr += b; - if (handle->_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom) + handle->_msg_ptr += b; + if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom) RETERR(EMSGSIZE); - NS_GET16(rr->type, handle->_ptr); - NS_GET16(rr->rr_class, handle->_ptr); + NS_GET16(rr->type, handle->_msg_ptr); + NS_GET16(rr->rr_class, handle->_msg_ptr); if (section == ns_s_qd) { rr->ttl = 0; rr->rdlength = 0; rr->rdata = NULL; } else { - if (handle->_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom) + if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom) RETERR(EMSGSIZE); - NS_GET32(rr->ttl, handle->_ptr); - NS_GET16(rr->rdlength, handle->_ptr); - if (handle->_ptr + rr->rdlength > handle->_eom) + NS_GET32(rr->ttl, handle->_msg_ptr); + NS_GET16(rr->rdlength, handle->_msg_ptr); + if (handle->_msg_ptr + rr->rdlength > handle->_eom) RETERR(EMSGSIZE); - rr->rdata = handle->_ptr; - handle->_ptr += rr->rdlength; + rr->rdata = handle->_msg_ptr; + handle->_msg_ptr += rr->rdlength; } if (++handle->_rrnum > handle->_counts[(int)section]) setsection(handle, (ns_sect)((int)section + 1)); @@ -178,6 +187,7 @@ ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) { /* All done. */ return (0); } +libresolv_hidden_def (ns_parserr) /* Private. */ @@ -186,9 +196,11 @@ setsection(ns_msg *msg, ns_sect sect) { msg->_sect = sect; if (sect == ns_s_max) { msg->_rrnum = -1; - msg->_ptr = NULL; + msg->_msg_ptr = NULL; } else { msg->_rrnum = 0; - msg->_ptr = msg->_sections[(int)sect]; + msg->_msg_ptr = msg->_sections[(int)sect]; } } + +/*! \file */ diff --git a/resolv/ns_print.c b/resolv/ns_print.c index b0b7a1046e..36d39784a5 100644 --- a/resolv/ns_print.c +++ b/resolv/ns_print.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -34,11 +35,7 @@ static const char rcsid[] = "$BINDId: ns_print.c,v 8.18 2000/02/29 05:48:12 vixi #include <string.h> #include <ctype.h> -#ifdef SPRINTF_CHAR -# define SPRINTF(x) strlen(sprintf/**/x) -#else -# define SPRINTF(x) ((size_t)sprintf x) -#endif +#define SPRINTF(x) ((size_t)sprintf x) /* Forward. */ @@ -54,11 +51,7 @@ static int addstr(const char *src, size_t len, static int addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen); -/* Proto. */ - -#ifndef _LIBC -u_int16_t dst_s_dns_key_id(const u_char *, const int); -#endif +static u_int16_t dst_s_dns_key_id(const u_char *, const int); /* Macros. */ @@ -70,12 +63,11 @@ u_int16_t dst_s_dns_key_id(const u_char *, const int); /* Public. */ -/* - * int - * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen) +/*% * Convert an RR to presentation format. + * * return: - * Number of characters written to buf, or -1 (check errno). + *\li Number of characters written to buf, or -1 (check errno). */ int ns_sprintrr(const ns_msg *handle, const ns_rr *rr, @@ -90,14 +82,13 @@ ns_sprintrr(const ns_msg *handle, const ns_rr *rr, name_ctx, origin, buf, buflen); return (n); } +libresolv_hidden_def (ns_sprintrr) -/* - * int - * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen, - * name_ctx, origin, buf, buflen) +/*% * Convert the fields of an RR into presentation format. + * * return: - * Number of characters written to buf, or -1 (check errno). + *\li Number of characters written to buf, or -1 (check errno). */ int ns_sprintrrf(const u_char *msg, size_t msglen, @@ -122,14 +113,17 @@ ns_sprintrrf(const u_char *msg, size_t msglen, T(addstr("\t\t\t", 3, &buf, &buflen)); } else { len = prune_origin(name, origin); - if (len == 0) { + if (*name == '\0') { + goto root; + } else if (len == 0) { T(addstr("@\t\t\t", 4, &buf, &buflen)); } else { T(addstr(name, len, &buf, &buflen)); /* Origin not used or not root, and no trailing dot? */ if (((origin == NULL || origin[0] == '\0') || - (origin[0] != '.' && origin[1] != '\0' && - name[len] == '\0')) && name[len - 1] != '.') { + (origin[0] != '.' && origin[1] != '\0' && + name[len] == '\0')) && name[len - 1] != '.') { + root: T(addstr(".", 1, &buf, &buflen)); len++; } @@ -151,7 +145,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, */ switch (type) { case ns_t_a: - if (rdlen != NS_INADDRSZ) + if (rdlen != (size_t)NS_INADDRSZ) goto formerr; (void) inet_ntop(AF_INET, rdata, buf, buflen); addlen(strlen(buf), &buf, &buflen); @@ -163,6 +157,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, case ns_t_mr: case ns_t_ns: case ns_t_ptr: + case ns_t_dname: T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); break; @@ -254,7 +249,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, case ns_t_rt: { u_int t; - if (rdlen < NS_INT16SZ) + if (rdlen < (size_t)NS_INT16SZ) goto formerr; /* Priority. */ @@ -272,7 +267,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, case ns_t_px: { u_int t; - if (rdlen < NS_INT16SZ) + if (rdlen < (size_t)NS_INT16SZ) goto formerr; /* Priority. */ @@ -310,9 +305,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, break; case ns_t_nsap: { - /* 2*255 for hex digits, 128 for '.' and '\0', 2 for - 0x if inet_nsap_ntoa starts using it. */ - char t[255*2 + 128 + 2]; + char t[2+255*3]; (void) inet_nsap_ntoa(rdlen, rdata, t); T(addstr(t, strlen(t), &buf, &buflen)); @@ -320,7 +313,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, } case ns_t_aaaa: - if (rdlen != NS_IN6ADDRSZ) + if (rdlen != (size_t)NS_IN6ADDRSZ) goto formerr; (void) inet_ntop(AF_INET6, rdata, buf, buflen); addlen(strlen(buf), &buf, &buflen); @@ -339,7 +332,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, u_int order, preference; char t[50]; - if (rdlen < 2*NS_INT16SZ) + if (rdlen < 2U*NS_INT16SZ) goto formerr; /* Order, Precedence. */ @@ -380,7 +373,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, u_int priority, weight, port; char t[50]; - if (rdlen < NS_INT16SZ*3) + if (rdlen < 3U*NS_INT16SZ) goto formerr; /* Priority, Weight, Port. */ @@ -409,7 +402,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, case ns_t_wks: { int n, lcnt; - if (rdlen < NS_INT32SZ + 1) + if (rdlen < 1U + NS_INT32SZ) goto formerr; /* Address. */ @@ -448,13 +441,12 @@ ns_sprintrrf(const u_char *msg, size_t msglen, } case ns_t_key: { -#ifndef _LIBC char base64_key[NS_MD5RSA_MAX_BASE64]; u_int keyflags, protocol, algorithm, key_id; const char *leader; int n; - if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ) + if (rdlen < 0U + NS_INT16SZ + NS_INT8SZ + NS_INT8SZ) goto formerr; /* Key flags, Protocol, Algorithm. */ @@ -486,20 +478,18 @@ ns_sprintrrf(const u_char *msg, size_t msglen, T(addstr(" )", 2, &buf, &buflen)); n = SPRINTF((tmp, " ; key_tag= %u", key_id)); T(addstr(tmp, n, &buf, &buflen)); -#endif /* !_LIBC */ break; } case ns_t_sig: { -#ifndef _LIBC char base64_key[NS_MD5RSA_MAX_BASE64]; u_int type, algorithm, labels, footprint; const char *leader; u_long t; int n; - if (rdlen < 22) + if (rdlen < 22U) goto formerr; /* Type covered, Algorithm, Label count, Original TTL. */ @@ -549,7 +539,6 @@ ns_sprintrrf(const u_char *msg, size_t msglen, } if (len > 15) T(addstr(" )", 2, &buf, &buflen)); -#endif /* !_LIBC */ break; } @@ -571,8 +560,10 @@ ns_sprintrrf(const u_char *msg, size_t msglen, case ns_t_cert: { u_int c_type, key_tag, alg; - int n, siz; - char base64_cert[8192], *leader, tmp[40]; + int n; + unsigned int siz; + char base64_cert[8192], tmp[40]; + const char *leader; c_type = ns_get16(rdata); rdata += NS_INT16SZ; key_tag = ns_get16(rdata); rdata += NS_INT16SZ; @@ -582,7 +573,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, T(addstr(tmp, len, &buf, &buflen)); siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */ if (siz > sizeof(base64_cert) * 3/4) { - char *str = "record too long to print"; + const char *str = "record too long to print"; T(addstr(str, strlen(str), &buf, &buflen)); } else { @@ -610,16 +601,47 @@ ns_sprintrrf(const u_char *msg, size_t msglen, break; } + case ns_t_tkey: { + /* KJD - need to complete this */ + u_long t; + int mode, err, keysize; + + /* Algorithm name. */ + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); + T(addstr(" ", 1, &buf, &buflen)); + + /* Inception. */ + t = ns_get32(rdata); rdata += NS_INT32SZ; + len = SPRINTF((tmp, "%s ", p_secstodate(t))); + T(addstr(tmp, len, &buf, &buflen)); + + /* Experation. */ + t = ns_get32(rdata); rdata += NS_INT32SZ; + len = SPRINTF((tmp, "%s ", p_secstodate(t))); + T(addstr(tmp, len, &buf, &buflen)); + + /* Mode , Error, Key Size. */ + /* Priority, Weight, Port. */ + mode = ns_get16(rdata); rdata += NS_INT16SZ; + err = ns_get16(rdata); rdata += NS_INT16SZ; + keysize = ns_get16(rdata); rdata += NS_INT16SZ; + len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize)); + T(addstr(tmp, len, &buf, &buflen)); + + /* XXX need to dump key, print otherdata length & other data */ + break; + } + case ns_t_tsig: { /* BEW - need to complete this */ int n; T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen)); T(addstr(" ", 1, &buf, &buflen)); - rdata += 8; /* time */ + rdata += 8; /*%< time */ n = ns_get16(rdata); rdata += INT16SZ; - rdata += n; /* sig */ - n = ns_get16(rdata); rdata += INT16SZ; /* original id */ + rdata += n; /*%< sig */ + n = ns_get16(rdata); rdata += INT16SZ; /*%< original id */ sprintf(buf, "%d", ns_get16(rdata)); rdata += INT16SZ; addlen(strlen(buf), &buf, &buflen); @@ -677,7 +699,8 @@ ns_sprintrrf(const u_char *msg, size_t msglen, int n, m; char *p; - len = SPRINTF((tmp, "\\#(\t\t; %s", comment)); + len = SPRINTF((tmp, "\\# %u%s\t; %s", (unsigned)(edata - rdata), + rdlen != 0U ? " (" : "", comment)); T(addstr(tmp, len, &buf, &buflen)); while (rdata < edata) { p = tmp; @@ -703,10 +726,11 @@ ns_sprintrrf(const u_char *msg, size_t msglen, return (buf - obuf); } } +libresolv_hidden_def (ns_sprintrrf) /* Private. */ -/* +/*% * size_t * prune_origin(name, origin) * Find out if the name is at or under the current origin. @@ -739,7 +763,7 @@ prune_origin(const char *name, const char *origin) { return (name - oname); } -/* +/*% * int * charstr(rdata, edata, buf, buflen) * Format a <character-string> into the presentation buffer. @@ -795,9 +819,11 @@ addname(const u_char *msg, size_t msglen, n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen); if (n < 0) - goto enospc; /* Guess. */ + goto enospc; /*%< Guess. */ newlen = prune_origin(*buf, origin); - if (newlen == 0) { + if (**buf == '\0') { + goto root; + } else if (newlen == 0U) { /* Use "@" instead of name. */ if (newlen + 2 > *buflen) goto enospc; /* No room for "@\0". */ @@ -808,6 +834,7 @@ addname(const u_char *msg, size_t msglen, (origin[0] != '.' && origin[1] != '\0' && (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') { /* No trailing dot. */ + root: if (newlen + 2 > *buflen) goto enospc; /* No room for ".\0". */ (*buf)[newlen++] = '.'; @@ -864,3 +891,81 @@ addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) { } return (spaced); } + +/* DST algorithm codes */ +#define KEY_RSA 1 +#define KEY_HMAC_MD5 157 + +/*% + * calculates a checksum used in dst for an id. + * takes an array of bytes and a length. + * returns a 16 bit checksum. + */ +static u_int16_t +dst_s_id_calc(const u_char *key, const int keysize) +{ + u_int32_t ac; + const u_char *kp = key; + int size = keysize; + + if (!key || (keysize <= 0)) + return (0xffffU); + + for (ac = 0; size > 1; size -= 2, kp += 2) + ac += ((*kp) << 8) + *(kp + 1); + + if (size > 0) + ac += ((*kp) << 8); + ac += (ac >> 16) & 0xffff; + + return (ac & 0xffff); +} + +/*% + * dst_s_get_int16 + * This routine extracts a 16 bit integer from a two byte character + * string. The character string is assumed to be in network byte + * order and may be unaligned. The number returned is in host order. + * Parameter + * buf A two byte character string. + * Return + * The converted integer value. + */ + +static u_int16_t +dst_s_get_int16(const u_char *buf) +{ + register u_int16_t a = 0; + a = ((u_int16_t)(buf[0] << 8)) | ((u_int16_t)(buf[1])); + return (a); +} + +/*% + * dst_s_dns_key_id() Function to calculate DNSSEC footprint from KEY record + * rdata + * Input: + * dns_key_rdata: the raw data in wire format + * rdata_len: the size of the input data + * Output: + * the key footprint/id calculated from the key data + */ +static u_int16_t +dst_s_dns_key_id(const u_char *dns_key_rdata, const int rdata_len) +{ + if (!dns_key_rdata) + return 0; + + /* compute id */ + if (dns_key_rdata[3] == KEY_RSA) /*%< Algorithm RSA */ + return dst_s_get_int16((const u_char *) + &dns_key_rdata[rdata_len - 3]); + else if (dns_key_rdata[3] == KEY_HMAC_MD5) + /* compatibility */ + return 0; + else + /* compute a checksum on the key part of the key rr */ + return dst_s_id_calc(dns_key_rdata, rdata_len); +} + + +/*! \file */ diff --git a/resolv/ns_samedomain.c b/resolv/ns_samedomain.c index 1fb1c552d0..44b843a74b 100644 --- a/resolv/ns_samedomain.c +++ b/resolv/ns_samedomain.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -24,21 +25,22 @@ static const char rcsid[] = "$BINDId: ns_samedomain.c,v 8.9 1999/10/15 21:06:51 #include <errno.h> #include <string.h> -/* - * int - * ns_samedomain(a, b) +/*% * Check whether a name belongs to a domain. + * * Inputs: - * a - the domain whose ancestory is being verified - * b - the potential ancestor we're checking against + *\li a - the domain whose ancestory is being verified + *\li b - the potential ancestor we're checking against + * * Return: - * boolean - is a at or below b? + *\li boolean - is a at or below b? + * * Notes: - * Trailing dots are first removed from name and domain. + *\li Trailing dots are first removed from name and domain. * Always compare complete subdomains, not only whether the * domain name is the trailing string of the given name. * - * "host.foobar.top" lies in "foobar.top" and in "top" and in "" + *\li "host.foobar.top" lies in "foobar.top" and in "top" and in "" * but NOT in "bar.top" */ @@ -52,7 +54,7 @@ ns_samedomain(const char *a, const char *b) { lb = strlen(b); /* Ignore a trailing label separator (i.e. an unescaped dot) in 'a'. */ - if (la != 0 && a[la - 1] == '.') { + if (la != 0U && a[la - 1] == '.') { escaped = 0; /* Note this loop doesn't get executed if la==1. */ for (i = la - 2; i >= 0; i--) @@ -68,7 +70,7 @@ ns_samedomain(const char *a, const char *b) { } /* Ignore a trailing label separator (i.e. an unescaped dot) in 'b'. */ - if (lb != 0 && b[lb - 1] == '.') { + if (lb != 0U && b[lb - 1] == '.') { escaped = 0; /* note this loop doesn't get executed if lb==1 */ for (i = lb - 2; i >= 0; i--) @@ -84,7 +86,7 @@ ns_samedomain(const char *a, const char *b) { } /* lb == 0 means 'b' is the root domain, so 'a' must be in 'b'. */ - if (lb == 0) + if (lb == 0U) return (1); /* 'b' longer than 'a' means 'a' can't be in 'b'. */ @@ -121,24 +123,23 @@ ns_samedomain(const char *a, const char *b) { */ escaped = 0; for (i = diff - 2; i >= 0; i--) - if (a[i] == '\\') + if (a[i] == '\\') { if (escaped) escaped = 0; else escaped = 1; - else + } else break; if (escaped) return (0); - + /* Now compare aligned trailing substring. */ cp = a + diff; return (strncasecmp(cp, b, lb) == 0); } +libresolv_hidden_def (ns_samedomain) -/* - * int - * ns_subdomain(a, b) +/*% * is "a" a subdomain of "b"? */ int @@ -146,30 +147,31 @@ ns_subdomain(const char *a, const char *b) { return (ns_samename(a, b) != 1 && ns_samedomain(a, b)); } -/* - * int - * ns_makecanon(src, dst, dstsize) +/*% * make a canonical copy of domain name "src" + * * notes: + * \code * foo -> foo. * foo. -> foo. * foo.. -> foo. * foo\. -> foo\.. * foo\\. -> foo\\. + * \endcode */ int ns_makecanon(const char *src, char *dst, size_t dstsize) { size_t n = strlen(src); - if (n + sizeof "." > dstsize) { + if (n + sizeof "." > dstsize) { /*%< Note: sizeof == 2 */ __set_errno (EMSGSIZE); return (-1); } strcpy(dst, src); - while (n > 0 && dst[n - 1] == '.') /* Ends in "." */ - if (n > 1 && dst[n - 2] == '\\' && /* Ends in "\." */ - (n < 2 || dst[n - 3] != '\\')) /* But not "\\." */ + while (n >= 1U && dst[n - 1] == '.') /*%< Ends in "." */ + if (n >= 2U && dst[n - 2] == '\\' && /*%< Ends in "\." */ + (n < 3U || dst[n - 3] != '\\')) /*%< But not "\\." */ break; else dst[--n] = '\0'; @@ -177,15 +179,15 @@ ns_makecanon(const char *src, char *dst, size_t dstsize) { dst[n] = '\0'; return (0); } +libresolv_hidden_def (ns_makecanon) -/* - * int - * ns_samename(a, b) +/*% * determine whether domain name "a" is the same as domain name "b" + * * return: - * -1 on error - * 0 if names differ - * 1 if names are the same + *\li -1 on error + *\li 0 if names differ + *\li 1 if names are the same */ int @@ -200,3 +202,6 @@ ns_samename(const char *a, const char *b) { else return (0); } +libresolv_hidden_def (ns_samename) + +/*! \file */ diff --git a/resolv/ns_ttl.c b/resolv/ns_ttl.c index 0f74178bbb..d4c98bcf3a 100644 --- a/resolv/ns_ttl.c +++ b/resolv/ns_ttl.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -88,8 +89,8 @@ ns_format_ttl(u_long src, char *dst, size_t dstlen) { return (dst - odst); } +libresolv_hidden_def (ns_format_ttl) -#ifndef SHARED // Seems not to be needed. It's not exported from the DSO. Some libresolv.a // might depend on it so we let it in. int @@ -132,7 +133,8 @@ ns_parse_ttl(const char *src, u_long *dst) { goto einval; else ttl += tmp; - } + } else if (!dirty) + goto einval; *dst = ttl; return (0); @@ -140,7 +142,6 @@ ns_parse_ttl(const char *src, u_long *dst) { __set_errno (EINVAL); return (-1); } -#endif /* Private. */ @@ -157,3 +158,5 @@ fmt1(int t, char s, char **buf, size_t *buflen) { *buflen -= len; return (0); } + +/*! \file */ diff --git a/resolv/nss_dns/dns-canon.c b/resolv/nss_dns/dns-canon.c index cee3d57bc1..50a0fc0260 100644 --- a/resolv/nss_dns/dns-canon.c +++ b/resolv/nss_dns/dns-canon.c @@ -134,14 +134,14 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, if (type != ns_t_cname) goto unavail; - if (ns_get16 (ptr) != ns_c_in) + if (__ns_get16 (ptr) != ns_c_in) goto unavail; /* Also skip over the TTL. */ ptr += sizeof (uint16_t) + sizeof (uint32_t); /* Skip over the data length and data. */ - ptr += sizeof (uint16_t) + ns_get16 (ptr); + ptr += sizeof (uint16_t) + __ns_get16 (ptr); } } } diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c index 80c0bd9fa8..4d43dec946 100644 --- a/resolv/nss_dns/dns-host.c +++ b/resolv/nss_dns/dns-host.c @@ -698,13 +698,13 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, continue; } - type = ns_get16 (cp); + type = __ns_get16 (cp); cp += INT16SZ; /* type */ - class = ns_get16 (cp); + class = __ns_get16 (cp); cp += INT16SZ; /* class */ - ttl = ns_get32 (cp); + ttl = __ns_get32 (cp); cp += INT32SZ; /* TTL */ - n = ns_get16 (cp); + n = __ns_get16 (cp); cp += INT16SZ; /* len */ if (__builtin_expect (class != C_IN, 0)) { @@ -1032,13 +1032,13 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, continue; } - int type = ns_get16 (cp); + int type = __ns_get16 (cp); cp += INT16SZ; /* type */ - int class = ns_get16 (cp); + int class = __ns_get16 (cp); cp += INT16SZ; /* class */ - int32_t ttl = ns_get32 (cp); + int32_t ttl = __ns_get32 (cp); cp += INT32SZ; /* TTL */ - n = ns_get16 (cp); + n = __ns_get16 (cp); cp += INT16SZ; /* len */ if (class != C_IN) diff --git a/resolv/res_debug.c b/resolv/res_debug.c index 76fd34bf3c..c38de640a5 100644 --- a/resolv/res_debug.c +++ b/resolv/res_debug.c @@ -1024,6 +1024,7 @@ dn_count_labels(const char *name) { count++; return (count); } +libresolv_hidden_def (__dn_count_labels) /* @@ -1051,3 +1052,4 @@ p_secstodate (u_long secs) { time->tm_hour, time->tm_min, time->tm_sec); return (output); } +libresolv_hidden_def (__p_secstodate) |