sockets.inc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. type thostaddr= packed array[1..4] of byte;
  11. function htonl( host : longint):longint; inline;
  12. begin
  13. {$ifdef FPC_BIG_ENDIAN}
  14. htonl:=host;
  15. {$else}
  16. htonl:=THostAddr(host)[4];
  17. htonl:=htonl or ( (THostAddr(host)[3]) shl 8);
  18. htonl:=htonl or ( (THostAddr(host)[2]) shl 16);
  19. htonl:=htonl or ( (THostAddr(host)[1]) shl 24);
  20. {$endif}
  21. end;
  22. Function NToHl (Net : Longint) : Longint; inline;
  23. begin
  24. {$ifdef FPC_BIG_ENDIAN}
  25. ntohl:=net;
  26. {$else}
  27. ntohl:=THostAddr(Net)[4];
  28. ntohl:=ntohl or ( (THostAddr(Net)[3]) shl 8);
  29. ntohl:=ntohl or ( (THostAddr(Net)[2]) shl 16);
  30. ntohl:=ntohl or ( (THostAddr(Net)[1]) shl 24);
  31. {$endif}
  32. end;
  33. function htons( host : word):word; inline;
  34. begin
  35. {$ifdef FPC_BIG_ENDIAN}
  36. htons:=host;
  37. {$else}
  38. htons:=swap(host);
  39. {$endif}
  40. end;
  41. Function NToHs (Net : word):word; inline;
  42. begin
  43. {$ifdef FPC_BIG_ENDIAN}
  44. ntohs:=net;
  45. {$else}
  46. ntohs:=swap(net);
  47. {$endif}
  48. end;
  49. Type array4int = array[1..4] of byte;
  50. function NetAddrToStr (Entry : in_addr) : AnsiString;
  51. Var Dummy : Ansistring;
  52. i,j : Longint;
  53. begin
  54. NetAddrToStr:='';
  55. j:=entry.s_addr;
  56. For I:=1 to 4 do
  57. begin
  58. Str(array4int(j)[i],Dummy);
  59. NetAddrToStr:=NetAddrToStr+Dummy;
  60. If I<4 Then
  61. NetAddrToStr:=NetAddrToStr+'.';
  62. end;
  63. end;
  64. function HostAddrToStr (Entry : in_addr) : AnsiString;
  65. Var x: in_addr;
  66. begin
  67. x.s_addr:=htonl(entry.s_addr);
  68. HostAddrToStr:=NetAddrToStr(x);
  69. end;
  70. function StrToHostAddr(IP : AnsiString) : in_addr ;
  71. Var
  72. Dummy : AnsiString;
  73. I,j,k : Longint;
  74. Temp : in_addr;
  75. begin
  76. strtohostaddr.s_addr:=0; //:=NoAddress;
  77. For I:=1 to 4 do
  78. begin
  79. If I<4 Then
  80. begin
  81. J:=Pos('.',IP);
  82. If J=0 then
  83. exit;
  84. Dummy:=Copy(IP,1,J-1);
  85. Delete (IP,1,J);
  86. end
  87. else
  88. Dummy:=IP;
  89. Val (Dummy,k,J);
  90. array4int(temp.s_addr)[i]:=k;
  91. If J<>0 then Exit;
  92. end;
  93. strtohostaddr.s_addr:=ntohl(Temp.s_addr);
  94. end;
  95. function StrToNetAddr(IP : AnsiString) : in_addr;
  96. begin
  97. StrToNetAddr.s_addr:=htonl(StrToHostAddr(IP).s_addr);
  98. end;
  99. Function HostToNet (Host : in_addr):in_addr;
  100. begin
  101. HostToNet.s_addr:=htonl(host.s_addr);
  102. end;
  103. Function NetToHost (Net : in_addr) : in_addr;
  104. begin
  105. NetToHost.s_addr:=ntohl(net.s_addr);
  106. end;
  107. Function HostToNet (Host : Longint) : Longint;
  108. begin
  109. HostToNet:=htonl(host);
  110. end;
  111. Function NetToHost (Net : Longint) : Longint;
  112. begin
  113. NetToHost:=ntohl(net);
  114. end;
  115. Function ShortHostToNet (Host : Word) : Word;
  116. begin
  117. ShortHostToNet:=htons(host);
  118. end;
  119. Function ShortNetToHost (Net : Word) : Word;
  120. begin
  121. ShortNEtToHost:=ntohs(net);
  122. end;
  123. const digittab : shortstring = ('0123456789ABCDEF');
  124. function lclinttohex (i:integer;digits:longint): ansistring;
  125. begin
  126. SetLength(lclinttohex,4);
  127. lclinttohex[4]:=digittab[1+(i and 15)];
  128. lclinttohex[3]:=digittab[1+((i shr 4) and 15)];
  129. lclinttohex[2]:=digittab[1+((i shr 8) and 15)];
  130. lclinttohex[1]:=digittab[1+((i shr 12) and 15)];;
  131. end;
  132. function HostAddrToStr6 (Entry : TIn6_Addr) :ansiString;
  133. var
  134. i: byte;
  135. zr1,zr2: set of byte;
  136. zc1,zc2: byte;
  137. have_skipped: boolean;
  138. begin
  139. zr1 := [];
  140. zr2 := [];
  141. zc1 := 0;
  142. zc2 := 0;
  143. for i := 0 to 7 do begin
  144. if Entry.u6_addr16[i] = 0 then begin
  145. include(zr2, i);
  146. inc(zc2);
  147. end else begin
  148. if zc1 < zc2 then begin
  149. zc1 := zc2;
  150. zr1 := zr2;
  151. zc2 := 0; zr2 := [];
  152. end;
  153. end;
  154. end;
  155. if zc1 < zc2 then begin
  156. zc1 := zc2;
  157. zr1 := zr2;
  158. end;
  159. SetLength(HostAddrToStr6, 8*5-1);
  160. SetLength(HostAddrToStr6, 0);
  161. have_skipped := false;
  162. for i := 0 to 7 do begin
  163. if not (i in zr1) then begin
  164. if have_skipped then begin
  165. if HostAddrToStr6 = ''
  166. then HostAddrToStr6 := '::'
  167. else HostAddrToStr6 := HostAddrToStr6 + ':';
  168. have_skipped := false;
  169. end;
  170. // FIXME: is that shortnettohost really proper there? I wouldn't be too sure...
  171. HostAddrToStr6 := HostAddrToStr6 +lclIntToHex(ShortNetToHost(Entry.u6_addr16[i]), 1) + ':';
  172. end else begin
  173. have_skipped := true;
  174. end;
  175. end;
  176. if have_skipped then
  177. if HostAddrToStr6 = ''
  178. then HostAddrToStr6 := '::'
  179. else HostAddrToStr6 := HostAddrToStr6 + ':';
  180. if HostAddrToStr6 = '' then HostAddrToStr6 := '::';
  181. if not (7 in zr1) then
  182. SetLength(HostAddrToStr6, Length(HostAddrToStr6)-1);
  183. end;
  184. function StrToHostAddr6(IP : String) : TIn6_addr;
  185. Var Part : String;
  186. IPv6 : TIn6_addr;
  187. P,J : Integer;
  188. W : Word;
  189. Index : Integer;
  190. ZeroAt : Integer;
  191. Begin
  192. FillChar(IPv6,SizeOf(IPv6),0);
  193. { Every 16-bit block is converted at its own and stored into Result. When }
  194. { the '::' zero-spacer is found, its location is stored. Afterwards the }
  195. { address is shifted and zero-filled. }
  196. Index := 0; ZeroAt := -1;
  197. J := 0;
  198. P := Pos(':',IP);
  199. While (P > 0) and (Length(IP) > 0) and (Index < 8) do
  200. Begin
  201. Part := '$'+Copy(IP,1,P-1);
  202. Delete(IP,1,P);
  203. if Length(Part) > 1 then { is there a digit after the '$'? }
  204. Val(Part,W,J)
  205. else W := 0;
  206. IPv6.u6_addr16[Index] := HtoNS(W);
  207. if J <> 0 then
  208. Begin
  209. FillChar(IPv6,SizeOf(IPv6),0);
  210. Exit;
  211. End;
  212. if IP[1] = ':' then
  213. Begin
  214. ZeroAt := Index;
  215. Delete(IP,1,1);
  216. End;
  217. Inc(Index);
  218. P := Pos(':',IP); if P = 0 then P := Length(IP)+1;
  219. End;
  220. { address a:b:c::f:g:h }
  221. { Result now a : b : c : f : g : h : 0 : 0, ZeroAt = 2, Index = 6 }
  222. { Result after a : b : c : 0 : 0 : f : g : h }
  223. if ZeroAt >= 0 then
  224. Begin
  225. Move(IPv6.u6_addr16[ZeroAt+1],IPv6.u6_addr16[(8-Index)+ZeroAt+1],2*(Index-ZeroAt-1));
  226. FillChar(IPv6.u6_addr16[ZeroAt+1],2*(8-Index),0);
  227. End;
  228. StrToHostAddr6:=IPv6;
  229. End;
  230. function NetAddrToStr6 (Entry : TIn6_Addr) : ansiString;
  231. begin
  232. netaddrtostr6 := HostAddrToStr6((Entry));
  233. end;
  234. function StrToNetAddr6(IP : ansiString) : TIn6_Addr;
  235. begin
  236. StrToNetAddr6 := StrToHostAddr6(IP);
  237. end;