【问题标题】:How to extract local computers Site Local and Link Local IPv6 address in Delphi?如何在 Delphi 中提取本地计算机站点本地和链接本地 IPv6 地址?
【发布时间】:2013-02-28 09:56:49
【问题描述】:

我目前正在尝试开发一个显示 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;

提前致谢。

【问题讨论】:

    标签: delphi


    【解决方案1】:

    关于什么是站点本地地址和链接本地地址以及它们如何工作,请参阅以下说明:

    IPv6 tutorial – Part 6: Site-local addresses and link-local addresses

    您可以使用 Win32 API GetAdapterAddresses() 函数来获取本地机器的 IPv6 地址。

    【讨论】:

      【解决方案2】:

      我找到了另一种使用 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;
      

      结束;

      debugLog 只是一种写入文本文件的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-10
        • 2010-09-12
        相关资源
        最近更新 更多