1 #include "otsdaq/NetworkUtilities/NetworkDevice.h"
2 #include "otsdaq/Macros/CoutMacros.h"
3 #include "otsdaq/MessageFacility/MessageFacility.h"
10 #include <arpa/inet.h>
15 #include <sys/ioctl.h>
16 #if defined(SIOCGIFHWADDR)
19 #include <net/if_dl.h>
28 NetworkDevice::NetworkDevice(std::string IPAddress,
unsigned int IPPort) : communicationInterface_(NULL)
31 deviceAddress_.sin_family = AF_INET;
32 deviceAddress_.sin_port = htons(IPPort);
34 if(inet_aton(IPAddress.c_str(), &deviceAddress_.sin_addr) == 0)
36 __COUT__ <<
"FATAL: Invalid IP address " << IPAddress << std::endl;
38 __SS__ <<
"Error!" << __E__;
42 memset(&(deviceAddress_.sin_zero),
'\0', 8);
46 NetworkDevice::~NetworkDevice(
void)
48 for(std::map<int, int>::iterator it = openSockets_.begin(); it != openSockets_.end(); it++)
50 __COUT__ <<
"Closing socket for port " << it->second << std::endl;
57 int NetworkDevice::initSocket(std::string socketPort)
59 struct addrinfo hints;
66 memset(&hints, 0,
sizeof hints);
67 hints.ai_family = AF_INET;
68 hints.ai_socktype = SOCK_DGRAM;
69 hints.ai_flags = AI_PASSIVE;
71 bool socketInitialized =
false;
72 int fromPort = FirstSocketPort;
73 int toPort = LastSocketPort;
76 fromPort = toPort = strtol(socketPort.c_str(), 0, 10);
78 std::stringstream port;
80 for(
int p = fromPort; p <= toPort && !socketInitialized; p++)
84 __COUT__ <<
"Binding port: " << port.str() << std::endl;
86 if((status = getaddrinfo(NULL, port.str().c_str(), &hints, &res)) != 0)
88 __COUT__ <<
"Getaddrinfo error status: " << status << std::endl;
93 socketOut = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
96 if(bind(socketOut, res->ai_addr, res->ai_addrlen) == -1)
98 __COUT_ERR__ <<
"Failed bind for port: " << port.str();
105 setsockopt(socketOut, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(
int));
106 socketInitialized =
true;
107 openSockets_[socketOut] = p;
108 __COUT__ <<
"Socket Number: " << socketOut <<
" for port: " << p <<
" initialized." << std::endl;
118 int NetworkDevice::initSocket(
unsigned int socketPort)
120 std::stringstream socket(
"");
122 socket << socketPort;
123 return initSocket(socket.str());
127 int NetworkDevice::send(
int socketDescriptor,
const std::string& buffer)
129 if(sendto(socketDescriptor, buffer.c_str(), buffer.size(), 0, (
struct sockaddr*)&(deviceAddress_),
sizeof(deviceAddress_)) < (int)(buffer.size()))
131 __COUT__ <<
"Error writing buffer" << std::endl;
138 int NetworkDevice::receive(
int socketDescriptor, std::string& buffer)
143 fd_set fileDescriptor;
144 FD_ZERO(&fileDescriptor);
145 FD_SET(socketDescriptor, &fileDescriptor);
146 select(socketDescriptor + 1, &fileDescriptor, 0, 0, &tv);
148 if(FD_ISSET(socketDescriptor, &fileDescriptor))
151 struct sockaddr_in tmpAddress;
152 socklen_t addressLength =
sizeof(tmpAddress);
154 char readBuffer[maxSocketSize];
155 if((nOfBytes = recvfrom(socketDescriptor, readBuffer, maxSocketSize, 0, (
struct sockaddr*)&tmpAddress, &addressLength)) == -1)
157 __COUT__ <<
"Error reading buffer" << std::endl;
160 buffer.resize(nOfBytes);
161 for(
int i = 0; i < nOfBytes; i++)
162 buffer[i] = readBuffer[i];
166 __COUT__ <<
"Network device unresponsive. Read request timed out." << std::endl;
174 int NetworkDevice::listen(
int socketDescriptor, std::string& buffer)
176 __COUT__ <<
"LISTENING!!!!!" << std::endl;
180 fd_set fileDescriptor;
181 FD_ZERO(&fileDescriptor);
182 FD_SET(socketDescriptor, &fileDescriptor);
183 select(socketDescriptor + 1, &fileDescriptor, 0, 0, &tv);
185 if(FD_ISSET(socketDescriptor, &fileDescriptor))
188 struct sockaddr_in tmpAddress;
189 socklen_t addressLength =
sizeof(tmpAddress);
191 char readBuffer[maxSocketSize];
192 if((nOfBytes = recvfrom(socketDescriptor, readBuffer, maxSocketSize, 0, (
struct sockaddr*)&tmpAddress, &addressLength)) == -1)
194 __COUT__ <<
"Error reading buffer" << std::endl;
197 buffer.resize(nOfBytes);
198 for(
int i = 0; i < nOfBytes; i++)
199 buffer[i] = readBuffer[i];
203 __COUT__ <<
"Timed out" << std::endl;
211 int NetworkDevice::ping(
int socketDescriptor)
213 std::string pingMsg(1, 0);
214 if(send(socketDescriptor, pingMsg) == -1)
216 __COUT__ <<
"Can't send ping Message!" << std::endl;
221 if(receive(socketDescriptor, bufferS) == -1)
223 __COUT__ <<
"Failed to ping device" << std::endl;
254 std::string NetworkDevice::getFullIPAddress(std::string partialIpAddress)
256 __COUT__ <<
"partial IP: " << partialIpAddress << std::endl;
257 if(getInterface(partialIpAddress))
260 p = inet_ntoa(((
struct sockaddr_in*)(communicationInterface_->ifa_addr))->sin_addr);
261 strncpy(addr, p,
sizeof(addr) - 1);
262 addr[
sizeof(addr) - 1] =
'\0';
268 __COUT__ <<
"FIXME substitute with try catch solution !!\n\nFailed to locate "
269 "network interface matching partial IP address"
272 __SS__ <<
"Error!" << __E__;
282 std::string NetworkDevice::getInterfaceName(std::string ipAddress)
284 __COUT__ <<
"IP: " << ipAddress << std::endl;
285 if(getInterface(ipAddress))
286 return communicationInterface_->ifa_name;
290 __COUT__ <<
"FIXME substitute with try catch solution !!\n\nFailed to get "
293 __SS__ <<
"Error!" << __E__;
296 __COUT__ <<
"Failed to get interface name for IP address" << std::endl;
302 int NetworkDevice::getInterface(std::string ipAddress)
305 char host[NI_MAXHOST];
307 __COUT__ <<
"IP2: " << ipAddress << std::endl;
308 if(communicationInterface_ != 0)
310 s = getnameinfo(communicationInterface_->ifa_addr,
312 (communicationInterface_->ifa_addr->sa_family == AF_INET) ?
sizeof(
struct sockaddr_in) :
314 sizeof(
struct sockaddr_in6),
323 __COUT__ <<
"getnameinfo() failed: " << gai_strerror(s) << std::endl;
325 __COUT__ <<
"FIXME substitute with try catch solution !!\n\nFailed to get "
328 __SS__ <<
"Error!" << __E__;
332 if(std::string(host).find(ipAddress) != std::string::npos)
336 delete communicationInterface_;
337 communicationInterface_ = NULL;
341 struct ifaddrs* ifaddr;
345 if(getifaddrs(&ifaddr) == -1)
347 perror(
"getifaddrs");
349 __COUT__ <<
"FIXME substitute with try catch solution !!\n\nFailed to get ifaddress!" << std::endl;
350 __SS__ <<
"Error!" << __E__;
359 for(ifa = ifaddr; ifa != NULL && !found; ifa = ifa->ifa_next)
361 if(ifa->ifa_addr == NULL)
364 family = ifa->ifa_addr->sa_family;
368 if(family == AF_INET || family == AF_INET6)
370 s = getnameinfo(ifa->ifa_addr,
372 (family == AF_INET) ?
sizeof(
struct sockaddr_in) :
374 sizeof(
struct sockaddr_in6),
383 __COUT__ <<
"getnameinfo() failed: " << gai_strerror(s) << std::endl;
385 __COUT__ <<
"FIXME substitute with try catch solution !!\n\nFailed to "
388 __SS__ <<
"Error!" << __E__;
392 if(std::string(host).find(ipAddress) != std::string::npos)
394 communicationInterface_ =
new struct ifaddrs(*ifa);
406 std::string NetworkDevice::getMacAddress(std::string interfaceName)
408 std::string macAddress(6,
'0');
409 #if defined(SIOCGIFHWADDR)
414 sock = socket(PF_INET, SOCK_STREAM, 0);
422 strncpy(ifr.ifr_name, interfaceName.c_str(),
sizeof(ifr.ifr_name) - 1);
423 ifr.ifr_name[
sizeof(ifr.ifr_name) - 1] =
'\0';
425 if(-1 == ioctl(sock, SIOCGIFHWADDR, &ifr))
427 perror(
"ioctl(SIOCGIFHWADDR) ");
430 for(
int j = 0; j < 6; j++)
431 macAddress[j] = ifr.ifr_hwaddr.sa_data[j];
437 if(getifaddrs(&iflist) == 0)
439 for(ifaddrs* cur = iflist; cur; cur = cur->ifa_next)
441 if((cur->ifa_addr->sa_family == AF_LINK) && (strcmp(cur->ifa_name, interfaceName.c_str()) == 0) && cur->ifa_addr)
443 sockaddr_dl* sdl = (sockaddr_dl*)cur->ifa_addr;
444 memcpy(mac, LLADDR(sdl), sdl->sdl_alen);
452 for(
int j = 0; j < 6; j++)
453 macAddress[j] = mac[j];