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..22] 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
));
158 procedure t
.ToString( var str
:String );
162 str
:='//ip4/'+Sockets
.NetAddrToStr(data
.inet
.addr
)+
163 '/'+IntToStr(ShortNetToHost(data
.inet
.port
));
166 str
:='//ip6/'+Sockets
.NetAddrToStr6(data
.inet6
.addr
)+
167 '/'+IntToStr(ShortNetToHost(data
.inet6
.port
));
170 else str
:='//nil/UnknownAddressFamily';
174 procedure t
.FromString( str
:String );
178 if System
.Length(str
)=0 then begin Clear
; exit
end;
179 if Copy(str
,1,2)<>'//' then raise eConvertError
.Create('');
181 i
:=pos('/',str
); if i
=0 then i
:=System
.Length(str
)+1;
182 fam
:=copy(str
,1,i
-1);
184 if fam
='ip4' then begin
187 i
:=pos('/',str
); if i
=0 then i
:=System
.Length(str
)+1;
188 fam
:=copy(str
,1,i
-1);
190 data
.inet
.addr
:=StrToNetAddr(fam
);
192 i
:=pos('/',str
); if i
=0 then i
:=System
.Length(str
)+1;
193 fam
:=copy(str
,1,i
-1);
195 data
.inet
.port
:=ShortHostToNet(StrToInt(fam
));
197 end else if fam
='ip6' then begin
198 data
.family
:=afInet6
;
200 i
:=pos('/',str
); if i
=0 then i
:=System
.Length(str
)+1;
201 fam
:=copy(str
,1,i
-1);
203 data
.inet6
.addr
:=StrToNetAddr6(fam
);
205 i
:=pos('/',str
); if i
=0 then i
:=System
.Length(str
)+1;
206 fam
:=copy(str
,1,i
-1);
208 data
.inet6
.port
:=ShortHostToNet(StrToInt(fam
));
210 end else if fam
='nil' then begin
212 end else raise eConvertError
.Create('');
215 function t
.Hash
:word;
218 procedure hashstep(v
:byte);
220 h
:=((h
shl 5)and $FFFF) xor ((h
shr 2)and $FFFF) xor v
;
224 assert(sizeof(data
.family
)=1,'simple set size'+IntToStr(sizeof(data
.family
)));
225 hashstep(byte(data
.family
));
227 afInet
: for i
:=1 to 4 do HashStep(data
.inet
.addr
.s_bytes
[i
]);
228 afInet6
: for i
:=1 to 16 do HashStep(data
.inet6
.addr
.u6_addr8
[i
]);
232 afInet
,afInet6
: begin
233 HashStep(data
.inet
.port
and $FF);
234 HashStep((data
.inet
.port
shr 8) and $FF);
240 const cLocalHostIP4
:Sockets
.tInAddr
=( s_bytes
:(127,0,0,1) );
241 const cLocalIP4Port
:word=1030;
243 procedure t
.LocalHost( af
: tFamily
);
248 data
.inet
.port
:=ShortHostToNet(cLocalIP4Port
);
249 data
.inet
.addr
:=cLocalHostIP4
;
258 self
.data
.family
:=afNil
;
261 function t
.isNil
:boolean;
263 isNil
:= self
.data
.family
=afNil
;
266 operator
:= ( at
: t
) aString
: string;
268 at
.ToString( aString
);
270 operator
:= ( aString
: string) at
: t
;
272 at
.FromString( aString
);
275 operator
:= (net
: Word2
) host
:word;
279 host
:=ShortNetToHost( pnet
^ );
281 operator
:= (net
: Word4
) host
:Dword
;
285 host
:=LEtoN( pnet
^ );
288 operator
:= (host
: word) net
:Word2
;
292 pnet
^:= ShortHostToNet( host
);
294 operator
:= (host
: Dword
) net
:Word4
;
298 pnet
^:=NtoLE( host
);