void DnsQuery(PCHAR pDomain, UCHAR iType, UCHAR iBankOffset, USHORT sCallBackAddr) { UCHAR i; DNS_HANDLE pDcb; pDcb = _pDcbData; for (i = 0; i < DNS_CB_TSIZE; i ++) { if(pDcb->iState == DS_RESOLVED && iType == pDcb->iType) { // this should be a case insensitive string compare if (!strcmp(pDomain, pDcb->pName)) { // domain name alreay resolved TaskDnsDone(pDcb->pAnswer, sCallBackAddr, iBankOffset); return; } } pDcb ++; } pDcb = dns_alloc(); if (pDcb) { dns_save_send(pDcb, pDomain, sCallBackAddr, iBankOffset, iType); } else { dns_failed(sCallBackAddr, iBankOffset); } }
static char *dns_str_from_rdata( const unsigned char *rdata ) { char *str; unsigned int len = rdata[0]; str = dns_alloc( len + 1 ); if (str) { memcpy( str, ++rdata, len ); str[len] = '\0'; } return str; }
static char *dns_dname_from_msg( ns_msg msg, const unsigned char *pos ) { int len; char *str, dname[NS_MAXDNAME] = "."; /* returns *compressed* length, ignore it */ len = dns_ns_name_uncompress( ns_msg_base( msg ), ns_msg_end( msg ), pos, dname, sizeof(dname) ); len = strlen( dname ); str = dns_alloc( len + 1 ); if (str) strcpy( str, dname ); return str; }
struct dnspkt * dns_extractpkt(const unsigned char *buf, int len) { u_int16_t qdcount, ancount, remain, *offsets, i, j, off; const unsigned char *ptr; struct dnspkt *pkt; struct rr *rrp; struct ns_answer_header *nsh; if (len < 17) return NULL; pkt = dns_alloc(); struct ns_transaction_header *nsth= (struct ns_transaction_header*)buf; pkt->id = ntohs(nsth->tid); qdcount = ntohs(nsth->questions); ancount = ntohs(nsth->answers); offsets = malloc(qdcount * 4); ptr = buf + sizeof(struct ns_transaction_header); remain = len - sizeof(struct ns_transaction_header); i = 0; while (qdcount--) { offsets[i++] = ptr - buf; rrp = _new_listitem(&pkt->query); rrp->data = decompress_label((char*)buf, len, (char*)ptr); if (!rrp->data) { syslog(LOG_ERR, "dns_extractpkt: decompress_label choked in qd\n"); free(offsets); dns_free(pkt); return NULL; } rrp->len = strlen(rrp->data)+1; ptr = _skip_lbl(ptr, &remain); if (!ptr) { syslog(LOG_ERR, "dns_extractpkt: _skip_lbl choked in qd\n"); free(offsets); dns_free(pkt); return NULL; } ptr += 4; remain -= 4; } while (ancount--) { rrp = _new_listitem(&pkt->answer); rrp->link = -1; if ((ptr[0] & 0xc0) == 0xc0) { off = (ptr[0] & ~(0xc0)) * 256 + ptr[1]; for (j = 0; j < i; j++) if (offsets[j] == off) break; if (j < i) rrp->link = j; } ptr=_skip_lbl(ptr,&remain); nsh=(struct ns_answer_header *)ptr; ptr+=sizeof(struct ns_answer_header); remain-=sizeof(struct ns_answer_header); //printf("REMAIN=%u, datalen=%u, type= 0x%02x, sizeof ns_answer_header=%u\n",remain,ntohs(nsh->datalen), ntohs(nsh->type),sizeof(struct ns_answer_header)); if (ntohs(nsh->type) != NSTYPE_TXT){ ptr+=ntohs(nsh->datalen); remain-=ntohs(nsh->datalen); continue; } rrp->len = ntohs(nsh->datalen); rrp->data = malloc(rrp->len); memcpy(rrp->data, ptr,rrp->len); remain -= rrp->len; ptr += rrp->len; } return(pkt); }