2010年9月10日   
[首页] [业界新闻] [编程技巧] [控件仓库] [源码下载] [书籍下载] [系统设计] [会员中心] [请您留言] [自由论坛]
  本站新增划词翻译功能!!

Socket DNS查詢之實現
日期:2007-12-17 类别:网络 作者: 推荐:本站 人气:3471


       昨天突然無法訪問任何網站了,可是QQ還在正常工作~~~~~`嗯,肯定是DNS出了問題~~
 用自己做的TraceRoute察看了一下,6個網關都工作正常~~~确實是DNS壞了~~
 爛鐵通的DNS太差~~換~~~可是哪個DNS更好?
 自己做一個工具比較一下吧~~可是還不懂DNS的工作原理^_^
 搜索百度,下載TCP/IP 詳解2卷~~竟然沒有一個能下的了......還中了木馬~~~~`暈倒!
 不過有收獲!找到了全國的各大城市DNS列表!
  看來隻有自己蒙了!好在還有IRIS。不過試用期隻剩10天了!呵呵,抓包......原來是這樣的:Windows向DNS發送了一個UDP包,這個包中當然有’www.xxx.com’,然後DNS服務器返回一個包含IP地址的UDP包,我們的工作就是分解這個包~~~~~

 DNS服務器的端口是53,接受的Query package格式如下:

 PDomainQuery = ^YDomainQuery;
 YDomainQuery = record
 u16id : word;//任意
 u16flag : word;//$0100; //标準查詢
 u16question : word;//1
 u16answer : word;//0
 u16author : word;//0
 u16addition : word;//0
 u8secB : byte;//section begin
 u8secE : byte;//section end
 u16type : word;//1
 u16class : word;//1
 end;


我們這樣填充這個包:

procedure FillDomainQuery( pdq: PDomainQuery; sAddr: string );
var
 pData, pTemp : PChar;
 i, cbLen : Integer;
 pu16 : PWord;
begin
   FillChar( pdq^, sizeof(YDomainQuery) + Length(sAddr), 0 );
  
   pdq^.u16id := htons( DNS_ID );
   pdq^.u16flag := htons( DNS_STAND_QUERY );
   pdq^.u16question := htons( DNS_QUESTION );
   //pdq^.u16answer := 0; //pdq^.u16author := 0; //pdq^.u16addition := 0;

   //初始化域名數據緩沖區
 cbLen := Length(sAddr) + 2;
   pData := AllocMem( cbLen );
   Inc( pData );
   Move( sAddr[1], pData^, Length(sAddr) );
   Dec( pData );
  
   //填充域名數據緩沖區
 pTemp := pData;
   i := Pos( ’.’, sAddr ); //www.baidu.com --- example
 while i > 0 do
   begin //i=4; i=6
 pTemp^ := Chr(i-1); // 3 5
 Inc( pTemp, i ); // ^ ^
 Delete( sAddr, 1, i ); //s=’baidu.com’; s=’com’
 i := Pos( ’.’, sAddr );
     end;
   pTemp^ := Chr( Length(sAddr) ); //s=’com’
 Inc( pTemp, Length(sAddr)+1 );
   pTemp^ := #0;
  
   //把域名數據拷貝到pdq^.u8secB
 pTemp := @pdq^.u8secB;
   Move( pData^, pTemp^, cbLen );
   FreeMem( pData );
  
   //最後填寫Type/Class
 pu16 := PWord( pTemp + cbLen );
   pu16^ := htons( DNS_TYPE_HOST );
   Inc( pu16 );
   pu16^ := htons( DNS_CLASS_INET );
  end;

//把構造好的包發送出去
var
 pdq : PDomainQuery;
 pdq := AllocMem( sizeof(YDomainQuery) + Length(edtDomain.text) );
 FillDomainQuery( pdq, edtDomain.text );
 udp.SendBuf( PChar(pdq), sizeof(YDomainQuery) + Length(edtDomain.text) );

//不過DNS返回的包更複雜~~~不給它定義什麽結構了,直接整!!!
function DecodeDomainAnwser( pbuf: PChar; len: Integer ):string;
var
 p : PChar;
 w : Word;
 j : Integer;
 s1,s2,s3,s4: string;
begin
   p := pbuf; j:=0;
   result := ’TransactionID: ’ + IntToStr( PWord(p)^ ) +#13#10;
  
   Inc( p, 2 ); Inc( j, 2 );
   result := result + ’Response Flag:’ + Format(’%x’, [ntohs(PWord(p)^)]) +#13#10;
   if ntohs( PWord(p)^ ) <> DNS_STAND_RES then
   begin
     result := result + ’Response error...’ +#13#10;
     Exit;
     end;
  
   Inc( p, 2 ); Inc( j, 2 );
   result := result + ’Question: ’ +IntToStr( ntohs(PWord(p)^) )+ #13#10;
   Inc( p, 2 ); Inc( j, 2 );
   result := result + ’Answer: ’ +IntToStr( ntohs(PWord(p)^) )+ #13#10;
   Inc( p, 2 ); Inc( j, 2 );
   result := result + ’Authority: ’ +IntToStr( ntohs(PWord(p)^) )+ #13#10;
   Inc( p, 2 ); Inc( j, 2 );
   result := result + ’Addition: ’ +IntToStr( ntohs(PWord(p)^) )+ #13#10;
  
   Inc( p, 2 ); Inc( j, 2 );
   w := Byte( p^ );
   while w > 0 do //跳過DNS HOST返回的要查詢的域名
 begin
     Inc( p, w + 1 ); Inc( j, w+1 );
     w := Byte( p^ );
     end;
  
   Inc( p ); Inc( j );
   Inc( p, 4 ); Inc( j, 4 );//type/class
 Inc( p, 6 ); Inc( j, 6 );//name/type/class
 Inc( p, 4 ); Inc( j, 4 );//time

   w := ntohs( PWord(p)^ ); //得到數據長度
 Inc( p, 2 ); Inc( j, 2 );//到達真正的數據地址
 Inc( p, w ); Inc( j, w );
   Inc( p, 10 ); Inc( j, 10 );
   Inc( p, 2 ); Inc( j, 2 );
   s1 := IntToStr( Byte(p^) ); Inc( p ); Inc( j );
   s2 := IntToStr( Byte(p^) ); Inc( p ); Inc( j );
   s3 := IntToStr( Byte(p^) ); Inc( p ); Inc( j );
   s4 := IntToStr( Byte(p^) ); Inc( p ); Inc( j );
   result := result + ’IP: ’ + s1 + ’.’ + s2 + ’.’ + s3 + ’.’ + s4 + #13#10;
  
   if len < j+32 then
   Exit;
  
   Inc( p, 6 ); //+name/type/class
 Inc( p, 4 ); //+time

   Inc( p, 2 ); //到達真正的數據地址
 s1 := IntToStr( Byte(p^) ); Inc( p );
   s2 := IntToStr( Byte(p^) ); Inc( p );
   s3 := IntToStr( Byte(p^) ); Inc( p );
   s4 := IntToStr( Byte(p^) );
   result := result + ’IP: ’ + s1 + ’.’ + s2 + ’.’ + s3 + ’.’ + s4 +#13#10;
  end;

 呵呵,試驗一下,全國的各大城市DNS列表中的Host竟然大都不能用~~~~~~~

网友评论区



(C)Copyright Delphi俱乐部, 1999-2010。所有版权保留
京ICP备05013674号