You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

andns.c 23KB

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