Parent Directory
|
Revision Log
|
Revision Graph
* just a dir
1 /************************************** 2 * AUTHOR: Federico Tomassini * 3 * Copyright (C) Federico Tomassini * 4 * Contact effetom@gmail.com * 5 *********************************************** 6 ******* BEGIN 3/2006 ******** 7 ************************************************************************* 8 * * 9 * This program is free software; you can redistribute it and/or modify * 10 * it under the terms of the GNU General Public License as published by * 11 * the Free Software Foundation; either version 2 of the License, or * 12 * (at your option) any later version. * 13 * * 14 * This program is distributed in the hope that it will be useful, * 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 * GNU General Public License for more details. * 18 * * 19 ************************************************************************/ 20 21 #define _GNU_SOURCE 22 #include <string.h> 23 #include <netdb.h> 24 25 #include "includes.h" 26 #include "common.h" 27 #include "andns.h" 28 #include "err_errno.h" 29 #include "andna.h" 30 #include "andns/andns_lib.h" 31 #include "andns/andns_net.h" 32 #include "andns/andns_snsd.h" 33 #include "dnslib.h" 34 35 36 static uint8_t _dns_forwarding_; 37 static uint8_t _andns_ns_count_; 38 static uint8_t _default_realm_; 39 40 static struct addrinfo _ns_filter_; 41 static struct addrinfo *_andns_ns_[MAXNSSERVERS]; 42 43 static int _ip_len_; 44 45 /* Debugging Functions to isolate andns from andna 46 snsd_service* debug_andna_resolve_hname(char *s,int service,u_char proto,int *records) 47 { 48 char *ciccio="111.222.123.123"; 49 debug(DBG_NORMAL,"Entering debug_andna_resolve."); 50 snsd_service *ss; 51 snsd_prio *sp; 52 snsd_node *sn; 53 ss=xmalloc(sizeof(snsd_service)); 54 ss->prio=xmalloc(sizeof(snsd_prio)); 55 sp=ss->prio; 56 sp->node=xmalloc(sizeof(snsd_node)); 57 sn=sp->node; 58 inet_pton(AF_INET,ciccio,sn->record); 59 sn->flags|=SNSD_NODE_MAIN_IP; 60 sn->flags|=SNSD_NODE_IP; 61 ss->next=0; 62 ss->prev=0; 63 sp->next=0; 64 sp->prev=0; 65 sn->next=0; 66 sn->prev=0; 67 *records=1; 68 return ss; 69 } 70 lcl_cache* debug_andna_reverse_resolve(inet_prefix addr) 71 { 72 lcl_cache *lc; 73 debug(DBG_NORMAL,"Entering debug_andna_reverse."); 74 lc=xmalloc(sizeof(lcl_cache)); 75 memset(lc,0,sizeof(lcl_cache)); 76 lc->hostname=xmalloc(12); 77 strcpy(lc->hostname,"Ciao mamma"); 78 return lc; 79 }*/ 80 81 82 83 84 /* INIT FUNCTIONS */ 85 86 87 /* 88 * Saves on `nsbuf' and `ns_count' the ip 89 * address ns: these infos will be used for DNS 90 * forwarding. 91 * 92 * Returns: 93 * -1 on error 94 * 0 if OK 95 */ 96 int store_ns(char *ns) 97 { 98 int res; 99 struct addrinfo **ai; 100 101 if (strstr(ns, "127.0.0.")) /* TODO: make it proto independent */ 102 return -1; 103 104 ai= &_andns_ns_[_andns_ns_count_]; 105 res= getaddrinfo(ns, DNS_PORT_STR, &_ns_filter_, ai); 106 if (res) { 107 debug(DBG_NORMAL,"In store_ns(): gai `%s' -> %s",ns,gai_strerror(errno)); 108 return -1; 109 } 110 _andns_ns_count_++; 111 return 0; 112 } 113 114 /* 115 * Reads resolv.conf, searching nameserver lines. 116 * Takes the ip address from these lines and calls store_ns. 117 * "nameserver 127.0.0.1" is discarded to remove looping behaviors. 118 * The number of stored nameservers is written in 119 * `*ns_count' and it is returned. 120 * If an error occurred or no hostnames are available, -1 is returned. 121 */ 122 int collect_resolv_conf(char *resolve_conf) 123 { 124 FILE *erc; 125 char buf[512],*crow; 126 127 if (!(erc= fopen(resolve_conf, "r"))) { 128 error("In collect_resolv_conf: error -> %s.", strerror(errno)); 129 err_ret(ERR_RSLERC,-1); 130 } 131 132 while ((crow= fgets(buf, 512, erc)) && _andns_ns_count_< MAXNSSERVERS) { 133 if (!(crow= strstr(buf, "nameserver "))) /* is a good line? */ 134 continue; 135 136 /* Skip if the line is commented */ 137 *crow=0; 138 if(strchr(buf, '#')) continue; 139 140 crow+=11; 141 /* remove unwanted chars */ 142 strip_char(crow, '\t'); 143 strip_char(crow, ' '); 144 strip_char(crow, '\n'); 145 146 store_ns(crow); /* finally store nameserver */ 147 } 148 149 if (fclose(erc)) { 150 error("In collect_resolv_conf: closing resolv.conf -> %s",strerror(errno)); 151 err_ret(ERR_RSLERC,-1); 152 } 153 154 if (!_andns_ns_count_) 155 err_ret(ERR_RSLNNS,-1); 156 157 return _andns_ns_count_; 158 } 159 160 void reset_andns_ns(void) 161 { 162 int i; 163 for(i=0; i<_andns_ns_count_; i++) 164 if(_andns_ns_[i]) 165 freeaddrinfo(_andns_ns_[i]); 166 _andns_ns_count_=0; 167 setzero(_andns_ns_, sizeof(struct addrinfo *)*MAXNSSERVERS); 168 } 169 170 /* 171 * This function must be called before all. 172 * Sets the default realm for domain name resolution 173 * and stores infos about nameservers for dns query. 174 * On error -1 is returned. 175 */ 176 int andns_init(int restricted, char *resolv_conf,int family) 177 { 178 int i,res; 179 char msg[(INET6_ADDRSTRLEN+2)*MAXNSSERVERS]; 180 char buf[INET6_ADDRSTRLEN]; 181 struct addrinfo *ai; 182 183 memset(&_ns_filter_,0,sizeof(struct addrinfo)); 184 185 _ns_filter_.ai_socktype= SOCK_DGRAM; 186 _ip_len_= family== AF_INET? 4: 16; 187 188 _default_realm_=(restricted)?INET_REALM:NTK_REALM; 189 _andns_ns_count_=0; 190 191 setzero(_andns_ns_, sizeof(struct addrinfo *)*MAXNSSERVERS); 192 193 memset(msg, 0, (INET_ADDRSTRLEN+2)*MAXNSSERVERS); 194 195 if(_default_realm_ == NTK_REALM) { 196 /* We are in NTK realm, every IP is assigned to Netsukuku, 197 * therefore dns forwarding is meaningless */ 198 _dns_forwarding_=0; 199 return 0; 200 } 201 202 res= collect_resolv_conf(resolv_conf); 203 if (res <=0) { 204 _dns_forwarding_=0; 205 debug(DBG_NORMAL,err_str); 206 err_ret(ERR_RSLAIE,-1); 207 } 208 209 /* 210 * Debug message 211 */ 212 for (i=0;i<_andns_ns_count_;i++) { 213 ai= _andns_ns_[i]; 214 res= idp_inet_ntop(ai->ai_family, ai->ai_addr, buf, INET6_ADDRSTRLEN); 215 if (!res) { 216 strncat(msg,buf,INET_ADDRSTRLEN); 217 strncat(msg,i==_andns_ns_count_-1?". ":", ",2); 218 } 219 else 220 error("In andns_init: error converting sockaddr -> %s.",\ 221 strerror(errno)); 222 } 223 224 loginfo("Inet DNS queries will be forwarded to: %s",msg); 225 226 _dns_forwarding_=1; 227 return 0; 228 } 229 230 void andns_close(void) 231 { 232 reset_andns_ns(); 233 } 234 235 236 /* NET FUNCTIONS */ 237 238 int ns_general_send(char *msg, int msglen, char *answer, int anslen) 239 { 240 int res, i; 241 242 for (i=0; i<_andns_ns_count_;i++) { 243 res= ai_send_recv_close(_andns_ns_[i], msg, msglen, 244 answer, anslen, 0, 0, ANDNS_TIMEOUT); 245 if (res<0) continue; 246 return res; 247 } 248 if (res==-1) { 249 err_ret(ERR_SKTCON,-1);} 250 else if (res==-2) { 251 err_ret(ERR_SKTSEN,-1);} 252 else if (res==-3) { 253 err_ret(ERR_SKTREC,-1);} 254 255 } 256 257 /* UTILS FUNCTIONS */ 258 259 /* 260 * Make a copy of DNS pkt data. If prefix is not NULL, 261 * the prefix is added to strings. 262 */ 263 void dpktacpy(dns_pkt *dst,dns_pkt *src,const char *prefix) 264 { 265 dns_pkt_a *dpas,*dpad; 266 int slen; 267 int yet_pref= 0; 268 char temp[257]; 269 270 dpas= src->pkt_answ; 271 while(dpas) { 272 dpad= DP_ADD_ANSWER(dst); 273 memcpy(dpad, dpas, sizeof(dns_pkt_a)); 274 dpad->next= NULL; 275 276 if (prefix && !yet_pref) 277 { /* TODO: yet_pref better */ 278 slen= strlen(dpad->name); 279 if (dpas->type!=T_PTR) 280 memcpy(dpad->name+ slen, prefix, REALM_PREFIX_LEN); 281 else { 282 strcpy(temp, dpad->name); 283 memcpy(dpad->name, prefix+ 1, REALM_PREFIX_LEN- 1); 284 dpad->name[REALM_PREFIX_LEN-1]= '.'; 285 strcpy(dpad->name+ REALM_PREFIX_LEN, temp); 286 } 287 *(dpad->name+slen+REALM_PREFIX_LEN)= 0; 288 yet_pref= 1; 289 } 290 291 dpas= dpas->next; 292 } 293 294 dpas= src->pkt_auth; 295 while(dpas) 296 { 297 dpad= DP_ADD_AUTH(dst); 298 memcpy(dpad, dpas, sizeof(dns_pkt_a)); 299 dpad->next= NULL; 300 dpas= dpas->next; 301 } 302 303 dpas= src->pkt_add; 304 while(dpas) 305 { 306 dpad= DP_ADD_ADD(dst); 307 memcpy(dpad, dpas, sizeof(dns_pkt_a)); 308 dpad->next= NULL; 309 dpas= dpas->next; 310 } 311 } 312 313 /* 314 * Make a full copy of a dns pkt. If prefix is not 315 * null, prefix is added to names. 316 */ 317 dns_pkt* dpktcpy(dns_pkt *src,const char *prefix) 318 { 319 dns_pkt *dst; 320 dns_pkt_qst *dpq,*dpq_src; 321 322 dst= create_dns_pkt(); 323 memcpy(dst, src, sizeof(dns_pkt)); 324 dst->pkt_qst= NULL; 325 dst->pkt_answ= NULL; 326 dst->pkt_auth= NULL; 327 dst->pkt_add= NULL; 328 329 dpq_src= src->pkt_qst; 330 while (dpq_src) 331 { 332 dpq= dns_add_qst(dst); 333 memcpy(dpq, dpq_src, sizeof(dns_pkt_qst)); 334 dpq->next= NULL; 335 dpq_src= dpq_src->next; 336 } 337 dpktacpy(dst, src, prefix); 338 return dst; 339 } 340 341 /* 342 * Remove the suffix realm, if any. 343 * Writes the result on dst. 344 */ 345 char* rm_realm_prefix(char *from,char *dst,int type) 346 { 347 int slen; 348 slen=strlen(from); 349 350 if (slen<5) 351 strcpy(dst, from); 352 353 else if (type == T_PTR) 354 { 355 if (strcasestr(from, PTR_INET_REALM_PREFIX)== from 356 || 357 strcasestr(from, PTR_NTK_REALM_PREFIX)== from) 358 359 strcpy(dst,from+ REALM_PREFIX_LEN); 360 361 else strcpy(dst, from); 362 363 } 364 365 else if (strcasestr(from+ slen- REALM_PREFIX_LEN, INET_REALM_PREFIX) 366 || 367 strcasestr(from+ slen- REALM_PREFIX_LEN, NTK_REALM_PREFIX)) 368 { 369 strncpy(dst, from, slen- REALM_PREFIX_LEN); 370 dst[slen- REALM_PREFIX_LEN]= 0; 371 } 372 373 else strcpy(dst, from); 374 375 return dst; 376 } 377 378 /* Make a copy of a dns pkt, only for headers and questions. 379 * If the question is prefixed, the prefix is removed. 380 */ 381 dns_pkt* dpktcpy_rm_pref(dns_pkt *src) 382 { 383 dns_pkt *dst; 384 dns_pkt_qst *dpq; 385 386 dst= dpktcpy(src, NULL); 387 dpq= dst->pkt_qst; 388 rm_realm_prefix(src->pkt_qst->qname, dpq->qname, dpq->qtype); 389 return dst; 390 } 391 392 int andns_realm(dns_pkt_qst *dpq, int *prefixed) 393 { 394 int slen; 395 char *qst; 396 397 qst= dpq->qname; 398 399 if (!qst) err_ret(ERR_UFOERR,-1); 400 401 slen=strlen(qst); 402 403 /* 404 * if qst is tto short, it's impossible to 405 * consider a prefix. 406 */ 407 if (slen<5) return _default_realm_; 408 409 if (dpq->qtype==T_PTR) 410 { 411 412 if (strcasestr(qst,PTR_INET_REALM_PREFIX)==qst) 413 { 414 if (prefixed) *prefixed=1; 415 return INET_REALM; 416 } 417 418 if (strcasestr(qst,PTR_NTK_REALM_PREFIX)==qst) 419 { 420 if (prefixed) *prefixed=1; 421 return NTK_REALM; 422 } 423 424 if (prefixed) *prefixed=0; 425 return _default_realm_; 426 427 } 428 429 if (strcasestr(qst+ slen- REALM_PREFIX_LEN, INET_REALM_PREFIX)) 430 { 431 if (prefixed) *prefixed=1; 432 return INET_REALM; 433 } 434 if (strcasestr(qst+ slen- REALM_PREFIX_LEN, NTK_REALM_PREFIX)) 435 { 436 if (prefixed) *prefixed=1; 437 return NTK_REALM; 438 } 439 440 if (prefixed) *prefixed=0; 441 return _default_realm_; 442 } 443 444 /* 445 * Returns: 446 * 0 if the question does not have a suffix 447 * 1 if the question has suffix 448 */ 449 int is_prefixed(dns_pkt *dp) 450 { 451 int prefix=0; 452 453 andns_realm(dp->pkt_qst, &prefix); 454 return prefix; 455 } 456 457 /* 458 * A very stupid function that converts 459 * ANDNS code to DNS code. 460 */ 461 int qtype_a_to_d(andns_pkt *ap) 462 { 463 switch (ap->qtype) 464 { 465 case AT_PTR: 466 return T_PTR; 467 case AT_A: 468 if (ap->service==25) 469 return T_MX; 470 else if (!ap->service) 471 return T_A; 472 else 473 return -1; 474 default: 475 return -1; 476 } 477 } 478 479 int apqsttodpqst(andns_pkt *ap,dns_pkt **dpsrc) 480 { 481 dns_pkt *dp; 482 dns_pkt_hdr *dph; 483 dns_pkt_qst *dpq; 484 int res,qt; 485 int qlen,family; 486 487 qt= qtype_a_to_d(ap); 488 if (qt== -1) 489 err_ret(ERR_ANDNCQ, -1); 490 491 *dpsrc= create_dns_pkt(); 492 dp= *dpsrc; 493 dph= &(dp->pkt_hdr); 494 dpq= dns_add_qst(dp); 495 496 if (qt==T_A || qt==T_MX) 497 { 498 qlen= strlen(ap->qstdata); 499 if (qlen> DNS_MAX_HNAME_LEN) 500 goto incomp_err; 501 strcpy(dpq->qname, ap->qstdata); 502 } 503 504 else if (qt==T_PTR) 505 { 506 char temp[DNS_MAX_HNAME_LEN]; 507 qlen= ap->qstlength; 508 if (qlen== 4) 509 family= AF_INET; 510 else if (qlen== 16) 511 family= AF_INET6; 512 else 513 goto incomp_err; 514 515 if (!inet_ntop(family, ap->qstdata,temp, DNS_MAX_HNAME_LEN)) 516 { 517 debug(DBG_INSANE, err_str); 518 goto incomp_err; 519 } 520 res= swapped_straddr_pref(temp, dpq->qname, family); 521 if (res==-1) 522 { 523 debug(DBG_INSANE, err_str); 524 goto incomp_err; 525 } 526 } 527 else 528 goto incomp_err; 529 530 dph->id= ap->id; 531 dph->rd= 1; 532 dph->qdcount++; 533 dpq->qtype= qt; 534 dpq->qclass= C_IN; 535 return 0; 536 537 incomp_err: 538 destroy_dns_pkt(dp); 539 err_ret(ERR_ANDNCQ,-1); 540 } 541 542 int dpanswtoapansw(dns_pkt *dp, andns_pkt *ap) 543 { 544 int i, rcode, qt, ancount, nan= 0; 545 dns_pkt_a *dpa; 546 andns_pkt_data *apd; 547 548 ancount= DNS_GET_ANCOUNT(dp); 549 rcode= DNS_GET_RCODE(dp); 550 ap->rcode= rcode; 551 ap->qr= 1; 552 553 if (rcode!=DNS_RCODE_NOERR) 554 return 0; 555 556 qt= dp->pkt_qst->qtype; 557 dpa= dp->pkt_answ; 558 for (i=0;i<ancount;i++) 559 { 560 if (!dpa) 561 break; 562 563 apd= andns_add_answ(ap); 564 if (qt==T_A) 565 { 566 apd->rdlength= _ip_len_; 567 APD_ALIGN(apd); 568 memcpy(apd->rdata, dpa->rdata, _ip_len_); 569 nan++; 570 } 571 else if (qt==T_PTR ) 572 { 573 apd->rdlength= strlen(dpa->rdata); 574 APD_ALIGN(apd); 575 strcpy(apd->rdata, dpa->rdata); 576 nan++; 577 } 578 else if (qt==T_MX) 579 { 580 struct hostent *h; 581 uint16_t prio; 582 h= gethostbyname(dpa->rdata+ 2); 583 if (!h || !(h->h_length)) 584 { 585 andns_del_answ(ap); 586 debug(DBG_INSANE,"MX Ip Record not found."); 587 continue; 588 } 589 apd->rdlength= h->h_addrtype == AF_INET? 4: 16; 590 APD_ALIGN(apd); 591 memcpy(apd->rdata, h->h_addr_list[0], apd->rdlength); 592 memcpy(&prio, dpa->rdata, sizeof(uint16_t)); 593 apd->prio= prio>> 8; 594 nan++; 595 } 596 else 597 andns_del_answ(ap); 598 599 dpa=dpa->next; 600 } 601 if (i!= ancount || nan!= ancount) 602 debug(DBG_INSANE,"In dpanswtoapansw: " 603 "ancount=%d, andns answers=%d",\ 604 DNS_GET_ANCOUNT(dp),i); 605 606 ap->ancount=nan; 607 608 return 0; 609 } 610 611 /* FINALLY RESOLVING FUNCTIONS */ 612 613 /* 614 * His goal is trivial. 615 * DO NOT USE suffixes query, i.e. query with ".INT" or ".NTK". 616 * NXDOMAIN otherwise. 617 * 618 * Returns: 619 * -1 on error 620 * 0 if OK 621 */ 622 int andns_gethostbyname(char *hname, inet_prefix *ip) 623 { 624 dns_pkt *dp; 625 dns_pkt_hdr *dph; 626 dns_pkt_qst *dpq; 627 int res; 628 char msg[DNS_MAX_SZ],answ[DNS_MAX_SZ]; 629 uint32_t addr; 630 631 dp= create_dns_pkt(); 632 dph= &(dp->pkt_hdr); 633 634 dph->id= (xrand_fast() >> 16) ^ (xrand_fast() >> 16); 635 dph->rd= 1; 636 637 dpq= dns_add_qst(dp); 638 rm_realm_prefix(hname,dpq->qname,T_A); 639 dpq->qtype= T_A; 640 dpq->qclass= C_IN; 641 642 DP_QDCOUNT(dp)++; 643 644 memset(msg, 0, DNS_MAX_SZ); 645 memset(answ, 0, DNS_MAX_SZ); 646 647 if ((res=d_p(dp,msg))==-1) 648 { 649 error(err_str); 650 err_ret(ERR_RSLRSL,-1); 651 } 652 if ((res=ns_general_send(msg,res,answ,DNS_MAX_SZ))==-1) 653 { 654 error(err_str); 655 err_ret(ERR_RSLRSL,-1); 656 } 657 if ((res=d_u(answ,res,&dp))==-1) 658 { 659 error(err_str); 660 err_ret(ERR_RSLRSL,-1); 661 } 662 memcpy(&addr, dp->pkt_answ->rdata, sizeof(uint32_t)); 663 664 addr= ntohl(addr); 665 if ((res=inet_setip_raw(ip,&addr, AF_INET))==-1) 666 { 667 error("In andns_gethostbyname: can not fill inet_prefix."); 668 err_ret(ERR_RSLRSL,-1); 669 } 670 destroy_dns_pkt(dp); 671 return 0; 672 } 673 674 675 /* 676 * There is a DNS query, internet realm. 677 * I'm going to forward it, but first I have 678 * to control suffix presence. 679 * 680 * After this function, `answer` is the answer to be 681 * sent to the client. 682 * 683 * Returns: 684 * answer len 685 */ 686 int dns_forward(dns_pkt *dp,char *msg,int msglen,char* answer) 687 { 688 dns_pkt *dp_forward; 689 char fwdbuf[DNS_MAX_SZ]; 690 int res; 691 692 if (!_dns_forwarding_) 693 { 694 error("In rslv: dns forwardind is disable."); 695 goto safe_failing; 696 } 697 698 debug(DBG_INSANE, "Forwarding dns query to inet nameservers..."); 699 if (!is_prefixed(dp)) 700 { 701 if((res= ns_general_send(msg,msglen,answer,ANDNS_MAX_SZ))==-1) 702 { 703 error(err_str); 704 goto safe_failing; 705 } 706 destroy_dns_pkt(dp); 707 return res; 708 } 709 710 /* 711 * prepare to re-format query without prefix 712 */ 713 dp_forward= dpktcpy_rm_pref(dp); 714 memset(fwdbuf, 0, DNS_MAX_SZ); 715 716 if ((res= d_p(dp_forward, fwdbuf))==-1) 717 { /* dp_foward is destroyed */ 718 error(err_str); 719 goto safe_failing; 720 } 721 722 res= ns_general_send(fwdbuf, res, answer, ANDNS_MAX_SZ); 723 if (res==-1) 724 { 725 error(err_str); 726 goto safe_failing; 727 } 728 729 res= d_u(answer, res, &dp_forward); 730 if (res<=0) 731 { 732 error(err_str); 733 goto safe_failing; 734 } 735 736 dpktacpy(dp, dp_forward, INET_REALM_PREFIX); 737 destroy_dns_pkt(dp_forward); 738 DNS_SET_NSCOUNT(dp,0); 739 DNS_SET_ARCOUNT(dp,0); 740 741 if ((res= d_p(dp,answer))==-1) 742 { 743 error(err_str); 744 goto failing; 745 } 746 747 return res; 748 749 safe_failing: 750 destroy_dns_pkt(dp); 751 goto failing; 752 753 failing: 754 memcpy(answer, msg, msglen); 755 ANDNS_SET_RCODE(answer, RCODE_ESRVFAIL); 756 ANDNS_SET_QR(answer); 757 res= msglen; 758 err_ret(ERR_RSLFDQ, res); 759 } 760 761 /* There is a DNS query, netsukuku realm. 762 * 763 * I'm going to resolve it in ANDNA. 764 * 765 * After this function, `answer` is the answer to be 766 * sent to the client. 767 * 768 * Returns: 769 * answer len 770 */ 771 772 int inet_rslv(dns_pkt *dp,char *msg,int msglen,char *answer) 773 { 774 inet_prefix addr; 775 int res,qt,rcode; 776 u_short service; 777 snsd_service *ss; 778 snsd_prio *sp; 779 int records; 780 u_char proto; 781 char temp[DNS_MAX_HNAME_LEN]; 782 783 qt= dp->pkt_qst->qtype; 784 rm_realm_prefix(dp->pkt_qst->qname, temp, qt); 785 786 if (qt==T_A || qt==T_MX) 787 { /* snsd tcp resolution service */ 788 service= (qt==T_A)?0:25; 789 proto = (qt!=T_A); 790 ss= andna_resolve_hname(temp, service, proto, &records); 791 792 if (!ss) 793 { 794 rcode=RCODE_ENSDMN; 795 goto safe_return_rcode; 796 } 797 sp= ss->prio; 798 snsd_prio_to_dansws(dp, sp, _ip_len_); 799 snsd_service_llist_del(&ss); 800 801 } 802 else if (qt==T_PTR) 803 { 804 char tomp[DNS_MAX_HNAME_LEN]; 805 lcl_cache *lc; 806 807 res= swapped_straddr(temp, tomp); 808 if (res==-1) 809 { 810 rcode= RCODE_EINTRPRT; 811 goto safe_return_rcode; 812 } 813 814 res= str_to_inet(tomp, &addr); 815 if (res==-1) 816 { 817 rcode=RCODE_ESRVFAIL; 818 goto safe_return_rcode; 819 } 820 821 lc= andna_reverse_resolve(addr); 822 res= lcl_cache_to_dansws(dp, lc); /* destroy lc */ 823 if (!res) 824 { 825 rcode=RCODE_ENSDMN; 826 goto safe_return_rcode; 827 } 828 } 829 else 830 { 831 rcode=RCODE_ENIMPL; 832 goto safe_return_rcode; 833 } 834 835 DNS_SET_QR(dp,1); 836 res= d_p(dp, answer); 837 838 if (res==-1) 839 { 840 rcode= RCODE_ESRVFAIL; 841 goto return_rcode; 842 } 843 return res; 844 845 safe_return_rcode: 846 destroy_dns_pkt(dp); 847 goto return_rcode; 848 849 return_rcode: 850 memcpy(answer, msg, msglen); 851 ANDNS_SET_RCODE(answer, rcode); 852 ANDNS_SET_QR(answer); 853 return msglen; 854 } 855 856 int nk_rslv(andns_pkt *ap,char *msg,int msglen,char *answer) 857 { 858 int qt,res,rcode,records; 859 inet_prefix ipres; 860 uint8_t recs; 861 uint16_t s; 862 863 qt= ap->qtype; 864 if (qt==AT_A) 865 { 866 snsd_service *ss; 867 868 ss= andna_resolve_hash((u_int *)ap->qstdata, 869 ap->service, ap->p+ 1, &records); 870 871 if (!ss) 872 { 873 rcode= RCODE_ENSDMN; 874 goto safe_return_rcode; 875 } 876 877 res= snsd_prio_to_aansws(answer+msglen, 878 ss->prio,_ip_len_,ap->r,&records); 879 if (!records) 880 { 881 rcode= RCODE_ENSDMN; 882 goto safe_return_rcode; 883 } 884 snsd_service_llist_del(&ss); 885 } 886 else if (qt==AT_PTR) 887 { 888 lcl_cache *lc; 889 int family; 890 891 family= ap->qstlength == 4? AF_INET: AF_INET6; 892 res= inet_setip_raw(&ipres, (u_int*)ap->qstdata, family); 893 if (res==-1) 894 { 895 rcode= RCODE_EINTRPRT; 896 goto safe_return_rcode; 897 } 898 inet_ntohl(ipres.data, family); 899 lc= andna_reverse_resolve(ipres); 900 901 if (!lc) 902 { 903 rcode=RCODE_ENSDMN; 904 goto safe_return_rcode; 905 } 906 res= lcl_cache_to_aansws(answer+ msglen, lc, &records); /* destroys lc */ 907 } 908 909 else if (qt==AT_G) 910 { 911 snsd_service *ss; 912 ss= andna_resolve_hash((u_int *)ap->qstdata,-1,0,&records); 913 if (!ss) 914 { 915 rcode=RCODE_ENSDMN; 916 goto safe_return_rcode; 917 } 918 919 res= snsd_service_to_aansws(answer+msglen+2,ss, 920 _ip_len_,&records,ap->r); 921 if (!res) 922 { 923 rcode= RCODE_ENSDMN; 924 goto safe_return_rcode; 925 } 926 if (!records) 927 { 928 rcode= RCODE_ESRVFAIL; 929 goto safe_return_rcode; 930 } 931 snsd_service_llist_del(&ss); 932 } 933 else 934 { 935 rcode= RCODE_EINTRPRT; 936 goto safe_return_rcode; 937 } 938 939 memcpy(answer, msg, msglen); 940 ANDNS_SET_RCODE(answer, RCODE_NOERR); 941 ANDNS_SET_QR(answer); 942 recs= records; 943 if (qt==AT_G) 944 { 945 ANDNS_SET_ANCOUNT(answer,1); 946 s= htons(recs); 947 memcpy(answer+ msglen, &s, 2); 948 res+= 2; 949 } 950 else 951 ANDNS_SET_ANCOUNT(answer, recs); 952 953 return res+msglen; 954 955 safe_return_rcode: 956 destroy_andns_pkt(ap); 957 memcpy(answer,msg,msglen); 958 ANDNS_SET_RCODE(answer,rcode); 959 ANDNS_SET_QR(answer); 960 return msglen; 961 } 962 963 int nk_forward(andns_pkt *ap,char *msg,int msglen,char *answer) 964 { 965 int res,rcode; 966 dns_pkt *dp; 967 char new_answ[DNS_MAX_SZ]; 968 969 res= apqsttodpqst(ap,&dp); 970 if (res==-1) { 971 rcode=RCODE_EINTRPRT; 972 goto safe_return_rcode; 973 } 974 975 res= d_p(dp,answer); 976 if (res==-1) { 977 rcode= RCODE_ESRVFAIL; 978 goto safe_return_rcode; 979 } 980 981 res= ns_general_send(answer,res,new_answ,DNS_MAX_SZ); 982 if (res==-1) { 983 rcode= RCODE_ESRVFAIL; 984 goto safe_return_rcode; 985 } 986 987 res= d_u(new_answ,res,&dp); 988 if (res==-1) { 989 rcode= RCODE_ESRVFAIL; 990 goto safe_return_rcode; 991 } 992 993 res= dpanswtoapansw(dp,ap); 994 if (res==-1) { 995 rcode= RCODE_ESRVFAIL; 996 destroy_dns_pkt(dp); 997 goto safe_return_rcode; 998 } 999 1000 destroy_dns_pkt(dp); 1001 res= a_p(ap,answer); 1002 if (res==-1) { 1003 rcode= RCODE_ESRVFAIL; 1004 goto safe_return_rcode; 1005 } 1006 1007 return res; 1008 1009 safe_return_rcode: 1010 debug(DBG_INSANE,err_str); 1011 destroy_andns_pkt(ap); 1012 memcpy(answer,msg,msglen); 1013 ANDNS_SET_QR(answer); 1014 ANDNS_SET_RCODE(answer,rcode); 1015 return msglen; 1016 } 1017 1018 /* 1019 * This is the main function for the resolution: the dns_wrapper receive the 1020 * buffer and rslv builds the answer. 1021 * `answer' is the buffer where the answer will be stored, it must be at 1022 * least of `ANDNS_MAX_SZ' bytes. 1023 * 1024 * Returns: 1025 * NULL if the pkt has to be discarded. 1026 * A ptr to the answer to be sended if OK: 1027 * in this case, answ_len is filled with 1028 * the answer len. 1029 */ 1030 char *andns_rslv(char *msg, int msglen,char *answer, int *answ_len) 1031 { 1032 int proto, res, r; 1033 dns_pkt *dp; 1034 andns_pkt *ap; 1035 1036 proto= GET_NK_BIT(msg); 1037 if (proto==NK_DNS) res= d_u(msg,msglen,&dp); 1038 else if (proto==NK_INET || proto==NK_NTK) res= a_u(msg,msglen,&ap); 1039 else { 1040 debug(DBG_INSANE,"andns_rslv(): Which language are you speaking?"); 1041 return NULL; 1042 } 1043 1044 if (res==0) goto discard; 1045 1046 memset(answer, 0, ANDNS_MAX_SZ); 1047 if (res==-1) goto intrprt; 1048 1049 if (proto== NK_DNS) 1050 { 1051 r= andns_realm(dp->pkt_qst, NULL); 1052 if (r== INET_REALM) 1053 res= dns_forward(dp, msg, msglen, answer); 1054 else 1055 res= inet_rslv(dp, msg, msglen, answer); 1056 } 1057 else if (proto==NK_NTK) res= nk_rslv(ap,msg,msglen,answer); 1058 else if (proto==NK_INET) res= nk_forward(ap,msg,msglen,answer); 1059 1060 *answ_len= res; 1061 return answer; 1062 1063 discard: 1064 debug(DBG_INSANE, err_str); 1065 err_ret(ERR_RSLAQD, NULL); 1066 intrprt: 1067 debug(DBG_INSANE, err_str); 1068 memcpy(answer, msg, msglen); 1069 ANDNS_SET_RCODE(answer, 1); 1070 ANDNS_SET_QR(answer); 1071 *answ_len= msglen; 1072 return answer; 1073 } 1074 1075 1076 1077
| alpt (at) freaknet (dot) org | ViewVC Help |
| Powered by ViewVC 1.1-dev |