Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 265 - (hide annotations) (download)
Wed Jul 11 23:16:10 2007 UTC (16 years, 11 months ago) by niro
File size: 21606 byte(s)
- proftpd-1.3.0a-r1

1 niro 265 # 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     +}