xref: /onnv-gate/usr/src/cmd/lms/tools/ATNetworkTool.cpp (revision 9203:3ebffd0a1b10)
1*9203SMark.Logan@Sun.COM /*******************************************************************************
2*9203SMark.Logan@Sun.COM  * Copyright (C) 2004-2008 Intel Corp. All rights reserved.
3*9203SMark.Logan@Sun.COM  *
4*9203SMark.Logan@Sun.COM  * Redistribution and use in source and binary forms, with or without
5*9203SMark.Logan@Sun.COM  * modification, are permitted provided that the following conditions are met:
6*9203SMark.Logan@Sun.COM  *
7*9203SMark.Logan@Sun.COM  *  - Redistributions of source code must retain the above copyright notice,
8*9203SMark.Logan@Sun.COM  *    this list of conditions and the following disclaimer.
9*9203SMark.Logan@Sun.COM  *
10*9203SMark.Logan@Sun.COM  *  - Redistributions in binary form must reproduce the above copyright notice,
11*9203SMark.Logan@Sun.COM  *    this list of conditions and the following disclaimer in the documentation
12*9203SMark.Logan@Sun.COM  *    and/or other materials provided with the distribution.
13*9203SMark.Logan@Sun.COM  *
14*9203SMark.Logan@Sun.COM  *  - Neither the name of Intel Corp. nor the names of its
15*9203SMark.Logan@Sun.COM  *    contributors may be used to endorse or promote products derived from this
16*9203SMark.Logan@Sun.COM  *    software without specific prior written permission.
17*9203SMark.Logan@Sun.COM  *
18*9203SMark.Logan@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19*9203SMark.Logan@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*9203SMark.Logan@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*9203SMark.Logan@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
22*9203SMark.Logan@Sun.COM  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*9203SMark.Logan@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*9203SMark.Logan@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*9203SMark.Logan@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*9203SMark.Logan@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*9203SMark.Logan@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*9203SMark.Logan@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
29*9203SMark.Logan@Sun.COM  *******************************************************************************/
30*9203SMark.Logan@Sun.COM 
31*9203SMark.Logan@Sun.COM #ifdef HAVE_CONFIG_H
32*9203SMark.Logan@Sun.COM #include "config.h"
33*9203SMark.Logan@Sun.COM #endif
34*9203SMark.Logan@Sun.COM 
35*9203SMark.Logan@Sun.COM #include "ATNetworkTool.h"
36*9203SMark.Logan@Sun.COM #include <sstream>
37*9203SMark.Logan@Sun.COM #include <algorithm>
38*9203SMark.Logan@Sun.COM #include <cerrno>
39*9203SMark.Logan@Sun.COM #include <net/if.h>
40*9203SMark.Logan@Sun.COM #include <netdb.h>
41*9203SMark.Logan@Sun.COM 
42*9203SMark.Logan@Sun.COM #ifdef __sun
43*9203SMark.Logan@Sun.COM #include <arpa/inet.h>
44*9203SMark.Logan@Sun.COM #include <sys/sockio.h>
45*9203SMark.Logan@Sun.COM #include <stdio.h>
46*9203SMark.Logan@Sun.COM #include <stropts.h>
47*9203SMark.Logan@Sun.COM #else
48*9203SMark.Logan@Sun.COM #include <ifaddrs.h>
49*9203SMark.Logan@Sun.COM #endif // __sun
50*9203SMark.Logan@Sun.COM 
51*9203SMark.Logan@Sun.COM #include <unistd.h>
52*9203SMark.Logan@Sun.COM #include <fcntl.h>
53*9203SMark.Logan@Sun.COM 
GetHostNameDomain(const char * name,std::string & domain)54*9203SMark.Logan@Sun.COM bool ATNetworkTool::GetHostNameDomain(const char *name, std::string &domain)
55*9203SMark.Logan@Sun.COM {
56*9203SMark.Logan@Sun.COM 	const char *domp = strchr(name, '.');
57*9203SMark.Logan@Sun.COM 	if (domp) {
58*9203SMark.Logan@Sun.COM 		domp++;
59*9203SMark.Logan@Sun.COM 		if (*domp) {
60*9203SMark.Logan@Sun.COM #ifdef LMS_NET_DEBUG
61*9203SMark.Logan@Sun.COM 			printf("D:  %s\n", domp);
62*9203SMark.Logan@Sun.COM #endif
63*9203SMark.Logan@Sun.COM 			domain = domp;
64*9203SMark.Logan@Sun.COM 			return true;
65*9203SMark.Logan@Sun.COM 		}
66*9203SMark.Logan@Sun.COM 	}
67*9203SMark.Logan@Sun.COM 	return false;
68*9203SMark.Logan@Sun.COM }
69*9203SMark.Logan@Sun.COM 
GetHentDomain(struct hostent * hent,std::string & domain)70*9203SMark.Logan@Sun.COM bool ATNetworkTool::GetHentDomain(struct hostent *hent, std::string &domain)
71*9203SMark.Logan@Sun.COM {
72*9203SMark.Logan@Sun.COM 	if (NULL == hent) {
73*9203SMark.Logan@Sun.COM 		return false;
74*9203SMark.Logan@Sun.COM 	}
75*9203SMark.Logan@Sun.COM 	if (NULL == hent->h_name) {
76*9203SMark.Logan@Sun.COM 		return false;
77*9203SMark.Logan@Sun.COM 	}
78*9203SMark.Logan@Sun.COM 
79*9203SMark.Logan@Sun.COM #ifdef LMS_NET_DEBUG
80*9203SMark.Logan@Sun.COM 	printf("N:  %s\n", hent->h_name);
81*9203SMark.Logan@Sun.COM #endif
82*9203SMark.Logan@Sun.COM 	if (ATNetworkTool::GetHostNameDomain(hent->h_name, domain)) {
83*9203SMark.Logan@Sun.COM 		return true;
84*9203SMark.Logan@Sun.COM 	}
85*9203SMark.Logan@Sun.COM 
86*9203SMark.Logan@Sun.COM 	if (NULL != hent->h_aliases) {
87*9203SMark.Logan@Sun.COM 		for (char **ssx = hent->h_aliases; ssx && *ssx; ssx++) {
88*9203SMark.Logan@Sun.COM #ifdef LMS_NET_DEBUG
89*9203SMark.Logan@Sun.COM 			printf("A:  %s\n", *ssx);
90*9203SMark.Logan@Sun.COM #endif
91*9203SMark.Logan@Sun.COM 			if (ATNetworkTool::GetHostNameDomain(*ssx, domain)) {
92*9203SMark.Logan@Sun.COM 				return true;
93*9203SMark.Logan@Sun.COM 			}
94*9203SMark.Logan@Sun.COM 		}
95*9203SMark.Logan@Sun.COM 	}
96*9203SMark.Logan@Sun.COM 	return false;
97*9203SMark.Logan@Sun.COM }
98*9203SMark.Logan@Sun.COM 
GetIPDomain(const ATAddress & ip,std::string & domain,int & error)99*9203SMark.Logan@Sun.COM bool ATNetworkTool::GetIPDomain(const ATAddress &ip, std::string &domain, int &error)
100*9203SMark.Logan@Sun.COM {
101*9203SMark.Logan@Sun.COM 	char hbuf[NI_MAXHOST];
102*9203SMark.Logan@Sun.COM 
103*9203SMark.Logan@Sun.COM 	if (0 != (error = getnameinfo(ip.addr(), ip.size(),
104*9203SMark.Logan@Sun.COM 				      hbuf, sizeof(hbuf),
105*9203SMark.Logan@Sun.COM 				      NULL, 0,
106*9203SMark.Logan@Sun.COM 				      NI_NAMEREQD))) {
107*9203SMark.Logan@Sun.COM 		return false;
108*9203SMark.Logan@Sun.COM 	}
109*9203SMark.Logan@Sun.COM 
110*9203SMark.Logan@Sun.COM 	return ATNetworkTool::GetHostNameDomain(hbuf, domain);
111*9203SMark.Logan@Sun.COM }
112*9203SMark.Logan@Sun.COM 
GetLocalIPs(ATAddressList & addresses,int & error,int family,bool withloopback)113*9203SMark.Logan@Sun.COM int ATNetworkTool::GetLocalIPs(ATAddressList &addresses, int &error, int family, bool withloopback)
114*9203SMark.Logan@Sun.COM {
115*9203SMark.Logan@Sun.COM 	struct ifaddrs *ifap;
116*9203SMark.Logan@Sun.COM 
117*9203SMark.Logan@Sun.COM #ifdef __sun
118*9203SMark.Logan@Sun.COM 
119*9203SMark.Logan@Sun.COM 	char          buf[1024];
120*9203SMark.Logan@Sun.COM 	struct ifconf ifc;
121*9203SMark.Logan@Sun.COM 	struct ifreq *ifr;
122*9203SMark.Logan@Sun.COM 	int           sock;
123*9203SMark.Logan@Sun.COM 	int           nInterfaces;
124*9203SMark.Logan@Sun.COM 	int           i;
125*9203SMark.Logan@Sun.COM 
126*9203SMark.Logan@Sun.COM 	addresses.clear();
127*9203SMark.Logan@Sun.COM 
128*9203SMark.Logan@Sun.COM 	sock = socket(AF_INET, SOCK_DGRAM, 0);
129*9203SMark.Logan@Sun.COM 	if(sock < 0)
130*9203SMark.Logan@Sun.COM 	{
131*9203SMark.Logan@Sun.COM 		perror("socket");
132*9203SMark.Logan@Sun.COM 		return 1;
133*9203SMark.Logan@Sun.COM 	}
134*9203SMark.Logan@Sun.COM 
135*9203SMark.Logan@Sun.COM 	/* Query available interfaces. */
136*9203SMark.Logan@Sun.COM 	ifc.ifc_len = sizeof(buf);
137*9203SMark.Logan@Sun.COM 	ifc.ifc_buf = buf;
138*9203SMark.Logan@Sun.COM 	if(ioctl(sock, SIOCGIFCONF, &ifc) < 0)
139*9203SMark.Logan@Sun.COM 	{
140*9203SMark.Logan@Sun.COM 		perror("ioctl(SIOCGIFCONF)");
141*9203SMark.Logan@Sun.COM 		close(sock);
142*9203SMark.Logan@Sun.COM 		return 1;
143*9203SMark.Logan@Sun.COM 	}
144*9203SMark.Logan@Sun.COM 
145*9203SMark.Logan@Sun.COM 	/* Iterate through the list of interfaces. */
146*9203SMark.Logan@Sun.COM 	ifr         = ifc.ifc_req;
147*9203SMark.Logan@Sun.COM 	nInterfaces = ifc.ifc_len / sizeof(struct ifreq);
148*9203SMark.Logan@Sun.COM 	for(i = 0; i < nInterfaces; i++)
149*9203SMark.Logan@Sun.COM 	{
150*9203SMark.Logan@Sun.COM 		struct ifreq *item = &ifr[i];
151*9203SMark.Logan@Sun.COM 
152*9203SMark.Logan@Sun.COM 		if (item->ifr_flags & IFF_LOOPBACK)
153*9203SMark.Logan@Sun.COM 			continue;
154*9203SMark.Logan@Sun.COM 
155*9203SMark.Logan@Sun.COM 		addresses.insert(&item->ifr_addr);
156*9203SMark.Logan@Sun.COM 	}
157*9203SMark.Logan@Sun.COM 
158*9203SMark.Logan@Sun.COM 	close(sock);
159*9203SMark.Logan@Sun.COM 
160*9203SMark.Logan@Sun.COM #else // ! __sun
161*9203SMark.Logan@Sun.COM 
162*9203SMark.Logan@Sun.COM 	if (0 != getifaddrs(&ifap)) {
163*9203SMark.Logan@Sun.COM 		error = errno;
164*9203SMark.Logan@Sun.COM 		return -1;
165*9203SMark.Logan@Sun.COM 	}
166*9203SMark.Logan@Sun.COM 
167*9203SMark.Logan@Sun.COM 	addresses.clear();
168*9203SMark.Logan@Sun.COM 	for (struct ifaddrs *ifa = ifap; ifa; ifa = ifa->ifa_next) {
169*9203SMark.Logan@Sun.COM 		if (NULL == ifa->ifa_addr) {
170*9203SMark.Logan@Sun.COM 			continue;
171*9203SMark.Logan@Sun.COM 		}
172*9203SMark.Logan@Sun.COM 		if ((ifa->ifa_flags & IFF_UP) == 0) {
173*9203SMark.Logan@Sun.COM 			continue;
174*9203SMark.Logan@Sun.COM 		}
175*9203SMark.Logan@Sun.COM 		if ((!withloopback) &&
176*9203SMark.Logan@Sun.COM 		    (((ifa->ifa_flags & IFF_LOOPBACK) != 0) ||
177*9203SMark.Logan@Sun.COM 		    ((ifa->ifa_flags & (IFF_BROADCAST | IFF_POINTOPOINT)) == 0))) {
178*9203SMark.Logan@Sun.COM 			continue;
179*9203SMark.Logan@Sun.COM 		}
180*9203SMark.Logan@Sun.COM 
181*9203SMark.Logan@Sun.COM 		if (AF_UNSPEC != family) {
182*9203SMark.Logan@Sun.COM 			if (ATNetworkTool::AF_XINETX == family) {
183*9203SMark.Logan@Sun.COM 				if (!ATAddress::saIsInet(ifa->ifa_addr)) {
184*9203SMark.Logan@Sun.COM 					continue;
185*9203SMark.Logan@Sun.COM 				}
186*9203SMark.Logan@Sun.COM 			} else {
187*9203SMark.Logan@Sun.COM 				if (ifa->ifa_addr->sa_family != family) {
188*9203SMark.Logan@Sun.COM 					continue;
189*9203SMark.Logan@Sun.COM 				}
190*9203SMark.Logan@Sun.COM 			}
191*9203SMark.Logan@Sun.COM 		}
192*9203SMark.Logan@Sun.COM 
193*9203SMark.Logan@Sun.COM 		addresses.insert(ifa->ifa_addr);
194*9203SMark.Logan@Sun.COM 	}
195*9203SMark.Logan@Sun.COM 	freeifaddrs(ifap);
196*9203SMark.Logan@Sun.COM 
197*9203SMark.Logan@Sun.COM #endif // __sun
198*9203SMark.Logan@Sun.COM 
199*9203SMark.Logan@Sun.COM 	return 0;
200*9203SMark.Logan@Sun.COM }
201*9203SMark.Logan@Sun.COM 
GetLocalNetDomains(ATDomainMap & domains,int & error,int family)202*9203SMark.Logan@Sun.COM int ATNetworkTool::GetLocalNetDomains(ATDomainMap &domains, int &error, int family)
203*9203SMark.Logan@Sun.COM {
204*9203SMark.Logan@Sun.COM 	int ret;
205*9203SMark.Logan@Sun.COM 	ATAddressList addresses;
206*9203SMark.Logan@Sun.COM 
207*9203SMark.Logan@Sun.COM 	if (0 != (ret = ATNetworkTool::GetLocalIPs(addresses, error, family))) {
208*9203SMark.Logan@Sun.COM 		return ret;
209*9203SMark.Logan@Sun.COM 	}
210*9203SMark.Logan@Sun.COM 
211*9203SMark.Logan@Sun.COM 	domains.clear();
212*9203SMark.Logan@Sun.COM 	ATAddressList::iterator aend = addresses.end();
213*9203SMark.Logan@Sun.COM 	for (ATAddressList::iterator ait = addresses.begin();
214*9203SMark.Logan@Sun.COM 	    ait != aend;
215*9203SMark.Logan@Sun.COM 	    ait++)
216*9203SMark.Logan@Sun.COM 	{
217*9203SMark.Logan@Sun.COM 		std::string domain;
218*9203SMark.Logan@Sun.COM 		if (ATNetworkTool::GetIPDomain(*ait, domain, error)) {
219*9203SMark.Logan@Sun.COM 			domains[*ait] = domain;
220*9203SMark.Logan@Sun.COM 		}
221*9203SMark.Logan@Sun.COM 	}
222*9203SMark.Logan@Sun.COM 	return 0;
223*9203SMark.Logan@Sun.COM }
224*9203SMark.Logan@Sun.COM 
GetSockDomain(int sock,std::string & domain,int & error)225*9203SMark.Logan@Sun.COM int ATNetworkTool::GetSockDomain(int sock, std::string &domain, int &error)
226*9203SMark.Logan@Sun.COM {
227*9203SMark.Logan@Sun.COM 	struct sockaddr_storage ss;
228*9203SMark.Logan@Sun.COM 	socklen_t salen = sizeof(ss);
229*9203SMark.Logan@Sun.COM 	struct sockaddr *sa;
230*9203SMark.Logan@Sun.COM 
231*9203SMark.Logan@Sun.COM 	sa = (struct sockaddr *)&ss;
232*9203SMark.Logan@Sun.COM 
233*9203SMark.Logan@Sun.COM 	if (getsockname(sock, sa, &salen) != 0) {
234*9203SMark.Logan@Sun.COM 		error = errno;
235*9203SMark.Logan@Sun.COM 		return -1;
236*9203SMark.Logan@Sun.COM 	}
237*9203SMark.Logan@Sun.COM 
238*9203SMark.Logan@Sun.COM 	if (ATNetworkTool::GetIPDomain(sa, domain, error)) {
239*9203SMark.Logan@Sun.COM 		return 1;
240*9203SMark.Logan@Sun.COM 	}
241*9203SMark.Logan@Sun.COM 	return 0;
242*9203SMark.Logan@Sun.COM }
243*9203SMark.Logan@Sun.COM 
GetSockPeerIPs(int sock,ATAddressList & addresses,int & error,int family,bool zeroport)244*9203SMark.Logan@Sun.COM int ATNetworkTool::GetSockPeerIPs(int sock, ATAddressList &addresses, int &error,
245*9203SMark.Logan@Sun.COM 				  int family, bool zeroport)
246*9203SMark.Logan@Sun.COM {
247*9203SMark.Logan@Sun.COM 	struct sockaddr_storage ss;
248*9203SMark.Logan@Sun.COM 	socklen_t salen = sizeof(ss);
249*9203SMark.Logan@Sun.COM 	struct sockaddr *sa;
250*9203SMark.Logan@Sun.COM 	struct addrinfo hints, *paddr, *paddrp;
251*9203SMark.Logan@Sun.COM 
252*9203SMark.Logan@Sun.COM 	sa = (struct sockaddr *)&ss;
253*9203SMark.Logan@Sun.COM 
254*9203SMark.Logan@Sun.COM 	if (getpeername(sock, sa, &salen) != 0) {
255*9203SMark.Logan@Sun.COM 		error = errno;
256*9203SMark.Logan@Sun.COM 		return -1;
257*9203SMark.Logan@Sun.COM 	}
258*9203SMark.Logan@Sun.COM 
259*9203SMark.Logan@Sun.COM 	char hbuf[NI_MAXHOST];
260*9203SMark.Logan@Sun.COM 	char pbuf[NI_MAXSERV];
261*9203SMark.Logan@Sun.COM 	if (0 != (error = getnameinfo(sa, salen,
262*9203SMark.Logan@Sun.COM 				      hbuf, sizeof(hbuf),
263*9203SMark.Logan@Sun.COM 				      pbuf, sizeof(pbuf),
264*9203SMark.Logan@Sun.COM 				      0))) {
265*9203SMark.Logan@Sun.COM 		return -1;
266*9203SMark.Logan@Sun.COM 	}
267*9203SMark.Logan@Sun.COM 
268*9203SMark.Logan@Sun.COM 	memset(&hints, 0, sizeof(hints));
269*9203SMark.Logan@Sun.COM 	if (ATNetworkTool::AF_XINETX == family) {
270*9203SMark.Logan@Sun.COM 		hints.ai_family = PF_UNSPEC;
271*9203SMark.Logan@Sun.COM 	} else {
272*9203SMark.Logan@Sun.COM 		hints.ai_family = family;
273*9203SMark.Logan@Sun.COM 	}
274*9203SMark.Logan@Sun.COM 	hints.ai_socktype = SOCK_STREAM;
275*9203SMark.Logan@Sun.COM 	if (0 != (error = getaddrinfo(hbuf, pbuf, &hints, &paddrp))) {
276*9203SMark.Logan@Sun.COM 		return -1;
277*9203SMark.Logan@Sun.COM 	}
278*9203SMark.Logan@Sun.COM 	addresses.clear();
279*9203SMark.Logan@Sun.COM 	for (paddr = paddrp; paddr; paddr = paddr->ai_next) {
280*9203SMark.Logan@Sun.COM 		if (ATNetworkTool::AF_XINETX == family) {
281*9203SMark.Logan@Sun.COM 			if (!ATAddress::saIsInet(paddr->ai_addr)) {
282*9203SMark.Logan@Sun.COM 				continue;
283*9203SMark.Logan@Sun.COM 			}
284*9203SMark.Logan@Sun.COM 		}
285*9203SMark.Logan@Sun.COM 		if (zeroport) {
286*9203SMark.Logan@Sun.COM 			addresses.insert(ATAddress(paddr->ai_addr, 0));
287*9203SMark.Logan@Sun.COM 		} else {
288*9203SMark.Logan@Sun.COM 			addresses.insert(paddr->ai_addr);
289*9203SMark.Logan@Sun.COM 		}
290*9203SMark.Logan@Sun.COM 	}
291*9203SMark.Logan@Sun.COM 	freeaddrinfo(paddrp);
292*9203SMark.Logan@Sun.COM 	return 0;
293*9203SMark.Logan@Sun.COM }
294*9203SMark.Logan@Sun.COM 
IsSockPeerLocal(int sock,int & error,int family)295*9203SMark.Logan@Sun.COM int ATNetworkTool::IsSockPeerLocal(int sock, int &error, int family)
296*9203SMark.Logan@Sun.COM {
297*9203SMark.Logan@Sun.COM 	ATAddressList localAddresses;
298*9203SMark.Logan@Sun.COM 	ATAddressList targAddresses;
299*9203SMark.Logan@Sun.COM 
300*9203SMark.Logan@Sun.COM 	if (0 != ATNetworkTool::GetSockPeerIPs(sock, targAddresses, error,
301*9203SMark.Logan@Sun.COM 						family, true)) {
302*9203SMark.Logan@Sun.COM 		return -1;
303*9203SMark.Logan@Sun.COM 	}
304*9203SMark.Logan@Sun.COM 	if (0 != ATNetworkTool::GetLocalIPs(localAddresses, error,
305*9203SMark.Logan@Sun.COM 						family, true)) {
306*9203SMark.Logan@Sun.COM 		return -1;
307*9203SMark.Logan@Sun.COM 	}
308*9203SMark.Logan@Sun.COM 	if (std::includes(localAddresses.begin(), localAddresses.end(),
309*9203SMark.Logan@Sun.COM 			  targAddresses.begin(), targAddresses.end())) {
310*9203SMark.Logan@Sun.COM 		return 1;
311*9203SMark.Logan@Sun.COM 	}
312*9203SMark.Logan@Sun.COM 	return 0;
313*9203SMark.Logan@Sun.COM }
314*9203SMark.Logan@Sun.COM 
CloseSocket(int s)315*9203SMark.Logan@Sun.COM int ATNetworkTool::CloseSocket(int s)
316*9203SMark.Logan@Sun.COM {
317*9203SMark.Logan@Sun.COM 	shutdown(s, SHUT_RDWR);
318*9203SMark.Logan@Sun.COM 	return close(s);
319*9203SMark.Logan@Sun.COM }
320*9203SMark.Logan@Sun.COM 
CreateSocket(const struct addrinfo * addr,int & error)321*9203SMark.Logan@Sun.COM int ATNetworkTool::CreateSocket(const struct addrinfo *addr, int &error)
322*9203SMark.Logan@Sun.COM {
323*9203SMark.Logan@Sun.COM 	return ATNetworkTool::CreateSocket(addr->ai_addr, addr->ai_addrlen,
324*9203SMark.Logan@Sun.COM 					    error,
325*9203SMark.Logan@Sun.COM 					    addr->ai_family, addr->ai_socktype,
326*9203SMark.Logan@Sun.COM 					    addr->ai_protocol);
327*9203SMark.Logan@Sun.COM }
328*9203SMark.Logan@Sun.COM 
CreateSocket(const struct sockaddr * addr,socklen_t addrlen,int & error,int family,int socktype,int protocol)329*9203SMark.Logan@Sun.COM int ATNetworkTool::CreateSocket(const struct sockaddr *addr, socklen_t addrlen,
330*9203SMark.Logan@Sun.COM 				int &error,
331*9203SMark.Logan@Sun.COM 				int family, int socktype, int protocol)
332*9203SMark.Logan@Sun.COM {
333*9203SMark.Logan@Sun.COM 	int s = socket(family, socktype, protocol);
334*9203SMark.Logan@Sun.COM 	if (s < 0) {
335*9203SMark.Logan@Sun.COM 		error = errno;
336*9203SMark.Logan@Sun.COM 		return -1;
337*9203SMark.Logan@Sun.COM 	}
338*9203SMark.Logan@Sun.COM 
339*9203SMark.Logan@Sun.COM 	if (socktype != SOCK_DGRAM) {
340*9203SMark.Logan@Sun.COM 		linger l;
341*9203SMark.Logan@Sun.COM 		l.l_onoff = 0;
342*9203SMark.Logan@Sun.COM 		l.l_linger = 0;
343*9203SMark.Logan@Sun.COM 		if (setsockopt(s, SOL_SOCKET, SO_LINGER,
344*9203SMark.Logan@Sun.COM 			       (char *)&l, sizeof(l)) == -1) {
345*9203SMark.Logan@Sun.COM 			error = errno;
346*9203SMark.Logan@Sun.COM 			close(s);
347*9203SMark.Logan@Sun.COM 			return -1;
348*9203SMark.Logan@Sun.COM 		}
349*9203SMark.Logan@Sun.COM 	}
350*9203SMark.Logan@Sun.COM 
351*9203SMark.Logan@Sun.COM 	if (bind(s, addr, addrlen) == -1) {
352*9203SMark.Logan@Sun.COM 		error = errno;
353*9203SMark.Logan@Sun.COM 		close(s);
354*9203SMark.Logan@Sun.COM 		return -1;
355*9203SMark.Logan@Sun.COM 	}
356*9203SMark.Logan@Sun.COM 
357*9203SMark.Logan@Sun.COM 	return s;
358*9203SMark.Logan@Sun.COM }
359*9203SMark.Logan@Sun.COM 
ConnectSocket(struct addrinfo * addr,int & error,bool loopback)360*9203SMark.Logan@Sun.COM int ATNetworkTool::ConnectSocket(struct addrinfo *addr,
361*9203SMark.Logan@Sun.COM 				 int &error, bool loopback)
362*9203SMark.Logan@Sun.COM {
363*9203SMark.Logan@Sun.COM 	return ATNetworkTool::ConnectSocket(addr->ai_addr, addr->ai_addrlen,
364*9203SMark.Logan@Sun.COM 					    error, loopback,
365*9203SMark.Logan@Sun.COM 					    addr->ai_family, addr->ai_socktype,
366*9203SMark.Logan@Sun.COM 					    addr->ai_protocol);
367*9203SMark.Logan@Sun.COM }
368*9203SMark.Logan@Sun.COM 
ConnectSocket(const struct sockaddr * addr,socklen_t addrlen,int & error,bool loopback,int family,int socktype,int protocol)369*9203SMark.Logan@Sun.COM int ATNetworkTool::ConnectSocket(const struct sockaddr *addr, socklen_t addrlen,
370*9203SMark.Logan@Sun.COM 				 int &error, bool loopback,
371*9203SMark.Logan@Sun.COM 				 int family, int socktype, int protocol)
372*9203SMark.Logan@Sun.COM {
373*9203SMark.Logan@Sun.COM 	struct addrinfo hints, *paddr, *paddrp;
374*9203SMark.Logan@Sun.COM 	int oks = -1;
375*9203SMark.Logan@Sun.COM 
376*9203SMark.Logan@Sun.COM 	memset(&hints, 0, sizeof(hints));
377*9203SMark.Logan@Sun.COM 	if (ATNetworkTool::AF_XINETX == family) {
378*9203SMark.Logan@Sun.COM 		hints.ai_family = PF_UNSPEC;
379*9203SMark.Logan@Sun.COM 	} else {
380*9203SMark.Logan@Sun.COM 		hints.ai_family = family;
381*9203SMark.Logan@Sun.COM 	}
382*9203SMark.Logan@Sun.COM 	hints.ai_socktype = socktype;
383*9203SMark.Logan@Sun.COM 	hints.ai_protocol = protocol;
384*9203SMark.Logan@Sun.COM #ifdef AI_NUMERICSERV
385*9203SMark.Logan@Sun.COM 	hints.ai_flags   |= AI_NUMERICSERV;
386*9203SMark.Logan@Sun.COM #endif
387*9203SMark.Logan@Sun.COM 	if (!loopback) {
388*9203SMark.Logan@Sun.COM 		hints.ai_flags |= AI_PASSIVE;
389*9203SMark.Logan@Sun.COM 	}
390*9203SMark.Logan@Sun.COM 	if ((error = getaddrinfo(NULL, "0", &hints, &paddrp)) != 0) {
391*9203SMark.Logan@Sun.COM 		return -1;
392*9203SMark.Logan@Sun.COM 	}
393*9203SMark.Logan@Sun.COM 	for (paddr = paddrp; paddr; paddr = paddr->ai_next) {
394*9203SMark.Logan@Sun.COM 		if (ATNetworkTool::AF_XINETX == family) {
395*9203SMark.Logan@Sun.COM 			if (!ATAddress::saIsInet(paddr->ai_addr)) {
396*9203SMark.Logan@Sun.COM 				continue;
397*9203SMark.Logan@Sun.COM 			}
398*9203SMark.Logan@Sun.COM 		}
399*9203SMark.Logan@Sun.COM 
400*9203SMark.Logan@Sun.COM 		int s = ATNetworkTool::CreateSocket(paddr, error);
401*9203SMark.Logan@Sun.COM 		if (s < 0) {
402*9203SMark.Logan@Sun.COM 			continue;
403*9203SMark.Logan@Sun.COM 		}
404*9203SMark.Logan@Sun.COM 
405*9203SMark.Logan@Sun.COM 		if (connect(s, addr, addrlen) != 0) {
406*9203SMark.Logan@Sun.COM 			error = errno;
407*9203SMark.Logan@Sun.COM 			ATNetworkTool::CloseSocket(s);
408*9203SMark.Logan@Sun.COM 			continue;
409*9203SMark.Logan@Sun.COM 		}
410*9203SMark.Logan@Sun.COM 
411*9203SMark.Logan@Sun.COM 		oks = s;
412*9203SMark.Logan@Sun.COM 		break;
413*9203SMark.Logan@Sun.COM 	}
414*9203SMark.Logan@Sun.COM 	freeaddrinfo(paddrp);
415*9203SMark.Logan@Sun.COM 	return oks;
416*9203SMark.Logan@Sun.COM }
417*9203SMark.Logan@Sun.COM 
CreateServerSocket(in_port_t port,int & error,bool loopback,bool nonblocking,int family,int socktype,int protocol,int backlog)418*9203SMark.Logan@Sun.COM int ATNetworkTool::CreateServerSocket(in_port_t port,
419*9203SMark.Logan@Sun.COM 					int &error,
420*9203SMark.Logan@Sun.COM 					bool loopback, bool nonblocking,
421*9203SMark.Logan@Sun.COM 					int family, int socktype, int protocol,
422*9203SMark.Logan@Sun.COM 					int backlog)
423*9203SMark.Logan@Sun.COM {
424*9203SMark.Logan@Sun.COM 	std::stringstream ssport;
425*9203SMark.Logan@Sun.COM 
426*9203SMark.Logan@Sun.COM 	ssport << port;
427*9203SMark.Logan@Sun.COM 	return ATNetworkTool::CreateServerSocket(ssport.str().c_str(),
428*9203SMark.Logan@Sun.COM 						 error,
429*9203SMark.Logan@Sun.COM 						 loopback, nonblocking,
430*9203SMark.Logan@Sun.COM 						 family, socktype, protocol,
431*9203SMark.Logan@Sun.COM 						 backlog);
432*9203SMark.Logan@Sun.COM }
433*9203SMark.Logan@Sun.COM 
CreateServerSocket(const char * port,int & error,bool loopback,bool nonblocking,int family,int socktype,int protocol,int backlog)434*9203SMark.Logan@Sun.COM int ATNetworkTool::CreateServerSocket(const char *port,
435*9203SMark.Logan@Sun.COM 					int &error,
436*9203SMark.Logan@Sun.COM 					bool loopback, bool nonblocking,
437*9203SMark.Logan@Sun.COM 					int family, int socktype, int protocol,
438*9203SMark.Logan@Sun.COM 					int backlog)
439*9203SMark.Logan@Sun.COM {
440*9203SMark.Logan@Sun.COM 	ATSocketList sockets;
441*9203SMark.Logan@Sun.COM 	int s = -1;
442*9203SMark.Logan@Sun.COM 
443*9203SMark.Logan@Sun.COM 	int num = ATNetworkTool::CreateServerSockets(sockets, port,
444*9203SMark.Logan@Sun.COM 						     error,
445*9203SMark.Logan@Sun.COM 						     loopback, nonblocking,
446*9203SMark.Logan@Sun.COM 						     family, socktype, protocol,
447*9203SMark.Logan@Sun.COM 						     backlog, true);
448*9203SMark.Logan@Sun.COM 	if ((num > 0) && (sockets.size() > 0)) {
449*9203SMark.Logan@Sun.COM 		s = sockets[0];
450*9203SMark.Logan@Sun.COM 	}
451*9203SMark.Logan@Sun.COM 	sockets.clear();
452*9203SMark.Logan@Sun.COM 	return s;
453*9203SMark.Logan@Sun.COM }
454*9203SMark.Logan@Sun.COM 
455*9203SMark.Logan@Sun.COM 
CreateServerSockets(ATSocketList & sockets,in_port_t port,int & error,bool loopback,bool nonblocking,int family,int socktype,int protocol,int backlog,bool one)456*9203SMark.Logan@Sun.COM int ATNetworkTool::CreateServerSockets(ATSocketList &sockets, in_port_t port,
457*9203SMark.Logan@Sun.COM 					int &error,
458*9203SMark.Logan@Sun.COM 					bool loopback, bool nonblocking,
459*9203SMark.Logan@Sun.COM 					int family, int socktype, int protocol,
460*9203SMark.Logan@Sun.COM 					int backlog, bool one)
461*9203SMark.Logan@Sun.COM {
462*9203SMark.Logan@Sun.COM 	std::stringstream ssport;
463*9203SMark.Logan@Sun.COM 
464*9203SMark.Logan@Sun.COM 	ssport << port;
465*9203SMark.Logan@Sun.COM 	return ATNetworkTool::CreateServerSockets(sockets, ssport.str().c_str(),
466*9203SMark.Logan@Sun.COM 						  error,
467*9203SMark.Logan@Sun.COM 						  loopback, nonblocking,
468*9203SMark.Logan@Sun.COM 						  family, socktype, protocol,
469*9203SMark.Logan@Sun.COM 						  backlog, one);
470*9203SMark.Logan@Sun.COM }
471*9203SMark.Logan@Sun.COM 
CreateServerSockets(ATSocketList & sockets,const char * port,int & error,bool loopback,bool nonblocking,int family,int socktype,int protocol,int backlog,bool one)472*9203SMark.Logan@Sun.COM int ATNetworkTool::CreateServerSockets(ATSocketList &sockets, const char *port,
473*9203SMark.Logan@Sun.COM 					int &error,
474*9203SMark.Logan@Sun.COM 					bool loopback, bool nonblocking,
475*9203SMark.Logan@Sun.COM 					int family, int socktype, int protocol,
476*9203SMark.Logan@Sun.COM 					int backlog, bool one)
477*9203SMark.Logan@Sun.COM {
478*9203SMark.Logan@Sun.COM 	struct addrinfo hints, *paddr, *paddrp;
479*9203SMark.Logan@Sun.COM 	int num = 0;
480*9203SMark.Logan@Sun.COM 
481*9203SMark.Logan@Sun.COM 	memset(&hints, 0, sizeof(hints));
482*9203SMark.Logan@Sun.COM 	if (ATNetworkTool::AF_XINETX == family) {
483*9203SMark.Logan@Sun.COM 		hints.ai_family = PF_UNSPEC;
484*9203SMark.Logan@Sun.COM 	} else {
485*9203SMark.Logan@Sun.COM 		hints.ai_family = family;
486*9203SMark.Logan@Sun.COM 	}
487*9203SMark.Logan@Sun.COM 	hints.ai_socktype = socktype;
488*9203SMark.Logan@Sun.COM 	hints.ai_protocol = protocol;
489*9203SMark.Logan@Sun.COM #ifdef AI_NUMERICSERV
490*9203SMark.Logan@Sun.COM 	hints.ai_flags   |= AI_NUMERICSERV;
491*9203SMark.Logan@Sun.COM #endif
492*9203SMark.Logan@Sun.COM 	if (!loopback) {
493*9203SMark.Logan@Sun.COM 		hints.ai_flags |= AI_PASSIVE;
494*9203SMark.Logan@Sun.COM 	}
495*9203SMark.Logan@Sun.COM 	if ((error = getaddrinfo(NULL, port, &hints, &paddrp)) != 0) {
496*9203SMark.Logan@Sun.COM 		return -1;
497*9203SMark.Logan@Sun.COM 	}
498*9203SMark.Logan@Sun.COM 	for (paddr = paddrp; paddr; paddr = paddr->ai_next) {
499*9203SMark.Logan@Sun.COM 		if (ATNetworkTool::AF_XINETX == family) {
500*9203SMark.Logan@Sun.COM 			if (!ATAddress::saIsInet(paddr->ai_addr)) {
501*9203SMark.Logan@Sun.COM 				continue;
502*9203SMark.Logan@Sun.COM 			}
503*9203SMark.Logan@Sun.COM 		}
504*9203SMark.Logan@Sun.COM 
505*9203SMark.Logan@Sun.COM 		int s = ATNetworkTool::CreateServerSocket(paddr, error,
506*9203SMark.Logan@Sun.COM 							  nonblocking,
507*9203SMark.Logan@Sun.COM 							  backlog);
508*9203SMark.Logan@Sun.COM 		if (s < 0) {
509*9203SMark.Logan@Sun.COM 			continue;
510*9203SMark.Logan@Sun.COM 		}
511*9203SMark.Logan@Sun.COM 		sockets.push_back(s);
512*9203SMark.Logan@Sun.COM 		num++;
513*9203SMark.Logan@Sun.COM 		if (one) {
514*9203SMark.Logan@Sun.COM 			break;
515*9203SMark.Logan@Sun.COM 		}
516*9203SMark.Logan@Sun.COM 	}
517*9203SMark.Logan@Sun.COM 	freeaddrinfo(paddrp);
518*9203SMark.Logan@Sun.COM 	return num;
519*9203SMark.Logan@Sun.COM }
520*9203SMark.Logan@Sun.COM 
CreateServerSocket(const struct addrinfo * addr,int & error,bool nonblocking,int backlog)521*9203SMark.Logan@Sun.COM int ATNetworkTool::CreateServerSocket(const struct addrinfo *addr, int &error,
522*9203SMark.Logan@Sun.COM 					bool nonblocking, int backlog)
523*9203SMark.Logan@Sun.COM {
524*9203SMark.Logan@Sun.COM 	int s = ATNetworkTool::CreateSocket(addr, error);
525*9203SMark.Logan@Sun.COM 	if (s < 0) {
526*9203SMark.Logan@Sun.COM 		return -1;
527*9203SMark.Logan@Sun.COM 	}
528*9203SMark.Logan@Sun.COM 
529*9203SMark.Logan@Sun.COM 	if (nonblocking) {
530*9203SMark.Logan@Sun.COM 		ATNetworkTool::SetNonBlocking(s);
531*9203SMark.Logan@Sun.COM 	}
532*9203SMark.Logan@Sun.COM 
533*9203SMark.Logan@Sun.COM 	if (listen(s, backlog) == -1) {
534*9203SMark.Logan@Sun.COM 		error = errno;
535*9203SMark.Logan@Sun.COM 		ATNetworkTool::CloseSocket(s);
536*9203SMark.Logan@Sun.COM 		return -1;
537*9203SMark.Logan@Sun.COM 	}
538*9203SMark.Logan@Sun.COM 
539*9203SMark.Logan@Sun.COM 	return s;
540*9203SMark.Logan@Sun.COM }
541*9203SMark.Logan@Sun.COM 
SetNonBlocking(int s,bool block)542*9203SMark.Logan@Sun.COM int ATNetworkTool::SetNonBlocking(int s, bool block)
543*9203SMark.Logan@Sun.COM {
544*9203SMark.Logan@Sun.COM 	if (block) {
545*9203SMark.Logan@Sun.COM 		return fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
546*9203SMark.Logan@Sun.COM 	} else {
547*9203SMark.Logan@Sun.COM 		return fcntl(s, F_SETFL, fcntl(s, F_GETFL) & ~O_NONBLOCK);
548*9203SMark.Logan@Sun.COM 	}
549*9203SMark.Logan@Sun.COM }
550*9203SMark.Logan@Sun.COM 
ConnectToSocket(int sock,int & error,bool loopback,int socktype,int protocol)551*9203SMark.Logan@Sun.COM int ATNetworkTool::ConnectToSocket(int sock, int &error, bool loopback,
552*9203SMark.Logan@Sun.COM 				    int socktype, int protocol)
553*9203SMark.Logan@Sun.COM {
554*9203SMark.Logan@Sun.COM 	struct sockaddr_storage ss;
555*9203SMark.Logan@Sun.COM 	socklen_t addrLen = sizeof(ss);
556*9203SMark.Logan@Sun.COM 	struct sockaddr *sa = (struct sockaddr *)&ss;
557*9203SMark.Logan@Sun.COM 
558*9203SMark.Logan@Sun.COM 	if (getsockname(sock, sa, &addrLen) != 0) {
559*9203SMark.Logan@Sun.COM 		error = errno;
560*9203SMark.Logan@Sun.COM 		return -1;
561*9203SMark.Logan@Sun.COM 	}
562*9203SMark.Logan@Sun.COM 	int s = ATNetworkTool::ConnectSocket(sa, addrLen,
563*9203SMark.Logan@Sun.COM 					     error, loopback,
564*9203SMark.Logan@Sun.COM 					     sa->sa_family,
565*9203SMark.Logan@Sun.COM 					     socktype, protocol);
566*9203SMark.Logan@Sun.COM 	if (s < 0) {
567*9203SMark.Logan@Sun.COM 		return -1;
568*9203SMark.Logan@Sun.COM 	}
569*9203SMark.Logan@Sun.COM 	return s;
570*9203SMark.Logan@Sun.COM }
571*9203SMark.Logan@Sun.COM 
Connect(const char * host,in_port_t port,int & error,int family,int socktype,int protocol)572*9203SMark.Logan@Sun.COM int ATNetworkTool::Connect(const char *host, in_port_t port,
573*9203SMark.Logan@Sun.COM 				int &error,
574*9203SMark.Logan@Sun.COM 				int family, int socktype, int protocol)
575*9203SMark.Logan@Sun.COM {
576*9203SMark.Logan@Sun.COM 	std::stringstream ssport;
577*9203SMark.Logan@Sun.COM 
578*9203SMark.Logan@Sun.COM 	ssport << port;
579*9203SMark.Logan@Sun.COM 
580*9203SMark.Logan@Sun.COM 	return ATNetworkTool::Connect(host, ssport.str().c_str(), error,
581*9203SMark.Logan@Sun.COM 					family, socktype, protocol);
582*9203SMark.Logan@Sun.COM }
583*9203SMark.Logan@Sun.COM 
Connect(const char * host,const char * port,int & error,int family,int socktype,int protocol)584*9203SMark.Logan@Sun.COM int ATNetworkTool::Connect(const char *host, const char *port,
585*9203SMark.Logan@Sun.COM 				int &error,
586*9203SMark.Logan@Sun.COM 				int family, int socktype, int protocol)
587*9203SMark.Logan@Sun.COM {
588*9203SMark.Logan@Sun.COM 	struct addrinfo hints, *paddr, *paddrp;
589*9203SMark.Logan@Sun.COM 	int oks = -1;
590*9203SMark.Logan@Sun.COM 
591*9203SMark.Logan@Sun.COM 	if (socktype != SOCK_DGRAM) {
592*9203SMark.Logan@Sun.COM 		socktype = SOCK_STREAM;
593*9203SMark.Logan@Sun.COM 	}
594*9203SMark.Logan@Sun.COM 
595*9203SMark.Logan@Sun.COM 	memset(&hints, 0, sizeof(hints));
596*9203SMark.Logan@Sun.COM 	if (ATNetworkTool::AF_XINETX == family) {
597*9203SMark.Logan@Sun.COM 		hints.ai_family = PF_UNSPEC;
598*9203SMark.Logan@Sun.COM 	} else {
599*9203SMark.Logan@Sun.COM 		hints.ai_family = family;
600*9203SMark.Logan@Sun.COM 	}
601*9203SMark.Logan@Sun.COM 	hints.ai_socktype = socktype;
602*9203SMark.Logan@Sun.COM 	hints.ai_protocol = protocol;
603*9203SMark.Logan@Sun.COM 	hints.ai_flags    = AI_NUMERICHOST;
604*9203SMark.Logan@Sun.COM #ifdef AI_NUMERICSERV
605*9203SMark.Logan@Sun.COM 	hints.ai_flags   |= AI_NUMERICSERV;
606*9203SMark.Logan@Sun.COM #endif
607*9203SMark.Logan@Sun.COM 	if ((error = getaddrinfo(host, port, &hints, &paddrp)) != 0) {
608*9203SMark.Logan@Sun.COM 		memset(&hints, 0, sizeof(hints));
609*9203SMark.Logan@Sun.COM 		if (ATNetworkTool::AF_XINETX == family) {
610*9203SMark.Logan@Sun.COM 			hints.ai_family = PF_UNSPEC;
611*9203SMark.Logan@Sun.COM 		} else {
612*9203SMark.Logan@Sun.COM 			hints.ai_family = family;
613*9203SMark.Logan@Sun.COM 		}
614*9203SMark.Logan@Sun.COM 		hints.ai_socktype = socktype;
615*9203SMark.Logan@Sun.COM 		hints.ai_protocol = protocol;
616*9203SMark.Logan@Sun.COM #ifdef AI_NUMERICSERV
617*9203SMark.Logan@Sun.COM 		hints.ai_flags   |= AI_NUMERICSERV;
618*9203SMark.Logan@Sun.COM #endif
619*9203SMark.Logan@Sun.COM 		if ((error = getaddrinfo(host, port, &hints, &paddrp)) != 0) {
620*9203SMark.Logan@Sun.COM 			return -1;
621*9203SMark.Logan@Sun.COM 		}
622*9203SMark.Logan@Sun.COM 	}
623*9203SMark.Logan@Sun.COM 	for (paddr = paddrp; paddr; paddr = paddr->ai_next) {
624*9203SMark.Logan@Sun.COM 		if (ATNetworkTool::AF_XINETX == family) {
625*9203SMark.Logan@Sun.COM 			if (!ATAddress::saIsInet(paddr->ai_addr)) {
626*9203SMark.Logan@Sun.COM 				continue;
627*9203SMark.Logan@Sun.COM 			}
628*9203SMark.Logan@Sun.COM 		}
629*9203SMark.Logan@Sun.COM 
630*9203SMark.Logan@Sun.COM 		int s = ATNetworkTool::ConnectSocket(paddr, error);
631*9203SMark.Logan@Sun.COM 		if (s < 0) {
632*9203SMark.Logan@Sun.COM 			continue;
633*9203SMark.Logan@Sun.COM 		}
634*9203SMark.Logan@Sun.COM 		oks = s;
635*9203SMark.Logan@Sun.COM 		break;
636*9203SMark.Logan@Sun.COM 	}
637*9203SMark.Logan@Sun.COM 	freeaddrinfo(paddrp);
638*9203SMark.Logan@Sun.COM 	return oks;
639*9203SMark.Logan@Sun.COM }
640*9203SMark.Logan@Sun.COM 
ConnectLoopback(in_port_t port,int & error,int family,int socktype,int protocol)641*9203SMark.Logan@Sun.COM int ATNetworkTool::ConnectLoopback(in_port_t port,
642*9203SMark.Logan@Sun.COM 				int &error,
643*9203SMark.Logan@Sun.COM 				int family, int socktype, int protocol)
644*9203SMark.Logan@Sun.COM {
645*9203SMark.Logan@Sun.COM 	std::stringstream ssport;
646*9203SMark.Logan@Sun.COM 
647*9203SMark.Logan@Sun.COM 	ssport << port;
648*9203SMark.Logan@Sun.COM 
649*9203SMark.Logan@Sun.COM 	return ATNetworkTool::ConnectLoopback(ssport.str().c_str(), error,
650*9203SMark.Logan@Sun.COM 					family, socktype, protocol);
651*9203SMark.Logan@Sun.COM }
652*9203SMark.Logan@Sun.COM 
ConnectLoopback(const char * port,int & error,int family,int socktype,int protocol)653*9203SMark.Logan@Sun.COM int ATNetworkTool::ConnectLoopback(const char *port,
654*9203SMark.Logan@Sun.COM 				int &error,
655*9203SMark.Logan@Sun.COM 				int family, int socktype, int protocol)
656*9203SMark.Logan@Sun.COM {
657*9203SMark.Logan@Sun.COM 	struct addrinfo hints, *paddr, *paddrp;
658*9203SMark.Logan@Sun.COM 	int oks = -1;
659*9203SMark.Logan@Sun.COM 
660*9203SMark.Logan@Sun.COM 	if (socktype != SOCK_DGRAM) {
661*9203SMark.Logan@Sun.COM 		socktype = SOCK_STREAM;
662*9203SMark.Logan@Sun.COM 	}
663*9203SMark.Logan@Sun.COM 
664*9203SMark.Logan@Sun.COM 	memset(&hints, 0, sizeof(hints));
665*9203SMark.Logan@Sun.COM 	if (ATNetworkTool::AF_XINETX == family) {
666*9203SMark.Logan@Sun.COM 		hints.ai_family = PF_UNSPEC;
667*9203SMark.Logan@Sun.COM 	} else {
668*9203SMark.Logan@Sun.COM 		hints.ai_family = family;
669*9203SMark.Logan@Sun.COM 	}
670*9203SMark.Logan@Sun.COM 	hints.ai_socktype = socktype;
671*9203SMark.Logan@Sun.COM 	hints.ai_protocol = protocol;
672*9203SMark.Logan@Sun.COM #ifdef AI_NUMERICSERV
673*9203SMark.Logan@Sun.COM 	hints.ai_flags   |= AI_NUMERICSERV;
674*9203SMark.Logan@Sun.COM #endif
675*9203SMark.Logan@Sun.COM 	if ((error = getaddrinfo(NULL, port, &hints, &paddrp)) != 0) {
676*9203SMark.Logan@Sun.COM 		return -1;
677*9203SMark.Logan@Sun.COM 	}
678*9203SMark.Logan@Sun.COM 	for (paddr = paddrp; paddr; paddr = paddr->ai_next) {
679*9203SMark.Logan@Sun.COM 		if (ATNetworkTool::AF_XINETX == family) {
680*9203SMark.Logan@Sun.COM 			if (!ATAddress::saIsInet(paddr->ai_addr)) {
681*9203SMark.Logan@Sun.COM 				continue;
682*9203SMark.Logan@Sun.COM 			}
683*9203SMark.Logan@Sun.COM 		}
684*9203SMark.Logan@Sun.COM 
685*9203SMark.Logan@Sun.COM 		int s = ATNetworkTool::ConnectSocket(paddr, error, true);
686*9203SMark.Logan@Sun.COM 		if (s < 0) {
687*9203SMark.Logan@Sun.COM 			continue;
688*9203SMark.Logan@Sun.COM 		}
689*9203SMark.Logan@Sun.COM 		oks = s;
690*9203SMark.Logan@Sun.COM 		break;
691*9203SMark.Logan@Sun.COM 	}
692*9203SMark.Logan@Sun.COM 	freeaddrinfo(paddrp);
693*9203SMark.Logan@Sun.COM 	return oks;
694*9203SMark.Logan@Sun.COM }
695*9203SMark.Logan@Sun.COM 
GetLocalPort(int sock)696*9203SMark.Logan@Sun.COM unsigned int ATNetworkTool::GetLocalPort(int sock)
697*9203SMark.Logan@Sun.COM {
698*9203SMark.Logan@Sun.COM 	struct sockaddr_storage ss;
699*9203SMark.Logan@Sun.COM 	socklen_t addrLen = sizeof(ss);
700*9203SMark.Logan@Sun.COM 	struct sockaddr *sa = (struct sockaddr *)&ss;
701*9203SMark.Logan@Sun.COM 
702*9203SMark.Logan@Sun.COM 	if (getsockname(sock, sa, &addrLen) != 0) {
703*9203SMark.Logan@Sun.COM 		return 0;
704*9203SMark.Logan@Sun.COM 	}
705*9203SMark.Logan@Sun.COM 	switch (sa->sa_family) {
706*9203SMark.Logan@Sun.COM 	case AF_INET6:
707*9203SMark.Logan@Sun.COM 		return ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
708*9203SMark.Logan@Sun.COM 		break;
709*9203SMark.Logan@Sun.COM 	case AF_INET:
710*9203SMark.Logan@Sun.COM 		return ntohs(((struct sockaddr_in *)sa)->sin_port);
711*9203SMark.Logan@Sun.COM 		break;
712*9203SMark.Logan@Sun.COM 	}
713*9203SMark.Logan@Sun.COM 	return 0;
714*9203SMark.Logan@Sun.COM }
715*9203SMark.Logan@Sun.COM 
Accept(int s,ATAddress & address,int & error,bool nonblocking)716*9203SMark.Logan@Sun.COM int ATNetworkTool::Accept(int s, ATAddress &address,
717*9203SMark.Logan@Sun.COM 			  int &error, bool nonblocking)
718*9203SMark.Logan@Sun.COM {
719*9203SMark.Logan@Sun.COM 	struct sockaddr_storage saddr;
720*9203SMark.Logan@Sun.COM 	socklen_t addrLen = sizeof(saddr);
721*9203SMark.Logan@Sun.COM 	struct sockaddr *addr = (struct sockaddr *)&saddr;
722*9203SMark.Logan@Sun.COM 
723*9203SMark.Logan@Sun.COM 	int s_new = accept(s, addr, &addrLen);
724*9203SMark.Logan@Sun.COM 	if (s_new == -1) {
725*9203SMark.Logan@Sun.COM 		error = errno;
726*9203SMark.Logan@Sun.COM 		return -1;
727*9203SMark.Logan@Sun.COM 	}
728*9203SMark.Logan@Sun.COM 
729*9203SMark.Logan@Sun.COM 	address = addr;
730*9203SMark.Logan@Sun.COM 
731*9203SMark.Logan@Sun.COM 	ATNetworkTool::SetNonBlocking(s_new, nonblocking);
732*9203SMark.Logan@Sun.COM 
733*9203SMark.Logan@Sun.COM 	return s_new;
734*9203SMark.Logan@Sun.COM }
735*9203SMark.Logan@Sun.COM 
736