Contents of /trunk/proftpd/patches/proftpd-1.3.0a-ipv6_on-off.patch
Parent Directory | Revision Log
Revision 265 -
(show annotations)
(download)
Wed Jul 11 23:16:10 2007 UTC (17 years, 2 months ago) by niro
File size: 21606 byte(s)
Wed Jul 11 23:16:10 2007 UTC (17 years, 2 months ago) by niro
File size: 21606 byte(s)
- proftpd-1.3.0a-r1
1 | # ipv6_onoff.dpatch by Francesco Paolo Lovergine <frankie@debian.org> |
2 | |
3 | diff -urNad proftpd-dfsg-1.3.0~/include/netaddr.h proftpd-dfsg-1.3.0/include/netaddr.h |
4 | --- proftpd-dfsg-1.3.0~/include/netaddr.h 2006-11-22 19:44:32.000000000 +0100 |
5 | +++ proftpd-dfsg-1.3.0/include/netaddr.h 2006-11-22 19:44:46.000000000 +0100 |
6 | @@ -1,6 +1,6 @@ |
7 | /* |
8 | * ProFTPD - FTP server daemon |
9 | - * Copyright (c) 2003-2005 The ProFTPD Project team |
10 | + * Copyright (c) 2003-2006 The ProFTPD Project team |
11 | * |
12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by |
14 | @@ -344,7 +344,7 @@ |
15 | /* Returns TRUE if the given pr_netaddr_t contains a loopback address, |
16 | * FALSE otherwise. |
17 | */ |
18 | -int pr_netaddr_loopback(const pr_netaddr_t *); |
19 | +int pr_netaddr_is_loopback(const pr_netaddr_t *); |
20 | |
21 | /* Returns TRUE if the given pr_netaddr_t is of the AF_INET6 family and |
22 | * contains an IPv4-mapped IPv6 address; otherwise FALSE is returned. A |
23 | @@ -352,6 +352,15 @@ |
24 | */ |
25 | int pr_netaddr_is_v4mappedv6(const pr_netaddr_t *); |
26 | |
27 | +/* Returns TRUE if IPv6 support is enabled, FALSE otherwise. */ |
28 | +unsigned char pr_netaddr_use_ipv6(void); |
29 | + |
30 | +/* Disables runtime use of IPv6 functionality (assuming IPv6 is supported). */ |
31 | +void pr_netaddr_disable_ipv6(void); |
32 | + |
33 | +/* Enables runtime use of IPv6 functionality (assuming IPv6 is supported). */ |
34 | +void pr_netaddr_enable_ipv6(void); |
35 | + |
36 | /* Return pointers to static memory which contains the local and remote |
37 | * netaddr information for the sesssion. DO NOT MODIFY the pointed-to |
38 | * memory! Returns NULL if no such session information exists. |
39 | diff -urNad proftpd-dfsg-1.3.0~/modules/mod_core.c proftpd-dfsg-1.3.0/modules/mod_core.c |
40 | --- proftpd-dfsg-1.3.0~/modules/mod_core.c 2006-11-22 19:44:45.000000000 +0100 |
41 | +++ proftpd-dfsg-1.3.0/modules/mod_core.c 2006-11-22 19:48:23.000000000 +0100 |
42 | @@ -448,14 +448,16 @@ |
43 | const char *ipstr = pr_netaddr_get_ipstr(elts[i]); |
44 | |
45 | #ifdef PR_USE_IPV6 |
46 | - char ipbuf[INET6_ADDRSTRLEN]; |
47 | - if (pr_netaddr_get_family(elts[i]) == AF_INET) { |
48 | + if (pr_netaddr_use_ipv6()) { |
49 | + char *ipbuf = pcalloc(cmd->tmp_pool, INET6_ADDRSTRLEN); |
50 | + if (pr_netaddr_get_family(elts[i]) == AF_INET) { |
51 | |
52 | - /* Create the bind record using the IPv4-mapped IPv6 version of |
53 | - * this address. |
54 | - */ |
55 | - snprintf(ipbuf, sizeof(ipbuf), "::ffff:%s", ipstr); |
56 | - ipstr = ipbuf; |
57 | + /* Create the bind record using the IPv4-mapped IPv6 version of |
58 | + * this address. |
59 | + */ |
60 | + snprintf(ipbuf, sizeof(ipbuf), "::ffff:%s", ipstr); |
61 | + ipstr = ipbuf; |
62 | + } |
63 | } |
64 | #endif /* PR_USE_IPV6 */ |
65 | |
66 | @@ -601,6 +603,33 @@ |
67 | return HANDLED(cmd); |
68 | } |
69 | |
70 | +/* usage: UseIPv6 on|off */ |
71 | +MODRET set_useipv6(cmd_rec *cmd) { |
72 | +#ifdef PR_USE_IPV6 |
73 | + int bool = -1; |
74 | + |
75 | + CHECK_ARGS(cmd, 1); |
76 | + CHECK_CONF(cmd, CONF_ROOT); |
77 | + |
78 | + bool = get_boolean(cmd, 1); |
79 | + if (bool == -1) |
80 | + CONF_ERROR(cmd, "expected Boolean parameter"); |
81 | + |
82 | + if (bool == 0) { |
83 | + pr_log_debug(DEBUG2, "disabling runtime support for IPv6 connections"); |
84 | + pr_netaddr_disable_ipv6(); |
85 | + |
86 | + } else { |
87 | + pr_netaddr_enable_ipv6(); |
88 | + } |
89 | + |
90 | + return HANDLED(cmd); |
91 | +#else |
92 | + CONF_ERROR(cmd, |
93 | + "Use of the UseIPv6 directive requires IPv6 support (--enable-ipv6)"); |
94 | +#endif /* PR_USE_IPV6 */ |
95 | +} |
96 | + |
97 | MODRET set_usereversedns(cmd_rec *cmd) { |
98 | int bool = -1; |
99 | |
100 | @@ -3110,9 +3139,15 @@ |
101 | port = ((p1 << 8) | p2); |
102 | |
103 | #ifdef PR_USE_IPV6 |
104 | - if (pr_netaddr_get_family(session.c->remote_addr) == AF_INET6) |
105 | - snprintf(buf, sizeof(buf), "::ffff:%u.%u.%u.%u", h1, h2, h3, h4); |
106 | - else |
107 | + if (pr_netaddr_use_ipv6()) { |
108 | + if (pr_netaddr_get_family(session.c->remote_addr) == AF_INET6) { |
109 | + snprintf(buf, sizeof(buf), "::ffff:%u.%u.%u.%u", h1, h2, h3, h4); |
110 | + |
111 | + } else { |
112 | + snprintf(buf, sizeof(buf), "%u.%u.%u.%u", h1, h2, h3, h4); |
113 | + } |
114 | + |
115 | + } else |
116 | #endif /* PR_USE_IPV6 */ |
117 | snprintf(buf, sizeof(buf), "%u.%u.%u.%u", h1, h2, h3, h4); |
118 | buf[sizeof(buf)-1] = '\0'; |
119 | @@ -3139,15 +3174,17 @@ |
120 | pr_netaddr_t *remote_addr = session.c->remote_addr; |
121 | |
122 | #ifdef PR_USE_IPV6 |
123 | - /* We can only compare the PORT-given address against the remote client |
124 | - * address if the remote client address is an IPv4-mapped IPv6 address. |
125 | - */ |
126 | - if (pr_netaddr_get_family(remote_addr) == AF_INET6 && |
127 | - pr_netaddr_is_v4mappedv6(remote_addr) != TRUE) { |
128 | - pr_log_pri(PR_LOG_WARNING, "Refused PORT %s (IPv4/IPv6 address mismatch)", |
129 | - cmd->arg); |
130 | - pr_response_add_err(R_500, "Illegal PORT command"); |
131 | - return ERROR(cmd); |
132 | + if (pr_netaddr_use_ipv6()) { |
133 | + /* We can only compare the PORT-given address against the remote client |
134 | + * address if the remote client address is an IPv4-mapped IPv6 address. |
135 | + */ |
136 | + if (pr_netaddr_get_family(remote_addr) == AF_INET6 && |
137 | + pr_netaddr_is_v4mappedv6(remote_addr) != TRUE) { |
138 | + pr_log_pri(PR_LOG_WARNING, |
139 | + "Refused PORT %s (IPv4/IPv6 address mismatch)", cmd->arg); |
140 | + pr_response_add_err(R_500, "Illegal PORT command"); |
141 | + return ERROR(cmd); |
142 | + } |
143 | } |
144 | #endif /* PR_USE_IPV6 */ |
145 | |
146 | @@ -3244,12 +3281,16 @@ |
147 | |
148 | #ifdef PR_USE_IPV6 |
149 | case 2: |
150 | - break; |
151 | + if (pr_netaddr_use_ipv6()) |
152 | + break; |
153 | #endif /* PR_USE_IPV6 */ |
154 | |
155 | default: |
156 | #ifdef PR_USE_IPV6 |
157 | - pr_response_add_err(R_522, "Network protocol not supported, use (1,2)"); |
158 | + if (pr_netaddr_use_ipv6()) |
159 | + pr_response_add_err(R_522, "Network protocol not supported, use (1,2)"); |
160 | + else |
161 | + pr_response_add_err(R_522, "Network protocol not supported, use (1)"); |
162 | #else |
163 | pr_response_add_err(R_522, "Network protocol not supported, use (1)"); |
164 | #endif /* PR_USE_IPV6 */ |
165 | @@ -3435,8 +3476,10 @@ |
166 | |
167 | #ifdef PR_USE_IPV6 |
168 | case AF_INET6: |
169 | - family = 2; |
170 | - break; |
171 | + if (pr_netaddr_use_ipv6()) { |
172 | + family = 2; |
173 | + break; |
174 | + } |
175 | #endif /* PR_USE_IPV6 */ |
176 | |
177 | default: |
178 | @@ -3451,12 +3494,16 @@ |
179 | |
180 | #ifdef PR_USE_IPV6 |
181 | case 2: |
182 | - break; |
183 | + if (pr_netaddr_use_ipv6()) |
184 | + break; |
185 | #endif /* PR_USE_IPV6 */ |
186 | |
187 | default: |
188 | #ifdef PR_USE_IPV6 |
189 | - pr_response_add_err(R_522, "Network protocol not supported, use (1,2)"); |
190 | + if (pr_netaddr_use_ipv6()) |
191 | + pr_response_add_err(R_522, "Network protocol not supported, use (1,2)"); |
192 | + else |
193 | + pr_response_add_err(R_522, "Network protocol not supported, use (1)"); |
194 | #else |
195 | pr_response_add_err(R_522, "Network protocol not supported, use (1)"); |
196 | #endif /* PR_USE_IPV6 */ |
197 | @@ -4619,6 +4666,7 @@ |
198 | { "TransferLog", add_transferlog, NULL }, |
199 | { "Umask", set_umask, NULL }, |
200 | { "UnsetEnv", set_unsetenv, NULL }, |
201 | + { "UseIPv6", set_useipv6, NULL }, |
202 | { "UseReverseDNS", set_usereversedns, NULL }, |
203 | { "User", set_user, NULL }, |
204 | { "UserOwner", add_userowner, NULL }, |
205 | diff -urNad proftpd-dfsg-1.3.0~/src/bindings.c proftpd-dfsg-1.3.0/src/bindings.c |
206 | --- proftpd-dfsg-1.3.0~/src/bindings.c 2006-11-22 19:44:32.000000000 +0100 |
207 | +++ proftpd-dfsg-1.3.0/src/bindings.c 2006-11-22 19:44:46.000000000 +0100 |
208 | @@ -57,10 +57,6 @@ |
209 | static pr_ipbind_t *ipbind_default_server = NULL, |
210 | *ipbind_localhost_server = NULL; |
211 | |
212 | -#ifdef PR_USE_IPV6 |
213 | -static int ipv6_supported = TRUE; |
214 | -#endif /* PR_USE_IPV6 */ |
215 | - |
216 | /* Server cleanup callback function */ |
217 | static void server_cleanup_cb(void *conn) { |
218 | *((conn_t **) conn) = NULL; |
219 | @@ -464,7 +460,7 @@ |
220 | /* Not found in binding list, and no DefaultServer, so see if it's the |
221 | * loopback address |
222 | */ |
223 | - if (ipbind_localhost_server && pr_netaddr_loopback(addr)) |
224 | + if (ipbind_localhost_server && pr_netaddr_is_loopback(addr)) |
225 | return ipbind_localhost_server->ib_server; |
226 | |
227 | return NULL; |
228 | @@ -863,7 +859,7 @@ |
229 | */ |
230 | if (!SocketBindTight) { |
231 | #ifdef PR_USE_IPV6 |
232 | - if (ipv6_supported) { |
233 | + if (pr_netaddr_use_ipv6()) { |
234 | pr_inet_set_default_family(NULL, AF_INET6); |
235 | |
236 | } else { |
237 | @@ -907,7 +903,7 @@ |
238 | if (serv->ServerPort) { |
239 | if (!SocketBindTight) { |
240 | #ifdef PR_USE_IPV6 |
241 | - if (ipv6_supported) { |
242 | + if (pr_netaddr_use_ipv6()) { |
243 | pr_inet_set_default_family(NULL, AF_INET6); |
244 | |
245 | } else { |
246 | @@ -973,7 +969,7 @@ |
247 | /* Check to see whether we can actually create an IPv6 socket. */ |
248 | sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); |
249 | if (sock < 0) { |
250 | - ipv6_supported = FALSE; |
251 | + pr_netaddr_disable_ipv6(); |
252 | |
253 | } else { |
254 | close(sock); |
255 | diff -urNad proftpd-dfsg-1.3.0~/src/dirtree.c proftpd-dfsg-1.3.0/src/dirtree.c |
256 | --- proftpd-dfsg-1.3.0~/src/dirtree.c 2006-11-22 19:44:32.000000000 +0100 |
257 | +++ proftpd-dfsg-1.3.0/src/dirtree.c 2006-11-22 19:44:46.000000000 +0100 |
258 | @@ -2830,14 +2830,16 @@ |
259 | const char *ipstr = pr_netaddr_get_ipstr(elts[i]); |
260 | |
261 | #ifdef PR_USE_IPV6 |
262 | - char ipbuf[INET6_ADDRSTRLEN]; |
263 | - if (pr_netaddr_get_family(elts[i]) == AF_INET) { |
264 | + if (pr_netaddr_use_ipv6()) { |
265 | + char *ipbuf = pcalloc(s->pool, INET6_ADDRSTRLEN); |
266 | + if (pr_netaddr_get_family(elts[i]) == AF_INET) { |
267 | |
268 | - /* Create the bind record using the IPv4-mapped IPv6 version of |
269 | - * this address. |
270 | - */ |
271 | - snprintf(ipbuf, sizeof(ipbuf), "::ffff:%s", ipstr); |
272 | - ipstr = ipbuf; |
273 | + /* Create the bind record using the IPv4-mapped IPv6 version of |
274 | + * this address. |
275 | + */ |
276 | + snprintf(ipbuf, sizeof(ipbuf), "::ffff:%s", ipstr); |
277 | + ipstr = ipbuf; |
278 | + } |
279 | } |
280 | #endif /* PR_USE_IPV6 */ |
281 | |
282 | diff -urNad proftpd-dfsg-1.3.0~/src/inet.c proftpd-dfsg-1.3.0/src/inet.c |
283 | --- proftpd-dfsg-1.3.0~/src/inet.c 2006-11-22 19:44:32.000000000 +0100 |
284 | +++ proftpd-dfsg-1.3.0/src/inet.c 2006-11-22 19:44:46.000000000 +0100 |
285 | @@ -209,7 +209,11 @@ |
286 | * support is enabled), otherwise use IPv4. |
287 | */ |
288 | #ifdef PR_USE_IPV6 |
289 | - addr_family = AF_INET6; |
290 | + if (pr_netaddr_use_ipv6()) |
291 | + addr_family = AF_INET6; |
292 | + |
293 | + else |
294 | + addr_family = AF_INET; |
295 | #else |
296 | addr_family = AF_INET; |
297 | #endif /* PR_USE_IPV6 */ |
298 | @@ -292,7 +296,8 @@ |
299 | pr_netaddr_set_sockaddr_any(&na); |
300 | |
301 | #if defined(PR_USE_IPV6) && defined(IPV6_V6ONLY) |
302 | - if (addr_family == AF_INET6) { |
303 | + if (pr_netaddr_use_ipv6() && |
304 | + addr_family == AF_INET6) { |
305 | int on = 0; |
306 | |
307 | # ifdef SOL_IP |
308 | @@ -1019,7 +1024,11 @@ |
309 | pr_netaddr_clear(&na); |
310 | |
311 | #ifdef PR_USE_IPV6 |
312 | - pr_netaddr_set_family(&na, AF_INET6); |
313 | + if (pr_netaddr_use_ipv6()) |
314 | + pr_netaddr_set_family(&na, AF_INET6); |
315 | + |
316 | + else |
317 | + pr_netaddr_set_family(&na, AF_INET); |
318 | #else |
319 | pr_netaddr_set_family(&na, AF_INET); |
320 | #endif /* PR_USE_IPV6 */ |
321 | @@ -1044,7 +1053,11 @@ |
322 | |
323 | /* "Reset" the pr_netaddr_t struct for the getpeername(2) call. */ |
324 | #ifdef PR_USE_IPV6 |
325 | - pr_netaddr_set_family(&na, AF_INET6); |
326 | + if (pr_netaddr_use_ipv6()) |
327 | + pr_netaddr_set_family(&na, AF_INET6); |
328 | + |
329 | + else |
330 | + pr_netaddr_set_family(&na, AF_INET); |
331 | #else |
332 | pr_netaddr_set_family(&na, AF_INET); |
333 | #endif /* PR_USE_IPV6 */ |
334 | diff -urNad proftpd-dfsg-1.3.0~/src/main.c proftpd-dfsg-1.3.0/src/main.c |
335 | --- proftpd-dfsg-1.3.0~/src/main.c 2006-11-22 19:44:45.000000000 +0100 |
336 | +++ proftpd-dfsg-1.3.0/src/main.c 2006-11-22 19:44:46.000000000 +0100 |
337 | @@ -2553,6 +2553,10 @@ |
338 | "Print version number and exit" }, |
339 | { "--version-status", "-vv", |
340 | "Print extended version information and exit" }, |
341 | + { "--ipv4", "-4", |
342 | + "Support IPv4 connections only" }, |
343 | + { "--ipv6", "-6", |
344 | + "Support IPv6 connections" }, |
345 | { NULL, NULL, NULL } |
346 | }; |
347 | |
348 | @@ -2574,7 +2578,7 @@ |
349 | |
350 | int main(int argc, char *argv[], char **envp) { |
351 | int optc, show_version = 0; |
352 | - const char *cmdopts = "D:NVc:d:hlnp:qtv"; |
353 | + const char *cmdopts = "D:NVc:d:hlnp:qtv46"; |
354 | mode_t *main_umask = NULL; |
355 | socklen_t peerlen; |
356 | struct sockaddr peer; |
357 | @@ -2658,6 +2662,10 @@ |
358 | * --configtest |
359 | * -v report version number |
360 | * --version |
361 | + * -4 support IPv4 connections only |
362 | + * --ipv4 |
363 | + * -6 support IPv6 connections |
364 | + * --ipv6 |
365 | */ |
366 | |
367 | opterr = 0; |
368 | @@ -2755,6 +2763,12 @@ |
369 | case 'h': |
370 | show_usage(0); |
371 | |
372 | + case 4: |
373 | + pr_netaddr_disable_ipv6(); |
374 | + |
375 | + case 6: |
376 | + pr_netaddr_enable_ipv6(); |
377 | + |
378 | case '?': |
379 | pr_log_pri(PR_LOG_ERR, "unknown option: %c", (char)optopt); |
380 | show_usage(1); |
381 | diff -urNad proftpd-dfsg-1.3.0~/src/netacl.c proftpd-dfsg-1.3.0/src/netacl.c |
382 | --- proftpd-dfsg-1.3.0~/src/netacl.c 2006-11-22 19:44:45.000000000 +0100 |
383 | +++ proftpd-dfsg-1.3.0/src/netacl.c 2006-11-22 19:44:46.000000000 +0100 |
384 | @@ -172,19 +172,20 @@ |
385 | |
386 | #ifdef PR_USE_IPV6 |
387 | case AF_INET6: { |
388 | - if (acl->masklen > 128) { |
389 | - errno = EINVAL; |
390 | - return NULL; |
391 | - |
392 | - } else if (pr_netaddr_is_v4mappedv6(acl->addr) == TRUE && |
393 | - acl->masklen > 32) { |
394 | - |
395 | - /* The admin may be trying to use IPv6-style masks on IPv4-mapped |
396 | - * IPv6 addresses, which of course will not work as expected. |
397 | - * If the mask is 32 bits or more, warn the admin. |
398 | - */ |
399 | - pr_log_pri(PR_LOG_WARNING, "warning: possibly using IPv6-style netmask on IPv4-mapped IPv6 address, which will not work as expected"); |
400 | - break; |
401 | + if (pr_netaddr_use_ipv6()) { |
402 | + if (acl->masklen > 128) { |
403 | + errno = EINVAL; |
404 | + return NULL; |
405 | + |
406 | + } else if (pr_netaddr_is_v4mappedv6(acl->addr) == TRUE && |
407 | + acl->masklen > 32) { |
408 | + /* The admin may be trying to use IPv6-style masks on IPv4-mapped |
409 | + * IPv6 addresses, which of course will not work as expected. |
410 | + * If the mask is 32 bits or more, warn the admin. |
411 | + */ |
412 | + pr_log_pri(PR_LOG_WARNING, "warning: possibly using IPv6-style netmask on IPv4-mapped IPv6 address, which will not work as expected"); |
413 | + break; |
414 | + } |
415 | } |
416 | } |
417 | #endif /* PR_USE_IPV6 */ |
418 | @@ -194,7 +195,7 @@ |
419 | } |
420 | |
421 | #ifdef PR_USE_IPV6 |
422 | - } else if (strspn(aclstr, "0123456789ABCDEFabcdef.:") != strlen(aclstr)) { |
423 | + } else if (pr_netaddr_use_ipv6() && strspn(aclstr, "0123456789ABCDEFabcdef.:") != strlen(aclstr)) { |
424 | #else |
425 | } else if (strspn(aclstr, "0123456789.") != strlen(aclstr)) { |
426 | #endif /* PR_USE_IPV6 */ |
427 | diff -urNad proftpd-dfsg-1.3.0~/src/netaddr.c proftpd-dfsg-1.3.0/src/netaddr.c |
428 | --- proftpd-dfsg-1.3.0~/src/netaddr.c 2006-11-22 19:44:45.000000000 +0100 |
429 | +++ proftpd-dfsg-1.3.0/src/netaddr.c 2006-11-22 19:44:46.000000000 +0100 |
430 | @@ -43,6 +43,13 @@ |
431 | /* Do reverse DNS lookups? */ |
432 | static int reverse_dns = 1; |
433 | |
434 | +/* Use IPv6? */ |
435 | +#ifdef PR_USE_IPV6 |
436 | +static int use_ipv6 = TRUE; |
437 | +#else |
438 | +static int use_ipv6 = FALSE; |
439 | +#endif /* PR_USE_IPV6 */ |
440 | + |
441 | /* Provide replacements for needed functions. */ |
442 | |
443 | #if !defined(HAVE_GETNAMEINFO) || defined(PR_USE_GETNAMEINFO) |
444 | @@ -276,9 +283,6 @@ |
445 | array_header **addrs) { |
446 | |
447 | struct sockaddr_in v4; |
448 | -#ifdef PR_USE_IPV6 |
449 | - struct sockaddr_in6 v6; |
450 | -#endif /* PR_USE_IPV6 */ |
451 | pr_netaddr_t *na = NULL; |
452 | int res; |
453 | |
454 | @@ -300,23 +304,26 @@ |
455 | na = (pr_netaddr_t *) pcalloc(p, sizeof(pr_netaddr_t)); |
456 | |
457 | #ifdef PR_USE_IPV6 |
458 | - memset(&v6, 0, sizeof(v6)); |
459 | - v6.sin6_family = AF_INET6; |
460 | + if (use_ipv6) { |
461 | + struct sockaddr_in6 v6; |
462 | + memset(&v6, 0, sizeof(v6)); |
463 | + v6.sin6_family = AF_INET6; |
464 | |
465 | # ifdef SIN6_LEN |
466 | - v6.sin6_len = sizeof(struct sockaddr_in6); |
467 | + v6.sin6_len = sizeof(struct sockaddr_in6); |
468 | # endif /* SIN6_LEN */ |
469 | |
470 | - res = pr_inet_pton(AF_INET6, name, &v6.sin6_addr); |
471 | - if (res > 0) { |
472 | - pr_netaddr_set_family(na, AF_INET6); |
473 | - pr_netaddr_set_sockaddr(na, (struct sockaddr *) &v6); |
474 | - if (addrs) |
475 | - *addrs = NULL; |
476 | + res = pr_inet_pton(AF_INET6, name, &v6.sin6_addr); |
477 | + if (res > 0) { |
478 | + pr_netaddr_set_family(na, AF_INET6); |
479 | + pr_netaddr_set_sockaddr(na, (struct sockaddr *) &v6); |
480 | + if (addrs) |
481 | + *addrs = NULL; |
482 | |
483 | - pr_log_debug(DEBUG10, "'%s' resolved to IPv6 address %s", name, |
484 | - pr_netaddr_get_ipstr(na)); |
485 | - return na; |
486 | + pr_log_debug(DEBUG10, "'%s' resolved to IPv6 address %s", name, |
487 | + pr_netaddr_get_ipstr(na)); |
488 | + return na; |
489 | + } |
490 | } |
491 | #endif /* PR_USE_IPV6 */ |
492 | |
493 | @@ -377,7 +384,7 @@ |
494 | } |
495 | |
496 | #ifdef PR_USE_IPV6 |
497 | - if (addrs) { |
498 | + if (use_ipv6 && addrs) { |
499 | /* Do the call again, this time for IPv6 addresses. |
500 | * |
501 | * We make two separate getaddrinfo(3) calls, rather than one |
502 | @@ -454,8 +461,10 @@ |
503 | |
504 | #ifdef PR_USE_IPV6 |
505 | case AF_INET6: |
506 | - na->na_addr.v6.sin6_family = AF_INET6; |
507 | - break; |
508 | + if (use_ipv6) { |
509 | + na->na_addr.v6.sin6_family = AF_INET6; |
510 | + break; |
511 | + } |
512 | #endif /* PR_USE_IPV6 */ |
513 | |
514 | default: |
515 | @@ -483,7 +492,8 @@ |
516 | |
517 | #ifdef PR_USE_IPV6 |
518 | case AF_INET6: |
519 | - return sizeof(struct sockaddr_in6); |
520 | + if (use_ipv6) |
521 | + return sizeof(struct sockaddr_in6); |
522 | #endif /* PR_USE_IPV6 */ |
523 | } |
524 | |
525 | @@ -503,7 +513,8 @@ |
526 | |
527 | #ifdef PR_USE_IPV6 |
528 | case AF_INET6: |
529 | - return sizeof(struct in6_addr); |
530 | + if (use_ipv6) |
531 | + return sizeof(struct in6_addr); |
532 | #endif /* PR_USE_IPV6 */ |
533 | } |
534 | |
535 | @@ -523,7 +534,8 @@ |
536 | |
537 | #ifdef PR_USE_IPV6 |
538 | case AF_INET6: |
539 | - return (struct sockaddr *) &na->na_addr.v6; |
540 | + if (use_ipv6) |
541 | + return (struct sockaddr *) &na->na_addr.v6; |
542 | #endif /* PR_USE_IPV6 */ |
543 | } |
544 | |
545 | @@ -545,8 +557,10 @@ |
546 | |
547 | #ifdef PR_USE_IPV6 |
548 | case AF_INET6: |
549 | - memcpy(&(na->na_addr.v6), addr, sizeof(struct sockaddr_in6)); |
550 | - return 0; |
551 | + if (use_ipv6) { |
552 | + memcpy(&(na->na_addr.v6), addr, sizeof(struct sockaddr_in6)); |
553 | + return 0; |
554 | + } |
555 | #endif /* PR_USE_IPV6 */ |
556 | } |
557 | |
558 | @@ -574,12 +588,14 @@ |
559 | |
560 | #ifdef PR_USE_IPV6 |
561 | case AF_INET6: |
562 | - na->na_addr.v6.sin6_family = AF_INET6; |
563 | + if (use_ipv6) { |
564 | + na->na_addr.v6.sin6_family = AF_INET6; |
565 | #ifdef SIN6_LEN |
566 | - na->na_addr.v6.sin6_len = sizeof(struct sockaddr_in6); |
567 | + na->na_addr.v6.sin6_len = sizeof(struct sockaddr_in6); |
568 | #endif /* SIN6_LEN */ |
569 | - memcpy(&na->na_addr.v6.sin6_addr, &in6addr_any, sizeof(struct in6_addr)); |
570 | - return 0; |
571 | + memcpy(&na->na_addr.v6.sin6_addr, &in6addr_any, sizeof(struct in6_addr)); |
572 | + return 0; |
573 | + } |
574 | #endif /* PR_USE_IPV6 */ |
575 | } |
576 | |
577 | @@ -599,7 +615,8 @@ |
578 | |
579 | #ifdef PR_USE_IPV6 |
580 | case AF_INET6: |
581 | - return (void *) &na->na_addr.v6.sin6_addr; |
582 | + if (use_ipv6) |
583 | + return (void *) &na->na_addr.v6.sin6_addr; |
584 | #endif /* PR_USE_IPV6 */ |
585 | } |
586 | |
587 | @@ -619,7 +636,8 @@ |
588 | |
589 | #ifdef PR_USE_IPV6 |
590 | case AF_INET6: |
591 | - return na->na_addr.v6.sin6_port; |
592 | + if (use_ipv6) |
593 | + return na->na_addr.v6.sin6_port; |
594 | #endif /* PR_USE_IPV6 */ |
595 | } |
596 | |
597 | @@ -640,8 +658,10 @@ |
598 | |
599 | #ifdef PR_USE_IPV6 |
600 | case AF_INET6: |
601 | - na->na_addr.v6.sin6_port = port; |
602 | - return 0; |
603 | + if (use_ipv6) { |
604 | + na->na_addr.v6.sin6_port = port; |
605 | + return 0; |
606 | + } |
607 | #endif /* PR_USE_IPV6 */ |
608 | } |
609 | |
610 | @@ -724,11 +744,13 @@ |
611 | |
612 | #ifdef PR_USE_IPV6 |
613 | case AF_INET6: |
614 | - res = memcmp(&a->na_addr.v6.sin6_addr, &b->na_addr.v6.sin6_addr, |
615 | - sizeof(struct in6_addr)); |
616 | - if (tmp_pool); |
617 | - destroy_pool(tmp_pool); |
618 | - return res; |
619 | + if (use_ipv6) { |
620 | + res = memcmp(&a->na_addr.v6.sin6_addr, &b->na_addr.v6.sin6_addr, |
621 | + sizeof(struct in6_addr)); |
622 | + if (tmp_pool) |
623 | + destroy_pool(tmp_pool); |
624 | + return res; |
625 | + } |
626 | #endif /* PR_USE_IPV6 */ |
627 | } |
628 | |
629 | @@ -821,15 +843,17 @@ |
630 | |
631 | #ifdef PR_USE_IPV6 |
632 | case AF_INET6: { |
633 | - /* Make sure that the given number of bits is not more than supported |
634 | - * for IPv6 addresses (128). |
635 | - */ |
636 | - if (bitlen > 128) { |
637 | - errno = EINVAL; |
638 | - return -1; |
639 | - } |
640 | + if (use_ipv6) { |
641 | + /* Make sure that the given number of bits is not more than supported |
642 | + * for IPv6 addresses (128). |
643 | + */ |
644 | + if (bitlen > 128) { |
645 | + errno = EINVAL; |
646 | + return -1; |
647 | + } |
648 | |
649 | - break; |
650 | + break; |
651 | + } |
652 | } |
653 | #endif /* PR_USE_IPV6 */ |
654 | |
655 | @@ -1029,7 +1053,7 @@ |
656 | |
657 | #ifdef PR_USE_IPV6 |
658 | case AF_INET6: |
659 | - if (family == AF_INET6) { |
660 | + if (use_ipv6 && family == AF_INET6) { |
661 | for (checkaddr = hent->h_addr_list; *checkaddr; ++checkaddr) { |
662 | if (memcmp(*checkaddr, inaddr, hent->h_length) == 0) { |
663 | ok = TRUE; |
664 | @@ -1090,7 +1114,7 @@ |
665 | return NULL; |
666 | } |
667 | |
668 | -int pr_netaddr_loopback(const pr_netaddr_t *na) { |
669 | +int pr_netaddr_is_loopback(const pr_netaddr_t *na) { |
670 | if (!na) { |
671 | errno = EINVAL; |
672 | return -1; |
673 | @@ -1103,7 +1127,6 @@ |
674 | |
675 | #ifdef PR_USE_IPV6 |
676 | case AF_INET6: |
677 | - |
678 | /* XXX *sigh* Different platforms implement the IN6_IS_ADDR macros |
679 | * differently. For example, on Linux, those macros expect to operate |
680 | * on s6_addr32, while on Solaris, the macros operate on struct in6_addr. |
681 | @@ -1175,7 +1198,11 @@ |
682 | return -1; |
683 | |
684 | #ifdef PR_USE_IPV6 |
685 | - case AF_INET6: |
686 | + case AF_INET6: { |
687 | + if (!use_ipv6) { |
688 | + errno = EINVAL; |
689 | + return -1; |
690 | + } |
691 | |
692 | # ifndef LINUX |
693 | return IN6_IS_ADDR_V4MAPPED( |
694 | @@ -1184,6 +1211,7 @@ |
695 | return IN6_IS_ADDR_V4MAPPED( |
696 | ((struct in6_addr *) pr_netaddr_get_inaddr(na))->s6_addr32); |
697 | # endif |
698 | + } |
699 | #endif /* PR_USE_IPV6 */ |
700 | } |
701 | |
702 | @@ -1234,3 +1262,22 @@ |
703 | sstrncpy(sess_remote_name, session.c->remote_name, sizeof(sess_remote_name)); |
704 | have_sess_remote_addr = TRUE; |
705 | } |
706 | + |
707 | +unsigned char pr_netaddr_use_ipv6(void) { |
708 | + if (use_ipv6) |
709 | + return TRUE; |
710 | + |
711 | + return FALSE; |
712 | +} |
713 | + |
714 | +void pr_netaddr_disable_ipv6(void) { |
715 | +#ifdef PR_USE_IPV6 |
716 | + use_ipv6 = 0; |
717 | +#endif /* PR_USE_IPV6 */ |
718 | +} |
719 | + |
720 | +void pr_netaddr_enable_ipv6(void) { |
721 | +#ifdef PR_USE_IPV6 |
722 | + use_ipv6 = 1; |
723 | +#endif /* PR_USE_IPV6 */ |
724 | +} |