www.pudn.com > Net_apps.rar > dns.c


/* 
********************************************************************************************************* 
* Copyright 2003 Service & Quality Technology CO., LTD. ALL RIGHTS RESERVED. 
* This software is provided under license and contains proprietary and 
* confidential material which is the property of SQ tech. 
* 
* FileName     : dns.c 
* Description  : 
* 
* 
* Version control: 
*  $Revision: 0.1 $    Date: 2003/12/15 12:00:00  gofly 
*      first implemetation 
* 
********************************************************************************************************* 
*/ 
#include "..\include\L3\net_apps\dns\dns.h" 
 
Sdns_table G_dns_table[DNS_TABLE_NUMBER]; 
INT8U DnsSendKey = 0; 
 
#if DNS_OPEN 
 
 
 
int   socket_udp_dns_client; 
 
void http_dns_recv_thread (void *data){ 
    Sdns_packet          dns_packet; 
    struct sockaddr_in   name; 
    struct sockaddr      from; 
    INT8U                fromlen; 
    INT32U                i; 
    INT8U                count; 
     //-- test 
    INT8U   ip[4]; 
            // sleep_forever(); 
    socket_udp_dns_client      =       socket(0,SOCK_DGRAM,0); 
 
 
 
    ASSERT_EX1(DNS_DEBUG, "DNS sock creat DESTORY", socket_udp_dns_client !=  INVALID_SOCKET); 
 
    name.sin_addr.s_addr    =   0; 
    name.sin_port           =   0x3f0d;//3391 
 
 
 
    bind(socket_udp_dns_client,&name,0); 
 
    memset(G_dns_table,0x00,sizeof(G_dns_table)); 
 
    //--- test 
 
  //  dns_table(0, (INT8U*)"tknet.tku.edu.tw" , ip, DNS_LOOK_UP); 
 
    DnsSendKey = 1; 
 
    while(1){ 
        recvfrom(socket_udp_dns_client,&dns_packet,sizeof(dns_packet),0,&from,&fromlen); 
 ////       if(dns_packet.frr != 0x80|| (dns_packet.qa<<16) != 0x01000000||(dns_packet.qa>>24) < 0x01) 
        if( (dns_packet.frr & 0x7f) != 0) 
        { 
            dns_table(dns_packet.query_ident ,NULL ,"\xff\xff\xff\xff",DNS_FINISH ); 
        } 
        else 
        { 
 
            count = dns_packet.qa >> 24; 
 
            for(i=1; i < 65530 ; i++ ) 
            { 
                if(dns_packet.zone[i] == 0xc0) 
                { 
                    count--; 
 
                    if(count == 0 ) 
                    { 
                        dns_table(dns_packet.query_ident ,NULL ,dns_packet.zone+i+12,DNS_FINISH ); 
                        break; 
                    } 
                } 
            }/*for(i=1; i < 128 ; i++ )*/ 
        } 
    } 
 
 
} 
 
 
 
void http_dns_send_thread (void *data){ 
 
    INT8U                   searchdnstablei,flag,dnsname[16],i; 
    INT8U                   ucErr; 
    INT8S                   index; 
    INT8U                   fqdn[32]; 
    INT8U                   fqdntemp[32]; 
    INT8U                   fqdntemplen; 
    INT8U                   *pch; 
    Sdns_packet             dns_packet; 
    struct  ip_addr         addr; 
    struct sockaddr         from; 
 
    dns_packet.qof          =   0x01; 
    dns_packet.frr          =   0x00; 
    dns_packet.qa           =   0x00000100; 
    dns_packet.aa           =   0x00000000; 
 
    searchdnstablei         =   0; 
 
//    OSSemPend(http_dns_send_even_sem,0,&ucErr); 
    while(!DnsSendKey) 
    { 
        OSTimeDlyHMSM(0, 0, 1, 0); 
    } 
 
    while(1){ 
        memset(fqdn,0x00,sizeof(fqdn)) ; 
        index = dns_table(searchdnstablei,fqdn ,NULL,DNS_UNFINISH); 
        searchdnstablei++; 
 
        if(searchdnstablei  == DNS_TABLE_NUMBER) 
        { 
           searchdnstablei    =   0; 
        } 
 
        if(index == 0) 
        { 
          OSTimeDlyHMSM(0, 0, 1 , 0); 
          continue; 
        } 
        //---- make request msg-----------// 
        dns_packet.query_ident = index; 
 
        memset(fqdntemp,0x00,sizeof(fqdntemp)); 
        sprintf((char*)fqdntemp,".%s.\x00\x00\x00",(char*)fqdn); 
        pch         =   fqdntemp; 
        fqdntemplen =   strlen((char*)fqdntemp); 
 
 
        while(1){ 
            *pch=strcspn(pch+1,"\x2e\x00"); 
            pch+=*pch+1; 
 
            if(*pch==0x00) 
                break; 
        } 
        memset(dns_packet.zone,0x00,sizeof(dns_packet.zone)); 
        memcpy(dns_packet.zone,fqdntemp,fqdntemplen); 
        memcpy(dns_packet.zone+fqdntemplen,"\x00\x01\x00\x01",4); 
        //-----------------------------------// 
 
 
 
        ((struct sockaddr_in *)&from)->sin_port         =   0x3500;//53; 
 
        for (i=1;i<3;i++) 
        { 
            sprintf(dnsname,"DNS_IP_Address_%d",i); 
                         
            inet_aton((const char*)IoDns((INT8U*)dnsname, NULL, IOR, ROOT), &addr); 
 
        ((struct sockaddr_in *)&from)->sin_addr.s_addr  =    addr.addr; 
 
            flag = sendto(socket_udp_dns_client,&dns_packet,sizeof(dns_packet)-sizeof(dns_packet.zone)+4+fqdntemplen,0,&from,0); 
 
            if (flag < 0 ) 
            { 
                break; 
            } 
        } 
        OSTimeDlyHMSM(0, 0, 1 , 0); 
    } 
 
 
} 
#endif  /*DNS_OPEN  */ 
 
 
/****************************************************************************/ 
/* FUNCTION NAME :   dns_table 
/* DESCRIPTION   : 
/* in PARAMETERS : 
/* out PARAMETERS: 
/* RETURN VALUES :   R_OK R_ER 
/* EXAMPLE	 : 
*****************************************************************************/ 
 
INT8S dns_table(INT8U index,INT8U *fqdn,INT8U *ip,INT8U order ){ 
    INT8S return_val; 
    //OS_ENTER_CRITICAL(); 
    if(!DnsSendKey)// dns clinet not start 
        return R_ER; 
 
    asm {PUSHF; CLI} 
    switch(order) 
    { 
        case  DNS_LOOK_UP: 
            return_val = dns_table_lookup(fqdn,ip); 
            break; 
        case  DNS_CLEAR: 
              memset(G_dns_table,0x00,sizeof(G_dns_table)); 
             return_val = R_OK; 
            break; 
        case  DNS_UNFINISH: 
             return_val = dns_table_unfinish(index,fqdn); 
            break; 
        case  DNS_FINISH: 
 
             return_val = dns_table_finish(index,ip); 
            break; 
        default : 
             return_val = R_ER; 
    } 
    asm  POPF 
    //OS_EXIT_CRITICAL(); 
    return return_val; 
 
} 
/****************************************************************************/ 
/* FUNCTION NAME :   dns_table_finish 
/* DESCRIPTION   :   dns request ok,finish dns table 
/* in PARAMETERS : 
/* out PARAMETERS: 
/* RETURN VALUES :   R_OK R_ER 
/* 
/* EXAMPLE	 : 
*****************************************************************************/ 
INT8S dns_table_finish(INT8U index,INT8U *ip){ 
    INT8U i; 
 
 
    for(i =0 ; i < DNS_TABLE_NUMBER; i++ ) 
    { 
        if(G_dns_table[i].index == index ) 
        { 
 
         memcpy(G_dns_table[i].ip,ip,4); 
         break; 
 
        } 
 
 
    } 
 
 
    return R_OK; 
} 
 
/****************************************************************************/ 
/* FUNCTION NAME :   dns_table_lookup 
/* DESCRIPTION   :   find dns table data 
/* in PARAMETERS : 
/* out PARAMETERS: 
/* RETURN VALUES :   R_OK R_ER 
/* 
/* EXAMPLE	 : 
*****************************************************************************/ 
INT8S dns_table_lookup(INT8U *fqdn,INT8U* ip){ 
    INT8U        i; 
    static INT8U index = 0; 
 
 
    if(fqdn == NULL ) return R_ER; 
    for(i =0 ; i < DNS_TABLE_NUMBER; i++ ) 
    { 
        if(!strncmp(G_dns_table[i].fqdn,fqdn,strlen(fqdn))&& 
            strlen(G_dns_table[i].fqdn)==strlen(fqdn) ) 
        { 
            if(G_dns_table[i].ip[0] != 0x00 ) 
            { 
                 
                memcpy(ip,G_dns_table[i].ip,4); 
                G_dns_table[i].count = DNS_COUNT_MAX; 
                return R_OK;   // find 
            } 
 
 
            return R_RU;  //running 
 
        } 
    } 
    // find err  search empty | count ==  DNS_COUNT_MAX 
    if(i == DNS_TABLE_NUMBER) 
    { 
 
        for(i =0 ;i < DNS_TABLE_NUMBER ; i++) 
        { 
            if(G_dns_table[i].count == DNS_COUNT_MAX || G_dns_table[i].index == 0x00) 
            { 
                if(index == 64 ) 
                { 
                    memset(G_dns_table,0x00,sizeof(G_dns_table)); 
                    index = 0; 
                } 
                index++; 
                memset(&G_dns_table[i],0x00,sizeof(Sdns_table)); 
                G_dns_table[i].index=index; 
                memcpy(G_dns_table[i].fqdn,fqdn,strlen(fqdn)); 
                break; 
            } 
 
        } /* for(i =0 ;i < DNS_TABLE_NUMBER ; i++)*/ 
 
    } /* if(i == DNS_TABLE_NUMBER)*/ 
 
 
 
    if( i == DNS_TABLE_NUMBER) return R_ER; 
 
    return R_RU; 
} 
/****************************************************************************/ 
/* FUNCTION NAME :   dns_table 
/* DESCRIPTION   : 
/* in PARAMETERS : 
/* out PARAMETERS: 
/* RETURN VALUES :   index R_ER 
/* EXAMPLE	 : 
*****************************************************************************/ 
INT8S dns_table_unfinish(INT8U index,INT8U *fqdn){ 
    INT8U               i; 
 
    for(i =0 ; i < DNS_TABLE_NUMBER; i++ ) 
    { 
        if(G_dns_table[i].index != 0x00  ) 
        { 
            if(G_dns_table[i].count != DNS_COUNT_MAX)//0x3c 60 
            { 
                G_dns_table[i].count++; 
            } 
        } 
 
    } 
 
    if(G_dns_table[index].index != 0x00 && G_dns_table[index].ip[0] == 0x00) 
    { 
        memcpy(fqdn,G_dns_table[index].fqdn,strlen(G_dns_table[index].fqdn)); 
        return   G_dns_table[index].index; 
    } 
 
    return 0; 
 
  
 
 
}