| 1 | + | #ifndef _DECODE_DNS_ |
| 2 | + | #define _DECODE_DNS_ |
| 3 | + | #include <stdint.h> |
| 4 | + | #include <netinet/in.h> |
| 5 | + | #include <stdio.h> |
| 6 | + | #include <string.h> |
| 7 | + | #include <stdlib.h> |
| 8 | + | #include <arpa/inet.h> |
| 9 | + | #include "debug.h" |
| 10 | + | /////////////////////////////////////////////////////////////////////////////////////////////////// |
| 11 | + | // DNS |
| 12 | + | /////// |
| 13 | + | // Definitions in this section were taken from /usr/include/arpa/nameser.h and modified as needed. |
| 14 | + | // Many of the definitions found here may not actually be used. |
| 15 | + | |
| 16 | + | /* |
| 17 | + | * Define constants based on RFC 883, RFC 1034, RFC 1035 |
| 18 | + | */ |
| 19 | + | #define NS_PACKETSZ 512 /* default UDP packet size */ |
| 20 | + | #define NS_MAXDNAME 1025 /* maximum domain name */ |
| 21 | + | #define NS_MAXMSG 65535 /* maximum message size */ |
| 22 | + | #define NS_MAXCDNAME 255 /* maximum compressed domain name */ |
| 23 | + | #define NS_MAXLABEL 63 /* maximum length of domain label */ |
| 24 | + | #define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */ |
| 25 | + | #define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */ |
| 26 | + | #define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ |
| 27 | + | #define NS_INT32SZ 4 /* #/bytes of data in a uint32_t */ |
| 28 | + | #define NS_INT16SZ 2 /* #/bytes of data in a uint16_t */ |
| 29 | + | #define NS_INT8SZ 1 /* #/bytes of data in a uint8_t */ |
| 30 | + | #define NS_INADDRSZ 4 /* IPv4 T_A */ |
| 31 | + | #define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */ |
| 32 | + | #define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */ |
| 33 | + | #define NS_DEFAULTPORT 53 /* For both TCP and UDP. */ |
| 34 | + | |
| 35 | + | // Message header |
| 36 | + | typedef struct { |
| 37 | + | uint16_t id; /* query identification number */ |
| 38 | + | uint16_t flags; /* flags */ |
| 39 | + | uint16_t qdcount; /* number of question entries */ |
| 40 | + | uint16_t ancount; /* number of answer entries */ |
| 41 | + | uint16_t nscount; /* number of authority entries */ |
| 42 | + | uint16_t arcount; /* number of resource entries */ |
| 43 | + | } DNS_hdr; |
| 44 | + | |
| 45 | + | /* |
| 46 | + | * Macros for subfields of flag fields. |
| 47 | + | */ |
| 48 | + | #define DNS_QR(np) (ntohs((np)->flags) & 0x8000) /* response flag */ |
| 49 | + | #define DNS_OPCODE(np) ((ntohs((np)->flags) >> 11) & 0xF) /* purpose of message */ |
| 50 | + | #define DNS_AA(np) (ntohs((np)->flags) & 0x0400) /* authoritative answer */ |
| 51 | + | #define DNS_TC(np) (ntohs((np)->flags) & 0x0200) /* truncated message */ |
| 52 | + | #define DNS_RD(np) (ntohs((np)->flags) & 0x0100) /* recursion desired */ |
| 53 | + | |
| 54 | + | #define DNS_RA(np) (ntohs((np)->flags) & 0x80) /* recursion available */ |
| 55 | + | #define DNS_AD(np) (ntohs((np)->flags) & 0x20) /* authentic data from named */ |
| 56 | + | #define DNS_CD(np) (ntohs((np)->flags) & 0x10) /* checking disabled by resolver */ |
| 57 | + | #define DNS_ZERO(np) ((ntohs((np)->flags) >> 4) & 0x7) /* 3 bits should be zero */ |
| 58 | + | #define DNS_RCODE(np) (ntohs((np)->flags) & 0xF) /* response code */ |
| 59 | + | |
| 60 | + | // Resource record data structure |
| 61 | + | struct _dns_rr_data { |
| 62 | + | uint16_t type; |
| 63 | + | uint16_t rr_class; |
| 64 | + | uint32_t ttl; |
| 65 | + | uint16_t rdlength; |
| 66 | + | } __attribute__((packed)); |
| 67 | + | typedef struct _dns_rr_data DNS_rr_data; |
| 68 | + | |
| 69 | + | #if 0 |
| 70 | + | // Broken code that isn't used anyway |
| 71 | + | typedef struct { |
| 72 | + | char name[NS_MAXDNAME]; // <--- this doesn't work here |
| 73 | + | DNS_rr_data rrmetadata; |
| 74 | + | const u_char *rdata; |
| 75 | + | } DNS_rr; |
| 76 | + | #endif |
| 77 | + | |
| 78 | + | /* Accessor macros - this is part of the public interface. */ |
| 79 | + | #define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".") |
| 80 | + | #define ns_rr_type(rr) ((ns_type)((rr).type + 0)) |
| 81 | + | #define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0)) |
| 82 | + | #define ns_rr_ttl(rr) ((rr).ttl + 0) |
| 83 | + | #define ns_rr_rdlen(rr) ((rr).rdlength + 0) |
| 84 | + | #define ns_rr_rdata(rr) ((rr).rdata + 0) |
| 85 | + | |
| 86 | + | /*% |
| 87 | + | * These don't have to be in the same order as in the packet flags word, |
| 88 | + | * and they can even overlap in some cases, but they will need to be kept |
| 89 | + | * in synch with ns_parse.c:ns_flagdata[]. |
| 90 | + | */ |
| 91 | + | typedef enum __ns_flag { |
| 92 | + | ns_f_qr, /*%< Question/Response. */ |
| 93 | + | ns_f_opcode, /*%< Operation code. */ |
| 94 | + | ns_f_aa, /*%< Authoritative Answer. */ |
| 95 | + | ns_f_tc, /*%< Truncation occurred. */ |
| 96 | + | ns_f_rd, /*%< Recursion Desired. */ |
| 97 | + | ns_f_ra, /*%< Recursion Available. */ |
| 98 | + | ns_f_z, /*%< MBZ. */ |
| 99 | + | ns_f_ad, /*%< Authentic Data (DNSSEC). */ |
| 100 | + | ns_f_cd, /*%< Checking Disabled (DNSSEC). */ |
| 101 | + | ns_f_rcode, /*%< Response code. */ |
| 102 | + | ns_f_max |
| 103 | + | } ns_flag; |
| 104 | + | |
| 105 | + | /*% |
| 106 | + | * Currently defined opcodes. |
| 107 | + | */ |
| 108 | + | typedef enum __ns_opcode { |
| 109 | + | ns_o_query = 0, /*%< Standard query. */ |
| 110 | + | ns_o_iquery = 1, /*%< Inverse query (deprecated/unsupported). */ |
| 111 | + | ns_o_status = 2, /*%< Name server status query (unsupported). */ |
| 112 | + | /* Opcode 3 is undefined/reserved. */ |
| 113 | + | ns_o_notify = 4, /*%< Zone change notification. */ |
| 114 | + | ns_o_update = 5, /*%< Zone update message. */ |
| 115 | + | ns_o_max = 6 |
| 116 | + | } ns_opcode; |
| 117 | + | |
| 118 | + | /*% |
| 119 | + | * Currently defined response codes. |
| 120 | + | */ |
| 121 | + | typedef enum __ns_rcode { |
| 122 | + | ns_r_noerror = 0, /*%< No error occurred. */ |
| 123 | + | ns_r_formerr = 1, /*%< Format error. */ |
| 124 | + | ns_r_servfail = 2, /*%< Server failure. */ |
| 125 | + | ns_r_nxdomain = 3, /*%< Name error. */ |
| 126 | + | ns_r_notimpl = 4, /*%< Unimplemented. */ |
| 127 | + | ns_r_refused = 5, /*%< Operation refused. */ |
| 128 | + | /* these are for BIND_UPDATE */ |
| 129 | + | ns_r_yxdomain = 6, /*%< Name exists */ |
| 130 | + | ns_r_yxrrset = 7, /*%< RRset exists */ |
| 131 | + | ns_r_nxrrset = 8, /*%< RRset does not exist */ |
| 132 | + | ns_r_notauth = 9, /*%< Not authoritative for zone */ |
| 133 | + | ns_r_notzone = 10, /*%< Zone of record different from zone section */ |
| 134 | + | ns_r_max = 11, |
| 135 | + | /* The following are EDNS extended rcodes */ |
| 136 | + | ns_r_badvers = 16, |
| 137 | + | /* The following are TSIG errors */ |
| 138 | + | ns_r_badsig = 16, |
| 139 | + | ns_r_badkey = 17, |
| 140 | + | ns_r_badtime = 18 |
| 141 | + | } ns_rcode; |
| 142 | + | |
| 143 | + | |
| 144 | + | /* |
| 145 | + | * Currently defined type values for resources and queries. |
| 146 | + | */ |
| 147 | + | typedef enum __ns_type { |
| 148 | + | ns_t_invalid = 0, /* Cookie. */ |
| 149 | + | ns_t_a = 1, /* Host address. */ |
| 150 | + | ns_t_ns = 2, /* Authoritative server. */ |
| 151 | + | ns_t_md = 3, /* Mail destination. */ |
| 152 | + | ns_t_mf = 4, /* Mail forwarder. */ |
| 153 | + | ns_t_cname = 5, /* Canonical name. */ |
| 154 | + | ns_t_soa = 6, /* Start of authority zone. */ |
| 155 | + | ns_t_mb = 7, /* Mailbox domain name. */ |
| 156 | + | ns_t_mg = 8, /* Mail group member. */ |
| 157 | + | ns_t_mr = 9, /* Mail rename name. */ |
| 158 | + | ns_t_null = 10, /* Null resource record. */ |
| 159 | + | ns_t_wks = 11, /* Well known service. */ |
| 160 | + | ns_t_ptr = 12, /* Domain name pointer. */ |
| 161 | + | ns_t_hinfo = 13, /* Host information. */ |
| 162 | + | ns_t_minfo = 14, /* Mailbox information. */ |
| 163 | + | ns_t_mx = 15, /* Mail routing information. */ |
| 164 | + | ns_t_txt = 16, /* Text strings. */ |
| 165 | + | ns_t_rp = 17, /* Responsible person. */ |
| 166 | + | ns_t_afsdb = 18, /* AFS cell database. */ |
| 167 | + | ns_t_x25 = 19, /* X_25 calling address. */ |
| 168 | + | ns_t_isdn = 20, /* ISDN calling address. */ |
| 169 | + | ns_t_rt = 21, /* Router. */ |
| 170 | + | ns_t_nsap = 22, /* NSAP address. */ |
| 171 | + | ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */ |
| 172 | + | ns_t_sig = 24, /* Security signature. */ |
| 173 | + | ns_t_key = 25, /* Security key. */ |
| 174 | + | ns_t_px = 26, /* X.400 mail mapping. */ |
| 175 | + | ns_t_gpos = 27, /* Geographical position (withdrawn). */ |
| 176 | + | ns_t_aaaa = 28, /* Ip6 Address. */ |
| 177 | + | ns_t_loc = 29, /* Location Information. */ |
| 178 | + | ns_t_nxt = 30, /* Next domain (security). */ |
| 179 | + | ns_t_eid = 31, /* Endpoint identifier. */ |
| 180 | + | ns_t_nimloc = 32, /* Nimrod Locator. */ |
| 181 | + | ns_t_srv = 33, /* Server Selection. */ |
| 182 | + | ns_t_atma = 34, /* ATM Address */ |
| 183 | + | ns_t_naptr = 35, /* Naming Authority PoinTeR */ |
| 184 | + | ns_t_kx = 36, /* Key Exchange */ |
| 185 | + | ns_t_cert = 37, /* Certification record */ |
| 186 | + | ns_t_a6 = 38, /* IPv6 address (deprecated, use ns_t_aaaa) */ |
| 187 | + | ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */ |
| 188 | + | ns_t_sink = 40, /* Kitchen sink (experimentatl) */ |
| 189 | + | ns_t_opt = 41, /* EDNS0 option (meta-RR) */ |
| 190 | + | ns_t_apl = 42, /* Address prefix list (RFC3123) */ |
| 191 | + | ns_t_tkey = 249, /* Transaction key */ |
| 192 | + | ns_t_tsig = 250, /* Transaction signature. */ |
| 193 | + | ns_t_ixfr = 251, /* Incremental zone transfer. */ |
| 194 | + | ns_t_axfr = 252, /* Transfer zone of authority. */ |
| 195 | + | ns_t_mailb = 253, /* Transfer mailbox records. */ |
| 196 | + | ns_t_maila = 254, /* Transfer mail agent records. */ |
| 197 | + | ns_t_any = 255, /* Wildcard match. */ |
| 198 | + | ns_t_zxfr = 256, /* BIND-specific, nonstandard. */ |
| 199 | + | ns_t_max = 65536 |
| 200 | + | } ns_type; |
| 201 | + | |
| 202 | + | #define DNS_type(p) (ntohs(((ns_query_typeclass *)p)->type)) |
| 203 | + | typedef struct __ns_query_typeclass { |
| 204 | + | uint16_t type; |
| 205 | + | uint16_t class; |
| 206 | + | } ns_query_typeclass; |
| 207 | + | #endif |
| 208 | + | |
| 209 | + | char *decode_dns(void *dns); |
| 210 | + | |