summaryrefslogtreecommitdiffstats
path: root/vsftpd/04-link-local.patch
blob: 53b373561098d562a9200984f2fcca01cca03cb6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
Author: Michael Stapelberg <michael@stapelberg.de>
Description:
 vsftpd does not accept IPv6 scope identifier in listen_address6
 (Closes: #544993).
 .
 When specifying a link-local address, you need a scope identifier (tha name of
 the index usually), thus you cannot use the following:
 listen_address6=fe80::21f:16ff:fe06:3aab
 but you have to use:
 listen_address6=fe80::21f:16ff:fe06:3aab%eth0
 so that it is clear on which interface this link-local address should be used.
 .
 Unfortunately, vsftpd does not correctly parse the address mentioned above and
 thus fails to be useful in link-local-only environments.
 .
 This patch fixes it.

diff -Naurp vsftpd.orig/standalone.c vsftpd/standalone.c
--- vsftpd.orig/standalone.c	2009-10-02 14:15:18.000000000 +0200
+++ vsftpd/standalone.c	2009-10-17 17:10:02.000000000 +0200
@@ -7,6 +7,8 @@
  * Code to listen on the network and launch children servants.
  */
 
+#include <net/if.h>
+
 #include "standalone.h"
 
 #include "parseconf.h"
@@ -111,8 +113,17 @@ vsf_standalone_main(void)
     else
     {
       struct mystr addr_str = INIT_MYSTR;
+      struct mystr scope_id = INIT_MYSTR;
       const unsigned char* p_raw_addr;
+      unsigned int if_index = 0;
+
+      /* See if we got a scope id */
       str_alloc_text(&addr_str, tunable_listen_address6);
+      str_split_char(&addr_str, &scope_id, '%');
+      if (str_getlen(&scope_id) > 0) {
+        if_index = if_nametoindex(str_getbuf(&scope_id));
+        str_free(&scope_id);
+      }
       p_raw_addr = vsf_sysutil_parse_ipv6(&addr_str);
       str_free(&addr_str);
       if (!p_raw_addr)
@@ -120,6 +131,7 @@ vsf_standalone_main(void)
         die2("bad listen_address6: ", tunable_listen_address6);
       }
       vsf_sysutil_sockaddr_set_ipv6addr(p_sockaddr, p_raw_addr);
+      vsf_sysutil_sockaddr_set_ipv6scope(p_sockaddr, if_index);
     }
     retval = vsf_sysutil_bind(listen_sock, p_sockaddr);
     vsf_sysutil_free(p_sockaddr);
diff -Naurp vsftpd.orig/sysutil.c vsftpd/sysutil.c
--- vsftpd.orig/sysutil.c	2009-10-02 14:15:18.000000000 +0200
+++ vsftpd/sysutil.c	2009-10-17 17:10:02.000000000 +0200
@@ -2039,6 +2039,19 @@ vsf_sysutil_sockaddr_set_ipv6addr(struct
   }
 }
 
+int
+vsf_sysutil_sockaddr_get_ipv6scope(struct vsf_sysutil_sockaddr* p_sockptr)
+{
+  return p_sockptr->u.u_sockaddr_in6.sin6_scope_id;
+}
+
+void
+vsf_sysutil_sockaddr_set_ipv6scope(struct vsf_sysutil_sockaddr* p_sockptr,
+                                  const int scope_id)
+{
+  p_sockptr->u.u_sockaddr_in6.sin6_scope_id = scope_id;
+}
+
 const void*
 vsf_sysutil_sockaddr_ipv6_v4(const struct vsf_sysutil_sockaddr* p_addr)
 {
diff -Naurp vsftpd.orig/sysutil.h vsftpd/sysutil.h
--- vsftpd.orig/sysutil.h	2009-10-02 14:15:18.000000000 +0200
+++ vsftpd/sysutil.h	2009-10-17 17:10:02.000000000 +0200
@@ -228,6 +228,9 @@ void vsf_sysutil_sockaddr_set_ipv4addr(s
                                        const unsigned char* p_raw);
 void vsf_sysutil_sockaddr_set_ipv6addr(struct vsf_sysutil_sockaddr* p_sockptr,
                                        const unsigned char* p_raw);
+void vsf_sysutil_sockaddr_set_ipv6scope(struct vsf_sysutil_sockaddr* p_sockptr,
+                                      const int scope_id);
+int vsf_sysutil_sockaddr_get_ipv6scope(struct vsf_sysutil_sockaddr* p_sockptr);
 void vsf_sysutil_sockaddr_set_any(struct vsf_sysutil_sockaddr* p_sockaddr);
 unsigned short vsf_sysutil_sockaddr_get_port(
     const struct vsf_sysutil_sockaddr* p_sockptr);