libassa  3.5.1
INETAddress.cpp
Go to the documentation of this file.
1 // -*- c++ -*-
2 //------------------------------------------------------------------------------
3 // INETAddress.cpp
4 //------------------------------------------------------------------------------
5 // Copyright (c) 1999 by Vladislav Grinchenko
6 //
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Library General Public
9 // License as published by the Free Software Foundation; either
10 // version 2 of the License, or (at your option) any later version.
11 //------------------------------------------------------------------------------
12 
13 #include <cstdlib>
14 #include <string>
15 
16 #if defined(WIN32)
17 # include <winsock2.h>
18 #else
19 # include <netdb.h> // gethostbyname(3)
20 // extern int h_errno; // gethostbyname(3)
21 # include <sys/socket.h> // for AF_INET
22 # include <unistd.h>
23 # include <sys/utsname.h>
24 #endif
25 
26 #include "assa/INETAddress.h"
27 using namespace ASSA;
28 
30 
31 void
33 init ()
34 {
35  ::memset ((char*) &m_address, 0, sizeof(m_address));
36 }
37 
39 INETAddress ()
40 {
41 // trace_with_mask("INETAddress::INETAddress()",SOCKTRACE);
42  init ();
43 }
44 
46 INETAddress (const char* host_, int port_)
47 {
48 // trace_with_mask("INETAddress::INETAddress(host, port)",SOCKTRACE);
49  init ();
50  createHostPort (host_, htons (port_));
51 }
52 
54 INETAddress (const char* host_, const char* service_, Protocol protocol_)
55 {
56 // trace_with_mask("INETAddress::INETAddress(host, port, protocol)",
57 // SOCKTRACE);
58  init ();
59  createHostPort (host_, getServiceByName (service_,protocol_));
60 }
61 
63 INETAddress (int port_)
64 {
65 // trace_with_mask("INETAddress::INETAddress(port)",SOCKTRACE);
66 
67  init ();
68  createHostPort ("", htons (port_));
69 }
70 
72 INETAddress (SA_IN* address_)
73 {
74 // trace_with_mask("INETAddress::INETAddress(SA_IN*)",SOCKTRACE);
75 
76  init ();
77  ::memcpy ((void*) &m_address, (const void*) address_, sizeof(SA_IN));
78 }
79 
81 INETAddress (SA* address_)
82 {
83 // trace_with_mask("INETAddress::INETAddress(SA*)",SOCKTRACE);
84 
85  init ();
86  ::memcpy ((void*) &m_address, (const void*) address_, sizeof(SA_IN));
87 }
88 
90 INETAddress (struct in_addr * haddr_, int port_)
91 {
92 // trace_with_mask("INETAddress::INETAddress(in_addr*,port)",ADDRESS);
93 
94  init ();
95  m_address.sin_addr = *haddr_;
96  m_address.sin_family = AF_INET;
97  m_address.sin_port = htons(port_);
98 }
99 
101 INETAddress (const char* address_, Protocol protocol_)
102 {
103 // trace_with_mask("INETAddress::INETAddress(address, protocol)",ADDRESS);
104 
105  init ();
106 
107  string s(address_);
108  string sPort(s);
109  int r = 0;
110  string host;
111 
112 #ifdef BLOCKED
113  const u_int HOSTNAMELEN = 64;
114  char buf[HOSTNAMELEN]; // 64 on Linux/i386
115  if (gethostname (buf, HOSTNAMELEN) == 0) {
116  host = buf;
117  }
118 #endif
119 
120  if ( (r = s.find(':')) > 0 ) { // host:service
121  host = s.substr(0, r);
122  sPort = s.substr(r+1);
123  }
124  else if ( (r = s.find('@')) > 0 ) { // service@host
125  sPort = s.substr(0, r);
126  host = s.substr(r+1);
127  }
128 
129  if ( (r = getServiceByName (sPort)) == 0 ) { // service
130  return;
131  }
132 
133  createHostPort (host.c_str(), r);
134 }
135 
136 int
138 getServiceByName (string s_, Protocol p_)
139 {
140 // trace_with_mask("INETAddress::getServiceByName", ADDRESS);
141 
142  long l = 0;
143  struct servent* sp = NULL;
144 
145  if ((l = strtol (s_.c_str(), (char**) NULL, 10))) {
146  return htons ((unsigned short int) l);
147  }
148 
149  if ((sp = getservbyname (s_.c_str(), (p_==TCP ? "tcp" : "udp")))) {
150  return sp->s_port;
151  }
152 
154  return 0;
155 }
156 
157 void
159 createHostPort (const char* host_, int port_)
160 {
161 // trace_with_mask("INETAddress::createHostPort(char*,int)", ADDRESS);
162 
163  struct hostent* hp = 0;
164 
165  if (strlen (host_) == 0) {
166  m_address.sin_addr.s_addr = htonl(INADDR_ANY);
167  goto done;
168  }
169 
170  if ((hp = gethostbyname (host_)) == NULL) {
172  errno = h_errno;
173  EL((ASSAERR,"gethostbyname (\"%s\") failed\n", host_));
174  return;
175  }
176  memcpy ((char*) &m_address.sin_addr, hp->h_addr_list[0], hp->h_length);
177 
178 done:
179  m_address.sin_family = AF_INET;
180  m_address.sin_port = port_;
181 }
182 
183 string
185 getHostName ()
186 {
187  if (m_address.sin_addr.s_addr == htonl(INADDR_ANY)) {
188  return ("");
189  }
190 
191  struct hostent* hentry;
192  hentry = gethostbyaddr ((const char*) &m_address.sin_addr,
193  sizeof(m_address.sin_addr),
194  AF_INET);
195  if (hentry == NULL) {
196  errno = h_errno;
198  EL((ASSAERR,"gethostbyaddr() failed\n"));
199  return ("");
200  }
201  return hentry->h_name;
202 }
203 
204 void
206 dump ()
207 {
208 // trace_with_mask("INETAddress::dump", ADDRESS);
209 
210  Address::dump ();
211  DL((ADDRESS,"Family - %s\n", ntohs(m_address.sin_family) == AF_INET ?
212  "AF_INET" : "AF_UNIX"));
213  DL((ADDRESS,"host - %s\n", getHostName ().c_str()));
214  DL((ADDRESS,"port - %d\n", getPort ()));
215  DL((ADDRESS,"address - %s\n", inet_ntoa (m_address.sin_addr)));
216 }
217 
218 #if defined(WIN32)
219 struct utsname
220 {
221  char sysname[20];
222  char nodename[20];
223  char release[20];
224  char version[20];
225  char machine[20];
226 };
227 #endif
228 
229 string
231 get_fully_qualified_domain_name (vector<string>& aliases_)
232 {
233 // trace_with_mask ("INETAddress::get_fully_qualified_domain_name", ADDRESS);
234 
235  if (m_fqdn_cache.length ()) {
236  return m_fqdn_cache;
237  }
238 
239  struct utsname myname;
240  struct hostent* hptr = NULL;
241 
242 #if defined(WIN32)
243  DWORD slen;
244  slen = sizeof (myname.nodename) - 1;
245  GetComputerNameA (myname.nodename, &slen);
246 #else
247  if (::uname (&myname) < 0) {
248  EL((ADDRESS,"Hostname is not set!\n"));
249  return m_fqdn_cache;
250  }
251 #endif
252 
253  if ((hptr = ::gethostbyname (myname.nodename)) == NULL) {
254  errno = h_errno;
255  EL((ADDRESS,"gethostbyname (%s) failed\n", myname.nodename));
256  return m_fqdn_cache;
257  }
258  m_fqdn_cache = hptr->h_name;
259  char** pptr = hptr->h_aliases;
260  while (*pptr != NULL) {
261  aliases_.push_back (*pptr);
262  pptr++;
263  }
264 
265  return m_fqdn_cache;
266 }
An incapsulation of TCP/UDP Internet Protocol socket address structure.
#define EL(X)
A macro for writing error message to the Logger.
Definition: Logger.h:285
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
unsigned int u_int
Definition: Logger_Impl.h:40
virtual void dump()
Dump object state to the log file.
Definition: Address.h:101
void setstate(addrstate flag_)
Set state of the Address object.
Definition: Address.h:111
@ badbit
bad state
Definition: Address.h:56
void init()
Perform initialization common to all ctors.
Definition: INETAddress.cpp:33
string getHostName()
Return host name.
void dump()
Dump the address content to log file.
static string get_fully_qualified_domain_name(vector< string > &aliases_)
Return fully-qualified host name.
INETAddress()
Default constructor.
Definition: INETAddress.cpp:39
int getServiceByName(string serv_, Protocol prot_=TCP)
Lookup port by its service name found in /etc/services.
int getPort() const
Return port.
Definition: INETAddress.h:116
void createHostPort(const char *host_, int port_)
Makes socket address out of host name and port.
@ TCP
TCP protocol.
Definition: INETAddress.h:31
SA_IN m_address
Internet address structure sockaddr_in.
Definition: INETAddress.h:172
static string m_fqdn_cache
Cached fully-qualified domain name.
Definition: INETAddress.h:168
Definition: Acceptor.h:40
struct sockaddr_in SA_IN
Definition: Address.h:34
@ ADDRESS
Class Address & friends messages
Definition: LogMask.h:51
@ ASSAERR
ASSA and system errors
Definition: LogMask.h:34
struct sockaddr SA
Definition: Address.h:33