diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index a9698ec90..80c2a76e5 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -13,6 +13,13 @@
+
Improvements to aToIPAddr()
+
+The libCom routine aToIPAddr() and the vxWorks implementation of the
+associated hostToIPAddr() function have been modified to be able to look up
+hostnames that begin with one or more digits. The epicsSockResolveTest program
+was added to check this functionality.
+
Added osdFindSymbol for Windows
Dirk Zimoch implemented the epicsLoadLibrary(), epicsLoadError() and
diff --git a/src/libCom/misc/aToIPAddr.c b/src/libCom/misc/aToIPAddr.c
index c5d53bc30..04809bffe 100644
--- a/src/libCom/misc/aToIPAddr.c
+++ b/src/libCom/misc/aToIPAddr.c
@@ -1,11 +1,10 @@
/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* rational replacement for inet_addr()
@@ -13,49 +12,25 @@
* author: Jeff Hill
*/
#include
-#include
-#include
#include
#define epicsExportSharedSymbols
#include "osiSock.h"
-
-#ifndef NELEMENTS
-#define NELEMENTS(A) (sizeof(A)/sizeof(A[0]))
-#endif /*NELEMENTS*/
-
-/*
- * addrArrayToUL ()
- */
-static int addrArrayToUL (const unsigned short *pAddr, unsigned nElements, struct in_addr *pIpAddr)
-{
- unsigned i;
- unsigned long addr = 0ul;
-
- for ( i=0u; i < nElements; i++ ) {
- if ( pAddr[i] > 0xff ) {
- return -1;
- }
- addr <<= 8;
- addr |= pAddr[i];
- }
- pIpAddr->s_addr = htonl ( addr );
-
- return 0;
-}
+#include "epicsStdlib.h"
/*
* initIPAddr()
* !! ipAddr should be passed in in network byte order !!
* !! port is passed in in host byte order !!
*/
-static int initIPAddr (struct in_addr ipAddr, unsigned short port, struct sockaddr_in *pIP)
+static int initIPAddr (struct in_addr ipAddr, unsigned short port,
+ struct sockaddr_in *pIP)
{
- memset (pIP, '\0', sizeof(*pIP));
- pIP->sin_family = AF_INET;
- pIP->sin_port = htons(port);
- pIP->sin_addr = ipAddr;
- return 0;
+ memset(pIP, '\0', sizeof(*pIP));
+ pIP->sin_family = AF_INET;
+ pIP->sin_port = htons(port);
+ pIP->sin_addr = ipAddr;
+ return 0;
}
/*
@@ -69,68 +44,46 @@ static int initIPAddr (struct in_addr ipAddr, unsigned short port, struct sockad
* "pAddrString" does not contain an address of the form
* "n.n.n.n:p"
*/
-epicsShareFunc int epicsShareAPI
- aToIPAddr(const char *pAddrString, unsigned short defaultPort, struct sockaddr_in *pIP)
+epicsShareFunc int epicsShareAPI
+aToIPAddr(const char *pAddrString, unsigned short defaultPort,
+ struct sockaddr_in *pIP)
{
- int status;
- unsigned short addr[4];
- unsigned long rawAddr;
- char hostName[512]; /* !! change n elements here requires change in format below !! */
- unsigned short port;
- struct in_addr ina;
+ int status;
+ char hostName[512]; /* !! change n elements here requires change in format below !! */
+ char *endp;
+ unsigned int port;
+ unsigned long numaddr;
+ struct in_addr ina;
- /*
- * dotted ip addresses
- */
- status = sscanf (pAddrString, " %hu.%hu.%hu.%hu:%hu",
- addr, addr+1u, addr+2u, addr+3u, &port);
- if (status>0) {
- if (status>=4) {
- if ( addrArrayToUL ( addr, NELEMENTS ( addr ), &ina ) < 0 ) {
- return -1;
- }
- if (status==4) {
- port = defaultPort;
- }
- return initIPAddr (ina, port, pIP);
- }
- else {
- return -1;
- }
- }
-
- /*
- * IP address as a raw number
- */
- status = sscanf ( pAddrString, " %lu:%hu", &rawAddr, &port );
- if (status>=1) {
- if ( rawAddr > 0xffffffff ) {
- return -1;
- }
- if ( status == 1 ) {
- port = defaultPort;
- }
- ina.s_addr = htonl ( rawAddr );
- return initIPAddr ( ina, port, pIP );
- }
-
- /*
- * check for a valid host name before giving up
- */
- status = sscanf ( pAddrString, " %511[^:]:%hu", hostName, &port );
- if ( status >= 1 ) {
- if ( status == 1 ) {
- port = defaultPort;
- }
- status = hostToIPAddr ( hostName, &ina );
- if ( status == 0 ) {
- return initIPAddr ( ina, port, pIP );
- }
- else {
- return -1;
- }
- }
- else {
+ /*
+ * Scan for a port number
+ */
+ status = sscanf( pAddrString, " %511[^:]:%u", hostName, &port );
+ if ( status == 0 ) {
return -1;
}
+ if ( status == 1 ) {
+ port = defaultPort;
+ }
+ else if (status == 2 && port > 65535) {
+ return -1;
+ }
+
+ /*
+ * Look for a valid host name or dotted quad
+ */
+ status = hostToIPAddr( hostName, &ina );
+ if ( status == 0 ) {
+ return initIPAddr( ina, port, pIP );
+ }
+
+ /*
+ * Try the IP address as a decimal integer
+ */
+ numaddr = strtoul( hostName, &endp, 10 );
+ if (*endp)
+ return -1;
+
+ ina.s_addr = htonl( numaddr );
+ return initIPAddr( ina, port, pIP );
}
diff --git a/src/libCom/osi/os/vxWorks/osdSock.c b/src/libCom/osi/os/vxWorks/osdSock.c
index dd6bab973..13798803b 100644
--- a/src/libCom/osi/os/vxWorks/osdSock.c
+++ b/src/libCom/osi/os/vxWorks/osdSock.c
@@ -27,7 +27,7 @@
int osiSockAttach()
{
- return 1;
+ return 1;
}
void osiSockRelease()
@@ -112,27 +112,25 @@ epicsShareFunc unsigned epicsShareAPI ipAddrToHostName
/*
* hostToIPAddr ()
*/
-epicsShareFunc int epicsShareAPI hostToIPAddr
- (const char *pHostName, struct in_addr *pIPA)
+epicsShareFunc int epicsShareAPI
+hostToIPAddr(const char *pHostName, struct in_addr *pIPA)
{
- int addr;
+ int addr;
- addr = hostGetByName ((char *)pHostName);
- if (addr==ERROR) {
- addr = inet_addr ((char *)pHostName);
- if (addr==ERROR) {
- /*
- * return indicating an error
- */
- return -1;
- }
+ addr = hostGetByName((char *)pHostName);
+ if (addr != ERROR) {
+ pIPA->s_addr = (unsigned long) addr;
+ }
+ else if (inet_aton((char *)pHostName, pIPA) == ERROR) {
+ /*
+ * return indicating an error
+ */
+ return -1;
}
- pIPA->s_addr = (unsigned long) addr;
-
- /*
- * success
- */
- return 0;
+ /*
+ * success
+ */
+ return 0;
}
diff --git a/src/libCom/test/Makefile b/src/libCom/test/Makefile
index 9bf92f528..ef89f3875 100644
--- a/src/libCom/test/Makefile
+++ b/src/libCom/test/Makefile
@@ -47,6 +47,11 @@ epicsStdioTest_SRCS += epicsStdioTest.c
testHarness_SRCS += epicsStdioTest.c
TESTS += epicsStdioTest
+TESTPROD_HOST += epicsSockResolveTest
+epicsSockResolveTest_SRCS += epicsSockResolveTest.c
+testHarness_SRCS += epicsSockResolveTest.c
+TESTS += epicsSockResolveTest
+
TESTPROD_HOST += epicsStringTest
epicsStringTest_SRCS += epicsStringTest.c
testHarness_SRCS += epicsStringTest.c
diff --git a/src/libCom/test/epicsRunLibComTests.c b/src/libCom/test/epicsRunLibComTests.c
index 80ddbf3b3..7a6da1e66 100644
--- a/src/libCom/test/epicsRunLibComTests.c
+++ b/src/libCom/test/epicsRunLibComTests.c
@@ -38,6 +38,7 @@ int macEnvExpandTest(void);
int ringPointerTest(void);
int ringBytesTest(void);
int blockingSockTest(void);
+int epicsSockResolveTest(void);
int taskwdTest(void);
int epicsExitTest(void);
@@ -94,6 +95,8 @@ void epicsRunLibComTests(void)
runTest(ringBytesTest);
runTest(blockingSockTest);
+
+ runTest(epicsSockResolveTest);
runTest(taskwdTest);
diff --git a/src/libCom/test/epicsSockResolveTest.c b/src/libCom/test/epicsSockResolveTest.c
new file mode 100644
index 000000000..166a29b90
--- /dev/null
+++ b/src/libCom/test/epicsSockResolveTest.c
@@ -0,0 +1,92 @@
+/*************************************************************************\
+* Copyright (c) 2012 Brookhaven Science Associates as Operator of
+* Brookhaven National Lab.
+* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+\*************************************************************************/
+
+#include "dbDefs.h"
+#include "osiSock.h"
+
+#include "epicsUnitTest.h"
+#include "testMain.h"
+
+#define DEFAULT_PORT 4000
+
+typedef struct {
+ const char *input;
+ unsigned long IP;
+ unsigned short port;
+} testData;
+
+static testData okdata[] = {
+ {"127.0.0.1", 0x7f000001, DEFAULT_PORT},
+ {"127.0.0.1:42", 0x7f000001, 42},
+ {"localhost", 0x7f000001, DEFAULT_PORT},
+ {"localhost:42", 0x7f000001, 42},
+ {"2424", 2424, DEFAULT_PORT},
+ {"2424:42", 2424, 42},
+ {"255.255.255.255", 0xffffffff, DEFAULT_PORT},
+ {"255.255.255.255:65535", 0xffffffff, 65535},
+};
+
+static const char * baddata[] = {
+ "127.0.0.hi",
+ "127.0.0.hi:42",
+ "16invalidhostname",
+ "16invalidhostname:42",
+ "256.255.255.255",
+ "255.256.255.255",
+ "255.255.256.255",
+ "255.255.255.256",
+ "255.255.255.255:65536",
+};
+
+MAIN(epicsSockResolveTest)
+{
+ int i;
+
+ testPlan(3*NELEMENTS(okdata) + NELEMENTS(baddata));
+
+ {
+ struct in_addr addr;
+
+ if (hostToIPAddr("obviously.invalid.host", &addr) == 0) {
+ testAbort("hostToIPAddr() is broken, testing not possible");
+ }
+ }
+
+ testDiag("Tests of aToIPAddr");
+
+ for (i=0; i %d",
+ okdata[i].input, DEFAULT_PORT, ret);
+ if (ret) {
+ testSkip(2, " aToIPAddr() failed");
+ }
+ else {
+ testOk(addr.sin_addr.s_addr == htonl(okdata[i].IP), " IP correct");
+ testOk(addr.sin_port == htons(okdata[i].port), " Port correct");
+ }
+ }
+
+ for (i=0; i %d",
+ baddata[i], DEFAULT_PORT, ret);
+ if (ret==0) {
+ testDiag(" IP=0x%lx, port=%d",
+ (unsigned long) ntohl(addr.sin_addr.s_addr),
+ ntohs(addr.sin_port));
+ }
+ }
+
+ return testDone();
+}