libCom/osi: osiSockDiscoverBroadcastAddresses() finds 127.255.255.255
For the default implementation of osiSockDiscoverBroadcastAddresses() allow the loopback interface to have IFF_BROADCAST set (usually isn't) and on Linux assume that the loopback broadcast address is usable even if IFF_BROADCAST isn't set.
This commit is contained in:
@@ -73,21 +73,6 @@ epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses
|
||||
struct ifreq *pifreq;
|
||||
struct ifreq *pnextifreq;
|
||||
osiSockAddrNode *pNewNode;
|
||||
|
||||
if ( pMatchAddr->sa.sa_family == AF_INET ) {
|
||||
if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) {
|
||||
pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) );
|
||||
if ( pNewNode == NULL ) {
|
||||
errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" );
|
||||
return;
|
||||
}
|
||||
pNewNode->addr.ia.sin_family = AF_INET;
|
||||
pNewNode->addr.ia.sin_port = htons ( 0 );
|
||||
pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
ellAdd ( pList, &pNewNode->node );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* use pool so that we avoid using too much stack space
|
||||
@@ -116,6 +101,7 @@ epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses
|
||||
|
||||
for ( pifreq = pIfreqList; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) {
|
||||
uint32_t current_ifreqsize;
|
||||
struct sockaddr_in if_addr;
|
||||
|
||||
/*
|
||||
* find the next ifreq
|
||||
@@ -139,6 +125,7 @@ epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses
|
||||
ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): interface \"%s\" was not AF_INET\n", pIfreqList->ifr_name) );
|
||||
continue;
|
||||
}
|
||||
if_addr = *(struct sockaddr_in *)&pIfreqList->ifr_addr;
|
||||
|
||||
/*
|
||||
* if it isnt a wildcarded interface then look for
|
||||
@@ -149,8 +136,7 @@ epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses
|
||||
continue;
|
||||
}
|
||||
if ( pMatchAddr->ia.sin_addr.s_addr != htonl (INADDR_ANY) ) {
|
||||
struct sockaddr_in *pInetAddr = (struct sockaddr_in *) &pIfreqList->ifr_addr;
|
||||
if ( pInetAddr->sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr ) {
|
||||
if ( if_addr.sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr ) {
|
||||
ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" didnt match\n", pIfreqList->ifr_name) );
|
||||
continue;
|
||||
}
|
||||
@@ -171,14 +157,6 @@ epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* dont use the loop back interface
|
||||
*/
|
||||
if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) {
|
||||
ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): ignoring loopback interface: \"%s\"\n", pIfreqList->ifr_name) );
|
||||
continue;
|
||||
}
|
||||
|
||||
pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) );
|
||||
if ( pNewNode == NULL ) {
|
||||
errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" );
|
||||
@@ -216,6 +194,22 @@ epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses
|
||||
}
|
||||
pNewNode->addr.sa = pIfreqList->ifr_dstaddr;
|
||||
}
|
||||
#endif
|
||||
#if defined(__linux__)
|
||||
/* On Linux, even though the 'lo' interface doesn't set IFF_BROADCAST
|
||||
* a broadcast route often exists. Assume that sending to 127.255.255.255
|
||||
* reaches all local listeners.
|
||||
*
|
||||
* $ ip route show table local scope link dev lo
|
||||
* broadcast 127.0.0.0 proto kernel src 127.0.0.1
|
||||
* broadcast 127.255.255.255 proto kernel src 127.0.0.1
|
||||
*/
|
||||
else if ( pIfreqList->ifr_flags & IFF_LOOPBACK && if_addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK) ) {
|
||||
memset(&pNewNode->addr.ia, 0, sizeof(pNewNode->addr.ia));
|
||||
pNewNode->addr.ia.sin_family = AF_INET;
|
||||
pNewNode->addr.ia.sin_addr.s_addr = htonl(0x7fffffff);
|
||||
ifDepenDebugPrintf ( ( "assume loopback broadcast addr = %x\n", ntohl ( pNewNode->addr.ia.sin_addr.s_addr ) ) );
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
ifDepenDebugPrintf ( ( "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": not point to point or bcast?\n", pIfreqList->ifr_name ) );
|
||||
|
||||
Reference in New Issue
Block a user