FreeBSD kernel IPv4 code
alias_ftp.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2001 Charles Mott <cm@linktel.net>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD$");
31
32/*
33 Alias_ftp.c performs special processing for FTP sessions under
34 TCP. Specifically, when a PORT/EPRT command from the client
35 side or 227/229 reply from the server is sent, it is intercepted
36 and modified. The address is changed to the gateway machine
37 and an aliasing port is used.
38
39 For this routine to work, the message must fit entirely into a
40 single TCP packet. This is typically the case, but exceptions
41 can easily be envisioned under the actual specifications.
42
43 Probably the most troubling aspect of the approach taken here is
44 that the new message will typically be a different length, and
45 this causes a certain amount of bookkeeping to keep track of the
46 changes of sequence and acknowledgment numbers, since the client
47 machine is totally unaware of the modification to the TCP stream.
48
49 References: RFC 959, RFC 2428.
50
51 Initial version: August, 1996 (cjm)
52
53 Version 1.6
54 Brian Somers and Martin Renters identified an IP checksum
55 error for modified IP packets.
56
57 Version 1.7: January 9, 1996 (cjm)
58 Differential checksum computation for change
59 in IP packet length.
60
61 Version 2.1: May, 1997 (cjm)
62 Very minor changes to conform with
63 local/global/function naming conventions
64 within the packet aliasing module.
65
66 Version 3.1: May, 2000 (eds)
67 Add support for passive mode, alias the 227 replies.
68
69 See HISTORY file for record of revisions.
70*/
71
72/* Includes */
73#ifdef _KERNEL
74#include <sys/param.h>
75#include <sys/ctype.h>
76#include <sys/systm.h>
77#include <sys/kernel.h>
78#include <sys/module.h>
79#else
80#include <ctype.h>
81#include <errno.h>
82#include <sys/types.h>
83#include <stdio.h>
84#include <string.h>
85#endif
86
87#include <netinet/in_systm.h>
88#include <netinet/in.h>
89#include <netinet/ip.h>
90#include <netinet/tcp.h>
91
92#ifdef _KERNEL
96#else
97#include "alias_local.h"
98#include "alias_mod.h"
99#endif
100
101#define FTP_CONTROL_PORT_NUMBER 21
102
103static void
104AliasHandleFtpOut(struct libalias *, struct ip *, struct alias_link *,
105 int maxpacketsize);
106static void
107AliasHandleFtpIn(struct libalias *, struct ip *, struct alias_link *);
108
109static int
110fingerprint_out(struct libalias *la, struct alias_data *ah)
111{
112 if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
113 ah->maxpktsize == 0)
114 return (-1);
115 if (ntohs(*ah->dport) == FTP_CONTROL_PORT_NUMBER ||
116 ntohs(*ah->sport) == FTP_CONTROL_PORT_NUMBER)
117 return (0);
118 return (-1);
119}
120
121static int
122fingerprint_in(struct libalias *la, struct alias_data *ah)
123{
124 if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL)
125 return (-1);
126 if (ntohs(*ah->dport) == FTP_CONTROL_PORT_NUMBER ||
127 ntohs(*ah->sport) == FTP_CONTROL_PORT_NUMBER)
128 return (0);
129 return (-1);
130}
131
132static int
133protohandler_out(struct libalias *la, struct ip *pip, struct alias_data *ah)
134{
135 AliasHandleFtpOut(la, pip, ah->lnk, ah->maxpktsize);
136 return (0);
137}
138
139static int
140protohandler_in(struct libalias *la, struct ip *pip, struct alias_data *ah)
141{
142 AliasHandleFtpIn(la, pip, ah->lnk);
143 return (0);
144}
145
147 {
148 .pri = 80,
149 .dir = OUT,
150 .proto = TCP,
151 .fingerprint = &fingerprint_out,
152 .protohandler = &protohandler_out
153 },
154 {
155 .pri = 80,
156 .dir = IN,
157 .proto = TCP,
158 .fingerprint = &fingerprint_in,
159 .protohandler = &protohandler_in
160 },
161 { EOH }
162};
163
164static int
165mod_handler(module_t mod, int type, void *data)
166{
167 int error;
168
169 switch (type) {
170 case MOD_LOAD:
171 error = 0;
173 break;
174 case MOD_UNLOAD:
175 error = 0;
177 break;
178 default:
179 error = EINVAL;
180 }
181 return (error);
182}
183
184#ifdef _KERNEL
185static
186#endif
187moduledata_t alias_mod = {
188 "alias_ftp", mod_handler, NULL
189};
190
191#ifdef _KERNEL
192DECLARE_MODULE(alias_ftp, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
193MODULE_VERSION(alias_ftp, 1);
194MODULE_DEPEND(alias_ftp, libalias, 1, 1, 1);
195#endif
196
197#define FTP_CONTROL_PORT_NUMBER 21
198#define MAX_MESSAGE_SIZE 128
199
200/* FTP protocol flags. */
201#define WAIT_CRLF 0x01
202
210
211static int ParseFtpPortCommand(struct libalias *la, char *, int);
212static int ParseFtpEprtCommand(struct libalias *la, char *, int);
213static int ParseFtp227Reply(struct libalias *la, char *, int);
214static int ParseFtp229Reply(struct libalias *la, char *, int);
215static void NewFtpMessage(struct libalias *la, struct ip *, struct alias_link *, int, int);
216
217static void
219 struct libalias *la,
220 struct ip *pip, /* IP packet to examine/patch */
221 struct alias_link *lnk, /* The link to go through (aliased port) */
222 int maxpacketsize /* The maximum size this packet can grow to
223 (including headers) */ )
224{
225 int hlen, tlen, dlen, pflags;
226 char *sptr;
227 struct tcphdr *tc;
229
230 /* Calculate data length of TCP packet */
231 tc = (struct tcphdr *)ip_next(pip);
232 hlen = (pip->ip_hl + tc->th_off) << 2;
233 tlen = ntohs(pip->ip_len);
234 dlen = tlen - hlen;
235
236 /* Place string pointer and beginning of data */
237 sptr = (char *)pip;
238 sptr += hlen;
239
240 /*
241 * Check that data length is not too long and previous message was
242 * properly terminated with CRLF.
243 */
244 pflags = GetProtocolFlags(lnk);
245 if (dlen <= MAX_MESSAGE_SIZE && !(pflags & WAIT_CRLF)) {
247
248 if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER) {
249 /* When aliasing a client, check for the PORT/EPRT command. */
250 if (ParseFtpPortCommand(la, sptr, dlen))
252 else if (ParseFtpEprtCommand(la, sptr, dlen))
254 } else {
255 /* When aliasing a server, check for the 227/229 reply. */
256 if (ParseFtp227Reply(la, sptr, dlen))
258 else if (ParseFtp229Reply(la, sptr, dlen)) {
260 la->true_addr.s_addr = pip->ip_src.s_addr;
261 }
262 }
263
265 NewFtpMessage(la, pip, lnk, maxpacketsize, ftp_message_type);
266 }
267
268 /* Track the msgs which are CRLF term'd for PORT/PASV FW breach */
269 if (dlen) { /* only if there's data */
270 sptr = (char *)pip; /* start over at beginning */
271 tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may have grown */
272 if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n')
273 pflags &= ~WAIT_CRLF;
274 else
275 pflags |= WAIT_CRLF;
276 SetProtocolFlags(lnk, pflags);
277 }
278}
279
280static void
282 struct ip *pip, /* IP packet to examine/patch */
283 struct alias_link *lnk) /* The link to go through (aliased port) */
284{
285 int hlen, tlen, dlen, pflags;
286 char *sptr;
287 struct tcphdr *tc;
288
289 /* Calculate data length of TCP packet */
290 tc = (struct tcphdr *)ip_next(pip);
291 hlen = (pip->ip_hl + tc->th_off) << 2;
292 tlen = ntohs(pip->ip_len);
293 dlen = tlen - hlen;
294
295 /* Place string pointer and beginning of data */
296 sptr = (char *)pip;
297 sptr += hlen;
298
299 /*
300 * Check that data length is not too long and previous message was
301 * properly terminated with CRLF.
302 */
303 pflags = GetProtocolFlags(lnk);
304 if (dlen <= MAX_MESSAGE_SIZE && (pflags & WAIT_CRLF) == 0 &&
305 ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER &&
306 (ParseFtpPortCommand(la, sptr, dlen) != 0 ||
307 ParseFtpEprtCommand(la, sptr, dlen) != 0)) {
308 /*
309 * Alias active mode client requesting data from server
310 * behind NAT. We need to alias server->client connection
311 * to external address client is connecting to.
312 */
316 }
317 /* Track the msgs which are CRLF term'd for PORT/PASV FW breach */
318 if (dlen) {
319 sptr = (char *)pip; /* start over at beginning */
320 tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may
321 * have grown. */
322 if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n')
323 pflags &= ~WAIT_CRLF;
324 else
325 pflags |= WAIT_CRLF;
326 SetProtocolFlags(lnk, pflags);
327 }
328}
329
330static int
331ParseFtpPortCommand(struct libalias *la, char *sptr, int dlen)
332{
333 char ch;
334 int i, state;
335 u_int32_t addr;
336 u_short port;
337 u_int8_t octet;
338
339 /* Format: "PORT A,D,D,R,PO,RT". */
340
341 /* Return if data length is too short. */
342 if (dlen < 18)
343 return (0);
344
345 if (strncasecmp("PORT ", sptr, 5))
346 return (0);
347
348 addr = port = octet = 0;
349 state = 0;
350 for (i = 5; i < dlen; i++) {
351 ch = sptr[i];
352 switch (state) {
353 case 0:
354 if (isspace(ch))
355 break;
356 else
357 state++;
358 case 1:
359 case 3:
360 case 5:
361 case 7:
362 case 9:
363 case 11:
364 if (isdigit(ch)) {
365 octet = ch - '0';
366 state++;
367 } else
368 return (0);
369 break;
370 case 2:
371 case 4:
372 case 6:
373 case 8:
374 if (isdigit(ch))
375 octet = 10 * octet + ch - '0';
376 else if (ch == ',') {
377 addr = (addr << 8) + octet;
378 state++;
379 } else
380 return (0);
381 break;
382 case 10:
383 case 12:
384 if (isdigit(ch))
385 octet = 10 * octet + ch - '0';
386 else if (ch == ',' || state == 12) {
387 port = (port << 8) + octet;
388 state++;
389 } else
390 return (0);
391 break;
392 }
393 }
394
395 if (state == 13) {
396 la->true_addr.s_addr = htonl(addr);
397 la->true_port = port;
398 return (1);
399 } else
400 return (0);
401}
402
403static int
404ParseFtpEprtCommand(struct libalias *la, char *sptr, int dlen)
405{
406 char ch, delim;
407 int i, state;
408 u_int32_t addr;
409 u_short port;
410 u_int8_t octet;
411
412 /* Format: "EPRT |1|A.D.D.R|PORT|". */
413
414 /* Return if data length is too short. */
415 if (dlen < 18)
416 return (0);
417
418 if (strncasecmp("EPRT ", sptr, 5))
419 return (0);
420
421 addr = port = octet = 0;
422 delim = '|'; /* XXX gcc -Wuninitialized */
423 state = 0;
424 for (i = 5; i < dlen; i++) {
425 ch = sptr[i];
426 switch (state) {
427 case 0:
428 if (!isspace(ch)) {
429 delim = ch;
430 state++;
431 }
432 break;
433 case 1:
434 if (ch == '1') /* IPv4 address */
435 state++;
436 else
437 return (0);
438 break;
439 case 2:
440 if (ch == delim)
441 state++;
442 else
443 return (0);
444 break;
445 case 3:
446 case 5:
447 case 7:
448 case 9:
449 if (isdigit(ch)) {
450 octet = ch - '0';
451 state++;
452 } else
453 return (0);
454 break;
455 case 4:
456 case 6:
457 case 8:
458 case 10:
459 if (isdigit(ch))
460 octet = 10 * octet + ch - '0';
461 else if (ch == '.' || state == 10) {
462 addr = (addr << 8) + octet;
463 state++;
464 } else
465 return (0);
466 break;
467 case 11:
468 if (isdigit(ch)) {
469 port = ch - '0';
470 state++;
471 } else
472 return (0);
473 break;
474 case 12:
475 if (isdigit(ch))
476 port = 10 * port + ch - '0';
477 else if (ch == delim)
478 state++;
479 else
480 return (0);
481 break;
482 }
483 }
484
485 if (state == 13) {
486 la->true_addr.s_addr = htonl(addr);
487 la->true_port = port;
488 return (1);
489 } else
490 return (0);
491}
492
493static int
494ParseFtp227Reply(struct libalias *la, char *sptr, int dlen)
495{
496 char ch;
497 int i, state;
498 u_int32_t addr;
499 u_short port;
500 u_int8_t octet;
501
502 /* Format: "227 Entering Passive Mode (A,D,D,R,PO,RT)" */
503
504 /* Return if data length is too short. */
505 if (dlen < 17)
506 return (0);
507
508 if (strncmp("227 ", sptr, 4))
509 return (0);
510
511 addr = port = octet = 0;
512
513 state = 0;
514 for (i = 4; i < dlen; i++) {
515 ch = sptr[i];
516 switch (state) {
517 case 0:
518 if (ch == '(')
519 state++;
520 break;
521 case 1:
522 case 3:
523 case 5:
524 case 7:
525 case 9:
526 case 11:
527 if (isdigit(ch)) {
528 octet = ch - '0';
529 state++;
530 } else
531 return (0);
532 break;
533 case 2:
534 case 4:
535 case 6:
536 case 8:
537 if (isdigit(ch))
538 octet = 10 * octet + ch - '0';
539 else if (ch == ',') {
540 addr = (addr << 8) + octet;
541 state++;
542 } else
543 return (0);
544 break;
545 case 10:
546 case 12:
547 if (isdigit(ch))
548 octet = 10 * octet + ch - '0';
549 else if (ch == ',' || (state == 12 && ch == ')')) {
550 port = (port << 8) + octet;
551 state++;
552 } else
553 return (0);
554 break;
555 }
556 }
557
558 if (state == 13) {
559 la->true_port = port;
560 la->true_addr.s_addr = htonl(addr);
561 return (1);
562 } else
563 return (0);
564}
565
566static int
567ParseFtp229Reply(struct libalias *la, char *sptr, int dlen)
568{
569 char ch, delim;
570 int i, state;
571 u_short port;
572
573 /* Format: "229 Entering Extended Passive Mode (|||PORT|)" */
574
575 /* Return if data length is too short. */
576 if (dlen < 11)
577 return (0);
578
579 if (strncmp("229 ", sptr, 4))
580 return (0);
581
582 port = 0;
583 delim = '|'; /* XXX gcc -Wuninitialized */
584
585 state = 0;
586 for (i = 4; i < dlen; i++) {
587 ch = sptr[i];
588 switch (state) {
589 case 0:
590 if (ch == '(')
591 state++;
592 break;
593 case 1:
594 delim = ch;
595 state++;
596 break;
597 case 2:
598 case 3:
599 if (ch == delim)
600 state++;
601 else
602 return (0);
603 break;
604 case 4:
605 if (isdigit(ch)) {
606 port = ch - '0';
607 state++;
608 } else
609 return (0);
610 break;
611 case 5:
612 if (isdigit(ch))
613 port = 10 * port + ch - '0';
614 else if (ch == delim)
615 state++;
616 else
617 return (0);
618 break;
619 case 6:
620 if (ch == ')')
621 state++;
622 else
623 return (0);
624 break;
625 }
626 }
627
628 if (state == 7) {
629 la->true_port = port;
630 return (1);
631 } else
632 return (0);
633}
634
635static void
636NewFtpMessage(struct libalias *la, struct ip *pip,
637 struct alias_link *lnk,
638 int maxpacketsize,
640{
641 struct alias_link *ftp_lnk;
642
643 /* Security checks. */
644 if (pip->ip_src.s_addr != la->true_addr.s_addr)
645 return;
646
647 if (la->true_port < IPPORT_RESERVED)
648 return;
649
650 /* Establish link to address and port found in FTP control message. */
651 ftp_lnk = AddLink(la, la->true_addr, GetDestAddress(lnk),
652 GetAliasAddress(lnk), htons(la->true_port), 0, GET_ALIAS_PORT,
654
655 if (ftp_lnk != NULL) {
656 int slen, hlen, tlen, dlen;
657 struct tcphdr *tc;
658
659#ifndef NO_FW_PUNCH
660 /* Punch hole in firewall */
661 PunchFWHole(ftp_lnk);
662#endif
663
664 /* Calculate data length of TCP packet */
665 tc = (struct tcphdr *)ip_next(pip);
666 hlen = (pip->ip_hl + tc->th_off) << 2;
667 tlen = ntohs(pip->ip_len);
668 dlen = tlen - hlen;
669
670 /* Create new FTP message. */
671 {
672 char stemp[MAX_MESSAGE_SIZE + 1];
673 char *sptr;
674 u_short alias_port;
675 u_char *ptr;
676 int a1, a2, a3, a4, p1, p2;
677 struct in_addr alias_address;
678
679 /* Decompose alias address into quad format */
680 alias_address = GetAliasAddress(lnk);
681 ptr = (u_char *)&alias_address.s_addr;
682 a1 = *ptr++;
683 a2 = *ptr++;
684 a3 = *ptr++;
685 a4 = *ptr;
686
687 alias_port = GetAliasPort(ftp_lnk);
688
689 /* Prepare new command */
690 switch (ftp_message_type) {
691 case FTP_PORT_COMMAND:
692 case FTP_227_REPLY:
693 /* Decompose alias port into pair format. */
694 ptr = (char *)&alias_port;
695 p1 = *ptr++;
696 p2 = *ptr;
697
699 /* Generate PORT command string. */
700 sprintf(stemp, "PORT %d,%d,%d,%d,%d,%d\r\n",
701 a1, a2, a3, a4, p1, p2);
702 } else {
703 /* Generate 227 reply string. */
704 sprintf(stemp,
705 "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n",
706 a1, a2, a3, a4, p1, p2);
707 }
708 break;
709 case FTP_EPRT_COMMAND:
710 /* Generate EPRT command string. */
711 sprintf(stemp, "EPRT |1|%d.%d.%d.%d|%d|\r\n",
712 a1, a2, a3, a4, ntohs(alias_port));
713 break;
714 case FTP_229_REPLY:
715 /* Generate 229 reply string. */
716 sprintf(stemp, "229 Entering Extended Passive Mode (|||%d|)\r\n",
717 ntohs(alias_port));
718 break;
719 }
720
721 /* Save string length for IP header modification */
722 slen = strlen(stemp);
723
724 /* Copy modified buffer into IP packet. */
725 sptr = (char *)pip;
726 sptr += hlen;
727 strncpy(sptr, stemp, maxpacketsize - hlen);
728 }
729
730 /* Save information regarding modified seq and ack numbers */
731 {
732 int delta;
733
734 SetAckModified(lnk);
735 tc = (struct tcphdr *)ip_next(pip);
736 delta = GetDeltaSeqOut(tc->th_seq, lnk);
737 AddSeq(lnk, delta + slen - dlen, pip->ip_hl,
738 pip->ip_len, tc->th_seq, tc->th_off);
739 }
740
741 /* Revise IP header */
742 {
743 u_short new_len;
744
745 new_len = htons(hlen +
746 MIN(slen, maxpacketsize - hlen));
748 &new_len,
749 &pip->ip_len,
750 1);
751 pip->ip_len = new_len;
752 }
753
754 /* Compute TCP checksum for revised packet */
755 tc->th_sum = 0;
756#ifdef _KERNEL
757 tc->th_x2 = 1;
758#else
759 tc->th_sum = TcpChecksum(pip);
760#endif
761 } else {
762#ifdef LIBALIAS_DEBUG
763 fprintf(stderr,
764 "PacketAlias/HandleFtpOut: Cannot allocate FTP data port\n");
765#endif
766 }
767}
u_short GetAliasPort(struct alias_link *lnk)
Definition: alias_db.c:1529
void PunchFWHole(struct alias_link *lnk)
Definition: alias_db.c:2318
struct in_addr GetAliasAddress(struct alias_link *lnk)
Definition: alias_db.c:1500
struct in_addr GetDestAddress(struct alias_link *lnk)
Definition: alias_db.c:1494
int GetProtocolFlags(struct alias_link *lnk)
Definition: alias_db.c:1723
struct in_addr GetOriginalAddress(struct alias_link *lnk)
Definition: alias_db.c:1485
void SetAckModified(struct alias_link *lnk)
Definition: alias_db.c:1545
struct alias_link * AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr, struct in_addr alias_addr, u_short src_port, u_short dst_port, int alias_port_param, int link_type)
Definition: alias_db.c:564
void SetProtocolFlags(struct alias_link *lnk, int pflags)
Definition: alias_db.c:1717
void AddSeq(struct alias_link *lnk, int delta, u_int ip_hl, u_short ip_len, u_long th_seq, u_int th_off)
Definition: alias_db.c:1672
int GetDeltaSeqOut(u_long seq, struct alias_link *lnk)
Definition: alias_db.c:1630
static int mod_handler(module_t mod, int type, void *data)
Definition: alias_ftp.c:165
static int ParseFtp227Reply(struct libalias *la, char *, int)
Definition: alias_ftp.c:494
static int protohandler_in(struct libalias *la, struct ip *pip, struct alias_data *ah)
Definition: alias_ftp.c:140
MODULE_VERSION(alias_ftp, 1)
static void NewFtpMessage(struct libalias *la, struct ip *, struct alias_link *, int, int)
Definition: alias_ftp.c:636
static moduledata_t alias_mod
Definition: alias_ftp.c:187
static int fingerprint_out(struct libalias *la, struct alias_data *ah)
Definition: alias_ftp.c:110
#define FTP_CONTROL_PORT_NUMBER
Definition: alias_ftp.c:197
static int ParseFtpEprtCommand(struct libalias *la, char *, int)
Definition: alias_ftp.c:404
static int ParseFtp229Reply(struct libalias *la, char *, int)
Definition: alias_ftp.c:567
__FBSDID("$FreeBSD$")
MODULE_DEPEND(alias_ftp, libalias, 1, 1, 1)
DECLARE_MODULE(alias_ftp, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND)
static void AliasHandleFtpIn(struct libalias *, struct ip *, struct alias_link *)
Definition: alias_ftp.c:281
static int protohandler_out(struct libalias *la, struct ip *pip, struct alias_data *ah)
Definition: alias_ftp.c:133
static void AliasHandleFtpOut(struct libalias *, struct ip *, struct alias_link *, int maxpacketsize)
Definition: alias_ftp.c:218
struct proto_handler handlers[]
Definition: alias_ftp.c:146
#define MAX_MESSAGE_SIZE
Definition: alias_ftp.c:198
ftp_message_type
Definition: alias_ftp.c:203
@ FTP_PORT_COMMAND
Definition: alias_ftp.c:204
@ FTP_229_REPLY
Definition: alias_ftp.c:207
@ FTP_227_REPLY
Definition: alias_ftp.c:206
@ FTP_UNKNOWN_MESSAGE
Definition: alias_ftp.c:208
@ FTP_EPRT_COMMAND
Definition: alias_ftp.c:205
static int fingerprint_in(struct libalias *la, struct alias_data *ah)
Definition: alias_ftp.c:122
#define WAIT_CRLF
Definition: alias_ftp.c:201
static int ParseFtpPortCommand(struct libalias *la, char *, int)
Definition: alias_ftp.c:331
#define GET_ALIAS_PORT
Definition: alias_local.h:70
void DifferentialChecksum(u_short *_cksum, void *_new, void *_old, int _n)
Definition: alias_util.c:154
int LibAliasAttachHandlers(struct proto_handler *p)
Definition: alias_mod.c:82
int LibAliasDetachHandlers(struct proto_handler *p)
Definition: alias_mod.c:98
#define TCP
Definition: alias_mod.h:58
#define EOH
Definition: alias_mod.h:92
#define IN
Definition: alias_mod.h:52
#define OUT
Definition: alias_mod.h:53
#define IPPROTO_TCP
Definition: in.h:45
u_int32_t state
Definition: ip_fw.h:10
uint16_t * dport
Definition: alias_mod.h:71
uint16_t maxpktsize
Definition: alias_mod.h:72
uint16_t * sport
Definition: alias_mod.h:71
struct alias_link * lnk
Definition: alias_mod.h:67
Definition: in.h:83
in_addr_t s_addr
Definition: in.h:84
Definition: ip.h:51
u_char ip_hl
Definition: ip.h:53
u_short ip_sum
Definition: ip.h:70
u_short ip_len
Definition: ip.h:61
struct in_addr true_addr
Definition: alias_local.h:141
u_short true_port
Definition: alias_local.h:142