1 Author: Michael Stapelberg <michael@stapelberg.de>
3 vsftpd does not accept IPv6 scope identifier in listen_address6
6 When specifying a link-local address, you need a scope identifier (tha name of
7 the index usually), thus you cannot use the following:
8 listen_address6=fe80::21f:16ff:fe06:3aab
10 listen_address6=fe80::21f:16ff:fe06:3aab%eth0
11 so that it is clear on which interface this link-local address should be used.
13 Unfortunately, vsftpd does not correctly parse the address mentioned above and
14 thus fails to be useful in link-local-only environments.
18 diff -Naurp vsftpd.orig/standalone.c vsftpd/standalone.c
19 --- vsftpd.orig/standalone.c 2009-10-02 14:15:18.000000000 +0200
20 +++ vsftpd/standalone.c 2009-10-17 17:10:02.000000000 +0200
22 * Code to listen on the network and launch children servants.
27 #include "standalone.h"
29 #include "parseconf.h"
30 @@ -111,8 +113,17 @@ vsf_standalone_main(void)
33 struct mystr addr_str = INIT_MYSTR;
34 + struct mystr scope_id = INIT_MYSTR;
35 const unsigned char* p_raw_addr;
36 + unsigned int if_index = 0;
38 + /* See if we got a scope id */
39 str_alloc_text(&addr_str, tunable_listen_address6);
40 + str_split_char(&addr_str, &scope_id, '%');
41 + if (str_getlen(&scope_id) > 0) {
42 + if_index = if_nametoindex(str_getbuf(&scope_id));
43 + str_free(&scope_id);
45 p_raw_addr = vsf_sysutil_parse_ipv6(&addr_str);
48 @@ -120,6 +131,7 @@ vsf_standalone_main(void)
49 die2("bad listen_address6: ", tunable_listen_address6);
51 vsf_sysutil_sockaddr_set_ipv6addr(p_sockaddr, p_raw_addr);
52 + vsf_sysutil_sockaddr_set_ipv6scope(p_sockaddr, if_index);
54 retval = vsf_sysutil_bind(listen_sock, p_sockaddr);
55 vsf_sysutil_free(p_sockaddr);
56 diff -Naurp vsftpd.orig/sysutil.c vsftpd/sysutil.c
57 --- vsftpd.orig/sysutil.c 2009-10-02 14:15:18.000000000 +0200
58 +++ vsftpd/sysutil.c 2009-10-17 17:10:02.000000000 +0200
59 @@ -2039,6 +2039,19 @@ vsf_sysutil_sockaddr_set_ipv6addr(struct
64 +vsf_sysutil_sockaddr_get_ipv6scope(struct vsf_sysutil_sockaddr* p_sockptr)
66 + return p_sockptr->u.u_sockaddr_in6.sin6_scope_id;
70 +vsf_sysutil_sockaddr_set_ipv6scope(struct vsf_sysutil_sockaddr* p_sockptr,
73 + p_sockptr->u.u_sockaddr_in6.sin6_scope_id = scope_id;
77 vsf_sysutil_sockaddr_ipv6_v4(const struct vsf_sysutil_sockaddr* p_addr)
79 diff -Naurp vsftpd.orig/sysutil.h vsftpd/sysutil.h
80 --- vsftpd.orig/sysutil.h 2009-10-02 14:15:18.000000000 +0200
81 +++ vsftpd/sysutil.h 2009-10-17 17:10:02.000000000 +0200
82 @@ -228,6 +228,9 @@ void vsf_sysutil_sockaddr_set_ipv4addr(s
83 const unsigned char* p_raw);
84 void vsf_sysutil_sockaddr_set_ipv6addr(struct vsf_sysutil_sockaddr* p_sockptr,
85 const unsigned char* p_raw);
86 +void vsf_sysutil_sockaddr_set_ipv6scope(struct vsf_sysutil_sockaddr* p_sockptr,
87 + const int scope_id);
88 +int vsf_sysutil_sockaddr_get_ipv6scope(struct vsf_sysutil_sockaddr* p_sockptr);
89 void vsf_sysutil_sockaddr_set_any(struct vsf_sysutil_sockaddr* p_sockaddr);
90 unsigned short vsf_sysutil_sockaddr_get_port(
91 const struct vsf_sysutil_sockaddr* p_sockptr);