PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/boa-0.94.14rc21/src/ip.c

#
C | 139 lines | 80 code | 7 blank | 52 comment | 9 complexity | d2177b7571f0975ffc85a6e8dd3826c7 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * Boa, an http server
  3. * Copyright (C) 1999 Larry Doolittle <ldoolitt@boa.org>
  4. * Copyright (C) 2000-2003 Jon Nelson <jnelson@boa.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 1, or (at your option)
  9. * any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. *
  21. Encapsulation of ipv4 and ipv6 stuff, try to get rid of the ifdef's
  22. elsewhere in the code.
  23. The IPv6 code here is based on contributions from Martin Hinner <martin@tdp.cz>
  24. and Arkadiusz Miskiewicz <misiek@misiek.eu.org>. This incarnation of that
  25. code is untested. The original IPv4 code is based on original Boa code
  26. from Paul Phillips <paulp@go2net.com>.
  27. A goal is to compile in as many families as are supported, and
  28. make the final choice at runtime.
  29. globals.h:
  30. #ifdef INET6
  31. char remote_ip_addr[BOA_NI_MAXHOST];
  32. #else
  33. char remote_ip_addr[20]; after inet_ntoa
  34. #endif
  35. None of this code interacts with the rest of Boa except through
  36. the parameter lists and return values.
  37. Consider making these functions __inline__ and using this as a .h file
  38. */
  39. #include "boa.h"
  40. #include <arpa/inet.h> /* inet_ntoa */
  41. /* Binds to the existing server_s, based on the configuration string
  42. in server_ip. IPv6 version doesn't pay attention to server_ip yet. */
  43. int bind_server(int sock, char *ip, unsigned int port)
  44. {
  45. #ifdef INET6
  46. struct sockaddr_in6 server_sockaddr;
  47. server_sockaddr.sin6_family = PF_INET6;
  48. memcpy(&server_sockaddr.sin6_addr, &in6addr_any, sizeof (in6addr_any));
  49. server_sockaddr.sin6_port = htons(server_port);
  50. #else
  51. struct sockaddr_in server_sockaddr;
  52. memset(&server_sockaddr, 0, sizeof server_sockaddr);
  53. #ifdef HAVE_SIN_LEN /* uncomment for BSDs */
  54. server_sockaddr.sin_len = sizeof server_sockaddr;
  55. #endif
  56. server_sockaddr.sin_family = PF_INET;
  57. if (ip != NULL) {
  58. #ifdef HAVE_INET_ATON
  59. inet_aton(ip, &server_sockaddr.sin_addr);
  60. #elif defined HAVE_INET_ADDR
  61. server_sockaddr.sin_addr.s_addr = inet_addr(ip);
  62. #else
  63. #error "Neither inet_aton nor inet_addr exist!"
  64. #endif
  65. } else {
  66. server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  67. }
  68. server_sockaddr.sin_port = htons(port);
  69. #endif
  70. return bind(sock, (struct sockaddr *) &server_sockaddr,
  71. sizeof (server_sockaddr));
  72. }
  73. char *ascii_sockaddr(struct SOCKADDR *s, char *dest, unsigned int len)
  74. {
  75. #ifdef INET6
  76. if (getnameinfo((struct sockaddr *) s,
  77. sizeof (struct SOCKADDR),
  78. dest, len, NULL, 0, NI_NUMERICHOST)) {
  79. fprintf(stderr, "[IPv6] getnameinfo failed\n");
  80. *dest = '\0';
  81. }
  82. #ifdef WHEN_DOES_THIS_APPLY
  83. #error Dont use memmove
  84. if ((s->__ss_family == PF_INET6) &&
  85. IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) s)->sin6_addr))) {
  86. #error The following two lines are broken
  87. memmove(dest, dest + 7, BOA_NI_MAXHOST);
  88. dest[BOA_NI_MAXHOST] = '\0';
  89. }
  90. #endif /* ifdef WHEN_DOES_THIS_APPLY */
  91. #else /* ifdef INET6 */
  92. unsigned int newlen;
  93. char *buf;
  94. /* memmove(dest, inet_ntoa(s->sin_addr), len); */
  95. buf = inet_ntoa(s->sin_addr);
  96. newlen = strlen(buf);
  97. /* we need newlen + 1 byte to be <= len, thus
  98. * newlen <= len - 1 is good
  99. * and newlen > len -1 is bad thus
  100. * newlen + 1 > len ==== newlen >= len
  101. */
  102. if (newlen + 1 > len) { /* too many bytes incl. the NUL */
  103. return NULL;
  104. }
  105. memcpy(dest, buf, newlen);
  106. dest[newlen] = '\0';
  107. #endif /* ifdef INET6 */
  108. return dest;
  109. }
  110. int net_port(struct SOCKADDR *s)
  111. {
  112. int p = -1;
  113. #ifdef INET6
  114. char serv[NI_MAXSERV];
  115. if (getnameinfo((struct sockaddr *) s,
  116. sizeof (struct SOCKADDR),
  117. NULL, 0, serv, sizeof (serv), NI_NUMERICSERV)) {
  118. fprintf(stderr, "[IPv6] getnameinfo failed\n");
  119. } else {
  120. p = atoi(serv);
  121. }
  122. #else
  123. p = ntohs(s->sin_port);
  124. #endif
  125. return p;
  126. }