This is Unofficial EPICS BASE Doxygen Site
aToIPAddr.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2013 LANS LLC, as Operator of
3 * Los Alamos National Laboratory.
4 * Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
5 * National Laboratory.
6 * EPICS BASE is distributed subject to a Software License Agreement found
7 * in file LICENSE that is included with this distribution.
8 \*************************************************************************/
9 /*
10  * rational replacement for inet_addr()
11  *
12  * author: Jeff Hill
13  */
14 #include <stdio.h>
15 #include <string.h>
16 
17 #include "epicsTypes.h"
18 #include "osiSock.h"
19 
20 #ifndef NELEMENTS
21 #define NELEMENTS(A) (sizeof(A)/sizeof(A[0]))
22 #endif /*NELEMENTS*/
23 
24 /*
25  * addrArrayToUL ()
26  */
27 static int addrArrayToUL ( const unsigned *pAddr,
28  unsigned nElements, struct in_addr *pIpAddr )
29 {
30  unsigned i;
31  epicsUInt32 addr = 0ul;
32 
33  for ( i=0u; i < nElements; i++ ) {
34  if ( pAddr[i] > 0xff ) {
35  return -1;
36  }
37  addr <<= 8;
38  addr |= ( epicsUInt32 ) pAddr[i];
39  }
40  pIpAddr->s_addr = htonl ( addr );
41 
42  return 0;
43 }
44 
45 /*
46  * initIPAddr()
47  * !! ipAddr should be passed in in network byte order !!
48  * !! port is passed in in host byte order !!
49  */
50 static int initIPAddr ( struct in_addr ipAddr, unsigned port,
51  struct sockaddr_in *pIP )
52 {
53  if ( port > 0xffff ) {
54  return -1;
55  }
56  {
57  epicsUInt16 port_16 = (epicsUInt16) port;
58  memset (pIP, '\0', sizeof(*pIP));
59  pIP->sin_family = AF_INET;
60  pIP->sin_port = htons(port_16);
61  pIP->sin_addr = ipAddr;
62  }
63  return 0;
64 }
65 
66 /*
67  * rational replacement for inet_addr()
68  * which allows the limited broadcast address
69  * 255.255.255.255, allows the user
70  * to specify a port number, and allows also a
71  * named host to be specified.
72  *
73  * Sets the port number to "defaultPort" only if
74  * "pAddrString" does not contain an address of the form
75  * "n.n.n.n:p or host:p"
76  */
77 LIBCOM_API int epicsStdCall
78 aToIPAddr( const char *pAddrString, unsigned short defaultPort,
79  struct sockaddr_in *pIP )
80 {
81  int status;
82  unsigned addr[4];
83  unsigned long rawAddr;
84  /*
85  * !! change n elements here requires change in format below !!
86  */
87  char hostName[512];
88  char dummy[8];
89  unsigned port;
90  struct in_addr ina;
91 
92  /*
93  * dotted ip addresses
94  */
95  status = sscanf ( pAddrString, " %u . %u . %u . %u %7s ",
96  addr, addr+1u, addr+2u, addr+3u, dummy );
97  if ( status == 4 ) {
98  if ( addrArrayToUL ( addr, NELEMENTS ( addr ), & ina ) < 0 ) {
99  return -1;
100  }
101  port = defaultPort;
102  return initIPAddr ( ina, port, pIP );
103  }
104 
105  /*
106  * dotted ip addresses and port
107  */
108  status = sscanf ( pAddrString, " %u . %u . %u . %u : %u %7s",
109  addr, addr+1u, addr+2u, addr+3u, &port, dummy );
110  if ( status >= 5 ) {
111  if ( status > 5 ) {
112  /*
113  * valid at the start but detritus on the end
114  */
115  return -1;
116  }
117  if ( addrArrayToUL ( addr, NELEMENTS ( addr ), &ina ) < 0 ) {
118  return -1;
119  }
120  return initIPAddr ( ina, port, pIP );
121  }
122 
123  /*
124  * IP address as a raw number
125  */
126  status = sscanf ( pAddrString, " %lu %7s ", &rawAddr, dummy );
127  if ( status == 1 ) {
128  if ( rawAddr > 0xffffffff ) {
129  return -1;
130  }
131  port = defaultPort;
132  {
133  epicsUInt32 rawAddr_32 = ( epicsUInt32 ) rawAddr;
134  ina.s_addr = htonl ( rawAddr_32 );
135  return initIPAddr ( ina, port, pIP );
136  }
137  }
138 
139  /*
140  * IP address as a raw number, and port
141  */
142  status = sscanf ( pAddrString, " %lu : %u %7s ", &rawAddr, &port, dummy );
143  if ( status >= 2 ) {
144  if ( status > 2 ) {
145  /*
146  * valid at the start but detritus on the end
147  */
148  return -1;
149  }
150  if ( rawAddr > 0xffffffff ) {
151  return -1;
152  }
153  {
154  epicsUInt32 rawAddr_32 = ( epicsUInt32 ) rawAddr;
155  ina.s_addr = htonl ( rawAddr_32 );
156  return initIPAddr ( ina, port, pIP );
157  }
158  }
159 
160 
161  /*
162  * host name string
163  */
164  status = sscanf ( pAddrString, " %511[^:] %s ", hostName, dummy );
165  if ( status == 1 ) {
166  port = defaultPort;
167  status = hostToIPAddr ( hostName, &ina );
168  if ( status == 0 ) {
169  return initIPAddr ( ina, port, pIP );
170  }
171  }
172 
173  /*
174  * host name string, and port
175  */
176  status = sscanf ( pAddrString, " %511[^:] : %u %s ", hostName,
177  &port, dummy );
178  if ( status >= 2 ) {
179  if ( status > 2 ) {
180  /*
181  * valid at the start but detritus on the end
182  */
183  return -1;
184  }
185  status = hostToIPAddr ( hostName, &ina );
186  if ( status == 0 ) {
187  return initIPAddr ( ina, port, pIP );
188  }
189  }
190 
191  return -1;
192 }
LIBCOM_API int epicsStdCall aToIPAddr(const char *pAddrString, unsigned short defaultPort, struct sockaddr_in *pIP)
Definition: aToIPAddr.c:78
pvd::Status status
int i
Definition: scan.c:967
unsigned short epicsUInt16
Definition: epicsTypes.h:41
LIBCOM_API int epicsStdCall hostToIPAddr(const char *pHostName, struct in_addr *pIPA)
Definition: osdSock.c:162
unsigned int epicsUInt32
Definition: epicsTypes.h:43
#define NELEMENTS(A)
Definition: aToIPAddr.c:21
epics::pvData::PVStructurePtr dummy
Definition: pvAccess.cpp:72