2013-02-28 107 views
1

我目前正在嘗試開發一個顯示IPv6流量的應用程序。我很困惑如何提取本地站點和本地機器的鏈接本地地址。任何指導將不勝感激。如何提取本地計算機站點本地和鏈接Delphi中的本地IPv6地址?

在Delphi將IPv6分組我使用的結構是:預先

type 
PIPV6HeaderPtr = ^TIPV6Header; 
TIPV6Header = packed record 
ip6_flow  : DWORD; // 4 bits = version #,// 8 bits = Trafic class,// 20 bits = flow label 
ip6_len  : Word;//Cardinal; // Payload length 
//ip6_next  : Cardinal; // Next Header 
    ip6_next  : Byte; // Next Header 
ip6_hops  : Byte;   // Hop Limit 
    h_source : IN6_ADDR; 
h_dest : IN6_ADDR; 
end; 

// 
// IPv6 extension header format 
// 
type 
    PIPV6EXTPTR = ^TIPV6EXT; 
    TIPV6EXT = packed record 
    ip6_next  : Byte; 
    ip6_len  : Byte; 
    ip6_data  : array[0..1] of Byte; 

End; 


type 
    PIPV6EXT_FRAGPTR = ^TIPV6EXT_FRAG; 
    TIPV6EXT_FRAG = packed record 
    ip6_next  : Byte; 
    ip6_reserved : Byte; 
    ip6_offlg  : Word; 
    ip6_ident  : DWORD; 
End; 

感謝。

回答

0

我已經找到另一種方法使用的WSAIoctl以獲取地址。我在下面添加我的代碼。

使用WinSock2; //網上廣泛使用

function TForm1.GetIPUsingIoctlMethod(var sInt: string): Boolean; 
    var 
    s: TSocket; 
    wsaD: TWSADATA; 
    NumInterfaces: Integer; 
    BytesReturned, SetFlags: u_long; 
    pAddrInet: SOCKADDR_IN; 
    pAddrString: PCHAR; 
    PtrA: pointer; 
    Buffer: Array[0..20] Of INTERFACE_INFO_EX; 
    i: Integer; 
    Local_IpList : TStringList ; 
    addrList : LPSOCKET_ADDRESS_LIST ; 
    in6 : PSockAddr; 
    protoInfo : WSAProtocol_Info; 
    text : Array[1..46] Of Char; 
    Buffer1 : DWORD; 
    Str : String; 

begin 
     result := False;        // Initialize 
     sInt := ''; 
Try 

    WSAStartup($0101, wsaD);      // Start WinSock 
                // You should normally check 
                // for errors here :) 

    {Create a WSA Socket} 
    //s := WSASocketA(AF_INET6,SOCK_STREAM, IPPROTO_IP, nil, 0, 0); 

    s:= Socket(AF_INET6,SOCK_STREAM,IPPROTO_IP); 

    //s := Socket(AF_INET6, SOCK_STREAM, 0);   // Open a socket 
    if (s = INVALID_SOCKET) then exit; 

    try           // Call WSAIoCtl 
     PtrA := @bytesReturned; 

     if (WSAIoCtl(s, SIO_ADDRESS_LIST_QUERY, nil, 0, @Buffer, SizeOf(Buffer), PtrA, nil, nil)<> SOCKET_ERROR) 
     then 
      begin          // If ok, find out how 
                // many interfaces exist 

       Result := True; 
       addrList := LPSOCKET_ADDRESS_LIST(@Buffer); 


       DebugLog(' i = ' + IntToStr(addrList.iAddressCount),0); 
       // NumInterfaces := BytesReturned div SizeOf(INTERFACE_INFO); 

       Local_IpList := TStringList.Create ; 
       for i := 0 to addrList.iAddressCount - 1 do  // For every interface 
       begin 
        If (addrList.Address[i].lpSockaddr.sin_family = AF_Inet6) Then 
        Begin 
         in6 := PSockaddr(@addrList.Address[i].lpSockaddr); 
         Buffer1 := SizeOf(Text); 
         //protoInfo. 
         FillChar(Text,SizeOf(Text),#0); 
         If WSAAddressToString(addrList.Address[i].lpSockaddr,addrList.Address[i].iSockaddrLength, 
              nil,@text,Buffer1) <> 0 Then 
         Begin 
          debuglog('err1 = ' + SysErrorMessage(WSAGetLastError),0); 
         end; 
         Str := Text; 
         DebugLog(' Addr cnt =' + IntToStr(i) + ' = ' + Str,0); 
         Buffer1 := 0; 
         FillChar(Text,SizeOf(Text),#0); 
         //in6. 
         //DebugLog('ip = ' +); 
         //IN6_IS_ADDR_LINKLOCAL 
        end; 
       end; 

     end 
     Else 
      sInt := SysErrorMessage(WSAGetLastError); 
    except 
    end; 
    // 
    // Close sockets 
    // 
    CloseSocket(s); 
    WSACleanUp; 
Except 
End; 

end;

debugLog只是一種在文本文件中寫入的方法。

相關問題