home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / OWLSRC.PAK / WSKADDR.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  9.6 KB  |  333 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1995, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.16  $
  6. //
  7. // Winsock for OWL subsystem.
  8. // Based on work by Paul Pedriana, 70541.3223@compuserve.com
  9. //----------------------------------------------------------------------------
  10. #include <owl/pch.h>
  11. #if !defined(OWL_WINSOCK_H)
  12. # include <owl/winsock.h>
  13. #endif
  14.  
  15. OWL_DIAGINFO;
  16.  
  17. //
  18. // Only the family is specified.  The rest of the data will currently be
  19. // undefined.
  20. //
  21. TSocketAddress::TSocketAddress()
  22. {
  23.   sa_family = AF_UNSPEC;
  24. }
  25.  
  26. //
  27. // The argument is a sockaddr in network byte ordering.
  28. //
  29. TSocketAddress::TSocketAddress(const sockaddr& src)
  30. {
  31.   operator =(src);
  32. }
  33.  
  34. //
  35. // The argument address should be in network byte ordering.
  36. //
  37. TSocketAddress::TSocketAddress(const TSocketAddress& src)
  38. {
  39.   operator =(src);
  40. }
  41.  
  42. //
  43. // The argument address should be in network byte ordering.
  44. //
  45. TSocketAddress::TSocketAddress(ushort newFamily, char* data, short dataLength)
  46. {
  47.   SetAddress(newFamily, data, dataLength);
  48. }
  49.  
  50. //
  51. // The argument address should be in network byte ordering.
  52. //
  53. TSocketAddress& TSocketAddress::operator =(const sockaddr& src)
  54. {
  55.   SetAddress(src.sa_family, src.sa_data, 14);
  56.   return *this;
  57. }
  58.  
  59. //
  60. // Both addresses should be in the same byte ordering as each other.
  61. // We just happen to know for a fact that the sockaddr's have same data as
  62. // TSocketAddress's.
  63. //
  64. bool operator ==(const TSocketAddress& address1, const TSocketAddress& address2)
  65. {
  66.   if (address1.sa_family != address2.sa_family)
  67.     return false;
  68.  
  69.   for (int i = 0; i < 14; i++) {
  70.     if (address1.sa_data[i] != address2.sa_data[i])
  71.       return false;
  72.   }
  73.   return true;
  74. }
  75.  
  76. //
  77. // 'newFamily' is AF_INET, etc.  'data' is a pointer to data in the same
  78. // format as sockaddr.sa_data[].  'dataLength' is the length of data.  It is
  79. // limited to 14 bytes in WinSock 1.1.  The passed data should be in network
  80. // byte ordering.
  81. //
  82. void TSocketAddress::SetAddress(ushort family, const char* data, short dataLength)
  83. {
  84.   sa_family = family;
  85.   for (int i = 0; i < dataLength && i < 14; i++)
  86.     sa_data[i] = data[i];
  87. }
  88.  
  89. //----------------------------------------------------------------------------
  90.  
  91. //
  92. // Empty constructor.  Useful for creating an TInetSocketAddress, but delaying
  93. // the actual assignment of addressing data until later.
  94. //
  95. TINetSocketAddress::TINetSocketAddress()
  96. :
  97.   TSocketAddress()
  98. {
  99.   SetAddress(AF_INET, 0, INADDR_ANY);  // default values.  Can be changed later.
  100. }
  101.  
  102. //
  103. // The argument should be in network byte ordering
  104. //
  105. TINetSocketAddress::TINetSocketAddress(const sockaddr& src)
  106. :
  107.   TSocketAddress(src)
  108. {
  109. }
  110.  
  111. //
  112. // All arguments should be in network byte ordering. newFamily is an
  113. // enumeration, so there is no specific byte ordering.  Note that address can
  114. // also be INADDR_ANY, INADDR_LOOPBACK, INADDR_BROADCAST, INADDR_NONE.  Also
  115. // note that in winsock.h (1.1), Microsoft defines these addresses in network
  116. // byte ordering format, so you don't need to convert to network byte ordering
  117. // upon passing to this function or any other that expects network byte
  118. // ordering.
  119. //
  120. TINetSocketAddress::TINetSocketAddress(ushort newPort, ulong newAddress, ushort newFamily)
  121. {
  122.   SetAddress(newFamily, newPort, newAddress);
  123. }
  124.  
  125. //
  126. // newPort should be passed in network byte ordering.  newAddress is in the
  127. // format of numerical IP addressing (e.g. "132.212.43.1").  It cannot be in
  128. // the form of "user@place" nFamily is in the form of AF_INET, etc.
  129. //
  130. TINetSocketAddress::TINetSocketAddress(ushort newPort, const char* newAddressStr, ushort newFamily)
  131. {
  132.   ulong newAddress = ConvertAddress(newAddressStr);
  133.   SetAddress(newFamily, newPort, newAddress);
  134. }
  135.  
  136. // 
  137. // Obsolete version of previous constructor included for backward
  138. // compatibility (doesn't use const)
  139. // 
  140.  
  141. TINetSocketAddress::TINetSocketAddress(ushort newPort, char* newAddressStr, ushort newFamily)
  142. {
  143.   ulong newAddress = ConvertAddress(newAddressStr);
  144.   SetAddress(newFamily, newPort, newAddress);
  145. }
  146.  
  147. //
  148. // The argument should be in the same byte ordering (network) as this object.
  149. //
  150. TINetSocketAddress& TINetSocketAddress::operator =(const sockaddr& newSockaddr)
  151. {
  152.   TSocketAddress::SetAddress(newSockaddr.sa_family, newSockaddr.sa_data, 14);
  153.   return *this;
  154. }
  155.  
  156. //
  157. // This function accepts a string in the form of e.g. 162.132.211.204" and
  158. // converts it to an IP address (ulong) if possible.  The returned value will
  159. // be in network byte ordering. It should be INADDR_NONE if there was an error.
  160. //
  161. ulong TINetSocketAddress::ConvertAddress(const char far* address)
  162. {
  163.   return TWinSockDll::inet_addr(address);
  164. }
  165.  
  166. //
  167. // This function accepts a ulong in the form of an IP binary address and
  168. // converts it to an character string IP address (e.g.  "123.213.132.122") if
  169. // possible.  The lAddress parameter must be given in network byte ordering to
  170. // work properly.  Note that this function returns a character pointer to a
  171. // string allocated by the system.  It is imperative that the caller
  172. // immediately copy this data, and neither modify it nor de-allocate it, etc.
  173. // This restriction is imposed by Winsock.
  174. //
  175. char far* TINetSocketAddress::ConvertAddress(ulong address)
  176. {
  177.   in_addr   tempAddress;
  178.   char far* addressStr;
  179.  
  180.   tempAddress.s_addr = address;
  181.   addressStr = TWinSockDll::inet_ntoa(tempAddress);
  182.   return addressStr;
  183. }
  184.  
  185. //
  186. // This function can be used to tell if a character string points to an
  187. // address in dotted-decimal IP format (e.g. "162.132.211.204") or in name
  188. // format (e.g.  "jimmy_carter@wh.com").  You could call this function if the
  189. // user typed in a destination address in one of either of the above formats,
  190. // and you need to know which one it is, so you can know how to convert it to
  191. // a ulong IP address.  If the address is dotted-decimal, then you can simpoy
  192. // use the TINetSocketAddress::ConvertAddress() function.  Otherwise, you need
  193. // to use one ofthe HostInfoManager functions.  The szAddress is a pointer to
  194. // a string that can be in any format, but most likely, one of either the
  195. // dotted-decimal or the name formats mentioned above.  This function's job is
  196. // only to tell you if it is in dotted-decimal format or not.  The return
  197. // value is 1 if in dotted-decimal format, and 0 if not.
  198. //
  199. #pragma warn -cln
  200. short TINetSocketAddress::IsAddressDottedDecimal(const char far* addressStr)
  201. {
  202.   ulong returnValue = TWinSockDll::inet_addr(addressStr);
  203.   if (returnValue == INADDR_NONE)
  204.     return 0;
  205.   return 1;
  206. }
  207. #pragma warn .cln
  208.  
  209. //
  210. // This function makes an address out of the necessary IP address components.
  211. // newFamily is an enumeration, e.g. AF_INET.
  212. // newPort is in network byte ordering, as is lNewAddress.
  213. //
  214. void TINetSocketAddress::SetAddress(ushort newFamily, ushort newPort,
  215.                                     ulong newAddress)
  216. {
  217.   SetFamily(newFamily);
  218.   SetPort(newPort);
  219.   SetNetworkAddress(newAddress);
  220.   SetFiller();
  221. }
  222.  
  223. //
  224. // Returns port in network byte ordering
  225. //
  226. ushort TINetSocketAddress::GetPort() const
  227. {
  228.   return ((sockaddr_in*)this)->sin_port;
  229. }
  230.  
  231. //
  232. // Returns IP binary address in network byte ordering
  233. //
  234. ulong TINetSocketAddress::GetNetworkAddress() const
  235. {
  236.   return ((sockaddr_in*)this)->sin_addr.s_addr;
  237. }
  238.  
  239. //
  240. // This function returns 0 if the network cannot be determined.
  241. //
  242. #pragma warn -cln
  243. ulong TINetSocketAddress::GetNetwork() const
  244. {
  245.   TINetClass theINetClass = GetClass();
  246.  
  247.   ulong    subnetMask;
  248.   if (theINetClass == ClassA)
  249.     subnetMask = IN_CLASSA_NET;  //0xFF000000L;
  250.   else if (theINetClass == ClassB)
  251.     subnetMask = IN_CLASSB_NET; //0xFFFF0000L;
  252.   else if (theINetClass == ClassC)
  253.     subnetMask = IN_CLASSC_NET; //0xFFFFFF00L;
  254.   else // ClassUnknown
  255.     return 0;
  256.  
  257.   return GetNetwork(subnetMask);
  258. }
  259. #pragma warn .cln
  260.  
  261. //
  262. // Return network address with subnet masked out
  263. //
  264. ulong TINetSocketAddress::GetNode() const
  265. {
  266.   TINetClass theINetClass = GetClass();
  267.  
  268.   ulong    subnetMask;
  269.   if (theINetClass == ClassA)
  270.     subnetMask = 0xFF000000L;
  271.   else if (theINetClass == ClassB)
  272.     subnetMask = 0xFFFF0000L;
  273.   else if (theINetClass == ClassC)
  274.     subnetMask = 0xFFFFFF00L;
  275.   else //ClassUnknown
  276.     return 0;
  277.  
  278.   return GetNode(subnetMask);
  279. }
  280.  
  281. //
  282. // Sets the port.
  283. // This function expects the argument to be in network byte ordering.
  284. //
  285. void TINetSocketAddress::SetPort(ushort port)
  286. {
  287.   ((sockaddr_in*)this)->sin_port = port;
  288. }
  289.  
  290. //
  291. // Sets the network address.
  292. // This function expects the argument to be in network byte ordering.
  293. //
  294. void TINetSocketAddress::SetNetworkAddress(ulong address)
  295. {
  296.    ((sockaddr_in*)this)->sin_addr.s_addr = address;
  297. }
  298.  
  299. //
  300. // Sets the network address.
  301. //
  302. void TINetSocketAddress::SetNetworkAddress(const char* addressDottedDecimal)
  303. {
  304.    SetNetworkAddress(ConvertAddress(addressDottedDecimal));
  305. }
  306.  
  307. //
  308. // This is an internal function.  It is merely used to zero out the unused
  309. //  data of the address.
  310. //
  311. void TINetSocketAddress::SetFiller()
  312. {
  313.   for (int i = 0; i < 8; i++)
  314.     ((sockaddr_in*)this)->sin_zero[i] = 0;
  315. }
  316.  
  317. //
  318. // This function uses WinSock macros to get standard class information.
  319. // It knows nothing about subnetting, nor any classes beyond class C.
  320. //
  321. #pragma warn -cln
  322. TINetSocketAddress::TINetClass TINetSocketAddress::GetClass() const
  323. {
  324.   if (IN_CLASSA(GetNetworkAddress()))
  325.     return ClassA;
  326.   if (IN_CLASSB(GetNetworkAddress()))
  327.     return ClassB;
  328.   if (IN_CLASSC(GetNetworkAddress()))
  329.     return ClassC;
  330.   return ClassUnknown;
  331. }
  332. #pragma warn .cln
  333.