]> git.pld-linux.org Git - packages/proftpd.git/blob - proftpd-IPv6.patch
- added Obsolete: glftpd
[packages/proftpd.git] / proftpd-IPv6.patch
1 diff -urN proftpd-1.2.5/Make.rules.in proftpd-1.2.5.v6/Make.rules.in
2 --- proftpd-1.2.5/Make.rules.in Sat Mar 17 21:34:31 2001
3 +++ proftpd-1.2.5.v6/Make.rules.in      Thu Aug  8 21:35:24 2002
4 @@ -56,18 +56,18 @@
5  
6  OBJS=main.o timers.o sets.o pool.o regexp.o dirtree.o support.o inet.o \
7       log.o bindings.o scoreboard.o feat.o netio.o response.o ident.o \
8 -     data.o modules.o auth.o fsio.o mkhome.o
9 +     data.o modules.o auth.o fsio.o mkhome.o intoa.o
10  BUILD_OBJS=src/main.o src/timers.o src/sets.o src/pool.o src/regexp.o \
11             src/dirtree.o src/support.o src/inet.o src/log.o src/bindings.o \
12             src/scoreboard.o src/feat.o src/netio.o src/response.o \
13             src/ident.o src/data.o src/modules.o src/auth.o src/fsio.o \
14 -           src/mkhome.o
15 +           src/mkhome.o src/intoa.o
16  
17  MODULE_OBJS=@MODULE_OBJS@
18  BUILD_MODULE_OBJS=@BUILD_MODULE_OBJS@ modules/module_glue.o
19  
20 -FTPCOUNT_OBJS=ftpcount.o scoreboard.o
21 -BUILD_FTPCOUNT_OBJS=utils/ftpcount.o utils/scoreboard.o
22 +FTPCOUNT_OBJS=ftpcount.o scoreboard.o intoa.o
23 +BUILD_FTPCOUNT_OBJS=utils/ftpcount.o utils/scoreboard.o src/intoa.o
24  
25  FTPSHUT_OBJS=ftpshut.o
26  BUILD_FTPSHUT_OBJS=utils/ftpshut.o
27 @@ -75,5 +75,5 @@
28  FTPTOP_OBJS=ftptop.o scoreboard.o
29  BUILD_FTPTOP_OBJS=utils/ftptop.o utils/scoreboard.o
30  
31 -FTPWHO_OBJS=ftpwho.o scoreboard.o misc.o
32 -BUILD_FTPWHO_OBJS=utils/ftpwho.o utils/scoreboard.o utils/misc.o
33 +FTPWHO_OBJS=ftpwho.o scoreboard.o misc.o intoa.o
34 +BUILD_FTPWHO_OBJS=utils/ftpwho.o utils/scoreboard.o utils/misc.o src/intoa.o
35 diff -urN proftpd-1.2.5/README.IPv6 proftpd-1.2.5.v6/README.IPv6
36 --- proftpd-1.2.5/README.IPv6   Thu Jan  1 01:00:00 1970
37 +++ proftpd-1.2.5.v6/README.IPv6        Thu Aug  8 21:35:24 2002
38 @@ -0,0 +1,23 @@
39 +FTP Daemon with IPv6 support for PLD GNU/Linux (http://www.pld.org.pl/)
40 +
41 +IPv6 port by Jan Rekorajski <baggins@pld.org.pl>
42 +Note from me:
43 +Proftpd program is an example of How NOT To write networking code.
44 +
45 +Fixes by Arkadiusz Miskiewicz <misiek@pld.org.pl>:
46 +- removed IPv4-mapped hell
47 +- don't duplicate connection code
48 +- fixed EPRT (parsing, address missmatch)
49 +- inet_validate() recognize colon address notation
50 +- "EPSV ALL" support as specified in RFC
51 +- recognize [v6addr]/mask in Class
52 +
53 +Config:
54 +If you want to specify IPv6 addres, you may use '[' ']'
55 +notation ([::1] for example).
56 +
57 +Known Bugs:
58 +- none known
59 +
60 +Todo:
61 +- test fully VirtualHosts and IPv4 <-> IPv6 interoperability
62 diff -urN proftpd-1.2.5/acconfig.h proftpd-1.2.5.v6/acconfig.h
63 --- proftpd-1.2.5/acconfig.h    Sat Mar 17 21:34:31 2001
64 +++ proftpd-1.2.5.v6/acconfig.h Thu Aug  8 21:35:24 2002
65 @@ -80,6 +80,13 @@
66   * configure should, we hope <wink>, detect this for you.
67   */
68  #undef PF_ARGV_TYPE
69 +
70 +/* Define if you want IPv6 support */
71 +#undef INET6
72 +
73 +/* Define if you have ss_family field in struct sockaddr_storage */
74 +#undef HAVE_SS_FAMILY_IN_SS
75 +
76  @TOP@
77  
78  /* autoheader generated things inserted here. */
79 diff -urN proftpd-1.2.5/config.h.in proftpd-1.2.5.v6/config.h.in
80 --- proftpd-1.2.5/config.h.in   Sun May 12 22:48:54 2002
81 +++ proftpd-1.2.5.v6/config.h.in        Thu Aug  8 21:35:24 2002
82 @@ -82,6 +82,13 @@
83   */
84  #undef PF_ARGV_TYPE
85  
86 +/* Define if you want IPv6 support */
87 +#undef INET6
88 +
89 +/* Define if you have ss_family field in struct sockaddr_storage */
90 +#undef HAVE_SS_FAMILY_IN_SS
91 +
92 +
93  /* Define if using alloca.c.  */
94  #undef C_ALLOCA
95  
96 diff -urN proftpd-1.2.5/configure.in proftpd-1.2.5.v6/configure.in
97 --- proftpd-1.2.5/configure.in  Tue May 21 20:26:30 2002
98 +++ proftpd-1.2.5.v6/configure.in       Thu Aug  8 21:35:24 2002
99 @@ -520,6 +520,45 @@
100    esac
101  fi
102  
103 +dnl === part for IPv6 support ===
104 +AC_MSG_CHECKING([whether to enable ipv6])
105 +AC_ARG_ENABLE(ipv6,
106 +[  --enable-ipv6           Enable ipv6 support
107 +  --disable-ipv6          Disable ipv6 support],
108 +[case "$enableval" in
109 +  no)   AC_MSG_RESULT(no)
110 +        ;;
111 +  *)    AC_MSG_RESULT(yes)
112 +       AC_DEFINE(INET6)
113 +        CFLAGS="$CFLAGS -DINET6"
114 +        ;;
115 +esac],
116 +AC_TRY_RUN([ /* PF_INET6 avalable check */
117 +#include <sys/types.h>
118 +#include <sys/socket.h>
119 +main(){if (socket(PF_INET6, SOCK_STREAM, 0) < 0) exit(1); else exit(0);}
120 +],[     AC_MSG_RESULT(yes)
121 +       AC_DEFINE(INET6)
122 +],[     AC_MSG_RESULT(no)
123 +],[     AC_MSG_RESULT(unknown)
124 +]))
125 +AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage],
126 +               ac_cv_have_ss_family_in_struct_ss, [
127 +       AC_TRY_COMPILE(
128 +               [
129 +#include <sys/types.h>
130 +#include <sys/socket.h>
131 +               ],
132 +               [ struct sockaddr_storage s; s.ss_family = 1; ],
133 +               [ ac_cv_have_ss_family_in_struct_ss="yes" ],
134 +               [ ac_cv_have_ss_family_in_struct_ss="no" ],
135 +       )
136 +])
137 +if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then
138 +       AC_DEFINE(HAVE_SS_FAMILY_IN_SS)
139 +fi
140 +dnl === end of part for IPv6 support ===
141 +
142  dnl Check for various argv[] replacing functions on various OSs
143  AC_CHECK_FUNCS(setproctitle)
144  AC_CHECK_HEADERS(libutil.h)
145 diff -urN proftpd-1.2.5/contrib/mod_ratio.c proftpd-1.2.5.v6/contrib/mod_ratio.c
146 --- proftpd-1.2.5/contrib/mod_ratio.c   Mon May 27 04:31:50 2002
147 +++ proftpd-1.2.5.v6/contrib/mod_ratio.c        Thu Aug  8 21:35:24 2002
148 @@ -224,8 +224,6 @@
149  {
150    modret_t *mr = 0;
151    config_rec *c;
152 -  char buf[1024] = {'\0'};
153 -  char *mask;
154    char **data;
155  
156    if (!(g.enable = get_param_int (main_server->conf, "Ratios", FALSE) == TRUE))
157 @@ -256,23 +254,7 @@
158    c = find_config (main_server->conf, CONF_PARAM, "HostRatio", TRUE);
159    while (c)
160      {
161 -     mask = buf;
162 -      if (*(char *) c->argv[0] == '.')
163 -       {
164 -         *mask++ = '*';
165 -         sstrncpy (mask, c->argv[0], sizeof (buf));
166 -       }
167 -      else if (*(char *) ((char *) c->argv[0] + (strlen (c->argv[0]) - 1)) == '.')
168 -       {
169 -         sstrncpy (mask, c->argv[0], sizeof(buf) - 2);
170 -         sstrcat(buf, "*", sizeof(buf));
171 -       }
172 -      else
173 -       sstrncpy (mask, c->argv[0], sizeof (buf));
174 -
175 -      if (!pr_fnmatch (buf, session.c->remote_name, PR_FNM_NOESCAPE | PR_FNM_CASEFOLD) ||
176 -         !pr_fnmatch (buf, inet_ntoa (*session.c->remote_ipaddr),
177 -                      PR_FNM_NOESCAPE | PR_FNM_CASEFOLD))
178 +      if (match_ip(session.c->remote_ipaddr, session.c->remote_name, c->argv[0]))
179         {
180           _set_ratios (c->argv[1], c->argv[2], c->argv[3], c->argv[4]);
181           g.rtype = "h";
182 @@ -436,7 +418,7 @@
183        snprintf (buf, sizeof(buf), RATIO_STUFFS);
184        log_pri (LOG_NOTICE, "Ratio: %s/%s %s[%s]: %s.", g.user,
185                session.group, session.c->remote_name,
186 -              inet_ntoa (*session.c->remote_ipaddr), buf);
187 +              INET_NTOA (session.c->remote_ipaddr), buf);
188      }
189    return DECLINED (cmd);
190  }
191 diff -urN proftpd-1.2.5/contrib/mod_sql.c proftpd-1.2.5.v6/contrib/mod_sql.c
192 --- proftpd-1.2.5/contrib/mod_sql.c     Sun Jun  9 04:38:27 2002
193 +++ proftpd-1.2.5.v6/contrib/mod_sql.c  Thu Aug  8 21:35:24 2002
194 @@ -1314,7 +1314,7 @@
195      break;
196    case 'a':
197      argp = arg;
198 -    sstrncpy(argp, inet_ntoa(*session.c->remote_ipaddr), sizeof(arg));
199 +    sstrncpy(argp, INET_NTOA(session.c->remote_ipaddr), sizeof(arg));
200      break;
201    case 'l':
202      argp = arg;
203 diff -urN proftpd-1.2.5/include/conf.h proftpd-1.2.5.v6/include/conf.h
204 --- proftpd-1.2.5/include/conf.h        Wed Sep 26 17:00:33 2001
205 +++ proftpd-1.2.5.v6/include/conf.h     Thu Aug  8 21:35:24 2002
206 @@ -322,8 +322,6 @@
207  
208  /* Generic typedefs */
209  
210 -typedef struct in_addr p_in_addr_t;
211 -
212  #include "pool.h"
213  #include "regexp.h"
214  #include "proftpd.h"
215 @@ -357,4 +355,8 @@
216  
217  #endif /* __PROFTPD_SUPPORT_LIBRARY */
218  
219 +#ifdef HAVE_SS_FAMILY_IN_SS
220 +#define __ss_family   ss_family
221 +#endif
222 +
223  #endif /* PR_CONF_H */
224 diff -urN proftpd-1.2.5/include/dirtree.h proftpd-1.2.5.v6/include/dirtree.h
225 --- proftpd-1.2.5/include/dirtree.h     Tue May 21 22:47:15 2002
226 +++ proftpd-1.2.5.v6/include/dirtree.h  Thu Aug  8 21:35:24 2002
227 @@ -59,7 +59,7 @@
228  
229    int AnonymousGreeting;       /* Do not greet until after user login */  
230  
231 -  p_in_addr_t *ipaddr;         /* Internal address of this server */
232 +  struct sockaddr_storage *ipaddr;     /* Internal address of this server */
233    struct conn_struc *listen;   /* Our listening connection */
234    xaset_t *conf;               /* Configuration details */
235  
236 @@ -201,7 +201,7 @@
237  config_rec *find_config(xaset_t *, int, const char *, int);
238  void find_config_set_top(config_rec *);
239  int remove_config(xaset_t *, const char *, int);
240 -class_t *find_class(p_in_addr_t *, char *);
241 +class_t *find_class(struct sockaddr_storage *, char *);
242  
243  array_header *parse_group_expression(pool *, int *, char **);
244  array_header *parse_user_expression(pool *, int *, char **);
245 @@ -236,6 +236,6 @@
246  char *get_context_name(cmd_rec *);
247  int get_boolean(cmd_rec *, int);
248  char *get_full_cmd(cmd_rec *);
249 -int match_ip(p_in_addr_t *, char *, const char *);
250 +int match_ip(struct sockaddr_storage*, char*, const char *);
251  
252  #endif /* __DIRTREE_H */
253 diff -urN proftpd-1.2.5/include/ftp.h proftpd-1.2.5.v6/include/ftp.h
254 --- proftpd-1.2.5/include/ftp.h Fri May 10 18:52:39 2002
255 +++ proftpd-1.2.5.v6/include/ftp.h      Thu Aug  8 21:35:24 2002
256 @@ -85,6 +85,8 @@
257  #define C_MIC   "MIC"          /* Integrity protected command */
258  #define C_PBSZ  "PBSZ"         /* Protection buffer size */
259  #define C_PROT  "PROT"         /* Data channel protection level */
260 +#define C_EPSV "EPSV"          /* Extended PASV */
261 +#define C_EPRT "EPRT"          /* Extended PORT */
262  
263  #define C_ANY  "*"             /* Special "wildcard" matching command */
264  
265 @@ -113,6 +115,7 @@
266  #define R_225  "225"           /* Data connection open; no transfer in progress */
267  #define R_226  "226"           /* Closing data connection.  File transfer/abort successful */
268  #define R_227  "227"           /* Entering passive mode (h1,h2,h3,h4,p1,p2) */
269 +#define R_229  "229"           /* Entering extended passive mode (|||p|) */
270  #define R_230  "230"           /* User logged in, proceed */
271  #define R_232   "232"          /* User logged in, authorized by security data */
272  #define R_234   "234"          /* Security data exchange complete */
273 @@ -138,6 +141,7 @@
274  #define R_502  "502"           /* Command not implemented */
275  #define R_503  "503"           /* Bad sequence of commands */
276  #define R_504  "504"           /* Command not implemented for that parameter */
277 +#define R_522  "522"           /* Extended Port Failure - unknown network protocol */
278  #define R_530  "530"           /* Not logged in */
279  #define R_532  "532"           /* Need account for storing files */
280  #define R_533   "533"          /* Integrity protected command required by policy */
281 diff -urN proftpd-1.2.5/include/inet.h proftpd-1.2.5.v6/include/inet.h
282 --- proftpd-1.2.5/include/inet.h        Tue May 21 22:47:15 2002
283 +++ proftpd-1.2.5.v6/include/inet.h     Thu Aug  8 21:35:24 2002
284 @@ -69,9 +69,9 @@
285    int rfd,wfd;                         /* Read and write fds */
286    pr_netio_stream_t *instrm, *outstrm; /* Input/Output streams */
287  
288 -  p_in_addr_t *remote_ipaddr;          /* Remote address of connection */
289 +  struct sockaddr_storage *remote_ipaddr;      /* Remote address of connection */
290    int remote_port;                     /* Remote port of connection */
291 -  p_in_addr_t *local_ipaddr;           /* Local side of connection */
292 +  struct sockaddr_storage *local_ipaddr;       /* Local side of connection */
293    int local_port;                      /* Local port */
294    char *remote_name;                   /* Remote FQDN */
295  } conn_t;
296 @@ -85,14 +85,16 @@
297  char *inet_validate(char *);
298  char *inet_gethostname(pool *);
299  char *inet_fqdn(pool *, const char *);
300 -p_in_addr_t *inet_getaddr(pool *, char *);
301 -char *inet_ascii(pool *, p_in_addr_t *);
302 -char *inet_getname(pool *, p_in_addr_t *);
303 +struct sockaddr_storage *inet_getaddr(pool*,char*);
304 +char *inet_ascii(pool*,struct sockaddr_storage*);
305 +char *inet_getname(pool*,struct sockaddr_storage*);
306  conn_t *inet_copy_connection(pool *, conn_t*);
307 +#if 0
308  int inet_prebind_socket(pool *, p_in_addr_t *, int);
309 -conn_t *inet_create_dup_connection(pool *, xaset_t *, int, p_in_addr_t *);
310 -conn_t *inet_create_connection(pool *, xaset_t *, int, p_in_addr_t *, int, int);
311 -conn_t *inet_create_connection_portrange(pool *, xaset_t *, p_in_addr_t *,
312 +#endif
313 +conn_t *inet_create_dup_connection(pool*,xaset_t*,int,struct sockaddr_storage*);
314 +conn_t *inet_create_connection(pool *, xaset_t *, int, struct sockaddr_storage *, int, int);
315 +conn_t *inet_create_connection_portrange(pool *, xaset_t *, struct sockaddr_storage *,
316    int, int);
317  void inet_close(pool *, conn_t *);
318  void inet_lingering_close(pool *, conn_t *, long);
319 @@ -104,13 +106,19 @@
320  int inet_listen(pool *, conn_t *, int);
321  int inet_resetlisten(pool *, conn_t *);
322  int inet_accept_nowait(pool *, conn_t *);
323 -int inet_connect(pool *, conn_t *, p_in_addr_t *, int);
324 -int inet_connect_nowait(pool*,conn_t*,p_in_addr_t*,int);
325 +int inet_connect(pool *, conn_t *, struct sockaddr_storage *, int);
326 +int inet_connect_nowait(pool*,conn_t*,struct sockaddr_storage*, int);
327  int inet_get_conn_info(conn_t *, int);
328  conn_t *inet_accept(pool *, conn_t *, conn_t *, int, int, unsigned char);
329 -conn_t *inet_associate(pool *, conn_t *, p_in_addr_t *,
330 -  pr_netio_stream_t *, pr_netio_stream_t *, int);
331 -conn_t *inet_openrw(pool *, conn_t *, p_in_addr_t *, int, int, int, int, int);
332 +conn_t *inet_associate(pool *, conn_t *, struct sockaddr_storage *, IOFILE *, IOFILE *, int);
333 +conn_t *inet_openrw(pool *, conn_t *, struct sockaddr_storage *, int, int, int, int);
334  void inet_resolve_ip(pool *, conn_t *);
335 +int inet_address_match(struct sockaddr_storage *cp,struct sockaddr_storage *rp);
336 +int inet_prefix_match(struct sockaddr_storage *cp,struct sockaddr_storage *rp, int prefix);
337 +#ifdef INET6
338 +char *INET_NTOA(struct sockaddr_storage *ss);
339 +#else
340 +#define INET_NTOA(a) inet_ntoa(((struct sockaddr_in *)(a))->sin_addr)
341 +#endif
342  
343  #endif /* PR_INET_H */
344 diff -urN proftpd-1.2.5/include/log.h proftpd-1.2.5.v6/include/log.h
345 --- proftpd-1.2.5/include/log.h Tue May 21 22:47:15 2002
346 +++ proftpd-1.2.5.v6/include/log.h      Thu Aug  8 21:35:24 2002
347 @@ -66,7 +66,7 @@
348  #define LOG_XFER_MODE           0644
349  
350  char *fmt_time(time_t);
351 -int log_wtmp(char *, const char *, const char *, p_in_addr_t *);
352 +int log_wtmp(char *, char *, char *, struct sockaddr_storage *);
353  void log_setfacility(int);
354  int log_openfile(const char *, int *, mode_t);
355  int log_opensyslog(const char *);
356 diff -urN proftpd-1.2.5/include/proftpd.h proftpd-1.2.5.v6/include/proftpd.h
357 --- proftpd-1.2.5/include/proftpd.h     Tue May 21 22:47:15 2002
358 +++ proftpd-1.2.5.v6/include/proftpd.h  Thu Aug  8 21:35:24 2002
359 @@ -71,8 +71,8 @@
360  typedef struct cdir_struc {
361    struct cdir_struc *next;
362  
363 -  u_int_32 address;
364 -  u_int_32 netmask;
365 +  struct sockaddr_storage address;
366 +  u_int_32 prefix;
367    class_t *class;
368  } cdir_t;
369  
370 @@ -94,7 +94,7 @@
371    volatile int sf_flags;               /* Session/State flags */
372    volatile int sp_flags;               /* Session/Protection flags */
373  
374 -  p_in_addr_t data_addr;               /* Remote data address */
375 +  struct sockaddr_storage data_addr;   /* Remote data address */
376    unsigned short data_port;            /* Remote data port */
377  
378    unsigned char ident_lookups;         /* Is RFC931 (ident) protocol used? */
379 @@ -210,9 +210,11 @@
380  #define SF_ANON                (1 << 5)        /* Anonymous (chroot) login */
381  #define SF_POST_ABORT  (1 << 6)        /* After abort has occured */
382  #define SF_PORT                (1 << 7)        /* Port command given */
383 +#define        SF_EPSV_ALL     (1 << 8)        /* EPSV ALL command given */
384  
385  #define SF_ALL         (SF_PASSIVE|SF_ABORT|SF_XFER|SF_ASCII| \
386 -                        SF_ASCII_OVERRIDE|SF_ANON|SF_POST_ABORT|SF_PORT)
387 +                        SF_ASCII_OVERRIDE|SF_ANON|SF_POST_ABORT|SF_PORT| \
388 +                       SF_EPSV_ALL)
389  
390  /* Session/Protection flags (RFC 2228) */
391  
392 diff -urN proftpd-1.2.5/include/support.h proftpd-1.2.5.v6/include/support.h
393 --- proftpd-1.2.5/include/support.h     Tue May 21 22:47:15 2002
394 +++ proftpd-1.2.5.v6/include/support.h  Thu Aug  8 21:35:24 2002
395 @@ -98,4 +98,6 @@
396  char *sstrncpy(char *, const char *, size_t);
397  char *sreplace(pool *, char *, ...);
398  
399 +void mappedtov4(struct sockaddr_storage *);
400 +
401  #endif /* PR_SUPPORT_H */
402 diff -urN proftpd-1.2.5/modules/mod_auth.c proftpd-1.2.5.v6/modules/mod_auth.c
403 --- proftpd-1.2.5/modules/mod_auth.c    Tue May 21 22:47:16 2002
404 +++ proftpd-1.2.5.v6/modules/mod_auth.c Thu Aug  8 21:35:24 2002
405 @@ -1210,7 +1210,7 @@
406    PRIVS_ROOT
407    while((l = log_read_run(NULL)) != NULL)
408        /* Make sure it matches our current server */
409 -      if(l->server_ip.s_addr == main_server->ipaddr->s_addr &&
410 +      if(inet_address_match(&l->server_ip, main_server->ipaddr) &&
411           l->server_port == main_server->ServerPort) {
412          
413         cur++;
414 @@ -1270,11 +1270,11 @@
415        
416        /* Make sure it matches our current server.
417         */
418 -      if(l->server_ip.s_addr == main_server->ipaddr->s_addr &&
419 +      if(inet_address_match(&l->server_ip, main_server->ipaddr) &&
420           l->server_port == main_server->ServerPort) {
421          if((c && c->config_type == CONF_ANON && !strcmp(l->user, user)) ||
422            !c) {
423 -          char *s, *d, ip[32] = {'\0'};
424 +          char *s, *d, ip[64] = {'\0'};
425            int mpos = sizeof(ip) - 1;
426           
427            cur++;
428 @@ -1292,7 +1292,7 @@
429           
430           /* Count up sessions on a per-host basis.
431            */
432 -          if(!strcmp(ip, inet_ntoa(*session.c->remote_ipaddr))) {
433 +          if(!strcmp(ip, INET_NTOA(session.c->remote_ipaddr))) {
434             samehost++;
435              hcur++;
436           }
437 diff -urN proftpd-1.2.5/modules/mod_core.c proftpd-1.2.5.v6/modules/mod_core.c
438 --- proftpd-1.2.5/modules/mod_core.c    Tue May 21 22:47:16 2002
439 +++ proftpd-1.2.5.v6/modules/mod_core.c Thu Aug  8 21:35:24 2002
440 @@ -63,6 +63,8 @@
441    { C_REIN, "is not implemented",              FALSE },
442    { C_PORT, "<sp> h1,h2,h3,h4,p1,p2",          TRUE },
443    { C_PASV, "(returns address/port)",          TRUE },
444 +  { C_EPRT, "<sp> |proto|addr|port|",          TRUE },
445 +  { C_EPSV, "(returns port |||port|)",         TRUE },
446    { C_TYPE, "<sp> type-code (A, I, L 7, L 8)", TRUE },
447    { C_STRU, "is not implemented (always F)",   TRUE },
448    { C_MODE, "is not implemented (always S)",   TRUE },
449 @@ -401,7 +403,7 @@
450  
451  MODRET add_masqueradeaddress(cmd_rec *cmd) {
452   config_rec *c = NULL;
453 - p_in_addr_t *masq_addr = NULL;
454 + struct sockaddr_storage *masq_addr = NULL;
455   char masq_ip[80] = {'\0'};
456  
457   CHECK_ARGS(cmd, 1);
458 @@ -2029,7 +2031,7 @@
459     
460    if ((c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress",
461        FALSE)) != NULL) {
462 -    p_in_addr_t *masq_addr = (p_in_addr_t *) c->argv[0];
463 +    struct sockaddr_storage *masq_addr = (struct sockaddr_storage *) c->argv[0];
464      serverfqdn = inet_getname(main_server->pool, masq_addr);
465    }
466   
467 @@ -2191,7 +2193,7 @@
468  MODRET cmd_pasv(cmd_rec *cmd)
469  {
470    union {
471 -    p_in_addr_t addr;
472 +    struct in_addr addr;
473      unsigned char u[4];
474    } addr;
475  
476 @@ -2203,8 +2205,16 @@
477    config_rec *c = NULL;
478    int pasv_min_port,pasv_max_port;
479    
480 +  if (session.flags & SF_EPSV_ALL)
481 +      return ERROR_MSG(cmd,R_500,"Illegal PASV command - EPSV ALL requested before.");
482 +
483    CHECK_CMD_ARGS(cmd, 1);
484  
485 +#ifdef INET6
486 +  if (session.c->local_ipaddr->__ss_family == AF_INET6)
487 +      return ERROR_MSG(cmd,R_425, "PASV over IPv6? Find a real FTP client.");
488 +#endif
489 +
490    /* If we already have a passive listen data connection open, kill it.
491     */
492    if(session.d) {
493 @@ -2250,14 +2260,16 @@
494    session.data_port = session.d->local_port;
495    session.flags |= SF_PASSIVE;
496    
497 -  addr.addr = *session.d->local_ipaddr;
498 +  addr.addr.s_addr = ((struct sockaddr_in *)session.d->local_ipaddr)->sin_addr.s_addr;
499  
500    /* check for a MasqueradeAddress configuration record, and return that
501     * addr if appropriate.
502     */
503    if ((c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress",
504 -      FALSE)) != NULL)
505 -   addr.addr = *((p_in_addr_t *) c->argv[0]);
506 +      FALSE)) != NULL) {
507 +       struct sockaddr_storage *masq_addr = (struct sockaddr_storage *)c->argv[0];
508 +       addr.addr.s_addr = ((struct sockaddr_in *)masq_addr)->sin_addr.s_addr;
509 +  }
510  
511    port.port = htons(session.data_port);
512    
513 @@ -2275,7 +2287,7 @@
514  MODRET cmd_port(cmd_rec *cmd)
515  {
516    union {
517 -    p_in_addr_t addr;
518 +    struct in_addr addr;
519      unsigned char u[4];
520    } addr;
521  
522 @@ -2285,11 +2297,19 @@
523    } port;
524  
525    char *a,*endp,*arg;
526 -  int i,cnt = 0;
527 +  int p,i,cnt = 0;
528    int allow_foreign_addr = 0;
529  
530 +  if (session.flags & SF_EPSV_ALL)
531 +      return ERROR_MSG(cmd,R_500,"Illegal PORT command - EPSV ALL requested before.");
532 +  
533    CHECK_CMD_ARGS(cmd, 2);
534  
535 +#ifdef INET6
536 +  if (session.c->local_ipaddr->__ss_family == AF_INET6)
537 +      return ERROR_MSG(cmd,R_500, "PORT over IPv6? Find a real FTP client.");
538 +#endif
539 +
540    /* Format is h1,h2,h3,h4,p1,p2 (ASCII in network order) */
541    a = pstrdup(cmd->tmp_pool,cmd->argv[1]);
542  
543 @@ -2322,8 +2342,10 @@
544    allow_foreign_addr = get_param_int(TOPLEVEL_CONF,"AllowForeignAddress",FALSE);
545  
546    if(allow_foreign_addr != 1) {
547 -    if(addr.addr.s_addr != session.c->remote_ipaddr->s_addr ||
548 -       !port.port) {
549 +    
550 +    p = ((struct sockaddr_in *)session.c->remote_ipaddr)->sin_addr.s_addr;
551 +
552 +    if(addr.addr.s_addr != p || !port.port) {
553        log_pri(LOG_WARNING, "Refused PORT %s (address mismatch).", cmd->arg);
554        return ERROR_MSG(cmd, R_500, "Illegal PORT command.");
555      }
556 @@ -2338,7 +2360,9 @@
557      return ERROR_MSG(cmd,R_500,"Illegal PORT command.");
558    }
559  
560 -  memcpy(&session.data_addr, &addr.addr, sizeof(session.data_addr));
561 +  session.data_addr.__ss_family = AF_INET;
562 +  ((struct sockaddr_in *)&session.data_addr)->sin_port = port.port;
563 +  ((struct sockaddr_in *)&session.data_addr)->sin_addr.s_addr = addr.addr.s_addr;
564    session.data_port = ntohs(port.port);
565    session.flags &= (SF_ALL^SF_PASSIVE);
566  
567 @@ -2355,6 +2379,207 @@
568    return HANDLED(cmd);
569  }
570  
571 +MODRET cmd_epsv(cmd_rec *cmd)
572 +{
573 +  char *endp,*arg;
574 +  int family;
575 +  config_rec *c = NULL;
576 +  int pasv_min_port,pasv_max_port;
577 +
578 +  CHECK_CMD_MIN_ARGS(cmd, 1);
579 +
580 +  arg = pstrdup(cmd->tmp_pool,cmd->argv[1]);
581 +
582 +  if (arg) {
583 +    if (!strncasecmp(arg, "all", 3)) {
584 +       session.flags |= SF_EPSV_ALL;
585 +       add_response(R_200, "EPSV ALL command successful.");
586 +       return HANDLED(cmd);
587 +    } else {
588 +      family = strtol(arg, &endp, 10);
589 +      if (family == 1) {
590 +#ifdef INET6
591 +       if (!(session.c->local_ipaddr->__ss_family == AF_INET))
592 +          return ERROR_MSG(cmd,R_522,"Illegal EPSV command - IPv4 not supported over this link.");
593 +#endif
594 +      } else if (family == 2) {
595 +#ifdef INET6
596 +       if (!(session.c->local_ipaddr->__ss_family == AF_INET6))
597 +#endif
598 +          return ERROR_MSG(cmd,R_522,"Illegal EPSV command - IPv6 not supported over this link.");
599 +      } else {
600 +        return ERROR_MSG(cmd,R_522,"Illegal EPSV command - unknown network protocol.");
601 +      }
602 +    }
603 +  }
604 +
605 +  /* If we already have a passive listen data connection open,
606 +   * kill it.
607 +   */
608 +
609 +  if(session.d) {
610 +    inet_close(session.d->pool,session.d);
611 +    session.d = NULL;
612 +  }
613 +
614 +  if ((c = find_config(main_server->conf, CONF_PARAM, "PassivePorts", FALSE)) !=
615 +      NULL) {
616 +    pasv_min_port = (int)c->argv[0];
617 +    pasv_max_port = (int)c->argv[1];
618 +
619 +    if(!(session.d = inet_create_connection_portrange(session.pool, NULL,
620 +                                   session.c->local_ipaddr,
621 +                                   pasv_min_port,pasv_max_port))) {
622 +      /* If not able to open a passive port in the given range, default to
623 +       * normal behavior (using INPORT_ANY), and log the failure.  This
624 +       * indicates a too-small range configuration.
625 +       */
626 +      log_pri(LOG_WARNING, "unable to find open port in PassivePorts range "
627 +             "%d-%d: defaulting to INPORT_ANY", pasv_min_port, pasv_max_port);
628 +    }
629 +  }
630 +
631 +  
632 +  /* Open up the connection and pass it back.
633 +   */
634 +  if (!session.d)
635 +    session.d = inet_create_connection(session.pool, NULL, -1,
636 +                                       session.c->local_ipaddr,
637 +                                       INPORT_ANY, FALSE);
638 +
639 +  if(!session.d)
640 +     return ERROR_MSG(cmd,R_425,
641 +                     "Unable to build data connection: Internal error.");
642 +
643 +  inet_setblock(session.pool,session.d);
644 +  inet_listen(session.pool,session.d,1);
645 +
646 +  session.d->inf = io_open(session.pool,session.d->listen_fd,IO_READ);
647 +
648 +  /* Now tell the client our address/port */
649 +  session.data_port = session.d->local_port;
650 +  session.flags |= SF_PASSIVE;
651 +
652 +  log_debug(DEBUG1,"Entering Extended Passive Mode (|||%u|).", (int)session.data_port);
653 +  add_response(R_229, "Entering Extended Passive Mode (|||%u|).", (int)session.data_port);
654 +
655 +  return HANDLED(cmd);
656 +}
657 +
658 +MODRET cmd_eprt(cmd_rec *cmd)
659 +{
660 +  struct sockaddr_storage addr;
661 +  unsigned short port = 0;
662 +  char *a,*endp,*arg;
663 +  char delim[2];
664 +  int family,i,cnt = 0;
665 +  int allow_foreign_addr = 0;
666 +
667 +  if (session.flags & SF_EPSV_ALL)
668 +      return ERROR_MSG(cmd,R_500,"Illegal EPRT command - EPSV ALL requested before.");
669 +
670 +  CHECK_CMD_ARGS(cmd, 2);
671 +
672 +  bzero(&addr, sizeof(struct sockaddr_storage));
673 +
674 +  /* Format is <d>proto<d>ip address<d>port<d> (ASCII in network order) */
675 +  a = pstrdup(cmd->tmp_pool,cmd->argv[1]);
676 +
677 +  delim[0] = *a++;
678 +  delim[1] = '\0';
679 +
680 +  family = strtol(a, &endp, 10);
681 +  if (family == 1)
682 +    addr.__ss_family = AF_INET;
683 +#ifdef INET6
684 +  else if (family == 2)
685 +    addr.__ss_family = AF_INET6;
686 +#endif
687 +  else
688 +    return ERROR_MSG(cmd,R_522,"Illegal EPRT command - unknown network protocol.");
689 +
690 +  if (!*endp)
691 +    return ERROR_MSG(cmd,R_501,"Illegal EPRT command.");
692 +
693 +  a = ++endp;
694 +  
695 +  while(a && *a && cnt < 2) {
696 +    arg = strsep(&a,delim);
697 +
698 +    if(!arg && a && *a) {
699 +      arg = a;
700 +      a = NULL;
701 +    } else if(!arg)
702 +      break;
703 +
704 +    if (cnt == 0) {
705 +      i = 0;
706 +      if (family == 1)
707 +        i = inet_pton(AF_INET, arg, &((struct sockaddr_in *)&addr)->sin_addr);
708 +#ifdef INET6
709 +      else
710 +        i = inet_pton(AF_INET6, arg, &((struct sockaddr_in6 *)&addr)->sin6_addr);
711 +#endif
712 +      if (i == 0)
713 +        break;
714 +    } else if (cnt == 1) {
715 +      i = strtol(arg,&endp,10);
716 +      if(*endp || i < 1)
717 +        break;
718 +      port = (unsigned short)i;
719 +      if (family == 1)
720 +        ((struct sockaddr_in *)&addr)->sin_port = htons(port);
721 +#ifdef INET6
722 +      else
723 +        ((struct sockaddr_in6 *)&addr)->sin6_port = htons(port);
724 +#endif
725 +    } else
726 +       break;
727 +    cnt++;
728 +  }
729 +
730 +  if(cnt != 2 || (a && *a))
731 +    return ERROR_MSG(cmd,R_501,"Illegal EPRT command.");
732 +
733 +  /* Make sure that the address specified matches the address
734 +   * that the control connection is coming from.
735 +   */
736 +
737 +  allow_foreign_addr = get_param_int(TOPLEVEL_CONF,"AllowForeignAddress",FALSE);
738 +
739 +  if(allow_foreign_addr != 1) {
740 +    if(!inet_address_match(&addr, session.c->remote_ipaddr) || !port) {
741 +      log_pri(LOG_WARNING, "Refused EPRT %s (address mismatch).", cmd->arg);
742 +      return ERROR_MSG(cmd, R_500, "Illegal EPRT command.");
743 +    }
744 +  }
745 +
746 +  /* Additionally, make sure that the port number used is a "high
747 +   * numbered" port, to avoid bounce attacks
748 +   */
749 +
750 +  if(port < 1024) {
751 +    log_pri(LOG_WARNING, "Refused EPRT %s (bounce attack).", cmd->arg);
752 +    return ERROR_MSG(cmd,R_500,"Illegal EPRT command.");
753 +  }
754 +
755 +  memcpy(&session.data_addr, &addr, sizeof(struct sockaddr_storage));
756 +  session.data_port = port;
757 +  session.flags &= (SF_ALL^SF_PASSIVE);
758 +
759 +  /* If we already have a data connection open, kill it.
760 +   */
761 +
762 +  if(session.d) {
763 +    inet_close(session.d->pool,session.d);
764 +    session.d = NULL;
765 +  }
766 +  
767 +  session.flags |= SF_PORT;
768 +  add_response(R_200,"EPRT command successful.");
769 +  return HANDLED(cmd);
770 +}
771 +
772  MODRET cmd_help(cmd_rec *cmd)
773  {
774    int i,c = 0;
775 @@ -3044,18 +3269,15 @@
776         return NULL;
777  }
778  
779 -static cdir_t *add_cdir(class_t *class, u_int_32 address, u_int_8 netmask)
780 +static cdir_t *add_cdir(class_t *class, struct sockaddr_storage *address, u_int_32 prefix)
781  {
782         cdir_t *n;
783  
784         n = calloc(1, sizeof(cdir_t));
785  
786         n->class = class;
787 -       while (netmask--) {
788 -               n->netmask >>= 1;
789 -               n->netmask |= 0x80000000;
790 -       }
791 -       n->address = address & n->netmask;
792 +       n->prefix = prefix;
793 +       memcpy(&n->address, address, sizeof(struct sockaddr_storage));
794  
795         n->next = cdir_list;
796         cdir_list = n;                  
797 @@ -3063,7 +3285,7 @@
798         return n;
799  }
800  
801 -static cdir_t *find_cdir(u_int_32 address)
802 +static cdir_t *find_cdir(struct sockaddr_storage *address)
803  {
804         cdir_t *c, *f;
805  
806 @@ -3071,7 +3293,8 @@
807         f = NULL;
808         while (c) {
809                 /* within cdir range ? && more specific netmask ? */
810 -               if (((address & c->netmask) == c->address) && (f == NULL || (f && (f->netmask < c->netmask))))
811 +               if (inet_prefix_match(&c->address, address, c->prefix) &&
812 +                   (f == NULL || (f && (f->prefix < c->prefix))))
813                         f = c;
814  
815                 c = c->next;
816 @@ -3108,18 +3331,18 @@
817         return NULL;
818  }
819  
820 -class_t *find_class(p_in_addr_t *addr, char *remote_name)
821 +class_t *find_class(struct sockaddr_storage *addr, char *remote_name)
822  {
823         cdir_t *ip;
824         hostname_t *host;
825         class_t *c, *f;
826  
827 -       if ((ip = find_cdir(ntohl(addr->s_addr))) != NULL)
828 +       if ((ip = find_cdir(addr)) != NULL)
829                 return ip->class;
830  
831         if ((host = find_hostname(remote_name)) != NULL)
832                 return host->class;
833 -       if ((host = find_hostname(inet_ntoa(*addr))) != NULL)
834 +       if ((host = find_hostname(INET_NTOA(addr))) != NULL)
835                 return host->class;
836  
837         c = class_list;
838 @@ -3140,8 +3363,8 @@
839  {
840    int bits, ret;
841    class_t *n;
842 -  p_in_addr_t *res;
843 -  char *ptr, ipaddress[20] = {'\0'}, errmsg[80] = {'\0'};
844 +  struct sockaddr_storage *res;
845 +  char *ptr, *ptrr, ipaddress[50] = {'\0'}, errmsg[80] = {'\0'};
846  #if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
847    regex_t *preg;
848  #endif
849 @@ -3197,19 +3420,28 @@
850        CONF_ERROR(cmd, "wrong syntax error.");
851      } else {
852        bits = atol(ptr + 1);
853 -      
854 +#ifdef INET6
855 +      if (bits < 0 || bits > 128) {
856 +#else
857        if (bits < 0 || bits > 32) {
858 +#endif
859         log_pri(LOG_ERR, "Class '%s' ipmask %s skipped: wrong netmask.",
860                 cmd->argv[1], cmd->argv[3]);
861        }
862        
863        *ptr = 0;
864      }
865 +
866 +    if ((ptr = strchr(ipaddress, '[')) && (ptrr = strrchr(ipaddress, ']'))) {
867 +      ptr++;
868 +      *ptrr = 0;
869 +    } else
870 +       ptr = ipaddress;
871      
872 -    if((res = inet_getaddr(cmd->pool, ipaddress)) != NULL) {
873 -      add_cdir(n, ntohl(res->s_addr), bits);
874 -      log_debug(DEBUG4, "Class '%s' ipmask %p/%d added.",
875 -               cmd->argv[1], res, bits);
876 +    if((res = inet_getaddr(cmd->pool, ptr)) != NULL) {
877 +      add_cdir(n, res, bits);
878 +      log_debug(DEBUG4, "Class '%s' ipmask %s/%d added.",
879 +               cmd->argv[1], INET_NTOA(res), bits);
880      } else {
881        log_pri(LOG_ERR, "Class '%s' ip could not parse '%s'.",
882               cmd->argv[1], cmd->argv[3]);
883 @@ -3335,6 +3567,8 @@
884    { PRE_CMD, "*",G_NONE,  regex_filters,FALSE,  FALSE, CL_NONE },
885  #endif
886    { CMD, C_HELP, G_NONE,  cmd_help,    FALSE,  FALSE, CL_INFO },
887 +  { CMD, C_EPRT, G_NONE,  cmd_eprt,    TRUE,   FALSE, CL_MISC },
888 +  { CMD, C_EPSV, G_NONE,  cmd_epsv,    TRUE,   FALSE, CL_MISC },
889    { CMD, C_PORT, G_NONE,  cmd_port,    TRUE,   FALSE, CL_MISC },
890    { CMD, C_PASV, G_NONE,  cmd_pasv,    TRUE,   FALSE, CL_MISC },
891    { CMD, C_SYST, G_NONE,  cmd_syst,    TRUE,   FALSE, CL_INFO },
892 diff -urN proftpd-1.2.5/modules/mod_log.c proftpd-1.2.5.v6/modules/mod_log.c
893 --- proftpd-1.2.5/modules/mod_log.c     Tue May 21 22:47:17 2002
894 +++ proftpd-1.2.5.v6/modules/mod_log.c  Thu Aug  8 21:35:24 2002
895 @@ -537,7 +537,7 @@
896  
897    case META_REMOTE_IP:
898      argp = arg;
899 -    sstrncpy(argp, inet_ntoa(*session.c->remote_ipaddr), sizeof(arg));
900 +    sstrncpy(argp, INET_NTOA(session.c->remote_ipaddr), sizeof(arg));
901      m++;
902      break;
903  
904 diff -urN proftpd-1.2.5/src/data.c proftpd-1.2.5.v6/src/data.c
905 --- proftpd-1.2.5/src/data.c    Tue May 21 22:47:22 2002
906 +++ proftpd-1.2.5.v6/src/data.c Thu Aug  8 21:35:24 2002
907 @@ -230,10 +230,9 @@
908    
909    if(c) {
910      log_debug(DEBUG4,"active data connection opened - local  : %s:%d",
911 -             inet_ntoa(*session.d->local_ipaddr), session.d->local_port);
912 +             INET_NTOA(session.d->local_ipaddr), session.d->local_port);
913      log_debug(DEBUG4,"active data connection opened - remote : %s:%d",
914 -             inet_ntoa(*session.d->remote_ipaddr),
915 -             session.d->remote_port);
916 +             INET_NTOA(session.d->remote_ipaddr), session.d->remote_port);
917      
918      if(size) {
919        send_response(R_150,
920 diff -urN proftpd-1.2.5/src/dirtree.c proftpd-1.2.5.v6/src/dirtree.c
921 --- proftpd-1.2.5/src/dirtree.c Tue May 21 22:47:22 2002
922 +++ proftpd-1.2.5.v6/src/dirtree.c      Thu Aug  8 21:35:24 2002
923 @@ -917,13 +917,14 @@
924   * returns 0 if no match
925   */
926  
927 -int match_ip(p_in_addr_t *addr, char *name, const char *match)
928 +int match_ip(struct sockaddr_storage *addr, char *name, const char *match)
929  {
930    char buf[1024];
931 -  char *mask,*cp;
932 -  int cidr_mode = 0, cidr_bits;
933 -  p_in_addr_t cidr_addr;
934 -  u_int_32 cidr_mask = 0;
935 +  char *bufptr,*cp;
936 +  int netmatch = 0;
937 +#ifdef INET6
938 +  struct in6_addr     ia6, net6;
939 +#endif  /* INET6 */
940  
941    if(!strcasecmp(match,"ALL"))
942      return 1;
943 @@ -932,55 +933,108 @@
944      return -1;
945  
946    memset(buf,0,sizeof(buf));
947 -  mask = buf;
948 +  bufptr = buf;
949  
950    if(*match == '.') {
951 -    *mask++ = '*';
952 -    *mask = '\0';
953 +    *bufptr++ = '*';
954 +    *bufptr = '\0';
955      sstrcat(buf, match, sizeof(buf));
956    } else if(*(match + strlen(match) - 1) == '.') {
957      sstrcat(buf, match, sizeof(buf));
958      sstrcat(buf, "*", sizeof(buf));
959 -  } else if((cp = strchr(match,'/')) != NULL) { /* check for CIDR notation */
960 -    /* first portion of CIDR should be dotted quad, second portion
961 -     * is netmask
962 -     */
963 -    sstrncpy(buf, match, (cp-match)+1 <= sizeof(buf) ?
964 -                         (cp-match)+1 :  sizeof(buf));    
965 -    cidr_bits = atoi(cp+1);
966 -    
967 -    if(cidr_bits > 0 && cidr_bits < 33) {
968 -      int shift = 32 - cidr_bits;
969 -      
970 -      cidr_mode = 1;
971 -      while(cidr_bits--)
972 -       cidr_mask = (cidr_mask << 1) | 1;
973 -      cidr_mask = cidr_mask << shift;
974 -#ifdef HAVE_INET_ATON
975 -      if(inet_aton(mask,&cidr_addr) == 0)
976 -       return 0;
977 -#else
978 -      cidr_addr.s_addr = inet_addr(mask);
979 -#endif
980 -      cidr_addr.s_addr &= htonl(cidr_mask);
981 -    } else {
982 -      return 0;
983 -    }
984 +  } else if(*match == '[' && *(match + strlen(match) - 1) == ']') {
985 +    sstrcat(buf, match+1, sizeof(buf));
986 +    *(bufptr + strlen(bufptr) - 1) = '\0';
987    } else {
988      sstrcat(buf, match, sizeof(buf));
989    }
990 -  
991 -  if(cidr_mode) {
992 -    if((addr->s_addr & htonl(cidr_mask)) == cidr_addr.s_addr)
993 +  /* Now match can be one of the following:
994 +   * (1)       *.domain
995 +   * (2)       123.456.*
996 +   * (3)       123.456.0.0/16
997 +   * (4)       abcd:1234::
998 +   * (5)       abcd:1234::dead:beef
999 +   * (6)       abcd:1234::/32
1000 +   */
1001 +#ifdef INET6
1002 +  if (addr->__ss_family == AF_INET6) {
1003 +    cp = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
1004 +  } else
1005 +#endif
1006 +    cp = (char *)&((struct sockaddr_in *)addr)->sin_addr;
1007 +  /* This will catch (1) and (2) */
1008 +  if(pr_fnmatch(buf, name, PR_FNM_NOESCAPE | PR_FNM_CASEFOLD) == 0 ||
1009 +     pr_fnmatch(buf, INET_NTOA(addr), PR_FNM_NOESCAPE | PR_FNM_CASEFOLD) == 0)
1010 +    return 1;
1011 +
1012 +  /* This will catch (4) and (5) */
1013 +#ifdef INET6
1014 +  /* For IPv6, pr_fnmatch() for comparing addresses is
1015 +     not working enough. */
1016 +  if (inet_pton(AF_INET6, buf, &net6) == 1) {
1017 +    if (name && inet_pton(AF_INET6, name, &ia6) == 1 &&
1018 +       IN6_ARE_ADDR_EQUAL(&ia6, &net6)) {
1019        return 1;
1020 -  } else {
1021 -    if(pr_fnmatch(buf, name, PR_FNM_NOESCAPE | PR_FNM_CASEFOLD) == 0 ||
1022 -       pr_fnmatch(buf, inet_ntoa(*addr),
1023 -                 PR_FNM_NOESCAPE | PR_FNM_CASEFOLD) == 0)
1024 +    } else if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)addr)->sin6_addr, &net6)) {
1025        return 1;
1026 +    }
1027    }
1028 -  
1029 -  return 0;
1030 +#endif
1031 +
1032 +  /* And now (3) and (6) */
1033 +  if((cp = strchr(match,'/')) != NULL) { /* check for CIDR notation */
1034 +    /* first portion of CIDR should be dotted quad, second portion
1035 +     * is netmask
1036 +     */
1037 +    int bits, c, n;
1038 +    struct in_addr ia, net;
1039 +    unsigned int mask;
1040 +
1041 +    *cp = '\0';
1042 +#ifdef INET6
1043 +    if (addr->__ss_family == AF_INET6) {
1044 +       ia.s_addr = INADDR_NONE;
1045 +    } else
1046 +#endif
1047 +    ia.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
1048 +    net.s_addr = inet_addr(match);
1049 +    if (ia.s_addr != (unsigned int)INADDR_NONE &&
1050 +       net.s_addr != (unsigned int)INADDR_NONE) {
1051 +      if (strchr(cp+1, '.') == (char *)NULL) {
1052 +       mask = atoi(cp+1);
1053 +       for (bits = c = 0; c < mask && c < 32; c++)
1054 +         bits |= (1 << (31 - c));
1055 +       mask = htonl(bits);
1056 +      } else {
1057 +       mask = inet_addr(cp+1);
1058 +      }
1059 +      if ((ia.s_addr & mask) == (net.s_addr & mask))
1060 +       return 1;
1061 +#ifdef INET6
1062 +    } else if (inet_pton(AF_INET6, buf, &net6) == 1) {
1063 +      struct sockaddr_in6 *pia6;
1064 +
1065 +      pia6 = (struct sockaddr_in6 *)addr;
1066 +      if (strchr(cp+1, ':') == (char *)NULL) {
1067 +       mask = atoi(cp+1);
1068 +       n = mask / 8;
1069 +       bits = mask % 8;
1070 +       netmatch = 1;
1071 +       for (c = 0; c < n; c++)
1072 +         if (pia6->sin6_addr.s6_addr[c] != net6.s6_addr[c]) {
1073 +           netmatch = 0;
1074 +           break;
1075 +         }
1076 +       if (netmatch && bits > 0) {
1077 +         if ((pia6->sin6_addr.s6_addr[c] & (0xff << (8 - bits))) !=
1078 +             (net6.s6_addr[c] & (0xff << (8 - bits))))
1079 +           netmatch = 0;
1080 +       }
1081 +      }
1082 +#endif  /* INET6 */
1083 +    }
1084 +  }
1085 +  return netmatch;
1086  }
1087  
1088  /* As of 1.2.0rc3, a '!' character in front of the IP address
1089 @@ -2513,7 +2567,7 @@
1090          FALSE)) != NULL) {
1091        log_pri(LOG_INFO, "%s:%d masquerading as %s",
1092          inet_ascii(s->pool, s->ipaddr), s->ServerPort,
1093 -        inet_ascii(s->pool, (p_in_addr_t *) c->argv[0]));
1094 +        inet_ascii(s->pool, c->argv[0]));
1095      }
1096  
1097      /* honor the DefaultServer directive only if SocketBindTight is not
1098 @@ -2521,7 +2575,11 @@
1099       */
1100      if (get_param_int(s->conf, "DefaultServer", FALSE) == 1) {
1101        if (!SocketBindTight)
1102 -        s->ipaddr->s_addr = 0;
1103 +#ifdef INET6
1104 +        memcpy(&((struct sockaddr_in6 *)s->ipaddr)->sin6_addr, &in6addr_any, sizeof(struct in6_addr));
1105 +#else
1106 +        ((struct sockaddr_in *)s->ipaddr)->sin_addr = INADDR_ANY;
1107 +#endif
1108        else
1109          log_pri(LOG_NOTICE,
1110            "SocketBindTight in effect, ignoring DefaultServer");
1111 diff -urN proftpd-1.2.5/src/inet.c proftpd-1.2.5.v6/src/inet.c
1112 --- proftpd-1.2.5/src/inet.c    Tue May 21 22:47:22 2002
1113 +++ proftpd-1.2.5.v6/src/inet.c Thu Aug  8 21:35:31 2002
1114 @@ -130,7 +130,11 @@
1115    for(p = buf; p && *p; p++) {
1116      /* Per RFC requirements, these are all that are valid from a DNS.
1117       */
1118 -    if(!isalnum(*p) && *p != '.' && *p != '-') {
1119 +    if(!isalnum(*p) && *p != '.' && *p != '-'
1120 +#ifdef INET6
1121 +           && *p != ':'
1122 +#endif
1123 +           ) {
1124        /* We set it to _ because we know that's an invalid, yet safe, option
1125         * for a DNS entry.
1126         */
1127 @@ -175,35 +179,31 @@
1128  
1129  /* DNS/hosts lookup for a particular name
1130   */
1131 -p_in_addr_t *inet_getaddr(pool *pool, char *name)
1132 +struct sockaddr_storage *inet_getaddr(pool *pool, char *name)
1133  {
1134 -  struct hostent *host;
1135 -  p_in_addr_t *res;
1136 +  struct addrinfo hints, *res, *res0;
1137 +  struct sockaddr_storage *ss;
1138  
1139 -  res = (p_in_addr_t*)pcalloc(pool,sizeof(p_in_addr_t));
1140 +  ss = (struct sockaddr_storage*)pcalloc(pool,sizeof(struct sockaddr_storage));
1141  
1142 -  /* Try dotted quad notation first */
1143 -#ifdef HAVE_INET_ATON
1144 -  if(inet_aton(name,res))
1145 -    return res;
1146 -#else
1147 -  /* This is a bit unclean, because inet_addr() is obsolete, and
1148 -   * returns -1 (255.255.255.255) if the input is invalid.  The caller
1149 -   * _might_ just be trying to resolve "255.255.255.255", in which case
1150 -   * this entire function will fail.  Hopefully, you have inet_aton().
1151 -   * <grin>
1152 -   */
1153 -  if((res->s_addr = inet_addr(name)) != -1)
1154 -    return res;
1155 -#endif
1156 +  bzero(&hints, sizeof(hints));
1157 +  hints.ai_family = AF_UNSPEC;
1158 +  hints.ai_socktype = SOCK_STREAM;
1159  
1160 -  host = gethostbyname(name);
1161 -  if(host) {
1162 -    memcpy(res, host->h_addr_list[0], sizeof(p_in_addr_t));
1163 -    return res;
1164 +  if (getaddrinfo(name, "0", &hints, &res0))
1165 +      return NULL;
1166 +  for (res = res0; res; res = res->ai_next) {
1167 +      if (res->ai_family == AF_INET
1168 +#ifdef INET6
1169 +             || res->ai_family == AF_INET6
1170 +#endif
1171 +             ) {
1172 +         memcpy(ss, res->ai_addr, res->ai_addrlen);
1173 +         freeaddrinfo(res0);
1174 +         return ss;
1175 +      }
1176    }
1177 -    
1178 -
1179 +  freeaddrinfo(res0);
1180    return NULL;
1181  }
1182  
1183 @@ -211,54 +211,51 @@
1184   * memory.
1185   */
1186  
1187 -char *inet_ascii(pool *pool, p_in_addr_t *addr)
1188 +char *inet_ascii(pool *pool, struct sockaddr_storage *ss)
1189  {
1190 +  static char buf[1024];
1191    char *res = NULL;
1192  
1193 -  if((res = inet_ntoa(*addr)) != NULL)
1194 -    res = pstrdup(pool,res);
1195 +  if (getnameinfo((struct sockaddr *)ss, sizeof(struct sockaddr_storage),
1196 +                         buf, sizeof(buf), NULL, 0, NI_NUMERICHOST))
1197 +         return NULL;
1198 +  
1199 +  res = pstrdup(pool,buf);
1200  
1201    return res;
1202  }
1203  
1204  /* Given an ip addresses, return the FQDN */
1205 -char *inet_getname(pool *pool, p_in_addr_t *addr)
1206 +char *inet_getname(pool *pool, struct sockaddr_storage *addr)
1207  {
1208 +  static char peername[1024];
1209    char *res = NULL;
1210    char **checkaddr;
1211 -  struct hostent *hptr_rev = NULL, *hptr_forw = NULL;
1212    static char *res_cache = NULL;
1213 -  static p_in_addr_t *addr_cache = NULL;
1214 +  static struct sockaddr_storage *addr_cache = NULL;
1215  
1216    if(reverse_dns) {
1217 -    if(res_cache && addr_cache && addr_cache->s_addr == addr->s_addr) {
1218 +    if(res_cache && addr_cache && inet_address_match(addr_cache, addr)) {
1219        res = pstrdup(pool, res_cache);
1220        return inet_validate(res);
1221      }
1222 -    
1223 -    if((hptr_rev = gethostbyaddr((const char *)addr,
1224 -                                 sizeof(p_in_addr_t), AF_INET)) != NULL) {
1225 -      if((hptr_forw = gethostbyname(hptr_rev->h_name)) != NULL) {
1226 -        for(checkaddr = hptr_forw->h_addr_list; *checkaddr; ++checkaddr) {
1227 -          if(((p_in_addr_t*)(*checkaddr))->s_addr == addr->s_addr) {
1228 -            res = pstrdup(pool, hptr_rev->h_name);
1229 -            break;
1230 -          }
1231 -        }
1232 -      }
1233 +
1234 +    if (getnameinfo((struct sockaddr *)&addr, sizeof(struct sockaddr_storage),
1235 +                   peername, sizeof(peername), NULL, 0, 0) == 0) {
1236 +            res = pstrdup(pool, peername);
1237      }
1238    }
1239    
1240    if(!res)
1241 -    res = pstrdup(pool, inet_ntoa(*addr));
1242 +    res = pstrdup(pool, INET_NTOA(addr));
1243   
1244    if(reverse_dns) {
1245      /* cache the result */
1246      if(!addr_cache)
1247 -      addr_cache = malloc(sizeof(p_in_addr_t));
1248 +      addr_cache = malloc(sizeof(struct sockaddr_storage));
1249  
1250      if(addr_cache)
1251 -      memcpy(addr_cache, addr, sizeof(p_in_addr_t));
1252 +      memcpy(addr_cache, addr, sizeof(struct sockaddr_storage));
1253  
1254      if(res_cache)
1255        free(res_cache);
1256 @@ -305,12 +302,12 @@
1257    res->inf = res->outf = NULL;
1258  
1259    if(c->local_ipaddr) {
1260 -    res->local_ipaddr = (p_in_addr_t*)palloc(res->pool,sizeof(p_in_addr_t));
1261 +    res->local_ipaddr = (struct sockaddr_storage*)palloc(res->pool,sizeof(struct sockaddr_storage));
1262      *res->local_ipaddr = *c->local_ipaddr;
1263    }
1264  
1265    if(c->remote_ipaddr) {
1266 -    res->remote_ipaddr = (p_in_addr_t*)palloc(res->pool,sizeof(p_in_addr_t));
1267 +    res->remote_ipaddr = (struct sockaddr_storage*)palloc(res->pool,sizeof(struct sockaddr_storage));
1268      *res->remote_ipaddr = *c->remote_ipaddr;
1269    }
1270  
1271 @@ -396,14 +393,15 @@
1272   * just for the new connection.
1273   */
1274  static conn_t *inet_initialize_connection(pool *p, xaset_t *servers, int fd,
1275 -                                         p_in_addr_t *bind_addr, int port,
1276 -                                         int retry_bind, int reporting)
1277 +                               struct sockaddr_storage *bind_addr,
1278 +                              int port, int retry_bind, int reporting)
1279  {
1280    pool *subpool;
1281    conn_t *c;
1282    array_header *tmp;
1283    server_rec *s;
1284 -  struct sockaddr_in servaddr;
1285 +  struct sockaddr_storage servaddr;
1286 +  int family;
1287    int i,res = 0, len, one = 1, hold_errno;
1288    
1289    CHECK_INET_POOL;
1290 @@ -414,7 +412,7 @@
1291    /* Build the accept IPs dynamically using the inet work pool,
1292     * once built, move into the conn struc.
1293     */
1294 -  tmp = make_array(inet_pool, 5, sizeof(p_in_addr_t));
1295 +  tmp = make_array(inet_pool, 5, sizeof(struct sockaddr_storage));
1296    subpool = make_sub_pool(p);
1297    c = (conn_t *) pcalloc(subpool, sizeof(conn_t));
1298    c->pool = subpool;
1299 @@ -422,9 +420,9 @@
1300    if(servers && servers->xas_list) {
1301      for(s = (server_rec *) servers->xas_list; s; s = s->next)
1302        if(s->ipaddr)
1303 -        *((p_in_addr_t *) push_array(tmp)) = *s->ipaddr;
1304 +        memcpy(((struct sockaddr_storage*)push_array(tmp)), s->ipaddr, sizeof(struct sockaddr_storage));
1305    } else {
1306 -    *((p_in_addr_t *) push_array(tmp)) = *main_server->ipaddr;
1307 +    memcpy(((struct sockaddr_storage*)push_array(tmp)), main_server->ipaddr, sizeof(struct sockaddr_storage));
1308    }
1309    
1310    c->local_port = port;
1311 @@ -436,6 +434,18 @@
1312     */
1313    if(fd == -1) {
1314      
1315 +    if (bind_addr)
1316 +       family = bind_addr->__ss_family;
1317 +    else {
1318 +#ifdef INET6
1319 +       if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) != -1) {
1320 +           close(fd);
1321 +           family = AF_INET6;
1322 +       } else
1323 +#endif
1324 +           family = AF_INET;
1325 +    }
1326 +
1327      /* Certain versions of Solaris apparently require us to be root
1328       * in order to create a socket inside a chroot ??
1329       */
1330 @@ -461,7 +471,7 @@
1331  # endif
1332  #endif
1333  
1334 -    fd = socket(AF_INET, SOCK_STREAM, tcp_proto);
1335 +    fd = socket(family, SOCK_STREAM, tcp_proto);
1336  
1337  #if defined(SOLARIS2) || defined(FREEBSD2) || defined(FREEBSD3) || \
1338      defined(FREEBSD4) || defined(__OpenBSD__) || defined(__NetBSD__) || \
1339 @@ -494,15 +504,28 @@
1340      
1341      memset(&servaddr, 0, sizeof(servaddr));
1342      
1343 -    servaddr.sin_family = AF_INET;
1344 -    
1345      if(bind_addr)
1346 -      memcpy(&servaddr.sin_addr, bind_addr, sizeof(servaddr.sin_addr));
1347 -    else
1348 -      servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
1349 -    
1350 -    servaddr.sin_port = htons(port);
1351 +       memcpy(&servaddr, bind_addr, sizeof(struct sockaddr_storage));
1352 +    else {
1353 +#ifdef INET6
1354 +       if (family == AF_INET6)
1355 +           ((struct sockaddr_in6 *)&servaddr)->sin6_addr = in6addr_any;
1356 +       else
1357 +#endif
1358 +           ((struct sockaddr_in *)&servaddr)->sin_addr.s_addr = htonl(INADDR_ANY);
1359 +    }
1360      
1361 +#ifdef INET6
1362 +    if (family == AF_INET6) {
1363 +       ((struct sockaddr_in6 *)&servaddr)->sin6_family = AF_INET6;
1364 +       ((struct sockaddr_in6 *)&servaddr)->sin6_port = htons(port);
1365 +    } else
1366 +#endif
1367 +    {
1368 +       ((struct sockaddr_in *)&servaddr)->sin_family = AF_INET;
1369 +       ((struct sockaddr_in *)&servaddr)->sin_port = htons(port);
1370 +    }
1371 +
1372      if(port != INPORT_ANY && port < 1024) {
1373        block_signals();
1374        PRIVS_ROOT
1375 @@ -549,7 +572,8 @@
1376  
1377        if(reporting) {
1378          log_pri(LOG_ERR, "Failed binding to %s, port %d: %s",
1379 -                inet_ntoa(servaddr.sin_addr), port, strerror(hold_errno));
1380 +                INET_NTOA((struct sockaddr_storage *)&servaddr),
1381 +                port, strerror(hold_errno));
1382          log_pri(LOG_ERR, "Check the ServerType directive "
1383                          "to ensure you are configured correctly.");
1384        }
1385 @@ -571,11 +595,16 @@
1386       */
1387      len = sizeof(servaddr);
1388      if(fd >= 0 && getsockname(fd, (struct sockaddr *) &servaddr, &len) != -1) {
1389 +      mappedtov4(&servaddr);
1390        if(!c->local_ipaddr)
1391 -        c->local_ipaddr = (p_in_addr_t *) pcalloc(c->pool,
1392 -                                                 sizeof(p_in_addr_t));
1393 -      *c->local_ipaddr = servaddr.sin_addr;
1394 -      c->local_port = ntohs(servaddr.sin_port);
1395 +        c->local_ipaddr = (struct sockaddr_storage*)pcalloc(c->pool,sizeof(struct sockaddr_storage));
1396 +      memcpy(c->local_ipaddr, &servaddr, sizeof(struct sockaddr_storage));
1397 +#ifdef INET6
1398 +      if (servaddr.__ss_family == AF_INET6)
1399 +         c->local_port = ntohs(((struct sockaddr_in6 *)&servaddr)->sin6_port);
1400 +      else
1401 +#endif
1402 +         c->local_port = ntohs(((struct sockaddr_in *)&servaddr)->sin_port);
1403      }
1404    }
1405    
1406 @@ -586,8 +615,8 @@
1407  }
1408  
1409  conn_t *inet_create_connection(pool *p, xaset_t *servers, int fd,
1410 -                               p_in_addr_t *bind_addr, int port,
1411 -                              int retry_bind)
1412 +                               struct sockaddr_storage *bind_addr,
1413 +                               int port, int retry_bind)
1414  {
1415    conn_t *c = inet_initialize_connection(p, servers, fd, bind_addr,
1416                                          port, retry_bind, TRUE);
1417 @@ -607,7 +636,8 @@
1418   */
1419  
1420  conn_t *inet_create_connection_portrange(pool *p, xaset_t *servers,
1421 -                               p_in_addr_t *bind_addr, int low_port, int high_port)
1422 +                               struct sockaddr_storage *bind_addr,
1423 +                               int low_port, int high_port)
1424  {
1425    int range_len, index;
1426    int *range, *ports;
1427 @@ -902,20 +932,30 @@
1428    return 0;
1429  }
1430  
1431 -int inet_connect(pool *pool, conn_t *c, p_in_addr_t *addr, int port)
1432 +int inet_connect(pool *pool, conn_t *c, struct sockaddr_storage *addr, int port)
1433  {
1434 -  struct sockaddr_in remaddr;
1435    int ret;
1436 +  struct sockaddr_storage remaddr;
1437  
1438    inet_setblock(pool,c);
1439 -  remaddr.sin_family = AF_INET;
1440 -  remaddr.sin_addr = *addr;
1441 -  remaddr.sin_port = htons(port);
1442 -
1443 +  memcpy(&remaddr, addr, sizeof(struct sockaddr_storage));
1444 +#ifdef INET6
1445 +  if (addr->__ss_family == AF_INET6)
1446 +    ((struct sockaddr_in6 *)&remaddr)->sin6_port = htons(port);
1447 +  else
1448 +#endif
1449 +    ((struct sockaddr_in *)&remaddr)->sin_port = htons(port);
1450 +  
1451    c->mode = CM_CONNECT;
1452  
1453 -  while( (ret = connect(c->listen_fd,(struct sockaddr*)&remaddr,sizeof(remaddr))) == -1 &&
1454 -         errno == EINTR ) ;
1455 +  while( (ret = connect(c->listen_fd,(struct sockaddr*)&remaddr,
1456 +#ifdef INET6
1457 +               (addr->__ss_family == AF_INET) ?
1458 +               sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)
1459 +#else
1460 +               sizeof(struct sockaddr_in)
1461 +#endif
1462 +         ) == -1) && errno == EINTR ) ;
1463  
1464    if(ret == -1) {
1465      c->mode = CM_ERROR;
1466 @@ -937,18 +977,28 @@
1467   * called once, and can then be selected for writing.
1468   */
1469  
1470 -int inet_connect_nowait(pool *pool, conn_t *c, p_in_addr_t *addr, int port)
1471 +int inet_connect_nowait(pool *pool, conn_t *c, struct sockaddr_storage *addr, int port)
1472  {
1473 -  struct sockaddr_in remaddr;
1474 +  struct sockaddr_storage remaddr;
1475  
1476    inet_setnonblock(pool,c);
1477 -
1478 -  remaddr.sin_family = AF_INET;
1479 -  remaddr.sin_addr = *addr;
1480 -  remaddr.sin_port = htons(port);
1481 +  memcpy(&remaddr, addr, sizeof(struct sockaddr_storage));
1482 +#ifdef INET6
1483 +  if (addr->__ss_family == AF_INET6)
1484 +    ((struct sockaddr_in6 *)&remaddr)->sin6_port = htons(port);
1485 +  else
1486 +#endif
1487 +    ((struct sockaddr_in *)&remaddr)->sin_port = htons(port);
1488  
1489    c->mode = CM_CONNECT;
1490 -  if(connect(c->listen_fd,(struct sockaddr*)&remaddr,sizeof(remaddr)) == -1) {
1491 +  if(connect(c->listen_fd,(struct sockaddr*)&remaddr,
1492 +#ifdef INET6
1493 +               (addr->__ss_family == AF_INET) ?
1494 +               sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)
1495 +#else
1496 +               sizeof(struct sockaddr_in)
1497 +#endif
1498 +           ) == -1) {
1499      if(errno != EINPROGRESS && errno != EALREADY) {
1500        c->mode = CM_ERROR;
1501        c->xerrno = errno;
1502 @@ -978,7 +1028,7 @@
1503  int inet_accept_nowait(pool *pool, conn_t *c)
1504  {
1505    int fd;
1506 -  struct sockaddr_in servaddr;
1507 +  struct sockaddr_storage servaddr;
1508    int len = sizeof(servaddr);
1509  
1510    if(c->mode == CM_LISTEN)
1511 @@ -1013,7 +1063,7 @@
1512                     int resolve) {
1513    conn_t *res = NULL;
1514    int newfd = -1, allow_foreign_addr = -1;
1515 -  struct sockaddr_in addr;
1516 +  struct sockaddr_storage addr;
1517    int addrlen = sizeof(addr);
1518    
1519    d->mode = CM_ACCEPT;
1520 @@ -1025,10 +1075,32 @@
1521                        &addrlen)) != -1) {
1522        if((allow_foreign_addr != 1) &&
1523          (getpeername(newfd, (struct sockaddr *) &addr, &addrlen) != -1)) {
1524 -       if(addr.sin_addr.s_addr != c->remote_ipaddr->s_addr) {
1525 +         mappedtov4(&addr);
1526 +#ifdef INET6
1527 +       if (addr.__ss_family == AF_INET6) {
1528 +         if (!IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)&addr)->sin6_addr,
1529 +                                 &((struct sockaddr_in6 *)c->remote_ipaddr)->sin6_addr)) {
1530 +           log_pri(LOG_NOTICE,
1531 +                 "SECURITY VIOLATION: Passive connection from %s rejected.",
1532 +                 INET_NTOA(&addr));
1533 +           close(newfd);
1534 +           continue;
1535 +         }
1536 +       } else
1537 +#endif
1538 +       if (addr.__ss_family == AF_INET) {
1539 +         if(((struct sockaddr_in *)&addr)->sin_addr.s_addr != 
1540 +               ((struct sockaddr_in *)c->remote_ipaddr)->sin_addr.s_addr) {
1541 +           log_pri(LOG_NOTICE,
1542 +                 "SECURITY VIOLATION: Passive connection from %s rejected.",
1543 +                 INET_NTOA(&addr));
1544 +           close(newfd);
1545 +           continue;
1546 +         }
1547 +       } else {
1548           log_pri(LOG_NOTICE,
1549                   "SECURITY VIOLATION: Passive connection from %s rejected.",
1550 -                 inet_ntoa(addr.sin_addr));
1551 +                 INET_NTOA(&addr));
1552           close(newfd);
1553           continue;
1554         }
1555 @@ -1047,7 +1119,7 @@
1556  }
1557  
1558  int inet_get_conn_info(conn_t *c, int fd) {
1559 -  static struct sockaddr_in servaddr;
1560 +  static struct sockaddr_storage servaddr;
1561    int len = sizeof(servaddr);
1562    
1563    /* Sanity check.
1564 @@ -1058,21 +1130,33 @@
1565    }
1566   
1567    if (getsockname(fd, (struct sockaddr *) &servaddr, &len) != -1) {
1568 +    mappedtov4(&servaddr);
1569      if (!c->local_ipaddr)
1570 -      c->local_ipaddr = (p_in_addr_t *) pcalloc(c->pool, sizeof(p_in_addr_t));     
1571 -    *c->local_ipaddr = servaddr.sin_addr;
1572 -    c->local_port = ntohs(servaddr.sin_port);
1573 -
1574 +      c->local_ipaddr = (struct sockaddr_storage*)pcalloc(c->pool,sizeof(struct sockaddr_storage));
1575 +    memcpy(c->local_ipaddr, &servaddr, sizeof(struct sockaddr_storage));
1576 +#ifdef INET6
1577 +    if (servaddr.__ss_family == AF_INET6)
1578 +      c->local_port = ntohs(((struct sockaddr_in6 *)&servaddr)->sin6_port);
1579 +    else
1580 +#endif
1581 +           if (servaddr.__ss_family == AF_INET)
1582 +      c->local_port = ntohs(((struct sockaddr_in *)&servaddr)->sin_port);
1583    } else
1584      return -1;
1585    
1586    len = sizeof(servaddr);
1587  
1588    if (getpeername(fd, (struct sockaddr *) &servaddr, &len) != -1) {
1589 -    c->remote_ipaddr = (p_in_addr_t *) pcalloc(c->pool, sizeof(p_in_addr_t));
1590 -    *c->remote_ipaddr = servaddr.sin_addr;
1591 -    c->remote_port = ntohs(servaddr.sin_port);
1592 -
1593 +    mappedtov4(&servaddr);
1594 +    c->remote_ipaddr = (struct sockaddr_storage*)pcalloc(c->pool,sizeof(struct sockaddr_storage));
1595 +    memcpy(c->remote_ipaddr, &servaddr, sizeof(struct sockaddr_storage));
1596 +#ifdef INET6
1597 +    if (servaddr.__ss_family == AF_INET6)
1598 +      c->remote_port = ntohs(((struct sockaddr_in6 *)&servaddr)->sin6_port);
1599 +    else
1600 +#endif
1601 +           if (servaddr.__ss_family == AF_INET)
1602 +      c->remote_port = ntohs(((struct sockaddr_in *)&servaddr)->sin_port);
1603    } else
1604      return -1;
1605  
1606 @@ -1086,7 +1170,7 @@
1607   * If resolve is non-zero, the remote address is reverse resolved.
1608   */
1609  
1610 -conn_t *inet_associate(pool *pool, conn_t *c, p_in_addr_t *addr, 
1611 +conn_t *inet_associate(pool *pool, conn_t *c, struct sockaddr_storage *addr, 
1612                         IOFILE *inf, IOFILE *outf, int resolve)
1613  {
1614    int rfd,wfd;
1615 @@ -1120,15 +1204,15 @@
1616  
1617    if(addr) {
1618      if(!res->remote_ipaddr)
1619 -      res->remote_ipaddr = (p_in_addr_t*)palloc(res->pool,sizeof(p_in_addr_t));
1620 -    *res->remote_ipaddr = *addr;
1621 +      res->remote_ipaddr = (struct sockaddr_storage*)palloc(res->pool,sizeof(struct sockaddr_storage));
1622 +    memcpy(res->remote_ipaddr, addr, sizeof(struct sockaddr_storage));
1623    }
1624  
1625    if(resolve && res->remote_ipaddr)
1626      res->remote_name = inet_getname(res->pool,res->remote_ipaddr);
1627  
1628    if(!res->remote_name)
1629 -    res->remote_name = pstrdup(res->pool,inet_ntoa(*res->remote_ipaddr));
1630 +    res->remote_name = pstrdup(res->pool,INET_NTOA(res->remote_ipaddr));
1631  
1632    inet_setoptions(res->pool,res,0,0);
1633    /* inet_setnonblock(res->pool,res); */
1634 @@ -1152,7 +1236,7 @@
1635   * Important, do not call any log_* functions from inside of inet_openrw()
1636   * or any functions it calls, as the possibility for fd overwriting occurs.
1637   */
1638 -conn_t *inet_openrw(pool *pool, conn_t *c, p_in_addr_t *addr, int fd,
1639 +conn_t *inet_openrw(pool *pool, conn_t *c, struct sockaddr_storage *addr, int fd,
1640                      int rfd,int wfd, int resolve)
1641  {
1642    conn_t *res = NULL;
1643 @@ -1172,15 +1256,15 @@
1644  
1645    if (addr) {
1646      if (!res->remote_ipaddr)
1647 -      res->remote_ipaddr = (p_in_addr_t*)palloc(res->pool,sizeof(p_in_addr_t));
1648 -    *res->remote_ipaddr = *addr;
1649 +      res->remote_ipaddr = (struct sockaddr_storage*)palloc(res->pool,sizeof(struct sockaddr_storage));
1650 +    memcpy(res->remote_ipaddr, addr, sizeof(struct sockaddr_storage));
1651    }
1652  
1653    if (resolve && res->remote_ipaddr)
1654      res->remote_name = inet_getname(res->pool,res->remote_ipaddr);
1655  
1656    if (!res->remote_name)
1657 -    res->remote_name = pstrdup(res->pool,inet_ntoa(*res->remote_ipaddr));
1658 +    res->remote_name = pstrdup(res->pool,INET_NTOA(res->remote_ipaddr));
1659  
1660    if (fd == -1 && c->listen_fd != -1)
1661      fd = c->listen_fd;
1662 @@ -1224,6 +1308,127 @@
1663    return res;
1664  }
1665  
1666 +int inet_address_match(struct sockaddr_storage *cp,
1667 +               struct sockaddr_storage *rp)
1668 +{
1669 +  struct sockaddr_in  *sin_cp, *sin_rp;
1670 +#ifdef INET6
1671 +  struct sockaddr_in6 *sin6_cp, *sin6_rp;
1672 +
1673 +  if (cp->__ss_family == AF_INET6 && rp->__ss_family == AF_INET) {
1674 +    sin6_cp = (struct sockaddr_in6 *)cp;
1675 +    sin_rp = (struct sockaddr_in *)rp;
1676 +    if (IN6_IS_ADDR_V4MAPPED(&sin6_cp->sin6_addr) &&
1677 +       memcmp(&sin6_cp->sin6_addr.s6_addr[12], &sin_rp->sin_addr.s_addr,
1678 +               sizeof(struct in_addr)) == 0)
1679 +      return 1;
1680 +    else
1681 +      return 0;
1682 +  } else if (cp->__ss_family == AF_INET && rp->__ss_family == AF_INET6) {
1683 +    sin_cp = (struct sockaddr_in *)cp;
1684 +    sin6_rp = (struct sockaddr_in6 *)rp;
1685 +    if (IN6_IS_ADDR_V4MAPPED(&sin6_rp->sin6_addr) &&
1686 +       memcmp(&sin6_rp->sin6_addr.s6_addr[12], &sin_cp->sin_addr.s_addr,
1687 +               sizeof(struct in_addr)) == 0)
1688 +      return 1;
1689 +    else
1690 +      return 0;
1691 +  }
1692 +#endif  /* INET6 */
1693 +  if (cp->__ss_family != rp->__ss_family)
1694 +    return 0;
1695 +  if (cp->__ss_family == AF_INET) {
1696 +    sin_cp = (struct sockaddr_in *)cp;
1697 +    sin_rp = (struct sockaddr_in *)rp;
1698 +    if (sin_cp->sin_addr.s_addr == sin_rp->sin_addr.s_addr)
1699 +      return 1;
1700 +    else
1701 +      return 0;
1702 +#ifdef INET6
1703 +  } else if (cp->__ss_family == AF_INET6) {
1704 +    sin6_cp = (struct sockaddr_in6 *)cp;
1705 +    sin6_rp = (struct sockaddr_in6 *)rp;
1706 +    if (IN6_ARE_ADDR_EQUAL(&sin6_cp->sin6_addr, &sin6_rp->sin6_addr))
1707 +      return 1;
1708 +    else
1709 +      return 0;
1710 +#endif  /* INET6 */
1711 +  }
1712 +  return 0;
1713 +}
1714 +
1715 +int inet_prefix_match(struct sockaddr_storage *cp,
1716 +               struct sockaddr_storage *rp, int prefix)
1717 +{
1718 +  u_int_32 netmask = 0;
1719 +  struct sockaddr_in  *sin_cp, *sin_rp;
1720 +  struct in_addr cp4, rp4;
1721 +#ifdef INET6
1722 +  struct sockaddr_in6 *sin6_cp, *sin6_rp;
1723 +  struct in6_addr cp6, rp6;
1724 +
1725 +  if (cp->__ss_family == AF_INET6 && rp->__ss_family == AF_INET) {
1726 +    sin6_cp = (struct sockaddr_in6 *)cp;
1727 +    sin_rp = (struct sockaddr_in *)rp;
1728 +    if (IN6_IS_ADDR_V4MAPPED(&sin6_cp->sin6_addr)) {
1729 +      if (prefix > 32) prefix = 32;
1730 +      while (prefix--) { netmask >>= 1; netmask |= 0x80000000; }
1731 +      cp4.s_addr = ntohl(sin6_cp->sin6_addr.s6_addr32[3]) & netmask;
1732 +      rp4.s_addr = ntohl(sin_rp->sin_addr.s_addr) & netmask;
1733 +      if (cp4.s_addr == rp4.s_addr)
1734 +        return 1;
1735 +      else
1736 +        return 0;
1737 +    } else
1738 +      return 0;
1739 +  } else if (cp->__ss_family == AF_INET && rp->__ss_family == AF_INET6) {
1740 +    sin_cp = (struct sockaddr_in *)cp;
1741 +    sin6_rp = (struct sockaddr_in6 *)rp;
1742 +    if (IN6_IS_ADDR_V4MAPPED(&sin6_rp->sin6_addr)) {
1743 +      if (prefix > 32) prefix = 32;
1744 +      while (prefix--) { netmask >>= 1; netmask |= 0x80000000; }
1745 +      cp4.s_addr = ntohl(sin_cp->sin_addr.s_addr) & netmask;
1746 +      rp4.s_addr = ntohl(sin6_rp->sin6_addr.s6_addr32[3]) & netmask;
1747 +      if (cp4.s_addr == rp4.s_addr)
1748 +        return 1;
1749 +      else
1750 +        return 0;
1751 +    } else
1752 +      return 0;
1753 +  }
1754 +#endif  /* INET6 */
1755 +  if (cp->__ss_family != rp->__ss_family)
1756 +    return 0;
1757 +  if (cp->__ss_family == AF_INET) {
1758 +    if (prefix > 32) prefix = 32;
1759 +    while (prefix--) { netmask >>= 1; netmask |= 0x80000000; }
1760 +    cp4.s_addr = ntohl(((struct sockaddr_in *)cp)->sin_addr.s_addr) & netmask;
1761 +    rp4.s_addr = ntohl(((struct sockaddr_in *)rp)->sin_addr.s_addr) & netmask;
1762 +    if (cp4.s_addr == rp4.s_addr)
1763 +      return 1;
1764 +    else
1765 +      return 0;
1766 +#ifdef INET6
1767 +  } else if (cp->__ss_family == AF_INET6) {
1768 +    int i,j;
1769 +
1770 +    memcpy(&cp6, &((struct sockaddr_in6 *)cp)->sin6_addr, sizeof(struct in6_addr));
1771 +    memcpy(&rp6, &((struct sockaddr_in6 *)rp)->sin6_addr, sizeof(struct in6_addr));
1772 +    for (i=0; i<4; i++) {
1773 +      j=0; netmask=0;
1774 +      while (prefix && j++<32) { prefix--; netmask >>= 1; netmask |= 0x80000000; }
1775 +      cp6.s6_addr32[i] &= htonl(netmask);
1776 +      rp6.s6_addr32[i] &= htonl(netmask);
1777 +    }
1778 +    if (IN6_ARE_ADDR_EQUAL(&cp6, &rp6))
1779 +      return 1;
1780 +    else
1781 +      return 0;
1782 +#endif  /* INET6 */
1783 +  }
1784 +  return 0;
1785 +}
1786 +
1787  /* Perform reverse ip dns resolution on an existing
1788   * connection.
1789   */
1790 @@ -1234,7 +1439,7 @@
1791      c->remote_name = inet_getname(c->pool,c->remote_ipaddr);
1792  
1793      if(!c->remote_name)
1794 -      c->remote_name = pstrdup(c->pool,inet_ntoa(*c->remote_ipaddr));
1795 +      c->remote_name = pstrdup(c->pool,INET_NTOA(c->remote_ipaddr));
1796  
1797    }
1798  }
1799 diff -urN proftpd-1.2.5/src/intoa.c proftpd-1.2.5.v6/src/intoa.c
1800 --- proftpd-1.2.5/src/intoa.c   Thu Jan  1 01:00:00 1970
1801 +++ proftpd-1.2.5.v6/src/intoa.c        Thu Aug  8 21:35:24 2002
1802 @@ -0,0 +1,40 @@
1803 +/*
1804 + * ProFTPD - FTP server daemon
1805 + * Copyright (c) 1997, 1998 Public Flood Software
1806 + * Copyright (C) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver@tos.net>
1807 + *  
1808 + * This program is free software; you can redistribute it and/or modify
1809 + * it under the terms of the GNU General Public License as published by
1810 + * the Free Software Foundation; either version 2 of the License, or
1811 + * (at your option) any later version.
1812 + *
1813 + * This program is distributed in the hope that it will be useful,
1814 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1815 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1816 + * GNU General Public License for more details.
1817 + *
1818 + * You should have received a copy of the GNU General Public License
1819 + * along with this program; if not, write to the Free Software
1820 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
1821 + */
1822 +
1823 +/*
1824 + * Inet support functions, many wrappers for netdb functions
1825 + */
1826 +
1827 +
1828 +#include "conf.h"
1829 +#include "privs.h"
1830 +
1831 +#ifdef INET6
1832 +char *INET_NTOA(struct sockaddr_storage *ss)
1833 +{
1834 +  static char buf[1024];
1835 +
1836 +  if (getnameinfo((struct sockaddr *)ss, sizeof(struct sockaddr_storage),
1837 +                 buf, sizeof(buf), NULL, 0, NI_NUMERICHOST))
1838 +      strcpy(buf, "0.0.0.0");
1839 +
1840 +  return buf;
1841 +}
1842 +#endif
1843 diff -urN proftpd-1.2.5/src/log.c proftpd-1.2.5.v6/src/log.c
1844 --- proftpd-1.2.5/src/log.c     Tue May 21 22:47:22 2002
1845 +++ proftpd-1.2.5.v6/src/log.c  Thu Aug  8 21:35:24 2002
1846 @@ -434,12 +434,12 @@
1847    return NULL;
1848  }
1849  
1850 -void log_run_address(const char *remote_name, const p_in_addr_t *remote_ipaddr)
1851 +void log_run_address(const char *remote_name, const struct sockaddr_storage *remote_ipaddr)
1852  {
1853    char buf[LOGBUFFER_SIZE] = {'\0'};
1854  
1855    snprintf(buf, sizeof(buf), "%s [%s]",
1856 -          remote_name, inet_ntoa(*remote_ipaddr));
1857 +          remote_name, INET_NTOA((struct sockaddr_storage *)remote_ipaddr));
1858    buf[sizeof(buf) - 1] = '\0';
1859    address = pstrdup(permanent_pool,buf);
1860  }
1861 @@ -459,7 +459,7 @@
1862   */
1863  
1864  int log_add_run(pid_t mpid, time_t *idle_since, char *user,char *class,
1865 -                p_in_addr_t *server_ip, unsigned short server_port, 
1866 +                struct sockaddr_storage *server_ip, unsigned short server_port, 
1867                  unsigned long tx_size, unsigned long tx_done, char *op, ...)
1868  {
1869    logrun_t ent,fent;
1870 @@ -590,7 +590,7 @@
1871   * but I haven't been able to test them.
1872   */
1873  
1874 -int log_wtmp(char *line, char *name, char *host, p_in_addr_t *ip)
1875 +int log_wtmp(char *line, char *name, char *host, struct sockaddr_storage *ip)
1876  {
1877    struct stat buf;
1878    struct utmp ut;
1879 @@ -657,8 +657,14 @@
1880      memset(&ut,0,sizeof(ut));
1881  #ifdef HAVE_UTMAXTYPE
1882  #ifdef LINUX
1883 -    if(ip)
1884 -      memcpy(&ut.ut_addr,ip,sizeof(ut.ut_addr));
1885 +    if(ip) {
1886 +#ifdef INET6
1887 +      if (ip->__ss_family == AF_INET6)
1888 +       memcpy(&ut.ut_addr_v6,&((struct sockaddr_in6 *)ip)->sin6_addr,sizeof(ut.ut_addr_v6));
1889 +      else
1890 +#endif
1891 +       memcpy(&ut.ut_addr,&((struct sockaddr_in *)ip)->sin_addr,sizeof(ut.ut_addr));
1892 +    }
1893  #else
1894      sstrncpy(ut.ut_id,"ftp",sizeof(ut.ut_id));
1895      ut.ut_exit.e_termination = 0;
1896 @@ -835,7 +841,7 @@
1897      if(session.c && session.c->remote_name) {
1898        snprintf(serverinfo + strlen(serverinfo),
1899                sizeof(serverinfo) - strlen(serverinfo), " (%s[%s])",
1900 -              session.c->remote_name, inet_ntoa(*session.c->remote_ipaddr));
1901 +              session.c->remote_name, INET_NTOA(session.c->remote_ipaddr));
1902        serverinfo[sizeof(serverinfo) - 1] = '\0';
1903      }
1904    }
1905 diff -urN proftpd-1.2.5/src/main.c proftpd-1.2.5.v6/src/main.c
1906 --- proftpd-1.2.5/src/main.c    Tue May 21 22:47:23 2002
1907 +++ proftpd-1.2.5.v6/src/main.c Thu Aug  8 21:35:24 2002
1908 @@ -108,7 +108,7 @@
1909    struct _binding *next;
1910  
1911    server_rec *server;                  /* server to handle request */
1912 -  p_in_addr_t ipaddr;                  /* ip address "bound" to */
1913 +  struct sockaddr_storage ipaddr;      /* ip address "bound" to */
1914    int        port;
1915    conn_t     *listen;                  /* listen connection (if separate) */
1916    char       isdefault;                        /* if default connection */
1917 @@ -158,17 +158,17 @@
1918  
1919  char *config_filename = CONFIG_FILE_PATH;
1920  
1921 -int add_binding(server_rec *server, p_in_addr_t *ipaddr, conn_t *listen,
1922 +int add_binding(server_rec *server, struct sockaddr_storage *ipaddr, conn_t *listen,
1923                  char isdefault, char islocalhost)
1924  {
1925    binding_t *b;
1926  
1927    for(b = bind_list; b; b=b->next)
1928 -    if(b->ipaddr.s_addr == ipaddr->s_addr &&
1929 +    if(inet_address_match(&b->ipaddr, ipaddr) &&
1930         b->port == server->ServerPort) {
1931        /* binding already exists for this IP */
1932        log_pri(LOG_NOTICE,"cannot bind %s:%d to server '%s', already bound to '%s'.",
1933 -              inet_ntoa(*ipaddr),server->ServerPort,
1934 +              INET_NTOA(ipaddr),server->ServerPort,
1935                server->ServerName,b->server->ServerName);
1936        return -1;
1937      }
1938 @@ -179,7 +179,7 @@
1939    b = palloc(bind_pool,sizeof(binding_t));
1940    b->server = server;
1941    b->port = server->ServerPort;
1942 -  b->ipaddr = *ipaddr;
1943 +  memcpy(&b->ipaddr, ipaddr, sizeof(struct sockaddr_storage));
1944    b->listen = listen;
1945    b->isdefault = isdefault;
1946    b->islocalhost = islocalhost;
1947 @@ -190,12 +190,12 @@
1948    return 0;
1949  }
1950  
1951 -server_rec *find_binding(p_in_addr_t *ipaddr, int port)
1952 +server_rec *find_binding(struct sockaddr_storage *ipaddr, int port)
1953  {
1954    binding_t *b,*local_b = NULL,*default_b = NULL;
1955  
1956    for(b = bind_list; b; b=b->next) {
1957 -    if(b->ipaddr.s_addr == ipaddr->s_addr && (!b->port || b->port == port))
1958 +    if(inet_address_match(&b->ipaddr, ipaddr) && (!b->port || b->port == port))
1959        return b->server;
1960  
1961      if(b->islocalhost)
1962 @@ -206,20 +206,20 @@
1963  
1964    /* Not found in binding list, so see if it's the loopback address */
1965    if(local_b) {
1966 -    p_in_addr_t loopback,loopmask,tmp;
1967 -
1968 -#ifdef HAVE_INET_ATON
1969 -    inet_aton(LOOPBACK_NET,&loopback);
1970 -    inet_aton(LOOPBACK_MASK,&loopmask);
1971 -#else
1972 -    loopback.s_addr = inet_addr(LOOPBACK_NET);
1973 -    loopmask.s_addr = inet_addr(LOOPBACK_MASK);
1974 +    struct sockaddr_storage loopback;
1975 +    struct sockaddr_in *loopback4 = (struct sockaddr_in *)&loopback;
1976 +#ifdef INET6
1977 +    struct sockaddr_in6 *loopback6 = (struct sockaddr_in6 *)&loopback;
1978 +
1979 +    loopback.__ss_family = AF_INET6;
1980 +    memcpy(&loopback6->sin6_addr, &in6addr_loopback, sizeof(struct in6_addr));
1981 +    if(inet_address_match(ipaddr, (struct sockaddr_storage *)&loopback) &&
1982 +       (!local_b->port || port == local_b->port))
1983 +      return local_b->server;
1984  #endif
1985 -    loopback.s_addr = ntohl(loopback.s_addr);
1986 -    loopmask.s_addr = ntohl(loopmask.s_addr);
1987 -    tmp.s_addr = ntohl(ipaddr->s_addr);
1988 -
1989 -    if((tmp.s_addr & loopmask.s_addr) == loopback.s_addr &&
1990 +    loopback.__ss_family = AF_INET;
1991 +    loopback4->sin_addr.s_addr = INADDR_LOOPBACK;
1992 +    if(inet_address_match(ipaddr, (struct sockaddr_storage *)&loopback) &&
1993         (!local_b->port || port == local_b->port))
1994        return local_b->server;
1995    }
1996 @@ -664,8 +664,8 @@
1997      if ((c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress",
1998          FALSE)) != NULL) {
1999  
2000 -      p_in_addr_t *masq_addr = (p_in_addr_t *) c->argv[0];
2001 -      serveraddress = pstrdup(main_server->pool, inet_ntoa(*masq_addr));
2002 +      struct sockaddr_storage *masq_addr = (struct sockaddr_storage *) c->argv[0];
2003 +      serveraddress = pstrdup(main_server->pool, INET_NTOA(masq_addr));
2004      }
2005  
2006      time(&now);
2007 @@ -962,7 +962,7 @@
2008  
2009    set_proc_title("proftpd: connected: %s (%s:%d)",
2010                 c->remote_name ? c->remote_name : "?",
2011 -               c->remote_ipaddr ? inet_ntoa(*c->remote_ipaddr) : "?",
2012 +               c->remote_ipaddr ? INET_NTOA(c->remote_ipaddr) : "?",
2013                 c->remote_port ? c->remote_port : 0
2014                 );
2015  
2016 @@ -972,8 +972,8 @@
2017  
2018    if ((masq_c = find_config(server->conf, CONF_PARAM, "MasqueradeAddress",
2019        FALSE)) != NULL) {
2020 -    p_in_addr_t *masq_addr = (p_in_addr_t *) masq_c->argv[0];
2021 -    serveraddress = pstrdup(server->pool, inet_ntoa(*masq_addr));
2022 +    struct sockaddr_storage *masq_addr = (struct sockaddr_storage *) masq_c->argv[0];
2023 +    serveraddress = pstrdup(server->pool, INET_NTOA(masq_addr));
2024    }
2025  
2026    display = (char*)get_param_ptr(server->conf,"DisplayConnect",FALSE);
2027 @@ -1482,8 +1482,8 @@
2028        if ((c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress",
2029          FALSE)) != NULL) {
2030  
2031 -        p_in_addr_t *masq_addr = (p_in_addr_t *) c->argv[0];
2032 -        serveraddress = pstrdup(main_server->pool, inet_ntoa(*masq_addr));
2033 +        struct sockaddr_storage *masq_addr = (struct sockaddr_storage *) c->argv[0];
2034 +        serveraddress = pstrdup(main_server->pool, INET_NTOA(masq_addr));
2035        }
2036  
2037        reason = sreplace(permanent_pool,shutmsg,
2038 @@ -1501,7 +1501,7 @@
2039  
2040        log_auth(LOG_NOTICE, "connection refused (%s) from %s [%s]",
2041                 reason, session.c->remote_name,
2042 -               inet_ntoa(*session.c->remote_ipaddr));
2043 +               INET_NTOA(session.c->remote_ipaddr));
2044  
2045        send_response(R_500, 
2046                     "FTP server shut down (%s) -- please try again later.",
2047 @@ -1532,7 +1532,7 @@
2048    /* Check config tree for <Limit LOGIN> directives */
2049    if(!login_check_limits(serv->conf,TRUE,FALSE,&i)) {
2050      log_pri(LOG_NOTICE,"Connection from %s [%s] denied.",
2051 -            session.c->remote_name,inet_ntoa(*session.c->remote_ipaddr));
2052 +            session.c->remote_name,INET_NTOA(session.c->remote_ipaddr));
2053      exit(0);
2054    }
2055  
2056 @@ -1563,10 +1563,10 @@
2057    init_child_modules();
2058  
2059    log_debug(DEBUG4,"connected - local  : %s:%d",
2060 -                    inet_ntoa(*session.c->local_ipaddr),
2061 +                    INET_NTOA(session.c->local_ipaddr),
2062                      session.c->local_port);
2063    log_debug(DEBUG4,"connected - remote : %s:%d",
2064 -                    inet_ntoa(*session.c->remote_ipaddr),
2065 +                   INET_NTOA(session.c->remote_ipaddr),
2066                      session.c->remote_port);
2067  
2068    /* xfer_set_data_port(conn->local_ipaddr,conn->local_port-1); */
2069 @@ -2172,7 +2172,7 @@
2070  {
2071    config_rec *c;
2072    conn_t *listen;
2073 -  p_in_addr_t *ipaddr;
2074 +  struct sockaddr_storage *ipaddr;
2075  
2076    c = find_config(s->conf,CONF_PARAM,"Bind",FALSE);
2077    while(c) {
2078 diff -urN proftpd-1.2.5/src/support.c proftpd-1.2.5.v6/src/support.c
2079 --- proftpd-1.2.5/src/support.c Tue May 21 22:47:23 2002
2080 +++ proftpd-1.2.5.v6/src/support.c      Thu Aug  8 21:35:24 2002
2081 @@ -902,3 +902,22 @@
2082    
2083    return dest;
2084  }
2085 +
2086 +/* convert IPv4-mapped to real IPv4 struct */
2087 +void mappedtov4( struct sockaddr_storage *ss )
2088 +{
2089 +    struct sockaddr_in sin;
2090 +    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ss;
2091 +    if (ss->__ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ) {
2092 +       memcpy(&sin.sin_addr, sin6->sin6_addr.s6_addr+12,
2093 +               sizeof(sin.sin_addr));
2094 +       sin.sin_port = ((struct sockaddr_in6 *)ss)->sin6_port;
2095 +       sin.sin_family = AF_INET;
2096 +#ifdef SIN6_LEN
2097 +       sin.sin_len = sizeof(struct sockaddr_in);
2098 +#endif
2099 +       memset(ss, 0, sizeof(struct sockaddr_storage));
2100 +       memcpy(ss, &sin, sizeof(sin));
2101 +    }
2102 +}
2103 +
This page took 0.24691 seconds and 3 git commands to generate.