aboutsummaryrefslogtreecommitdiff
path: root/src/dns/dnsparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dns/dnsparser.c')
-rw-r--r--src/dns/dnsparser.c86
1 files changed, 43 insertions, 43 deletions
diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c
index 369f90215..d10da1ca9 100644
--- a/src/dns/dnsparser.c
+++ b/src/dns/dnsparser.c
@@ -20,7 +20,7 @@
20 20
21/** 21/**
22 * @file dns/dnsparser.c 22 * @file dns/dnsparser.c
23 * @brief helper library to parse DNS packets. 23 * @brief helper library to parse DNS packets.
24 * @author Philipp Toelke 24 * @author Philipp Toelke
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 */ 26 */
@@ -47,10 +47,10 @@ GNUNET_DNSPARSER_check_label (const char *label)
47{ 47{
48 char *output; 48 char *output;
49 size_t slen; 49 size_t slen;
50 50
51 if (NULL != strchr (label, '.')) 51 if (NULL != strchr (label, '.'))
52 return GNUNET_SYSERR; /* not a label! Did you mean GNUNET_DNSPARSER_check_name? */ 52 return GNUNET_SYSERR; /* not a label! Did you mean GNUNET_DNSPARSER_check_name? */
53 if (IDNA_SUCCESS != 53 if (IDNA_SUCCESS !=
54 idna_to_ascii_8z (label, &output, IDNA_ALLOW_UNASSIGNED)) 54 idna_to_ascii_8z (label, &output, IDNA_ALLOW_UNASSIGNED))
55 return GNUNET_SYSERR; 55 return GNUNET_SYSERR;
56 slen = strlen (output); 56 slen = strlen (output);
@@ -78,7 +78,7 @@ GNUNET_DNSPARSER_check_name (const char *name)
78 char *output; 78 char *output;
79 size_t slen; 79 size_t slen;
80 char *tok; 80 char *tok;
81 81
82 ldup = GNUNET_strdup (name); 82 ldup = GNUNET_strdup (name);
83 for (tok = strtok (ldup, "."); NULL != tok; tok = strtok (NULL, ".")) 83 for (tok = strtok (ldup, "."); NULL != tok; tok = strtok (NULL, "."))
84 if (GNUNET_OK != 84 if (GNUNET_OK !=
@@ -88,7 +88,7 @@ GNUNET_DNSPARSER_check_name (const char *name)
88 return GNUNET_SYSERR; 88 return GNUNET_SYSERR;
89 } 89 }
90 GNUNET_free (ldup); 90 GNUNET_free (ldup);
91 if (IDNA_SUCCESS != 91 if (IDNA_SUCCESS !=
92 idna_to_ascii_8z (name, &output, IDNA_ALLOW_UNASSIGNED)) 92 idna_to_ascii_8z (name, &output, IDNA_ALLOW_UNASSIGNED))
93 return GNUNET_SYSERR; 93 return GNUNET_SYSERR;
94 slen = strlen (output); 94 slen = strlen (output);
@@ -113,7 +113,7 @@ GNUNET_DNSPARSER_free_soa (struct GNUNET_DNSPARSER_SoaRecord *soa)
113 return; 113 return;
114 GNUNET_free_non_null (soa->mname); 114 GNUNET_free_non_null (soa->mname);
115 GNUNET_free_non_null (soa->rname); 115 GNUNET_free_non_null (soa->rname);
116 GNUNET_free (soa); 116 GNUNET_free (soa);
117} 117}
118 118
119 119
@@ -131,7 +131,7 @@ GNUNET_DNSPARSER_free_srv (struct GNUNET_DNSPARSER_SrvRecord *srv)
131 GNUNET_free_non_null (srv->domain_name); 131 GNUNET_free_non_null (srv->domain_name);
132 GNUNET_free_non_null (srv->proto); 132 GNUNET_free_non_null (srv->proto);
133 GNUNET_free_non_null (srv->service); 133 GNUNET_free_non_null (srv->service);
134 GNUNET_free (srv); 134 GNUNET_free (srv);
135} 135}
136 136
137 137
@@ -146,13 +146,13 @@ GNUNET_DNSPARSER_free_mx (struct GNUNET_DNSPARSER_MxRecord *mx)
146 if (NULL == mx) 146 if (NULL == mx)
147 return; 147 return;
148 GNUNET_free_non_null (mx->mxhost); 148 GNUNET_free_non_null (mx->mxhost);
149 GNUNET_free (mx); 149 GNUNET_free (mx);
150} 150}
151 151
152 152
153/** 153/**
154 * Free the given DNS record. 154 * Free the given DNS record.
155 * 155 *
156 * @param r record to free 156 * @param r record to free
157 */ 157 */
158void 158void
@@ -206,7 +206,7 @@ parse_name (const char *udp_payload,
206 size_t xoff; 206 size_t xoff;
207 char *utf8; 207 char *utf8;
208 Idna_rc rc; 208 Idna_rc rc;
209 209
210 ret = GNUNET_strdup (""); 210 ret = GNUNET_strdup ("");
211 while (1) 211 while (1)
212 { 212 {
@@ -301,7 +301,7 @@ parse_name (const char *udp_payload,
301 *off += 2; 301 *off += 2;
302 /* pointers always terminate names */ 302 /* pointers always terminate names */
303 break; 303 break;
304 } 304 }
305 else 305 else
306 { 306 {
307 /* neither pointer nor inline string, not supported... */ 307 /* neither pointer nor inline string, not supported... */
@@ -312,7 +312,7 @@ parse_name (const char *udp_payload,
312 if (0 < strlen(ret)) 312 if (0 < strlen(ret))
313 ret[strlen(ret)-1] = '\0'; /* eat tailing '.' */ 313 ret[strlen(ret)-1] = '\0'; /* eat tailing '.' */
314 return ret; 314 return ret;
315 error: 315 error:
316 GNUNET_break_op (0); 316 GNUNET_break_op (0);
317 GNUNET_free (ret); 317 GNUNET_free (ret);
318 return NULL; 318 return NULL;
@@ -356,7 +356,7 @@ GNUNET_DNSPARSER_parse_query (const char *udp_payload,
356 char *name; 356 char *name;
357 struct GNUNET_TUN_DnsQueryLine ql; 357 struct GNUNET_TUN_DnsQueryLine ql;
358 358
359 name = GNUNET_DNSPARSER_parse_name (udp_payload, 359 name = GNUNET_DNSPARSER_parse_name (udp_payload,
360 udp_payload_length, 360 udp_payload_length,
361 off); 361 off);
362 if (NULL == name) 362 if (NULL == name)
@@ -414,7 +414,7 @@ GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
414 return NULL; 414 return NULL;
415 } 415 }
416 memcpy (&soa_bin, 416 memcpy (&soa_bin,
417 &udp_payload[*off], 417 &udp_payload[*off],
418 sizeof (struct GNUNET_TUN_DnsSoaRecord)); 418 sizeof (struct GNUNET_TUN_DnsSoaRecord));
419 soa->serial = ntohl (soa_bin.serial); 419 soa->serial = ntohl (soa_bin.serial);
420 soa->refresh = ntohl (soa_bin.refresh); 420 soa->refresh = ntohl (soa_bin.refresh);
@@ -450,7 +450,7 @@ GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
450 GNUNET_break_op (0); 450 GNUNET_break_op (0);
451 return NULL; 451 return NULL;
452 } 452 }
453 memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t)); 453 memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t));
454 (*off) += sizeof (uint16_t); 454 (*off) += sizeof (uint16_t);
455 mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord); 455 mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord);
456 mx->preference = ntohs (mxpref); 456 mx->preference = ntohs (mxpref);
@@ -498,8 +498,8 @@ GNUNET_DNSPARSER_parse_srv (const char *r_name,
498 if (*off + sizeof (struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length) 498 if (*off + sizeof (struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length)
499 return NULL; 499 return NULL;
500 memcpy (&srv_bin, 500 memcpy (&srv_bin,
501 &udp_payload[*off], 501 &udp_payload[*off],
502 sizeof (struct GNUNET_TUN_DnsSrvRecord)); 502 sizeof (struct GNUNET_TUN_DnsSrvRecord));
503 (*off) += sizeof (struct GNUNET_TUN_DnsSrvRecord); 503 (*off) += sizeof (struct GNUNET_TUN_DnsSrvRecord);
504 srv = GNUNET_new (struct GNUNET_DNSPARSER_SrvRecord); 504 srv = GNUNET_new (struct GNUNET_DNSPARSER_SrvRecord);
505 srv->priority = ntohs (srv_bin.prio); 505 srv->priority = ntohs (srv_bin.prio);
@@ -565,7 +565,7 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload,
565 size_t old_off; 565 size_t old_off;
566 uint16_t data_len; 566 uint16_t data_len;
567 567
568 name = GNUNET_DNSPARSER_parse_name (udp_payload, 568 name = GNUNET_DNSPARSER_parse_name (udp_payload,
569 udp_payload_length, 569 udp_payload_length,
570 off); 570 off);
571 if (NULL == name) 571 if (NULL == name)
@@ -599,7 +599,7 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload,
599 case GNUNET_DNSPARSER_TYPE_PTR: 599 case GNUNET_DNSPARSER_TYPE_PTR:
600 r->data.hostname = GNUNET_DNSPARSER_parse_name (udp_payload, 600 r->data.hostname = GNUNET_DNSPARSER_parse_name (udp_payload,
601 udp_payload_length, 601 udp_payload_length,
602 off); 602 off);
603 if ( (NULL == r->data.hostname) || 603 if ( (NULL == r->data.hostname) ||
604 (old_off + data_len != *off) ) 604 (old_off + data_len != *off) )
605 return GNUNET_SYSERR; 605 return GNUNET_SYSERR;
@@ -645,7 +645,7 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload,
645 break; 645 break;
646 } 646 }
647 (*off) += data_len; 647 (*off) += data_len;
648 return GNUNET_OK; 648 return GNUNET_OK;
649} 649}
650 650
651 651
@@ -654,7 +654,7 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload,
654 * processing and manipulation. 654 * processing and manipulation.
655 * 655 *
656 * @param udp_payload wire-format of the DNS packet 656 * @param udp_payload wire-format of the DNS packet
657 * @param udp_payload_length number of bytes in @a udp_payload 657 * @param udp_payload_length number of bytes in @a udp_payload
658 * @return NULL on error, otherwise the parsed packet 658 * @return NULL on error, otherwise the parsed packet
659 */ 659 */
660struct GNUNET_DNSPARSER_Packet * 660struct GNUNET_DNSPARSER_Packet *
@@ -664,7 +664,7 @@ GNUNET_DNSPARSER_parse (const char *udp_payload,
664 struct GNUNET_DNSPARSER_Packet *p; 664 struct GNUNET_DNSPARSER_Packet *p;
665 const struct GNUNET_TUN_DnsHeader *dns; 665 const struct GNUNET_TUN_DnsHeader *dns;
666 size_t off; 666 size_t off;
667 unsigned int n; 667 unsigned int n;
668 unsigned int i; 668 unsigned int i;
669 669
670 if (udp_payload_length < sizeof (struct GNUNET_TUN_DnsHeader)) 670 if (udp_payload_length < sizeof (struct GNUNET_TUN_DnsHeader))
@@ -711,7 +711,7 @@ GNUNET_DNSPARSER_parse (const char *udp_payload,
711 udp_payload_length, 711 udp_payload_length,
712 &off, 712 &off,
713 &p->authority_records[i])) 713 &p->authority_records[i]))
714 goto error; 714 goto error;
715 } 715 }
716 n = ntohs (dns->additional_rcount); 716 n = ntohs (dns->additional_rcount);
717 if (n > 0) 717 if (n > 0)
@@ -724,7 +724,7 @@ GNUNET_DNSPARSER_parse (const char *udp_payload,
724 udp_payload_length, 724 udp_payload_length,
725 &off, 725 &off,
726 &p->additional_records[i])) 726 &p->additional_records[i]))
727 goto error; 727 goto error;
728 } 728 }
729 return p; 729 return p;
730 error: 730 error:
@@ -793,7 +793,7 @@ GNUNET_DNSPARSER_builder_add_name (char *dst,
793 if (NULL == name) 793 if (NULL == name)
794 return GNUNET_SYSERR; 794 return GNUNET_SYSERR;
795 795
796 if (IDNA_SUCCESS != 796 if (IDNA_SUCCESS !=
797 (rc = idna_to_ascii_8z (name, &idna_start, IDNA_ALLOW_UNASSIGNED))) 797 (rc = idna_to_ascii_8z (name, &idna_start, IDNA_ALLOW_UNASSIGNED)))
798 { 798 {
799 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 799 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -815,7 +815,7 @@ GNUNET_DNSPARSER_builder_add_name (char *dst,
815 else 815 else
816 len = dot - idna_name; 816 len = dot - idna_name;
817 if ( (len >= 64) || (0 == len) ) 817 if ( (len >= 64) || (0 == len) )
818 goto fail; /* segment too long or empty */ 818 goto fail; /* segment too long or empty */
819 dst[pos++] = (char) (uint8_t) len; 819 dst[pos++] = (char) (uint8_t) len;
820 memcpy (&dst[pos], idna_name, len); 820 memcpy (&dst[pos], idna_name, len);
821 pos += len; 821 pos += len;
@@ -836,7 +836,7 @@ GNUNET_DNSPARSER_builder_add_name (char *dst,
836#else 836#else
837 free (idna_start); 837 free (idna_start);
838#endif 838#endif
839 return GNUNET_NO; 839 return GNUNET_NO;
840} 840}
841 841
842 842
@@ -1004,7 +1004,7 @@ add_record (char *dst,
1004 size_t pos; 1004 size_t pos;
1005 struct GNUNET_TUN_DnsRecordLine rl; 1005 struct GNUNET_TUN_DnsRecordLine rl;
1006 char *name; 1006 char *name;
1007 1007
1008 start = *off; 1008 start = *off;
1009 /* for SRV records, we can create the name from the details 1009 /* for SRV records, we can create the name from the details
1010 of the record if needed */ 1010 of the record if needed */
@@ -1025,9 +1025,9 @@ add_record (char *dst,
1025 1025
1026 pos = *off + sizeof (struct GNUNET_TUN_DnsRecordLine); 1026 pos = *off + sizeof (struct GNUNET_TUN_DnsRecordLine);
1027 switch (record->type) 1027 switch (record->type)
1028 { 1028 {
1029 case GNUNET_DNSPARSER_TYPE_MX: 1029 case GNUNET_DNSPARSER_TYPE_MX:
1030 ret = GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &pos, record->data.mx); 1030 ret = GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &pos, record->data.mx);
1031 break; 1031 break;
1032 case GNUNET_DNSPARSER_TYPE_SOA: 1032 case GNUNET_DNSPARSER_TYPE_SOA:
1033 ret = GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &pos, record->data.soa); 1033 ret = GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &pos, record->data.soa);
@@ -1069,14 +1069,14 @@ add_record (char *dst,
1069 rl.data_len = htons ((uint16_t) (pos - (*off + sizeof (struct GNUNET_TUN_DnsRecordLine)))); 1069 rl.data_len = htons ((uint16_t) (pos - (*off + sizeof (struct GNUNET_TUN_DnsRecordLine))));
1070 memcpy (&dst[*off], &rl, sizeof (struct GNUNET_TUN_DnsRecordLine)); 1070 memcpy (&dst[*off], &rl, sizeof (struct GNUNET_TUN_DnsRecordLine));
1071 *off = pos; 1071 *off = pos;
1072 return GNUNET_OK; 1072 return GNUNET_OK;
1073} 1073}
1074 1074
1075 1075
1076/** 1076/**
1077 * Given a DNS packet @a p, generate the corresponding UDP payload. 1077 * Given a DNS packet @a p, generate the corresponding UDP payload.
1078 * Note that we do not attempt to pack the strings with pointers 1078 * Note that we do not attempt to pack the strings with pointers
1079 * as this would complicate the code and this is about being 1079 * as this would complicate the code and this is about being
1080 * simple and secure, not fast, fancy and broken like bind. 1080 * simple and secure, not fast, fancy and broken like bind.
1081 * 1081 *
1082 * @param p packet to pack 1082 * @param p packet to pack
@@ -1092,14 +1092,14 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
1092 uint16_t max, 1092 uint16_t max,
1093 char **buf, 1093 char **buf,
1094 size_t *buf_length) 1094 size_t *buf_length)
1095{ 1095{
1096 struct GNUNET_TUN_DnsHeader dns; 1096 struct GNUNET_TUN_DnsHeader dns;
1097 size_t off; 1097 size_t off;
1098 char tmp[max]; 1098 char tmp[max];
1099 unsigned int i; 1099 unsigned int i;
1100 int ret; 1100 int ret;
1101 int trc; 1101 int trc;
1102 1102
1103 if ( (p->num_queries > UINT16_MAX) || 1103 if ( (p->num_queries > UINT16_MAX) ||
1104 (p->num_answers > UINT16_MAX) || 1104 (p->num_answers > UINT16_MAX) ||
1105 (p->num_authority_records > UINT16_MAX) || 1105 (p->num_authority_records > UINT16_MAX) ||
@@ -1116,55 +1116,55 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
1116 trc = GNUNET_NO; 1116 trc = GNUNET_NO;
1117 for (i=0;i<p->num_queries;i++) 1117 for (i=0;i<p->num_queries;i++)
1118 { 1118 {
1119 ret = GNUNET_DNSPARSER_builder_add_query (tmp, sizeof (tmp), &off, &p->queries[i]); 1119 ret = GNUNET_DNSPARSER_builder_add_query (tmp, sizeof (tmp), &off, &p->queries[i]);
1120 if (GNUNET_SYSERR == ret) 1120 if (GNUNET_SYSERR == ret)
1121 return GNUNET_SYSERR; 1121 return GNUNET_SYSERR;
1122 if (GNUNET_NO == ret) 1122 if (GNUNET_NO == ret)
1123 { 1123 {
1124 dns.query_count = htons ((uint16_t) (i-1)); 1124 dns.query_count = htons ((uint16_t) (i-1));
1125 trc = GNUNET_YES; 1125 trc = GNUNET_YES;
1126 break; 1126 break;
1127 } 1127 }
1128 } 1128 }
1129 for (i=0;i<p->num_answers;i++) 1129 for (i=0;i<p->num_answers;i++)
1130 { 1130 {
1131 ret = add_record (tmp, sizeof (tmp), &off, &p->answers[i]); 1131 ret = add_record (tmp, sizeof (tmp), &off, &p->answers[i]);
1132 if (GNUNET_SYSERR == ret) 1132 if (GNUNET_SYSERR == ret)
1133 return GNUNET_SYSERR; 1133 return GNUNET_SYSERR;
1134 if (GNUNET_NO == ret) 1134 if (GNUNET_NO == ret)
1135 { 1135 {
1136 dns.answer_rcount = htons ((uint16_t) (i-1)); 1136 dns.answer_rcount = htons ((uint16_t) (i-1));
1137 trc = GNUNET_YES; 1137 trc = GNUNET_YES;
1138 break; 1138 break;
1139 } 1139 }
1140 } 1140 }
1141 for (i=0;i<p->num_authority_records;i++) 1141 for (i=0;i<p->num_authority_records;i++)
1142 { 1142 {
1143 ret = add_record (tmp, sizeof (tmp), &off, &p->authority_records[i]); 1143 ret = add_record (tmp, sizeof (tmp), &off, &p->authority_records[i]);
1144 if (GNUNET_SYSERR == ret) 1144 if (GNUNET_SYSERR == ret)
1145 return GNUNET_SYSERR; 1145 return GNUNET_SYSERR;
1146 if (GNUNET_NO == ret) 1146 if (GNUNET_NO == ret)
1147 { 1147 {
1148 dns.authority_rcount = htons ((uint16_t) (i-1)); 1148 dns.authority_rcount = htons ((uint16_t) (i-1));
1149 trc = GNUNET_YES; 1149 trc = GNUNET_YES;
1150 break; 1150 break;
1151 } 1151 }
1152 } 1152 }
1153 for (i=0;i<p->num_additional_records;i++) 1153 for (i=0;i<p->num_additional_records;i++)
1154 { 1154 {
1155 ret = add_record (tmp, sizeof (tmp), &off, &p->additional_records[i]); 1155 ret = add_record (tmp, sizeof (tmp), &off, &p->additional_records[i]);
1156 if (GNUNET_SYSERR == ret) 1156 if (GNUNET_SYSERR == ret)
1157 return GNUNET_SYSERR; 1157 return GNUNET_SYSERR;
1158 if (GNUNET_NO == ret) 1158 if (GNUNET_NO == ret)
1159 { 1159 {
1160 dns.additional_rcount = htons (i-1); 1160 dns.additional_rcount = htons (i-1);
1161 trc = GNUNET_YES; 1161 trc = GNUNET_YES;
1162 break; 1162 break;
1163 } 1163 }
1164 } 1164 }
1165 1165
1166 if (GNUNET_YES == trc) 1166 if (GNUNET_YES == trc)
1167 dns.flags.message_truncated = 1; 1167 dns.flags.message_truncated = 1;
1168 memcpy (tmp, &dns, sizeof (struct GNUNET_TUN_DnsHeader)); 1168 memcpy (tmp, &dns, sizeof (struct GNUNET_TUN_DnsHeader));
1169 1169
1170 *buf = GNUNET_malloc (off); 1170 *buf = GNUNET_malloc (off);