/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
22 Encapsulation of ipv4 and ipv6 stuff, try to get rid of the ifdef's
23 elsewhere in the code.
24
25 The IPv6 code here is based on contributions from Martin Hinner <martin@tdp.cz>
26 and Arkadiusz Miskiewicz <misiek@misiek.eu.org>. This incarnation of that
27 code is untested. The original IPv4 code is based on original Boa code
28 from Paul Phillips <paulp@go2net.com>.
29
30 A goal is to compile in as many families as are supported, and
31 make the final choice at runtime.
32
33globals.h:
34#ifdef INET6
35 char remote_ip_addr[BOA_NI_MAXHOST];
36#else
37 char remote_ip_addr[20]; after inet_ntoa
38#endif
39
40 None of this code interacts with the rest of Boa except through
41 the parameter lists and return values.
42
43 Consider making these functions __inline__ and using this as a .h file
44 */
45
46#include "boa.h"
47#include <arpa/inet.h> /* inet_ntoa */
48
49/* Binds to the existing server_s, based on the configuration string
50 in server_ip. IPv6 version doesn't pay attention to server_ip yet. */
51int bind_server(int sock, char *ip, unsigned int port)
52{
53#ifdef INET6
54 struct sockaddr_in6 server_sockaddr;
55 server_sockaddr.sin6_family = PF_INET6;
56 memcpy(&server_sockaddr.sin6_addr, &in6addr_any, sizeof (in6addr_any));
57 server_sockaddr.sin6_port = htons(server_port);
58#else
59 struct sockaddr_in server_sockaddr;
60 memset(&server_sockaddr, 0, sizeof server_sockaddr);
61#ifdef HAVE_SIN_LEN /* uncomment for BSDs */
62 server_sockaddr.sin_len = sizeof server_sockaddr;
63#endif
64 server_sockaddr.sin_family = PF_INET;
65 if (ip != NULL) {
66#ifdef HAVE_INET_ATON
67 inet_aton(ip, &server_sockaddr.sin_addr);
68#elif defined HAVE_INET_ADDR
69 server_sockaddr.sin_addr.s_addr = inet_addr(ip);
70#else
71#error "Neither inet_aton nor inet_addr exist!"
72#endif
73 } else {
74 server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
75 }
76 server_sockaddr.sin_port = htons(port);
77#endif
78
79 return bind(sock, (struct sockaddr *) &server_sockaddr,
80 sizeof (server_sockaddr));
81}
82
83char *ascii_sockaddr(struct SOCKADDR *s, char *dest, unsigned int len)
84{
85#ifdef INET6
86 if (getnameinfo((struct sockaddr *) s,
87 sizeof (struct SOCKADDR),
88 dest, len, NULL, 0, NI_NUMERICHOST)) {
89 fprintf(stderr, "[IPv6] getnameinfo failed\n");
90 *dest = '\0';
91 }
92#ifdef WHEN_DOES_THIS_APPLY
93#error Dont use memmove
94 if ((s->__ss_family == PF_INET6) &&
95 IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) s)->sin6_addr))) {
96#error The following two lines are broken
97 memmove(dest, dest + 7, BOA_NI_MAXHOST);
98 dest[BOA_NI_MAXHOST] = '\0';
99 }
100#endif /* ifdef WHEN_DOES_THIS_APPLY */
101#else /* ifdef INET6 */
102 unsigned int newlen;
103 char *buf;
104
105 /* memmove(dest, inet_ntoa(s->sin_addr), len); */
106 buf = inet_ntoa(s->sin_addr);
107 newlen = strlen(buf);
108 /* we need newlen + 1 byte to be <= len, thus
109 * newlen <= len - 1 is good
110 * and newlen > len -1 is bad thus
111 * newlen + 1 > len ==== newlen >= len
112 */
113 if (newlen + 1 > len) { /* too many bytes incl. the NUL */
114 return NULL;
115 }
116 memcpy(dest, buf, newlen);
117 dest[newlen] = '\0';
118#endif /* ifdef INET6 */
119 return dest;
120}
121
122int net_port(struct SOCKADDR *s)
123{
124 int p = -1;
125#ifdef INET6
126 char serv[NI_MAXSERV];
127
128 if (getnameinfo((struct sockaddr *) s,
129 sizeof (struct SOCKADDR),
130 NULL, 0, serv, sizeof (serv), NI_NUMERICSERV)) {
131 fprintf(stderr, "[IPv6] getnameinfo failed\n");
132 } else {
133 p = atoi(serv);
134 }
135#else
136 p = ntohs(s->sin_port);
137#endif
138 return p;
139}