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