This is Unofficial EPICS BASE Doxygen Site
osdNetIntf.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include "osiSock.h"
#include "errlog.h"
#include "epicsThread.h"
#include "epicsVersion.h"
+ Include dependency graph for osdNetIntf.c:

Go to the source code of this file.

Macros

#define VC_EXTRALEAN
 
#define STRICT
 

Functions

LIBCOM_API osiSockAddr epicsStdCall osiLocalAddr (SOCKET socket)
 
LIBCOM_API void epicsStdCall osiSockDiscoverBroadcastAddresses (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr)
 

Macro Definition Documentation

#define STRICT

Definition at line 30 of file osdNetIntf.c.

#define VC_EXTRALEAN

Definition at line 29 of file osdNetIntf.c.

Function Documentation

LIBCOM_API osiSockAddr epicsStdCall osiLocalAddr ( SOCKET  socket)

Definition at line 124 of file osdNetIntf.c.

125 {
126  epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, (void*)&socket);
127  return osiLocalAddrResult;
128 }
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
LIBCOM_API void epicsStdCall osiSockDiscoverBroadcastAddresses ( ELLLIST pList,
SOCKET  socket,
const osiSockAddr pMatchAddr 
)

Definition at line 134 of file osdNetIntf.c.

135 {
136  int status;
137  INTERFACE_INFO *pIfinfo;
138  INTERFACE_INFO *pIfinfoList;
139  unsigned nelem;
140  int numifs;
141  DWORD cbBytesReturned;
142  osiSockAddrNode *pNewNode;
143 
144  if ( pMatchAddr->sa.sa_family == AF_INET ) {
145  if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) {
146  pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) );
147  if ( pNewNode == NULL ) {
148  return;
149  }
150  pNewNode->addr.ia.sin_family = AF_INET;
151  pNewNode->addr.ia.sin_port = htons ( 0 );
152  pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
153  ellAdd ( pList, &pNewNode->node );
154  return;
155  }
156  }
157 
158  /* only valid for winsock 2 and above */
159  if (wsaMajorVersion() < 2 ) {
160  fprintf(stderr, "Need to set EPICS_CA_AUTO_ADDR_LIST=NO for winsock 1\n");
161  return;
162  }
163 
164  nelem = 100;
165  pIfinfoList = (INTERFACE_INFO *) calloc(nelem, sizeof(INTERFACE_INFO));
166  if(!pIfinfoList){
167  return;
168  }
169 
170  status = WSAIoctl (socket, SIO_GET_INTERFACE_LIST,
171  NULL, 0,
172  (LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO),
173  &cbBytesReturned, NULL, NULL);
174 
175  if (status != 0 || cbBytesReturned == 0) {
176  fprintf(stderr, "WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError());
177  free(pIfinfoList);
178  return;
179  }
180 
181  numifs = cbBytesReturned/sizeof(INTERFACE_INFO);
182  for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){
183 
184  /*
185  * dont bother with interfaces that have been disabled
186  */
187  if (!(pIfinfo->iiFlags & IFF_UP)) {
188  continue;
189  }
190 
191  if (pIfinfo->iiFlags & IFF_LOOPBACK) {
192  continue;
193  }
194 
195  /*
196  * work around WS2 bug
197  */
198  if (pIfinfo->iiAddress.Address.sa_family != AF_INET) {
199  if (pIfinfo->iiAddress.Address.sa_family == 0) {
200  pIfinfo->iiAddress.Address.sa_family = AF_INET;
201  }
202  }
203 
204  /*
205  * if it isnt a wildcarded interface then look for
206  * an exact match
207  */
208  if (pMatchAddr->sa.sa_family != AF_UNSPEC) {
209  if (pIfinfo->iiAddress.Address.sa_family != pMatchAddr->sa.sa_family) {
210  continue;
211  }
212  if (pIfinfo->iiAddress.Address.sa_family != AF_INET) {
213  continue;
214  }
215  if (pMatchAddr->sa.sa_family != AF_INET) {
216  continue;
217  }
218  if (pMatchAddr->ia.sin_addr.s_addr != htonl(INADDR_ANY)) {
219  if (pIfinfo->iiAddress.AddressIn.sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr) {
220  continue;
221  }
222  }
223  }
224 
225  pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode));
226  if (pNewNode==NULL) {
227  errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n");
228  return;
229  }
230 
231  if (pIfinfo->iiAddress.Address.sa_family == AF_INET &&
232  pIfinfo->iiFlags & IFF_BROADCAST) {
233  const unsigned mask = pIfinfo->iiNetmask.AddressIn.sin_addr.s_addr;
234  const unsigned bcast = pIfinfo->iiBroadcastAddress.AddressIn.sin_addr.s_addr;
235  const unsigned addr = pIfinfo->iiAddress.AddressIn.sin_addr.s_addr;
236  unsigned result = (addr & mask) | (bcast &~mask);
237  pNewNode->addr.ia.sin_family = AF_INET;
238  pNewNode->addr.ia.sin_addr.s_addr = result;
239  pNewNode->addr.ia.sin_port = htons ( 0 );
240  }
241  else {
242  pNewNode->addr.sa = pIfinfo->iiBroadcastAddress.Address;
243  }
244 
245  /*
246  * LOCK applied externally
247  */
248  ellAdd (pList, &pNewNode->node);
249  }
250 
251  free (pIfinfoList);
252 }
#define INADDR_LOOPBACK
Definition: osdSock.h:76
pvac::PutEvent result
Definition: clientSync.cpp:117
osiSockAddr addr
Definition: osiSock.h:163
pvd::Status status
struct sockaddr sa
Definition: osiSock.h:158
struct sockaddr_in ia
Definition: osiSock.h:157
#define NULL
Definition: catime.c:38
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
Definition: ellLib.c:24
LIBCOM_API unsigned epicsStdCall wsaMajorVersion()
Definition: osdSock.c:41
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
ELLNODE node
Definition: osiSock.h:162
#define stderr
Definition: epicsStdio.h:32