sockaddr.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "fspr_arch_networkio.h"
  17. #include "fspr_strings.h"
  18. #include "fspr.h"
  19. #include "fspr_lib.h"
  20. #include "fspr_strings.h"
  21. #include "fspr_private.h"
  22. #if APR_HAVE_STDLIB_H
  23. #include <stdlib.h>
  24. #endif
  25. #define APR_WANT_STRFUNC
  26. #include "fspr_want.h"
  27. struct fspr_ipsubnet_t {
  28. int family;
  29. #if APR_HAVE_IPV6
  30. fspr_uint32_t sub[4]; /* big enough for IPv4 and IPv6 addresses */
  31. fspr_uint32_t mask[4];
  32. #else
  33. fspr_uint32_t sub[1];
  34. fspr_uint32_t mask[1];
  35. #endif
  36. };
  37. #if !defined(NETWARE) && !defined(WIN32)
  38. #ifdef HAVE_SET_H_ERRNO
  39. #define SET_H_ERRNO(newval) set_h_errno(newval)
  40. #else
  41. #define SET_H_ERRNO(newval) h_errno = (newval)
  42. #endif
  43. #else
  44. #define SET_H_ERRNO(newval)
  45. #endif
  46. #if APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \
  47. defined(HAVE_GETHOSTBYNAME_R)
  48. /* This is the maximum size that may be returned from the reentrant
  49. * gethostbyname_r function. If the system tries to use more, it
  50. * should return ERANGE.
  51. */
  52. #define GETHOSTBYNAME_BUFLEN 512
  53. #endif
  54. #ifdef _WIN32_WCE
  55. /* XXX: BS solution. Need an HAVE_GETSERVBYNAME and actually
  56. * do something here, to provide the obvious proto mappings.
  57. */
  58. static void *getservbyname(const char *name, const char *proto)
  59. {
  60. return NULL;
  61. }
  62. #endif
  63. static fspr_status_t get_local_addr(fspr_socket_t *sock)
  64. {
  65. sock->local_addr->salen = sizeof(sock->local_addr->sa);
  66. if (getsockname(sock->socketdes, (struct sockaddr *)&sock->local_addr->sa,
  67. &sock->local_addr->salen) < 0) {
  68. return fspr_get_netos_error();
  69. }
  70. else {
  71. sock->local_port_unknown = sock->local_interface_unknown = 0;
  72. /* XXX assumes sin_port and sin6_port at same offset */
  73. sock->local_addr->port = ntohs(sock->local_addr->sa.sin.sin_port);
  74. return APR_SUCCESS;
  75. }
  76. }
  77. static fspr_status_t get_remote_addr(fspr_socket_t *sock)
  78. {
  79. sock->remote_addr->salen = sizeof(sock->remote_addr->sa);
  80. if (getpeername(sock->socketdes, (struct sockaddr *)&sock->remote_addr->sa,
  81. &sock->remote_addr->salen) < 0) {
  82. return fspr_get_netos_error();
  83. }
  84. else {
  85. sock->remote_addr_unknown = 0;
  86. /* XXX assumes sin_port and sin6_port at same offset */
  87. sock->remote_addr->port = ntohs(sock->remote_addr->sa.sin.sin_port);
  88. return APR_SUCCESS;
  89. }
  90. }
  91. APR_DECLARE(fspr_status_t) fspr_sockaddr_ip_get(char **addr,
  92. fspr_sockaddr_t *sockaddr)
  93. {
  94. *addr = fspr_palloc(sockaddr->pool, sockaddr->addr_str_len);
  95. fspr_inet_ntop(sockaddr->family,
  96. sockaddr->ipaddr_ptr,
  97. *addr,
  98. sockaddr->addr_str_len);
  99. #if APR_HAVE_IPV6
  100. if (sockaddr->family == AF_INET6 &&
  101. IN6_IS_ADDR_V4MAPPED((struct in6_addr *)sockaddr->ipaddr_ptr)) {
  102. /* This is an IPv4-mapped IPv6 address; drop the leading
  103. * part of the address string so we're left with the familiar
  104. * IPv4 format.
  105. */
  106. *addr += strlen("::ffff:");
  107. }
  108. #endif
  109. return APR_SUCCESS;
  110. }
  111. void fspr_sockaddr_vars_set(fspr_sockaddr_t *addr, int family, fspr_port_t port)
  112. {
  113. addr->family = family;
  114. addr->sa.sin.sin_family = family;
  115. if (port) {
  116. /* XXX IPv6: assumes sin_port and sin6_port at same offset */
  117. addr->sa.sin.sin_port = htons(port);
  118. addr->port = port;
  119. }
  120. if (family == APR_INET) {
  121. addr->salen = sizeof(struct sockaddr_in);
  122. addr->addr_str_len = 16;
  123. addr->ipaddr_ptr = &(addr->sa.sin.sin_addr);
  124. addr->ipaddr_len = sizeof(struct in_addr);
  125. }
  126. #if APR_HAVE_IPV6
  127. else if (family == APR_INET6) {
  128. addr->salen = sizeof(struct sockaddr_in6);
  129. addr->addr_str_len = 46;
  130. addr->ipaddr_ptr = &(addr->sa.sin6.sin6_addr);
  131. addr->ipaddr_len = sizeof(struct in6_addr);
  132. }
  133. #endif
  134. }
  135. APR_DECLARE(fspr_status_t) fspr_socket_addr_get(fspr_sockaddr_t **sa,
  136. fspr_interface_e which,
  137. fspr_socket_t *sock)
  138. {
  139. if (which == APR_LOCAL) {
  140. if (sock->local_interface_unknown || sock->local_port_unknown) {
  141. fspr_status_t rv = get_local_addr(sock);
  142. if (rv != APR_SUCCESS) {
  143. return rv;
  144. }
  145. }
  146. *sa = sock->local_addr;
  147. }
  148. else if (which == APR_REMOTE) {
  149. if (sock->remote_addr_unknown) {
  150. fspr_status_t rv = get_remote_addr(sock);
  151. if (rv != APR_SUCCESS) {
  152. return rv;
  153. }
  154. }
  155. *sa = sock->remote_addr;
  156. }
  157. else {
  158. *sa = NULL;
  159. return APR_EINVAL;
  160. }
  161. return APR_SUCCESS;
  162. }
  163. APR_DECLARE(fspr_status_t) fspr_parse_addr_port(char **addr,
  164. char **scope_id,
  165. fspr_port_t *port,
  166. const char *str,
  167. fspr_pool_t *p)
  168. {
  169. const char *ch, *lastchar;
  170. int big_port;
  171. fspr_size_t addrlen;
  172. *addr = NULL; /* assume not specified */
  173. *scope_id = NULL; /* assume not specified */
  174. *port = 0; /* assume not specified */
  175. /* First handle the optional port number. That may be all that
  176. * is specified in the string.
  177. */
  178. ch = lastchar = str + strlen(str) - 1;
  179. while (ch >= str && fspr_isdigit(*ch)) {
  180. --ch;
  181. }
  182. if (ch < str) { /* Entire string is the port. */
  183. big_port = atoi(str);
  184. if (big_port < 1 || big_port > 65535) {
  185. return APR_EINVAL;
  186. }
  187. *port = big_port;
  188. return APR_SUCCESS;
  189. }
  190. if (*ch == ':' && ch < lastchar) { /* host and port number specified */
  191. if (ch == str) { /* string starts with ':' -- bad */
  192. return APR_EINVAL;
  193. }
  194. big_port = atoi(ch + 1);
  195. if (big_port < 1 || big_port > 65535) {
  196. return APR_EINVAL;
  197. }
  198. *port = big_port;
  199. lastchar = ch - 1;
  200. }
  201. /* now handle the hostname */
  202. addrlen = lastchar - str + 1;
  203. /* XXX we don't really have to require APR_HAVE_IPV6 for this;
  204. * just pass char[] for ipaddr (so we don't depend on struct in6_addr)
  205. * and always define APR_INET6
  206. */
  207. #if APR_HAVE_IPV6
  208. if (*str == '[') {
  209. const char *end_bracket = memchr(str, ']', addrlen);
  210. struct in6_addr ipaddr;
  211. const char *scope_delim;
  212. if (!end_bracket || end_bracket != lastchar) {
  213. *port = 0;
  214. return APR_EINVAL;
  215. }
  216. /* handle scope id; this is the only context where it is allowed */
  217. scope_delim = memchr(str, '%', addrlen);
  218. if (scope_delim) {
  219. if (scope_delim == end_bracket - 1) { /* '%' without scope id */
  220. *port = 0;
  221. return APR_EINVAL;
  222. }
  223. addrlen = scope_delim - str - 1;
  224. *scope_id = fspr_palloc(p, end_bracket - scope_delim);
  225. memcpy(*scope_id, scope_delim + 1, end_bracket - scope_delim - 1);
  226. (*scope_id)[end_bracket - scope_delim - 1] = '\0';
  227. }
  228. else {
  229. addrlen = addrlen - 2; /* minus 2 for '[' and ']' */
  230. }
  231. *addr = fspr_palloc(p, addrlen + 1);
  232. memcpy(*addr,
  233. str + 1,
  234. addrlen);
  235. (*addr)[addrlen] = '\0';
  236. if (fspr_inet_pton(AF_INET6, *addr, &ipaddr) != 1) {
  237. *addr = NULL;
  238. *scope_id = NULL;
  239. *port = 0;
  240. return APR_EINVAL;
  241. }
  242. }
  243. else
  244. #endif
  245. {
  246. /* XXX If '%' is not a valid char in a DNS name, we *could* check
  247. * for bogus scope ids first.
  248. */
  249. *addr = fspr_palloc(p, addrlen + 1);
  250. memcpy(*addr, str, addrlen);
  251. (*addr)[addrlen] = '\0';
  252. }
  253. return APR_SUCCESS;
  254. }
  255. #if defined(HAVE_GETADDRINFO)
  256. static fspr_status_t call_resolver(fspr_sockaddr_t **sa,
  257. const char *hostname, fspr_int32_t family,
  258. fspr_port_t port, fspr_int32_t flags,
  259. fspr_pool_t *p)
  260. {
  261. struct addrinfo hints, *ai, *ai_list;
  262. fspr_sockaddr_t *prev_sa;
  263. int error;
  264. char *servname = NULL;
  265. memset(&hints, 0, sizeof(hints));
  266. hints.ai_family = family;
  267. hints.ai_socktype = SOCK_STREAM;
  268. #ifdef HAVE_GAI_ADDRCONFIG
  269. if (family == APR_UNSPEC) {
  270. /* By default, only look up addresses using address types for
  271. * which a local interface is configured, i.e. no IPv6 if no
  272. * IPv6 interfaces configured. */
  273. hints.ai_flags = AI_ADDRCONFIG;
  274. }
  275. #endif
  276. if(hostname == NULL) {
  277. #ifdef AI_PASSIVE
  278. /* If hostname is NULL, assume we are trying to bind to all
  279. * interfaces. */
  280. hints.ai_flags |= AI_PASSIVE;
  281. #endif
  282. /* getaddrinfo according to RFC 2553 must have either hostname
  283. * or servname non-NULL.
  284. */
  285. #ifdef OSF1
  286. /* The Tru64 5.0 getaddrinfo() can only resolve services given
  287. * by the name listed in /etc/services; a numeric or unknown
  288. * servname gets an EAI_SERVICE error. So just resolve the
  289. * appropriate anyaddr and fill in the port later. */
  290. hostname = family == AF_INET6 ? "::" : "0.0.0.0";
  291. servname = NULL;
  292. #ifdef AI_NUMERICHOST
  293. hints.ai_flags |= AI_NUMERICHOST;
  294. #endif
  295. #else
  296. #ifdef _AIX
  297. /* But current AIX getaddrinfo() doesn't like servname = "0";
  298. * the "1" won't hurt since we use the port parameter to fill
  299. * in the returned socket addresses later
  300. */
  301. if (!port) {
  302. servname = "1";
  303. }
  304. else
  305. #endif /* _AIX */
  306. servname = fspr_itoa(p, port);
  307. #endif /* OSF1 */
  308. }
  309. error = getaddrinfo(hostname, servname, &hints, &ai_list);
  310. #ifdef HAVE_GAI_ADDRCONFIG
  311. if (error == EAI_BADFLAGS && family == APR_UNSPEC) {
  312. /* Retry with no flags if AI_ADDRCONFIG was rejected. */
  313. hints.ai_flags = 0;
  314. error = getaddrinfo(hostname, servname, &hints, &ai_list);
  315. }
  316. #endif
  317. if (error) {
  318. #ifndef WIN32
  319. if (error == EAI_SYSTEM) {
  320. return errno;
  321. }
  322. else
  323. #endif
  324. {
  325. /* issues with representing this with APR's error scheme:
  326. * glibc uses negative values for these numbers, perhaps so
  327. * they don't conflict with h_errno values... Tru64 uses
  328. * positive values which conflict with h_errno values
  329. */
  330. #if defined(NEGATIVE_EAI)
  331. error = -error;
  332. #endif
  333. return error + APR_OS_START_EAIERR;
  334. }
  335. }
  336. prev_sa = NULL;
  337. ai = ai_list;
  338. while (ai) { /* while more addresses to report */
  339. fspr_sockaddr_t *new_sa;
  340. /* Ignore anything bogus: getaddrinfo in some old versions of
  341. * glibc will return AF_UNIX entries for APR_UNSPEC+AI_PASSIVE
  342. * lookups. */
  343. if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
  344. ai = ai->ai_next;
  345. continue;
  346. }
  347. new_sa = fspr_pcalloc(p, sizeof(fspr_sockaddr_t));
  348. new_sa->pool = p;
  349. memcpy(&new_sa->sa, ai->ai_addr, ai->ai_addrlen);
  350. fspr_sockaddr_vars_set(new_sa, ai->ai_family, port);
  351. if (!prev_sa) { /* first element in new list */
  352. if (hostname) {
  353. new_sa->hostname = fspr_pstrdup(p, hostname);
  354. }
  355. *sa = new_sa;
  356. }
  357. else {
  358. new_sa->hostname = prev_sa->hostname;
  359. prev_sa->next = new_sa;
  360. }
  361. prev_sa = new_sa;
  362. ai = ai->ai_next;
  363. }
  364. freeaddrinfo(ai_list);
  365. return APR_SUCCESS;
  366. }
  367. static fspr_status_t find_addresses(fspr_sockaddr_t **sa,
  368. const char *hostname, fspr_int32_t family,
  369. fspr_port_t port, fspr_int32_t flags,
  370. fspr_pool_t *p)
  371. {
  372. if (flags & APR_IPV4_ADDR_OK) {
  373. fspr_status_t error = call_resolver(sa, hostname, AF_INET, port, flags, p);
  374. #if APR_HAVE_IPV6
  375. if (error) {
  376. family = AF_INET6; /* try again */
  377. }
  378. else
  379. #endif
  380. return error;
  381. }
  382. #if APR_HAVE_IPV6
  383. else if (flags & APR_IPV6_ADDR_OK) {
  384. fspr_status_t error = call_resolver(sa, hostname, AF_INET6, port, flags, p);
  385. if (error) {
  386. family = AF_INET; /* try again */
  387. }
  388. else {
  389. return APR_SUCCESS;
  390. }
  391. }
  392. #endif
  393. return call_resolver(sa, hostname, family, port, flags, p);
  394. }
  395. #else /* end of HAVE_GETADDRINFO code */
  396. static fspr_status_t find_addresses(fspr_sockaddr_t **sa,
  397. const char *hostname, fspr_int32_t family,
  398. fspr_port_t port, fspr_int32_t flags,
  399. fspr_pool_t *p)
  400. {
  401. struct hostent *hp;
  402. fspr_sockaddr_t *prev_sa;
  403. int curaddr;
  404. #if APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \
  405. defined(HAVE_GETHOSTBYNAME_R) && !defined(BEOS)
  406. #ifdef GETHOSTBYNAME_R_HOSTENT_DATA
  407. struct hostent_data hd;
  408. #else
  409. /* If you see ERANGE, that means GETHOSBYNAME_BUFLEN needs to be
  410. * bumped. */
  411. char tmp[GETHOSTBYNAME_BUFLEN];
  412. #endif
  413. int hosterror;
  414. #endif
  415. struct hostent hs;
  416. struct in_addr ipaddr;
  417. char *addr_list[2];
  418. const char *orig_hostname = hostname;
  419. if (hostname == NULL) {
  420. /* if we are given a NULL hostname, assume '0.0.0.0' */
  421. hostname = "0.0.0.0";
  422. }
  423. if (*hostname >= '0' && *hostname <= '9' &&
  424. strspn(hostname, "0123456789.") == strlen(hostname)) {
  425. ipaddr.s_addr = inet_addr(hostname);
  426. addr_list[0] = (char *)&ipaddr;
  427. addr_list[1] = NULL; /* just one IP in list */
  428. hs.h_addr_list = (char **)addr_list;
  429. hp = &hs;
  430. }
  431. else {
  432. #if APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \
  433. defined(HAVE_GETHOSTBYNAME_R) && !defined(BEOS)
  434. #if defined(GETHOSTBYNAME_R_HOSTENT_DATA)
  435. /* AIX, HP/UX, D/UX et alia */
  436. gethostbyname_r(hostname, &hs, &hd);
  437. hp = &hs;
  438. #else
  439. #if defined(GETHOSTBYNAME_R_GLIBC2)
  440. /* Linux glibc2+ */
  441. gethostbyname_r(hostname, &hs, tmp, GETHOSTBYNAME_BUFLEN - 1,
  442. &hp, &hosterror);
  443. #else
  444. /* Solaris, Irix et alia */
  445. hp = gethostbyname_r(hostname, &hs, tmp, GETHOSTBYNAME_BUFLEN - 1,
  446. &hosterror);
  447. #endif /* !defined(GETHOSTBYNAME_R_GLIBC2) */
  448. if (!hp) {
  449. return (hosterror + APR_OS_START_SYSERR);
  450. }
  451. #endif /* !defined(GETHOSTBYNAME_R_HOSTENT_DATA) */
  452. #else
  453. hp = gethostbyname(hostname);
  454. #endif
  455. if (!hp) {
  456. #ifdef WIN32
  457. return fspr_get_netos_error();
  458. #else
  459. return (h_errno + APR_OS_START_SYSERR);
  460. #endif
  461. }
  462. }
  463. prev_sa = NULL;
  464. curaddr = 0;
  465. while (hp->h_addr_list[curaddr]) {
  466. fspr_sockaddr_t *new_sa = fspr_pcalloc(p, sizeof(fspr_sockaddr_t));
  467. new_sa->pool = p;
  468. new_sa->sa.sin.sin_addr = *(struct in_addr *)hp->h_addr_list[curaddr];
  469. fspr_sockaddr_vars_set(new_sa, AF_INET, port);
  470. if (!prev_sa) { /* first element in new list */
  471. if (orig_hostname) {
  472. new_sa->hostname = fspr_pstrdup(p, orig_hostname);
  473. }
  474. *sa = new_sa;
  475. }
  476. else {
  477. new_sa->hostname = prev_sa->hostname;
  478. prev_sa->next = new_sa;
  479. }
  480. prev_sa = new_sa;
  481. ++curaddr;
  482. }
  483. return APR_SUCCESS;
  484. }
  485. #endif /* end of !HAVE_GETADDRINFO code */
  486. APR_DECLARE(fspr_status_t) fspr_sockaddr_info_get(fspr_sockaddr_t **sa,
  487. const char *hostname,
  488. fspr_int32_t family, fspr_port_t port,
  489. fspr_int32_t flags, fspr_pool_t *p)
  490. {
  491. fspr_int32_t masked;
  492. *sa = NULL;
  493. if ((masked = flags & (APR_IPV4_ADDR_OK | APR_IPV6_ADDR_OK))) {
  494. if (!hostname ||
  495. family != APR_UNSPEC ||
  496. masked == (APR_IPV4_ADDR_OK | APR_IPV6_ADDR_OK)) {
  497. return APR_EINVAL;
  498. }
  499. #if !APR_HAVE_IPV6
  500. if (flags & APR_IPV6_ADDR_OK) {
  501. return APR_ENOTIMPL;
  502. }
  503. #endif
  504. }
  505. #if !APR_HAVE_IPV6
  506. /* What may happen is that APR is not IPv6-enabled, but we're still
  507. * going to call getaddrinfo(), so we have to tell the OS we only
  508. * want IPv4 addresses back since we won't know what to do with
  509. * IPv6 addresses.
  510. */
  511. if (family == APR_UNSPEC) {
  512. family = APR_INET;
  513. }
  514. #endif
  515. return find_addresses(sa, hostname, family, port, flags, p);
  516. }
  517. APR_DECLARE(fspr_status_t) fspr_getnameinfo(char **hostname,
  518. fspr_sockaddr_t *sockaddr,
  519. fspr_int32_t flags)
  520. {
  521. #if defined(HAVE_GETNAMEINFO)
  522. int rc;
  523. #if defined(NI_MAXHOST)
  524. char tmphostname[NI_MAXHOST];
  525. #else
  526. char tmphostname[256];
  527. #endif
  528. /* don't know if it is portable for getnameinfo() to set h_errno;
  529. * clear it then see if it was set */
  530. SET_H_ERRNO(0);
  531. /* default flags are NI_NAMREQD; otherwise, getnameinfo() will return
  532. * a numeric address string if it fails to resolve the host name;
  533. * that is *not* what we want here
  534. *
  535. * For IPv4-mapped IPv6 addresses, drop down to IPv4 before calling
  536. * getnameinfo() to avoid getnameinfo bugs (MacOS X, glibc).
  537. */
  538. #if APR_HAVE_IPV6
  539. if (sockaddr->family == AF_INET6 &&
  540. IN6_IS_ADDR_V4MAPPED(&sockaddr->sa.sin6.sin6_addr)) {
  541. struct sockaddr_in tmpsa;
  542. tmpsa.sin_family = AF_INET;
  543. tmpsa.sin_port = 0;
  544. tmpsa.sin_addr.s_addr = ((fspr_uint32_t *)sockaddr->ipaddr_ptr)[3];
  545. #ifdef SIN6_LEN
  546. tmpsa.sin_len = sizeof(tmpsa);
  547. #endif
  548. rc = getnameinfo((const struct sockaddr *)&tmpsa, sizeof(tmpsa),
  549. tmphostname, sizeof(tmphostname), NULL, 0,
  550. flags != 0 ? flags : NI_NAMEREQD);
  551. }
  552. else
  553. #endif
  554. rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen,
  555. tmphostname, sizeof(tmphostname), NULL, 0,
  556. flags != 0 ? flags : NI_NAMEREQD);
  557. if (rc != 0) {
  558. *hostname = NULL;
  559. #ifndef WIN32
  560. /* something went wrong. Look at the EAI_ error code */
  561. if (rc == EAI_SYSTEM) {
  562. /* EAI_SYSTEM System error returned in errno. */
  563. /* IMHO, Implementations that set h_errno a simply broken. */
  564. if (h_errno) { /* for broken implementations which set h_errno */
  565. return h_errno + APR_OS_START_SYSERR;
  566. }
  567. else { /* "normal" case */
  568. return errno + APR_OS_START_SYSERR;
  569. }
  570. }
  571. else
  572. #endif
  573. {
  574. #if defined(NEGATIVE_EAI)
  575. if (rc < 0) rc = -rc;
  576. #endif
  577. return rc + APR_OS_START_EAIERR; /* return the EAI_ error */
  578. }
  579. }
  580. *hostname = sockaddr->hostname = fspr_pstrdup(sockaddr->pool,
  581. tmphostname);
  582. return APR_SUCCESS;
  583. #else
  584. #if APR_HAS_THREADS && !defined(GETHOSTBYADDR_IS_THREAD_SAFE) && \
  585. defined(HAVE_GETHOSTBYADDR_R) && !defined(BEOS)
  586. #ifdef GETHOSTBYNAME_R_HOSTENT_DATA
  587. struct hostent_data hd;
  588. #else
  589. char tmp[GETHOSTBYNAME_BUFLEN];
  590. #endif
  591. int hosterror;
  592. struct hostent hs, *hptr;
  593. #if defined(GETHOSTBYNAME_R_HOSTENT_DATA)
  594. /* AIX, HP/UX, D/UX et alia */
  595. gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
  596. sizeof(struct in_addr), AF_INET, &hs, &hd);
  597. hptr = &hs;
  598. #else
  599. #if defined(GETHOSTBYNAME_R_GLIBC2)
  600. /* Linux glibc2+ */
  601. gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
  602. sizeof(struct in_addr), AF_INET,
  603. &hs, tmp, GETHOSTBYNAME_BUFLEN - 1, &hptr, &hosterror);
  604. #else
  605. /* Solaris, Irix et alia */
  606. hptr = gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
  607. sizeof(struct in_addr), AF_INET,
  608. &hs, tmp, GETHOSTBYNAME_BUFLEN, &hosterror);
  609. #endif /* !defined(GETHOSTBYNAME_R_GLIBC2) */
  610. if (!hptr) {
  611. *hostname = NULL;
  612. return hosterror + APR_OS_START_SYSERR;
  613. }
  614. #endif /* !defined(GETHOSTBYNAME_R_HOSTENT_DATA) */
  615. #else
  616. struct hostent *hptr;
  617. hptr = gethostbyaddr((char *)&sockaddr->sa.sin.sin_addr,
  618. sizeof(struct in_addr), AF_INET);
  619. #endif
  620. if (hptr) {
  621. *hostname = sockaddr->hostname = fspr_pstrdup(sockaddr->pool, hptr->h_name);
  622. return APR_SUCCESS;
  623. }
  624. *hostname = NULL;
  625. #if defined(WIN32)
  626. return fspr_get_netos_error();
  627. #elif defined(OS2)
  628. return h_errno;
  629. #else
  630. return h_errno + APR_OS_START_SYSERR;
  631. #endif
  632. #endif
  633. }
  634. APR_DECLARE(fspr_status_t) fspr_getservbyname(fspr_sockaddr_t *sockaddr,
  635. const char *servname)
  636. {
  637. struct servent *se;
  638. if (servname == NULL)
  639. return APR_EINVAL;
  640. if ((se = getservbyname(servname, NULL)) != NULL){
  641. sockaddr->port = htons(se->s_port);
  642. sockaddr->servname = fspr_pstrdup(sockaddr->pool, servname);
  643. sockaddr->sa.sin.sin_port = se->s_port;
  644. return APR_SUCCESS;
  645. }
  646. return errno;
  647. }
  648. #define V4MAPPED_EQUAL(a,b) \
  649. ((a)->sa.sin.sin_family == AF_INET && \
  650. (b)->sa.sin.sin_family == AF_INET6 && \
  651. IN6_IS_ADDR_V4MAPPED((struct in6_addr *)(b)->ipaddr_ptr) && \
  652. !memcmp((a)->ipaddr_ptr, \
  653. &((struct in6_addr *)(b)->ipaddr_ptr)->s6_addr[12], \
  654. (a)->ipaddr_len))
  655. APR_DECLARE(int) fspr_sockaddr_equal(const fspr_sockaddr_t *addr1,
  656. const fspr_sockaddr_t *addr2)
  657. {
  658. if (addr1->ipaddr_len == addr2->ipaddr_len &&
  659. !memcmp(addr1->ipaddr_ptr, addr2->ipaddr_ptr, addr1->ipaddr_len)) {
  660. return 1;
  661. }
  662. #if APR_HAVE_IPV6
  663. if (V4MAPPED_EQUAL(addr1, addr2)) {
  664. return 1;
  665. }
  666. if (V4MAPPED_EQUAL(addr2, addr1)) {
  667. return 1;
  668. }
  669. #endif
  670. return 0; /* not equal */
  671. }
  672. static fspr_status_t parse_network(fspr_ipsubnet_t *ipsub, const char *network)
  673. {
  674. /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
  675. int shift;
  676. char *s, *t;
  677. int octet;
  678. char buf[sizeof "255.255.255.255"];
  679. if (strlen(network) < sizeof buf) {
  680. strcpy(buf, network);
  681. }
  682. else {
  683. return APR_EBADIP;
  684. }
  685. /* parse components */
  686. s = buf;
  687. ipsub->sub[0] = 0;
  688. ipsub->mask[0] = 0;
  689. shift = 24;
  690. while (*s) {
  691. t = s;
  692. if (!fspr_isdigit(*t)) {
  693. return APR_EBADIP;
  694. }
  695. while (fspr_isdigit(*t)) {
  696. ++t;
  697. }
  698. if (*t == '.') {
  699. *t++ = 0;
  700. }
  701. else if (*t) {
  702. return APR_EBADIP;
  703. }
  704. if (shift < 0) {
  705. return APR_EBADIP;
  706. }
  707. octet = atoi(s);
  708. if (octet < 0 || octet > 255) {
  709. return APR_EBADIP;
  710. }
  711. ipsub->sub[0] |= octet << shift;
  712. ipsub->mask[0] |= 0xFFUL << shift;
  713. s = t;
  714. shift -= 8;
  715. }
  716. ipsub->sub[0] = ntohl(ipsub->sub[0]);
  717. ipsub->mask[0] = ntohl(ipsub->mask[0]);
  718. ipsub->family = AF_INET;
  719. return APR_SUCCESS;
  720. }
  721. /* return values:
  722. * APR_EINVAL not an IP address; caller should see if it is something else
  723. * APR_BADIP IP address portion is is not valid
  724. * APR_BADMASK mask portion is not valid
  725. */
  726. static fspr_status_t parse_ip(fspr_ipsubnet_t *ipsub, const char *ipstr, int network_allowed)
  727. {
  728. /* supported flavors of IP:
  729. *
  730. * . IPv6 numeric address string (e.g., "fe80::1")
  731. *
  732. * IMPORTANT: Don't store IPv4-mapped IPv6 address as an IPv6 address.
  733. *
  734. * . IPv4 numeric address string (e.g., "127.0.0.1")
  735. *
  736. * . IPv4 network string (e.g., "9.67")
  737. *
  738. * IMPORTANT: This network form is only allowed if network_allowed is on.
  739. */
  740. int rc;
  741. #if APR_HAVE_IPV6
  742. rc = fspr_inet_pton(AF_INET6, ipstr, ipsub->sub);
  743. if (rc == 1) {
  744. if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ipsub->sub)) {
  745. /* fspr_ipsubnet_test() assumes that we don't create IPv4-mapped IPv6
  746. * addresses; this of course forces the user to specify IPv4 addresses
  747. * in a.b.c.d style instead of ::ffff:a.b.c.d style.
  748. */
  749. return APR_EBADIP;
  750. }
  751. ipsub->family = AF_INET6;
  752. }
  753. else
  754. #endif
  755. {
  756. rc = fspr_inet_pton(AF_INET, ipstr, ipsub->sub);
  757. if (rc == 1) {
  758. ipsub->family = AF_INET;
  759. }
  760. }
  761. if (rc != 1) {
  762. if (network_allowed) {
  763. return parse_network(ipsub, ipstr);
  764. }
  765. else {
  766. return APR_EBADIP;
  767. }
  768. }
  769. return APR_SUCCESS;
  770. }
  771. static int looks_like_ip(const char *ipstr)
  772. {
  773. if (strchr(ipstr, ':')) {
  774. /* definitely not a hostname; assume it is intended to be an IPv6 address */
  775. return 1;
  776. }
  777. /* simple IPv4 address string check */
  778. while ((*ipstr == '.') || fspr_isdigit(*ipstr))
  779. ipstr++;
  780. return (*ipstr == '\0');
  781. }
  782. static void fix_subnet(fspr_ipsubnet_t *ipsub)
  783. {
  784. /* in case caller specified more bits in network address than are
  785. * valid according to the mask, turn off the extra bits
  786. */
  787. int i;
  788. for (i = 0; i < sizeof ipsub->mask / sizeof(fspr_int32_t); i++) {
  789. ipsub->sub[i] &= ipsub->mask[i];
  790. }
  791. }
  792. /* be sure not to store any IPv4 address as a v4-mapped IPv6 address */
  793. APR_DECLARE(fspr_status_t) fspr_ipsubnet_create(fspr_ipsubnet_t **ipsub, const char *ipstr,
  794. const char *mask_or_numbits, fspr_pool_t *p)
  795. {
  796. fspr_status_t rv;
  797. char *endptr;
  798. long bits, maxbits = 32;
  799. /* filter out stuff which doesn't look remotely like an IP address; this helps
  800. * callers like mod_access which have a syntax allowing hostname or IP address;
  801. * APR_EINVAL tells the caller that it was probably not intended to be an IP
  802. * address
  803. */
  804. if (!looks_like_ip(ipstr)) {
  805. return APR_EINVAL;
  806. }
  807. *ipsub = fspr_pcalloc(p, sizeof(fspr_ipsubnet_t));
  808. /* assume ipstr is an individual IP address, not a subnet */
  809. memset((*ipsub)->mask, 0xFF, sizeof (*ipsub)->mask);
  810. rv = parse_ip(*ipsub, ipstr, mask_or_numbits == NULL);
  811. if (rv != APR_SUCCESS) {
  812. return rv;
  813. }
  814. if (mask_or_numbits) {
  815. #if APR_HAVE_IPV6
  816. if ((*ipsub)->family == AF_INET6) {
  817. maxbits = 128;
  818. }
  819. #endif
  820. bits = strtol(mask_or_numbits, &endptr, 10);
  821. if (*endptr == '\0' && bits > 0 && bits <= maxbits) {
  822. /* valid num-bits string; fill in mask appropriately */
  823. int cur_entry = 0;
  824. fspr_int32_t cur_bit_value;
  825. memset((*ipsub)->mask, 0, sizeof (*ipsub)->mask);
  826. while (bits > 32) {
  827. (*ipsub)->mask[cur_entry] = 0xFFFFFFFF; /* all 32 bits */
  828. bits -= 32;
  829. ++cur_entry;
  830. }
  831. cur_bit_value = 0x80000000;
  832. while (bits) {
  833. (*ipsub)->mask[cur_entry] |= cur_bit_value;
  834. --bits;
  835. cur_bit_value /= 2;
  836. }
  837. (*ipsub)->mask[cur_entry] = htonl((*ipsub)->mask[cur_entry]);
  838. }
  839. else if (fspr_inet_pton(AF_INET, mask_or_numbits, (*ipsub)->mask) == 1 &&
  840. (*ipsub)->family == AF_INET) {
  841. /* valid IPv4 netmask */
  842. }
  843. else {
  844. return APR_EBADMASK;
  845. }
  846. }
  847. fix_subnet(*ipsub);
  848. return APR_SUCCESS;
  849. }
  850. APR_DECLARE(int) fspr_ipsubnet_test(fspr_ipsubnet_t *ipsub, fspr_sockaddr_t *sa)
  851. {
  852. #if APR_HAVE_IPV6
  853. /* XXX This line will segv on Win32 build with APR_HAVE_IPV6,
  854. * but without the IPV6 drivers installed.
  855. */
  856. if (sa->sa.sin.sin_family == AF_INET) {
  857. if (ipsub->family == AF_INET &&
  858. ((sa->sa.sin.sin_addr.s_addr & ipsub->mask[0]) == ipsub->sub[0])) {
  859. return 1;
  860. }
  861. }
  862. else if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)sa->ipaddr_ptr)) {
  863. if (ipsub->family == AF_INET &&
  864. (((fspr_uint32_t *)sa->ipaddr_ptr)[3] & ipsub->mask[0]) == ipsub->sub[0]) {
  865. return 1;
  866. }
  867. }
  868. else {
  869. fspr_uint32_t *addr = (fspr_uint32_t *)sa->ipaddr_ptr;
  870. if ((addr[0] & ipsub->mask[0]) == ipsub->sub[0] &&
  871. (addr[1] & ipsub->mask[1]) == ipsub->sub[1] &&
  872. (addr[2] & ipsub->mask[2]) == ipsub->sub[2] &&
  873. (addr[3] & ipsub->mask[3]) == ipsub->sub[3]) {
  874. return 1;
  875. }
  876. }
  877. #else
  878. if ((sa->sa.sin.sin_addr.s_addr & ipsub->mask[0]) == ipsub->sub[0]) {
  879. return 1;
  880. }
  881. #endif /* APR_HAVE_IPV6 */
  882. return 0; /* no match */
  883. }