apr  1.7.0
About: APR (Apache Portable Runtime) project offers software libraries that provide a predictable and consistent interface to underlying platform-specific implementations (APR core library).
  Fossies Dox: apr-1.7.0.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

sockaddr.c
Go to the documentation of this file.
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 
17 #include "apr_arch_networkio.h"
18 #include "apr_strings.h"
19 #include "apr.h"
20 #include "apr_lib.h"
21 #include "apr_strings.h"
22 #include "apr_private.h"
23 
24 #if APR_HAVE_STDLIB_H
25 #include <stdlib.h>
26 #endif
27 
28 #ifdef HAVE_NET_IF_H
29 #include <net/if.h>
30 #endif
31 
32 #if defined(HAVE_IF_INDEXTONAME) && defined(_MSC_VER)
34 #endif
35 
36 #define APR_WANT_STRFUNC
37 #include "apr_want.h"
38 
40  int family;
41 #if APR_HAVE_IPV6
42  apr_uint32_t sub[4]; /* big enough for IPv4 and IPv6 addresses */
43  apr_uint32_t mask[4];
44 #else
45  apr_uint32_t sub[1];
46  apr_uint32_t mask[1];
47 #endif
48 };
49 
50 #if !defined(NETWARE) && !defined(WIN32)
51 #ifdef HAVE_SET_H_ERRNO
52 #define SET_H_ERRNO(newval) set_h_errno(newval)
53 #else
54 #define SET_H_ERRNO(newval) h_errno = (newval)
55 #endif
56 #else
57 #define SET_H_ERRNO(newval)
58 #endif
59 
60 #if APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \
61  defined(HAVE_GETHOSTBYNAME_R)
62 /* This is the maximum size that may be returned from the reentrant
63  * gethostbyname_r function. If the system tries to use more, it
64  * should return ERANGE.
65  */
66 #define GETHOSTBYNAME_BUFLEN 512
67 #endif
68 
69 #ifdef _AIX
70 /* Some levels of AIX getaddrinfo() don't like servname = "0", so
71  * set servname to "1" when port is 0 and fix it up later.
72  */
73 #define AIX_SERVNAME_HACK 1
74 #else
75 #define AIX_SERVNAME_HACK 0
76 #endif
77 
78 #ifdef _WIN32_WCE
79 /* XXX: BS solution. Need an HAVE_GETSERVBYNAME and actually
80  * do something here, to provide the obvious proto mappings.
81  */
82 static void *getservbyname(const char *name, const char *proto)
83 {
84  return NULL;
85 }
86 #endif
87 
89 {
90  sock->local_addr->salen = sizeof(sock->local_addr->sa);
91  if (getsockname(sock->socketdes, (struct sockaddr *)&sock->local_addr->sa,
92  &sock->local_addr->salen) < 0) {
93  return apr_get_netos_error();
94  }
95  else {
97  /* XXX assumes sin_port and sin6_port at same offset */
98  sock->local_addr->port = ntohs(sock->local_addr->sa.sin.sin_port);
99  return APR_SUCCESS;
100  }
101 }
102 
104 {
105  sock->remote_addr->salen = sizeof(sock->remote_addr->sa);
106  if (getpeername(sock->socketdes, (struct sockaddr *)&sock->remote_addr->sa,
107  &sock->remote_addr->salen) < 0) {
108  return apr_get_netos_error();
109  }
110  else {
112  /* XXX assumes sin_port and sin6_port at same offset */
113  sock->remote_addr->port = ntohs(sock->remote_addr->sa.sin.sin_port);
114  return APR_SUCCESS;
115  }
116 }
117 
118 APR_DECLARE(apr_status_t) apr_sockaddr_ip_getbuf(char *buf, apr_size_t buflen,
120 {
122  return APR_ENOSPC;
123  }
124 
125 #if APR_HAVE_IPV6
126  if (sockaddr->family == AF_INET6
127  && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)sockaddr->ipaddr_ptr)
128  && buflen > strlen("::ffff:")) {
129  /* This is an IPv4-mapped IPv6 address; drop the leading
130  * part of the address string so we're left with the familiar
131  * IPv4 format.
132  */
133  memmove(buf, buf + strlen("::ffff:"),
134  strlen(buf + strlen("::ffff:"))+1);
135  }
136 
137  /* ensure NUL termination if the buffer is too short */
138  buf[buflen-1] = '\0';
139 
140 #ifdef HAVE_IF_INDEXTONAME
141  /* Append scope name for link-local addresses. */
142  if (sockaddr->family == AF_INET6
143  && IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)sockaddr->ipaddr_ptr)) {
144  char scbuf[IF_NAMESIZE], *p = buf + strlen(buf);
145 
146  if (if_indextoname(sockaddr->sa.sin6.sin6_scope_id, scbuf) == scbuf) {
147  /* Space check, need room for buf + '%' + scope + '\0'.
148  * Assert: buflen >= strlen(buf) + strlen(scbuf) + 2
149  * Equiv: buflen >= (p-buf) + strlen(buf) + 2
150  * Thus, fail in inverse condition: */
151  if (buflen < strlen(scbuf) + (p - buf) + 2) {
152  return APR_ENOSPC;
153  }
154  *p++ = '%';
155  memcpy(p, scbuf, strlen(scbuf) + 1);
156  }
157  }
158 #endif /* HAVE_IF_INDEXTONAME */
159 #endif /* APR_HAVE_IPV6 */
160 
161  return APR_SUCCESS;
162 }
163 
164 APR_DECLARE(apr_status_t) apr_sockaddr_ip_get(char **addr,
166 {
167  *addr = apr_palloc(sockaddr->pool, sockaddr->addr_str_len);
168  return apr_sockaddr_ip_getbuf(*addr, sockaddr->addr_str_len, sockaddr);
169 }
170 
172 {
173  addr->family = family;
174  addr->sa.sin.sin_family = family;
175  if (port) {
176  /* XXX IPv6: assumes sin_port and sin6_port at same offset */
177  addr->sa.sin.sin_port = htons(port);
178  addr->port = port;
179  }
180 #if AIX_SERVNAME_HACK
181  else {
182  addr->sa.sin.sin_port = htons(port);
183  }
184 #endif
185 
186  if (family == APR_INET) {
187  addr->salen = sizeof(struct sockaddr_in);
188  addr->addr_str_len = 16;
189  addr->ipaddr_ptr = &(addr->sa.sin.sin_addr);
190  addr->ipaddr_len = sizeof(struct in_addr);
191  }
192 #if APR_HAVE_IPV6
193  else if (family == APR_INET6) {
194  addr->salen = sizeof(struct sockaddr_in6);
195  addr->addr_str_len = 46;
196  addr->ipaddr_ptr = &(addr->sa.sin6.sin6_addr);
197  addr->ipaddr_len = sizeof(struct in6_addr);
198  }
199 #endif
200 #if APR_HAVE_SOCKADDR_UN
201  else if (family == APR_UNIX) {
202  addr->salen = sizeof(struct sockaddr_un);
203  addr->addr_str_len = sizeof(addr->sa.unx.sun_path);;
204  addr->ipaddr_ptr = &(addr->sa.unx.sun_path);
206  }
207 #endif
208 }
209 
210 APR_DECLARE(apr_status_t) apr_socket_addr_get(apr_sockaddr_t **sa,
213 {
214  if (which == APR_LOCAL) {
217 
218  if (rv != APR_SUCCESS) {
219  return rv;
220  }
221  }
222  *sa = sock->local_addr;
223  }
224  else if (which == APR_REMOTE) {
225  if (sock->remote_addr_unknown) {
227 
228  if (rv != APR_SUCCESS) {
229  return rv;
230  }
231  }
232  *sa = sock->remote_addr;
233  }
234  else {
235  *sa = NULL;
236  return APR_EINVAL;
237  }
238  return APR_SUCCESS;
239 }
240 
241 APR_DECLARE(apr_status_t) apr_parse_addr_port(char **addr,
242  char **scope_id,
243  apr_port_t *port,
244  const char *str,
245  apr_pool_t *p)
246 {
247  const char *ch, *lastchar;
248  int big_port;
249  apr_size_t addrlen;
250 
251  *addr = NULL; /* assume not specified */
252  *scope_id = NULL; /* assume not specified */
253  *port = 0; /* assume not specified */
254 
255  /* First handle the optional port number. That may be all that
256  * is specified in the string.
257  */
258  ch = lastchar = str + strlen(str) - 1;
259  while (ch >= str && apr_isdigit(*ch)) {
260  --ch;
261  }
262 
263  if (ch < str) { /* Entire string is the port. */
264  big_port = atoi(str);
265  if (big_port < 1 || big_port > 65535) {
266  return APR_EINVAL;
267  }
268  *port = big_port;
269  return APR_SUCCESS;
270  }
271 
272  if (*ch == ':' && ch < lastchar) { /* host and port number specified */
273  if (ch == str) { /* string starts with ':' -- bad */
274  return APR_EINVAL;
275  }
276  big_port = atoi(ch + 1);
277  if (big_port < 1 || big_port > 65535) {
278  return APR_EINVAL;
279  }
280  *port = big_port;
281  lastchar = ch - 1;
282  }
283 
284  /* now handle the hostname */
285  addrlen = lastchar - str + 1;
286 
287 /* XXX we don't really have to require APR_HAVE_IPV6 for this;
288  * just pass char[] for ipaddr (so we don't depend on struct in6_addr)
289  * and always define APR_INET6
290  */
291 #if APR_HAVE_IPV6
292  if (*str == '[') {
293  const char *end_bracket = memchr(str, ']', addrlen);
294  struct in6_addr ipaddr;
295  const char *scope_delim;
296 
297  if (!end_bracket || end_bracket != lastchar) {
298  *port = 0;
299  return APR_EINVAL;
300  }
301 
302  /* handle scope id; this is the only context where it is allowed */
303  scope_delim = memchr(str, '%', addrlen);
304  if (scope_delim) {
305  if (scope_delim == end_bracket - 1) { /* '%' without scope id */
306  *port = 0;
307  return APR_EINVAL;
308  }
309  addrlen = scope_delim - str - 1;
310  *scope_id = apr_pstrmemdup(p, scope_delim + 1, end_bracket - scope_delim - 1);
311  }
312  else {
313  addrlen = addrlen - 2; /* minus 2 for '[' and ']' */
314  }
315 
316  *addr = apr_pstrmemdup(p, str + 1, addrlen);
317  if (apr_inet_pton(AF_INET6, *addr, &ipaddr) != 1) {
318  *addr = NULL;
319  *scope_id = NULL;
320  *port = 0;
321  return APR_EINVAL;
322  }
323  }
324  else
325 #endif
326  {
327  /* XXX If '%' is not a valid char in a DNS name, we *could* check
328  * for bogus scope ids first.
329  */
330  *addr = apr_pstrmemdup(p, str, addrlen);
331  }
332  return APR_SUCCESS;
333 }
334 
335 #if defined(HAVE_GETADDRINFO)
336 
337 static apr_status_t call_resolver(apr_sockaddr_t **sa,
338  const char *hostname, apr_int32_t family,
339  apr_port_t port, apr_int32_t flags,
340  apr_pool_t *p)
341 {
342  struct addrinfo hints, *ai, *ai_list;
343  apr_sockaddr_t *prev_sa;
344  int error;
345  char *servname = NULL;
346 
347  memset(&hints, 0, sizeof(hints));
348  hints.ai_family = family;
349  hints.ai_socktype = SOCK_STREAM;
350 #ifdef HAVE_GAI_ADDRCONFIG
351  if (family == APR_UNSPEC) {
352  /* By default, only look up addresses using address types for
353  * which a local interface is configured, i.e. no IPv6 if no
354  * IPv6 interfaces configured. */
355  hints.ai_flags = AI_ADDRCONFIG;
356  }
357 #endif
358 
359 #ifdef __MVS__
360  /* z/OS will not return IPv4 address under AF_UNSPEC if any IPv6 results
361  * are returned, w/o AI_ALL.
362  */
363  if (family == APR_UNSPEC) {
364  hints.ai_flags |= AI_ALL;
365  }
366 #endif
367 
368  if(hostname == NULL) {
369 #ifdef AI_PASSIVE
370  /* If hostname is NULL, assume we are trying to bind to all
371  * interfaces. */
372  hints.ai_flags |= AI_PASSIVE;
373 #endif
374  /* getaddrinfo according to RFC 2553 must have either hostname
375  * or servname non-NULL.
376  */
377 #ifdef OSF1
378  /* The Tru64 5.0 getaddrinfo() can only resolve services given
379  * by the name listed in /etc/services; a numeric or unknown
380  * servname gets an EAI_SERVICE error. So just resolve the
381  * appropriate anyaddr and fill in the port later. */
382  hostname = family == AF_INET6 ? "::" : "0.0.0.0";
383  servname = NULL;
384 #ifdef AI_NUMERICHOST
385  hints.ai_flags |= AI_NUMERICHOST;
386 #endif
387 #else
388 #if AIX_SERVNAME_HACK
389  if (!port) {
390  servname = "1";
391  }
392  else
393 #endif /* AIX_SERVNAME_HACK */
394  servname = apr_itoa(p, port);
395 #endif /* OSF1 */
396  }
397  error = getaddrinfo(hostname, servname, &hints, &ai_list);
398 #ifdef HAVE_GAI_ADDRCONFIG
399  /*
400  * Using AI_ADDRCONFIG involves some unfortunate guesswork because it
401  * does not consider loopback addresses when trying to determine if
402  * IPv4 or IPv6 is configured on a system (see RFC 3493).
403  * This is a problem if one actually wants to listen on or connect to
404  * the loopback address of a protocol family that is not otherwise
405  * configured on the system. See PR 52709.
406  * To work around some of the problems, retry without AI_ADDRCONFIG
407  * in case of EAI_ADDRFAMILY.
408  * XXX: apr_sockaddr_info_get() should really accept a flag to determine
409  * XXX: if AI_ADDRCONFIG's guesswork is wanted and if the address is
410  * XXX: to be used for listen() or connect().
411  *
412  * In case of EAI_BADFLAGS, AI_ADDRCONFIG is not supported.
413  */
414  if ((family == APR_UNSPEC) && (error == EAI_BADFLAGS
415 #ifdef EAI_ADDRFAMILY
416  || error == EAI_ADDRFAMILY
417 #endif
418  )) {
419  hints.ai_flags &= ~AI_ADDRCONFIG;
420  error = getaddrinfo(hostname, servname, &hints, &ai_list);
421  }
422 #endif
423  if (error) {
424 #if defined(WIN32)
425  return apr_get_netos_error();
426 #else
427  if (error == EAI_SYSTEM) {
428  return errno ? errno : APR_EGENERAL;
429  }
430  else
431  {
432  /* issues with representing this with APR's error scheme:
433  * glibc uses negative values for these numbers, perhaps so
434  * they don't conflict with h_errno values... Tru64 uses
435  * positive values which conflict with h_errno values
436  */
437 #if defined(NEGATIVE_EAI)
438  error = -error;
439 #endif
440  return error + APR_OS_START_EAIERR;
441  }
442 #endif /* WIN32 */
443  }
444 
445  prev_sa = NULL;
446  ai = ai_list;
447  while (ai) { /* while more addresses to report */
448  apr_sockaddr_t *new_sa;
449 
450  /* Ignore anything bogus: getaddrinfo in some old versions of
451  * glibc will return AF_UNIX entries for APR_UNSPEC+AI_PASSIVE
452  * lookups. */
453 #if APR_HAVE_IPV6
454  if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
455 #else
456  if (ai->ai_family != AF_INET) {
457 #endif
458  ai = ai->ai_next;
459  continue;
460  }
461 
462  new_sa = apr_pcalloc(p, sizeof(apr_sockaddr_t));
463 
464  new_sa->pool = p;
465  memcpy(&new_sa->sa, ai->ai_addr, ai->ai_addrlen);
466  apr_sockaddr_vars_set(new_sa, ai->ai_family, port);
467 
468  if (!prev_sa) { /* first element in new list */
469  if (hostname) {
470  new_sa->hostname = apr_pstrdup(p, hostname);
471  }
472  *sa = new_sa;
473  }
474  else {
475  new_sa->hostname = prev_sa->hostname;
476  prev_sa->next = new_sa;
477  }
478 
479  prev_sa = new_sa;
480  ai = ai->ai_next;
481  }
482  freeaddrinfo(ai_list);
483 
484  if (prev_sa == NULL) {
485  /*
486  * getaddrinfo returned only useless entries and *sa is still empty.
487  * This should be treated as an error.
488  */
489  return APR_EGENERAL;
490  }
491 
492  return APR_SUCCESS;
493 }
494 
496  const char *hostname, apr_int32_t family,
497  apr_port_t port, apr_int32_t flags,
498  apr_pool_t *p)
499 {
500  if (flags & APR_IPV4_ADDR_OK) {
501  apr_status_t error = call_resolver(sa, hostname, AF_INET, port, flags, p);
502 
503 #if APR_HAVE_IPV6
504  if (error) {
505  family = AF_INET6; /* try again */
506  }
507  else
508 #endif
509  return error;
510  }
511 #if APR_HAVE_IPV6
512  else if (flags & APR_IPV6_ADDR_OK) {
513  apr_status_t error = call_resolver(sa, hostname, AF_INET6, port, flags, p);
514 
515  if (error) {
516  family = AF_INET; /* try again */
517  }
518  else {
519  return APR_SUCCESS;
520  }
521  }
522 #endif
523 
524  return call_resolver(sa, hostname, family, port, flags, p);
525 }
526 
527 #else /* end of HAVE_GETADDRINFO code */
528 
530  const char *hostname, apr_int32_t family,
531  apr_port_t port, apr_int32_t flags,
532  apr_pool_t *p)
533 {
534  struct hostent *hp;
535  apr_sockaddr_t *prev_sa;
536  int curaddr;
537 #if APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \
538  defined(HAVE_GETHOSTBYNAME_R) && !defined(BEOS)
539 #ifdef GETHOSTBYNAME_R_HOSTENT_DATA
540  struct hostent_data hd;
541 #else
542  /* If you see ERANGE, that means GETHOSBYNAME_BUFLEN needs to be
543  * bumped. */
544  char tmp[GETHOSTBYNAME_BUFLEN];
545 #endif
546  int hosterror;
547 #endif
548  struct hostent hs;
549  struct in_addr ipaddr;
550  char *addr_list[2];
551  const char *orig_hostname = hostname;
552 
553  if (hostname == NULL) {
554  /* if we are given a NULL hostname, assume '0.0.0.0' */
555  hostname = "0.0.0.0";
556  }
557 
558  if (*hostname >= '0' && *hostname <= '9' &&
559  strspn(hostname, "0123456789.") == strlen(hostname)) {
560 
561  ipaddr.s_addr = inet_addr(hostname);
562  addr_list[0] = (char *)&ipaddr;
563  addr_list[1] = NULL; /* just one IP in list */
564  hs.h_addr_list = (char **)addr_list;
565  hp = &hs;
566  }
567  else {
568 #if APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \
569  defined(HAVE_GETHOSTBYNAME_R) && !defined(BEOS)
570 #if defined(GETHOSTBYNAME_R_HOSTENT_DATA)
571  /* AIX, HP/UX, D/UX et alia */
572  gethostbyname_r(hostname, &hs, &hd);
573  hp = &hs;
574 #else
575 #if defined(GETHOSTBYNAME_R_GLIBC2)
576  /* Linux glibc2+ */
577  gethostbyname_r(hostname, &hs, tmp, GETHOSTBYNAME_BUFLEN - 1,
578  &hp, &hosterror);
579 #else
580  /* Solaris, Irix et alia */
581  hp = gethostbyname_r(hostname, &hs, tmp, GETHOSTBYNAME_BUFLEN - 1,
582  &hosterror);
583 #endif /* !defined(GETHOSTBYNAME_R_GLIBC2) */
584  if (!hp) {
585  return (hosterror + APR_OS_START_SYSERR);
586  }
587 #endif /* !defined(GETHOSTBYNAME_R_HOSTENT_DATA) */
588 #else
589  hp = gethostbyname(hostname);
590 #endif
591 
592  if (!hp) {
593 #ifdef WIN32
594  return apr_get_netos_error();
595 #else
596  return (h_errno + APR_OS_START_SYSERR);
597 #endif
598  }
599  }
600 
601  prev_sa = NULL;
602  curaddr = 0;
603  while (hp->h_addr_list[curaddr]) {
604  apr_sockaddr_t *new_sa = apr_pcalloc(p, sizeof(apr_sockaddr_t));
605 
606  new_sa->pool = p;
607  new_sa->sa.sin.sin_addr = *(struct in_addr *)hp->h_addr_list[curaddr];
608  apr_sockaddr_vars_set(new_sa, AF_INET, port);
609 
610  if (!prev_sa) { /* first element in new list */
611  if (orig_hostname) {
612  new_sa->hostname = apr_pstrdup(p, orig_hostname);
613  }
614  *sa = new_sa;
615  }
616  else {
617  new_sa->hostname = prev_sa->hostname;
618  prev_sa->next = new_sa;
619  }
620 
621  prev_sa = new_sa;
622  ++curaddr;
623  }
624 
625  if (prev_sa == NULL) {
626  /* this should not happen but no result should be treated as error */
627  return APR_EGENERAL;
628  }
629 
630  return APR_SUCCESS;
631 }
632 
633 #endif /* end of !HAVE_GETADDRINFO code */
634 
635 APR_DECLARE(apr_status_t) apr_sockaddr_info_get(apr_sockaddr_t **sa,
636  const char *hostname,
637  apr_int32_t family, apr_port_t port,
638  apr_int32_t flags, apr_pool_t *p)
639 {
640  apr_int32_t masked;
641  *sa = NULL;
642 
643  if ((masked = flags & (APR_IPV4_ADDR_OK | APR_IPV6_ADDR_OK))) {
644  if (!hostname ||
645  family != APR_UNSPEC ||
646  masked == (APR_IPV4_ADDR_OK | APR_IPV6_ADDR_OK)) {
647  return APR_EINVAL;
648  }
649 #if !APR_HAVE_IPV6
650  if (flags & APR_IPV6_ADDR_OK) {
651  return APR_ENOTIMPL;
652  }
653 #endif
654  }
655  if (family == APR_UNSPEC && hostname && *hostname == '/') {
656  family = APR_UNIX;
657  }
658  if (family == APR_UNIX) {
659 #if APR_HAVE_SOCKADDR_UN
660  if (hostname && *hostname == '/') {
661  *sa = apr_pcalloc(p, sizeof(apr_sockaddr_t));
662  (*sa)->pool = p;
663  apr_cpystrn((*sa)->sa.unx.sun_path, hostname,
664  sizeof((*sa)->sa.unx.sun_path));
665  (*sa)->hostname = apr_pstrdup(p, hostname);
666  (*sa)->family = APR_UNIX;
667  (*sa)->sa.unx.sun_family = APR_UNIX;
668  (*sa)->salen = sizeof(struct sockaddr_un);
669  (*sa)->addr_str_len = sizeof((*sa)->sa.unx.sun_path);
670  (*sa)->ipaddr_ptr = &((*sa)->sa.unx.sun_path);
671  (*sa)->ipaddr_len = (*sa)->addr_str_len;
672 
673  return APR_SUCCESS;
674  }
675  else
676 #endif
677  {
678  *sa = NULL;
679  return APR_ENOTIMPL;
680  }
681  }
682 #if !APR_HAVE_IPV6
683  /* What may happen is that APR is not IPv6-enabled, but we're still
684  * going to call getaddrinfo(), so we have to tell the OS we only
685  * want IPv4 addresses back since we won't know what to do with
686  * IPv6 addresses.
687  */
688  if (family == APR_UNSPEC) {
689  family = APR_INET;
690  }
691 #endif
692 
693  return find_addresses(sa, hostname, family, port, flags, p);
694 }
695 
696 APR_DECLARE(apr_status_t) apr_sockaddr_info_copy(apr_sockaddr_t **dst,
697  const apr_sockaddr_t *src,
698  apr_pool_t *p)
699 {
700  apr_sockaddr_t *d;
701  const apr_sockaddr_t *s;
702 
703  for (*dst = d = NULL, s = src; s; s = s->next) {
704  if (!d) {
705  *dst = d = apr_pmemdup(p, s, sizeof *s);
706  }
707  else {
708  d = d->next = apr_pmemdup(p, s, sizeof *s);
709  }
710  if (s->hostname) {
711  if (s == src || s->hostname != src->hostname) {
712  d->hostname = apr_pstrdup(p, s->hostname);
713  }
714  else {
715  d->hostname = (*dst)->hostname;
716  }
717  }
718  if (s->servname) {
719  if (s == src || s->servname != src->servname) {
720  d->servname = apr_pstrdup(p, s->servname);
721  }
722  else {
723  d->servname = (*dst)->servname;
724  }
725  }
726  d->pool = p;
727  apr_sockaddr_vars_set(d, s->family, s->port);
728  }
729  return APR_SUCCESS;
730 }
731 
732 APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname,
734  apr_int32_t flags)
735 {
736 #if defined(HAVE_GETNAMEINFO)
737  int rc;
738 #if defined(NI_MAXHOST)
739  char tmphostname[NI_MAXHOST];
740 #else
741  char tmphostname[256];
742 #endif
743 
744  /* don't know if it is portable for getnameinfo() to set h_errno;
745  * clear it then see if it was set */
746  SET_H_ERRNO(0);
747 
748  /* default flags are NI_NAMREQD; otherwise, getnameinfo() will return
749  * a numeric address string if it fails to resolve the host name;
750  * that is *not* what we want here
751  *
752  * For IPv4-mapped IPv6 addresses, drop down to IPv4 before calling
753  * getnameinfo() to avoid getnameinfo bugs (MacOS X, glibc).
754  */
755 #if APR_HAVE_IPV6
756  if (sockaddr->family == AF_INET6 &&
757  IN6_IS_ADDR_V4MAPPED(&sockaddr->sa.sin6.sin6_addr)) {
758  struct sockaddr_in tmpsa;
759  tmpsa.sin_family = AF_INET;
760  tmpsa.sin_port = 0;
761  tmpsa.sin_addr.s_addr = ((apr_uint32_t *)sockaddr->ipaddr_ptr)[3];
762 #ifdef SIN6_LEN
763  tmpsa.sin_len = sizeof(tmpsa);
764 #endif
765 
766  rc = getnameinfo((const struct sockaddr *)&tmpsa, sizeof(tmpsa),
767  tmphostname, sizeof(tmphostname), NULL, 0,
768  flags != 0 ? flags : NI_NAMEREQD);
769  }
770 #if APR_HAVE_SOCKADDR_UN
771  else if (sockaddr->family == APR_UNIX) {
773  return APR_SUCCESS;
774  }
775 #endif
776  else
777 #endif
778  rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen,
779  tmphostname, sizeof(tmphostname), NULL, 0,
780  flags != 0 ? flags : NI_NAMEREQD);
781  if (rc != 0) {
782  *hostname = NULL;
783 
784 #ifndef WIN32
785  /* something went wrong. Look at the EAI_ error code */
786  if (rc == EAI_SYSTEM) {
787  /* EAI_SYSTEM System error returned in errno. */
788  /* IMHO, Implementations that set h_errno a simply broken. */
789  if (h_errno) { /* for broken implementations which set h_errno */
790  return h_errno + APR_OS_START_SYSERR;
791  }
792  else { /* "normal" case */
793  return errno + APR_OS_START_SYSERR;
794  }
795  }
796  else
797 #endif
798  {
799 #if defined(NEGATIVE_EAI)
800  if (rc < 0) rc = -rc;
801 #endif
802  return rc + APR_OS_START_EAIERR; /* return the EAI_ error */
803  }
804  }
805  *hostname = sockaddr->hostname = apr_pstrdup(sockaddr->pool,
806  tmphostname);
807  return APR_SUCCESS;
808 #else
809 #if APR_HAS_THREADS && !defined(GETHOSTBYADDR_IS_THREAD_SAFE) && \
810  defined(HAVE_GETHOSTBYADDR_R) && !defined(BEOS)
811 #ifdef GETHOSTBYNAME_R_HOSTENT_DATA
812  struct hostent_data hd;
813 #else
814  char tmp[GETHOSTBYNAME_BUFLEN];
815 #endif
816  int hosterror;
817  struct hostent hs, *hptr;
818 
819 #if defined(GETHOSTBYNAME_R_HOSTENT_DATA)
820  /* AIX, HP/UX, D/UX et alia */
821  gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
822  sizeof(struct in_addr), AF_INET, &hs, &hd);
823  hptr = &hs;
824 #else
825 #if defined(GETHOSTBYNAME_R_GLIBC2)
826  /* Linux glibc2+ */
827  gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
828  sizeof(struct in_addr), AF_INET,
829  &hs, tmp, GETHOSTBYNAME_BUFLEN - 1, &hptr, &hosterror);
830 #else
831  /* Solaris, Irix et alia */
832  hptr = gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr,
833  sizeof(struct in_addr), AF_INET,
834  &hs, tmp, GETHOSTBYNAME_BUFLEN, &hosterror);
835 #endif /* !defined(GETHOSTBYNAME_R_GLIBC2) */
836  if (!hptr) {
837  *hostname = NULL;
838  return hosterror + APR_OS_START_SYSERR;
839  }
840 #endif /* !defined(GETHOSTBYNAME_R_HOSTENT_DATA) */
841 #else
842  struct hostent *hptr;
843  hptr = gethostbyaddr((char *)&sockaddr->sa.sin.sin_addr,
844  sizeof(struct in_addr), AF_INET);
845 #endif
846 
847  if (hptr) {
848  *hostname = sockaddr->hostname = apr_pstrdup(sockaddr->pool, hptr->h_name);
849  return APR_SUCCESS;
850  }
851  *hostname = NULL;
852 #if defined(WIN32)
853  return apr_get_netos_error();
854 #elif defined(OS2)
855  return h_errno;
856 #else
857  return h_errno + APR_OS_START_SYSERR;
858 #endif
859 #endif
860 }
861 
862 APR_DECLARE(apr_status_t) apr_getservbyname(apr_sockaddr_t *sockaddr,
863  const char *servname)
864 {
865 #if APR_HAS_THREADS && !defined(GETSERVBYNAME_IS_THREAD_SAFE) && \
866  defined(HAVE_GETSERVBYNAME_R) && \
867  (defined(GETSERVBYNAME_R_GLIBC2) || defined(GETSERVBYNAME_R_SOLARIS) || \
868  defined(GETSERVBYNAME_R_OSF1))
869  struct servent se;
870 #if defined(GETSERVBYNAME_R_OSF1)
871  struct servent_data sed;
872 
873  memset(&sed, 0, sizeof(sed)); /* must zero fill before use */
874 #else
875 #if defined(GETSERVBYNAME_R_GLIBC2)
876  struct servent *res;
877 #endif
878  char buf[1024];
879 #endif
880 #else
881  struct servent *se;
882 #endif
883 
884  if (servname == NULL)
885  return APR_EINVAL;
886 
887 #if APR_HAS_THREADS && !defined(GETSERVBYNAME_IS_THREAD_SAFE) && \
888  defined(HAVE_GETSERVBYNAME_R) && \
889  (defined(GETSERVBYNAME_R_GLIBC2) || defined(GETSERVBYNAME_R_SOLARIS) || \
890  defined(GETSERVBYNAME_R_OSF1))
891 #if defined(GETSERVBYNAME_R_GLIBC2)
892  if (getservbyname_r(servname, NULL,
893  &se, buf, sizeof(buf), &res) == 0 && res != NULL) {
894  sockaddr->port = ntohs(res->s_port);
895  sockaddr->servname = apr_pstrdup(sockaddr->pool, servname);
896  sockaddr->sa.sin.sin_port = res->s_port;
897  return APR_SUCCESS;
898  }
899 #elif defined(GETSERVBYNAME_R_SOLARIS)
900  if (getservbyname_r(servname, NULL, &se, buf, sizeof(buf)) != NULL) {
901  sockaddr->port = ntohs(se.s_port);
902  sockaddr->servname = apr_pstrdup(sockaddr->pool, servname);
903  sockaddr->sa.sin.sin_port = se.s_port;
904  return APR_SUCCESS;
905  }
906 #elif defined(GETSERVBYNAME_R_OSF1)
907  if (getservbyname_r(servname, NULL, &se, &sed) == 0) {
908  sockaddr->port = ntohs(se.s_port);
909  sockaddr->servname = apr_pstrdup(sockaddr->pool, servname);
910  sockaddr->sa.sin.sin_port = se.s_port;
911  return APR_SUCCESS;
912  }
913 #endif
914 #else
915  if ((se = getservbyname(servname, NULL)) != NULL){
916  sockaddr->port = ntohs(se->s_port);
917  sockaddr->servname = apr_pstrdup(sockaddr->pool, servname);
918  sockaddr->sa.sin.sin_port = se->s_port;
919  return APR_SUCCESS;
920  }
921 #endif
922  return APR_ENOENT;
923 }
924 
925 #define V4MAPPED_EQUAL(a,b) \
926 ((a)->sa.sin.sin_family == AF_INET && \
927  (b)->sa.sin.sin_family == AF_INET6 && \
928  IN6_IS_ADDR_V4MAPPED((struct in6_addr *)(b)->ipaddr_ptr) && \
929  !memcmp((a)->ipaddr_ptr, \
930  &((struct in6_addr *)(b)->ipaddr_ptr)->s6_addr[12], \
931  (a)->ipaddr_len))
932 
933 #if APR_HAVE_IPV6
934 #define SCOPE_OR_ZERO(sa_) ((sa_)->family != AF_INET6 ? 0 : \
935  ((sa_)->sa.sin6.sin6_scope_id))
936 #else
937 #define SCOPE_OR_ZERO(sa_) (0)
938 #endif
939 
940 APR_DECLARE(int) apr_sockaddr_equal(const apr_sockaddr_t *addr1,
941  const apr_sockaddr_t *addr2)
942 {
943  if (addr1->ipaddr_len == addr2->ipaddr_len
944  && !memcmp(addr1->ipaddr_ptr, addr2->ipaddr_ptr, addr1->ipaddr_len)
945  && SCOPE_OR_ZERO(addr1) == SCOPE_OR_ZERO(addr2)) {
946  return 1;
947  }
948 #if APR_HAVE_IPV6
949  if (V4MAPPED_EQUAL(addr1, addr2)) {
950  return 1;
951  }
952  if (V4MAPPED_EQUAL(addr2, addr1)) {
953  return 1;
954  }
955 #endif
956  return 0; /* not equal */
957 }
958 
959 APR_DECLARE(int) apr_sockaddr_is_wildcard(const apr_sockaddr_t *addr)
960 {
961  static const char inaddr_any[
962 #if APR_HAVE_IPV6
963  sizeof(struct in6_addr)
964 #else
965  sizeof(struct in_addr)
966 #endif
967  ] = {0};
968 
969  if (addr->ipaddr_ptr /* IP address initialized */
970  && addr->ipaddr_len <= sizeof inaddr_any) { /* else bug elsewhere? */
971  if (!memcmp(inaddr_any, addr->ipaddr_ptr, addr->ipaddr_len)) {
972  return 1;
973  }
974 #if APR_HAVE_IPV6
975  if (addr->family == AF_INET6
976  && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr->ipaddr_ptr)) {
977  struct in_addr *v4 = (struct in_addr *)&((apr_uint32_t *)addr->ipaddr_ptr)[3];
978 
979  if (!memcmp(inaddr_any, v4, sizeof *v4)) {
980  return 1;
981  }
982  }
983 #endif
984  }
985  return 0;
986 }
987 
988 static apr_status_t parse_network(apr_ipsubnet_t *ipsub, const char *network)
989 {
990  /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
991  int shift;
992  char *s, *t;
993  int octet;
994  char buf[sizeof "255.255.255.255"];
995 
996  if (strlen(network) < sizeof buf) {
997  strcpy(buf, network);
998  }
999  else {
1000  return APR_EBADIP;
1001  }
1002 
1003  /* parse components */
1004  s = buf;
1005  ipsub->sub[0] = 0;
1006  ipsub->mask[0] = 0;
1007  shift = 24;
1008  while (*s) {
1009  t = s;
1010  if (!apr_isdigit(*t)) {
1011  return APR_EBADIP;
1012  }
1013  while (apr_isdigit(*t)) {
1014  ++t;
1015  }
1016  if (*t == '.') {
1017  *t++ = 0;
1018  }
1019  else if (*t) {
1020  return APR_EBADIP;
1021  }
1022  if (shift < 0) {
1023  return APR_EBADIP;
1024  }
1025  octet = atoi(s);
1026  if (octet < 0 || octet > 255) {
1027  return APR_EBADIP;
1028  }
1029  ipsub->sub[0] |= octet << shift;
1030  ipsub->mask[0] |= 0xFFUL << shift;
1031  s = t;
1032  shift -= 8;
1033  }
1034  ipsub->sub[0] = ntohl(ipsub->sub[0]);
1035  ipsub->mask[0] = ntohl(ipsub->mask[0]);
1036  ipsub->family = AF_INET;
1037  return APR_SUCCESS;
1038 }
1039 
1040 /* return values:
1041  * APR_EINVAL not an IP address; caller should see if it is something else
1042  * APR_BADIP IP address portion is is not valid
1043  * APR_BADMASK mask portion is not valid
1044  */
1045 
1046 static apr_status_t parse_ip(apr_ipsubnet_t *ipsub, const char *ipstr, int network_allowed)
1047 {
1048  /* supported flavors of IP:
1049  *
1050  * . IPv6 numeric address string (e.g., "fe80::1")
1051  *
1052  * IMPORTANT: Don't store IPv4-mapped IPv6 address as an IPv6 address.
1053  *
1054  * . IPv4 numeric address string (e.g., "127.0.0.1")
1055  *
1056  * . IPv4 network string (e.g., "9.67")
1057  *
1058  * IMPORTANT: This network form is only allowed if network_allowed is on.
1059  */
1060  int rc;
1061 
1062 #if APR_HAVE_IPV6
1063  rc = apr_inet_pton(AF_INET6, ipstr, ipsub->sub);
1064  if (rc == 1) {
1065  if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ipsub->sub)) {
1066  /* apr_ipsubnet_test() assumes that we don't create IPv4-mapped IPv6
1067  * addresses; this of course forces the user to specify IPv4 addresses
1068  * in a.b.c.d style instead of ::ffff:a.b.c.d style.
1069  */
1070  return APR_EBADIP;
1071  }
1072  ipsub->family = AF_INET6;
1073  }
1074  else
1075 #endif
1076  {
1077  rc = apr_inet_pton(AF_INET, ipstr, ipsub->sub);
1078  if (rc == 1) {
1079  ipsub->family = AF_INET;
1080  }
1081  }
1082  if (rc != 1) {
1083  if (network_allowed) {
1084  return parse_network(ipsub, ipstr);
1085  }
1086  else {
1087  return APR_EBADIP;
1088  }
1089  }
1090  return APR_SUCCESS;
1091 }
1092 
1093 static int looks_like_ip(const char *ipstr)
1094 {
1095  if (strlen(ipstr) == 0) {
1096  return 0;
1097  }
1098 
1099  if (strchr(ipstr, ':')) {
1100  /* definitely not a hostname; assume it is intended to be an IPv6 address */
1101  return 1;
1102  }
1103 
1104  /* simple IPv4 address string check */
1105  while ((*ipstr == '.') || apr_isdigit(*ipstr))
1106  ipstr++;
1107  return (*ipstr == '\0');
1108 }
1109 
1110 static void fix_subnet(apr_ipsubnet_t *ipsub)
1111 {
1112  /* in case caller specified more bits in network address than are
1113  * valid according to the mask, turn off the extra bits
1114  */
1115  int i;
1116 
1117  for (i = 0; i < sizeof ipsub->mask / sizeof(apr_int32_t); i++) {
1118  ipsub->sub[i] &= ipsub->mask[i];
1119  }
1120 }
1121 
1122 /* be sure not to store any IPv4 address as a v4-mapped IPv6 address */
1123 APR_DECLARE(apr_status_t) apr_ipsubnet_create(apr_ipsubnet_t **ipsub, const char *ipstr,
1124  const char *mask_or_numbits, apr_pool_t *p)
1125 {
1126  apr_status_t rv;
1127  char *endptr;
1128  long bits, maxbits = 32;
1129 
1130  /* filter out stuff which doesn't look remotely like an IP address; this helps
1131  * callers like mod_access which have a syntax allowing hostname or IP address;
1132  * APR_EINVAL tells the caller that it was probably not intended to be an IP
1133  * address
1134  */
1135  if (!looks_like_ip(ipstr)) {
1136  return APR_EINVAL;
1137  }
1138 
1139  *ipsub = apr_pcalloc(p, sizeof(apr_ipsubnet_t));
1140 
1141  /* assume ipstr is an individual IP address, not a subnet */
1142  memset((*ipsub)->mask, 0xFF, sizeof (*ipsub)->mask);
1143 
1144  rv = parse_ip(*ipsub, ipstr, mask_or_numbits == NULL);
1145  if (rv != APR_SUCCESS) {
1146  return rv;
1147  }
1148 
1149  if (mask_or_numbits) {
1150 #if APR_HAVE_IPV6
1151  if ((*ipsub)->family == AF_INET6) {
1152  maxbits = 128;
1153  }
1154 #endif
1155  bits = strtol(mask_or_numbits, &endptr, 10);
1156  if (*endptr == '\0' && bits > 0 && bits <= maxbits) {
1157  /* valid num-bits string; fill in mask appropriately */
1158  int cur_entry = 0;
1159  apr_int32_t cur_bit_value;
1160 
1161  memset((*ipsub)->mask, 0, sizeof (*ipsub)->mask);
1162  while (bits > 32) {
1163  (*ipsub)->mask[cur_entry] = 0xFFFFFFFF; /* all 32 bits */
1164  bits -= 32;
1165  ++cur_entry;
1166  }
1167  cur_bit_value = 0x80000000;
1168  while (bits) {
1169  (*ipsub)->mask[cur_entry] |= cur_bit_value;
1170  --bits;
1171  cur_bit_value /= 2;
1172  }
1173  (*ipsub)->mask[cur_entry] = htonl((*ipsub)->mask[cur_entry]);
1174  }
1175  else if (apr_inet_pton(AF_INET, mask_or_numbits, (*ipsub)->mask) == 1 &&
1176  (*ipsub)->family == AF_INET) {
1177  /* valid IPv4 netmask */
1178  }
1179  else {
1180  return APR_EBADMASK;
1181  }
1182  }
1183 
1184  fix_subnet(*ipsub);
1185 
1186  return APR_SUCCESS;
1187 }
1188 
1189 APR_DECLARE(int) apr_ipsubnet_test(apr_ipsubnet_t *ipsub, apr_sockaddr_t *sa)
1190 {
1191 #if APR_HAVE_IPV6
1192  /* XXX This line will segv on Win32 build with APR_HAVE_IPV6,
1193  * but without the IPV6 drivers installed.
1194  */
1195  if (sa->family == AF_INET) {
1196  if (ipsub->family == AF_INET &&
1197  ((sa->sa.sin.sin_addr.s_addr & ipsub->mask[0]) == ipsub->sub[0])) {
1198  return 1;
1199  }
1200  }
1201  else if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)sa->ipaddr_ptr)) {
1202  if (ipsub->family == AF_INET &&
1203  (((apr_uint32_t *)sa->ipaddr_ptr)[3] & ipsub->mask[0]) == ipsub->sub[0]) {
1204  return 1;
1205  }
1206  }
1207  else if (sa->family == AF_INET6 && ipsub->family == AF_INET6) {
1208  apr_uint32_t *addr = (apr_uint32_t *)sa->ipaddr_ptr;
1209 
1210  if ((addr[0] & ipsub->mask[0]) == ipsub->sub[0] &&
1211  (addr[1] & ipsub->mask[1]) == ipsub->sub[1] &&
1212  (addr[2] & ipsub->mask[2]) == ipsub->sub[2] &&
1213  (addr[3] & ipsub->mask[3]) == ipsub->sub[3]) {
1214  return 1;
1215  }
1216  }
1217 #else
1218  if ((sa->sa.sin.sin_addr.s_addr & ipsub->mask[0]) == ipsub->sub[0]) {
1219  return 1;
1220  }
1221 #endif /* APR_HAVE_IPV6 */
1222  return 0; /* no match */
1223 }
1224 
1225 APR_DECLARE(apr_status_t) apr_sockaddr_zone_set(apr_sockaddr_t *sa,
1226  const char *zone_id)
1227 {
1228 #if !APR_HAVE_IPV6 || !defined(HAVE_IF_NAMETOINDEX)
1229  return APR_ENOTIMPL;
1230 #else
1231  unsigned int idx;
1232 
1233  if (sa->family != APR_INET6
1234  || !IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)sa->ipaddr_ptr)) {
1235  return APR_EBADIP;
1236  }
1237 
1238  idx = if_nametoindex(zone_id);
1239  if (idx) {
1240  sa->sa.sin6.sin6_scope_id = idx;
1241  return APR_SUCCESS;
1242  }
1243 
1244  if (errno != ENODEV) {
1245  return errno;
1246  }
1247  else {
1248  char *endptr;
1249  apr_int64_t i = apr_strtoi64(zone_id, &endptr, 10);
1250 
1251  if (*endptr != '\0' || errno || i < 1 || i > APR_INT16_MAX) {
1252  return APR_EGENERAL;
1253  }
1254 
1255  sa->sa.sin6.sin6_scope_id = (unsigned int) i;
1256  return APR_SUCCESS;
1257  }
1258 #endif
1259 }
1260 
1261 APR_DECLARE(apr_status_t) apr_sockaddr_zone_get(const apr_sockaddr_t *sa,
1262  const char **name,
1263  apr_uint32_t *id,
1264  apr_pool_t *p)
1265 {
1266 #if !APR_HAVE_IPV6 || !defined(HAVE_IF_INDEXTONAME)
1267  return APR_ENOTIMPL;
1268 #else
1269  if (sa->family != APR_INET6 || !sa->sa.sin6.sin6_scope_id) {
1270  return APR_EBADIP;
1271  }
1272 
1273  if (name) {
1274  char *buf = apr_palloc(p, IF_NAMESIZE);
1275  if (if_indextoname(sa->sa.sin6.sin6_scope_id, buf) == NULL)
1276  return errno;
1277  *name = buf;
1278  }
1279 
1280  if (id) *id = sa->sa.sin6.sin6_scope_id;
1281 
1282  return APR_SUCCESS;
1283 #endif
1284 }
APR_IPV4_ADDR_OK
#define APR_IPV4_ADDR_OK
Definition: apr_network_io.h:148
apr_pcalloc
#define apr_pcalloc(p, size)
Definition: apr_pools.h:465
APR_IPV6_ADDR_OK
#define APR_IPV6_ADDR_OK
Definition: apr_network_io.h:149
APR_OS_START_SYSERR
#define APR_OS_START_SYSERR
Definition: apr_errno.h:185
SET_H_ERRNO
#define SET_H_ERRNO(newval)
Definition: sockaddr.c:54
apr_socket_t::local_port_unknown
int local_port_unknown
Definition: apr_arch_networkio.h:46
hostname
const char * hostname
Definition: apr_network_io.h:455
t
apr_interval_time_t t
Definition: apr_network_io.h:735
APR_EINVAL
#define APR_EINVAL
Definition: apr_errno.h:711
servname
const char * servname
Definition: apr_network_io.h:843
str
char ** str
Definition: apr_cstr.h:125
zone_id
const char * zone_id
Definition: apr_network_io.h:478
APR_UNIX
#define APR_UNIX
Definition: apr_network_io.h:208
apr_isdigit
#define apr_isdigit(c)
Definition: apr_lib.h:209
p
const char apr_int32_t apr_pool_t * p
Definition: apr_file_info.h:337
apr_inet_pton
int apr_inet_pton(int af, const char *src, void *dst)
Definition: inet_pton.c:79
APR_ENOTIMPL
#define APR_ENOTIMPL
Definition: apr_errno.h:476
apr_socket_t::socketdes
int socketdes
Definition: apr_arch_networkio.h:39
apr_strings.h
APR Strings library.
sock
apr_socket_t * sock
Definition: apr_network_io.h:403
apr_sockaddr_t::servname
char * servname
Definition: apr_network_io.h:272
APR_EBADMASK
#define APR_EBADMASK
Definition: apr_errno.h:319
apr_sockaddr_t::sin
struct sockaddr_in sin
Definition: apr_network_io.h:293
apr_get_netos_error
#define apr_get_netos_error()
Definition: apr_errno.h:1222
if_indextoname
#define if_indextoname
Definition: apr_arch_misc.h:504
get_remote_addr
static apr_status_t get_remote_addr(apr_socket_t *sock)
Definition: sockaddr.c:103
apr_sockaddr_t::next
apr_sockaddr_t * next
Definition: apr_network_io.h:289
apr_sockaddr_t::family
apr_int32_t family
Definition: apr_network_io.h:276
ipstr
const char * ipstr
Definition: apr_network_io.h:853
APR_DECLARE
APR_DECLARE(apr_status_t)
Definition: sockaddr.c:118
sockaddr
apr_sockaddr_t * sockaddr
Definition: apr_network_io.h:796
apr_inet_ntop
const char * apr_inet_ntop(int af, const void *src, char *dst, apr_size_t size)
Definition: inet_ntop.c:74
family
int family
Definition: apr_network_io.h:345
getsockname
#define getsockname
Definition: apr_arch_os2calls.h:48
in_addr::s_addr
apr_uint32_t s_addr
Definition: apr_network_io.h:157
apr_sockaddr_t::addr_str_len
int addr_str_len
Definition: apr_network_io.h:283
in_addr
Definition: apr_network_io.h:156
scope_id
char ** scope_id
Definition: apr_network_io.h:539
buf
char * buf
Definition: apr_errno.h:52
if_nametoindex
#define if_nametoindex
Definition: apr_arch_misc.h:495
parse_network
static apr_status_t parse_network(apr_ipsubnet_t *ipsub, const char *network)
Definition: sockaddr.c:988
buflen
apr_size_t buflen
Definition: apr_network_io.h:803
apr_want.h
APR Standard Headers Support.
apr_lib.h
APR general purpose library routines.
int
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray
s
const char * s
Definition: apr_strings.h:95
apr_sockaddr_t::sa
union apr_sockaddr_t::@1 sa
SCOPE_OR_ZERO
#define SCOPE_OR_ZERO(sa_)
Definition: sockaddr.c:937
looks_like_ip
static int looks_like_ip(const char *ipstr)
Definition: sockaddr.c:1093
APR_UNSPEC
#define APR_UNSPEC
Definition: apr_network_io.h:183
apr_ipsubnet_t::mask
apr_uint32_t mask[1]
Definition: sockaddr.c:46
apr_socket_t
Definition: apr_arch_networkio.h:37
apr_ipsubnet_t
Definition: sockaddr.c:39
apr_interface_e
apr_interface_e
Definition: apr_network_io.h:225
apr_pool_t
Definition: apr_pools.c:577
mask_or_numbits
const char const char * mask_or_numbits
Definition: apr_network_io.h:853
APR_OS_START_EAIERR
#define APR_OS_START_EAIERR
Definition: apr_errno.h:180
parse_ip
static apr_status_t parse_ip(apr_ipsubnet_t *ipsub, const char *ipstr, int network_allowed)
Definition: sockaddr.c:1046
apr_sockaddr_vars_set
void apr_sockaddr_vars_set(apr_sockaddr_t *addr, int family, apr_port_t port)
Definition: sockaddr.c:171
apr_arch_misc.h
apr_socket_t::remote_addr
apr_sockaddr_t * remote_addr
Definition: apr_arch_networkio.h:43
apr_socket_t::local_addr
apr_sockaddr_t * local_addr
Definition: apr_arch_networkio.h:42
which
apr_interface_e which
Definition: apr_network_io.h:785
APR_ENOENT
#define APR_ENOENT
Definition: apr_errno.h:662
apr_ipsubnet_t::family
int family
Definition: sockaddr.c:40
apr_port_t
apr_uint16_t apr_port_t
Definition: apr_network_io.h:257
name
const char ** name
Definition: apr_network_io.h:492
apr_status_t
int apr_status_t
Definition: apr_errno.h:44
APR_INET
#define APR_INET
Definition: apr_network_io.h:176
apr_socket_t::local_interface_unknown
int local_interface_unknown
Definition: apr_arch_networkio.h:47
APR_SUCCESS
#define APR_SUCCESS
Definition: apr_errno.h:225
apr_sockaddr_t::hostname
char * hostname
Definition: apr_network_io.h:270
fix_subnet
static void fix_subnet(apr_ipsubnet_t *ipsub)
Definition: sockaddr.c:1110
V4MAPPED_EQUAL
#define V4MAPPED_EQUAL(a, b)
Definition: sockaddr.c:925
apr_socket_t::remote_addr_unknown
int remote_addr_unknown
Definition: apr_arch_networkio.h:48
getpeername
#define getpeername
Definition: apr_arch_os2calls.h:47
flags
const char apr_ssize_t int flags
Definition: apr_encode.h:162
apr_sockaddr_t::salen
apr_socklen_t salen
Definition: apr_network_io.h:278
APR_EGENERAL
#define APR_EGENERAL
Definition: apr_errno.h:313
port
const char apr_int32_t apr_port_t port
Definition: apr_network_io.h:455
get_local_addr
static apr_status_t get_local_addr(apr_socket_t *sock)
Definition: sockaddr.c:88
APR_REMOTE
Definition: apr_network_io.h:227
APR_ENOSPC
#define APR_ENOSPC
Definition: apr_errno.h:676
apr_sockaddr_t::port
apr_port_t port
Definition: apr_network_io.h:274
memchr
void * memchr(const void *s, int c, size_t n)
Definition: apr_strings.c:216
memmove
#define memmove(a, b, c)
Definition: apr_general.h:156
apr_ipsubnet_t::sub
apr_uint32_t sub[1]
Definition: sockaddr.c:45
apr_sockaddr_t::ipaddr_len
int ipaddr_len
Definition: apr_network_io.h:280
src
const char * src
Definition: apr_encode.h:162
apr_sockaddr_t::ipaddr_ptr
void * ipaddr_ptr
Definition: apr_network_io.h:286
find_addresses
static apr_status_t find_addresses(apr_sockaddr_t **sa, const char *hostname, apr_int32_t family, apr_port_t port, apr_int32_t flags, apr_pool_t *p)
Definition: sockaddr.c:529
apr_sockaddr_t
Definition: apr_network_io.h:266
APR_LOCAL
Definition: apr_network_io.h:226
addr
apr_sockaddr_t * addr
Definition: apr_network_io.h:938
APR_EBADIP
#define APR_EBADIP
Definition: apr_errno.h:317
apr_sockaddr_t::pool
apr_pool_t * pool
Definition: apr_network_io.h:268
sa
apr_sockaddr_t * sa
Definition: apr_network_io.h:379
addr2
const apr_sockaddr_t * addr2
Definition: apr_network_io.h:817