diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-04 10:41:18 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-04 10:41:18 +0000 |
commit | e7e48851ecbaad0a42d234c19ac2cc428e98f764 (patch) | |
tree | 33a61b470eda34f709c49f067908f27d9b003ed7 /src/dns | |
parent | 3153e40168a6463327a2e76ae708d74abfa48cc4 (diff) | |
download | gnunet-e7e48851ecbaad0a42d234c19ac2cc428e98f764.tar.gz gnunet-e7e48851ecbaad0a42d234c19ac2cc428e98f764.zip |
-dns parser basics
Diffstat (limited to 'src/dns')
-rw-r--r-- | src/dns/dnsparser.c | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c index c2fd1671d..53c571edd 100644 --- a/src/dns/dnsparser.c +++ b/src/dns/dnsparser.c | |||
@@ -27,6 +27,206 @@ | |||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_dnsparser_lib.h" | 28 | #include "gnunet_dnsparser_lib.h" |
29 | 29 | ||
30 | |||
31 | // DNS-Stuff | ||
32 | GNUNET_NETWORK_STRUCT_BEGIN | ||
33 | struct dns_header | ||
34 | { | ||
35 | uint16_t id GNUNET_PACKED; | ||
36 | struct GNUNET_DNSPARSER_Flags flags GNUNET_PACKED; | ||
37 | uint16_t query_count GNUNET_PACKED; // number of questions | ||
38 | uint16_t answer_rcount GNUNET_PACKED; // number of answers | ||
39 | uint16_t authority_rcount GNUNET_PACKED; // number of authority-records | ||
40 | uint16_t additional_rcount GNUNET_PACKED; // number of additional records | ||
41 | }; | ||
42 | GNUNET_NETWORK_STRUCT_END | ||
43 | |||
44 | |||
45 | /** | ||
46 | * Parse a DNS query entry. | ||
47 | * | ||
48 | * @param udp_payload entire UDP payload | ||
49 | * @param udp_payload_length length of udp_payload | ||
50 | * @param off pointer to the offset of the query to parse in the udp_payload (to be | ||
51 | * incremented by the size of the query) | ||
52 | * @param q where to write the query information | ||
53 | * @return GNUNET_OK on success, GNUNET_SYSERR if the query is malformed | ||
54 | */ | ||
55 | static int | ||
56 | parse_query (const char *udp_payload, | ||
57 | size_t udp_payload_length, | ||
58 | size_t *off, | ||
59 | struct GNUNET_DNSPARSER_Query *q) | ||
60 | { | ||
61 | return GNUNET_SYSERR; | ||
62 | } | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Parse a DNS record entry. | ||
67 | * | ||
68 | * @param udp_payload entire UDP payload | ||
69 | * @param udp_payload_length length of udp_payload | ||
70 | * @param off pointer to the offset of the record to parse in the udp_payload (to be | ||
71 | * incremented by the size of the record) | ||
72 | * @param r where to write the record information | ||
73 | * @return GNUNET_OK on success, GNUNET_SYSERR if the record is malformed | ||
74 | */ | ||
75 | static int | ||
76 | parse_record (const char *udp_payload, | ||
77 | size_t udp_payload_length, | ||
78 | size_t *off, | ||
79 | struct GNUNET_DNSPARSER_Record *r) | ||
80 | { | ||
81 | return GNUNET_SYSERR; | ||
82 | } | ||
83 | |||
84 | |||
85 | |||
86 | /** | ||
87 | * Parse a UDP payload of a DNS packet in to a nice struct for further | ||
88 | * processing and manipulation. | ||
89 | * | ||
90 | * @param udp_payload wire-format of the DNS packet | ||
91 | * @param udp_payload_length number of bytes in udp_payload | ||
92 | * @return NULL on error, otherwise the parsed packet | ||
93 | */ | ||
94 | struct GNUNET_DNSPARSER_Packet * | ||
95 | GNUNET_DNSPARSER_parse (const char *udp_payload, | ||
96 | size_t udp_payload_length) | ||
97 | { | ||
98 | struct GNUNET_DNSPARSER_Packet *p; | ||
99 | const struct dns_header *dns; | ||
100 | size_t off; | ||
101 | unsigned int n; | ||
102 | unsigned int i; | ||
103 | |||
104 | if (udp_payload_length < sizeof (struct dns_header)) | ||
105 | return NULL; | ||
106 | dns = (const struct dns_header *) udp_payload; | ||
107 | off = sizeof (struct dns_header); | ||
108 | p = GNUNET_malloc (sizeof (struct GNUNET_DNSPARSER_Packet)); | ||
109 | p->flags = dns->flags; | ||
110 | p->id = dns->id; | ||
111 | n = ntohs (dns->query_count); | ||
112 | if (n > 0) | ||
113 | { | ||
114 | p->queries = GNUNET_malloc (n * sizeof (struct GNUNET_DNSPARSER_Query)); | ||
115 | p->num_queries = n; | ||
116 | for (i=0;i<n;i++) | ||
117 | if (GNUNET_OK != | ||
118 | parse_query (udp_payload, | ||
119 | udp_payload_length, | ||
120 | &off, | ||
121 | &p->queries[i])) | ||
122 | goto error; | ||
123 | } | ||
124 | n = ntohs (dns->answer_rcount); | ||
125 | if (n > 0) | ||
126 | { | ||
127 | p->answers = GNUNET_malloc (n * sizeof (struct GNUNET_DNSPARSER_Record)); | ||
128 | p->num_answers = n; | ||
129 | for (i=0;i<n;i++) | ||
130 | if (GNUNET_OK != | ||
131 | parse_record (udp_payload, | ||
132 | udp_payload_length, | ||
133 | &off, | ||
134 | &p->answers[i])) | ||
135 | goto error; | ||
136 | } | ||
137 | n = ntohs (dns->authority_rcount); | ||
138 | if (n > 0) | ||
139 | { | ||
140 | p->authority_records = GNUNET_malloc (n * sizeof (struct GNUNET_DNSPARSER_Record)); | ||
141 | p->num_authority_records = n; | ||
142 | for (i=0;i<n;i++) | ||
143 | if (GNUNET_OK != | ||
144 | parse_record (udp_payload, | ||
145 | udp_payload_length, | ||
146 | &off, | ||
147 | &p->authority_records[i])) | ||
148 | goto error; | ||
149 | } | ||
150 | n = ntohs (dns->additional_rcount); | ||
151 | if (n > 0) | ||
152 | { | ||
153 | p->additional_records = GNUNET_malloc (n * sizeof (struct GNUNET_DNSPARSER_Record)); | ||
154 | p->num_additional_records = n; | ||
155 | for (i=0;i<n;i++) | ||
156 | if (GNUNET_OK != | ||
157 | parse_record (udp_payload, | ||
158 | udp_payload_length, | ||
159 | &off, | ||
160 | &p->additional_records[i])) | ||
161 | goto error; | ||
162 | } | ||
163 | return p; | ||
164 | error: | ||
165 | GNUNET_DNSPARSER_free_packet (p); | ||
166 | return NULL; | ||
167 | } | ||
168 | |||
169 | |||
170 | /** | ||
171 | * Free memory taken by a packet. | ||
172 | * | ||
173 | * @param p packet to free | ||
174 | */ | ||
175 | void | ||
176 | GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p) | ||
177 | { | ||
178 | unsigned int i; | ||
179 | |||
180 | for (i=0;i<p->num_queries;i++) | ||
181 | GNUNET_free_non_null (p->queries[i].name); | ||
182 | GNUNET_free_non_null (p->queries); | ||
183 | for (i=0;i<p->num_answers;i++) | ||
184 | { | ||
185 | GNUNET_free_non_null (p->answers[i].name); | ||
186 | GNUNET_free_non_null (p->answers[i].data); | ||
187 | } | ||
188 | GNUNET_free_non_null (p->answers); | ||
189 | for (i=0;i<p->num_authority_records;i++) | ||
190 | { | ||
191 | GNUNET_free_non_null (p->authority_records[i].name); | ||
192 | GNUNET_free_non_null (p->authority_records[i].data); | ||
193 | } | ||
194 | GNUNET_free_non_null (p->authority_records); | ||
195 | for (i=0;i<p->num_additional_records;i++) | ||
196 | { | ||
197 | GNUNET_free_non_null (p->additional_records[i].name); | ||
198 | GNUNET_free_non_null (p->additional_records[i].data); | ||
199 | } | ||
200 | GNUNET_free_non_null (p->additional_records); | ||
201 | GNUNET_free (p); | ||
202 | } | ||
203 | |||
204 | |||
205 | /** | ||
206 | * Given a DNS packet, generate the corresponding UDP payload. | ||
207 | * | ||
208 | * @param p packet to pack | ||
209 | * @param buf set to a buffer with the packed message | ||
210 | * @param buf_length set to the length of buf | ||
211 | * @return GNUNET_SYSERR if 'p' is invalid | ||
212 | * GNUNET_NO if 'p' was truncated (but there is still a result in 'buf') | ||
213 | * GNUNET_OK if 'p' was packed completely into '*buf' | ||
214 | */ | ||
215 | int | ||
216 | GNUNET_DNSPARSER_pack (struct GNUNET_DNSPARSER_Packet *p, | ||
217 | char **buf, | ||
218 | size_t *buf_length) | ||
219 | { | ||
220 | // FIXME: not implemented | ||
221 | GNUNET_break (0); | ||
222 | return GNUNET_SYSERR; | ||
223 | } | ||
224 | |||
225 | |||
226 | |||
227 | |||
228 | /* legacy code follows */ | ||
229 | |||
30 | /** | 230 | /** |
31 | * Parse a name from DNS to a normal .-delimited, 0-terminated string. | 231 | * Parse a name from DNS to a normal .-delimited, 0-terminated string. |
32 | * | 232 | * |