20 #define epicsExportSharedSymbols 26 # define ifr_netmask ifr_addr 43 uint32_t ipv4Addr = ntohl(address->
ia.sin_addr.s_addr);
54 if (buffer->
getLong() != 0)
return false;
55 if (buffer->
getShort() != 0)
return false;
68 if (ffff != (
int16)0xFFFF && ipv4Addr != (uint32_t)0)
71 address->
ia.sin_addr.s_addr = htonl(ipv4Addr);
77 uint32_t ipv4Addr = ntohl(address->
ia.sin_addr.s_addr);
78 uint8_t msB = (uint8_t)((ipv4Addr>>24)&0xFF);
79 return msB >= 224 && msB <= 239;
83 const std::string & list,
int defaultPort,
88 size_t len = list.length();
90 while (subStart < len && isspace(list[subStart]))
95 while((subEnd = list.find(
' ', subStart))!=std::string::npos) {
96 string address = list.substr(subStart, (subEnd-subStart));
98 if (
aToIPAddr(address.c_str(), defaultPort, &addr.
ia) == 0)
100 subStart = list.find_first_not_of(
" \t\r\n\v", subEnd);
103 if(subStart!=std::string::npos && subStart<len) {
105 if (
aToIPAddr(list.substr(subStart).c_str(), defaultPort, &addr.
ia) == 0)
109 if(appendList!=
NULL) {
110 for(
size_t i = 0;
i<appendList->size();
i++)
111 ret.push_back((*appendList)[
i]);
116 bool displayPort,
bool displayHex) {
119 int ipa = ntohl(addr.
ia.sin_addr.s_addr);
121 saddr<<((int)(ipa>>24)&0xFF)<<
'.';
122 saddr<<((int)(ipa>>16)&0xFF)<<
'.';
123 saddr<<((int)(ipa>>8)&0xFF)<<
'.';
124 saddr<<((int)ipa&0xFF);
125 if(displayPort) saddr<<
":"<<ntohs(addr.
ia.sin_port);
126 if(displayHex) saddr<<
" ("<<
hex<<ntohl(addr.
ia.sin_addr.s_addr)
132 ifaceNode::ifaceNode()
134 memset(&addr, 0,
sizeof(addr));
135 memset(&peer, 0,
sizeof(peer));
136 memset(&bcast, 0,
sizeof(bcast));
137 memset(&mask, 0,
sizeof(mask));
138 validBcast = validP2P = loopback =
false;
149 mask = ntohl(node.
mask.
ia.sin_addr.s_addr),
150 bcast= ntohl(node.
bcast.
ia.sin_addr.s_addr),
151 bcast_expect = (addr & mask) | ~mask;
153 if(bcast == ntohl(INADDR_BROADCAST)) {
156 bcast = bcast_expect;
157 node.
bcast.
ia.sin_addr.s_addr = htonl(bcast);
160 if(bcast != bcast_expect) {
161 errlogPrintf(
"Warning: Inconsistent broadcast address on interface %08x/%08x. expect %08x found %08x.\n",
162 (
unsigned)addr, (
unsigned)mask, (
unsigned)bcast_expect, (
unsigned)bcast);
174 static size_t ifreqSize (
struct ifreq *pifreq )
179 if ( size <
sizeof ( *pifreq ) ) {
180 size =
sizeof ( *pifreq );
188 static struct ifreq * ifreqNext (
struct ifreq *pifreq )
192 ifr = (
struct ifreq * )( ifreqSize (pifreq) + (
char * ) pifreq );
198 static const unsigned nelem = 100;
200 struct ifconf ifconf;
201 struct ifreq *pIfreqList;
202 struct ifreq *pIfreqListEnd;
203 struct ifreq *pifreq;
204 struct ifreq *pnextifreq;
213 pIfreqList = (
struct ifreq *) calloc ( nelem,
sizeof(*pifreq) );
215 errlogPrintf (
"discoverInterfaces(): no memory to complete request\n");
219 ifconf.ifc_len = nelem *
sizeof(*pifreq);
220 ifconf.ifc_req = pIfreqList;
222 if (status < 0 || ifconf.ifc_len == 0) {
223 errlogPrintf (
"discoverInterfaces(): unable to fetch network interface configuration\n");
228 pIfreqListEnd = (
struct ifreq *) (ifconf.ifc_len + (
char *) pIfreqList);
231 for ( pifreq = pIfreqList; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) {
232 uint32_t current_ifreqsize;
237 pnextifreq = ifreqNext (pifreq);
240 current_ifreqsize = ifreqSize ( pifreq );
245 memmove(pIfreqList, pifreq, current_ifreqsize);
250 if ( pIfreqList->ifr_addr.sa_family != AF_INET ) {
259 if ( pMatchAddr && pMatchAddr->
sa.sa_family != AF_UNSPEC ) {
260 if ( pMatchAddr->
sa.sa_family != AF_INET ) {
263 if ( pMatchAddr->
ia.sin_addr.s_addr != htonl (INADDR_ANY) ) {
264 struct sockaddr_in *pInetAddr = (
struct sockaddr_in *) &pIfreqList->ifr_addr;
265 if ( pInetAddr->sin_addr.s_addr != pMatchAddr->
ia.sin_addr.s_addr ) {
274 node.
addr.
sa = pIfreqList->ifr_addr;
276 status =
socket_ioctl ( socket, SIOCGIFFLAGS, pIfreqList );
278 errlogPrintf (
"discoverInterfaces(): net intf flags fetch for \"%s\" failed\n", pIfreqList->ifr_name);
282 unsigned short ifflags = pIfreqList->ifr_flags;
283 node.
loopback = ifflags & IFF_LOOPBACK;
288 if ( ! ( ifflags & IFF_UP ) ) {
296 if ( ifflags & IFF_LOOPBACK ) {
311 if ( ifflags & IFF_BROADCAST ) {
312 status =
socket_ioctl (socket, SIOCGIFBRDADDR, pIfreqList);
314 errlogPrintf (
"discoverInterfaces(): net intf \"%s\": bcast addr fetch fail\n", pIfreqList->ifr_name);
317 node.
bcast.
sa = pIfreqList->ifr_broadaddr;
319 status =
socket_ioctl (socket, SIOCGIFNETMASK, pIfreqList);
321 errlogPrintf (
"discoverInterfaces(): net intf \"%s\": netmask fetch fail\n", pIfreqList->ifr_name);
324 node.
mask.
sa = pIfreqList->ifr_netmask;
330 #if defined (IFF_POINTOPOINT) 331 else if ( ifflags & IFF_POINTOPOINT ) {
332 status =
socket_ioctl ( socket, SIOCGIFDSTADDR, pIfreqList);
336 node.
peer.
sa = pIfreqList->ifr_dstaddr;
348 list.push_back(node);
359 #include <winsock2.h> 360 #include <ws2tcpip.h> 365 INTERFACE_INFO *pIfinfo;
366 INTERFACE_INFO *pIfinfoList;
369 DWORD cbBytesReturned;
381 pIfinfoList = (INTERFACE_INFO *) calloc(nelem,
sizeof(INTERFACE_INFO));
386 status = WSAIoctl (socket, SIO_GET_INTERFACE_LIST,
388 (LPVOID)pIfinfoList, nelem*
sizeof(INTERFACE_INFO),
391 if (status != 0 || cbBytesReturned == 0) {
392 fprintf(
stderr,
"WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError());
397 numifs = cbBytesReturned/
sizeof(INTERFACE_INFO);
398 for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++) {
403 if (!(pIfinfo->iiFlags & IFF_UP)) {
411 if (pIfinfo->iiAddress.Address.sa_family != AF_INET) {
412 if (pIfinfo->iiAddress.Address.sa_family == 0) {
413 pIfinfo->iiAddress.Address.sa_family = AF_INET;
424 if (pMatchAddr && pMatchAddr->
sa.sa_family != AF_UNSPEC) {
425 if (pIfinfo->iiAddress.Address.sa_family != pMatchAddr->
sa.sa_family) {
428 if (pIfinfo->iiAddress.Address.sa_family != AF_INET) {
431 if (pMatchAddr->
sa.sa_family != AF_INET) {
434 if (pMatchAddr->
ia.sin_addr.s_addr != htonl(INADDR_ANY)) {
435 if (pIfinfo->iiAddress.AddressIn.sin_addr.s_addr != pMatchAddr->
ia.sin_addr.s_addr) {
447 if (pIfinfo->iiFlags & IFF_LOOPBACK) {
453 node.
loopback = pIfinfo->iiFlags & IFF_LOOPBACK;
454 node.
addr.
ia = pIfinfo->iiAddress.AddressIn;
456 if (pIfinfo->iiFlags & IFF_BROADCAST) {
457 node.
mask.
ia = pIfinfo->iiNetmask.AddressIn;
458 node.
bcast.
ia = pIfinfo->iiBroadcastAddress.AddressIn;
461 else if (pIfinfo->iiFlags & IFF_POINTTOPOINT) {
462 node.
peer.
ia = pIfinfo->iiNetmask.AddressIn;
468 list.push_back(node);
LIBCOM_API int epicsStdCall aToIPAddr(const char *pAddrString, unsigned short defaultPort, struct sockaddr_in *pIP)
EPICS_ALWAYS_INLINE int8 getByte()
bool validBcast
true if bcast and mask have been set
TODO only here because of the Lockable.
osiSockAddr mask
Net mask.
osiSockAddr peer
point to point peer
#define ifreq_size(pifreq)
osiSockAddr addr
Our address.
#define socket_ioctl(A, B, C)
A doubly-linked list library.
std::vector< osiSockAddr > InetAddrVector
void encodeAsIPv6Address(ByteBuffer *buffer, const osiSockAddr *address)
std::vector< ifaceNode > IfaceNodeVector
EPICS_ALWAYS_INLINE void putByte(int8 value)
This class implements a Bytebuffer that is like the java.nio.ByteBuffer.
EPICS_ALWAYS_INLINE int16 getShort()
int errlogPrintf(const char *pFormat,...)
bool decodeAsIPv6Address(ByteBuffer *buffer, osiSockAddr *address)
bool isMulticastAddress(const osiSockAddr *address)
void getSocketAddressList(InetAddrVector &ret, const std::string &list, int defaultPort, const InetAddrVector *appendList)
bool validP2P
true if peer has been set.
EPICS_ALWAYS_INLINE int64 getLong()
EPICS_ALWAYS_INLINE void putLong(int64 value)
osiSockAddr bcast
sub-net broadcast address
string inetAddressToString(const osiSockAddr &addr, bool displayPort, bool displayHex)
int discoverInterfaces(IfaceNodeVector &list, SOCKET socket, const osiSockAddr *pMatchAddr)
EPICS_ALWAYS_INLINE void putShort(int16 value)