| 133 /***************************************/ |
133 /***************************************/ |
| 134 /* Functions for sending mDNS messages */ |
134 /* Functions for sending mDNS messages */ |
| 135 /***************************************/ |
135 /***************************************/ |
| 136 |
136 |
| 137 static int |
137 static int |
| |
138 mdns_getlength_RR_txt(void *rdata) |
| |
139 { |
| |
140 GSList *cur; |
| |
141 ResourceRecordTXTRDataNode *node; |
| |
142 int rdlength = 0; |
| |
143 |
| |
144 for (cur = (GSList *)rdata; cur != NULL; cur = cur->next) { |
| |
145 node = (ResourceRecordTXTRDataNode *)cur->data; |
| |
146 rdlength += 1 + strlen(node->name); |
| |
147 if (node->value != NULL) |
| |
148 rdlength += 1 + strlen(node->value); |
| |
149 } |
| |
150 |
| |
151 return rdlength; |
| |
152 } |
| |
153 |
| |
154 static int |
| 138 mdns_getlength_RR(const ResourceRecord *rr) |
155 mdns_getlength_RR(const ResourceRecord *rr) |
| 139 { |
156 { |
| 140 int ret = 0; |
157 int ret = 0; |
| 141 |
158 |
| 142 ret += strlen(rr->name) + 2; |
159 ret += strlen(rr->name) + 2; |
| 143 ret += 10; |
160 ret += 10; |
| 144 |
161 |
| 145 switch (rr->type) { |
162 switch (rr->type) { |
| 146 case RENDEZVOUS_RRTYPE_PTR: |
163 case RENDEZVOUS_RRTYPE_PTR: |
| 147 ret += strlen((const char *)rr->rdata) + 2; |
164 ret += strlen((const char *)rr->rdata) + 2; |
| |
165 break; |
| |
166 |
| |
167 case RENDEZVOUS_RRTYPE_TXT: |
| |
168 ret += mdns_getlength_RR_txt(rr->rdata); |
| 148 break; |
169 break; |
| 149 } |
170 } |
| 150 |
171 |
| 151 return ret; |
172 return ret; |
| 152 } |
173 } |
| 178 |
199 |
| 179 i += mdns_put_name(data, datalen, offset + i, rr->name); |
200 i += mdns_put_name(data, datalen, offset + i, rr->name); |
| 180 i += util_put16(&data[offset + i], rr->type); |
201 i += util_put16(&data[offset + i], rr->type); |
| 181 i += util_put16(&data[offset + i], rr->class); |
202 i += util_put16(&data[offset + i], rr->class); |
| 182 i += util_put32(&data[offset + i], rr->ttl); |
203 i += util_put32(&data[offset + i], rr->ttl); |
| 183 i += util_put16(&data[offset + i], rr->rdlength); |
|
| 184 |
204 |
| 185 switch (rr->type) { |
205 switch (rr->type) { |
| 186 case RENDEZVOUS_RRTYPE_PTR: |
206 case RENDEZVOUS_RRTYPE_PTR: |
| |
207 i += util_put16(&data[offset + i], strlen((const char *)rr->rdata) + 2); |
| 187 i += mdns_put_name(data, datalen, offset + i, (const char *)rr->rdata); |
208 i += mdns_put_name(data, datalen, offset + i, (const char *)rr->rdata); |
| 188 break; |
209 break; |
| |
210 |
| |
211 case RENDEZVOUS_RRTYPE_TXT: { |
| |
212 GSList *cur; |
| |
213 ResourceRecordTXTRDataNode *node; |
| |
214 int rdlength = mdns_getlength_RR_txt(rr->rdata); |
| |
215 int mylength; |
| |
216 |
| |
217 i += util_put16(&data[offset + i], rdlength); |
| |
218 for (cur = (GSList *)rr->rdata; cur != NULL; cur = cur->next) { |
| |
219 node = (ResourceRecordTXTRDataNode *)cur->data; |
| |
220 mylength = 1 + strlen(node->name); |
| |
221 if (node->value) |
| |
222 mylength += 1 + strlen(node->value); |
| |
223 i += util_put8(&data[offset + i], mylength - 1); |
| |
224 memcpy(&data[offset + i], node->name, strlen(node->name)); |
| |
225 i += strlen(node->name); |
| |
226 if (node->value) { |
| |
227 data[offset + i] = '='; |
| |
228 i++; |
| |
229 memcpy(&data[offset + i], node->value, strlen(node->value)); |
| |
230 i += strlen(node->value); |
| |
231 } |
| |
232 } |
| |
233 } break; |
| 189 } |
234 } |
| 190 |
235 |
| 191 return i; |
236 return i; |
| 192 } |
237 } |
| 193 |
238 |
| 312 dns->answers = (ResourceRecord *)g_malloc(1 * sizeof(ResourceRecord)); |
357 dns->answers = (ResourceRecord *)g_malloc(1 * sizeof(ResourceRecord)); |
| 313 dns->answers[0].name = g_strdup(name); |
358 dns->answers[0].name = g_strdup(name); |
| 314 dns->answers[0].type = RENDEZVOUS_RRTYPE_PTR; |
359 dns->answers[0].type = RENDEZVOUS_RRTYPE_PTR; |
| 315 dns->answers[0].class = 0x0001; |
360 dns->answers[0].class = 0x0001; |
| 316 dns->answers[0].ttl = 0x00001c20; |
361 dns->answers[0].ttl = 0x00001c20; |
| 317 dns->answers[0].rdlength = strlen(domain) + 2; |
362 dns->answers[0].rdlength = 0x0000; /* Set automatically */ |
| 318 dns->answers[0].rdata = (void *)g_strdup(domain); |
363 dns->answers[0].rdata = (void *)g_strdup(domain); |
| 319 |
364 |
| 320 dns->authority = NULL; |
365 dns->authority = NULL; |
| 321 dns->additional = NULL; |
366 dns->additional = NULL; |
| 322 |
367 |
| 323 mdns_send_dns(fd, dns); |
368 mdns_send_dns(fd, dns); |
| |
369 |
| |
370 mdns_free(dns); |
| |
371 |
| |
372 return ret; |
| |
373 } |
| |
374 |
| |
375 int |
| |
376 mdns_advertise_txt(int fd, const char *name, const GSList *rdata) |
| |
377 { |
| |
378 int ret; |
| |
379 DNSPacket *dns; |
| |
380 |
| |
381 if ((strlen(name) > 255)) { |
| |
382 return -EINVAL; |
| |
383 } |
| |
384 |
| |
385 dns = (DNSPacket *)g_malloc(sizeof(DNSPacket)); |
| |
386 dns->header.id = 0x0000; |
| |
387 dns->header.flags = 0x8400; |
| |
388 dns->header.numquestions = 0x0000; |
| |
389 dns->header.numanswers = 0x0001; |
| |
390 dns->header.numauthority = 0x0000; |
| |
391 dns->header.numadditional = 0x0000; |
| |
392 dns->questions = NULL; |
| |
393 |
| |
394 dns->answers = (ResourceRecord *)g_malloc(1 * sizeof(ResourceRecord)); |
| |
395 dns->answers[0].name = g_strdup(name); |
| |
396 dns->answers[0].type = RENDEZVOUS_RRTYPE_TXT; |
| |
397 dns->answers[0].class = 0x0001; |
| |
398 dns->answers[0].ttl = 0x00001c20; |
| |
399 dns->answers[0].rdlength = 0x0000; /* Set automatically */ |
| |
400 dns->answers[0].rdata = (void *)rdata; |
| |
401 |
| |
402 dns->authority = NULL; |
| |
403 dns->additional = NULL; |
| |
404 |
| |
405 mdns_send_dns(fd, dns); |
| |
406 |
| |
407 /* The hash table should be freed by the caller of this function */ |
| |
408 dns->answers[0].rdata = NULL; |
| 324 |
409 |
| 325 mdns_free(dns); |
410 mdns_free(dns); |
| 326 |
411 |
| 327 return ret; |
412 return ret; |
| 328 } |
413 } |