@@ -74,6 +74,8 @@ static inline void set_dns_msg_response(struct dns_msg_t *dns_msg, int type,
74
74
75
75
int dns_unpack_answer (struct dns_msg_t * dns_msg , int dname_ptr , u32_t * ttl )
76
76
{
77
+ int dname_len = DNS_COMMON_UINT_SIZE ;
78
+ int i = 0 ;
77
79
u16_t buf_size ;
78
80
u16_t pos ;
79
81
u16_t len ;
@@ -82,14 +84,33 @@ int dns_unpack_answer(struct dns_msg_t *dns_msg, int dname_ptr, u32_t *ttl)
82
84
83
85
answer = dns_msg -> msg + dns_msg -> answer_offset ;
84
86
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
+ }
88
92
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 ++ ;
93
114
}
94
115
95
116
/*
@@ -111,16 +132,20 @@ int dns_unpack_answer(struct dns_msg_t *dns_msg, int dname_ptr, u32_t *ttl)
111
132
/* Only DNS_CLASS_IN answers
112
133
* Here we use 2 as an offset because a ptr uses only 2 bytes.
113
134
*/
114
- if (dns_answer_class (DNS_COMMON_UINT_SIZE , answer ) != DNS_CLASS_IN ) {
135
+ if (dns_answer_class (dname_len , answer ) != DNS_CLASS_IN ) {
115
136
return - EINVAL ;
116
137
}
117
138
118
139
/* 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 )) {
124
149
case DNS_RR_TYPE_A :
125
150
case DNS_RR_TYPE_AAAA :
126
151
set_dns_msg_response (dns_msg , DNS_RESPONSE_IP , pos , len );
0 commit comments