Magellan Linux

Contents of /trunk/proftpd/patches/proftpd-1.3.0a-ipv6_on-off.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 265 - (show annotations) (download)
Wed Jul 11 23:16:10 2007 UTC (16 years, 10 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 +}