1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2014 projectchrono.org
5 // All rights reserved.
6 //
7 // Use of this source code is governed by a BSD-style license that can be found
8 // in the LICENSE file at the top level of the distribution and at
9 // http://projectchrono.org/license-chrono.txt.
10 //
11 // =============================================================================
12 // Authors: Alessandro Tasora
13 // =============================================================================
14
15 #define _WINSOCK_DEPRECATED_NO_WARNINGS
16
17 #include "chrono_cosimulation/ChHostInfo.h"
18 #include "chrono_cosimulation/ChExceptionSocket.h"
19
20 namespace chrono {
21 namespace cosimul {
22
ChHostInfo()23 ChHostInfo::ChHostInfo() {
24 #ifdef UNIX
25 openHostDb();
26 // winLog<<"UNIX version ChHostInfo() is called...\n";
27 #endif
28
29 #ifdef WINDOWS_XP
30
31 char sName[HOST_NAME_LENGTH + 1];
32 memset(sName, 0, sizeof(sName));
33 gethostname(sName, HOST_NAME_LENGTH);
34
35 try {
36 hostPtr = gethostbyname(sName);
37 if (hostPtr == NULL) {
38 int errorCode;
39 std::string errorMsg = "";
40 detectErrorGethostbyname(&errorCode, errorMsg);
41 ChExceptionSocket* gethostbynameException = new ChExceptionSocket(errorCode, errorMsg);
42 throw gethostbynameException;
43 }
44 } catch (ChExceptionSocket* excp) {
45 excp->response();
46 exit(1);
47 }
48
49 #endif
50 }
51
ChHostInfo(const std::string & hostName,hostType type)52 ChHostInfo::ChHostInfo(const std::string& hostName, hostType type) {
53 #ifdef UNIX
54 searchHostDB = 0;
55 #endif
56
57 try {
58 if (type == NAME) {
59 // Retrieve host by name
60 hostPtr = gethostbyname(hostName.c_str());
61
62 if (hostPtr == NULL) {
63 #ifdef WINDOWS_XP
64 int errorCode;
65 std::string errorMsg = "";
66 detectErrorGethostbyname(&errorCode, errorMsg);
67 ChExceptionSocket* gethostbynameException = new ChExceptionSocket(errorCode, errorMsg);
68 throw gethostbynameException;
69 #endif
70
71 #ifdef UNIX
72 ChExceptionSocket* gethostbynameException =
73 new ChExceptionSocket(0, "unix: error getting host by name");
74 throw gethostbynameException;
75 #endif
76 }
77 } else if (type == ADDRESS) {
78 // Retrieve host by address
79 unsigned long netAddr = inet_addr(hostName.c_str());
80 if (netAddr == -1) {
81 ChExceptionSocket* inet_addrException = new ChExceptionSocket(0, "Error calling inet_addr()");
82 throw inet_addrException;
83 }
84
85 hostPtr = gethostbyaddr((char*)&netAddr, sizeof(netAddr), AF_INET);
86 if (hostPtr == NULL) {
87 #ifdef WINDOWS_XP
88 int errorCode;
89 std::string errorMsg = "";
90 detectErrorGethostbyaddr(&errorCode, errorMsg);
91 ChExceptionSocket* gethostbyaddrException = new ChExceptionSocket(errorCode, errorMsg);
92 throw gethostbyaddrException;
93 #endif
94
95 #ifdef UNIX
96 ChExceptionSocket* gethostbynameException =
97 new ChExceptionSocket(0, "unix: error getting host by name");
98 throw gethostbynameException;
99 #endif
100 }
101 } else {
102 ChExceptionSocket* unknownTypeException =
103 new ChExceptionSocket(0, "unknown host type: host name/address has to be given ");
104 throw unknownTypeException;
105 }
106 } catch (ChExceptionSocket* excp) {
107 excp->response();
108 exit(1);
109 }
110 }
111
getHostIPAddress()112 char* ChHostInfo::getHostIPAddress() {
113 struct in_addr* addr_ptr;
114 // the first address in the list of host addresses
115 addr_ptr = (struct in_addr*)*hostPtr->h_addr_list;
116 // changed the address format to the Internet address in standard dot notation
117 return inet_ntoa(*addr_ptr);
118 }
119
120 #ifdef WINDOWS_XP
detectErrorGethostbyname(int * errCode,std::string & errorMsg)121 void ChHostInfo::detectErrorGethostbyname(int* errCode, std::string& errorMsg) {
122 *errCode = WSAGetLastError();
123
124 if (*errCode == WSANOTINITIALISED)
125 errorMsg.append("need to call WSAStartup to initialize socket system on Window system.");
126 else if (*errCode == WSAENETDOWN)
127 errorMsg.append("The network subsystem has failed.");
128 else if (*errCode == WSAHOST_NOT_FOUND)
129 errorMsg.append("Authoritative Answer Host not found.");
130 else if (*errCode == WSATRY_AGAIN)
131 errorMsg.append("Non-Authoritative Host not found, or server failure.");
132 else if (*errCode == WSANO_RECOVERY)
133 errorMsg.append("Nonrecoverable error occurred.");
134 else if (*errCode == WSANO_DATA)
135 errorMsg.append("Valid name, no data record of requested type.");
136 else if (*errCode == WSAEINPROGRESS)
137 errorMsg.append(
138 "A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a "
139 "callback function.");
140 else if (*errCode == WSAEFAULT)
141 errorMsg.append("The name parameter is not a valid part of the user address space.");
142 else if (*errCode == WSAEINTR)
143 errorMsg.append("A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.");
144 }
145 #endif
146
147 #ifdef WINDOWS_XP
detectErrorGethostbyaddr(int * errCode,std::string & errorMsg)148 void ChHostInfo::detectErrorGethostbyaddr(int* errCode, std::string& errorMsg) {
149 *errCode = WSAGetLastError();
150
151 if (*errCode == WSANOTINITIALISED)
152 errorMsg.append("A successful WSAStartup must occur before using this function.");
153 if (*errCode == WSAENETDOWN)
154 errorMsg.append("The network subsystem has failed.");
155 if (*errCode == WSAHOST_NOT_FOUND)
156 errorMsg.append("Authoritative Answer Host not found.");
157 if (*errCode == WSATRY_AGAIN)
158 errorMsg.append("Non-Authoritative Host not found, or server failed.");
159 if (*errCode == WSANO_RECOVERY)
160 errorMsg.append("Nonrecoverable error occurred.");
161 if (*errCode == WSANO_DATA)
162 errorMsg.append("Valid name, no data record of requested type.");
163 if (*errCode == WSAEINPROGRESS)
164 errorMsg.append(
165 "A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a "
166 "callback function.");
167 if (*errCode == WSAEAFNOSUPPORT)
168 errorMsg.append("The type specified is not supported by the Windows Sockets implementation.");
169 if (*errCode == WSAEFAULT)
170 errorMsg.append(
171 "The addr parameter is not a valid part of the user address space, or the len parameter is too small.");
172 if (*errCode == WSAEINTR)
173 errorMsg.append("A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.");
174 }
175 #endif
176
177 #ifdef UNIX
getNextHost()178 char ChHostInfo::getNextHost() {
179 // winLog<<"UNIX getNextHost() is called...\n";
180 // Get the next host from the database
181 if (searchHostDB == 1) {
182 if ((hostPtr = gethostent()) == NULL)
183 return 0;
184 else
185 return 1;
186 }
187 return 0;
188 }
189 #endif
190
191 } // end namespace cosimul
192 } // end namespace chrono
193