1 #include "otsdaq-core/NetworkUtilities/NetworkDevice.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutMacros.h"
11 #include <arpa/inet.h>
15 #include <sys/ioctl.h>
16 #if defined(SIOCGIFHWADDR)
19 #include <net/if_dl.h>
30 NetworkDevice::NetworkDevice(std::string IPAddress,
unsigned int IPPort) : communicationInterface_(NULL)
33 deviceAddress_.sin_family = AF_INET;
34 deviceAddress_.sin_port = htons(IPPort);
36 if(inet_aton(IPAddress.c_str(), &deviceAddress_.sin_addr) == 0)
38 std::cout << __COUT_HDR_FL__ << __LINE__ <<
"FATAL: Invalid IP address " << IPAddress << std::endl;
43 memset(&(deviceAddress_.sin_zero),
'\0', 8);
47 NetworkDevice::~NetworkDevice(
void)
49 for(std::map<int,int>::iterator it=openSockets_.begin(); it!=openSockets_.end(); it++)
51 std::cout << __COUT_HDR_FL__ <<
"Closing socket for port " << it->second << std::endl;
58 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 std::cout << __COUT_HDR_FL__ << __LINE__ <<
"]\tBinding port: " << port.str() << std::endl;
88 if((status = getaddrinfo(NULL, port.str().c_str(), &hints, &res)) != 0)
90 std::cout << __COUT_HDR_FL__ << __LINE__ <<
"]\tGetaddrinfo 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 mf::LogError(
"NetworkDevice") << __LINE__ <<
"]\tFailed bind for port: " << port.str();
107 setsockopt(socketOut,SOL_SOCKET,SO_REUSEADDR,&yes,
sizeof(
int));
108 socketInitialized =
true;
109 openSockets_[socketOut] = p;
110 std::cout << __COUT_HDR_FL__ << __LINE__ <<
"]\tSocket Number: " << socketOut <<
" for port: " << p <<
" initialized." << std::endl;
120 int NetworkDevice::initSocket(
unsigned int socketPort)
122 std::stringstream socket(
"");
124 socket << socketPort;
125 return initSocket(socket.str());
129 int NetworkDevice::send(
int socketDescriptor,
const std::string& buffer)
131 if(sendto(socketDescriptor,buffer.c_str(),buffer.size(),0,(
struct sockaddr *)&(deviceAddress_),
sizeof(deviceAddress_)) < (int)(buffer.size()))
133 std::cout << __COUT_HDR_FL__ <<
"Error writing buffer" << std::endl;
140 int NetworkDevice::receive(
int socketDescriptor, std::string& buffer)
145 fd_set fileDescriptor;
146 FD_ZERO(&fileDescriptor);
147 FD_SET(socketDescriptor,&fileDescriptor);
148 select(socketDescriptor+1, &fileDescriptor, 0, 0, &tv);
150 if(FD_ISSET(socketDescriptor,&fileDescriptor))
153 struct sockaddr_in tmpAddress;
154 socklen_t addressLength =
sizeof(tmpAddress);
156 char readBuffer[maxSocketSize];
157 if ((nOfBytes=recvfrom(socketDescriptor, readBuffer, maxSocketSize, 0, (
struct sockaddr *)&tmpAddress, &addressLength)) == -1)
159 std::cout << __COUT_HDR_FL__ << __LINE__ <<
"Error reading buffer" << std::endl;
162 buffer.resize(nOfBytes);
163 for(
int i=0; i<nOfBytes; i++)
164 buffer[i] = readBuffer[i];
168 std::cout << __COUT_HDR_FL__ << __LINE__ <<
"]\tNetwork device unresponsive. Read request timed out." << std::endl;
176 int NetworkDevice::listen(
int socketDescriptor, std::string& buffer)
178 std::cout << __COUT_HDR_FL__ <<
"LISTENING!!!!!" << std::endl;
182 fd_set fileDescriptor;
183 FD_ZERO(&fileDescriptor);
184 FD_SET(socketDescriptor,&fileDescriptor);
185 select(socketDescriptor+1, &fileDescriptor, 0, 0, &tv);
187 if(FD_ISSET(socketDescriptor,&fileDescriptor))
190 struct sockaddr_in tmpAddress;
191 socklen_t addressLength =
sizeof(tmpAddress);
193 char readBuffer[maxSocketSize];
194 if ((nOfBytes=recvfrom(socketDescriptor, readBuffer, maxSocketSize, 0, (
struct sockaddr *)&tmpAddress, &addressLength)) == -1)
196 std::cout << __COUT_HDR_FL__ << __LINE__ <<
"Error reading buffer" << std::endl;
199 buffer.resize(nOfBytes);
200 for(
int i=0; i<nOfBytes; i++)
201 buffer[i] = readBuffer[i];
205 std::cout << __COUT_HDR_FL__ << __LINE__ <<
"Timed out" << std::endl;
213 int NetworkDevice::ping(
int socketDescriptor)
215 std::string pingMsg(1,0);
216 if(send(socketDescriptor, pingMsg) == -1)
218 std::cout << __COUT_HDR_FL__ << __LINE__ <<
"]\tCan't send ping Message!" << std::endl;
223 if(receive(socketDescriptor,bufferS) == -1)
225 std::cout << __COUT_HDR_FL__ << __LINE__ <<
"]\tFailed to ping device"<< std::endl;
256 std::string NetworkDevice::getFullIPAddress(std::string partialIpAddress)
258 std::cout << __COUT_HDR_FL__ <<
"partial IP: " << partialIpAddress << std::endl;
259 if(getInterface(partialIpAddress))
262 p=inet_ntoa(((
struct sockaddr_in *)(communicationInterface_->ifa_addr))->sin_addr);
263 strncpy(addr,p,
sizeof(addr)-1);
264 addr[
sizeof(addr)-1]=
'\0';
270 std::cout << __COUT_HDR_FL__ <<
"FIXME substitute with try catch solution !!\n\nFailed to locate network interface matching partial IP address" << std::endl;
280 std::string NetworkDevice::getInterfaceName(std::string ipAddress)
282 std::cout << __COUT_HDR_FL__ <<
"IP: " << ipAddress << std::endl;
283 if(getInterface(ipAddress))
284 return communicationInterface_->ifa_name;
288 std::cout << __COUT_HDR_FL__ <<
"FIXME substitute with try catch solution !!\n\nFailed to get interface name!" << std::endl;
291 std::cout << __COUT_HDR_FL__ <<
"Failed to get interface name for IP address" << std::endl;
297 int NetworkDevice::getInterface(std::string ipAddress)
300 char host[NI_MAXHOST];
303 std::cout << __COUT_HDR_FL__ <<
"IP2: " << ipAddress << std::endl;
304 if(communicationInterface_ != 0)
306 s = getnameinfo(communicationInterface_->ifa_addr,
308 (communicationInterface_->ifa_addr->sa_family == AF_INET) ?
sizeof(
struct sockaddr_in) :
310 sizeof(
struct sockaddr_in6),
311 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
315 std::cout << __COUT_HDR_FL__ <<
"getnameinfo() failed: " << gai_strerror(s) << std::endl;
317 std::cout << __COUT_HDR_FL__ <<
"FIXME substitute with try catch solution !!\n\nFailed to get name info!" << std::endl;
321 if (std::string(host).find(ipAddress) != std::string::npos)
325 delete communicationInterface_;
326 communicationInterface_ = NULL;
330 struct ifaddrs* ifaddr;
334 if (getifaddrs(&ifaddr) == -1)
336 perror(
"getifaddrs");
338 std::cout << __COUT_HDR_FL__ <<
"FIXME substitute with try catch solution !!\n\nFailed to get ifaddress!" << std::endl;
347 for (ifa = ifaddr; ifa != NULL && !found; ifa = ifa->ifa_next)
349 if (ifa->ifa_addr == NULL)
352 family = ifa->ifa_addr->sa_family;
356 if (family == AF_INET || family == AF_INET6)
358 s = getnameinfo(ifa->ifa_addr,
360 (family == AF_INET) ?
sizeof(
struct sockaddr_in) :
362 sizeof(
struct sockaddr_in6),
363 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
367 std::cout << __COUT_HDR_FL__ <<
"getnameinfo() failed: " << gai_strerror(s) << std::endl;
369 std::cout << __COUT_HDR_FL__ <<
"FIXME substitute with try catch solution !!\n\nFailed to get getnameinfo!" << std::endl;
373 if (std::string(host).find(ipAddress) != std::string::npos)
375 communicationInterface_ =
new struct ifaddrs(*ifa);
387 std::string NetworkDevice::getMacAddress(std::string interfaceName)
390 std::string macAddress(6,
'0');
391 #if defined(SIOCGIFHWADDR)
396 sock=socket(PF_INET, SOCK_STREAM, 0);
404 strncpy(ifr.ifr_name,interfaceName.c_str(),
sizeof(ifr.ifr_name)-1);
405 ifr.ifr_name[
sizeof(ifr.ifr_name)-1]=
'\0';
407 if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr))
409 perror(
"ioctl(SIOCGIFHWADDR) ");
412 for (
int j=0; j<6; j++)
413 macAddress[j] = ifr.ifr_hwaddr.sa_data[j];
419 if (getifaddrs(&iflist) == 0)
421 for (ifaddrs* cur = iflist; cur; cur = cur->ifa_next)
423 if ((cur->ifa_addr->sa_family == AF_LINK) &&
424 (strcmp(cur->ifa_name, interfaceName.c_str()) == 0) &&
427 sockaddr_dl* sdl = (sockaddr_dl*)cur->ifa_addr;
428 memcpy(mac, LLADDR(sdl), sdl->sdl_alen);
436 for (
int j=0; j<6; j++)
437 macAddress[j] = mac[j];