📄 sslinux.pas
字号:
wVersion: Word;
wHighVersion: Word;
szDescription: array[0..WSADESCRIPTION_LEN] of Char;
szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char;
iMaxSockets: Word;
iMaxUdpDg: Word;
lpVendorInfo: PChar;
end;
function IN6_IS_ADDR_UNSPECIFIED(const a: PInAddr6): boolean;
function IN6_IS_ADDR_LOOPBACK(const a: PInAddr6): boolean;
function IN6_IS_ADDR_LINKLOCAL(const a: PInAddr6): boolean;
function IN6_IS_ADDR_SITELOCAL(const a: PInAddr6): boolean;
function IN6_IS_ADDR_MULTICAST(const a: PInAddr6): boolean;
function IN6_ADDR_EQUAL(const a: PInAddr6; const b: PInAddr6):boolean;
procedure SET_IN6_IF_ADDR_ANY (const a: PInAddr6);
procedure SET_LOOPBACK_ADDR6 (const a: PInAddr6);
var
in6addr_any, in6addr_loopback : TInAddr6;
procedure FD_CLR(Socket: TSocket; var FDSet: TFDSet);
function FD_ISSET(Socket: TSocket; var FDSet: TFDSet): Boolean;
procedure FD_SET(Socket: TSocket; var FDSet: TFDSet);
procedure FD_ZERO(var FDSet: TFDSet);
{=============================================================================}
type
TWSAStartup = function(wVersionRequired: Word; var WSData: TWSAData): Integer;
cdecl;
TWSACleanup = function: Integer;
cdecl;
TWSAGetLastError = function: Integer;
cdecl;
TGetServByName = function(name, proto: PChar): PServEnt;
cdecl;
TGetServByPort = function(port: Integer; proto: PChar): PServEnt;
cdecl;
TGetProtoByName = function(name: PChar): PProtoEnt;
cdecl;
TGetProtoByNumber = function(proto: Integer): PProtoEnt;
cdecl;
TGetHostByName = function(name: PChar): PHostEnt;
cdecl;
TGetHostByAddr = function(addr: Pointer; len, Struc: Integer): PHostEnt;
cdecl;
TGetHostName = function(name: PChar; len: Integer): Integer;
cdecl;
TShutdown = function(s: TSocket; how: Integer): Integer;
cdecl;
TSetSockOpt = function(s: TSocket; level, optname: Integer; optval: PChar;
optlen: Integer): Integer;
cdecl;
TGetSockOpt = function(s: TSocket; level, optname: Integer; optval: PChar;
var optlen: Integer): Integer;
cdecl;
TSendTo = function(s: TSocket; const Buf; len, flags: Integer; addrto: PSockAddr;
tolen: Integer): Integer;
cdecl;
TSend = function(s: TSocket; const Buf; len, flags: Integer): Integer;
cdecl;
TRecv = function(s: TSocket; var Buf; len, flags: Integer): Integer;
cdecl;
TRecvFrom = function(s: TSocket; var Buf; len, flags: Integer; from: PSockAddr;
var fromlen: Integer): Integer;
cdecl;
Tntohs = function(netshort: u_short): u_short;
cdecl;
Tntohl = function(netlong: u_long): u_long;
cdecl;
TListen = function(s: TSocket; backlog: Integer): Integer;
cdecl;
TIoctlSocket = function(s: TSocket; cmd: DWORD; var arg: integer): Integer;
cdecl;
TInet_ntoa = function(inaddr: TInAddr): PChar;
cdecl;
TInet_addr = function(cp: PChar): u_long;
cdecl;
Thtons = function(hostshort: u_short): u_short;
cdecl;
Thtonl = function(hostlong: u_long): u_long;
cdecl;
TGetSockName = function(s: TSocket; name: PSockAddr; var namelen: Integer): Integer;
cdecl;
TGetPeerName = function(s: TSocket; name: PSockAddr; var namelen: Integer): Integer;
cdecl;
TConnect = function(s: TSocket; name: PSockAddr; namelen: Integer): Integer;
cdecl;
TCloseSocket = function(s: TSocket): Integer;
cdecl;
TBind = function(s: TSocket; addr: PSockAddr; namelen: Integer): Integer;
cdecl;
TAccept = function(s: TSocket; addr: PSockAddr; var addrlen: Integer): TSocket;
cdecl;
TTSocket = function(af, Struc, Protocol: Integer): TSocket;
cdecl;
TSelect = function(nfds: Integer; readfds, writefds, exceptfds: PFDSet;
timeout: PTimeVal): Longint;
cdecl;
TGetAddrInfo = function(NodeName: PChar; ServName: PChar; Hints: PAddrInfo;
var Addrinfo: PAddrInfo): integer;
cdecl;
TFreeAddrInfo = procedure(ai: PAddrInfo);
cdecl;
TGetNameInfo = function( addr: PSockAddr; namelen: Integer; host: PChar;
hostlen: DWORD; serv: PChar; servlen: DWORD; flags: integer): integer;
cdecl;
var
WSAStartup: TWSAStartup = nil;
WSACleanup: TWSACleanup = nil;
WSAGetLastError: TWSAGetLastError = nil;
GetServByName: TGetServByName = nil;
GetServByPort: TGetServByPort = nil;
GetProtoByName: TGetProtoByName = nil;
GetProtoByNumber: TGetProtoByNumber = nil;
GetHostByName: TGetHostByName = nil;
GetHostByAddr: TGetHostByAddr = nil;
ssGetHostName: TGetHostName = nil;
Shutdown: TShutdown = nil;
SetSockOpt: TSetSockOpt = nil;
GetSockOpt: TGetSockOpt = nil;
ssSendTo: TSendTo = nil;
ssSend: TSend = nil;
ssRecv: TRecv = nil;
ssRecvFrom: TRecvFrom = nil;
ntohs: Tntohs = nil;
ntohl: Tntohl = nil;
Listen: TListen = nil;
IoctlSocket: TIoctlSocket = nil;
Inet_ntoa: TInet_ntoa = nil;
Inet_addr: TInet_addr = nil;
htons: Thtons = nil;
htonl: Thtonl = nil;
ssGetSockName: TGetSockName = nil;
ssGetPeerName: TGetPeerName = nil;
ssConnect: TConnect = nil;
CloseSocket: TCloseSocket = nil;
ssBind: TBind = nil;
ssAccept: TAccept = nil;
Socket: TTSocket = nil;
Select: TSelect = nil;
GetAddrInfo: TGetAddrInfo = nil;
FreeAddrInfo: TFreeAddrInfo = nil;
GetNameInfo: TGetNameInfo = nil;
function LSWSAStartup(wVersionRequired: Word; var WSData: TWSAData): Integer; cdecl;
function LSWSACleanup: Integer; cdecl;
function LSWSAGetLastError: Integer; cdecl;
var
SynSockCS: SyncObjs.TCriticalSection;
SockEnhancedApi: Boolean;
SockWship6Api: Boolean;
type
TVarSin = packed record
case integer of
0: (AddressFamily: u_short);
1: (
case sin_family: u_short of
AF_INET: (sin_port: u_short;
sin_addr: TInAddr;
sin_zero: array[0..7] of Char);
AF_INET6: (sin6_port: u_short;
sin6_flowinfo: u_long;
sin6_addr: TInAddr6;
sin6_scope_id: u_long);
);
end;
function SizeOfVarSin(sin: TVarSin): integer;
function Bind(s: TSocket; const addr: TVarSin): Integer;
function Connect(s: TSocket; const name: TVarSin): Integer;
function GetSockName(s: TSocket; var name: TVarSin): Integer;
function GetPeerName(s: TSocket; var name: TVarSin): Integer;
function GetHostName: string;
function Send(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
function Recv(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
function SendTo(s: TSocket; Buf: TMemory; len, flags: Integer; addrto: TVarSin): Integer;
function RecvFrom(s: TSocket; Buf: TMemory; len, flags: Integer; var from: TVarSin): Integer;
function Accept(s: TSocket; var addr: TVarSin): TSocket;
function IsNewApi(Family: integer): Boolean;
function SetVarSin(var Sin: TVarSin; IP, Port: string; Family, SockProtocol, SockType: integer; PreferIP4: Boolean): integer;
function GetSinIP(Sin: TVarSin): string;
function GetSinPort(Sin: TVarSin): Integer;
procedure ResolveNameToIP(Name: string; Family, SockProtocol, SockType: integer; const IPList: TStrings);
function ResolveIPToName(IP: string; Family, SockProtocol, SockType: integer): string;
function ResolvePort(Port: string; Family, SockProtocol, SockType: integer): Word;
{==============================================================================}
implementation
var
SynSockCount: Integer = 0;
LibHandle: TLibHandle = 0;
Libwship6Handle: TLibHandle = 0;
function IN6_IS_ADDR_UNSPECIFIED(const a: PInAddr6): boolean;
begin
Result := ((a^.u6_addr32[0] = 0) and (a^.u6_addr32[1] = 0) and
(a^.u6_addr32[2] = 0) and (a^.u6_addr32[3] = 0));
end;
function IN6_IS_ADDR_LOOPBACK(const a: PInAddr6): boolean;
begin
Result := ((a^.u6_addr32[0] = 0) and (a^.u6_addr32[1] = 0) and
(a^.u6_addr32[2] = 0) and
(a^.u6_addr8[12] = 0) and (a^.u6_addr8[13] = 0) and
(a^.u6_addr8[14] = 0) and (a^.u6_addr8[15] = 1));
end;
function IN6_IS_ADDR_LINKLOCAL(const a: PInAddr6): boolean;
begin
Result := ((a^.u6_addr8[0] = $FE) and (a^.u6_addr8[1] = $80));
end;
function IN6_IS_ADDR_SITELOCAL(const a: PInAddr6): boolean;
begin
Result := ((a^.u6_addr8[0] = $FE) and (a^.u6_addr8[1] = $C0));
end;
function IN6_IS_ADDR_MULTICAST(const a: PInAddr6): boolean;
begin
Result := (a^.u6_addr8[0] = $FF);
end;
function IN6_ADDR_EQUAL(const a: PInAddr6; const b: PInAddr6): boolean;
begin
Result := (CompareMem( a, b, sizeof(TInAddr6)));
end;
procedure SET_IN6_IF_ADDR_ANY (const a: PInAddr6);
begin
FillChar(a^, sizeof(TInAddr6), 0);
end;
procedure SET_LOOPBACK_ADDR6 (const a: PInAddr6);
begin
FillChar(a^, sizeof(TInAddr6), 0);
a^.u6_addr8[15] := 1;
end;
{=============================================================================}
var
{$IFNDEF VER1_0} //FTP version 1.0.x
errno_loc: function: PInteger cdecl = nil;
{$ELSE}
errno_loc: function: PInteger = nil; cdecl;
{$ENDIF}
function LSWSAStartup(wVersionRequired: Word; var WSData: TWSAData): Integer;
begin
with WSData do
begin
wVersion := wVersionRequired;
wHighVersion := $202;
szDescription := 'Synsock - Synapse Platform Independent Socket Layer';
szSystemStatus := 'Running on Linux';
iMaxSockets := 32768;
iMaxUdpDg := 8192;
end;
Result := 0;
end;
function LSWSACleanup: Integer;
begin
Result := 0;
end;
function LSWSAGetLastError: Integer;
var
p: PInteger;
begin
p := errno_loc;
Result := p^;
end;
function __FDELT(Socket: TSocket): Integer;
begin
Result := Socket div __NFDBITS;
end;
function __FDMASK(Socket: TSocket): __fd_mask;
begin
Result := LongWord(1) shl (Socket mod __NFDBITS);
end;
function FD_ISSET(Socket: TSocket; var fdset: TFDSet): Boolean;
begin
Result := (fdset.fds_bits[__FDELT(Socket)] and __FDMASK(Socket)) <> 0;
end;
procedure FD_SET(Socket: TSocket; var fdset: TFDSet);
begin
fdset.fds_bits[__FDELT(Socket)] := fdset.fds_bits[__FDELT(Socket)] or __FDMASK(Socket);
end;
procedure FD_CLR(Socket: TSocket; var fdset: TFDSet);
begin
fdset.fds_bits[__FDELT(Socket)] := fdset.fds_bits[__FDELT(Socket)] and (not __FDMASK(Socket));
end;
procedure FD_ZERO(var fdset: TFDSet);
var
I: Integer;
begin
with fdset do
for I := Low(fds_bits) to High(fds_bits) do
fds_bits[I] := 0;
end;
{=============================================================================}
function SizeOfVarSin(sin: TVarSin): integer;
begin
case sin.sin_family of
AF_INET:
Result := SizeOf(TSockAddrIn);
AF_INET6:
Result := SizeOf(TSockAddrIn6);
else
Result := 0;
end;
end;
{=============================================================================}
function Bind(s: TSocket; const addr: TVarSin): Integer;
begin
Result := ssBind(s, @addr, SizeOfVarSin(addr));
end;
function Connect(s: TSocket; const name: TVarSin): Integer;
begin
Result := ssConnect(s, @name, SizeOfVarSin(name));
end;
function GetSockName(s: TSocket; var name: TVarSin): Integer;
var
len: integer;
begin
len := SizeOf(name);
FillChar(name, len, 0);
Result := ssGetSockName(s, @name, Len);
end;
function GetPeerName(s: TSocket; var name: TVarSin): Integer;
var
len: integer;
begin
len := SizeOf(name);
FillChar(name, len, 0);
Result := ssGetPeerName(s, @name, Len);
end;
function GetHostName: string;
var
s: string;
begin
Result := '';
setlength(s, 255);
ssGetHostName(pchar(s), Length(s) - 1);
Result := Pchar(s);
end;
function Send(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
begin
Result := ssSend(s, Buf^, len, flags);
end;
function Recv(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
begin
Result := ssRecv(s, Buf^, len, flags);
end;
function SendTo(s: TSocket; Buf: TMemory; len, flags: Integer; addrto: TVarSin): Integer;
begin
Result := ssSendTo(s, Buf^, len, flags, @addrto, SizeOfVarSin(addrto));
end;
function RecvFrom(s: TSocket; Buf: TMemory; len, flags: Integer; var from: TVarSin): Integer;
var
x: integer;
begin
x := SizeOf(from);
Result := ssRecvFrom(s, Buf^, len, flags, @from, x);
end;
function Accept(s: TSocket; var addr: TVarSin): TSocket;
var
x: integer;
begin
x := SizeOf(addr);
Result := ssAccept(s, @addr, x);
end;
{=============================================================================}
function IsNewApi(Family: integer): Boolean;
begin
Result := SockEnhancedApi;
if not Result then
Result := (Family = AF_INET6) and SockWship6Api;
end;
function SetVarSin(var Sin: TVarSin; IP, Port: string; Family, SockProtocol, SockType: integer; PreferIP4: Boolean): integer;
type
pu_long = ^u_long;
var
ProtoEnt: PProtoEnt;
ServEnt: PServEnt;
HostEnt: PHostEnt;
r: integer;
Hints1, Hints2: TAddrInfo;
Sin1, Sin2: TVarSin;
TwoPass: boolean;
function GetAddr(const IP, port: string; Hints: TAddrInfo; var Sin: TVarSin): integer;
var
Addr: PAddrInfo;
begin
Addr := nil;
try
FillChar(Sin, Sizeof(Sin), 0);
if Hints.ai_socktype = SOCK_RAW then
begin
Hints.ai_socktype := 0;
Hints.ai_protocol := 0;
Result := synsock.GetAddrInfo(PChar(IP), nil, @Hints, Addr);
end
else
begin
if (IP = cAnyHost) or (IP = c6AnyHost) then
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -