diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-04 15:17:53 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-04 15:17:53 +0000 |
commit | c217aa8750bebf75b4a4a0d020cc516e8efad7be (patch) | |
tree | 6147622e7fb3e893e9a4c3d4910a61d0c96f06d5 /src/dns | |
parent | c8fe500945cd968e37f2e6c462689e0ada061bce (diff) | |
download | gnunet-c217aa8750bebf75b4a4a0d020cc516e8efad7be.tar.gz gnunet-c217aa8750bebf75b4a4a0d020cc516e8efad7be.zip |
-dns parser works now well-enough
Diffstat (limited to 'src/dns')
-rw-r--r-- | src/dns/dnsparser.c | 143 | ||||
-rw-r--r-- | src/dns/gnunet-dns-monitor.c | 49 |
2 files changed, 170 insertions, 22 deletions
diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c index 468c984aa..e02ce73fb 100644 --- a/src/dns/dnsparser.c +++ b/src/dns/dnsparser.c | |||
@@ -55,6 +55,15 @@ struct record_line | |||
55 | uint16_t data_len GNUNET_PACKED; | 55 | uint16_t data_len GNUNET_PACKED; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | struct soa_data | ||
59 | { | ||
60 | uint32_t serial GNUNET_PACKED; | ||
61 | uint32_t refresh GNUNET_PACKED; | ||
62 | uint32_t retry GNUNET_PACKED; | ||
63 | uint32_t expire GNUNET_PACKED; | ||
64 | uint32_t minimum GNUNET_PACKED; | ||
65 | }; | ||
66 | |||
58 | GNUNET_NETWORK_STRUCT_END | 67 | GNUNET_NETWORK_STRUCT_END |
59 | 68 | ||
60 | 69 | ||
@@ -191,6 +200,9 @@ parse_record (const char *udp_payload, | |||
191 | { | 200 | { |
192 | char *name; | 201 | char *name; |
193 | struct record_line rl; | 202 | struct record_line rl; |
203 | size_t old_off; | ||
204 | struct soa_data soa; | ||
205 | uint16_t mxpref; | ||
194 | 206 | ||
195 | name = parse_name (udp_payload, | 207 | name = parse_name (udp_payload, |
196 | udp_payload_length, | 208 | udp_payload_length, |
@@ -201,7 +213,7 @@ parse_record (const char *udp_payload, | |||
201 | if (*off + sizeof (struct record_line) > udp_payload_length) | 213 | if (*off + sizeof (struct record_line) > udp_payload_length) |
202 | return GNUNET_SYSERR; | 214 | return GNUNET_SYSERR; |
203 | memcpy (&rl, &udp_payload[*off], sizeof (rl)); | 215 | memcpy (&rl, &udp_payload[*off], sizeof (rl)); |
204 | *off += sizeof (rl); | 216 | (*off) += sizeof (rl); |
205 | r->type = ntohs (rl.type); | 217 | r->type = ntohs (rl.type); |
206 | r->class = ntohs (rl.class); | 218 | r->class = ntohs (rl.class); |
207 | r->expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, | 219 | r->expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, |
@@ -211,9 +223,62 @@ parse_record (const char *udp_payload, | |||
211 | return GNUNET_SYSERR; | 223 | return GNUNET_SYSERR; |
212 | if (0 == r->data_len) | 224 | if (0 == r->data_len) |
213 | return GNUNET_OK; | 225 | return GNUNET_OK; |
214 | r->data = GNUNET_malloc (r->data_len); | 226 | switch (r->type) |
215 | memcpy (r->data, &udp_payload[*off], r->data_len); | 227 | { |
216 | *off += r->data_len; | 228 | case GNUNET_DNSPARSER_TYPE_NS: |
229 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
230 | case GNUNET_DNSPARSER_TYPE_PTR: | ||
231 | old_off = *off; | ||
232 | r->data.hostname = parse_name (udp_payload, | ||
233 | udp_payload_length, | ||
234 | off); | ||
235 | if ( (NULL == r->data.hostname) || | ||
236 | (old_off + r->data_len != *off) ) | ||
237 | return GNUNET_SYSERR; | ||
238 | return GNUNET_OK; | ||
239 | case GNUNET_DNSPARSER_TYPE_SOA: | ||
240 | old_off = *off; | ||
241 | r->data.soa = GNUNET_malloc (sizeof (struct GNUNET_DNSPARSER_SoaRecord)); | ||
242 | r->data.soa->mname = parse_name (udp_payload, | ||
243 | udp_payload_length, | ||
244 | off); | ||
245 | r->data.soa->rname = parse_name (udp_payload, | ||
246 | udp_payload_length, | ||
247 | off); | ||
248 | if ( (NULL == r->data.soa->mname) || | ||
249 | (NULL == r->data.soa->rname) || | ||
250 | (*off + sizeof (soa) > udp_payload_length) ) | ||
251 | return GNUNET_SYSERR; | ||
252 | memcpy (&soa, &udp_payload[*off], sizeof (soa)); | ||
253 | r->data.soa->serial = ntohl (soa.serial); | ||
254 | r->data.soa->refresh = ntohl (soa.refresh); | ||
255 | r->data.soa->retry = ntohl (soa.retry); | ||
256 | r->data.soa->expire = ntohl (soa.expire); | ||
257 | r->data.soa->minimum_ttl = ntohl (soa.minimum); | ||
258 | (*off) += sizeof (soa); | ||
259 | if (old_off + r->data_len != *off) | ||
260 | return GNUNET_SYSERR; | ||
261 | return GNUNET_OK; | ||
262 | case GNUNET_DNSPARSER_TYPE_MX: | ||
263 | old_off = *off; | ||
264 | if (*off + sizeof (uint16_t) > udp_payload_length) | ||
265 | return GNUNET_SYSERR; | ||
266 | memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t)); | ||
267 | (*off) += sizeof (uint16_t); | ||
268 | r->data.mx = GNUNET_malloc (sizeof (struct GNUNET_DNSPARSER_MxRecord)); | ||
269 | r->data.mx->preference = ntohs (mxpref); | ||
270 | r->data.mx->mxhost = parse_name (udp_payload, | ||
271 | udp_payload_length, | ||
272 | off); | ||
273 | if (old_off + r->data_len != *off) | ||
274 | return GNUNET_SYSERR; | ||
275 | return GNUNET_OK; | ||
276 | default: | ||
277 | r->data.raw = GNUNET_malloc (r->data_len); | ||
278 | memcpy (r->data.raw, &udp_payload[*off], r->data_len); | ||
279 | break; | ||
280 | } | ||
281 | (*off) += r->data_len; | ||
217 | return GNUNET_OK; | 282 | return GNUNET_OK; |
218 | } | 283 | } |
219 | 284 | ||
@@ -303,6 +368,61 @@ GNUNET_DNSPARSER_parse (const char *udp_payload, | |||
303 | 368 | ||
304 | 369 | ||
305 | /** | 370 | /** |
371 | * Free SOA information record. | ||
372 | * | ||
373 | * @param soa record to free | ||
374 | */ | ||
375 | static void | ||
376 | free_soa (struct GNUNET_DNSPARSER_SoaRecord *soa) | ||
377 | { | ||
378 | if (NULL == soa) | ||
379 | return; | ||
380 | GNUNET_free_non_null (soa->mname); | ||
381 | GNUNET_free_non_null (soa->rname); | ||
382 | GNUNET_free (soa); | ||
383 | } | ||
384 | |||
385 | |||
386 | /** | ||
387 | * Free MX information record. | ||
388 | * | ||
389 | * @param mx record to free | ||
390 | */ | ||
391 | static void | ||
392 | free_mx (struct GNUNET_DNSPARSER_MxRecord *mx) | ||
393 | { | ||
394 | if (NULL == mx) | ||
395 | return; | ||
396 | GNUNET_free_non_null (mx->mxhost); | ||
397 | GNUNET_free (mx); | ||
398 | } | ||
399 | |||
400 | |||
401 | static void | ||
402 | free_record (struct GNUNET_DNSPARSER_Record *r) | ||
403 | { | ||
404 | GNUNET_free_non_null (r->name); | ||
405 | switch (r->type) | ||
406 | { | ||
407 | case GNUNET_DNSPARSER_TYPE_MX: | ||
408 | free_mx (r->data.mx); | ||
409 | break; | ||
410 | case GNUNET_DNSPARSER_TYPE_SOA: | ||
411 | free_soa (r->data.soa); | ||
412 | break; | ||
413 | case GNUNET_DNSPARSER_TYPE_NS: | ||
414 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
415 | case GNUNET_DNSPARSER_TYPE_PTR: | ||
416 | GNUNET_free_non_null (r->data.hostname); | ||
417 | break; | ||
418 | default: | ||
419 | GNUNET_free_non_null (r->data.raw); | ||
420 | break; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | |||
425 | /** | ||
306 | * Free memory taken by a packet. | 426 | * Free memory taken by a packet. |
307 | * | 427 | * |
308 | * @param p packet to free | 428 | * @param p packet to free |
@@ -316,22 +436,13 @@ GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p) | |||
316 | GNUNET_free_non_null (p->queries[i].name); | 436 | GNUNET_free_non_null (p->queries[i].name); |
317 | GNUNET_free_non_null (p->queries); | 437 | GNUNET_free_non_null (p->queries); |
318 | for (i=0;i<p->num_answers;i++) | 438 | for (i=0;i<p->num_answers;i++) |
319 | { | 439 | free_record (&p->answers[i]); |
320 | GNUNET_free_non_null (p->answers[i].name); | ||
321 | GNUNET_free_non_null (p->answers[i].data); | ||
322 | } | ||
323 | GNUNET_free_non_null (p->answers); | 440 | GNUNET_free_non_null (p->answers); |
324 | for (i=0;i<p->num_authority_records;i++) | 441 | for (i=0;i<p->num_authority_records;i++) |
325 | { | 442 | free_record (&p->authority_records[i]); |
326 | GNUNET_free_non_null (p->authority_records[i].name); | ||
327 | GNUNET_free_non_null (p->authority_records[i].data); | ||
328 | } | ||
329 | GNUNET_free_non_null (p->authority_records); | 443 | GNUNET_free_non_null (p->authority_records); |
330 | for (i=0;i<p->num_additional_records;i++) | 444 | for (i=0;i<p->num_additional_records;i++) |
331 | { | 445 | free_record (&p->additional_records[i]); |
332 | GNUNET_free_non_null (p->additional_records[i].name); | ||
333 | GNUNET_free_non_null (p->additional_records[i].data); | ||
334 | } | ||
335 | GNUNET_free_non_null (p->additional_records); | 446 | GNUNET_free_non_null (p->additional_records); |
336 | GNUNET_free (p); | 447 | GNUNET_free (p); |
337 | } | 448 | } |
diff --git a/src/dns/gnunet-dns-monitor.c b/src/dns/gnunet-dns-monitor.c index c8fb646e5..96d2a4959 100644 --- a/src/dns/gnunet-dns-monitor.c +++ b/src/dns/gnunet-dns-monitor.c | |||
@@ -70,8 +70,6 @@ get_type (uint16_t type) | |||
70 | case GNUNET_DNSPARSER_TYPE_MX: return "MX"; | 70 | case GNUNET_DNSPARSER_TYPE_MX: return "MX"; |
71 | case GNUNET_DNSPARSER_TYPE_TXT: return "TXT"; | 71 | case GNUNET_DNSPARSER_TYPE_TXT: return "TXT"; |
72 | case GNUNET_DNSPARSER_TYPE_AAAA: return "AAAA"; | 72 | case GNUNET_DNSPARSER_TYPE_AAAA: return "AAAA"; |
73 | case GNUNET_DNSPARSER_TYPE_IXFR: return "IXFR"; | ||
74 | case GNUNET_DNSPARSER_TYPE_AXFR: return "AXFR"; | ||
75 | } | 73 | } |
76 | GNUNET_snprintf (buf, sizeof (buf), "%u", (unsigned int) type); | 74 | GNUNET_snprintf (buf, sizeof (buf), "%u", (unsigned int) type); |
77 | return buf; | 75 | return buf; |
@@ -134,16 +132,55 @@ display_record (const struct GNUNET_DNSPARSER_Record *record) | |||
134 | if (record->data_len != sizeof (struct in_addr)) | 132 | if (record->data_len != sizeof (struct in_addr)) |
135 | format = "<invalid>"; | 133 | format = "<invalid>"; |
136 | else | 134 | else |
137 | format = inet_ntop (AF_INET, record->data, buf, sizeof (buf)); | 135 | format = inet_ntop (AF_INET, record->data.raw, buf, sizeof (buf)); |
138 | break; | 136 | break; |
139 | case GNUNET_DNSPARSER_TYPE_AAAA: | 137 | case GNUNET_DNSPARSER_TYPE_AAAA: |
140 | if (record->data_len != sizeof (struct in6_addr)) | 138 | if (record->data_len != sizeof (struct in6_addr)) |
141 | format = "<invalid>"; | 139 | format = "<invalid>"; |
142 | else | 140 | else |
143 | format = inet_ntop (AF_INET6, record->data, buf, sizeof (buf)); | 141 | format = inet_ntop (AF_INET6, record->data.raw, buf, sizeof (buf)); |
144 | break; | 142 | break; |
143 | case GNUNET_DNSPARSER_TYPE_NS: | ||
145 | case GNUNET_DNSPARSER_TYPE_CNAME: | 144 | case GNUNET_DNSPARSER_TYPE_CNAME: |
146 | tmp = GNUNET_strdup ("FIXME"); | 145 | case GNUNET_DNSPARSER_TYPE_PTR: |
146 | format = record->data.hostname; | ||
147 | break; | ||
148 | case GNUNET_DNSPARSER_TYPE_SOA: | ||
149 | if (record->data.soa == NULL) | ||
150 | format = "<invalid>"; | ||
151 | else | ||
152 | { | ||
153 | GNUNET_asprintf (&tmp, | ||
154 | "origin: %s, mail: %s, serial = %u, refresh = %u s, retry = %u s, expire = %u s, minimum = %u s", | ||
155 | record->data.soa->mname, | ||
156 | record->data.soa->rname, | ||
157 | (unsigned int) record->data.soa->serial, | ||
158 | (unsigned int) record->data.soa->refresh, | ||
159 | (unsigned int) record->data.soa->retry, | ||
160 | (unsigned int) record->data.soa->expire, | ||
161 | (unsigned int) record->data.soa->minimum_ttl); | ||
162 | format = tmp; | ||
163 | } | ||
164 | break; | ||
165 | case GNUNET_DNSPARSER_TYPE_MX: | ||
166 | if (record->data.mx == NULL) | ||
167 | format = "<invalid>"; | ||
168 | else | ||
169 | { | ||
170 | GNUNET_asprintf (&tmp, | ||
171 | "%u: %s", | ||
172 | record->data.mx->preference, | ||
173 | record->data.mx->mxhost); | ||
174 | format = tmp; | ||
175 | } | ||
176 | break; | ||
177 | case GNUNET_DNSPARSER_TYPE_TXT: | ||
178 | GNUNET_asprintf (&tmp, | ||
179 | "%.*s", | ||
180 | (unsigned int) record->data_len, | ||
181 | record->data.raw); | ||
182 | format = tmp; | ||
183 | break; | ||
147 | default: | 184 | default: |
148 | format = "<payload>"; | 185 | format = "<payload>"; |
149 | break; | 186 | break; |
@@ -215,7 +252,7 @@ display_request (void *cls, | |||
215 | return; | 252 | return; |
216 | } | 253 | } |
217 | fprintf (stdout, | 254 | fprintf (stdout, |
218 | "%s with ID: %5u Flags: %s%s%s%s%s%s Return Code: %s Opcode: %s\n", | 255 | "%s with ID: %5u Flags: %s%s%s%s%s%s, Return Code: %s, Opcode: %s\n", |
219 | p->flags.query_or_response ? "Response" : "Query", | 256 | p->flags.query_or_response ? "Response" : "Query", |
220 | p->id, | 257 | p->id, |
221 | p->flags.recursion_desired ? "RD " : "", | 258 | p->flags.recursion_desired ? "RD " : "", |