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 bool dot = false; 450 451 for (i = strlen(reverse_ip) - 1; i >= 0; i--) { 452 if ((reverse_ip[i] == '.') != dot) 453 return 0; 454 dot = !dot; 455 456 if (reverse_ip[i] == '.') 457 continue; 458 459 if (j == 4) { 460 temp_ip[idx] = ':'; 461 idx++; 462 j = 0; 463 } 464 temp_ip[idx] = reverse_ip[i]; 465 idx++; 466 j++; 467 } 468 469 if (inet_pton(AF_INET6, temp_ip, &buf) <= 0) 470 return 0; 471 472 return !memcmp(&buf, intf_ip, sizeof(buf)); 473 } 474 475 static int 476 match_ip_addresses(char *reverse_ip, char *intf_ip) 477 { 478 int ip1[4], ip2[4], res; 479 char c; 480 481 res = sscanf(reverse_ip, "%d.%d.%d.%d%c", &ip1[3], &ip1[2], &ip1[1], &ip1[0], &c); 482 if (res != 4) 483 return 0; 484 485 sscanf(intf_ip, "%d.%d.%d.%d", &ip2[0], &ip2[1], &ip2[2], &ip2[3]); 486 487 int i; 488 for (i = 0; i < 4; i++) { 489 if (ip1[i] != ip2[i]) 490 return 0; 491 } 492 return 1; 493 } 494 495 static void 496 dns_reply_reverse_ip6_mapping(struct interface *iface, struct sockaddr *to, int ttl, char *name, char *reverse_ip) 497 { 498 struct ifaddrs *ifap, *ifa; 499 struct sockaddr_in6 *sa6; 500 501 char intf_ip[INET6_ADDRSTRLEN] = ""; 502 uint8_t buffer[256]; 503 int len; 504 505 getifaddrs(&ifap); 506 dns_packet_init(); 507 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 508 if (strcmp(ifa->ifa_name, iface->name)) 509 continue; 510 if (ifa->ifa_addr->sa_family == AF_INET6) { 511 sa6 = (struct sockaddr_in6 *) ifa->ifa_addr; 512 if (inet_ntop(AF_INET6, &sa6->sin6_addr, intf_ip, INET6_ADDRSTRLEN) == NULL) 513 continue; 514 515 if (match_ipv6_addresses(reverse_ip, &sa6->sin6_addr)) { 516 len = dn_comp(mdns_hostname_local, buffer, sizeof(buffer), NULL, NULL); 517 518 if (len < 1) 519 continue; 520 521 dns_packet_answer(name, TYPE_PTR, buffer, len, ttl); 522 } 523 } 524 } 525 dns_packet_send(iface, to, 0, 0); 526 527 freeifaddrs(ifap); 528 } 529 530 static void 531 dns_reply_reverse_ip4_mapping(struct interface *iface, struct sockaddr *to, int ttl, char *name, char *reverse_ip) 532 { 533 struct ifaddrs *ifap, *ifa; 534 struct sockaddr_in *sa; 535 536 char intf_ip[INET_ADDRSTRLEN] = ""; 537 uint8_t buffer[256]; 538 int len; 539 540 getifaddrs(&ifap); 541 dns_packet_init(); 542 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 543 if (strcmp(ifa->ifa_name, iface->name)) 544 continue; 545 if (ifa->ifa_addr->sa_family == AF_INET) { 546 sa = (struct sockaddr_in *) ifa->ifa_addr; 547 if (inet_ntop(AF_INET, &sa->sin_addr, intf_ip, INET_ADDRSTRLEN) == NULL) 548 continue; 549 550 if (match_ip_addresses(reverse_ip, intf_ip)) { 551 len = dn_comp(mdns_hostname_local, buffer, sizeof(buffer), NULL, NULL); 552 553 if (len < 1) 554 continue; 555 556 dns_packet_answer(name, TYPE_PTR, buffer, len, ttl); 557 } 558 } 559 } 560 dns_packet_send(iface, to, 0, 0); 561 562 freeifaddrs(ifap); 563 } 564 565 static bool 566 is_reverse_dns_query(const char *name, const char *suffix) 567 { 568 if (!name || !suffix) 569 return false; 570 571 size_t name_len = strlen(name); 572 size_t suffix_len = strlen(suffix); 573 574 if (suffix_len > name_len) 575 return false; 576 577 if (strncmp(name + (name_len - suffix_len), suffix, suffix_len) == 0) 578 return true; 579 580 return false; 581 } 582 583 static void 584 parse_question(struct interface *iface, struct sockaddr *from, char *name, struct dns_question *q) 585 { 586 int is_unicast = (q->class & CLASS_UNICAST) != 0; 587 struct sockaddr *to = NULL; 588 struct hostname *h; 589 char *host, *host6; 590 591 /* TODO: Multicast if more than one quarter of TTL has passed */ 592 if (is_unicast) { 593 to = from; 594 if (interface_multicast(iface)) 595 iface = interface_get(iface->name, iface->type | SOCKTYPE_BIT_UNICAST); 596 } 597 598 DBG(1, "Q -> %s %s\n", dns_type_string(q->type), name); 599 600 switch (q->type) { 601 case TYPE_ANY: 602 if (!strcasecmp(name, mdns_hostname_local)) { 603 dns_reply_a(iface, to, announce_ttl, NULL); 604 dns_reply_a_additional(iface, to, announce_ttl); 605 service_reply(iface, to, NULL, NULL, announce_ttl, is_unicast); 606 } 607 break; 608 609 case TYPE_PTR: 610 if (is_reverse_dns_query(name, ".in-addr.arpa")) { 611 if (strlen(name) < MIN_PTR_NAME_LEN || 612 strlen(name) > MAX_PTR_NAME_LEN) 613 break; 614 615 host = strstr(name, ".in-addr.arpa"); 616 char name_buf[256]; 617 strcpy(name_buf, name); 618 *host = '\0'; 619 dns_reply_reverse_ip4_mapping(iface, to, announce_ttl, name_buf, name); 620 break; 621 } 622 623 if (is_reverse_dns_query(name, ".ip6.arpa")) { 624 if (strlen(name) != MAX_PTR6_NAME_LEN) 625 break; 626 627 host6 = strstr(name, ".ip6.arpa"); 628 char name_buf6[256]; 629 strcpy(name_buf6, name); 630 *host6 = '\0'; 631 dns_reply_reverse_ip6_mapping(iface, to, announce_ttl, name_buf6, name); 632 break; 633 } 634 635 if (!strcasecmp(name, C_DNS_SD)) { 636 service_announce_services(iface, to, announce_ttl); 637 } else { 638 if (name[0] == '_') { 639 service_reply(iface, to, NULL, name, announce_ttl, is_unicast); 640 } else { 641 /* First dot separates instance name from the rest */ 642 char *dot = strchr(name, '.'); 643 644 if (dot) { 645 *dot = '\0'; 646 service_reply(iface, to, name, dot + 1, announce_ttl, is_unicast); 647 *dot = '.'; 648 } 649 } 650 } 651 break; 652 653 case TYPE_AAAA: 654 case TYPE_A: 655 host = strcasestr(name, ".local"); 656 if (host) 657 *host = '\0'; 658 if (!strcasecmp(umdns_host_label, name)) { 659 dns_reply_a(iface, to, announce_ttl, NULL); 660 } else { 661 if (host) 662 *host = '.'; 663 vlist_for_each_element(&hostnames, h, node) 664 if (!strcasecmp(h->hostname, name)) 665 dns_reply_a(iface, to, announce_ttl, h->hostname); 666 } 667 break; 668 }; 669 } 670 671 void 672 dns_handle_packet(struct interface *iface, struct sockaddr *from, uint16_t port, uint8_t *buffer, int len) 673 { 674 struct dns_header *h; 675 uint8_t *b = buffer; 676 int rlen = len; 677 678 h = dns_consume_header(&b, &rlen); 679 if (!h) { 680 fprintf(stderr, "dropping: bad header\n"); 681 return; 682 } 683 684 if (h->questions && !interface_multicast(iface) && port != MCAST_PORT) 685 /* silently drop unicast questions that dont originate from port 5353 */ 686 return; 687 688 while (h->questions-- > 0) { 689 char *name = dns_consume_name(buffer, len, &b, &rlen); 690 struct dns_question *q; 691 692 if (!name || rlen < 0) { 693 fprintf(stderr, "dropping: bad name\n"); 694 return; 695 } 696 697 q = dns_consume_question(&b, &rlen); 698 if (!q) { 699 fprintf(stderr, "dropping: bad question\n"); 700 return; 701 } 702 703 if (!(h->flags & FLAG_RESPONSE)) 704 parse_question(iface, from, name, q); 705 } 706 707 if (!(h->flags & FLAG_RESPONSE)) 708 return; 709 710 while (h->answers-- > 0) 711 if (parse_answer(iface, from, buffer, len, &b, &rlen, 1)) 712 return; 713 714 while (h->authority-- > 0) 715 if (parse_answer(iface, from, buffer, len, &b, &rlen, 1)) 716 return; 717 718 while (h->additional-- > 0) 719 if (parse_answer(iface, from, buffer, len, &b, &rlen, 1)) 720 return; 721 722 } 723
This page was automatically generated by LXR 0.3.1. • OpenWrt