Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/net/netAddress.cxx

Go to the documentation of this file.
00001 // Filename: netAddress.cxx
00002 // Created by:  drose (08Feb00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "netAddress.h"
00020 #include "pprerror.h"
00021 #include "config_net.h"
00022 
00023 #include <prio.h>
00024 #include <prnetdb.h>
00025 
00026 
00027 ////////////////////////////////////////////////////////////////////
00028 //     Function: NetAddress::Constructor
00029 //       Access: Public
00030 //  Description: Constructs an unspecified address.
00031 ////////////////////////////////////////////////////////////////////
00032 NetAddress::
00033 NetAddress() {
00034   PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &_addr);
00035 }
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: NetAddress::Constructor
00039 //       Access: Public
00040 //  Description: Constructs an address from a given PRNetAddr.
00041 //               Normally, this constructor should not be used by user
00042 //               code; instead, create a default NetAddress and use
00043 //               one of the set_*() functions to set up an address.
00044 ////////////////////////////////////////////////////////////////////
00045 NetAddress::
00046 NetAddress(const PRNetAddr &addr) : _addr(addr) {
00047 }
00048 
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: NetAddress::set_any
00052 //       Access: Public
00053 //  Description: Sets the address up to refer to a particular port,
00054 //               but not to any particular IP.  Returns true if
00055 //               successful, false otherwise (currently, this only
00056 //               returns true).
00057 ////////////////////////////////////////////////////////////////////
00058 bool NetAddress::
00059 set_any(int port) {
00060   PR_InitializeNetAddr(PR_IpAddrAny, port, &_addr);
00061 
00062   return true;
00063 }
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //     Function: NetAddress::set_localhost
00067 //       Access: Public
00068 //  Description: Sets the address up to refer to a particular port,
00069 //               on this host.
00070 ////////////////////////////////////////////////////////////////////
00071 bool NetAddress::
00072 set_localhost(int port) {
00073   PR_InitializeNetAddr(PR_IpAddrLoopback, port, &_addr);
00074 
00075   return true;
00076 }
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: NetAddress::set_host
00080 //       Access: Public
00081 //  Description: Sets the address up to refer to a particular port
00082 //               on a particular host.  Returns true if the hostname
00083 //               is known, false otherwise.
00084 ////////////////////////////////////////////////////////////////////
00085 bool NetAddress::
00086 set_host(const string &hostname, int port) {
00087   // If the hostname appears to be a dot-separated IPv4 address, then
00088   // parse it directly and store it.  Some OS system libraries
00089   // (notably Win95) can't parse this themselves.
00090   union {
00091     PRUint32 l;
00092     unsigned char n[4];
00093   } ipaddr;
00094   int ni = 0;
00095   bool is_ip = true;
00096   size_t p = 0;
00097   size_t q = 0;
00098   unsigned int num = 0;
00099 
00100   while (p < hostname.length() && ni < 4 && is_ip) {
00101     if (hostname[p] == '.' && p > q) {
00102       // Now we have a number between q and p.
00103       ipaddr.n[ni] = (unsigned char)num;
00104       p++;
00105       q = p;
00106       num = 0;
00107       ni++;
00108 
00109       if (num >= 256 || ni >= 4) {
00110         is_ip = false;
00111       }
00112 
00113     } else if (isdigit(hostname[p])) {
00114       num = 10 * num + (unsigned int)(hostname[p] - '0');
00115       p++;
00116       if (num >= 256) {
00117         is_ip = false;
00118       }
00119     } else {
00120       is_ip = false;
00121     }
00122   }
00123 
00124   if (p == hostname.length() && ni < 4 && is_ip && p > q) {
00125     ipaddr.n[ni] = (unsigned char)num;
00126     ni++;
00127 
00128     if (num >= 256) {
00129       is_ip = false;
00130     }
00131   }
00132 
00133   if (p == hostname.length() && ni == 4 && is_ip) {
00134     net_cat.debug()
00135       << "Parsed IP " << (int)ipaddr.n[0] << "." << (int)ipaddr.n[1]
00136       << "." << (int)ipaddr.n[2] << "." << (int)ipaddr.n[3] << "\n";
00137 
00138     memset(&_addr, 0, sizeof(PRNetAddr));
00139     _addr.inet.family = PR_AF_INET;
00140     _addr.inet.port = PR_htons(port);
00141     _addr.inet.ip = ipaddr.l;
00142 
00143   } else {
00144     // If it's not a numeric IPv4 address, pass the whole thing on to
00145     // GetHostByName and let NSPR deal with it.
00146 
00147     char buf[PR_NETDB_BUF_SIZE];
00148     PRHostEnt host;
00149     PRStatus result =
00150       PR_GetHostByName(hostname.c_str(), buf, PR_NETDB_BUF_SIZE, &host);
00151     if (result != PR_SUCCESS) {
00152       pprerror("PR_GetHostByName");
00153       net_cat.error()
00154         << "Unable to look up hostname " << hostname << ".\n";
00155       return false;
00156     }
00157 
00158     PRIntn next = PR_EnumerateHostEnt(0, &host, port, &_addr);
00159 
00160     if (next == -1) {
00161       pprerror("PR_EnumerateHostEnt");
00162       return false;
00163     } else if (next == 0) {
00164       net_cat.error()
00165         << "No addresses available for " << hostname << ".\n";
00166       return false;
00167     }
00168   }
00169 
00170   return true;
00171 }
00172 
00173 ////////////////////////////////////////////////////////////////////
00174 //     Function: NetAddress::clear
00175 //       Access: Public
00176 //  Description: Resets the NetAddress to its initial state.
00177 ////////////////////////////////////////////////////////////////////
00178 void NetAddress::
00179 clear() {
00180   PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &_addr);
00181 }
00182 
00183 ////////////////////////////////////////////////////////////////////
00184 //     Function: NetAddress::get_port
00185 //       Access: Public
00186 //  Description: Returns the port number to which this address refers.
00187 ////////////////////////////////////////////////////////////////////
00188 int NetAddress::
00189 get_port() const {
00190   return PR_ntohs(_addr.inet.port);
00191 }
00192 
00193 ////////////////////////////////////////////////////////////////////
00194 //     Function: NetAddress::set_port
00195 //       Access: Public
00196 //  Description: Resets the port number without otherwise changing the
00197 //               address.
00198 ////////////////////////////////////////////////////////////////////
00199 void NetAddress::
00200 set_port(int port) {
00201   PR_InitializeNetAddr(PR_IpAddrNull, port, &_addr);
00202 }
00203 
00204 ////////////////////////////////////////////////////////////////////
00205 //     Function: NetAddress::get_ip_string
00206 //       Access: Public
00207 //  Description: Returns the IP address to which this address refers,
00208 //               formatted as a string.
00209 ////////////////////////////////////////////////////////////////////
00210 string NetAddress::
00211 get_ip_string() const {
00212   static const int buf_len = 1024;
00213   char buf[buf_len];
00214 
00215   PRStatus result =
00216     PR_NetAddrToString(&_addr, buf, buf_len);
00217   if (result != PR_SUCCESS) {
00218     pprerror("PR_NetAddrToString");
00219     return "error";
00220   }
00221 
00222   return string(buf);
00223 }
00224 
00225 ////////////////////////////////////////////////////////////////////
00226 //     Function: NetAddress::get_ip
00227 //       Access: Public
00228 //  Description: Returns the IP address to which this address refers,
00229 //               as a 32-bit integer, in host byte order.
00230 ////////////////////////////////////////////////////////////////////
00231 PN_uint32 NetAddress::
00232 get_ip() const {
00233   return PR_ntohl(_addr.inet.ip);
00234 }
00235 
00236 ////////////////////////////////////////////////////////////////////
00237 //     Function: NetAddress::get_ip_component
00238 //       Access: Public
00239 //  Description: Returns the nth 8-bit component of the IP address.
00240 //               An IP address has four components; component 0 is the
00241 //               first (leftmost), and component 3 is the last
00242 //               (rightmost) in the dotted number convention.
00243 ////////////////////////////////////////////////////////////////////
00244 PN_uint8 NetAddress::
00245 get_ip_component(int n) const {
00246   nassertr(n >= 0 && n < 4, 0);
00247   const PN_uint8 *ip = (const PN_uint8 *)&_addr.inet.ip;
00248   return ip[n];
00249 }
00250 
00251 
00252 ////////////////////////////////////////////////////////////////////
00253 //     Function: NetAddress::get_addr
00254 //       Access: Public
00255 //  Description: Returns the PRNetAddr for this address.
00256 ////////////////////////////////////////////////////////////////////
00257 PRNetAddr *NetAddress::
00258 get_addr() const {
00259   return (PRNetAddr *)&_addr;
00260 }
00261 
00262 ////////////////////////////////////////////////////////////////////
00263 //     Function: NetAddress::output
00264 //       Access: Public
00265 //  Description:
00266 ////////////////////////////////////////////////////////////////////
00267 void NetAddress::
00268 output(ostream &out) const {
00269   out << get_ip_string();
00270 }

Generated on Fri May 2 00:40:35 2003 for Panda by doxygen1.3