From 178f8e90087686279ddbf75faf1d73151d18161d Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Tue, 19 Sep 2006 16:13:34 +0000 Subject: [PATCH] Problem fixed that was found on ARM: ifreq buffer must always be word-aligned when passed to kernel functions. --- src/libCom/osi/os/default/osdNetIntf.c | 63 +++++++++++++++++--------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/libCom/osi/os/default/osdNetIntf.c b/src/libCom/osi/os/default/osdNetIntf.c index 43c77445b..b9f62e740 100644 --- a/src/libCom/osi/os/default/osdNetIntf.c +++ b/src/libCom/osi/os/default/osdNetIntf.c @@ -37,14 +37,17 @@ */ static struct ifreq * ifreqNext ( struct ifreq *pifreq ) { - size_t size; + size_t size; + struct ifreq *ifr; size = ifreq_size ( pifreq ); if ( size < sizeof ( *pifreq ) ) { size = sizeof ( *pifreq ); } - return ( struct ifreq * )( size + ( char * ) pifreq ); + ifr = ( struct ifreq * )( size + ( char * ) pifreq ); + ifDepenDebugPrintf( ("ifreqNext() pifreq 0x%08x, size 0x%08x, ifr 0x%08x\n", pifreq, size, ifr) ); + return ifr; } @@ -94,6 +97,7 @@ epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses ifconf.ifc_req = pIfreqList; status = socket_ioctl (socket, SIOCGIFCONF, &ifconf); if (status < 0 || ifconf.ifc_len == 0) { + ifDepenDebugPrintf(("osiSockDiscoverBroadcastAddresses(): status: 0x08x, ifconf.ifc_len: %d\n", status, ifconf.ifc_len)); errlogPrintf ("osiSockDiscoverBroadcastAddresses(): unable to fetch network interface configuration\n"); free (pIfreqList); return; @@ -103,17 +107,32 @@ epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses pIfreqListEnd--; for ( pifreq = pIfreqList; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) { + uint32_t current_ifreqsize; /* * find the next if req */ pnextifreq = ifreqNext (pifreq); + + /* determine ifreq size */ + current_ifreqsize = ifreq_size ( pifreq ); + if ( current_ifreqsize < sizeof ( *pifreq ) ) { + current_ifreqsize = sizeof ( *pifreq ); + } + /* copy current ifreq to aligned bufferspace (to start of pIfreqList buffer) */ + memmove(pIfreqList, pnextifreq, current_ifreqsize); + + ifDepenDebugPrintf (("osiSockDiscoverBroadcastAddresses(): found IFACE: %s len: 0x%x current_ifreqsize: 0x%x \n", + pIfreqList->ifr_name, + ifreq_size(pifreq), + current_ifreqsize)); + /* * If its not an internet interface then dont use it */ - if ( pifreq->ifr_addr.sa_family != AF_INET ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): interface \"%s\" was not AF_INET\n", pifreq->ifr_name) ); + if ( pIfreqList->ifr_addr.sa_family != AF_INET ) { + ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): interface \"%s\" was not AF_INET\n", pIfreqList->ifr_name) ); continue; } @@ -126,33 +145,33 @@ epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses continue; } if ( pMatchAddr->ia.sin_addr.s_addr != htonl (INADDR_ANY) ) { - struct sockaddr_in *pInetAddr = (struct sockaddr_in *) &pifreq->ifr_addr; + struct sockaddr_in *pInetAddr = (struct sockaddr_in *) &pIfreqList->ifr_addr; if ( pInetAddr->sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" didnt match\n", pifreq->ifr_name) ); + ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" didnt match\n", pIfreqList->ifr_name) ); continue; } } } - status = socket_ioctl ( socket, SIOCGIFFLAGS, pifreq ); + status = socket_ioctl ( socket, SIOCGIFFLAGS, pIfreqList ); if ( status ) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf flags fetch for \"%s\" failed\n", pifreq->ifr_name); + errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf flags fetch for \"%s\" failed\n", pIfreqList->ifr_name); continue; } /* * dont bother with interfaces that have been disabled */ - if ( ! ( pifreq->ifr_flags & IFF_UP ) ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" was down\n", pifreq->ifr_name) ); + if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) { + ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" was down\n", pIfreqList->ifr_name) ); continue; } /* * dont use the loop back interface */ - if ( pifreq->ifr_flags & IFF_LOOPBACK ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): ignoring loopback interface: \"%s\"\n", pifreq->ifr_name) ); + if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) { + ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): ignoring loopback interface: \"%s\"\n", pIfreqList->ifr_name) ); continue; } @@ -173,34 +192,34 @@ epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses * Otherwise CA will not query through the * interface. */ - if ( pifreq->ifr_flags & IFF_BROADCAST ) { - status = socket_ioctl (socket, SIOCGIFBRDADDR, pifreq); + if ( pIfreqList->ifr_flags & IFF_BROADCAST ) { + status = socket_ioctl (socket, SIOCGIFBRDADDR, pIfreqList); if ( status ) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail\n", pifreq->ifr_name); + errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail\n", pIfreqList->ifr_name); free ( pNewNode ); continue; } - pNewNode->addr.sa = pifreq->ifr_broadaddr; + pNewNode->addr.sa = pIfreqList->ifr_broadaddr; ifDepenDebugPrintf ( ( "found broadcast addr = %x\n", ntohl ( pNewNode->addr.ia.sin_addr.s_addr ) ) ); } #if defined (IFF_POINTOPOINT) - else if ( pifreq->ifr_flags & IFF_POINTOPOINT ) { - status = socket_ioctl ( socket, SIOCGIFDSTADDR, pifreq); + else if ( pIfreqList->ifr_flags & IFF_POINTOPOINT ) { + status = socket_ioctl ( socket, SIOCGIFDSTADDR, pIfreqList); if ( status ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail\n", pifreq->ifr_name) ); + ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail\n", pIfreqList->ifr_name) ); free ( pNewNode ); continue; } - pNewNode->addr.sa = pifreq->ifr_dstaddr; + pNewNode->addr.sa = pIfreqList->ifr_dstaddr; } #endif else { - ifDepenDebugPrintf ( ( "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": not point to point or bcast?\n", pifreq->ifr_name ) ); + ifDepenDebugPrintf ( ( "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": not point to point or bcast?\n", pIfreqList->ifr_name ) ); free ( pNewNode ); continue; } - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" found\n", pifreq->ifr_name) ); + ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" found\n", pIfreqList->ifr_name) ); /* * LOCK applied externally