@@ -74,6 +74,8 @@ static inline void set_dns_msg_response(struct dns_msg_t *dns_msg, int type,
7474
7575int dns_unpack_answer (struct dns_msg_t * dns_msg , int dname_ptr , u32_t * ttl )
7676{
77+ int dname_len = DNS_COMMON_UINT_SIZE ;
78+ int i = 0 ;
7779 u16_t buf_size ;
7880 u16_t pos ;
7981 u16_t len ;
@@ -82,14 +84,33 @@ int dns_unpack_answer(struct dns_msg_t *dns_msg, int dname_ptr, u32_t *ttl)
8284
8385 answer = dns_msg -> msg + dns_msg -> answer_offset ;
8486
85- if (answer [0 ] < DNS_LABEL_MAX_SIZE ) {
86- return - ENOMEM ;
87- }
87+ if (answer [i ] == 0xc0 && answer [i + 1 ] == 0x0c ) {
88+ check_pointer :
89+ if (answer [i ] < DNS_LABEL_MAX_SIZE ) {
90+ return - ENOMEM ;
91+ }
8892
89- /* Recovery of the pointer value */
90- ptr = (((answer [0 ] & DNS_LABEL_MAX_SIZE ) << 8 ) + answer [1 ]);
91- if (ptr != dname_ptr ) {
92- return - ENOMEM ;
93+ /* Recovery of the pointer value */
94+ ptr = ((answer [i ] & DNS_LABEL_MAX_SIZE ) << 8 ) + answer [i + 1 ];
95+ if (ptr != dname_ptr ) {
96+ return - ENOMEM ;
97+ }
98+ } else {
99+ dname_len = answer [i ++ ] + 1 ;
100+ while (answer [i ]) {
101+ if (answer [i ] == 0xc0 && answer [i + 1 ] == 0x0c ) {
102+ dname_len += DNS_COMMON_UINT_SIZE ;
103+ goto check_pointer ;
104+ }
105+
106+ if (answer [i ] < DNS_LABEL_MAX_SIZE ) {
107+ dname_len += answer [i ] + 1 ;
108+ }
109+
110+ i ++ ;
111+ }
112+
113+ dname_len ++ ;
93114 }
94115
95116 /*
@@ -111,16 +132,20 @@ int dns_unpack_answer(struct dns_msg_t *dns_msg, int dname_ptr, u32_t *ttl)
111132 /* Only DNS_CLASS_IN answers
112133 * Here we use 2 as an offset because a ptr uses only 2 bytes.
113134 */
114- if (dns_answer_class (DNS_COMMON_UINT_SIZE , answer ) != DNS_CLASS_IN ) {
135+ if (dns_answer_class (dname_len , answer ) != DNS_CLASS_IN ) {
115136 return - EINVAL ;
116137 }
117138
118139 /* TTL value */
119- * ttl = dns_answer_ttl (DNS_COMMON_UINT_SIZE , answer );
120- pos = dns_msg -> answer_offset + DNS_ANSWER_MIN_SIZE ;
121- len = dns_answer_rdlength (DNS_COMMON_UINT_SIZE , answer );
122-
123- switch (dns_answer_type (DNS_COMMON_UINT_SIZE , answer )) {
140+ * ttl = dns_answer_ttl (dname_len , answer );
141+ len = dns_answer_rdlength (dname_len , answer );
142+ pos = dns_msg -> answer_offset + dname_len +
143+ DNS_COMMON_UINT_SIZE + /* class length */
144+ DNS_COMMON_UINT_SIZE + /* type length */
145+ DNS_TTL_LEN +
146+ DNS_RDLENGTH_LEN ;
147+
148+ switch (dns_answer_type (dname_len , answer )) {
124149 case DNS_RR_TYPE_A :
125150 case DNS_RR_TYPE_AAAA :
126151 set_dns_msg_response (dns_msg , DNS_RESPONSE_IP , pos , len );
0 commit comments