aboutsummaryrefslogtreecommitdiff
path: root/src/dns
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-04 15:17:53 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-04 15:17:53 +0000
commitc217aa8750bebf75b4a4a0d020cc516e8efad7be (patch)
tree6147622e7fb3e893e9a4c3d4910a61d0c96f06d5 /src/dns
parentc8fe500945cd968e37f2e6c462689e0ada061bce (diff)
downloadgnunet-c217aa8750bebf75b4a4a0d020cc516e8efad7be.tar.gz
gnunet-c217aa8750bebf75b4a4a0d020cc516e8efad7be.zip
-dns parser works now well-enough
Diffstat (limited to 'src/dns')
-rw-r--r--src/dns/dnsparser.c143
-rw-r--r--src/dns/gnunet-dns-monitor.c49
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
58struct 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
58GNUNET_NETWORK_STRUCT_END 67GNUNET_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 */
375static void
376free_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 */
391static void
392free_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
401static void
402free_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 " : "",