📄 dns.c
字号:
dns_event_listener(DNS_EVENT_ERROR,DNS_ERROR_GENERAL);
return (-1);
}
dns_ancount=(((UINT16)RECEIVE_NETWORK_B())<<8);
dns_ancount+=RECEIVE_NETWORK_B();
dns_nscount=(((UINT16)RECEIVE_NETWORK_B())<<8);
dns_nscount+=RECEIVE_NETWORK_B();
/* skip ARCOUNT */
(void)RECEIVE_NETWORK_B();
(void)RECEIVE_NETWORK_B();
/* got to the data, let's process it */
/* check if question section is appropriate (QNAME the same
and QTYPE=QCLASS=1
*/
tmp_ptr=dns_hostptr;
while((tmp_byte=RECEIVE_NETWORK_B())!=0){
while((tmp_byte--)!=0){
if(*tmp_ptr++!=RECEIVE_NETWORK_B()){
DEBUGOUT("DNS: QNAME not the same!!!! \r\n");
/* we'll assume that this was from some previous
query and just exit here */
return (-1);
}
}
/* reached the end of the label. Is it dot or end of string? */
if(*tmp_ptr=='\0'){
continue;
}
if(*tmp_ptr++!='.'){
DEBUGOUT("DNS: DOT not where it's supposed to be!\r\n");
return (-1);
}
}
/* qtype and qclass */
tmp_int=(((UINT16)RECEIVE_NETWORK_B())<<8);
tmp_int+=RECEIVE_NETWORK_B();
tmp_int|=((UINT16)(RECEIVE_NETWORK_B())<<8);
tmp_int|=RECEIVE_NETWORK_B();
if(tmp_int!=0x0001){
DEBUGOUT("DNS: Question section QTYPE and/or QCLASS not ok!\r\n");
dns_event_listener(DNS_EVENT_ERROR,DNS_ERROR_GENERAL);
return (-1);
}
/* process all answer RRs and try to find answer */
/* simply try to find INET class RR. It is
_PROBABLY_ what we're after. More extensive checking
would demand buffering the reply which may not be
desireable.
*/
while(dns_ancount||dns_nscount){
do{
tmp_byte=RECEIVE_NETWORK_B();
}while((tmp_byte!=0)&&((tmp_byte&0xc0)!=0xc0));
if(tmp_byte!=0) /*second offset byte used in compression*/
RECEIVE_NETWORK_B();
/* TYPE */
tmp_int=((UINT16)RECEIVE_NETWORK_B())<<8;
tmp_int|=RECEIVE_NETWORK_B();
/* CLASS */
tmp_int|=(((UINT16)RECEIVE_NETWORK_B())<<8);
tmp_int|=RECEIVE_NETWORK_B();
/* CLASS==INET and TYPE=A ? */
if(tmp_int==0x0001){
/* got it. Skip TTL and read RDLENGTH */
for(tmp_byte=0;tmp_byte<6;tmp_byte++){
tmp_int=(tmp_int<<8)+RECEIVE_NETWORK_B();
}
if(tmp_int==0x0004){
/* great, read IP address*/
dns_tmp_ip=((UINT32)RECEIVE_NETWORK_B())<<24;
dns_tmp_ip+=((UINT32)RECEIVE_NETWORK_B())<<16;
dns_tmp_ip+=((UINT32)RECEIVE_NETWORK_B())<<8;
dns_tmp_ip+=RECEIVE_NETWORK_B();
/* we got some IP address. Is it what we asked for
or a NS IP addr*/
if(dns_ancount){
DEBUGOUT("DNS: Got IP address!\r\n");
dns_event_listener(DNS_EVENT_SUCCESS,dns_tmp_ip);
dns_state=DNS_STATE_READY;
}else{
DEBUGOUT("DNS: Got auth DNS IP addr!\r\n");
/* invoke another query to the authority */
dns_retransmit();
}
return 0;
}else{
/* nope, skip other bytes */
while(tmp_int--)
RECEIVE_NETWORK_B();
}
}else{
DEBUGOUT("DNS: RR.CLASS not INET. Skipping!\r\n");
/* skip TTL and read RDLENGTH*/
for(tmp_byte=0;tmp_byte<6;tmp_byte++){
tmp_int=(tmp_int<<8)+RECEIVE_NETWORK_B();
}
/* skip RDATA */
while(tmp_int--)
RECEIVE_NETWORK_B();
}
/* decrement counters */
if(dns_ancount)
dns_ancount--;
else
if(dns_nscount)
dns_nscount--;
}
break;
default:
DEBUGOUT("DNS: unknown UDP event :-(");
break;
}
return 0;
}
/** \brief Invokes DNS resolver
* \author
* \li Vladan Jovanovic (vladan.jovanovic@violasystems.com)
* \date 10.10.2002
* \param host_name_ptr Pointer to null-terminated host name to be
* resolved
* \param listener Pointer to DNS listener function that listens to events
* from DNS client. This function takes two parameters: first one can
* take a value of #DNS_EVENT_SUCCESS or #DNS_EVENT_ERROR and thus
* determine the meaning of the second parameter. If first parameter
* is #DNS_EVENT_SUCCESS, second parameter represents requested IP
* address. In case of #DNS_EVENT_ERROR, second parameter can be one
* of the: #DNS_ERROR_FORMAT, #DNS_ERROR_SERVER_FAILURE,
* #DNS_ERROR_NAME_ERROR, #DNS_ERROR_NOT_IMPLEMENTED, #DNS_ERROR_REFUSED,
* #DNS_ERROR_TIMEOUT, #DNS_ERROR_GENERAL
* \return
* \li #DNS_ERROR_BUSY - Signals that DNS is currently processing
* another request so it is not possible to process a new one
* \li #DNS_ERROR_OVERFLOW - Network transmit buffer too small to hold
* DNS request
* \li #DNS_ERROR_LABEL - Label in host name longer than 63 bytes. Error
* \li #DNS_ERROR_NAME - Host name longer than 264 bytes. Error
*
* Invoke this function to start name-resolving process. Note that currently
* DNS client can process only one request at a time and will not allow
* multiple requests.
*
*
*/
INT16 get_host_by_name(UINT8 *host_name_ptr, void (*listener)(UINT8 , UINT32 )){
UINT8 *buf_ptr;
INT8 i;
UINT16 total;
switch(dns_state){
case DNS_STATE_READY:
dns_state=DNS_STATE_BUSY;
dns_hostptr=host_name_ptr;
dns_event_listener=listener;
dns_tmp_ip=DNS_SERVER_IP;
dns_retries=DNS_NUM_RETRIES;
init_timer(dns_timer,DNS_RESEND_PERIOD*TIMERTIC);
break;
case DNS_STATE_BUSY:
DEBUGOUT("DNS: Error, trying to invoke two DNS requests at the same time!\r\n");
return DNS_ERROR_BUSY;
case DNS_STATE_RESEND:
if(host_name_ptr!=dns_hostptr){
DEBUGOUT("DNS: Ptrs different. Can't do that! \r\n");
return DNS_ERROR_BUSY;
}
break;
default:
DEBUGOUT("DNS: What am I doing in this state?\r\n");
RESET_SYSTEM();
}
/* OK, create message in the Netbuf transmit buffer */
buf_ptr=net_buf+UDP_APP_OFFSET;
/* first the header */
*((UINT16 *)buf_ptr)=0xAAAA; /* id, fixed for now*/
buf_ptr+=2;
*buf_ptr++=0x01;
*buf_ptr++=0x00;
/*question count*/
*buf_ptr++=0x00;
*buf_ptr++=0x01;
/* others are zero */
for(i=0;i<6;i++)
*buf_ptr++=0x00;
/* ok, create the question section */
total=0;
while((*host_name_ptr)!='\0'){
/* we are still not at the end. Reserve space for count */
buf_ptr++;
i=0;
while(((*host_name_ptr)!='.')&&((*host_name_ptr)!='\0')){
i++;
*buf_ptr++=*host_name_ptr++;
if(buf_ptr==(net_buf+NETWORK_TX_BUFFER_SIZE)){
DEBUGOUT("DNS: Buffer overflow!!!\r\n");
return(DNS_ERROR_OVERFLOW);
}
}
/* label shorter than 63 bytes or less? */
if((i<=0)||(i>=64)){
DEBUGOUT("DNS: Label size wrong! Aborting....\r\n");
return(DNS_ERROR_LABEL);
}
/* it seems ok for now. Increase total name length*/
total+=i;
if(total>=264){
DEBUGOUT("DNS: Name size wrong! Aborting....\r\n");
return(DNS_ERROR_NAME);
}
*(buf_ptr-i-1)=i; /* store label length */
/* ok, where are we ? */
if((*host_name_ptr)=='.'){
/* still not at the end, skip dot */
host_name_ptr++;
}else
if((*host_name_ptr)=='\0'){
/* OHO, finished,
add ZERO,QTYPE and QCLASS */
*buf_ptr++=0x00;
*buf_ptr++=0x00;
*buf_ptr++=0x01;
*buf_ptr++=0x00;
*buf_ptr++=0x01;
kick_WD();
/* ok, now send the request */
return udp_send(dns_socket,dns_tmp_ip,DNS_UDP_PORT,net_buf+UDP_APP_OFFSET,NETWORK_TX_BUFFER_SIZE-UDP_APP_OFFSET,buf_ptr-(net_buf+UDP_APP_OFFSET));
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -