COSMOS core  1.0.2 (beta)
Comprehensive Open-architecture Solution for Mission Operations Systems
Socket library functions
Collaboration diagram for Socket library functions:

Classes

struct  SocketOptions
 
class  Udp
 

Functions

int32_t socket_open (socket_channel *channel, NetworkType ntype, const char *address, uint16_t port, uint16_t direction, bool blocking=true, uint32_t usectimeo=0, uint32_t rcvbuf=0, uint32_t sndbuf=0)
 Open UDP socket. More...
 
int32_t socket_open (socket_channel &channel, NetworkType ntype, const char *address, uint16_t port, uint16_t direction, bool blocking=true, uint32_t usectimeo=0, uint32_t rcvbuf=0, uint32_t sndbuf=0)
 
int32_t socket_accept (socket_channel server, socket_channel &client)
 
uint16_t socket_calc_udp_checksum (vector< uint8_t > packet)
 Calculate UDP Checksum. More...
 
int32_t socket_check_udp_checksum (vector< uint8_t > packet)
 Check UDP checksum. More...
 
int32_t socket_set_udp_checksum (vector< uint8_t > &packet)
 Set UDP checksum. More...
 
int32_t socket_blocking (socket_channel *channel, bool blocking)
 
int32_t socket_blocking (socket_channel &channel, bool blocking)
 
int32_t socket_close (socket_channel *channel)
 Close socket. More...
 
int32_t socket_close (socket_channel &channel)
 
int32_t socket_recvfrom (socket_channel &channel, vector< uint8_t > &buffer, size_t maxlen, int flags=0)
 
int32_t socket_recvfrom (socket_channel &channel, string &buffer, size_t maxlen, int flags=0)
 
int32_t socket_sendto (socket_channel &channel, const string buffer, int flags=0)
 
int32_t socket_sendto (socket_channel &channel, const vector< uint8_t > buffer, int flags=0)
 
vector< socket_channelsocket_find_addresses (NetworkType ntype)
 Discover interfaces. More...
 

Detailed Description

Function Documentation

int32_t socket_open ( socket_channel channel,
NetworkType  ntype,
const char *  address,
uint16_t  port,
uint16_t  role,
bool  blocking,
uint32_t  usectimeo,
uint32_t  rcvbuf,
uint32_t  sndbuf 
)

Open UDP socket.

Open a UDP socket and configure it for the specified use. Various flags are set, and the socket is bound, if necessary. Support is provided for the extra steps necessary for MS Windows.

Parameters
channelPointer to socket_channel holding final configuration.
ntypetype of casting (NetworkType::BROADCAST, NetworkType::MULTICAST, NetworkType::TCP)
addressDestination address
portSource port. If zero, automatically assigned.
rolePublish, subscribe, communicate.
blockingTrue or false.
usectimeoBlocking read timeout in micro seconds.
rcvbufOptional size of buffer for setsockopt SO_RCVBUF.
sndbufOptional size of buffer for setsockopt SO_SNDBUF.
Returns
Zero, or negative error.
53 {
54  int32_t iretn;
55 
56  iretn = socket_open(*channel, ntype, address, port, role, blocking, usectimeo, rcvbuf, sndbuf);
57 
58  return iretn;
59 }
static string port
Definition: add_radio.cpp:16
int iretn
Definition: rw_test.cpp:37
char address[]
Definition: netperf_listen.cpp:69
NetworkType ntype
Definition: agent_node.cpp:50
int32_t socket_open(socket_channel *channel, NetworkType ntype, const char *address, uint16_t port, uint16_t role, bool blocking, uint32_t usectimeo, uint32_t rcvbuf, uint32_t sndbuf)
Open UDP socket.
Definition: socketlib.cpp:51
int32_t socket_open ( socket_channel channel,
NetworkType  ntype,
const char *  address,
uint16_t  port,
uint16_t  direction,
bool  blocking = true,
uint32_t  usectimeo = 0,
uint32_t  rcvbuf = 0,
uint32_t  sndbuf = 0 
)
  1. Join multicast
63 {
64 // socklen_t namelen;
65  int32_t iretn;
66  struct ip_mreq mreq;
67  int on = 1;
68 
69 #ifdef COSMOS_WIN_OS
70  unsigned long nonblocking = 1;
71  WORD wVersionRequested;
72  WSADATA wsaData;
73  static bool started=false;
74 
75  if (!started)
76  {
77  wVersionRequested = MAKEWORD( 1, 1 );
78  iretn = WSAStartup( wVersionRequested, &wsaData );
79  if (iretn != 0)
80  {
81  return SOCKET_ERROR_OPEN;
82  }
83  started = true;
84  }
85 #endif
86 
87  switch (ntype)
88  {
90  {
91  if ((channel.cudp = socket(AF_INET,SOCK_DGRAM,IPPROTO_IP)) <0)
92  {
93  return (-errno);
94  }
95  }
96  break;
98  case NetworkType::UDP:
99  {
100  if ((channel.cudp = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) <0)
101  {
102  return (-errno);
103  }
104  }
105  break;
106  case NetworkType::TCP:
107  {
108  if ((channel.cudp = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) <0)
109  {
110  return (-errno);
111  }
112  }
113  break;
114  default:
115  return (SOCKET_ERROR_PROTOCOL);
116  break;
117  }
118 
119  if (blocking == SOCKET_NONBLOCKING)
120  {
121  iretn = 0;
122 #ifdef COSMOS_WIN_OS
123  if (ioctlsocket(channel.cudp, FIONBIO, &nonblocking) != 0)
124  {
125  iretn = -WSAGetLastError();
126  }
127 #else
128  if (fcntl(channel.cudp, F_SETFL,O_NONBLOCK) < 0)
129  {
130  iretn = -errno;
131  }
132 #endif
133  if (iretn < 0)
134  {
135  CLOSE_SOCKET(channel.cudp);
136  channel.cudp = iretn;
137  return iretn;
138  }
139  }
140 
141  // this defines the wait time for a response from a request
142  if (usectimeo)
143  {
144 #ifdef COSMOS_WIN_OS
145  int msectimeo = usectimeo/1000;
146  iretn = setsockopt(channel.cudp,SOL_SOCKET,SO_RCVTIMEO,(const char *)&msectimeo,sizeof(msectimeo));
147 #else
148  struct timeval tv;
149  tv.tv_sec = usectimeo/1000000;
150  tv.tv_usec = usectimeo%1000000;
151  iretn = setsockopt(channel.cudp,SOL_SOCKET,SO_RCVTIMEO,(char*)&tv,sizeof(tv));
152 #endif
153  }
154 
155  memset(&channel.caddr,0,sizeof(struct sockaddr_in));
156  channel.caddr.sin_family = AF_INET;
157  channel.caddr.sin_port = htons(port);
158 
159  switch (role)
160  {
161  case SOCKET_LISTEN:
162 #ifdef COSMOS_MAC_OS
163  if (setsockopt(channel.cudp,SOL_SOCKET,SO_REUSEPORT,(char*)&on,sizeof(on)) < 0)
164 #else
165  if (setsockopt(channel.cudp,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(on)) < 0)
166 #endif
167  {
168  CLOSE_SOCKET(channel.cudp);
169  channel.cudp = -errno;
170  return (-errno);
171  }
172 
173  switch (ntype)
174  {
177  case NetworkType::UDP:
178  {
179  channel.caddr.sin_addr.s_addr = htonl(INADDR_ANY);
180  if (::bind(channel.cudp,(struct sockaddr *)&channel.caddr, sizeof(struct sockaddr_in)) < 0)
181  {
182  CLOSE_SOCKET(channel.cudp);
183  channel.cudp = -errno;
184  return (-errno);
185  }
186  }
187  break;
188  case NetworkType::TCP:
189  {
190  channel.caddr.sin_addr.s_addr = htonl(INADDR_ANY);
191  channel.caddr.sin_port = htons(port);
192  if (::bind(channel.cudp,(struct sockaddr *)&channel.caddr, sizeof(struct sockaddr_in)) < 0)
193  {
194  CLOSE_SOCKET(channel.cudp);
195  channel.cudp = -errno;
196  return (-errno);
197  }
198 
199  if (listen(channel.cudp, 1) < 0)
200  {
201  CLOSE_SOCKET(channel.cudp);
202  channel.cudp = -errno;
203  return (-errno);
204  }
205  }
206  break;
207  default:
208  return (SOCKET_ERROR_PROTOCOL);
209  break;
210  }
211 
213  {
215  inet_pton(AF_INET,address,&mreq.imr_multiaddr.s_addr);
216 // inte_pton(AF_INET, , &mreq.imr_interface.s_addr);
217  // mreq.imr_multiaddr.s_addr = inet_addr(address);
218  mreq.imr_interface.s_addr = htonl(INADDR_ANY);
219  if (setsockopt(channel.cudp, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq)) < 0)
220  {
221  CLOSE_SOCKET(channel.cudp);
222  channel.cudp = -errno;
223  return (-errno);
224  }
225  }
226  break;
227  case SOCKET_JABBER:
228  switch (ntype)
229  {
231  if ((iretn=setsockopt(channel.cudp,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on))) < 0)
232  {
233  CLOSE_SOCKET(channel.cudp);
234  channel.cudp = -errno;
235  return (-errno);
236  }
237  channel.caddr.sin_addr.s_addr = 0xffffffff;
238  break;
240  inet_pton(AF_INET,address,&channel.caddr.sin_addr);
241  break;
242  default:
243  return (SOCKET_ERROR_PROTOCOL);
244  break;
245  }
246  channel.cport = port;
247  break;
248  case SOCKET_TALK:
249  inet_pton(AF_INET,address,&channel.caddr.sin_addr);
250  channel.cport = port;
251 
252  if (ntype == NetworkType::TCP)
253  {
254  if (connect(channel.cudp,(struct sockaddr *)&channel.caddr, sizeof(struct sockaddr_in)) < 0 && errno != EINPROGRESS)
255  {
256  CLOSE_SOCKET(channel.cudp);
257  channel.cudp = -errno;
258  return (-errno);
259  }
260  }
261  break;
262  }
263 
264  // Find assigned port, place in cport, and set caddr to requested port
265  channel.baddr = channel.caddr;
266  channel.baddr.sin_addr.s_addr |= 0xff;
267 
268  switch (ntype)
269  {
270  case NetworkType::TCP:
271  channel.cport = ntohs(channel.caddr.sin_port);
272  break;
273  default:
274  iretn = sendto(channel.cudp, (const char *)nullptr, 0, 0, (struct sockaddr *)&channel.baddr, sizeof(struct sockaddr_in));
275  sockaddr_in taddr = channel.caddr;
276  socklen_t namelen = sizeof(struct sockaddr_in);
277  if ((iretn = getsockname(channel.cudp, (sockaddr*)&channel.caddr, &namelen)) == -1)
278  {
279  CLOSE_SOCKET(channel.cudp);
280  channel.cudp = -errno;
281  return (-errno);
282  }
283  channel.cport = ntohs(channel.caddr.sin_port);
284  channel.caddr = taddr;
285  break;
286  }
287 
288  if (rcvbuf)
289  {
290  setsockopt(channel.cudp, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbuf, 4);
291  }
292 
293  if (sndbuf)
294  {
295  setsockopt(channel.cudp, SOL_SOCKET, SO_SNDBUF, (char *)&sndbuf, 4);
296  }
297 
298  strncpy(channel.address,address,17);
299  channel.type = ntype;
300  channel.addrlen = sizeof(struct sockaddr_in);
301 
302  return 0;
303 }
static string port
Definition: add_radio.cpp:16
Agent socket using Unicast UDP.
Agent socket using Unicast TCP.
#define SOCKET_ERROR_PROTOCOL
Definition: cosmos-errno.h:230
int iretn
Definition: rw_test.cpp:37
#define SOCKET_ERROR_OPEN
Definition: cosmos-errno.h:232
struct sockaddr_in baddr
Definition: socketlib.h:124
char address[17]
Definition: socketlib.h:134
#define SOCKET_NONBLOCKING
Non-blocking Agent.
Definition: socketlib.h:80
#define SOCKET_TALK
Talk followed by optional listen (sendto address)
Definition: socketlib.h:82
uint16_t cport
Definition: socketlib.h:130
char address[]
Definition: netperf_listen.cpp:69
int32_t cudp
Definition: socketlib.h:120
NetworkType type
Definition: socketlib.h:118
struct sockaddr_in caddr
Definition: socketlib.h:122
int addrlen
Definition: socketlib.h:128
Agent socket using Broadcast UDP.
NetworkType ntype
Definition: agent_node.cpp:50
#define SOCKET_LISTEN
Listen followed by optional talk (recvfrom INADDRANY)
Definition: socketlib.h:84
#define SOCKET_JABBER
Talk over multiple interfaces.
Definition: socketlib.h:88
Agent socket using Multicast UDP.
int32_t socket_accept ( socket_channel  server,
socket_channel client 
)

Accept TCP Client connection If socket_channel is a TCP connection, accept the next client and make it available for socket_recvfrom call.

Parameters
serversocket_channel for existing server connection.
clientsocket_channel with new client information.
Returns
Zero or negative error.
312 {
313  int32_t iretn=0;
314  if (server.type != NetworkType::TCP)
315  {
316  return SOCKET_ERROR_PROTOCOL;
317  }
318 
319  iretn = accept(server.cudp, reinterpret_cast<struct sockaddr *>(&client.caddr), reinterpret_cast<socklen_t *>(&client.addrlen));
320  if (iretn < 0)
321  {
322  return -errno;
323  }
324 
325  client.cudp = iretn;
326 
327  return iretn;
328 }
Agent socket using Unicast TCP.
#define SOCKET_ERROR_PROTOCOL
Definition: cosmos-errno.h:230
int iretn
Definition: rw_test.cpp:37
int32_t cudp
Definition: socketlib.h:120
NetworkType type
Definition: socketlib.h:118
struct sockaddr_in caddr
Definition: socketlib.h:122
int addrlen
Definition: socketlib.h:128
uint16_t socket_calc_udp_checksum ( vector< uint8_t >  packet)

Calculate UDP Checksum.

Calculate UDP Checksum, as detailed in RFC 768, based on the provided IP packet.

Parameters
packetIP packet
Returns
Calculated checksum.
336 {
337  union
338  {
339  uint8_t* bytes;
340  uint16_t* ints;
341  } ;
342 
343  bytes = &packet[0];
344 
345  uint32_t csum32;
346  csum32 = 0;
347  // Pseudo header
348  // Source Address
349  csum32 += ints[6];
350  csum32 += ints[7];
351  // Destination Address
352  csum32 += ints[8];
353  csum32 += ints[9];
354  // Protocol byte
355  csum32 += bytes[SOCKET_IP_BYTE_PROTOCOL]*256U;
356  // UDP Length
357  csum32 += ints[12];
358 
359  // UDP header
360  // UDP Source Port
361  csum32 += ints[10];
362  // UDP Destination Port
363  csum32 += ints[11];
364  // UDP Length
365  csum32 += ints[12];
366  // UDP Checksum
367  csum32 += ints[13];
368 
369  // Actual data bytes. Do any even number, then special treatment for any odd byte.
370  uint16_t udpl = (bytes[24]*256U + bytes[25]) - 8;
371  if (udpl)
372  {
373  for (uint16_t i=0; i<udpl/2; ++i)
374  {
375  csum32 += ints[14+i];
376  }
377 
378  if (2*(udpl/2) != udpl)
379  {
380  csum32 += bytes[27+udpl];
381  }
382  }
383 
384  // Perform end around carry
385  while (csum32 > 0xffff)
386  {
387  csum32 = (csum32 & 0xffff) + (csum32 >> 16);
388  }
389 
390  csum32 = ~csum32;
391 
392  if ((uint16_t)csum32 == 0)
393  {
394  return 0xffff;
395  }
396  else
397  {
398  return (uint16_t)csum32;
399  }
400 }
int i
Definition: rw_test.cpp:37
#define SOCKET_IP_BYTE_PROTOCOL
Definition: socketlib.h:97
int32_t socket_check_udp_checksum ( vector< uint8_t >  packet)

Check UDP checksum.

Calculate UDP checksum for provided UDP packet and return whether it is valid or not.

Parameters
packetUDP packet
Returns
Zero or negative error.
408 {
409  uint16_t csum = socket_calc_udp_checksum(packet);
410 
411  // if (csum == uint16from(&packet[26], ByteOrder::NETWORK))
412  if (csum == 0xffff)
413  {
414  return 0;
415  }
416  else
417  {
418  return SOCKET_ERROR_CS;
419  }
420 }
#define SOCKET_ERROR_CS
Definition: cosmos-errno.h:229
uint16_t socket_calc_udp_checksum(vector< uint8_t > packet)
Calculate UDP Checksum.
Definition: socketlib.cpp:335
int32_t socket_set_udp_checksum ( vector< uint8_t > &  packet)

Set UDP checksum.

Clear UDP checksum field, calculate UDP checksum, and set UDP checksum field in provided UDP packet.

Parameters
packetUDP packet
Returns
Zero or negative error.
429 {
430  // Check if this is UDP packet
431  if (packet[SOCKET_IP_BYTE_PROTOCOL] != 17)
432  {
433  return SOCKET_ERROR_PROTOCOL;
434  }
435 
436  // Set UDP checksum bytes to zero.
437  packet[SOCKET_IP_BYTE_UDP_CS] = packet[SOCKET_IP_BYTE_UDP_CS+1] = 0;
438 
439  // Calculate checksum
440  uint16_t csum = socket_calc_udp_checksum(packet);
441 
442  // Place it in checksum bytes
444 
445  return 0;
446 }
#define SOCKET_IP_BYTE_UDP_CS
Definition: socketlib.h:101
void uint16to(uint16_t value, uint8_t *pointer, ByteOrder order)
16 bit unsigned integer to memory
Definition: mathlib.cpp:613
#define SOCKET_ERROR_PROTOCOL
Definition: cosmos-errno.h:230
#define SOCKET_IP_BYTE_PROTOCOL
Definition: socketlib.h:97
Little Endian byte order.
uint16_t socket_calc_udp_checksum(vector< uint8_t > packet)
Calculate UDP Checksum.
Definition: socketlib.cpp:335
int32_t socket_blocking ( socket_channel channel,
bool  blocking 
)
449 {
450  int32_t iretn;
451 
452  iretn = socket_blocking(*channel, blocking);
453 
454  return iretn;
455 }
int iretn
Definition: rw_test.cpp:37
int32_t socket_blocking(socket_channel *channel, bool blocking)
Definition: socketlib.cpp:448
int32_t socket_blocking ( socket_channel channel,
bool  blocking 
)
458 {
459  int32_t iretn;
460 
461  if (blocking == SOCKET_NONBLOCKING)
462  {
463  iretn = 0;
464 #ifdef COSMOS_WIN_OS
465  unsigned long nonblocking = 1;
466  if (ioctlsocket(channel.cudp, FIONBIO, &nonblocking) != 0)
467  {
468  iretn = -WSAGetLastError();
469  }
470 #else
471  if (fcntl(channel.cudp, F_SETFL,O_NONBLOCK) < 0)
472  {
473  iretn = -errno;
474  }
475 #endif
476  }
477  else
478  {
479  iretn = 0;
480 #ifdef COSMOS_WIN_OS
481  unsigned long nonblocking = 0;
482  if (ioctlsocket(channel.cudp, FIONBIO, &nonblocking) != 0)
483  {
484  iretn = -WSAGetLastError();
485  }
486 #else
487  int oldfl;
488  if ((oldfl = fcntl(channel.cudp, F_GETFL)) == -1)
489  {
490  iretn = -errno;
491  }
492  else
493  {
494  if (fcntl(channel.cudp, F_SETFL, oldfl & ~O_NONBLOCK) < 0)
495  {
496  iretn = -errno;
497  }
498  }
499 #endif
500  }
501  return iretn;
502 }
int iretn
Definition: rw_test.cpp:37
#define SOCKET_NONBLOCKING
Non-blocking Agent.
Definition: socketlib.h:80
int32_t cudp
Definition: socketlib.h:120
int32_t socket_close ( socket_channel channel)

Close socket.

Close down open socket connectiom.

Parameters
channelPointer to socket_channel holding final configuration.
Returns
Zero or negative error.
510 {
511  int32_t iretn;
512 
513  iretn = socket_close(*channel);
514 
515  return iretn;
516 }
int32_t socket_close(socket_channel *channel)
Close socket.
Definition: socketlib.cpp:509
int iretn
Definition: rw_test.cpp:37
int32_t socket_close ( socket_channel channel)
519 {
520  int32_t iretn = 0;
521 
522  if (channel.cudp >= 0)
523  {
524 #ifdef COSMOS_WIN_OS
525  if (closesocket(channel.cudp) < 0)
526  {
527  iretn = -WSAGetLastError();
528  }
529 #else
530  if (close(channel.cudp) < 0)
531  {
532  iretn = -errno;
533  }
534 #endif
535  // channel.address[0] = 0;
536  channel.cudp = -1;
537  }
538  return iretn;
539 }
int iretn
Definition: rw_test.cpp:37
int32_t cudp
Definition: socketlib.h:120
int32_t socket_recvfrom ( socket_channel channel,
vector< uint8_t > &  buffer,
size_t  maxlen,
int  flags = 0 
)
721  {
722  int32_t nbytes;
723  buffer.resize(maxlen);
724  if ((nbytes = recvfrom(channel.cudp, (char *)buffer.data(), maxlen, flags, (struct sockaddr *)&channel.caddr, (socklen_t *)&channel.addrlen)) > 0)
725  {
726  buffer.resize(nbytes);
727  inet_ntop(channel.caddr.sin_family, &channel.caddr.sin_addr, channel.address, sizeof(channel.address));
728  }
729  else
730  {
731  buffer.clear();
732  nbytes = -errno;
733  }
734  return nbytes;
735 }
char address[17]
Definition: socketlib.h:134
int32_t cudp
Definition: socketlib.h:120
static char buffer[255]
Definition: propagator_simple.cpp:60
struct sockaddr_in caddr
Definition: socketlib.h:122
int addrlen
Definition: socketlib.h:128
int32_t socket_recvfrom ( socket_channel channel,
string &  buffer,
size_t  maxlen,
int  flags = 0 
)
711 {
712  int32_t iretn;
713  vector<uint8_t> data;
714  iretn = socket_recvfrom(channel, data, maxlen, flags);
715  string str(data.begin(), data.end());
716  buffer = str;
717  return iretn;
718 }
int32_t socket_recvfrom(socket_channel &channel, string &buffer, size_t maxlen, int flags)
Definition: socketlib.cpp:710
int iretn
Definition: rw_test.cpp:37
const string & str
Definition: json11.cpp:360
static char buffer[255]
Definition: propagator_simple.cpp:60
int32_t socket_sendto ( socket_channel channel,
const string  buffer,
int  flags = 0 
)
738 {
739  vector<uint8_t> data(buffer.begin(), buffer.end());
740  return socket_sendto(channel, data, flags);
741 }
int32_t socket_sendto(socket_channel &channel, const string buffer, int flags)
Definition: socketlib.cpp:737
static char buffer[255]
Definition: propagator_simple.cpp:60
int32_t socket_sendto ( socket_channel channel,
const vector< uint8_t >  buffer,
int  flags = 0 
)
744 {
745  int32_t nbytes;
746 #if defined(COSMOS_WIN_OS)
747  nbytes = sendto(channel.cudp, (const char *)(buffer.data()), buffer.size(), flags, (struct sockaddr *)&channel.caddr, channel.addrlen);
748 #else
749  if ((nbytes = sendto(channel.cudp, const_cast<uint8_t*>(buffer.data()), buffer.size(), flags, reinterpret_cast<struct sockaddr *>(&channel.caddr), static_cast<socklen_t>(channel.addrlen))) < 0)
750  {
751  nbytes = -errno;
752  }
753 #endif
754  return nbytes;
755 }
int32_t cudp
Definition: socketlib.h:120
static char buffer[255]
Definition: propagator_simple.cpp:60
struct sockaddr_in caddr
Definition: socketlib.h:122
int addrlen
Definition: socketlib.h:128
vector<socket_channel> socket_find_addresses ( NetworkType  ntype)

Discover interfaces.

Return a vector of socket_channel containing info on each valid interface. For IPV4 this will include the address and broadcast address, in both string sockaddr_in format.

Parameters
ntypeType of network (Multicast, Broadcast UDP, CSP)
Returns
Vector of interfaces
548 {
549  vector<socket_channel> iface;
550  socket_channel tiface;
551 
552 #ifdef COSMOS_WIN_OS
553  INTERFACE_INFO ilist[20];
554  unsigned long nbytes;
555  uint32_t nif;
556  uint32_t ip, net, bcast;
557 #else
558  struct ifconf confa;
559  struct ifreq *ifra;
560  char data[512];
561 #endif // COSMOS_WIN_OS
562  int32_t iretn;
563  int on = 1;
564  int32_t cudp;
565 
566  switch (ntype)
567  {
569  case NetworkType::UDP:
570  {
571  if ((cudp=socket(AF_INET,SOCK_DGRAM,0)) < 0)
572  {
573  return (iface);
574  }
575 
576  // Use above socket to find available interfaces and establish
577  // publication on each.
578 #ifdef COSMOS_WIN_OS
579  if (WSAIoctl(cudp, SIO_GET_INTERFACE_LIST, 0, 0, &ilist,sizeof(ilist), &nbytes, 0, 0) == SOCKET_ERROR)
580  {
581  CLOSE_SOCKET(cudp);
582  return (iface);
583  }
584 
585  nif = nbytes / sizeof(INTERFACE_INFO);
586  PIP_ADAPTER_ADDRESSES pAddresses = NULL;
587  PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
588  pAddresses = (IP_ADAPTER_ADDRESSES *) calloc(sizeof(IP_ADAPTER_ADDRESSES), 2*nif);
589  ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 2 * nif;
590  DWORD dwRetVal;
591  if ((dwRetVal=GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &outBufLen)) == ERROR_BUFFER_OVERFLOW)
592  {
593  free(pAddresses);
594  return (iface);
595  }
596 
597  for (uint32_t i=0; i<nif; i++)
598  {
599  inet_ntop(ilist[i].iiAddress.AddressIn.sin_family,&ilist[i].iiAddress.AddressIn.sin_addr,tiface.address,sizeof(tiface.address));
600  // strncpy(tiface.address, inet_ntoa(((struct sockaddr_in*)&(ilist[i].iiAddress))->sin_addr), 17);
601  if (!strcmp(tiface.address,"127.0.0.1"))
602  {
603  continue;
604  }
605 
606  pCurrAddresses = pAddresses;
607  while (pAddresses)
608  {
609  if (((struct sockaddr_in *)(pCurrAddresses->FirstUnicastAddress->Address.lpSockaddr))->sin_addr.s_addr == ((struct sockaddr_in*)&(ilist[i].iiAddress))->sin_addr.s_addr)
610  {
611  strcpy(tiface.name, pCurrAddresses->AdapterName);
612  break;
613  }
614  pCurrAddresses = pCurrAddresses->Next;
615  }
616  memset(&tiface.caddr,0,sizeof(struct sockaddr_in));
617  memset(&tiface.baddr,0,sizeof(struct sockaddr_in));
618  tiface.caddr.sin_family = AF_INET;
619  tiface.baddr.sin_family = AF_INET;
621  {
622  inet_pton(AF_INET,(char *)COSMOSMCAST,&tiface.caddr.sin_addr);
623  inet_pton(AF_INET,(char *)COSMOSMCAST,&tiface.baddr.sin_addr);
624  // struct sockaddr_storage ss;
625  // int sslen;
626  // sslen = sizeof(ss);
627  // WSAStringToAddressA((char *)COSMOSMCAST,AF_INET,NULL,(struct sockaddr*)&ss,&sslen);
628  // tiface.caddr.sin_addr = ((struct sockaddr_in *)&ss)->sin_addr;
629  // tiface.baddr.sin_addr = ((struct sockaddr_in *)&ss)->sin_addr;
630  }
631  else
632  {
633  if ((iretn = setsockopt(cudp,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on))) < 0)
634  {
635  continue;
636  }
637  ip = ((struct sockaddr_in*)&(ilist[i].iiAddress))->sin_addr.S_un.S_addr;
638  net = ((struct sockaddr_in*)&(ilist[i].iiNetmask))->sin_addr.S_un.S_addr;
639  bcast = ip | (~net);
640 
641  tiface.caddr.sin_addr = ((struct sockaddr_in *)&ilist[i].iiAddress)->sin_addr;
642  tiface.caddr.sin_addr.S_un.S_addr = ip;
643  tiface.baddr.sin_addr = ((struct sockaddr_in *)&ilist[i].iiAddress)->sin_addr;
644  tiface.baddr.sin_addr.S_un.S_addr = bcast;
645  }
646  // struct sockaddr_storage ss;
647  // ((struct sockaddr_in *)&ss)->sin_addr = tiface.caddr.sin_addr;
648  // ssize = strlen(tiface.address);
649  // WSAAddressToStringA((struct sockaddr *)&tiface.caddr.sin_addr, sizeof(struct sockaddr_in), 0, tiface.address, (LPDWORD)&ssize);
650  inet_ntop(tiface.caddr.sin_family,&tiface.caddr.sin_addr,tiface.address,sizeof(tiface.address));
651  // ssize = strlen(tiface.baddress);
652  // WSAAddressToStringA((struct sockaddr *)&tiface.baddr.sin_addr, sizeof(struct sockaddr_in), 0, tiface.baddress, (LPDWORD)&ssize);
653  inet_ntop(tiface.baddr.sin_family,&tiface.baddr.sin_addr,tiface.baddress,sizeof(tiface.baddress));
654  tiface.type = ntype;
655  iface.push_back(tiface);
656  }
657 #else
658  confa.ifc_len = sizeof(data);
659  confa.ifc_buf = (caddr_t)data;
660  if (ioctl(cudp,SIOCGIFCONF,&confa) < 0)
661  {
662  CLOSE_SOCKET(cudp);
663  return (iface);
664  }
665  // Use result to discover interfaces.
666  ifra = confa.ifc_req;
667  for (int32_t n=confa.ifc_len/sizeof(struct ifreq); --n >= 0; ifra++)
668  {
669  if (ifra->ifr_addr.sa_family != AF_INET) continue;
670  inet_ntop(ifra->ifr_addr.sa_family,&((struct sockaddr_in*)&ifra->ifr_addr)->sin_addr,tiface.address,sizeof(tiface.address));
671 
672  if (ioctl(cudp,SIOCGIFFLAGS, (char *)ifra) < 0) continue;
673 
674  if ((ifra->ifr_flags & IFF_UP) == 0 || (ifra->ifr_flags & IFF_LOOPBACK) || (ifra->ifr_flags & (IFF_BROADCAST)) == 0) continue;
675 
677  {
678  inet_pton(AF_INET,COSMOSMCAST,&tiface.caddr.sin_addr);\
679  strncpy(tiface.baddress, COSMOSMCAST, 17);
680  inet_pton(AF_INET,COSMOSMCAST,&tiface.baddr.sin_addr);\
681  }
682  else
683  {
684  if ((iretn = setsockopt(cudp,SOL_SOCKET,SO_BROADCAST,(char*)&on,sizeof(on))) < 0)
685  {
686  continue;
687  }
688 
689  strncpy(tiface.name, ifra->ifr_name, COSMOS_MAX_NAME);
690  if (ioctl(cudp,SIOCGIFBRDADDR,(char *)ifra) < 0) continue;
691  memcpy((char *)&tiface.baddr, (char *)&ifra->ifr_broadaddr, sizeof(ifra->ifr_broadaddr));
692  if (ioctl(cudp,SIOCGIFADDR,(char *)ifra) < 0) continue;
693  memcpy((char *)&tiface.caddr, (char *)&ifra->ifr_addr, sizeof(ifra->ifr_addr));
694  inet_ntop(tiface.baddr.sin_family,&tiface.baddr.sin_addr,tiface.baddress,sizeof(tiface.baddress));
695  }
696  tiface.type = ntype;
697  iface.push_back(tiface);
698  }
699 
700 #endif // COSMOS_WIN_OS
701  }
702  break;
703  default:
704  break;
705  }
706 
707  return (iface);
708 }
Agent socket using Unicast UDP.
int i
Definition: rw_test.cpp:37
#define COSMOS_MAX_NAME
Largest JSON name.
Definition: cosmos-defs.h:55
int iretn
Definition: rw_test.cpp:37
struct sockaddr_in baddr
Definition: socketlib.h:124
char address[17]
Definition: socketlib.h:134
char name[COSMOS_MAX_NAME+1]
Definition: socketlib.h:138
NetworkType type
Definition: socketlib.h:118
#define COSMOSMCAST
COSMOS heartbeat Multicast address.
Definition: cosmos-defs.h:253
Definition: socketlib.h:115
struct sockaddr_in caddr
Definition: socketlib.h:122
NetworkType ntype
Definition: agent_node.cpp:50
Agent socket using Multicast UDP.
char baddress[17]
Definition: socketlib.h:136