libCom: Back-ported aToIPAddr fix from 3.15 branch.
Cherry-picked 3.15 revno 12398 with some changes.
This commit is contained in:
@@ -13,6 +13,13 @@
|
||||
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
|
||||
<h3>Improvements to aToIPAddr()</h3>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<h4>Added osdFindSymbol for Windows</h4>
|
||||
|
||||
<p>Dirk Zimoch implemented the epicsLoadLibrary(), epicsLoadError() and
|
||||
|
||||
@@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#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 );
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
92
src/libCom/test/epicsSockResolveTest.c
Normal file
92
src/libCom/test/epicsSockResolveTest.c
Normal file
@@ -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<NELEMENTS(okdata); i++) {
|
||||
struct sockaddr_in addr;
|
||||
int ret;
|
||||
|
||||
ret = aToIPAddr(okdata[i].input, DEFAULT_PORT, &addr);
|
||||
testOk(ret==0, "aToIPAddr(\"%s\", %u) -> %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<NELEMENTS(baddata); i++) {
|
||||
struct sockaddr_in addr;
|
||||
int ret;
|
||||
|
||||
ret = aToIPAddr(baddata[i], DEFAULT_PORT, &addr);
|
||||
testOk(ret!=0, "aToIPAddr(\"%s\", %u) -> %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();
|
||||
}
|
||||
Reference in New Issue
Block a user