?? dns_client.c
字號:
//*------------------------------------------------------------------------------------------------
//* 文件名 : dns_clinet.c
//* 功能描述 : dns客戶端
//* 作者 : 焦海波
//* 版本 : 0.1
//* 建立日期、時間 : 2006/08/10 15:23
//* 最近修改日期、時間 :
//* 修改原因 :
//*------------------------------------------------------------------------------------------------
//*------------------------------------------ 頭文件 -----------------------------------------------
#include "/uCOS_II/includes.h"
#include "/LwIP/include/lwip/tcpip.h"
#include "dns_client.h"
//*================================================================================================
//* 函 數 區
//*================================================================================================
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : ulDNToIP
//* 功能描述 : 查詢DNS服務器,將指定的域名轉換為IP地址
//* : <pszDN>[in] 指向域名的指針
//* : <lDNLen>[in] 域名長度
//* : <pstPbuf>[in] 指向st_pbuf結構的指針,它這個結構保存要發送的DNS的查詢包
//* 出口參數 : 無
//*------------------------------------------------------------------------------------------------
__inline void __ilvPacketDNSQuest(BYTE *pszDN, LONG lDNLen, st_pbuf *pstPbuf)
{
ST_DNS_PACKET_HDR *__pstDNSPacket;
BST_ID_AND_FLAGS *__pbstIDAndFlags;
__pstDNSPacket = (ST_DNS_PACKET_HDR*)pstPbuf->payload;
__pstDNSPacket->ulIDAndFlags = 0x00000000;
__pbstIDAndFlags = &__pstDNSPacket->ulIDAndFlags;
__pbstIDAndFlags->bitID = 0x0608;
__pbstIDAndFlags->bitIsRD = 0x1;
__pstDNSPacket->uwQCount = 0x0100;
__pstDNSPacket->uwACount = 0x0000;
__pstDNSPacket->uwAuthCount = 0x0000;
__pstDNSPacket->uwARC = 0x0000;
memcpy((UBYTE*)pstPbuf->payload + DNS_PACKET_HDR_LEN, pszDN, lDNLen);
*((UBYTE*)pstPbuf->payload + DNS_PACKET_HDR_LEN + lDNLen) = 0x00;
*((UBYTE*)pstPbuf->payload + DNS_PACKET_HDR_LEN + lDNLen + 1) = DNS_PACKET_QUERY_TYPE;
*((UBYTE*)pstPbuf->payload + DNS_PACKET_HDR_LEN + lDNLen + 2) = 0x00;
*((UBYTE*)pstPbuf->payload + DNS_PACKET_HDR_LEN + lDNLen + 3) = DNS_PACKET_QUERY_CLASS;
}
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : __ilulParseRespDNSPacket
//* 功能描述 : 解析DNS服務器響應的數據包
//* 入口參數 : <pstPbuf>[in] 指向ST_NETBUF的指針
//* : <pulIP>[in] 指向接收緩沖區(保存IP地址)的指針
//* : <lDNlen>[in] 要查詢域名的長度
//* 出口參數 : - DNS_OK : 查詢成功
//* : - DNS_NOT_EXIST : 指定的域名不存在
//* : - DNS_OTHER : 未知錯誤
//*------------------------------------------------------------------------------------------------
__inline ULONG __ilulParseRespDNSPacket(st_pbuf *pstPbuf, ULONG *pulIP, LONG lDNLen)
{
ST_DNS_PACKET_HDR *__pstDNSPacket;
ULONG __ulVal;
BST_ID_AND_FLAGS *__pbstIDAndFlags;
void *__pvData;
UWORD __uwACount, __uwAnswerDataLen, __uwOffset;
__pstDNSPacket = (ST_DNS_PACKET_HDR *)pstPbuf->payload;
__ulVal = __pstDNSPacket->ulIDAndFlags;
__pbstIDAndFlags = &__ulVal;
if(__pbstIDAndFlags->bitOptResult == 0)
{
__uwACount = macHighToLowForWord(__pstDNSPacket->uwACount);
__uwOffset = lDNLen + 14;
while(__uwACount > 0)
{
__pvData = (UBYTE*)pstPbuf->payload + DNS_PACKET_HDR_LEN + __uwOffset;
__uwAnswerDataLen = macHighToLowForWord(*((__packed UWORD*)__pvData));
if((__uwAnswerDataLen == 4) && macHighToLowForWord(*((__packed UWORD*)((UBYTE*)__pvData - 8))) == DNS_PACKET_QUERY_TYPE)
{
*pulIP = *((__packed ULONG *)((UBYTE*)__pvData + 2));
return DNS_OK;
}
__uwOffset += 12 + __uwAnswerDataLen;
__uwACount--;
}
return DNS_OTHER;
}
else if(__pbstIDAndFlags->bitOptResult == 3)
{
return DNS_NOT_EXIST;
}
return DNS_OTHER;
}
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : __vDNSRecv
//* 功能描述 : 接收并解析DNS服務器響應的數據包,它是一個回調函數,由udp_recv()設置
//* 入口參數 : <pstArg>[in] 指向ST_RECV_FUN_ARG結構的指針,這個結構保存著該函數需要的入口參數
//* : <pstUDPPCB>[in] 指向ST_UDP_PCB結構的指針
//* : <pstPbuf>[in] 指向st_pbuf結構的指針,它保存著收到的內容
//* : <pstIP>[in] IP地址
//* : <uwPort>[in] 端口號
//* 出口參數 : - DNS_OK : 查詢成功
//* : - DNS_NOT_EXIST : 指定的域名不存在
//* : - DNS_OTHER : 未知錯誤
//*------------------------------------------------------------------------------------------------
static void __vDNSRecv(ST_RECV_FUN_ARG *pstArg, ST_UDP_PCB *pstUDPPCB,
st_pbuf *pstPbuf, st_ip_addr *pstIP, UWORD uwPort)
{
if(pstPbuf != NULL)
{
pstArg->ulRtnCode = __ilulParseRespDNSPacket(pstPbuf, pstArg->pulIP, pstArg->lDNLen);
pbuf_free(pstPbuf);
}
}
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : __ulGetIP
//* 功能描述 : 查詢DNS服務器,獲取指定域名綁定的IP地址,這里只能使用協議棧直接接口實現,使用其提供
//* : 的API無法滿足需求。如果接收DNS響應包使用netconn_recv函數非常容易阻塞系統,因為UDP
//* : 不可靠。
//* : <pstPbuf>[in] 指向st_pbuf結構的指針,它這個結構保存要發送的DNS的查詢包
//* : <pulIP>[in] 指向接收緩沖區(保存IP地址)的指針
//* : <lDNLen>[in] 要查詢的域名長度
//* : <ulDNSIP>[in] DNS服務器的IP地址
//* 出口參數 : - DNS_OK : 查詢成功
//* : - DNS_NOT_EXIST : 指定的域名不存在
//* : - DNS_NOT_CONN : 無法連接指定的域名服務器(主、備服務器均不可用)
//* : - DNS_OTHER : 未知錯誤
//*------------------------------------------------------------------------------------------------
ULONG __ulGetIP(st_pbuf *pstPbuf, ULONG *pulIP, LONG lDNLen, ULONG ulDNSIP)
{
st_ip_addr __stIPAddr;
ST_UDP_PCB *__pstUDPPCB;
ST_RECV_FUN_ARG __stRecvArg;
LONG i, k = 0;
ULONG __ulRtnCode;
__pstUDPPCB = udp_new();
if(__pstUDPPCB == NULL)
return DNS_OTHER;
__stIPAddr.addr = htonl(ulDNSIP);
if(udp_connect(__pstUDPPCB, &__stIPAddr, DNS_PORT) != ERR_OK)
return DNS_OTHER;
memset(&__stRecvArg, 0, sizeof(ST_RECV_FUN_ARG));
__stRecvArg.ulRtnCode = -1;
__stRecvArg.pulIP = pulIP;
__stRecvArg.lDNLen = lDNLen;
udp_recv(__pstUDPPCB, __vDNSRecv, &__stRecvArg);
//* 發送和接收
while(k<15)
{
udp_send(__pstUDPPCB, pstPbuf);
i = 0;
while(i < 30)
{
__ulRtnCode = __stRecvArg.ulRtnCode;
if(__ulRtnCode != -1)
goto __lbEnd;
OSTimeDlyHMSM(0, 0, 0, 100);
i++;
}
k++;
}
__lbEnd:
//* 收尾工作,回收占用的資源
udp_disconnect(__pstUDPPCB);
udp_remove(__pstUDPPCB);
if(__ulRtnCode != -1)
return __stRecvArg.ulRtnCode;
else
return DNS_NOT_CONN;
}
//*------------------------------------------------------------------------------------------------
//* 函數名稱 : ulDNToIP
//* 功能描述 : 查詢DNS服務器,將指定的域名轉換為IP地址
//* 入口參數 : <pszDN>[in] 指向域名的指針
//* : <lDNLen>[in] 域名長度
//* : <pulIP>[in] 指向接收緩沖區(保存IP地址)的指針
//* 出口參數 : - DNS_OK : 查詢成功
//* : - DNS_NOT_EXIST : 指定的域名不存在
//* : - DNS_NOT_CONN : 無法連接指定的域名服務器(主、備服務器均不可用)
//* : - DNS_OTHER : 未知錯誤
//*------------------------------------------------------------------------------------------------
ULONG ulDNToIP(BYTE *pszDN, LONG lDNLen, ULONG *pulIP)
{
st_pbuf *__pstPbuf = NULL;
LONG __lTotLen;
ULONG __ulRtnCode;
__lTotLen = DNS_PACKET_HDR_LEN + lDNLen + 4;
__pstPbuf = pbuf_alloc(PBUF_RAW, __lTotLen, PBUF_POOL);
if(__pstPbuf == NULL)
return DNS_OTHER;
__ilvPacketDNSQuest(pszDN, lDNLen, __pstPbuf);
__ulRtnCode = __ulGetIP(__pstPbuf, pulIP, lDNLen, DNS1_IP_ADDR);
if(__ulRtnCode == DNS_NOT_CONN)
__ulRtnCode = __ulGetIP(__pstPbuf, pulIP, lDNLen, DNS2_IP_ADDR);
pbuf_free(__pstPbuf);
return __ulRtnCode;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -