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)
29 : communicationInterface_(NULL)
32 deviceAddress_.sin_family = AF_INET;
33 deviceAddress_.sin_port = htons(IPPort);
35 if(inet_aton(IPAddress.c_str(), &deviceAddress_.sin_addr) == 0)
37 __COUT__ <<
"FATAL: Invalid IP address " << IPAddress << std::endl;
39 __SS__ <<
"Error!" << __E__;
43 memset(&(deviceAddress_.sin_zero),
'\0', 8);
47 NetworkDevice::~NetworkDevice(
void)
52 __COUT__ <<
"Closing socket for port " << it->second << std::endl;
59 int NetworkDevice::initSocket(std::string socketPort)
61 struct addrinfo hints;
68 memset(&hints, 0,
sizeof hints);
69 hints.ai_family = AF_INET;
70 hints.ai_socktype = SOCK_DGRAM;
71 hints.ai_flags = AI_PASSIVE;
73 bool socketInitialized =
false;
74 int fromPort = FirstSocketPort;
75 int toPort = LastSocketPort;
78 fromPort = toPort = strtol(socketPort.c_str(), 0, 10);
80 std::stringstream port;
82 for(
int p = fromPort; p <= toPort && !socketInitialized; p++)
86 __COUT__ <<
"Binding port: " << port.str() << std::endl;
88 if((status = getaddrinfo(NULL, port.str().c_str(), &hints, &res)) != 0)
90 __COUT__ <<
"Getaddrinfo error status: " << status << std::endl;
95 socketOut = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
98 if(bind(socketOut, res->ai_addr, res->ai_addrlen) == -1)
100 __COUT_ERR__ <<
"Failed bind for port: " << port.str();
107 setsockopt(socketOut, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(
int));
108 socketInitialized =
true;
110 __COUT__ <<
"Socket Number: " << socketOut <<
" for port: " << p
111 <<
" initialized." << std::endl;
121 int NetworkDevice::initSocket(
unsigned int socketPort)
123 std::stringstream socket(
"");
125 socket << socketPort;
126 return initSocket(socket.str());
130 int NetworkDevice::send(
int socketDescriptor,
const std::string& buffer)
132 if(sendto(socketDescriptor,
136 (
struct sockaddr*)&(deviceAddress_),
137 sizeof(deviceAddress_)) < (
int)(buffer.size()))
139 __COUT__ <<
"Error writing buffer" << std::endl;
146 int NetworkDevice::receive(
int socketDescriptor, std::string& buffer)
151 fd_set fileDescriptor;
152 FD_ZERO(&fileDescriptor);
153 FD_SET(socketDescriptor, &fileDescriptor);
154 select(socketDescriptor + 1, &fileDescriptor, 0, 0, &tv);
156 if(FD_ISSET(socketDescriptor, &fileDescriptor))
159 struct sockaddr_in tmpAddress;
160 socklen_t addressLength =
sizeof(tmpAddress);
162 char readBuffer[maxSocketSize];
163 if((nOfBytes = recvfrom(socketDescriptor,
167 (
struct sockaddr*)&tmpAddress,
168 &addressLength)) == -1)
170 __COUT__ <<
"Error reading buffer" << std::endl;
173 buffer.resize(nOfBytes);
174 for(
int i = 0; i < nOfBytes; i++)
175 buffer[i] = readBuffer[i];
179 __COUT__ <<
"Network device unresponsive. Read request timed out." << std::endl;
187 int NetworkDevice::listen(
int socketDescriptor, std::string& buffer)
189 __COUT__ <<
"LISTENING!!!!!" << std::endl;
193 fd_set fileDescriptor;
194 FD_ZERO(&fileDescriptor);
195 FD_SET(socketDescriptor, &fileDescriptor);
196 select(socketDescriptor + 1, &fileDescriptor, 0, 0, &tv);
198 if(FD_ISSET(socketDescriptor, &fileDescriptor))
201 struct sockaddr_in tmpAddress;
202 socklen_t addressLength =
sizeof(tmpAddress);
204 char readBuffer[maxSocketSize];
205 if((nOfBytes = recvfrom(socketDescriptor,
209 (
struct sockaddr*)&tmpAddress,
210 &addressLength)) == -1)
212 __COUT__ <<
"Error reading buffer" << std::endl;
215 buffer.resize(nOfBytes);
216 for(
int i = 0; i < nOfBytes; i++)
217 buffer[i] = readBuffer[i];
221 __COUT__ <<
"Timed out" << std::endl;
229 int NetworkDevice::ping(
int socketDescriptor)
231 std::string pingMsg(1, 0);
232 if(send(socketDescriptor, pingMsg) == -1)
234 __COUT__ <<
"Can't send ping Message!" << std::endl;
239 if(receive(socketDescriptor, bufferS) == -1)
241 __COUT__ <<
"Failed to ping device" << std::endl;
272 std::string NetworkDevice::getFullIPAddress(std::string partialIpAddress)
274 __COUT__ <<
"partial IP: " << partialIpAddress << std::endl;
275 if(getInterface(partialIpAddress))
279 ((
struct sockaddr_in*)(communicationInterface_->ifa_addr))->sin_addr);
280 strncpy(addr, p,
sizeof(addr) - 1);
281 addr[
sizeof(addr) - 1] =
'\0';
287 __COUT__ <<
"FIXME substitute with try catch solution !!\n\nFailed to locate "
288 "network interface matching partial IP address"
291 __SS__ <<
"Error!" << __E__;
301 std::string NetworkDevice::getInterfaceName(std::string ipAddress)
303 __COUT__ <<
"IP: " << ipAddress << std::endl;
304 if(getInterface(ipAddress))
305 return communicationInterface_->ifa_name;
309 __COUT__ <<
"FIXME substitute with try catch solution !!\n\nFailed to get "
312 __SS__ <<
"Error!" << __E__;
315 __COUT__ <<
"Failed to get interface name for IP address" << std::endl;
321 int NetworkDevice::getInterface(std::string ipAddress)
324 char host[NI_MAXHOST];
326 __COUT__ <<
"IP2: " << ipAddress << std::endl;
327 if(communicationInterface_ != 0)
329 s = getnameinfo(communicationInterface_->ifa_addr,
331 (communicationInterface_->ifa_addr->sa_family == AF_INET)
332 ?
sizeof(
struct sockaddr_in)
335 sizeof(
struct sockaddr_in6),
344 __COUT__ <<
"getnameinfo() failed: " << gai_strerror(s) << std::endl;
346 __COUT__ <<
"FIXME substitute with try catch solution !!\n\nFailed to get "
349 __SS__ <<
"Error!" << __E__;
353 if(std::string(host).find(ipAddress) != std::string::npos)
357 delete communicationInterface_;
358 communicationInterface_ = NULL;
362 struct ifaddrs* ifaddr;
366 if(getifaddrs(&ifaddr) == -1)
368 perror(
"getifaddrs");
371 <<
"FIXME substitute with try catch solution !!\n\nFailed to get ifaddress!"
373 __SS__ <<
"Error!" << __E__;
382 for(ifa = ifaddr; ifa != NULL && !found; ifa = ifa->ifa_next)
384 if(ifa->ifa_addr == NULL)
387 family = ifa->ifa_addr->sa_family;
391 if(family == AF_INET || family == AF_INET6)
393 s = getnameinfo(ifa->ifa_addr,
395 (family == AF_INET) ?
sizeof(
struct sockaddr_in) :
397 sizeof(
struct sockaddr_in6),
406 __COUT__ <<
"getnameinfo() failed: " << gai_strerror(s) << std::endl;
408 __COUT__ <<
"FIXME substitute with try catch solution !!\n\nFailed to "
411 __SS__ <<
"Error!" << __E__;
415 if(std::string(host).find(ipAddress) != std::string::npos)
417 communicationInterface_ =
new struct ifaddrs(*ifa);
429 std::string NetworkDevice::getMacAddress(std::string interfaceName)
431 std::string macAddress(6,
'0');
432 #if defined(SIOCGIFHWADDR)
437 sock = socket(PF_INET, SOCK_STREAM, 0);
445 strncpy(ifr.ifr_name, interfaceName.c_str(),
sizeof(ifr.ifr_name) - 1);
446 ifr.ifr_name[
sizeof(ifr.ifr_name) - 1] =
'\0';
448 if(-1 == ioctl(sock, SIOCGIFHWADDR, &ifr))
450 perror(
"ioctl(SIOCGIFHWADDR) ");
453 for(
int j = 0; j < 6; j++)
454 macAddress[j] = ifr.ifr_hwaddr.sa_data[j];
460 if(getifaddrs(&iflist) == 0)
462 for(ifaddrs* cur = iflist; cur; cur = cur->ifa_next)
464 if((cur->ifa_addr->sa_family == AF_LINK) &&
465 (strcmp(cur->ifa_name, interfaceName.c_str()) == 0) && cur->ifa_addr)
467 sockaddr_dl* sdl = (sockaddr_dl*)cur->ifa_addr;
468 memcpy(mac, LLADDR(sdl), sdl->sdl_alen);
476 for(
int j = 0; j < 6; j++)
477 macAddress[j] = mac[j];
std::map< int, int > openSockets_
socket,socket port