00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 extern "C" {
00042 #include <unistd.h>
00043 #include <sys/types.h>
00044 #include <sys/socket.h>
00045 #include <arpa/inet.h>
00046 #include <netinet/in.h>
00047 }
00048
00049 #include <iostream>
00050 #include <sstream>
00051
00052 #include "consmgr.h"
00053 #include "ipsockaddr.h"
00054
00055
00061 IPSocketAddress::IPSocketAddress(const std::string &address, int port)
00062 {
00063 int ret;
00064 struct sockaddr_storage ss;
00065 struct sockaddr_in *sin = reinterpret_cast<struct sockaddr_in*>
00066 (&ss);
00067
00068 #ifdef INET6
00069 struct sockaddr_in6 *sin6 = reinterpret_cast<struct sockaddr_in6*>
00070 (&ss);
00071
00072
00073
00074 ret = inet_pton(AF_INET6, address.c_str(), &sin6->sin6_addr);
00075 if (ret < 0) {
00076 throw(fireball(74, "inet_pton(AF_INET6) failed"));
00077 } else if (ret > 0) {
00078 ss.ss_family = AF_INET6;
00079 #ifndef NO_SA_LEN
00080 ss.ss_len = sizeof(struct sockaddr_in6);
00081 #endif
00082
00083 sin6->sin6_port = htons(port);
00084
00085 goto finish;
00086 }
00087 #endif
00088
00089
00090 ret = inet_pton(AF_INET, address.c_str(), &sin->sin_addr);
00091 if (ret < 0) {
00092 throw(fireball(75, "inet_pton(AF_INET) failed"));
00093 } else if (ret == 0) {
00094 throw(CMInvalidParameter("Unable to parse " + address +
00095 " as an address."));
00096 }
00097
00098 ss.ss_family = AF_INET;
00099 #ifndef NO_SA_LEN
00100 ss.ss_len = sizeof(struct sockaddr_in);
00101 #endif
00102
00103 sin->sin_port = htons(port);
00104
00105 finish:
00106 set_addr(reinterpret_cast<struct sockaddr*>(&ss));
00107 }
00108
00109 IPSocketAddress::~IPSocketAddress()
00110 {
00111 }
00112
00113
00114
00115
00116
00117
00119 u_short
00120 IPSocketAddress::port() const
00121 {
00122 u_short pval;
00123
00124 switch (family()) {
00125 case AF_INET:
00126 pval = ((sockaddr_in *)&addr)->sin_port;
00127 break;
00128 case AF_INET6:
00129 pval = ((sockaddr_in6*)&addr)->sin6_port;
00130 break;
00131 default:
00132 throw(CMInvalidParameter("Unknown family seen in IPSocketAddress::port()"));
00133
00134 }
00135 return (pval);
00136 }
00137
00138
00139
00140
00141
00142 string
00143 IPSocketAddress::get_id(void) const
00144 {
00145 #if MAYBE_A_BAD_IDEA
00146
00147 if (! id_cache.empty())
00148 return id_cache;
00149 #endif
00150
00151 std::ostringstream id_str;
00152
00153
00154
00155 char host[64], svc[6];
00156 #ifdef BROKEN_GETNAMEINFO
00157 sockaddr_in *a4 = (sockaddr_in *)&addr;
00158 # ifdef INET6
00159 sockaddr_in6 *a6 = (sockaddr_in6 *)&addr;
00160 # endif
00161 void *aptr;
00162 u_short port;
00163 #else
00164 int ret;
00165 #endif
00166
00167 #ifdef BROKEN_GETNAMEINFO
00168
00169 switch (family()) {
00170 case AF_INET:
00171 aptr = (void *)&a4->sin_addr;
00172 port = a4->sin_port;
00173 break;
00174 #ifdef INET6
00175 case AF_INET6:
00176 aptr = (void *)&a6->sin6_addr;
00177 port = a6->sin6_port;
00178 break;
00179 #endif
00180 default:
00181 throw(fireball(19, "Unknown family in current addr"));
00182 }
00183
00184
00185
00186
00187 if (NULL == inet_ntop(family(), aptr, host, sizeof(host)))
00188 throw(fireball(19, "Cannot get printable address from inet_ntop"));
00189
00190
00191
00192 snprintf(svc, sizeof(svc), "%d", ntohs(port));
00193 #else
00194
00195
00196 ret = getnameinfo((sockaddr*)&this->addr, sock_addrlen, host, sizeof(host),
00197 svc, sizeof(svc), NI_NUMERICSERV | NI_NUMERICHOST);
00198
00199 if (ret) {
00200 throw(fireball(19, "unable to getnameinfo() for addr..."));
00201 }
00202 #endif
00203
00204 id_str << "IPSocketAddress[" << host << ":" << svc << "]";
00205
00206 #if MAYBE_A_BAD_IDEA
00207
00208 id_cache = id_str.str();
00209 #endif
00210
00211 return(id_str.str());
00212 }