8 {Redefine socaddr here, becouse original is too short for ipv6 and unix}
9 type tSockAddrL
= packed record
10 sa_family
: sa_family_t
;
11 sa_data
: array [0..107] of byte;
13 type tSockAddr
= type tSockAddrL deprecated
;
17 tFamily
=(afNil
=0, afInet
=1, afInet6
);
19 { Network-byte-ordered words }
20 Word2
=array [1..2] of byte; {0..65535}
21 Word4
=array [1..4] of byte; {0..4294967295}
23 { Object to store Socket Address }
26 function Length
:word;
27 { Returns length of the structure based on address family }
29 procedure ToSocket( var sockaddr
:tSockAddrL
);
30 {$HINT Not actually testet, byt seems to work}
31 procedure FromSocket( var sockaddr
:tSockAddrL
);
32 {$HINT Not actually testet, byt seems to work}
34 procedure ToString( var str
:String );
35 {$HINT Not actually testet, byt seems to work}
36 procedure FromString( str
:String );
37 {$HINT Not actually testet, byt seems to work}
40 procedure LocalHost( af
: tFamily
);
41 {Generate localhost address of address family af.}
42 {$HINT Not actually testet, byt seems to work}
45 function isNil
:boolean;
49 case Family
: tFamily
of
50 { note: maximum family is 32 so byte is enough }
51 afInet
:( inet
:packed record
55 afInet6
:( inet6
:packed record
60 pad_pV4IlkA4mKQL
:packed array [0..128] of byte;
67 function ConvertFamily( a
:tFamily
): sa_family_t
;
69 operator
:= (net
: Word2
) host
:word;
70 operator
:= (net
: Word4
) host
:Dword
;
71 operator
:= (host
: word) net
:Word2
;
72 operator
:= (host
: Dword
) net
:Word4
;
74 Operator
= (aa
, ab
:t
) b
: boolean;
76 operator
:= ( at
: t
) aString
: string;
77 operator
:= ( aString
: string) at
: t
;
80 Operator := (aa :t ) r : pSockAddr;
81 Operator := ( aa :pSockAddr ) r : t;
86 Operator
= (aa
, ab
:Sockets
.tInAddr
) b
: boolean;
88 b
:=aa
.s_addr
=ab
.s_addr
;
91 Operator
= (aa
, ab
:t
) b
: boolean;
94 if aa
.data
.Family
<>ab
.data
.Family
then exit
;
95 case aa
.data
.Family
of
96 afInet
: if (aa
.data
.inet
.port
<>ab
.data
.inet
.port
) or (aa
.data
.inet
.addr
<>ab
.data
.inet
.addr
) then exit
;
97 afNil
: {null addresses are always equal};
103 function t
.Length
:Word;
105 result
:=(sizeof(self
)-sizeof(data
))+sizeof(data
.Family
);
108 afInet
: result
+=sizeof( data
.inet
);
109 afInet6
: result
+=sizeof( data
.inet6
);
110 else result
:=sizeof(self
);
114 function ConvertFamily( a
:tFamily
): sa_family_t
;
117 afInet
: result
:=Sockets
.AF_INET
;
118 afInet6
: result
:=Sockets
.AF_INET6
;
123 procedure t
.ToSocket( var sockaddr
:tSockAddrL
);
127 sockaddr
.sa_family
:=Sockets
.AF_INET
;
128 Move(data
.inet
, sockaddr
.sa_data
, sizeof(data
.inet
) );
131 sockaddr
.sa_family
:=Sockets
.AF_INET6
;
132 with tInetSockAddr6(pointer(@sockaddr
)^) do begin
133 sin6_port
:=data
.inet6
.port
;
135 sin6_addr
:=data
.inet6
.addr
;
143 procedure t
.FromSocket( var sockaddr
:tSockAddrL
);
145 case sockaddr
.sa_family
of
146 Sockets
.AF_INET
: begin
148 move(sockaddr
.sa_data
, data
.inet
, sizeof(data
.inet
) );
150 Sockets
.AF_INET6
: begin
151 data
.family
:=afInet6
;
152 move(sockaddr
.sa_data
, data
.inet6
, sizeof(data
.inet6
) );
154 else raise Exception
.Create('Unknown AF '+IntToStr(sockaddr
.sa_family
));
160 procedure t
.ToString( var str
:String );
164 str
:='//ip4/'+Sockets
.NetAddrToStr(data
.inet
.addr
)+
165 '/'+IntToStr(ShortNetToHost(data
.inet
.port
));
168 str
:='//ip6/'+Sockets
.NetAddrToStr6(data
.inet6
.addr
)+
169 '/'+IntToStr(ShortNetToHost(data
.inet6
.port
));
172 else str
:='//nil/UnknownAddressFamily';
176 procedure t
.FromString( str
:String );
180 if System
.Length(str
)=0 then begin Clear
; exit
end;
181 if Copy(str
,1,2)<>'//' then raise eConvertError
.Create('');
183 i
:=pos('/',str
); if i
=0 then i
:=System
.Length(str
)+1;
184 fam
:=copy(str
,1,i
-1);
186 if fam
='ip4' then begin
189 i
:=pos('/',str
); if i
=0 then i
:=System
.Length(str
)+1;
190 fam
:=copy(str
,1,i
-1);
192 data
.inet
.addr
:=StrToNetAddr(fam
);
194 i
:=pos('/',str
); if i
=0 then i
:=System
.Length(str
)+1;
195 fam
:=copy(str
,1,i
-1);
197 data
.inet
.port
:=ShortHostToNet(StrToInt(fam
));
199 end else if fam
='ip6' then begin
200 data
.family
:=afInet6
;
202 i
:=pos('/',str
); if i
=0 then i
:=System
.Length(str
)+1;
203 fam
:=copy(str
,1,i
-1);
205 data
.inet6
.addr
:=StrToNetAddr6(fam
);
207 i
:=pos('/',str
); if i
=0 then i
:=System
.Length(str
)+1;
208 fam
:=copy(str
,1,i
-1);
210 data
.inet6
.port
:=ShortHostToNet(StrToInt(fam
));
212 end else if fam
='nil' then begin
214 end else raise eConvertError
.Create('');
217 function t
.Hash
:word;
220 procedure hashstep(v
:byte);
222 h
:=((h
shl 5)and $FFFF) xor ((h
shr 2)and $FFFF) xor v
;
226 assert(sizeof(data
.family
)=1,'simple set size'+IntToStr(sizeof(data
.family
)));
227 hashstep(byte(data
.family
));
229 afInet
: for i
:=1 to 4 do HashStep(data
.inet
.addr
.s_bytes
[i
]);
230 afInet6
: for i
:=1 to 16 do HashStep(data
.inet6
.addr
.u6_addr8
[i
]);
234 afInet
,afInet6
: begin
235 HashStep(data
.inet
.port
and $FF);
236 HashStep((data
.inet
.port
shr 8) and $FF);
242 const cLocalHostIP4
:Sockets
.tInAddr
=( s_bytes
:(127,0,0,1) );
243 const cLocalIP4Port
:word=1030;
245 procedure t
.LocalHost( af
: tFamily
);
250 data
.inet
.port
:=ShortHostToNet(cLocalIP4Port
);
251 data
.inet
.addr
:=cLocalHostIP4
;
260 self
.data
.family
:=afNil
;
263 function t
.isNil
:boolean;
265 isNil
:= self
.data
.family
=afNil
;
268 operator
:= ( at
: t
) aString
: string;
270 at
.ToString( aString
);
272 operator
:= ( aString
: string) at
: t
;
274 at
.FromString( aString
);
277 operator
:= (net
: Word2
) host
:word;
281 host
:=ShortNetToHost( pnet
^ );
283 operator
:= (net
: Word4
) host
:Dword
;
287 host
:=LEtoN( pnet
^ );
290 operator
:= (host
: word) net
:Word2
;
294 pnet
^:= ShortHostToNet( host
);
296 operator
:= (host
: Dword
) net
:Word4
;
300 pnet
^:=NtoLE( host
);