static void AliasHandleFtpIn(struct libalias *la, struct ip *pip, /* IP packet to examine/patch */ struct alias_link *lnk) /* The link to go through (aliased port) */ { int hlen, tlen, dlen, pflags; char *sptr; struct tcphdr *tc; /* Calculate data length of TCP packet */ tc = (struct tcphdr *)ip_next(pip); hlen = (pip->ip_hl + tc->th_off) << 2; tlen = ntohs(pip->ip_len); dlen = tlen - hlen; /* Place string pointer and beginning of data */ sptr = (char *)pip; sptr += hlen; /* * Check that data length is not too long and previous message was * properly terminated with CRLF. */ pflags = GetProtocolFlags(lnk); if (dlen <= MAX_MESSAGE_SIZE && (pflags & WAIT_CRLF) == 0 && ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER && (ParseFtpPortCommand(la, sptr, dlen) != 0 || ParseFtpEprtCommand(la, sptr, dlen) != 0)) { /* * Alias active mode client requesting data from server * behind NAT. We need to alias server->client connection * to external address client is connecting to. */ AddLink(la, GetOriginalAddress(lnk), la->true_addr, GetAliasAddress(lnk), htons(FTP_CONTROL_PORT_NUMBER - 1), htons(la->true_port), GET_ALIAS_PORT, IPPROTO_TCP); } /* Track the msgs which are CRLF term'd for PORT/PASV FW breach */ if (dlen) { sptr = (char *)pip; /* start over at beginning */ tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may * have grown. */ if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n') pflags &= ~WAIT_CRLF; else pflags |= WAIT_CRLF; SetProtocolFlags(lnk, pflags); } }
static void AliasHandleFtpOut( struct libalias *la, struct ip *pip, /* IP packet to examine/patch */ struct alias_link *lnk, /* The link to go through (aliased port) */ int maxpacketsize /* The maximum size this packet can grow to (including headers) */ ) { int hlen, tlen, dlen, pflags; char *sptr; struct tcphdr *tc; int ftp_message_type; /* Calculate data length of TCP packet */ tc = (struct tcphdr *)ip_next(pip); hlen = (pip->ip_hl + tc->th_off) << 2; tlen = ntohs(pip->ip_len); dlen = tlen - hlen; /* Place string pointer and beginning of data */ sptr = (char *)pip; sptr += hlen; /* * Check that data length is not too long and previous message was * properly terminated with CRLF. */ pflags = GetProtocolFlags(lnk); if (dlen <= MAX_MESSAGE_SIZE && !(pflags & WAIT_CRLF)) { ftp_message_type = FTP_UNKNOWN_MESSAGE; if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER) { /* * When aliasing a client, check for the PORT/EPRT command. */ if (ParseFtpPortCommand(la, sptr, dlen)) ftp_message_type = FTP_PORT_COMMAND; else if (ParseFtpEprtCommand(la, sptr, dlen)) ftp_message_type = FTP_EPRT_COMMAND; } else { /* * When aliasing a server, check for the 227/229 reply. */ if (ParseFtp227Reply(la, sptr, dlen)) ftp_message_type = FTP_227_REPLY; else if (ParseFtp229Reply(la, sptr, dlen)) { ftp_message_type = FTP_229_REPLY; la->true_addr.s_addr = pip->ip_src.s_addr; } } if (ftp_message_type != FTP_UNKNOWN_MESSAGE) NewFtpMessage(la, pip, lnk, maxpacketsize, ftp_message_type); } /* Track the msgs which are CRLF term'd for PORT/PASV FW breach */ if (dlen) { /* only if there's data */ sptr = (char *)pip; /* start over at beginning */ tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may * have grown */ if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n') pflags &= ~WAIT_CRLF; else pflags |= WAIT_CRLF; SetProtocolFlags(lnk, pflags); } }