Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
5.4 KiB

  1. ##
  2. ## Jeffrey Friedl ([email protected])
  3. ## Copyri.... ah hell, just take it.
  4. ##
  5. ## July 1994
  6. ##
  7. package network;
  8. $version = "950311.5";
  9. ## version 950311.5 -- turned off warnings when requiring 'socket.ph';
  10. ## version 941028.4 -- some changes to quiet perl5 warnings.
  11. ## version 940826.3 -- added check for "socket.ph", and alternate use of
  12. ## socket STREAM value for SunOS5.x
  13. ##
  14. ## BLURB:
  15. ## A few simple and easy-to-use routines to make internet connections.
  16. ## Similar to "chat2.pl" (but actually commented, and a bit more portable).
  17. ## Should work even on SunOS5.x.
  18. ##
  19. ##>
  20. ##
  21. ## connect_to() -- make an internet connection to a server.
  22. ##
  23. ## Two uses:
  24. ## $error = &network'connect_to(*FILEHANDLE, $fromsockaddr, $tosockaddr)
  25. ## $error = &network'connect_to(*FILEHANDLE, $hostname, $portnum)
  26. ##
  27. ## Makes the given connection and returns an error string, or undef if
  28. ## no error.
  29. ##
  30. ## In the first form, FROMSOCKADDR and TOSOCKADDR are of the form returned
  31. ## by SOCKET'GET_ADDR and SOCKET'MY_ADDR.
  32. ##
  33. ##<
  34. sub connect_to
  35. {
  36. local(*FD, $arg1, $arg2) = @_;
  37. local($from, $to) = ($arg1, $arg2); ## for one interpretation.
  38. local($host, $port) = ($arg1, $arg2); ## for the other
  39. if (defined($to) && length($from)==16 && length($to)==16) {
  40. ## ok just as is
  41. } elsif (defined($host)) {
  42. $to = &get_addr($host, $port);
  43. return qq/unknown address "$host"/ unless defined $to;
  44. $from = &my_addr;
  45. } else {
  46. return "unknown arguments to network'connect_to";
  47. }
  48. return "connect_to failed (socket: $!)" unless &my_inet_socket(*FD);
  49. return "connect_to failed (bind: $!)" unless bind(FD, $from);
  50. return "connect_to failed (connect: $!)" unless connect(FD, $to);
  51. local($old) = select(FD); $| = 1; select($old);
  52. undef;
  53. }
  54. ##>
  55. ##
  56. ## listen_at() - used by a server to indicate that it will accept requests
  57. ## at the port number given.
  58. ##
  59. ## Used as
  60. ## $error = &network'listen_at(*LISTEN, $portnumber);
  61. ## (returns undef upon success)
  62. ##
  63. ## You can then do something like
  64. ## $addr = accept(REMOTE, LISTEN);
  65. ## print "contact from ", &network'addr_to_ascii($addr), ".\n";
  66. ## while (<REMOTE>) {
  67. ## .... process request....
  68. ## }
  69. ## close(REMOTE);
  70. ##
  71. ##<
  72. sub listen_at
  73. {
  74. local(*FD, $port) = @_;
  75. local($empty) = pack('S n a4 x8', 2 ,$port, "\0\0\0\0");
  76. return "listen_for failed (socket: $!)" unless &my_inet_socket(*FD);
  77. return "listen_for failed (bind: $!)" unless bind(FD, $empty);
  78. return "listen_for failed (listen: $!)" unless listen(FD, 5);
  79. local($old) = select(FD); $| = 1; select($old);
  80. undef;
  81. }
  82. ##>
  83. ##
  84. ## Given an internal packed internet address (as returned by &connect_to
  85. ## or &get_addr), return a printable ``1.2.3.4'' version.
  86. ##
  87. ##<
  88. sub addr_to_ascii
  89. {
  90. local($addr) = @_;
  91. return "bad arg" if length $addr != 16;
  92. return join('.', unpack("CCCC", (unpack('S n a4 x8', $addr))[2]));
  93. }
  94. ##
  95. ##
  96. ## Given a host and a port name, returns the packed socket addresss.
  97. ## Mostly for internal use.
  98. ##
  99. ##
  100. sub get_addr
  101. {
  102. local($host, $port) = @_;
  103. return $addr{$host,$port} if defined $addr{$host,$port};
  104. local($addr);
  105. if ($host =~ m/^\d+\.\d+\.\d+\.\d+$/)
  106. {
  107. $addr = pack("C4", split(/\./, $host));
  108. }
  109. elsif ($addr = (gethostbyname($host))[4], !defined $addr)
  110. {
  111. local(@lookup) = `nslookup $host 2>&1`;
  112. if (@lookup)
  113. {
  114. local($lookup) = join('', @lookup[2 .. $#lookup]);
  115. if ($lookup =~ m/^Address:\s*(\d+\.\d+\.\d+\.\d+)/) {
  116. $addr = pack("C4", split(/\./, $1));
  117. }
  118. }
  119. if (!defined $addr) {
  120. ## warn "$host: SOL, dude\n";
  121. return undef;
  122. }
  123. }
  124. $addr{$host,$port} = pack('S n a4 x8', 2 ,$port, $addr);
  125. }
  126. ##
  127. ## my_addr()
  128. ## Returns the packed socket address of the local host (port 0)
  129. ## Mostly for internal use.
  130. ##
  131. ##
  132. sub my_addr
  133. {
  134. local(@x) = gethostbyname('localhost');
  135. local(@y) = gethostbyname($x[0]);
  136. # local($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($x[0]);
  137. # local(@bytes) = unpack("C4",$addrs[0]);
  138. # return pack('S n a4 x8', 2 ,0, $addr);
  139. return pack('S n a4 x8', 2 ,0, $y[4]);
  140. }
  141. ##
  142. ## my_inet_socket(*FD);
  143. ##
  144. ## Local routine to do socket(PF_INET, SOCK_STREAM, AF_NS).
  145. ## Takes care of figuring out the proper values for the args. Hopefully.
  146. ##
  147. ## Returns the same value as 'socket'.
  148. ##
  149. sub my_inet_socket
  150. {
  151. local(*FD) = @_;
  152. local($socket);
  153. if (!defined $socket_values_queried)
  154. {
  155. ## try to load some "socket.ph"
  156. if (!defined &main'_SYS_SOCKET_H_) {
  157. eval 'package main;
  158. local($^W) = 0;
  159. require("sys/socket.ph")||require("socket.ph");';
  160. }
  161. ## we'll use "the regular defaults" if for PF_INET and AF_NS if unknown
  162. $PF_INET = defined &main'PF_INET ? &main'PF_INET : 2;
  163. $AF_NS = defined &main'AF_NS ? &main'AF_NS : 6;
  164. $SOCK_STREAM = &main'SOCK_STREAM if defined &main'SOCK_STREAM;
  165. $socket_values_queried = 1;
  166. }
  167. if (defined $SOCK_STREAM) {
  168. $socket = socket(FD, $PF_INET, $SOCK_STREAM, $AF_NS);
  169. } else {
  170. ##
  171. ## We'll try the "regular default" of 1. If that returns a
  172. ## "not supported" error, we'll try 2, which SunOS5.x uses.
  173. ##
  174. $socket = socket(FD, $PF_INET, 1, $AF_NS);
  175. if ($socket) {
  176. $SOCK_STREAM = 1; ## got it.
  177. } elsif ($! =~ m/not supported/i) {
  178. ## we'll just assume from now on that it's 2.
  179. $socket = socket(FD, $PF_INET, $SOCK_STREAM = 2, $AF_NS);
  180. }
  181. }
  182. $socket;
  183. }
  184. ## This here just to quiet -w warnings.
  185. sub dummy {
  186. 1 || $version || &dummy;
  187. }
  188. 1;
  189. __END__