1 /* 2 * Copyright (C) 2014 John Crispin <blogic@openwrt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License version 2.1 6 * as published by the Free Software Foundation 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14 #define _GNU_SOURCE 15 #include <sys/types.h> 16 #include <sys/stat.h> 17 18 #include <fcntl.h> 19 #include <ifaddrs.h> 20 #include <time.h> 21 #include <stdio.h> 22 #include <unistd.h> 23 #include <sys/types.h> 24 #include <sys/socket.h> 25 #include <netinet/in.h> 26 #include <arpa/inet.h> 27 #include <arpa/nameser.h> 28 #include <resolv.h> 29 #include <stdlib.h> 30 #include <string.h> 31 32 #include <libubox/uloop.h> 33 #include <libubox/usock.h> 34 #include <libubox/utils.h> 35 #include <libubox/avl-cmp.h> 36 37 #include "announce.h" 38 #include "util.h" 39 #include "dns.h" 40 #include "cache.h" 41 #include "service.h" 42 #include "interface.h" 43 44 #define QUERY_BATCH_SIZE 16 45 46 struct query_entry { 47 struct avl_node node; 48 uint16_t type; 49 char name[]; 50 }; 51 52 static AVL_TREE(queries, avl_strcmp, true, NULL); 53 static char name_buffer[MAX_NAME_LEN + 1]; 54 55 static struct { 56 struct dns_header h; 57 unsigned char data[9000 - sizeof(struct dns_header)]; 58 } __attribute__((packed)) pkt; 59 static size_t pkt_len; 60 static struct dns_question *pkt_q[32]; 61 static unsigned int pkt_n_q; 62 static unsigned char *dnptrs[255]; 63 64 const char* 65 dns_type_string(uint16_t type) 66 { 67 static const struct { 68 uint16_t type; 69 char str[5]; 70 } type_str[] = { 71 { TYPE_A, "A" }, 72 { TYPE_AAAA, "AAAA" }, 73 { TYPE_PTR, "PTR" }, 74 { TYPE_TXT, "TXT" }, 75 { TYPE_SRV, "SRV" }, 76 { TYPE_ANY, "ANY" }, 77 }; 78 int i; 79 80 for (i = 0; i < ARRAY_SIZE(type_str); i++) { 81 if (type == type_str[i].type) 82 return type_str[i].str; 83 } 84 85 return "N/A"; 86 } 87 88 void dns_packet_init(void) 89 { 90 dnptrs[0] = (unsigned char *)&pkt; 91 dnptrs[1] = NULL; 92 pkt_len = 0; 93 pkt_n_q = 0; 94 memset(&pkt.h, 0, sizeof(pkt.h)); 95 } 96 97 static inline void *dns_packet_tail(size_t len) 98 { 99 if (pkt_len + len > sizeof(pkt.data)) 100 return NULL; 101 102 return &pkt.data[pkt_len]; 103 } 104 105 static int 106 dns_packet_add_name(const char *name) 107 { 108 void *data; 109 110 data = dns_packet_tail(MAX_NAME_LEN); 111 if (!data) 112 return -1; 113 114 return dn_comp(name, data, MAX_NAME_LEN, dnptrs, dnptrs + ARRAY_SIZE(dnptrs) - 1); 115 } 116 117 static void *dns_packet_record_add(size_t data_len, const char *name) 118 { 119 void *data; 120 int len; 121 122 len = dns_packet_add_name(name); 123 if (len < 1) 124 return NULL; 125 126 data = dns_packet_tail(len + data_len); 127 if (!data) 128 return NULL; 129 130 pkt_len += len + data_len; 131 132 return data + len; 133 } 134 135 bool dns_packet_question(const char *name, int type) 136 { 137 struct dns_question *q; 138 139 q = dns_packet_record_add(sizeof(*q), name); 140 if (!q) 141 return false; 142 143 pkt.h.questions += cpu_to_be16(1); 144 pkt_q[pkt_n_q++] = q; 145 memset(q, 0, sizeof(*q)); 146 q->class = cpu_to_be16(1); 147 q->type = cpu_to_be16(type); 148 DBG(1, "Q <- %s %s\n", dns_type_string(type), name); 149 150 return true; 151 } 152 153 void dns_packet_answer(const char *name, int type, const uint8_t *rdata, uint16_t rdlength, int ttl) 154 { 155 struct dns_answer *a; 156 157 pkt.h.flags |= cpu_to_be16(0x8400); 158 159 a = dns_packet_record_add(sizeof(*a) + rdlength, name); 160 memset(a, 0, sizeof(*a)); 161 a->type = cpu_to_be16(type); 162 a->class = cpu_to_be16(1); 163 a->ttl = cpu_to_be32(ttl); 164 a->rdlength = cpu_to_be16(rdlength); 165 memcpy(a + 1, rdata, rdlength); 166 DBG(1, "A <- %s %s\n", dns_type_string(be16_to_cpu(a->type)), name); 167 168 pkt.h.answers += cpu_to_be16(1); 169 } 170 171 static void dns_question_set_multicast(struct dns_question *q, bool val) 172 { 173 if (val) 174 q->class &= ~cpu_to_be16(CLASS_UNICAST); 175 else 176 q->class |= cpu_to_be16(CLASS_UNICAST); 177 } 178 179 void dns_packet_send(struct interface *iface, struct sockaddr *to, bool query, int multicast) 180 { 181 struct iovec iov = { 182 .iov_base = &pkt, 183 .iov_len = sizeof(pkt.h) + pkt_len, 184 }; 185 size_t i; 186 187 if (query) { 188 if (multicast < 0) 189 multicast = iface->need_multicast; 190 191 for (i = 0; i < pkt_n_q; i++) 192 dns_question_set_multicast(pkt_q[i], multicast); 193 } 194 195 if (interface_send_packet(iface, to, &iov, 1) < 0) 196 perror("failed to send answer"); 197 } 198 199 static void dns_packet_broadcast(void) 200 { 201 struct interface *iface; 202 203 vlist_for_each_element(&interfaces, iface, node) 204 dns_packet_send(iface, NULL, 1, -1); 205 } 206 207 void 208 dns_send_question(struct interface *iface, struct sockaddr *to, 209 const char *question, int type, int multicast) 210 { 211 dns_packet_init(); 212 dns_packet_question(question, type); 213 dns_packet_send(iface, to, true, multicast); 214 } 215 216 static void 217 dns_query_pending(struct uloop_timeout *t) 218 { 219 struct query_entry *e, *tmp; 220 int count = 0; 221 222 dns_packet_init(); 223 avl_remove_all_elements(&queries, e, node, tmp) { 224 dns_packet_question(e->name, e->type); 225 free(e); 226 227 if (++count < QUERY_BATCH_SIZE) 228 continue; 229 230 count = 0; 231 dns_packet_broadcast(); 232 } 233 234 if (count) 235 dns_packet_broadcast(); 236 } 237 238 void dns_query(const char *name, uint16_t type) 239 { 240 static struct uloop_timeout timer = { 241 .cb = dns_query_pending 242 }; 243 struct query_entry *e; 244 245 e = avl_find_element(&queries, name, e, node); 246 while (e) { 247 if (e->type == type) 248 return; 249 250 e = avl_next_element(e, node); 251 if (strcmp(e->name, name) != 0) 252 break; 253 } 254 255 e = calloc(1, sizeof(*e) + strlen(name) + 1); 256 e->type = type; 257 e->node.key = e->name; 258 strcpy(e->name, name); 259 avl_insert(&queries, &e->node); 260 261 if (queries.count > QUERY_BATCH_SIZE) 262 timer.cb(&timer); 263 264 if (!timer.pending) 265 uloop_timeout_set(&timer, 100); 266 } 267 268 void 269 dns_reply_a(struct interface *iface, struct sockaddr *to, int ttl, const char *hostname) 270 { 271 struct ifaddrs *ifap, *ifa; 272 struct sockaddr_in *sa; 273 struct sockaddr_in6 *sa6; 274 275 if (!hostname) 276 hostname = mdns_hostname_local; 277 278 getifaddrs(&ifap); 279 280 dns_packet_init(); 281 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 282 if (strcmp(ifa->ifa_name, iface->name)) 283 continue; 284 if (ifa->ifa_addr->sa_family == AF_INET) { 285 sa = (struct sockaddr_in *) ifa->ifa_addr; 286 dns_packet_answer(hostname, TYPE_A, (uint8_t *) &sa->sin_addr, 4, ttl); 287 } 288 if (ifa->ifa_addr->sa_family == AF_INET6) { 289 sa6 = (struct sockaddr_in6 *) ifa->ifa_addr; 290 dns_packet_answer(hostname, TYPE_AAAA, (uint8_t *) &sa6->sin6_addr, 16, ttl); 291 } 292 } 293 freeifaddrs(ifap); 294 295 dns_packet_send(iface, to, 0, 0); 296 } 297 298 void 299 dns_reply_a_additional(struct interface *iface, struct sockaddr *to, int ttl) 300 { 301 struct hostname *h; 302 303 vlist_for_each_element(&hostnames, h, node) 304 dns_reply_a(iface, to, ttl, h->hostname); 305 } 306 307 static int 308 scan_name(const uint8_t *buffer, int len) 309 { 310 int offset = 0; 311 312 while (len && (*buffer != '\0')) { 313 int l = *buffer; 314 315 if (IS_COMPRESSED(l)) 316 return offset + 2; 317 318 if (l + 1 > len) return -1; 319 len -= l + 1; 320 offset += l + 1; 321 buffer += l + 1; 322 } 323 324 if (!len || !offset || (*buffer != '\0')) 325 return -1; 326 327 return offset + 1; 328 } 329 330 static struct dns_header* 331 dns_consume_header(uint8_t **data, int *len) 332 { 333 struct dns_header *h = (struct dns_header *) *data; 334 335 if (*len < sizeof(struct dns_header)) 336 return NULL; 337 338 h->id = be16_to_cpu(h->id); 339 h->flags = be16_to_cpu(h->flags); 340 h->questions = be16_to_cpu(h->questions); 341 h->answers = be16_to_cpu(h->answers); 342 h->authority = be16_to_cpu(h->authority); 343 h->additional = be16_to_cpu(h->additional); 344 345 *len -= sizeof(struct dns_header); 346 *data += sizeof(struct dns_header); 347 348 return h; 349 } 350 351 static struct dns_question* 352 dns_consume_question(uint8_t **data, int *len) 353 { 354 struct dns_question *q = (struct dns_question *) *data; 355 356 if (*len < sizeof(struct dns_question)) 357 return NULL; 358 359 q->type = be16_to_cpu(q->type); 360 q->class = be16_to_cpu(q->class); 361 362 *len -= sizeof(struct dns_question); 363 *data += sizeof(struct dns_question); 364 365 return q; 366 } 367 368 static struct dns_answer* 369 dns_consume_answer(uint8_t **data, int *len) 370 { 371 struct dns_answer *a = (struct dns_answer *) *data; 372 373 if (*len < sizeof(struct dns_answer)) 374 return NULL; 375 376 a->type = be16_to_cpu(a->type); 377 a->class = be16_to_cpu(a->class); 378 a->ttl = be32_to_cpu(a->ttl); 379 a->rdlength = be16_to_cpu(a->rdlength); 380 381 *len -= sizeof(struct dns_answer); 382 *data += sizeof(struct dns_answer); 383 384 return a; 385 } 386 387 static char * 388 dns_consume_name(const uint8_t *base, int blen, uint8_t **data, int *len) 389 { 390 int nlen = scan_name(*data, *len); 391 392 if (nlen < 1) 393 return NULL; 394 395 if (dn_expand(base, base + blen, *data, name_buffer, MAX_NAME_LEN) < 0) { 396 perror("dns_consume_name/dn_expand"); 397 return NULL; 398 } 399 400 *len -= nlen; 401 *data += nlen; 402 403 return name_buffer; 404 } 405 406 static int parse_answer(struct interface *iface, struct sockaddr *from, 407 uint8_t *buffer, int len, uint8_t **b, int *rlen, 408 int cache) 409 { 410 char *name = dns_consume_name(buffer, len, b, rlen); 411 struct dns_answer *a; 412 uint8_t *rdata; 413 414 if (!name || *rlen < 0) { 415 fprintf(stderr, "dropping: bad question\n"); 416 return -1; 417 } 418 419 a = dns_consume_answer(b, rlen); 420 if (!a) { 421 fprintf(stderr, "dropping: bad question\n"); 422 return -1; 423 } 424 425 if ((a->class & ~CLASS_FLUSH) != CLASS_IN) 426 return -1; 427 428 rdata = *b; 429 if (a->rdlength > *rlen) { 430 fprintf(stderr, "dropping: bad question\n"); 431 return -1; 432 } 433 434 *rlen -= a->rdlength; 435 *b += a->rdlength; 436 437 if (cache) 438 cache_answer(iface, from, buffer, len, name, a, rdata, a->class & CLASS_FLUSH); 439 440 return 0; 441 } 442 443 static int 444 match_ipv6_addresses(char *reverse_ip, struct in6_addr *intf_ip) 445 { 446 int i = 0, j = 0, idx = 0; 447 char temp_ip[INET6_ADDRSTRLEN] = ""; 448 struct in6_addr buf; 449 450 for (i = strlen(reverse_ip) - 1; i >= 0; i--) { 451 if (reverse_ip[i] == '.') 452 continue; 453 454 if (j == 4) { 455 temp_ip[idx] = ':'; 456 idx++; 457 j = 0; 458 } 459 temp_ip[idx] = reverse_ip[i]; 460 idx++; 461 j++; 462 } 463 464 if (inet_pton(AF_INET6, temp_ip, &buf) <= 0) 465 return 0; 466 467 return !memcmp(&buf, intf_ip, sizeof(buf)); 468 } 469 470 static int 471 match_ip_addresses(char *reverse_ip, char *intf_ip) 472 { 473 int ip1[4], ip2[4]; 474 475 sscanf(reverse_ip, "%d.%d.%d.%d", &ip1[3], &ip1[2], &ip1[1], &ip1[0]); 476 sscanf(intf_ip, "%d.%d.%d.%d", &ip2[0], &ip2[1], &ip2[2], &ip2[3]); 477 478 int i; 479 for (i = 0; i < 4; i++) { 480 if (ip1[i] != ip2[i]) 481 return 0; 482 } 483 return 1; 484 } 485 486 static void 487 dns_reply_reverse_ip6_mapping(struct interface *iface, struct sockaddr *to, int ttl, char *name, char *reverse_ip) 488 { 489 struct ifaddrs *ifap, *ifa; 490 struct sockaddr_in6 *sa6; 491 492 char intf_ip[INET6_ADDRSTRLEN] = ""; 493 uint8_t buffer[256]; 494 int len; 495 496 getifaddrs(&ifap); 497 dns_packet_init(); 498 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 499 if (strcmp(ifa->ifa_name, iface->name)) 500 continue; 501 if (ifa->ifa_addr->sa_family == AF_INET6) { 502 sa6 = (struct sockaddr_in6 *) ifa->ifa_addr; 503 if (inet_ntop(AF_INET6, &sa6->sin6_addr, intf_ip, INET6_ADDRSTRLEN) == NULL) 504 continue; 505 506 if (match_ipv6_addresses(reverse_ip, &sa6->sin6_addr)) { 507 len = dn_comp(mdns_hostname_local, buffer, sizeof(buffer), NULL, NULL); 508 509 if (len < 1) 510 continue; 511 512 dns_packet_answer(name, TYPE_PTR, buffer, len, ttl); 513 } 514 } 515 } 516 dns_packet_send(iface, to, 0, 0); 517 518 freeifaddrs(ifap); 519 } 520 521 static void 522 dns_reply_reverse_ip4_mapping(struct interface *iface, struct sockaddr *to, int ttl, char *name, char *reverse_ip) 523 { 524 struct ifaddrs *ifap, *ifa; 525 struct sockaddr_in *sa; 526 527 char intf_ip[INET_ADDRSTRLEN] = ""; 528 uint8_t buffer[256]; 529 int len; 530 531 getifaddrs(&ifap); 532 dns_packet_init(); 533 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 534 if (strcmp(ifa->ifa_name, iface->name)) 535 continue; 536 if (ifa->ifa_addr->sa_family == AF_INET) { 537 sa = (struct sockaddr_in *) ifa->ifa_addr; 538 if (inet_ntop(AF_INET, &sa->sin_addr, intf_ip, INET_ADDRSTRLEN) == NULL) 539 continue; 540 541 if (match_ip_addresses(reverse_ip, intf_ip)) { 542 len = dn_comp(mdns_hostname_local, buffer, sizeof(buffer), NULL, NULL); 543 544 if (len < 1) 545 continue; 546 547 dns_packet_answer(name, TYPE_PTR, buffer, len, ttl); 548 } 549 } 550 } 551 dns_packet_send(iface, to, 0, 0); 552 553 freeifaddrs(ifap); 554 } 555 556 static bool 557 is_reverse_dns_query(const char *name, const char *suffix) 558 { 559 if (!name || !suffix) 560 return false; 561 562 size_t name_len = strlen(name); 563 size_t suffix_len = strlen(suffix); 564 565 if (suffix_len > name_len) 566 return false; 567 568 if (strncmp(name + (name_len - suffix_len), suffix, suffix_len) == 0) 569 return true; 570 571 return false; 572 } 573 574 static void 575 parse_question(struct interface *iface, struct sockaddr *from, char *name, struct dns_question *q) 576 { 577 int is_unicast = (q->class & CLASS_UNICAST) != 0; 578 struct sockaddr *to = NULL; 579 struct hostname *h; 580 char *host, *host6; 581 582 /* TODO: Multicast if more than one quarter of TTL has passed */ 583 if (is_unicast) { 584 to = from; 585 if (interface_multicast(iface)) 586 iface = interface_get(iface->name, iface->type | SOCKTYPE_BIT_UNICAST); 587 } 588 589 DBG(1, "Q -> %s %s\n", dns_type_string(q->type), name); 590 591 switch (q->type) { 592 case TYPE_ANY: 593 if (!strcasecmp(name, mdns_hostname_local)) { 594 dns_reply_a(iface, to, announce_ttl, NULL); 595 dns_reply_a_additional(iface, to, announce_ttl); 596 service_reply(iface, to, NULL, NULL, announce_ttl, is_unicast); 597 } 598 break; 599 600 case TYPE_PTR: 601 if (is_reverse_dns_query(name, ".in-addr.arpa")) { 602 host = strstr(name, ".in-addr.arpa"); 603 char name_buf[256]; 604 strcpy(name_buf, name); 605 *host = '\0'; 606 dns_reply_reverse_ip4_mapping(iface, to, announce_ttl, name_buf, name); 607 break; 608 } 609 610 if (is_reverse_dns_query(name, ".ip6.arpa")) { 611 host6 = strstr(name, ".ip6.arpa"); 612 char name_buf6[256]; 613 strcpy(name_buf6, name); 614 *host6 = '\0'; 615 dns_reply_reverse_ip6_mapping(iface, to, announce_ttl, name_buf6, name); 616 break; 617 } 618 619 if (!strcasecmp(name, C_DNS_SD)) { 620 service_announce_services(iface, to, announce_ttl); 621 } else { 622 if (name[0] == '_') { 623 service_reply(iface, to, NULL, name, announce_ttl, is_unicast); 624 } else { 625 /* First dot separates instance name from the rest */ 626 char *dot = strchr(name, '.'); 627 628 if (dot) { 629 *dot = '\0'; 630 service_reply(iface, to, name, dot + 1, announce_ttl, is_unicast); 631 *dot = '.'; 632 } 633 } 634 } 635 break; 636 637 case TYPE_AAAA: 638 case TYPE_A: 639 host = strcasestr(name, ".local"); 640 if (host) 641 *host = '\0'; 642 if (!strcasecmp(umdns_host_label, name)) { 643 dns_reply_a(iface, to, announce_ttl, NULL); 644 } else { 645 if (host) 646 *host = '.'; 647 vlist_for_each_element(&hostnames, h, node) 648 if (!strcasecmp(h->hostname, name)) 649 dns_reply_a(iface, to, announce_ttl, h->hostname); 650 } 651 break; 652 }; 653 } 654 655 void 656 dns_handle_packet(struct interface *iface, struct sockaddr *from, uint16_t port, uint8_t *buffer, int len) 657 { 658 struct dns_header *h; 659 uint8_t *b = buffer; 660 int rlen = len; 661 662 h = dns_consume_header(&b, &rlen); 663 if (!h) { 664 fprintf(stderr, "dropping: bad header\n"); 665 return; 666 } 667 668 if (h->questions && !interface_multicast(iface) && port != MCAST_PORT) 669 /* silently drop unicast questions that dont originate from port 5353 */ 670 return; 671 672 while (h->questions-- > 0) { 673 char *name = dns_consume_name(buffer, len, &b, &rlen); 674 struct dns_question *q; 675 676 if (!name || rlen < 0) { 677 fprintf(stderr, "dropping: bad name\n"); 678 return; 679 } 680 681 q = dns_consume_question(&b, &rlen); 682 if (!q) { 683 fprintf(stderr, "dropping: bad question\n"); 684 return; 685 } 686 687 if (!(h->flags & FLAG_RESPONSE)) 688 parse_question(iface, from, name, q); 689 } 690 691 if (!(h->flags & FLAG_RESPONSE)) 692 return; 693 694 while (h->answers-- > 0) 695 if (parse_answer(iface, from, buffer, len, &b, &rlen, 1)) 696 return; 697 698 while (h->authority-- > 0) 699 if (parse_answer(iface, from, buffer, len, &b, &rlen, 1)) 700 return; 701 702 while (h->additional-- > 0) 703 if (parse_answer(iface, from, buffer, len, &b, &rlen, 1)) 704 return; 705 706 } 707
This page was automatically generated by LXR 0.3.1. • OpenWrt