我目前正在尝试开发一个显示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 :(得分:3)
请参阅以下有关站点本地地址和链接本地地址以及它们如何工作的说明:
IPv6 tutorial – Part 6: Site-local addresses and link-local addresses
您可以使用Win32 API GetAdapterAddresses()
函数获取本地计算机的IPv6地址。
答案 1 :(得分: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;
端;
debugLog只是一种在文本文件中写入的方法。