📄 dns_recu.c.svn-base
字号:
case DNS_T_PTR:
if((pkt = OS_mem_alloc(pMsg->qsec_len+DNS_HDR_LENGTH+12+len)) == NULL)
{
#if DNSR_DEBUG
DBG_L3_Printf("dns_response_tx: allocate memory failed!!\n") ;
#endif
return FALSE;
}
pkt_len = pMsg->qsec_len+DNS_HDR_LENGTH+12+len;
dns_encode_bits32((unsigned char *)pkt + DNS_HDR_FLAGS,
DNS_FLD(pMsg->query_id, DNS_HDR_ID) | DNS_HDR_RD
| DNS_HDR_RESP | DNS_HDR_RA);
dns_encode_bits16((unsigned char *)pkt + DNS_HDR_QDCOUNT, 1);
dns_encode_bits16((unsigned char *)pkt + DNS_HDR_ANCOUNT, 1);
dns_encode_bits16((unsigned char *)pkt + DNS_HDR_NSCOUNT, 0);
dns_encode_bits16((unsigned char *)pkt + DNS_HDR_ARCOUNT, 0);
memcpy(pkt+DNS_HDR_LENGTH, pMsg->qsec_ptr, pMsg->qsec_len);
p = (unsigned char *)pkt+DNS_HDR_LENGTH+pMsg->qsec_len;
dns_encode_bits16(p,0xc00c);
p += 2;
dns_encode_bits16(p, pMsg->qtype);
p += 2;
dns_encode_bits16(p, pMsg->qclass);
p += 2;
dns_encode_bits32(p, ttls[0]);
p += 4;
dns_encode_bits16(p, (UI16_T )len);
p += 2;
memcpy(p, name, len);
break;
default:
break;
} /* switch */
DNSR_Send_Packet_To_Client(pkt,pkt_len, pMsg);
/* free the packet */
OS_mem_free(pkt);
return TRUE;
} /* dns_response_tx */
/*------------------------------------------------------------------------
* void dns_request_receive()
* Purpose: parse DNS request packet
*
* Parameters:
* Input:
* Output:
* returns :
*------------------------------------------------------------------------
*/
void dns_request_receive(PENDING_DNSR_MSG_PTR pMsg,
struct dns_header *hdr)
{
unsigned char *qsec_ptr = pMsg->udp_data + DNS_HDR_LENGTH;
unsigned char *p = qsec_ptr;
int qnamelen, namebuflen;
unsigned char namebuf[DNS_MAX_DOMAIN_NAME],cache_namebuf[DNS_MAX_DOMAIN_NAME];
struct dns_qrr qrr;
UI32_T answer_ip[1],ttl[1];
char *aname;
int encoded_anamelen;
BOOLEAN_T b_ask = FALSE;
/* DNSR status is Disabled or check structur NULL*/
if (!DNSR_Get_Status() || hdr == NULL)
{
#if DNSR_DEBUG
DBG_L3_Printf("OS_mem_free(dns_request_receive): pMsg=%x\n", pMsg);
#endif
OS_mem_free(pMsg);
return;
}
/* valid queries have one question and zero answers */
if (hdr->qdcount != 1 || hdr->ancount != 0 || hdr->nscount != 0 || hdr->arcount != 0)
{
#if DNSR_DEBUG
DBG_L3_Printf("OS_mem_free: pMsg=%x\n", pMsg);
#endif
OS_mem_free(pMsg);
return;
}
/*
* Check flag in the received header.
*
* The message must be a request
* The only opcode we support is QUERY.
* Should not be a TrunCation packet
* Recersion Desired
*/
if (hdr->resp || hdr->op != DNS_OPCODE_QUERY || hdr->tc || !hdr->rd)
{
#if DNSR_DEBUG
DBG_L3_Printf("Flags wrong 1\n");
DBG_L3_Printf("OS_mem_free: pMsg=%x\n", pMsg);
#endif
OS_mem_free(pMsg);
return;
}
/*
* Check the Question section.
*
* Make sure the name server claims to be answering the question we asked.
*/
if((qnamelen = strlen((const char*)qsec_ptr)) == 0)
{
#if DNSR_DEBUG
DBG_L3_Printf("qnamelen == 0 \n");
DBG_L3_Printf("OS_mem_free: pMsg=%x\n", pMsg);
#endif
OS_mem_free(pMsg);
return;
}
qrr.name = p;
p += (qnamelen+1);
qrr.type = (UI16_T )dns_decode_bits16(p);
p += 2;
qrr.class = (UI16_T )dns_decode_bits16(p);
if (qrr.class != DNS_C_IN)
{
#if DNSR_DEBUG
DBG_L3_Printf("Class is not equal to DNS_C_IN\n");
DBG_L3_Printf("OS_mem_free: pMsg=%x\n", pMsg);
#endif
OS_mem_free(pMsg);
return;
}
pMsg->query_id = hdr->id;
pMsg->qclass = qrr.class;
pMsg->qtype = qrr.type;
pMsg->qsec_ptr = qsec_ptr;
pMsg->qsec_len = (UI16_T )(qnamelen+1+DNS_QS_QUERY_TYPE_LENGTH+DNS_QS_QUERY_CLASS_LENGTH);
memset(&namebuf[0],0x0,DNS_MAX_DOMAIN_NAME);
namebuflen = dns_decode_name((char *)&namebuf[0],DNS_MAX_DOMAIN_NAME,qsec_ptr,0,0);
if (namebuflen<=0 || qnamelen+1 >DNS_MAX_DOMAIN_NAME)
{
#if DNSR_DEBUG
DBG_L3_Printf("dns_decode_name: namebuf error!\n");
#endif
OS_mem_free(pMsg);
return;
}
memcpy(&cache_namebuf[0],pMsg->qsec_ptr,qnamelen+1);
ttl[0] = DNSR_Get_Max_TTL();
switch (qrr.type)
{
case DNS_T_A:
/* Look up Static Table */
if (DNSR_Get_Lookup_Status())
{
answer_ip[0] = dns_find_ip_at_table((unsigned char*)&namebuf[0]);
if (answer_ip[0] != 0)
{
dns_response_tx(pMsg,1,answer_ip,0,ttl);
break;
}
}
/* Look up the cache */
if (DNSR_Get_Cache_Status())
{
answer_ip[0] = dns_cache_ip_lookup(cache_namebuf,pMsg);
if (answer_ip[0] != 0)
{
dns_response_tx(pMsg,1,answer_ip,0,ttl);
break;
}
}
if (dns_ask(namebuf, pMsg) == FALSE)
{
#if DNSR_DEBUG
DBG_L3_Printf("dns_ask failure!\n");
#endif
break;
}
b_ask = TRUE;
break;
case DNS_T_PTR:
/* Look up Static Table */
if (DNSR_Get_Lookup_Status())
{
aname = dns_find_name_at_table((unsigned char*)&namebuf[0]);
if (aname != 0)
{
memset(&namebuf[0],0x0,DNS_MAX_DOMAIN_NAME);
encoded_anamelen = dns_encode_name(namebuf,DNS_MAX_DOMAIN_NAME,aname);
if (encoded_anamelen <= 0)
{
#if DNSR_DEBUG
DBG_L3_Printf("dns_encode_name: aname error!\n");
#endif
break;
}
dns_response_tx(pMsg,encoded_anamelen,0,namebuf,ttl);
break;
}
}
/* Look up the cache */
if (DNSR_Get_Cache_Status())
{
aname = dns_cache_name_lookup(cache_namebuf,&encoded_anamelen,pMsg);
if (aname != 0)
{
dns_response_tx(pMsg,encoded_anamelen,0,(unsigned char*)aname,ttl);
break;
}
}
if (dns_ask(namebuf, pMsg)== FALSE)
{
#if DNSR_DEBUG
DBG_L3_Printf("dns_ask failure!\n");
#endif
break;
}
b_ask = TRUE;
break;
default:
#if DNSR_DEBUG
DBG_L3_Printf("invalid data type\n");
#endif
break;
} /* switch */
/* if the DNSR replay the response directly, the pkt buffer must be freed */
if (b_ask == FALSE)
{
#if DNSR_DEBUG
DBG_L3_Printf("OS_mem_free: pMsg=%x\n", pMsg);
#endif
OS_mem_free(pMsg);
}
return;
}
/*------------------------------------------------------------------------
* int dns_response_rx()
* Purpose: Handle the reply packets from network
*
* Parameters:
* Input:
* Output:
* returns :
*------------------------------------------------------------------------
*/
void dns_response_rx(PENDING_DNSR_MSG_PTR pMsg, struct dns_header *hdr)
{
int i;
UI32_T srv_ipa;
struct sockaddr_in *client;
BOOLEAN_T bfound;
/* Check DNS status */
if (!DNSR_Get_Status())
{
#if DNSR_DEBUG
DBG_L3_Printf("OS_mem_free: pMsg=%x\n", pMsg);
#endif
OS_mem_free(pMsg);
return;
}
if (retrieve_query_by_id(hdr->id) == 0)
{
#if DNSR_DEBUG
DBG_L3_Printf("dns_response_rx: dnsr_get_query_id returned 0\n");
DBG_L3_Printf("OS_mem_free(dns_response_rx): pMsg=%x\n", pMsg);
#endif
OS_mem_free(pMsg);
return;
}
/* to avoid DNS spoofing, check src IP */
bfound = FALSE;
client = (struct sockaddr_in *)&pMsg->client;
srv_ipa = client->sin_addr;
for (i=0;i<DNSR_MAX_NAME_SERVER;i++)
{
if (srv_ipa == DNSR_Get_DNS_Server(i))
{
bfound = TRUE;
break;
}
}
if (bfound == FALSE)
{
#if DNSR_DEBUG
DBG_L3_Printf("dns_response_rx: invaild src IP\n");
DBG_L3_Printf("OS_mem_free(dns_response_rx): pMsg=%x\n", pMsg);
#endif
OS_mem_free(pMsg);
return;
}
if (!dns_receive(pMsg,hdr,pMsg->udp_data,pMsg->udp_len))
{
#if DNSR_DEBUG
DBG_L3_Printf("dns_receive FAIL, ready to dns_udp_retransmit!!!\n");
#endif
}
DBG_L3_Printf("OS_mem_free: pMsg=%x\n", pMsg);
OS_mem_free(pMsg);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -