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

Go to the source code of this file.

Macros

#define ifDepenDebugPrintf(argsInParen)
 

Functions

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

Macro Definition Documentation

#define ifDepenDebugPrintf (   argsInParen)

Definition at line 29 of file osdNetIntf.c.

Function Documentation

LIBCOM_API osiSockAddr epicsStdCall osiLocalAddr ( SOCKET  socket)

Definition at line 347 of file osdNetIntf.c.

348 {
349  epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, &socket);
350  return osiLocalAddrResult;
351 }
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 68 of file osdNetIntf.c.

69 {
70  static const unsigned nelem = 100;
71  int status;
72  struct ifconf ifconf;
73  struct ifreq *pIfreqList;
74  struct ifreq *pIfreqListEnd;
75  struct ifreq *pifreq;
76  struct ifreq *pnextifreq;
77  osiSockAddrNode *pNewNode;
78 
79  if ( pMatchAddr->sa.sa_family == AF_INET ) {
80  if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) {
81  pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) );
82  if ( pNewNode == NULL ) {
83  errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" );
84  return;
85  }
86  pNewNode->addr.ia.sin_family = AF_INET;
87  pNewNode->addr.ia.sin_port = htons ( 0 );
88  pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
89  ellAdd ( pList, &pNewNode->node );
90  return;
91  }
92  }
93 
94  /*
95  * use pool so that we avoid using too much stack space
96  *
97  * nelem is set to the maximum interfaces
98  * on one machine here
99  */
100  pIfreqList = (struct ifreq *) calloc ( nelem, sizeof(*pifreq) );
101  if (!pIfreqList) {
102  errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no memory to complete request\n");
103  return;
104  }
105 
106  ifconf.ifc_len = nelem * sizeof(*pifreq);
107  ifconf.ifc_req = pIfreqList;
108  status = socket_ioctl (socket, SIOCGIFCONF, &ifconf);
109  if (status < 0 || ifconf.ifc_len == 0) {
110  errlogPrintf ("osiSockDiscoverBroadcastAddresses(): unable to fetch network interface configuration (%d)\n", status);
111  free (pIfreqList);
112  return;
113  }
114 
115  pIfreqListEnd = (struct ifreq *) (ifconf.ifc_len + (char *) pIfreqList);
116  pIfreqListEnd--;
117 
118  for ( pifreq = pIfreqList; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) {
119  uint32_t current_ifreqsize;
120 
121  /*
122  * find the next ifreq
123  */
124  pnextifreq = ifreqNext (pifreq);
125 
126  /* determine ifreq size */
127  current_ifreqsize = ifreqSize ( pifreq );
128  /* copy current ifreq to aligned bufferspace (to start of pIfreqList buffer) */
129  memmove(pIfreqList, pifreq, current_ifreqsize);
130 
131  ifDepenDebugPrintf (("osiSockDiscoverBroadcastAddresses(): found IFACE: %s len: 0x%x current_ifreqsize: 0x%x \n",
132  pIfreqList->ifr_name,
133  (unsigned)ifreq_size(pifreq),
134  (unsigned)current_ifreqsize));
135 
136  /*
137  * If its not an internet interface then dont use it
138  */
139  if ( pIfreqList->ifr_addr.sa_family != AF_INET ) {
140  ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): interface \"%s\" was not AF_INET\n", pIfreqList->ifr_name) );
141  continue;
142  }
143 
144  /*
145  * if it isnt a wildcarded interface then look for
146  * an exact match
147  */
148  if ( pMatchAddr->sa.sa_family != AF_UNSPEC ) {
149  if ( pMatchAddr->sa.sa_family != AF_INET ) {
150  continue;
151  }
152  if ( pMatchAddr->ia.sin_addr.s_addr != htonl (INADDR_ANY) ) {
153  struct sockaddr_in *pInetAddr = (struct sockaddr_in *) &pIfreqList->ifr_addr;
154  if ( pInetAddr->sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr ) {
155  ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" didnt match\n", pIfreqList->ifr_name) );
156  continue;
157  }
158  }
159  }
160 
161  status = socket_ioctl ( socket, SIOCGIFFLAGS, pIfreqList );
162  if ( status ) {
163  errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf flags fetch for \"%s\" failed\n", pIfreqList->ifr_name);
164  continue;
165  }
166  ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" flags: %x\n", pIfreqList->ifr_name, pIfreqList->ifr_flags) );
167 
168  /*
169  * dont bother with interfaces that have been disabled
170  */
171  if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) {
172  ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" was down\n", pIfreqList->ifr_name) );
173  continue;
174  }
175 
176  /*
177  * dont use the loop back interface
178  */
179  if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) {
180  ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): ignoring loopback interface: \"%s\"\n", pIfreqList->ifr_name) );
181  continue;
182  }
183 
184  pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) );
185  if ( pNewNode == NULL ) {
186  errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" );
187  free ( pIfreqList );
188  return;
189  }
190 
191  /*
192  * If this is an interface that supports
193  * broadcast fetch the broadcast address.
194  *
195  * Otherwise if this is a point to point
196  * interface then use the destination address.
197  *
198  * Otherwise CA will not query through the
199  * interface.
200  */
201  if ( pIfreqList->ifr_flags & IFF_BROADCAST ) {
202  osiSockAddr baddr;
203  status = socket_ioctl (socket, SIOCGIFBRDADDR, pIfreqList);
204  if ( status ) {
205  errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail\n", pIfreqList->ifr_name);
206  free ( pNewNode );
207  continue;
208  }
209  baddr.sa = pIfreqList->ifr_broadaddr;
210  if (baddr.ia.sin_family==AF_INET && baddr.ia.sin_addr.s_addr != INADDR_ANY) {
211  pNewNode->addr.sa = pIfreqList->ifr_broadaddr;
212  ifDepenDebugPrintf ( ( "found broadcast addr = %x\n", ntohl ( baddr.ia.sin_addr.s_addr ) ) );
213  } else {
214  ifDepenDebugPrintf ( ( "Ignoring broadcast addr = \n", ntohl ( baddr.ia.sin_addr.s_addr ) ) );
215  free ( pNewNode );
216  continue;
217  }
218  }
219 #if defined (IFF_POINTOPOINT)
220  else if ( pIfreqList->ifr_flags & IFF_POINTOPOINT ) {
221  status = socket_ioctl ( socket, SIOCGIFDSTADDR, pIfreqList);
222  if ( status ) {
223  ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail\n", pIfreqList->ifr_name) );
224  free ( pNewNode );
225  continue;
226  }
227  pNewNode->addr.sa = pIfreqList->ifr_dstaddr;
228  }
229 #endif
230  else {
231  ifDepenDebugPrintf ( ( "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": not point to point or bcast?\n", pIfreqList->ifr_name ) );
232  free ( pNewNode );
233  continue;
234  }
235 
236  ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" found\n", pIfreqList->ifr_name) );
237 
238  /*
239  * LOCK applied externally
240  */
241  ellAdd ( pList, &pNewNode->node );
242  }
243 
244  free ( pIfreqList );
245 }
#define INADDR_LOOPBACK
Definition: osdSock.h:76
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
#define ifDepenDebugPrintf(argsInParen)
Definition: osdNetIntf.c:29
#define ifreq_size(pifreq)
Definition: osdSock.h:71
#define socket_ioctl(A, B, C)
Definition: osdSock.h:34
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
Definition: ellLib.c:24
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
ELLNODE node
Definition: osiSock.h:162
if(yy_init)
Definition: scan.c:972