1 #ifndef _DNS_PARSER_H_ 2 #define _DNS_PARSER_H_ 3 4 #include <limits.h> 5 #include "common.h" 6 #include "dnsrelated.h" 7 8 #define GET_16_BIT_U_INT(ptr) (ntohs(*(int16_t *)(ptr))) 9 #define GET_32_BIT_U_INT(ptr) (ntohl(*(int32_t *)(ptr))) 10 #define GET_8_BIT_U_INT(ptr) (*(unsigned char*)(ptr)) 11 12 #define DNS_HEADER_LENGTH 12 13 14 /* Handle DNS header*/ 15 #define DNSGetTCPLength(dns_over_tcp_ptr) GET_16_BIT_U_INT(dns_over_tcp_ptr) 16 17 #define DNSGetQueryIdentifier(dns_body) GET_16_BIT_U_INT((char *)(dns_body)) 18 19 #define DNSGetFlags(dns_body) GET_16_BIT_U_INT((char *)(dns_body) + 2) 20 21 #define DNSGetQuestionCount(dns_body) GET_16_BIT_U_INT((char *)(dns_body) + 4) 22 23 #define DNSGetAnswerCount(dns_body) GET_16_BIT_U_INT((char *)(dns_body) + 6) 24 25 #define DNSGetNameServerCount(dns_body) GET_16_BIT_U_INT((char *)(dns_body) + 8) 26 27 #define DNSGetAdditionalCount(dns_body) GET_16_BIT_U_INT((char *)(dns_body) + 10) 28 29 #define DNSJumpHeader(dns_body) ((char *)(dns_body) + DNS_HEADER_LENGTH) 30 31 #define DNSGetTTL(ans_start_ptr) GET_32_BIT_U_INT(DNSJumpOverName(ans_start_ptr) + 4) 32 33 #define DNSGetResourceDataLength(ans_start_ptr) GET_16_BIT_U_INT(DNSJumpOverName(ans_start_ptr) + 8) 34 35 #define DNSGetResourceDataPos(ans_start_ptr) (DNSJumpOverName((char *)(ans_start_ptr)) + 10) 36 37 /* Common */ 38 char *DNSJumpOverName(char *NameStart); 39 40 int DNSGetHostName(const char *DNSBody, int DNSBodyLength, const char *NameStart, char *buffer, int BufferLength); 41 42 int DNSGetHostNameLength(const char *DNSBody, int DNSBodyLength, const char *NameStart); 43 44 #define DNSGetRecordType(rec_start_ptr) ((rec_start_ptr) == NULL ? DNS_TYPE_UNKNOWN : GET_16_BIT_U_INT(DNSJumpOverName(rec_start_ptr))) 45 46 #define DNSIsLabelPointerStart(num) (((num) & 0xC0) == 0xC0) 47 48 #define DNSLabelGetPointer(rec_start_ptr) ((rec_start_ptr) == NULL ? 0 : (int)((unsigned char *)(rec_start_ptr))[1] + (int)(((unsigned char *)(rec_start_ptr))[0] - 192) * 256) 49 50 #define DNSGetRecordClass(rec_start_ptr) ((rec_start_ptr) == NULL ? DNS_CLASS_UNKNOWN : GET_16_BIT_U_INT(DNSJumpOverName(rec_start_ptr) + 2)) 51 52 #ifdef HOST_BIG_ENDIAN 53 /* DNSMessageFlags, at 2-byte offset of a DNS header, is 2 bytes length. 54 * https://tools.ietf.org/html/rfc6895 55 */ 56 typedef struct _DNSMessageProperties{ 57 uint16_t Direction : 1; /* query (0), or response (1) */ 58 59 /* Type: 60 * 0 a standard query (QUERY). 61 * 1 an inverse query (IQUERY). 62 * 2 a server status request (STATUS). 63 * 3-15 reserved for future use */ 64 uint16_t Type : 4; 65 66 uint16_t AuthoritativeAnswer:1; 67 68 uint16_t TrunCation : 1; 69 70 uint16_t RecursionDesired: 1; /* 0 no, 1 yes */ 71 72 uint16_t RecursionAvailable: 1; /* 0 no, 1 yes */ 73 74 uint16_t Unused : 1; 75 76 uint16_t AuthenticData : 1; 77 78 uint16_t CheckingDisabled: 1; 79 80 /* ResponseCode: 81 * 0 No error condition. 82 * 1 Format error - The name server was unable to interpret the query. 83 * 2 Server failure - The name server was unable to process this query due to a problem with the name server. 84 * 3 Name Error - Meaningful only for responses from an authoritative name server, this code signifies that the domain name referenced in the query does not exist. 85 * 4 Not Implemented - The name server does not support the requested kind of query. 86 * 5 Refused - The name server refuses to perform the specified operation for policy reasons. For example, a name server may not wish to provide the information to the particular requester, or a name server may not wish to perform a particular operation (e.g., zone transfer) for particular data. 87 * 6-15 Reserved for future use. */ 88 uint16_t ResponseCode : 4; 89 90 }DNSFlags; 91 #else 92 typedef struct _DNSMessageProperties{ 93 uint16_t RecursionDesired: 1; /* 0 no, 1 yes */ 94 95 uint16_t TrunCation : 1; 96 97 uint16_t AuthoritativeAnswer:1; 98 99 /* Type: 100 * 0 a standard query (QUERY). 101 * 1 an inverse query (IQUERY). 102 * 2 a server status request (STATUS). 103 * 3-15 reserved for future use */ 104 uint16_t Type : 4; 105 106 uint16_t Direction : 1; /* query (0), or response (1) */ 107 108 109 /* ResponseCode: 110 * 0 No error condition. 111 * 1 Format error - The name server was unable to interpret the query. 112 * 2 Server failure - The name server was unable to process this query due to a problem with the name server. 113 * 3 Name Error - Meaningful only for responses from an authoritative name server, this code signifies that the domain name referenced in the query does not exist. 114 * 4 Not Implemented - The name server does not support the requested kind of query. 115 * 5 Refused - The name server refuses to perform the specified operation for policy reasons. For example, a name server may not wish to provide the information to the particular requester, or a name server may not wish to perform a particular operation (e.g., zone transfer) for particular data. 116 * 6-15 Reserved for future use. */ 117 uint16_t ResponseCode : 4; 118 119 uint16_t CheckingDisabled: 1; 120 121 uint16_t AuthenticData : 1; 122 123 uint16_t Unused : 1; 124 125 uint16_t RecursionAvailable: 1; /* 0 no, 1 yes */ 126 127 }DNSFlags; 128 #endif 129 130 typedef struct _DNSHeader{ 131 uint16_t Identifier; 132 DNSFlags Flags; 133 uint16_t QuestionCount; 134 uint16_t AnswerCount; 135 uint16_t NameServerCount; 136 uint16_t AdditionalCount; 137 }DNSHeader; 138 139 #define DNSGetHeader(dns_body_ptr) ((DNSHeader *)(dns_body_ptr)) 140 141 /* Convert a DNS message to text */ 142 char *GetAllAnswers(char *DNSBody, int DNSBodyLength, char *Buffer, int BufferLength); 143 144 int DNSCopyLable(const char *DNSBody, char *here, const char *src); 145 146 /** 147 New Implementation 148 */ 149 150 typedef enum _DnsDirection{ 151 DNS_DIRECTION_QUERY = 0, 152 DNS_DIRECTION_RESPONSE = 1, 153 } DnsDirection; 154 155 typedef enum _DnsOperation{ 156 DNS_OPERATION_QUERY = 0, 157 DNS_OPERATION_IQUERY = 1, 158 DNS_OPERATION_STATUS = 2, 159 } DnsOperation; 160 161 typedef enum _ResponseCode{ 162 RESPONSE_CODE_NO_ERROR = 0, 163 RESPONSE_CODE_FORMAT_ERROR = 1, 164 RESPONSE_CODE_SERVER_FAILURE = 2, 165 RESPONSE_CODE_NAME_ERROR = 3, 166 RESPONSE_CODE_NOT_IMPLEMENTED = 4, 167 RESPONSE_CODE_REFUSED = 5, 168 } ResponseCode; 169 170 typedef enum _DnsRecordPurpose{ 171 /* Their values are not important */ 172 DNS_RECORD_PURPOSE_UNKNOWN = 0, 173 DNS_RECORD_PURPOSE_QUESTION, 174 DNS_RECORD_PURPOSE_ANSWER, 175 DNS_RECORD_PURPOSE_NAME_SERVER, 176 DNS_RECORD_PURPOSE_ADDITIONAL, 177 } DnsRecordPurpose; 178 179 typedef struct _DnsSimpleParser DnsSimpleParser; 180 181 struct _DnsSimpleParser{ 182 /* public, but don't modify outside, unless you know what are you doing */ 183 char *RawDns; 184 int RawDnsLength; 185 186 struct { 187 /* private */ 188 const DNSFlags *Flags; 189 190 /* public */ 191 DnsDirection (*Direction)(DnsSimpleParser *p); 192 DnsOperation (*Operation)(DnsSimpleParser *p); 193 BOOL (*IsAuthoritative)(DnsSimpleParser *p); 194 BOOL (*Truncated)(DnsSimpleParser *p); 195 BOOL (*RecursionDesired)(DnsSimpleParser *p); 196 BOOL (*RecursionAvailable)(DnsSimpleParser *p); 197 ResponseCode (*ResponseCode)(DnsSimpleParser *p); 198 } _Flags; 199 200 /* public */ 201 uint16_t (*QueryIdentifier)(DnsSimpleParser *p); 202 int (*QuestionCount)(DnsSimpleParser *p); 203 int (*AnswerCount)(DnsSimpleParser *p); 204 int (*NameServerCount)(DnsSimpleParser *p); 205 int (*AdditionalCount)(DnsSimpleParser *p); 206 207 BOOL (*HasType)(DnsSimpleParser *p, 208 DnsRecordPurpose Purpose, 209 DNSRecordClass Klass, 210 DNSRecordType Type 211 ); 212 }; 213 214 int DnsSimpleParser_Init(DnsSimpleParser *p, 215 char *RawDns, 216 int Length, 217 BOOL IsTcp); 218 219 /** 220 Iterator 221 */ 222 typedef struct _DnsSimpleParserIterator DnsSimpleParserIterator; 223 224 struct _DnsSimpleParserIterator{ 225 /* public, but don't modify outside */ 226 DnsSimpleParser *Parser; 227 228 /* private */ 229 char *CurrentPosition; 230 int RecordPosition; /* Starts at 1 */ 231 232 int QuestionFirst; /* Starts at 1; 0 means no such record */ 233 int QuestionLast; 234 235 int AnswerFirst; /* Starts at 1; 0 means no such record */ 236 int AnswerLast; 237 238 int NameServerFirst; /* Starts at 1; 0 means no such record */ 239 int NameServerLast; 240 241 int AdditionalFirst; /* Starts at 1; 0 means no such record */ 242 int AdditionalLast; 243 244 int AllRecordCount; 245 246 /* public, but don't modify outside */ 247 /* Current record informations */ 248 DnsRecordPurpose Purpose; 249 DNSRecordType Type; 250 DNSRecordClass Klass; 251 int DataLength; 252 253 char *(*Next)(DnsSimpleParserIterator *i); 254 void (*GotoAnswers)(DnsSimpleParserIterator *i); 255 int (*GetName)(DnsSimpleParserIterator *i, 256 char *Buffer, /* Could be NULL */ 257 int BufferLength 258 ); 259 int (*GetNameLength)(DnsSimpleParserIterator *i); 260 char *(*RowData)(DnsSimpleParserIterator *i); 261 int (*TextifyData)(DnsSimpleParserIterator *i, 262 const char *Format, /* "%t:%v\n" */ 263 char *Buffer, 264 int BufferLength 265 ); 266 267 uint32_t (*GetTTL)(DnsSimpleParserIterator *i); 268 }; 269 270 int DnsSimpleParserIterator_Init(DnsSimpleParserIterator *i, 271 DnsSimpleParser *p 272 ); 273 274 #endif /* _DNS_PARSER_H_ */ 275