📄 jwaws2tcpip.pas
字号:
iiNetmask: SOCKET_ADDRESS; // Network mask
end;
{$EXTERNALSYM _INTERFACE_INFO_EX}
INTERFACE_INFO_EX = _INTERFACE_INFO_EX;
{$EXTERNALSYM INTERFACE_INFO_EX}
LPINTERFACE_INFO_EX = ^INTERFACE_INFO_EX;
{$EXTERNALSYM LPINTERFACE_INFO_EX}
TInterfaceInfoEx = INTERFACE_INFO_EX;
PInterfaceInfoEx = LPINTERFACE_INFO_EX;
// Possible flags for the iiFlags - bitmask
const
IFF_UP = $00000001; // Interface is up
{$EXTERNALSYM IFF_UP}
IFF_BROADCAST = $00000002; // Broadcast is supported
{$EXTERNALSYM IFF_BROADCAST}
IFF_LOOPBACK = $00000004; // this is loopback interface
{$EXTERNALSYM IFF_LOOPBACK}
IFF_POINTTOPOINT = $00000008; //this is point-to-point interface
{$EXTERNALSYM IFF_POINTTOPOINT}
IFF_MULTICAST = $00000010; // multicast is supported
{$EXTERNALSYM IFF_MULTICAST}
// structure for IP_PKTINFO option
//
type
in_pktinfo = record
ipi_addr: IN_ADDR; // destination IPv4 address
ipi_ifindex: UINT; // received interface index
end;
{$EXTERNALSYM in_pktinfo}
TInPktInfo = in_pktinfo;
PInPktInfo = ^in_pktinfo;
// C_ASSERT(sizeof(IN_PKTINFO) == 8);
// structure for IPV6_PKTINFO option
//
in6_pktinfo = record
ipi6_addr: IN6_ADDR; // destination IPv6 address
ipi6_ifindex: UINT; // received interface index
end;
{$EXTERNALSYM in6_pktinfo}
TIn6PktInfo = in6_pktinfo;
PIn6PktInfo = ^in6_pktinfo;
// C_ASSERT(sizeof(IN6_PKTINFO) == 20);
// Error codes from getaddrinfo()
const
EAI_AGAIN = WSATRY_AGAIN;
{$EXTERNALSYM EAI_AGAIN}
EAI_BADFLAGS = WSAEINVAL;
{$EXTERNALSYM EAI_BADFLAGS}
EAI_FAIL = WSANO_RECOVERY;
{$EXTERNALSYM EAI_FAIL}
EAI_FAMILY = WSAEAFNOSUPPORT;
{$EXTERNALSYM EAI_FAMILY}
EAI_MEMORY = WSA_NOT_ENOUGH_MEMORY;
{$EXTERNALSYM EAI_MEMORY}
//#define EAI_NODATA WSANO_DATA
EAI_NONAME = WSAHOST_NOT_FOUND;
{$EXTERNALSYM EAI_NONAME}
EAI_SERVICE = WSATYPE_NOT_FOUND;
{$EXTERNALSYM EAI_SERVICE}
EAI_SOCKTYPE = WSAESOCKTNOSUPPORT;
{$EXTERNALSYM EAI_SOCKTYPE}
//
// DCR_FIX: EAI_NODATA remove or fix
//
// EAI_NODATA was removed from rfc2553bis
// need to find out from the authors why and
// determine the error for "no records of this type"
// temporarily, we'll keep #define to avoid changing
// code that could change back; use NONAME
//
EAI_NODATA = EAI_NONAME;
{$EXTERNALSYM EAI_NODATA}
// Structure used in getaddrinfo() call
type
LPADDRINFO = ^addrinfo;
{$EXTERNALSYM LPADDRINFO}
addrinfo = record
ai_flags: Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST
ai_family: Integer; // PF_xxx
ai_socktype: Integer; // SOCK_xxx
ai_protocol: Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6
ai_addrlen: size_t; // Length of ai_addr
ai_canonname: PChar; // Canonical name for nodename
ai_addr: PSockAddr; // Binary address
ai_next: LPADDRINFO; // Next structure in linked list
end;
{$EXTERNALSYM addrinfo}
TAddrInfo = addrinfo;
PAddrInfo = LPADDRINFO;
// Flags used in "hints" argument to getaddrinfo()
const
AI_PASSIVE = $1; // Socket address will be used in bind() call
{$EXTERNALSYM AI_PASSIVE}
AI_CANONNAME = $2; // Return canonical name in first ai_canonname
{$EXTERNALSYM AI_CANONNAME}
AI_NUMERICHOST = $4; // Nodename must be a numeric address string
{$EXTERNALSYM AI_NUMERICHOST}
function getaddrinfo(nodename, servname: PChar; hints: PAddrInfo; var res: PAddrInfo): Integer; stdcall;
{$EXTERNALSYM getaddrinfo}
procedure freeaddrinfo(ai: PAddrInfo); stdcall;
{$EXTERNALSYM freeaddrinfo}
// WARNING: The gai_strerror inline functions below use static buffers,
// and hence are not thread-safe. We'll use buffers long enough to hold
// 1k characters. Any system error messages longer than this will be
// returned as empty strings. However 1k should work for the error codes
// used by getaddrinfo().
const
GAI_STRERROR_BUFFER_SIZE = 1024;
{$EXTERNALSYM GAI_STRERROR_BUFFER_SIZE}
function gai_strerrorA(ecode: Integer): PChar;
{$EXTERNALSYM gai_strerrorA}
function gai_strerrorW(ecode: Integer): PWideChar;
{$EXTERNALSYM gai_strerrorW}
{$IFDEF UNICODE}
function gai_strerror(ecode: Integer): PWideChar;
{$EXTERNALSYM gai_strerror}
{$ELSE}
function gai_strerror(ecode: Integer): PChar;
{$EXTERNALSYM gai_strerror}
{$ENDIF}
type
socklen_t = Integer;
{$EXTERNALSYM socklen_t}
function getnameinfo(sa: PSockAddr; salen: socklen_t; host: PChar; hostlen: DWORD; serv: PChar; servlen: DWORD; flags: Integer): Integer; stdcall;
{$EXTERNALSYM getnameinfo}
const
NI_MAXHOST = 1025; // Max size of a fully-qualified domain name
{$EXTERNALSYM NI_MAXHOST}
NI_MAXSERV = 32; // Max size of a service name
{$EXTERNALSYM NI_MAXSERV}
INET_ADDRSTRLEN = 16; // Max size of numeric form of IPv4 address
{$EXTERNALSYM INET_ADDRSTRLEN}
INET6_ADDRSTRLEN = 46; // Max size of numeric form of IPv6 address
{$EXTERNALSYM INET6_ADDRSTRLEN}
// Flags for getnameinfo()
NI_NOFQDN = $01; // Only return nodename portion for local hosts
{$EXTERNALSYM NI_NOFQDN}
NI_NUMERICHOST = $02; // Return numeric form of the host's address
{$EXTERNALSYM NI_NUMERICHOST}
NI_NAMEREQD = $04; // Error if the host's name not in DNS
{$EXTERNALSYM NI_NAMEREQD}
NI_NUMERICSERV = $08; // Return numeric form of the service (port #)
{$EXTERNALSYM NI_NUMERICSERV}
NI_DGRAM = $10; // Service is a datagram service
{$EXTERNALSYM NI_DGRAM}
implementation
uses
SysUtils, JwaWinBase, JwaWinNT;
function IP_MSFILTER_SIZE(numsrc: Integer): Integer;
begin
Result := SizeOf(ip_msfilter) - SizeOf(in_addr) + (numsrc * SizeOf(in_addr));
end;
function SS_PORT(ssp: Pointer): u_short;
begin
Result := PSockAddrIn(ssp)^.sin_port;
end;
procedure IN6ADDR_SETANY(var x: TSockAddrIn6);
var
I: Integer;
begin
x.sin6_family := AF_INET6;
x.sin6_port := 0;
x.sin6_flowinfo := 0;
for I := 0 to 15 do x.sin6_addr.s6_addr[I] := 0;
end;
procedure IN6ADDR_SETLOOPBACK(var x: TSockAddrIn6);
var
I: Integer;
begin
x.sin6_family := AF_INET6;
x.sin6_port := 0;
x.sin6_flowinfo := 0;
for I := 0 to 14 do x.sin6_addr.s6_addr[I] := 0;
x.sin6_addr.s6_addr[15] := 1;
end;
function IN6ADDR_ISANY(const x: TSockAddrIn6): Boolean;
var
I: Integer;
begin
Result := x.sin6_family = AF_INET6;
for I := 0 to 15 do Result := Result and (x.sin6_addr.s6_addr[I] = 0);
end;
function IN6ADDR_ISLOOPBACK(const x: TSockAddrIn6): Boolean;
var
I: Integer;
begin
Result := x.sin6_family = AF_INET6;
for I := 0 to 14 do Result := Result and (x.sin6_addr.s6_addr[I] = 0);
Result := Result and (x.sin6_addr.s6_addr[15] = 1);
end;
function IN6_ADDR_EQUAL(const a, b: in6_addr): Boolean;
begin
Result := CompareMem(@a, @b, SizeOf(in6_addr));
end;
function IN6_IS_ADDR_UNSPECIFIED(const a: in6_addr): boolean;
begin
Result := IN6_ADDR_EQUAL(a, in6addr_any);
end;
function IN6_IS_ADDR_LOOPBACK(const a: in6_addr): Boolean;
begin
Result := IN6_ADDR_EQUAL(a, in6addr_loopback);
end;
function IN6_IS_ADDR_MULTICAST(const a: in6_addr): Boolean;
begin
Result := (a.s6_bytes[0] = $ff);
end;
function IN6_IS_ADDR_LINKLOCAL(const a: in6_addr): Boolean;
begin
Result := ((a.s6_bytes[0] = $fe) and ((a.s6_bytes[1] and $c0) = $80));
end;
function IN6_IS_ADDR_SITELOCAL(const a: in6_addr): Boolean;
begin
Result := ((a.s6_bytes[0] = $fe) and ((a.s6_bytes[1] and $c0) = $c0));
end;
function IN6_IS_ADDR_V4MAPPED(const a: in6_addr): Boolean;
begin
Result := ((a.s6_words[0] = 0) and (a.s6_words[1] = 0) and (a.s6_words[2] = 0) and
(a.s6_words[3] = 0) and (a.s6_words[4] = 0) and (a.s6_words[5] = $ffff));
end;
function IN6_IS_ADDR_V4COMPAT(const a: in6_addr): Boolean;
begin
Result :=
((a.s6_words[0] = 0) and
(a.s6_words[1] = 0) and
(a.s6_words[2] = 0) and
(a.s6_words[3] = 0) and
(a.s6_words[4] = 0) and
(a.s6_words[5] = 0) and
not ((a.s6_words[6] = 0) and
(a.s6_addr[14] = 0) and
((a.s6_addr[15] = 0) or (a.s6_addr[15] = 1))));
end;
function IN6_IS_ADDR_MC_NODELOCAL(const a: in6_addr): Boolean;
begin
Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 1);
end;
function IN6_IS_ADDR_MC_LINKLOCAL(const a: in6_addr): Boolean;
begin
Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 2);
end;
function IN6_IS_ADDR_MC_SITELOCAL(const a: in6_addr): Boolean;
begin
Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 5);
end;
function IN6_IS_ADDR_MC_ORGLOCAL(const a: in6_addr): Boolean;
begin
Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = 8);
end;
function IN6_IS_ADDR_MC_GLOBAL(const a: in6_addr): Boolean;
begin
Result := IN6_IS_ADDR_MULTICAST(a) and ((a.s6_bytes[1] and $f) = $e);
end;
const
ws2tcpip = 'ws2_32.dll';
function getaddrinfo; external ws2tcpip name 'getaddrinfo';
procedure freeaddrinfo; external ws2tcpip name 'freeaddrinfo';
function gai_strerrorA(ecode: Integer): PChar;
var
dwMsgLen: DWORD;
buff: array [0..GAI_STRERROR_BUFFER_SIZE] of Char;
begin
dwMsgLen := FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK,
nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PChar(buff[0]), GAI_STRERROR_BUFFER_SIZE, nil);
if dwMsgLen = 0 then
Result := nil
else
Result := PChar(buff[0]);
end;
function gai_strerrorW(ecode: Integer): PWideChar;
var
dwMsgLen: DWORD;
buff: array [0..GAI_STRERROR_BUFFER_SIZE] of WideChar;
begin
dwMsgLen := FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK,
nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PWideChar(buff[0]), GAI_STRERROR_BUFFER_SIZE, nil);
if dwMsgLen = 0 then
Result := nil
else
Result := PWideChar(buff[0]);
end;
{$IFDEF UNICODE}
function gai_strerror(ecode: Integer): PWideChar;
var
dwMsgLen: DWORD;
buff: array [0..GAI_STRERROR_BUFFER_SIZE] of WideChar;
begin
dwMsgLen := FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK,
nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PWideChar(buff[0]), GAI_STRERROR_BUFFER_SIZE, nil);
if dwMsgLen = 0 then
Result := nil
else
Result := PWideChar(buff[0]);
end;
{$ELSE}
function gai_strerror(ecode: Integer): PChar;
var
dwMsgLen: DWORD;
buff: array [0..GAI_STRERROR_BUFFER_SIZE] of Char;
begin
dwMsgLen := FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_MAX_WIDTH_MASK,
nil, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), PChar(buff[0]), GAI_STRERROR_BUFFER_SIZE, nil);
if dwMsgLen = 0 then
Result := nil
else
Result := PChar(buff[0]);
end;
{$ENDIF}
function getnameinfo; external ws2tcpip name 'getnameinfo';
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -