summaryrefslogtreecommitdiff
path: root/polux/application/boa/src/ip.c
diff options
context:
space:
mode:
Diffstat (limited to 'polux/application/boa/src/ip.c')
-rw-r--r--polux/application/boa/src/ip.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/polux/application/boa/src/ip.c b/polux/application/boa/src/ip.c
new file mode 100644
index 0000000000..9ca2d54903
--- /dev/null
+++ b/polux/application/boa/src/ip.c
@@ -0,0 +1,138 @@
+/*
+ * Boa, an http server
+ * Copyright (C) 1999 Larry Doolittle <ldoolitt@boa.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+
+ Encapsulation of ipv4 and ipv6 stuff, try to get rid of the ifdef's
+ elsewhere in the code.
+
+ The IPv6 code here is based on contributions from Martin Hinner <martin@tdp.cz>
+ and Arkadiusz Miskiewicz <misiek@misiek.eu.org>. This incarnation of that
+ code is untested. The original IPv4 code is based on original Boa code
+ from Paul Phillips <paulp@go2net.com>.
+
+ A goal is to compile in as many families as are supported, and
+ make the final choice at runtime.
+
+globals.h:
+#ifdef INET6
+ char remote_ip_addr[BOA_NI_MAXHOST];
+#else
+ char remote_ip_addr[20]; after inet_ntoa
+#endif
+
+ None of this code interacts with the rest of Boa except through
+ the parameter lists and return values.
+
+ Consider making these functions __inline__ and using this as a .h file
+ */
+
+#include "boa.h"
+#include <arpa/inet.h> /* inet_ntoa */
+
+/* Binds to the existing server_s, based on the configuration string
+ in server_ip. IPv6 version doesn't pay attention to server_ip yet. */
+int bind_server(int sock, char *ip, unsigned int port)
+{
+#ifdef INET6
+ struct sockaddr_in6 server_sockaddr;
+ server_sockaddr.sin6_family = PF_INET6;
+ memcpy(&server_sockaddr.sin6_addr, &in6addr_any, sizeof (in6addr_any));
+ server_sockaddr.sin6_port = htons(server_port);
+#else
+ struct sockaddr_in server_sockaddr;
+ memset(&server_sockaddr, 0, sizeof server_sockaddr);
+#ifdef HAVE_SIN_LEN /* uncomment for BSDs */
+ server_sockaddr.sin_len = sizeof server_sockaddr;
+#endif
+ server_sockaddr.sin_family = PF_INET;
+ if (ip != NULL) {
+#ifdef HAVE_INET_ATON
+ inet_aton(ip, &server_sockaddr.sin_addr);
+#elif defined HAVE_INET_ADDR
+ server_sockaddr.sin_addr.s_addr = inet_addr(ip);
+#else
+#error "Neither inet_aton nor inet_addr exist!"
+#endif
+ } else {
+ server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ }
+ server_sockaddr.sin_port = htons(port);
+#endif
+
+ return bind(sock, (struct sockaddr *) &server_sockaddr,
+ sizeof (server_sockaddr));
+}
+
+char *ascii_sockaddr(struct SOCKADDR *s, char *dest, unsigned int len)
+{
+#ifdef INET6
+ if (getnameinfo((struct sockaddr *) s,
+ sizeof (struct SOCKADDR),
+ dest, len, NULL, 0, NI_NUMERICHOST)) {
+ fprintf(stderr, "[IPv6] getnameinfo failed\n");
+ *dest = '\0';
+ }
+#ifdef WHEN_DOES_THIS_APPLY
+#error Dont use memmove
+ if ((s->__ss_family == PF_INET6) &&
+ IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) s)->sin6_addr))) {
+#error The following two lines are broken
+ memmove(dest, dest + 7, BOA_NI_MAXHOST);
+ dest[BOA_NI_MAXHOST] = '\0';
+ }
+#endif /* ifdef WHEN_DOES_THIS_APPLY */
+#else /* ifdef INET6 */
+ unsigned int newlen;
+ char *buf;
+
+ /* memmove(dest, inet_ntoa(s->sin_addr), len); */
+ buf = inet_ntoa(s->sin_addr);
+ newlen = strlen(buf);
+ /* we need newlen + 1 byte to be <= len, thus
+ * newlen <= len - 1 is good
+ * and newlen > len -1 is bad thus
+ * newlen + 1 > len ==== newlen >= len
+ */
+ if (newlen + 1 > len) { /* too many bytes incl. the NUL */
+ return NULL;
+ }
+ memcpy(dest, buf, newlen);
+ dest[newlen] = '\0';
+#endif /* ifdef INET6 */
+ return dest;
+}
+
+int net_port(struct SOCKADDR *s)
+{
+ int p = -1;
+#ifdef INET6
+ char serv[NI_MAXSERV];
+
+ if (getnameinfo((struct sockaddr *) s,
+ sizeof (struct SOCKADDR),
+ NULL, 0, serv, sizeof (serv), NI_NUMERICSERV)) {
+ fprintf(stderr, "[IPv6] getnameinfo failed\n");
+ } else {
+ p = atoi(serv);
+ }
+#else
+ p = ntohs(s->sin_port);
+#endif
+ return p;
+}