Hi JJK, "client-ip" instead of "localhost" sounds good to me.
BR Gava On Wed, Aug 26, 2015 at 10:01 AM, Jan Just Keijser <janj...@nikhef.nl> wrote: > Hi, > > Rafael Gava wrote: > >> >> this is my first submission to the list and I hope that I'm doing in the >> right way. :-) >> >> >> Well, the features added to Network Address Translator are: >> >> 1) Allow the user to use the string "localhost" on the client-nat network >> configuration in a way that is not necessary to inform the IP address >> beforehand. Openvpn will set the dynamic received IP from DHCP. Example: >> >> client-nat snat localhost 255.255.255.255 172.20.1.15 # replaces the >> 'localhost' string with the DHCP address received from openvpn server. >> >> I understand the idea behind it but it would be a NACK from me on the > string "localhost" - to me, localhost is 127.0.0.1 or ::1, not the DHCP-IP > ; perhaps use something like "client-ip" ? > > > 2) Allow the user to enable the FTP NAT support through the >> --enable-nat-ftp-support option. This is useful for systems that don't have >> conntrack-tools support, for example on Windows systems. On windows this >> feature is enabled by default. >> >> enable-nat-ftp-support (yes | no) >> >> sounds like a useful feature to me. > > > JJK > > >> The following patch was written based on release/2.3 branch. >> >> -------------------------------------------------------------------------------------------------------------------------------------- >> >> From d11957a025dc6c113874e7b04ce4c8e9513c3b02 Mon Sep 17 00:00:00 2001 >> From: venturus <venturus@venturus-virtual-machine.(none)> >> Date: Thu, 13 Aug 2015 08:26:36 -0300 >> Subject: [PATCH] Replaces the client-nat network string 'localhost' with >> the >> dynamic IP set to the tun/tap interface by the openvpn >> server. Example: >> >> --client-nat snat localhost 255.255.255.255 172.20.1.15 # replaces the >> 'localhost' string with the DHCP address received from openvpn server. >> >> Signed-off-by: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> >> --- >> src/openvpn/clinat.c | 57 >> ++++++++++++++++++++++++++++++++++++++++++-------- >> src/openvpn/clinat.h | 2 ++ >> src/openvpn/init.c | 4 ++++ >> 3 files changed, 54 insertions(+), 9 deletions(-) >> mode change 100644 => 100755 src/openvpn/clinat.c >> mode change 100644 => 100755 src/openvpn/clinat.h >> mode change 100644 => 100755 src/openvpn/init.c >> >> diff --git a/src/openvpn/clinat.c b/src/openvpn/clinat.c >> old mode 100644 >> new mode 100755 >> index af75fc9..2460185 >> --- a/src/openvpn/clinat.c >> +++ b/src/openvpn/clinat.c >> @@ -107,11 +107,11 @@ copy_client_nat_option_list (struct >> client_nat_option_list *dest, >> void >> add_client_nat_to_option_list (struct client_nat_option_list *dest, >> - const char *type, >> - const char *network, >> - const char *netmask, >> - const char *foreign_network, >> - int msglevel) >> + const char *type, >> + const char *network, >> + const char *netmask, >> + const char *foreign_network, >> + int msglevel) >> { >> struct client_nat_entry e; >> bool ok; >> @@ -126,12 +126,19 @@ add_client_nat_to_option_list (struct >> client_nat_option_list *dest, >> return; >> } >> - e.network = getaddr(0, network, 0, &ok, NULL); >> - if (!ok) >> + if (network && !strcmp(network, "localhost")) >> { >> - msg(msglevel, "client-nat: bad network: %s", network); >> - return; >> + msg (M_INFO, "*** client-nat localhost detected..."); >> + e.network = 0xFFFFFFFF; >> + } else { >> + e.network = getaddr(0, network, 0, &ok, NULL); >> + if (!ok) >> + { >> + msg(msglevel, "client-nat: bad network: %s", network); >> + return; >> + } >> } >> + e.netmask = getaddr(0, netmask, 0, &ok, NULL); >> if (!ok) >> { >> @@ -148,6 +155,7 @@ add_client_nat_to_option_list (struct >> client_nat_option_list *dest, >> add_entry(dest, &e); >> } >> + >> #if 0 >> static void >> print_checksum (struct openvpn_iphdr *iph, const char *prefix) >> @@ -266,4 +274,35 @@ client_nat_transform (const struct >> client_nat_option_list *list, >> } >> } >> +/* >> +* Replaces the localhost token with the IP received from OpenVPN >> +*/ >> +bool +update_localhost_nat(struct client_nat_option_list *dest, >> in_addr_t local_ip) >> +{ >> + int i; >> + bool ret = false; >> + >> + if (!dest) >> + return ret; >> + >> + for (i=0; i <= dest->n; i++) + { >> + struct client_nat_entry *nat_entry = &dest->entries[i]; >> + if (nat_entry && nat_entry->network == 0xFFFFFFFF) + { >> + struct in_addr addr; >> + + nat_entry->network = ntohl(local_ip); >> + addr.s_addr = nat_entry->network; >> + char *dot_ip = inet_ntoa(addr); >> + >> + msg (M_INFO, "Updating NAT table from localhost to: %s", >> dot_ip); + ret = true; >> + } >> + } >> + >> + return ret; >> +} >> + >> #endif >> diff --git a/src/openvpn/clinat.h b/src/openvpn/clinat.h >> old mode 100644 >> new mode 100755 >> index d55a727..ce995d9 >> --- a/src/openvpn/clinat.h >> +++ b/src/openvpn/clinat.h >> @@ -62,4 +62,6 @@ void client_nat_transform (const struct >> client_nat_option_list *list, >> struct buffer *ipbuf, >> const int direction); >> +bool update_localhost_nat(struct client_nat_option_list *dest, >> in_addr_t local_ip); >> + >> #endif >> diff --git a/src/openvpn/init.c b/src/openvpn/init.c >> old mode 100644 >> new mode 100755 >> index 71c91a2..4a63ee8 >> --- a/src/openvpn/init.c >> +++ b/src/openvpn/init.c >> @@ -1476,6 +1476,10 @@ do_open_tun (struct context *c) >> c->c1.tuntap->post_open_mtu, >> SET_MTU_TUN | SET_MTU_UPPER_BOUND); >> +#ifdef ENABLE_CLIENT_NAT >> + update_localhost_nat(c->options.client_nat, c->c1.tuntap->local); >> +#endif >> + >> ret = true; >> static_context = c; >> } >> -- >> 1.7.9.5 >> >> >> From 18b1411689df67feafeb15630c3519ab2cbd42d4 Mon Sep 17 00:00:00 2001 >> From: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> Date: Fri, 14 Aug 2015 15:27:50 -0300 >> Subject: [PATCH] Added FTP NAT support. This feature can be enabled via >> --enable-nat-ftp-support option. >> >> >> Signed-off-by: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> >> --- >> src/openvpn/clinat.c | 773 >> ++++++++++++++++++++++++++++++++++++++++++++++--- >> src/openvpn/clinat.h | 15 +- >> src/openvpn/forward.c | 75 ++--- >> src/openvpn/options.c | 12 + >> src/openvpn/options.h | 1 + >> 5 files changed, 787 insertions(+), 89 deletions(-) >> mode change 100644 => 100755 src/openvpn/forward.c >> mode change 100644 => 100755 src/openvpn/options.c >> mode change 100644 => 100755 src/openvpn/options.h >> >> diff --git a/src/openvpn/clinat.c b/src/openvpn/clinat.c >> index 2460185..1d213f5 100755 >> --- a/src/openvpn/clinat.c >> +++ b/src/openvpn/clinat.c >> @@ -36,6 +36,159 @@ >> #include "proto.h" >> #include "socket.h" >> #include "memdbg.h" >> +#include <stdio.h> >> +#include <ctype.h> >> +#include <string.h> >> + >> +/* Delta Table Types */ >> + >> +typedef struct delta_table_key { >> + uint32_t src_addr; >> + uint32_t dest_addr; >> + uint16_t src_port; >> + uint16_t dest_port; >> +} delta_table_key_t; >> + >> +typedef struct delta_table_entry { >> + delta_table_key_t key; >> + uint16_t delta_out; >> + uint16_t delta_in; >> + uint8_t marked_to_remove; >> + uint8_t reserved[3]; >> + uint32_t timestamp; >> + struct delta_table_entry *_next; >> +} delta_table_entry_t; >> + >> +typedef struct delta_table { >> + struct delta_table_entry *head; >> +} delta_table_t; >> + >> + >> +// Global delta table >> +//#define DEBUG_DELTA 1 >> + >> +delta_table_t *table = NULL; >> + >> +#define TIME_TO_RESPOND 60 * 5 // 5 Minutes >> +#define TIME_TO_LIVE 24 * 60 * 60 >> + >> +/* Delta Table Functions */ >> + >> +// In seconds, since epoch >> +static uint32_t +get_timestamp() { >> + return (uint32_t)time(NULL); >> +} >> + >> +static void +print_delta_table_entries(delta_table_t *table) { >> + delta_table_entry_t *current = table->head; >> + >> + if (current == NULL) { >> + return; >> + } >> + >> + while (current != NULL) { >> + printf("from %d -> to %d: removed: %s, timestamp: %d, delta_out: %d, >> delta_in: %d\n", + current->key.src_addr, current->key.dest_addr, >> current->marked_to_remove ? "true" : "false", + current->timestamp, >> current->delta_out, current->delta_in); >> + current = current->_next; >> + } >> +} >> + >> +static struct delta_table * >> +init_delta_table() { >> + delta_table_t *table = malloc(sizeof(delta_table_t)); >> + table->head = NULL; >> + return table; >> +} >> + >> +static struct delta_table_entry * >> +add_delta_entry(delta_table_t *table, delta_table_entry_t >> *new_delta_entry) { >> + if (table->head == NULL) { >> + table->head = new_delta_entry; >> + table->head->_next = NULL; >> + } else { >> + // Add element to HEAD, for performance gain >> + new_delta_entry->_next = table->head; >> + table->head = new_delta_entry; + } >> + return new_delta_entry; >> +} >> + >> +static int +remove_delta_entry(delta_table_t *table, delta_table_entry_t >> *delta_entry) { >> + delta_table_entry_t *current = table->head; >> + delta_table_entry_t *before = NULL; >> + uint8_t found = 0; >> + >> + //msg (M_INFO, "On remove_delta_entry - entry: %p", &delta_entry); >> + >> + while (current != NULL) { >> + if(current == delta_entry) { >> + found = 1; >> + break; >> + } >> + before = current; >> + current = current->_next; >> + } >> + >> + //Element not found >> + if (!found) { >> + return 0; >> + } >> + >> + if(before==NULL){ >> + table->head = table->head->_next; >> + } else { >> + before->_next = delta_entry->_next; >> + } >> + >> + //msg (M_INFO, "On remove_delta_entry - entry: %p - freed", >> &delta_entry); >> + + free(delta_entry); >> + return 1; >> +} >> + >> +static struct delta_table_entry * >> +get_delta_entry(delta_table_t *table, delta_table_key_t key) { >> + delta_table_entry_t *current = table->head; >> + delta_table_entry_t *aux = NULL; >> + delta_table_entry_t *el = NULL; >> + >> + while (current != NULL) { >> + // Check TTL and Timeout >> + if ((current->marked_to_remove && get_timestamp() - >> current->timestamp >= TIME_TO_RESPOND) /* || get_timestamp() - >> current->timestamp >= TIME_TO_LIVE */){ >> + aux = current; >> + //If the CURRENT is to be removed, then dont return it >> + if (aux == el) { + el = NULL; >> + } >> + current = current->_next; >> + remove_delta_entry(table, aux); >> + } else { >> + if (( >> + // Regular connection >> + (current->key.src_addr == key.src_addr && >> + current->key.src_port == key.src_port && + >> current->key.dest_addr == key.dest_addr && + >> current->key.dest_port == key.dest_port) || >> + //Check if it is a returned connection >> + (current->key.dest_addr == key.src_addr && >> + current->key.dest_port == key.src_port && + >> current->key.src_addr == key.dest_addr && + current->key.src_port >> == key.dest_port))) { >> + el = current; >> + } + current = current->_next; >> + } >> + } >> + >> + return el; >> +} >> + >> +/* Delta Table Functions End */ >> + >> static bool >> add_entry(struct client_nat_option_list *dest, >> @@ -192,19 +345,533 @@ print_pkt (struct openvpn_iphdr *iph, const char >> *prefix, const int direction, c >> gc_free (&gc); >> } >> +#if DEBUG_DELTA >> + >> +#ifndef HEXDUMP_COLS >> +#define HEXDUMP_COLS 8 >> +#endif >> + >> +static void hexdump(void *mem, unsigned int len) >> +{ >> + unsigned int i, j; >> + + for(i = 0; i < len + ((len % HEXDUMP_COLS) ? (HEXDUMP_COLS - >> len % HEXDUMP_COLS) : 0); i++) >> + { >> + /* print offset */ >> + if(i % HEXDUMP_COLS == 0) >> + { >> + printf("0x%06x: ", i); >> + } >> + + /* print hex data */ >> + if(i < len) >> + { >> + printf("%02x ", 0xFF & ((char*)mem)[i]); >> + } >> + else /* end of block, just aligning for ASCII dump */ >> + { >> + printf(" "); >> + } >> + + /* print ASCII dump */ >> + if(i % HEXDUMP_COLS == (HEXDUMP_COLS - 1)) >> + { >> + for(j = i - (HEXDUMP_COLS - 1); j <= i; j++) >> + { >> + unsigned char ch = 0xFF & ((char*)mem)[j]; >> + >> + if(j >= len) /* end of block, not really printing */ >> + { >> + putchar(' '); >> + } + else if (ch >= 0x80) + { >> + putchar('.'); >> + } >> + else if(isprint(((char*)mem)[j])) /* printable char */ >> + { >> + putchar(0xFF & ((char*)mem)[j]); + } >> + else /* other char */ >> + { >> + putchar('.'); >> + } >> + } >> + putchar('\n'); >> + } >> + } >> +} >> +#endif >> + >> +static int try_number(const char *data, size_t dlen, uint32_t array[], >> + int array_size, char sep, char term) >> +{ >> + uint32_t i, len; >> + >> + memset(array, 0, sizeof(array[0])*array_size); >> + >> + /* Keep data pointing at next char. */ >> + for (i = 0, len = 0; len < dlen && i < array_size; len++, data++) { >> + if (*data >= '0' && *data <= '9') { >> + array[i] = array[i]*10 + *data - '0'; >> + } >> + else if (*data == sep) >> + i++; >> + else { >> + /* Unexpected character; true if it's the >> + terminator and we're finished. */ >> + if (*data == term && i == array_size - 1) >> + return len; >> + >> + msg (M_ERRNO, "CNAT - try_number - Char %u (got %u nums) `%u' >> unexpected\n", len, i, *data); >> + return 0; >> + } >> + } >> + >> + msg (M_ERRNO, "CNAT - ERROR: Failed to fill %u numbers separated by >> %c\n", array_size, sep); >> + >> + return 0; >> +} >> + >> +static int try_rfc959(const char *, size_t, u_int32_t [], char); >> + >> +static struct ftp_search { >> + int direction; >> + const char *pattern; >> + size_t plen; >> + char skip; >> + char term; >> + int (*getnum)(const char *, size_t, u_int32_t[], char); >> +} search[] = { >> + { >> + CN_OUTGOING, >> + "PORT", sizeof("PORT") - 1, ' ', '\r', >> + try_rfc959, >> + }, >> + { >> + CN_INCOMING, >> + "227 ", sizeof("227 ") - 1, '(', ')', >> + try_rfc959, >> + }, >> +}; >> + >> + >> +/* Returns 0, or length of numbers: 192,168,1,1,5,6 */ >> +static int +try_rfc959(const char *data, size_t dlen, u_int32_t array[6], >> + char term) >> +{ >> + return try_number(data, dlen, array, 6, ',', term); >> +} >> + >> +/* Grab port: number up to delimiter */ >> +static int +get_port(const char *data, int start, size_t dlen, char >> delim, >> + u_int32_t array[2]) >> +{ >> + u_int16_t port = 0; >> + int i; >> + >> + for (i = start; i < dlen; i++) { >> + /* Finished? */ >> + if (data[i] == delim) { >> + if (port == 0) >> + break; >> + array[0] = port >> 8; >> + array[1] = port; >> + return i + 1; >> + } >> + else if (data[i] >= '0' && data[i] <= '9') >> + port = port*10 + data[i] - '0'; >> + else /* Some other crap */ >> + break; >> + } >> + return 0; >> +} >> + >> +/* Return 1 for match, 0 for accept, -1 for partial. */ >> +static int +find_pattern(const char *data, size_t dlen, >> + const char *pattern, size_t plen, >> + char skip, char term, >> + unsigned int *numoff, >> + unsigned int *numlen, >> + u_int32_t array[6], >> + int (*getnum)(const char *, size_t, u_int32_t[], char)) >> +{ >> + size_t i; >> + >> + if (check_debug_level (D_CLIENT_NAT)) >> + msg (M_INFO, "CNAT - find_pattern %s: dlen = %u\n", pattern, dlen); >> + >> + if (dlen == 0) >> + return 0; >> + >> + if (dlen <= plen) { >> + /* Short packet: try for partial? */ >> + if (strncasecmp(data, pattern, dlen) == 0) >> + return -1; >> + else return 0; >> + } >> + >> + if (strncasecmp(data, pattern, plen) != 0) { >> + return 0; >> + } >> + >> + if (check_debug_level (D_CLIENT_NAT)) >> + msg (M_INFO, "CNAT - Pattern matches!\n"); >> + >> + /* Now we've found the constant string, try to skip >> + to the 'skip' character */ >> + for (i = plen; data[i] != skip; i++) >> + if (i == dlen - 1) return -1; >> + >> + /* Skip over the last character */ >> + i++; >> + >> + if (check_debug_level (D_CLIENT_NAT)) >> + msg (M_INFO, "CNAT - Skipped up to `%c'!\n", skip); >> + >> + *numoff = i; >> + *numlen = getnum(data + i, dlen - i, array, term); >> + if (!*numlen) >> + return -1; >> + >> + if (check_debug_level (D_CLIENT_NAT)) >> + msg (M_INFO, "CNAT - Match succeeded!\n"); >> + + return 1; >> +} >> + >> +static uint16_t >> +tcp_checksum (const uint8_t *buf, >> + const int len_tcp, >> + const uint32_t src_addr, >> + const uint32_t dest_addr) >> +{ >> + uint16_t word16; >> + uint32_t sum = 0; >> + int i; >> + uint8_t * psrc_addr = (uint8_t *) &src_addr; >> + uint8_t * pdest_addr = (uint8_t *) &dest_addr; >> + + /* make 16 bit words out of every two adjacent 8 bit words and */ >> + /* calculate the sum of all 16 bit words */ >> + for (i = 0; i < len_tcp; i += 2){ >> + word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_tcp) ? (buf[i+1] & >> 0xFF) : 0); >> + sum += word16; >> + } >> + >> + /* add the TCP pseudo header which contains the IP source and >> destination addresses */ >> + for (i = 0; i < 4; i += 2){ >> + word16 =((psrc_addr[i] << 8) & 0xFF00) + (psrc_addr[i+1] & 0xFF); >> + sum += word16; >> + } >> + for (i = 0; i < 4; i += 2){ >> + word16 =((pdest_addr[i] << 8) & 0xFF00) + (pdest_addr[i+1] & 0xFF); >> + sum += word16; + } >> + >> + /* the protocol number and the length of the TCP packet */ >> + sum += (uint16_t) OPENVPN_IPPROTO_TCP + (uint16_t) len_tcp; >> + >> + /* keep only the last 16 bits of the 32 bit calculated sum and add the >> carries */ >> + while (sum >> 16) >> + sum = (sum & 0xFFFF) + (sum >> 16); >> + + /* Take the one's complement of sum */ >> + return ((uint16_t) ~sum); >> +} >> + >> +static uint16_t +ip_checksum(const void *buf, uint16_t hdr_len) { >> + unsigned long sum = 0; >> + const uint16_t *ip1; >> + >> + ip1 = buf; >> + while (hdr_len > 1) { >> + sum += *ip1++; >> + if (sum & 0x80000000) >> + sum = (sum & 0xFFFF) + (sum >> 16); >> + hdr_len -= 2; >> + } >> + >> + while (sum >> 16) >> + sum = (sum & 0xFFFF) + (sum >> 16); >> + >> + return(~sum); >> +} >> + >> +static int +client_nat_ftp_transform(struct buffer *ipbuf, >> + const int direction, const uint32_t from_address, uint32_t >> replace_address) { >> + >> + uint32_t array[6] = {0}; >> + int ret = 0; >> + int data_len = 0; >> + >> + struct ip_tcp_udp_hdr *hdr = (struct ip_tcp_udp_hdr *) BPTR (ipbuf); >> + >> + if (hdr->ip.protocol != OPENVPN_IPPROTO_TCP) >> + return ret; >> + >> + if (table == NULL) + table = init_delta_table(); >> + + delta_table_entry_t *entry = NULL; >> + delta_table_key_t delta_key; >> + >> + // Because the address already was NATed, probably on OpenVPN Server >> + if (direction == CN_OUTGOING) >> + delta_key.src_addr = from_address; >> + else if (direction == CN_INCOMING) >> + delta_key.src_addr = hdr->ip.saddr; >> + >> + delta_key.src_port = hdr->u.tcp.source; >> + delta_key.dest_addr = hdr->ip.daddr; >> + delta_key.dest_port = hdr->u.tcp.dest; >> + >> +#if DEBUG_DELTA >> + msg (M_INFO, "delta_key - saddr: %d, sport: %d, daddr: %d, dport: %d", >> + delta_key.src_addr, delta_key.src_port, delta_key.dest_addr, >> delta_key.dest_port); >> + >> + msg (M_INFO, "seq: %x, ack: %x", + hdr->u.tcp.seq, >> hdr->u.tcp.ack_seq); >> +#endif >> + >> + int tcp_data_offset = OPENVPN_TCPH_GET_DOFF (hdr->u.tcp.doff_res); >> + >> + struct buffer tcpbuf = *ipbuf; >> + if (!buf_advance (&tcpbuf, sizeof(struct openvpn_iphdr) + >> tcp_data_offset)) >> + return ret; >> + >> + uint8_t * tcp_data = (uint8_t *) BPTR (&tcpbuf); >> + >> +#if DEBUG_DELTA >> + msg (M_INFO, "TCP DATA BEFORE NAT:"); >> + hexdump(tcp_data, BLEN(&tcpbuf)); +#endif >> + >> + u_int32_t matchlen, matchoff; >> + int found_pattern = -1; >> + int i = 0; >> + >> + for (i = 0; i < sizeof(search) / sizeof(search[0]); i++) { >> + if (search[i].direction != direction) continue; >> + >> + found_pattern = find_pattern(tcp_data, BLEN(&tcpbuf), >> + search[i].pattern, >> + search[i].plen, >> + search[i].skip, >> + search[i].term, >> + &matchoff, &matchlen, >> + array, >> + search[i].getnum); >> + if (found_pattern) break; >> + } >> + >> + if (found_pattern > 0) + { >> + >> + if (check_debug_level (D_CLIENT_NAT)) + { >> + msg (M_INFO, "client-nat FTP match: %.*s - data: %.*s\n", >> + matchoff, tcp_data, matchlen, &tcp_data[matchoff]); >> + } >> + >> + data_len = BLEN(&tcpbuf) - matchoff; >> + >> + uint32_t ip = htonl((array[0] << 24) | (array[1] << 16) >> + | (array[2] << 8) | array[3]); >> + uint16_t port = htons(array[4] << 8 | array[5]); >> + uint8_t * addr_tmp = (uint8_t *) &replace_address; >> + >> + uint8_t new_tcp_data[32]; >> + memset(&new_tcp_data[0], 0, sizeof(new_tcp_data)); >> + >> + int new_len = sprintf((char *) &new_tcp_data[0], >> "%d,%d,%d,%d,%d,%d%.*s", >> + addr_tmp[0], addr_tmp[1], addr_tmp[2], addr_tmp[3], array[4], >> array[5], + data_len - matchlen, (char *)&tcp_data[matchoff + >> matchlen]); >> + >> + if (check_debug_level (D_CLIENT_NAT)) + { >> + msg (M_INFO, "client-nat replaced address from: %.*s to: >> %.*s\n", >> + data_len, &tcp_data[matchoff], new_len, &new_tcp_data[0]); >> + } >> + >> + //If the new len is greater than the old, there will be there an >> adjustment >> + if (new_len > data_len) + { >> + //If the entry already exists >> + if (entry = get_delta_entry(table, delta_key)) + { >> + if (direction == CN_OUTGOING) + { >> + hdr->u.tcp.seq = htonl(ntohl(hdr->u.tcp.seq) + >> (entry->delta_out)); // Need to update seq and ack >> + hdr->u.tcp.ack_seq = htonl(ntohl(hdr->u.tcp.ack_seq) - >> entry->delta_in); >> + entry->delta_out += new_len - data_len; >> + } >> + else >> + { >> + hdr->u.tcp.seq = htonl(ntohl(hdr->u.tcp.seq) + >> (entry->delta_in)); // Need to update seq and ack >> + hdr->u.tcp.ack_seq = htonl(ntohl(hdr->u.tcp.ack_seq) - >> entry->delta_out); >> + entry->delta_in += new_len - data_len; >> + } >> + //Update timestamp entry on delta entry, to keep this >> delta alive >> + entry->timestamp = get_timestamp(); >> + } >> + else + { >> + // No entry found. Add a new one. >> + entry = malloc(sizeof(delta_table_entry_t)); >> + entry->key = delta_key; >> + >> + if (direction == CN_OUTGOING) + { >> + entry->delta_out = new_len - data_len; >> + entry->delta_in = 0; >> + } >> + else >> + { >> + entry->delta_in = new_len - data_len; >> + entry->delta_out = 0; >> + } >> + entry->marked_to_remove = 0; >> + entry->timestamp = get_timestamp(); >> + + //Add it to delta table >> + add_delta_entry(table, entry); >> + } >> + >> +#if DEBUG_DELTA >> + print_delta_table_entries(table); >> +#endif >> + >> + //Increase the tcpbuf and ipbuf reflecting the delta chars >> added to the segment. >> + ASSERT(buf_inc_len(&tcpbuf, new_len - data_len)); >> + ASSERT(buf_inc_len(ipbuf, new_len - data_len)); >> + >> + //Update tot_len >> + hdr->ip.tot_len = htons(ntohs(hdr->ip.tot_len) + (new_len - >> data_len)); >> + >> + // Readjust IP Checksum >> + uint16_t head_len = OPENVPN_IPH_GET_LEN(hdr->ip.version_len); >> + hdr->ip.check = 0; >> + uint16_t check = ip_checksum( BPTR (ipbuf), head_len); >> + hdr->ip.check = check; >> + >> + //Use new_len here! >> + memcpy(&tcp_data[matchoff], new_tcp_data, new_len); + } >> + else >> + { >> + // The replace size is the lesser or iqual the original? Pad >> with 0 if necessary. >> + memcpy(&tcp_data[matchoff], new_tcp_data, data_len); + >> + //If the entry already exists >> + if (entry = get_delta_entry(table, delta_key)) + { >> + if (direction == CN_OUTGOING) + { >> + hdr->u.tcp.seq = htonl(ntohl(hdr->u.tcp.seq) + >> (entry->delta_out)); // Need to update seq and ack >> + hdr->u.tcp.ack_seq = htonl(ntohl(hdr->u.tcp.ack_seq) - >> entry->delta_in); >> + } >> + else >> + { >> + hdr->u.tcp.seq = htonl(ntohl(hdr->u.tcp.seq) + >> (entry->delta_in)); // Need to update seq and ack >> + hdr->u.tcp.ack_seq = htonl(ntohl(hdr->u.tcp.ack_seq) - >> entry->delta_out); >> + } >> + //Update timestamp entry on delta entry, to keep this >> delta alive >> + entry->timestamp = get_timestamp(); >> + } >> + >> + } >> + >> + //Update TCP checksum >> + hdr->u.tcp.check = 0; >> + >> + uint16_t tot_len = ntohs(hdr->ip.tot_len); >> + uint16_t head_len = OPENVPN_IPH_GET_LEN(hdr->ip.version_len); >> + >> + uint16_t check = tcp_checksum(BPTR (ipbuf) + head_len, + >> tot_len - head_len, hdr->ip.saddr, hdr->ip.daddr); + >> + hdr->u.tcp.check = htons(check); >> + ret = 1; >> + } >> + else + { >> + //No pattern found. Check if there is a delta entry for this >> connection >> + if(entry = get_delta_entry(table, delta_key)) + { >> + if (direction == CN_OUTGOING) + { >> + hdr->u.tcp.seq = htonl(ntohl(hdr->u.tcp.seq) + >> entry->delta_out); >> + hdr->u.tcp.ack_seq = htonl(ntohl(hdr->u.tcp.ack_seq) - >> entry->delta_in); >> + } + else + { >> + hdr->u.tcp.seq = htonl(ntohl(hdr->u.tcp.seq) + >> entry->delta_in); >> + hdr->u.tcp.ack_seq = htonl(ntohl(hdr->u.tcp.ack_seq) - >> entry->delta_out); >> + } >> + >> + //Update TCP checksum >> + hdr->u.tcp.check = 0; >> + >> + uint16_t tot_len = ntohs(hdr->ip.tot_len); >> + uint16_t head_len = OPENVPN_IPH_GET_LEN(hdr->ip.version_len); >> + >> + uint16_t check = tcp_checksum(BPTR (ipbuf) + head_len, + >> tot_len - head_len, hdr->ip.saddr, hdr->ip.daddr); + >> + hdr->u.tcp.check = htons(check); >> + >> + //Update timestamp entry on delta entry >> + entry->timestamp = get_timestamp(); >> + >> + // If it is a FIN package, then remove entry from delta table >> + if (OPENVPN_TCPH_FIN_MASK & hdr->u.tcp.flags) + { >> + entry->marked_to_remove = 1; >> + msg (M_INFO, "Delta marked to be removed!"); >> + } >> + + ret = 1; + } >> + else + { >> +#if DEBUG_DELTA >> + // Regular package! >> + msg (M_INFO, "Regular package!: tot_len %d, seq %x, ack %x\n", >> ntohs(hdr->ip.tot_len), ntohl(hdr->u.tcp.seq), ntohl(hdr->u.tcp.ack_seq)); >> +#endif >> + } >> + } >> + >> +#if DEBUG_DELTA >> + msg (M_INFO, "TCP DATA AFTER NAT:"); >> + hexdump(tcp_data, BLEN(&tcpbuf)); >> +#endif >> + >> + return ret; >> +} >> + >> void >> client_nat_transform (const struct client_nat_option_list *list, >> - struct buffer *ipbuf, >> - const int direction) >> + struct buffer *ipbuf, >> + const int direction, + const bool >> enable_nat_ftp_support) >> { >> struct ip_tcp_udp_hdr *h = (struct ip_tcp_udp_hdr *) BPTR (ipbuf); >> int i; >> - uint32_t addr, *addr_ptr; >> + uint32_t addr, *addr_ptr, from_addr; >> const uint32_t *from, *to; >> int accumulate = 0; >> unsigned int amask; >> unsigned int alog = 0; >> + uint32_t orig_saddr = h->ip.saddr; >> + uint32_t orig_daddr = h->ip.daddr; >> + >> if (check_debug_level (D_CLIENT_NAT)) >> print_pkt (&h->ip, "BEFORE", direction, D_CLIENT_NAT); >> @@ -212,65 +879,81 @@ client_nat_transform (const struct >> client_nat_option_list *list, >> { >> const struct client_nat_entry *e = &list->entries[i]; /* current >> NAT rule */ >> if (e->type ^ direction) >> - { >> - addr = *(addr_ptr = &h->ip.daddr); >> - amask = 2; >> - } >> + { >> + addr = *(addr_ptr = &h->ip.daddr); >> + amask = 2; >> + } >> else >> - { >> - addr = *(addr_ptr = &h->ip.saddr); >> - amask = 1; >> - } >> + { >> + addr = *(addr_ptr = &h->ip.saddr); >> + amask = 1; >> + } >> if (direction) >> - { >> - from = &e->foreign_network; >> - to = &e->network; >> - } >> + { >> + from = &e->foreign_network; >> + to = &e->network; >> + } >> else >> - { >> - from = &e->network; >> - to = &e->foreign_network; >> - } >> + { >> + from = &e->network; >> + to = &e->foreign_network; >> + } >> if (((addr & e->netmask) == *from) && !(amask & alog)) >> - { >> - /* pre-adjust IP checksum */ >> - ADD_CHECKSUM_32(accumulate, addr); >> + { >> + from_addr = *from; >> + + /* pre-adjust IP checksum */ >> + ADD_CHECKSUM_32(accumulate, addr); >> - /* do NAT transform */ >> - addr = (addr & ~e->netmask) | *to; >> + /* do NAT transform */ >> + addr = (addr & ~e->netmask) | *to; >> - /* post-adjust IP checksum */ >> - SUB_CHECKSUM_32(accumulate, addr); >> + /* post-adjust IP checksum */ >> + SUB_CHECKSUM_32(accumulate, addr); >> - /* write the modified address to packet */ >> - *addr_ptr = addr; >> + /* write the modified address to packet */ >> + *addr_ptr = addr; >> - /* mark as modified */ >> - alog |= amask; >> - } >> + /* mark as modified */ >> + alog |= amask; >> + } >> } >> if (alog) >> { >> if (check_debug_level (D_CLIENT_NAT)) >> - print_pkt (&h->ip, "AFTER", direction, D_CLIENT_NAT); >> + print_pkt (&h->ip, "AFTER", direction, D_CLIENT_NAT); >> ADJUST_CHECKSUM(accumulate, h->ip.check); >> if (h->ip.protocol == OPENVPN_IPPROTO_TCP) >> - { >> - if (BLEN(ipbuf) >= sizeof(struct openvpn_iphdr) + sizeof(struct >> openvpn_tcphdr)) >> - { >> - ADJUST_CHECKSUM(accumulate, h->u.tcp.check); >> - } >> - } >> + { >> + if (BLEN(ipbuf) >= sizeof(struct openvpn_iphdr) + >> sizeof(struct openvpn_tcphdr)) >> + { >> + ADJUST_CHECKSUM(accumulate, h->u.tcp.check); >> + } >> + >> + uint32_t repl_addr = addr; >> + + if (amask == 2) + { >> + if (direction) >> + repl_addr = orig_saddr; >> + else >> + repl_addr = orig_daddr; >> + } >> + + if (enable_nat_ftp_support) >> + client_nat_ftp_transform(ipbuf, direction, from_addr, >> repl_addr); >> + + } >> else if (h->ip.protocol == OPENVPN_IPPROTO_UDP) >> - { >> - if (BLEN(ipbuf) >= sizeof(struct openvpn_iphdr) + sizeof(struct >> openvpn_udphdr)) >> - { >> - ADJUST_CHECKSUM(accumulate, h->u.udp.check); >> - } >> - } >> + { >> + if (BLEN(ipbuf) >= sizeof(struct openvpn_iphdr) + >> sizeof(struct openvpn_udphdr)) >> + { >> + ADJUST_CHECKSUM(accumulate, h->u.udp.check); >> + } >> + } >> } >> } >> @@ -297,7 +980,7 @@ update_localhost_nat(struct client_nat_option_list >> *dest, in_addr_t local_ip) >> addr.s_addr = nat_entry->network; >> char *dot_ip = inet_ntoa(addr); >> - msg (M_INFO, "Updating NAT table from localhost to: %s", >> dot_ip); + msg (M_INFO, "CNAT - Updating NAT table from localhost >> to: %s", dot_ip); ret = true; >> } >> } >> diff --git a/src/openvpn/clinat.h b/src/openvpn/clinat.h >> index ce995d9..a58da5d 100755 >> --- a/src/openvpn/clinat.h >> +++ b/src/openvpn/clinat.h >> @@ -52,15 +52,16 @@ void copy_client_nat_option_list (struct >> client_nat_option_list *dest, const str >> void print_client_nat_list(const struct client_nat_option_list *list, >> int msglevel); >> void add_client_nat_to_option_list (struct client_nat_option_list *dest, >> - const char *type, >> - const char *network, >> - const char *netmask, >> - const char *foreign_network, >> - int msglevel); >> + const char *type, >> + const char *network, >> + const char *netmask, >> + const char *foreign_network, >> + int msglevel); >> void client_nat_transform (const struct client_nat_option_list *list, >> - struct buffer *ipbuf, >> - const int direction); >> + struct buffer *ipbuf, >> + const int direction, >> + const bool enable_nat_ftp_support); >> bool update_localhost_nat(struct client_nat_option_list *dest, >> in_addr_t local_ip); >> diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c >> old mode 100644 >> new mode 100755 >> index 217fbb3..615db7a >> --- a/src/openvpn/forward.c >> +++ b/src/openvpn/forward.c >> @@ -980,9 +980,6 @@ process_incoming_tun (struct context *c) >> perf_push (PERF_PROC_IN_TUN); >> - if (c->c2.buf.len > 0) >> - c->c2.tun_read_bytes += c->c2.buf.len; >> - >> #ifdef LOG_RW >> if (c->c2.log_rw && c->c2.buf.len > 0) >> fprintf (stderr, "r"); >> @@ -999,6 +996,9 @@ process_incoming_tun (struct context *c) >> */ >> process_ip_header (c, PIPV4_PASSTOS|PIP_MSSFIX|PIPV4_CLIENT_NAT, >> &c->c2.buf); >> + if (c->c2.buf.len > 0) >> + c->c2.tun_read_bytes += c->c2.buf.len; >> + >> #ifdef PACKET_TRUNCATION_CHECK >> /* if (c->c2.buf.len > 1) --c->c2.buf.len; */ >> ipv4_packet_size_verify (BPTR (&c->c2.buf), >> @@ -1041,43 +1041,44 @@ process_ip_header (struct context *c, unsigned >> int flags, struct buffer *buf) >> #else >> if (flags & PIP_MSSFIX) >> #endif >> - { >> - struct buffer ipbuf = *buf; >> - if (is_ipv4 (TUNNEL_TYPE (c->c1.tuntap), &ipbuf)) >> - { >> -#if PASSTOS_CAPABILITY >> - /* extract TOS from IP header */ >> - if (flags & PIPV4_PASSTOS) >> - link_socket_extract_tos (c->c2.link_socket, &ipbuf); >> -#endif >> - - /* possibly alter the TCP MSS */ >> - if (flags & PIP_MSSFIX) >> - mss_fixup_ipv4 (&ipbuf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC >> (&c->c2.frame))); >> + { >> + if (is_ipv4 (TUNNEL_TYPE (c->c1.tuntap), buf)) >> + { >> #ifdef ENABLE_CLIENT_NAT >> - /* possibly do NAT on packet */ >> - if ((flags & PIPV4_CLIENT_NAT) && c->options.client_nat) >> - { >> - const int direction = (flags & PIPV4_OUTGOING) ? CN_INCOMING : >> CN_OUTGOING; >> - client_nat_transform (c->options.client_nat, &ipbuf, direction); >> - } >> + /* possibly do NAT on packet */ >> + if ((flags & PIPV4_CLIENT_NAT) && c->options.client_nat) >> + { >> + const int direction = (flags & PIPV4_OUTGOING) ? >> CN_INCOMING : CN_OUTGOING; >> + client_nat_transform(c->options.client_nat, buf, >> direction, c->options.enable_nat_ftp_support); >> + } >> #endif >> - /* possibly extract a DHCP router message */ >> - if (flags & PIPV4_EXTRACT_DHCP_ROUTER) >> - { >> - const in_addr_t dhcp_router = dhcp_extract_router_msg (&ipbuf); >> - if (dhcp_router) >> - route_list_add_vpn_gateway (c->c1.route_list, c->c2.es <http://c2.es>, >> dhcp_router); >> >> - } >> - } >> - else if (is_ipv6 (TUNNEL_TYPE (c->c1.tuntap), &ipbuf)) >> - { >> - /* possibly alter the TCP MSS */ >> - if (flags & PIP_MSSFIX) >> - mss_fixup_ipv6 (&ipbuf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC >> (&c->c2.frame))); >> - } >> - } >> + >> +#if PASSTOS_CAPABILITY >> + /* extract TOS from IP header */ >> + if (flags & PIPV4_PASSTOS) >> + link_socket_extract_tos (c->c2.link_socket, buf); >> +#endif >> + >> + /* possibly alter the TCP MSS */ >> + if (flags & PIP_MSSFIX) >> + mss_fixup_ipv4 (buf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC >> (&c->c2.frame))); >> + >> + /* possibly extract a DHCP router message */ >> + if (flags & PIPV4_EXTRACT_DHCP_ROUTER) >> + { >> + const in_addr_t dhcp_router = dhcp_extract_router_msg >> (buf); >> + if (dhcp_router) >> + route_list_add_vpn_gateway (c->c1.route_list, c-> >> c2.es <http://c2.es>, dhcp_router); >> >> + } >> + } >> + else if (is_ipv6 (TUNNEL_TYPE (c->c1.tuntap), buf)) >> + { >> + /* possibly alter the TCP MSS */ >> + if (flags & PIP_MSSFIX) >> + mss_fixup_ipv6 (buf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC >> (&c->c2.frame))); >> + } >> + } >> } >> } >> diff --git a/src/openvpn/options.c b/src/openvpn/options.c >> old mode 100644 >> new mode 100755 >> index 007bd8c..73b615a >> --- a/src/openvpn/options.c >> +++ b/src/openvpn/options.c >> @@ -236,6 +236,7 @@ static const char usage_message[] = >> " the default gateway. Useful when pushing private >> subnets.\n" >> #ifdef ENABLE_CLIENT_NAT >> "--client-nat snat|dnat network netmask alias : on client add 1-to-1 >> NAT rule.\n" >> + "--enable-nat-ftp-support : Enable NAT FTP Support, updating the IP >> address on FTP PORT commands or PASV responses\n" #endif >> #ifdef ENABLE_PUSH_PEER_INFO >> "--push-peer-info : (client only) push client info to server.\n" >> @@ -789,6 +790,11 @@ init_options (struct options *o, const bool init_gc) >> o->max_routes = MAX_ROUTES_DEFAULT; >> o->resolve_retry_seconds = RESOLV_RETRY_INFINITE; >> o->proto_force = -1; >> + >> +#ifdef ENABLE_CLIENT_NAT >> + o->enable_nat_ftp_support = false; >> +#endif >> + #ifdef ENABLE_OCC >> o->occ = true; >> #endif >> @@ -1535,6 +1541,8 @@ show_settings (const struct options *o) >> #ifdef ENABLE_CLIENT_NAT >> if (o->client_nat) >> print_client_nat_list(o->client_nat, D_SHOW_PARMS); >> + >> + SHOW_BOOL(enable_nat_ftp_support); >> #endif >> #ifdef ENABLE_MANAGEMENT >> @@ -5287,6 +5295,10 @@ add_option (struct options *options, >> cnol_check_alloc (options); >> add_client_nat_to_option_list(options->client_nat, p[1], p[2], >> p[3], p[4], msglevel); >> } >> + else if (streq (p[0], "enable_nat_ftp_support")) >> + { >> + options->enable_nat_ftp_support = true; >> + } >> #endif >> else if (streq (p[0], "route") && p[1]) >> { >> diff --git a/src/openvpn/options.h b/src/openvpn/options.h >> old mode 100644 >> new mode 100755 >> index af9a47f..2b27368 >> --- a/src/openvpn/options.h >> +++ b/src/openvpn/options.h >> @@ -347,6 +347,7 @@ struct options >> bool allow_pull_fqdn; /* as a client, allow server to push a FQDN for >> certain parameters */ >> #ifdef ENABLE_CLIENT_NAT >> + bool enable_nat_ftp_support; >> struct client_nat_option_list *client_nat; >> #endif >> >> -- >> 1.7.9.5 >> >> >> From 0aa64f57ecf653cd067dbef2b2378bdfc4f9a754 Mon Sep 17 00:00:00 2001 >> From: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> Date: Fri, 14 Aug 2015 16:46:13 -0300 >> Subject: [PATCH] Removed debug messages. >> >> >> Signed-off-by: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> --- >> src/openvpn/clinat.c | 2 ++ >> 1 file changed, 2 insertions(+) >> >> diff --git a/src/openvpn/clinat.c b/src/openvpn/clinat.c >> index 1d213f5..991ea75 100755 >> --- a/src/openvpn/clinat.c >> +++ b/src/openvpn/clinat.c >> @@ -833,7 +833,9 @@ client_nat_ftp_transform(struct buffer *ipbuf, >> if (OPENVPN_TCPH_FIN_MASK & hdr->u.tcp.flags) { >> entry->marked_to_remove = 1; >> +#if DEBUG_DELTA msg (M_INFO, "Delta marked >> to be removed!"); >> +#endif >> } >> ret = 1; >> -- >> 1.7.9.5 >> >> >> From cf7af4e4784c83a64b8c1e12601d33bdc5b14d59 Mon Sep 17 00:00:00 2001 >> From: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> Date: Thu, 20 Aug 2015 08:47:08 -0300 >> Subject: [PATCH] Fixed FTP NAT IP address. >> >> >> Signed-off-by: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> >> --- >> src/openvpn/clinat.c | 30 +++++++++++++++--------------- >> 1 file changed, 15 insertions(+), 15 deletions(-) >> >> diff --git a/src/openvpn/clinat.c b/src/openvpn/clinat.c >> index 991ea75..ef400de 100755 >> --- a/src/openvpn/clinat.c >> +++ b/src/openvpn/clinat.c >> @@ -423,7 +423,7 @@ static int try_number(const char *data, size_t dlen, >> uint32_t array[], >> if (*data == term && i == array_size - 1) >> return len; >> - msg (M_ERRNO, "CNAT - try_number - Char %u (got %u nums) `%u' >> unexpected\n", len, i, *data); >> + msg (M_ERRNO, "CNAT - try_number - Char %u (got %u nums) '%u' >> unexpected\n", len, i, *data); >> return 0; >> } >> } >> @@ -433,7 +433,7 @@ static int try_number(const char *data, size_t dlen, >> uint32_t array[], >> return 0; >> } >> -static int try_rfc959(const char *, size_t, u_int32_t [], char); >> +static int try_rfc959(const char *, size_t, uint32_t [], char); >> static struct ftp_search { >> int direction; >> @@ -441,7 +441,7 @@ static struct ftp_search { >> size_t plen; >> char skip; >> char term; >> - int (*getnum)(const char *, size_t, u_int32_t[], char); >> + int (*getnum)(const char *, size_t, uint32_t[], char); >> } search[] = { >> { >> CN_OUTGOING, >> @@ -458,7 +458,7 @@ static struct ftp_search { >> /* Returns 0, or length of numbers: 192,168,1,1,5,6 */ >> static int -try_rfc959(const char *data, size_t dlen, u_int32_t array[6], >> +try_rfc959(const char *data, size_t dlen, uint32_t array[6], >> char term) >> { >> return try_number(data, dlen, array, 6, ',', term); >> @@ -467,9 +467,9 @@ try_rfc959(const char *data, size_t dlen, u_int32_t >> array[6], >> /* Grab port: number up to delimiter */ >> static int get_port(const char *data, int start, size_t dlen, char >> delim, >> - u_int32_t array[2]) >> + uint32_t array[2]) >> { >> - u_int16_t port = 0; >> + uint16_t port = 0; >> int i; >> for (i = start; i < dlen; i++) { >> @@ -496,13 +496,13 @@ find_pattern(const char *data, size_t dlen, >> char skip, char term, >> unsigned int *numoff, >> unsigned int *numlen, >> - u_int32_t array[6], >> - int (*getnum)(const char *, size_t, u_int32_t[], char)) >> + uint32_t array[6], >> + int (*getnum)(const char *, size_t, uint32_t[], char)) >> { >> size_t i; >> if (check_debug_level (D_CLIENT_NAT)) >> - msg (M_INFO, "CNAT - find_pattern %s: dlen = %u\n", pattern, dlen); >> + msg (M_INFO, "CNAT - find_pattern %s: dlen = %u\n", pattern, >> (uint32_t) dlen); >> if (dlen == 0) >> return 0; >> @@ -530,7 +530,7 @@ find_pattern(const char *data, size_t dlen, >> i++; >> if (check_debug_level (D_CLIENT_NAT)) >> - msg (M_INFO, "CNAT - Skipped up to `%c'!\n", skip); >> + msg (M_INFO, "CNAT - Skipped up to '%c' (%d)!\n", skip, skip); >> *numoff = i; >> *numlen = getnum(data + i, dlen - i, array, term); >> @@ -652,7 +652,7 @@ client_nat_ftp_transform(struct buffer *ipbuf, >> hexdump(tcp_data, BLEN(&tcpbuf)); #endif >> - u_int32_t matchlen, matchoff; >> + uint32_t matchlen, matchoff; >> int found_pattern = -1; >> int i = 0; >> @@ -689,7 +689,7 @@ client_nat_ftp_transform(struct buffer *ipbuf, >> uint8_t new_tcp_data[32]; >> memset(&new_tcp_data[0], 0, sizeof(new_tcp_data)); >> - int new_len = sprintf((char *) &new_tcp_data[0], >> "%d,%d,%d,%d,%d,%d%.*s", >> + int new_len = sprintf((char *) &new_tcp_data[0], >> "%03d,%03d,%03d,%03d,%03d,%03d%.*s", >> addr_tmp[0], addr_tmp[1], addr_tmp[2], addr_tmp[3], array[4], >> array[5], data_len - matchlen, (char *)&tcp_data[matchoff + >> matchlen]); >> @@ -700,7 +700,7 @@ client_nat_ftp_transform(struct buffer *ipbuf, >> } >> //If the new len is greater than the old, there will be there an >> adjustment >> - if (new_len > data_len) + if (replace_address != ip && >> new_len > data_len) { >> //If the entry already exists >> if (entry = get_delta_entry(table, delta_key)) @@ -765,8 >> +765,8 @@ client_nat_ftp_transform(struct buffer *ipbuf, >> } >> else >> { >> - // The replace size is the lesser or iqual the original? Pad >> with 0 if necessary. >> - memcpy(&tcp_data[matchoff], new_tcp_data, data_len); + >> if (replace_address != ip) >> + memcpy(&tcp_data[matchoff], new_tcp_data, data_len); >> //If the entry already exists >> if (entry = get_delta_entry(table, delta_key)) >> -- >> 1.7.9.5 >> >> >> From 63b1ddad1628eb1a179c2bf5010b781284d2bc4f Mon Sep 17 00:00:00 2001 >> From: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> Date: Sat, 15 Aug 2015 16:58:45 -0300 >> Subject: [PATCH] Fixed options parameter name enable-nat-ftp-support. >> >> >> Signed-off-by: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> --- >> src/openvpn/options.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/src/openvpn/options.c b/src/openvpn/options.c >> index 73b615a..1a012e4 100755 >> --- a/src/openvpn/options.c >> +++ b/src/openvpn/options.c >> @@ -5295,7 +5295,7 @@ add_option (struct options *options, >> cnol_check_alloc (options); >> add_client_nat_to_option_list(options->client_nat, p[1], p[2], >> p[3], p[4], msglevel); >> } >> - else if (streq (p[0], "enable_nat_ftp_support")) >> + else if (streq (p[0], "enable-nat-ftp-support")) >> { >> options->enable_nat_ftp_support = true; >> } >> -- >> 1.7.9.5 >> >> >> From 2f5ac96c0c2c5d9d06a11e0b08ae958e09c2e9b5 Mon Sep 17 00:00:00 2001 >> From: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> Date: Mon, 24 Aug 2015 09:15:34 -0300 >> Subject: [PATCH] Allows set yes/no option to enable-nat-ftp-support >> feature. >> >> >> Signed-off-by: Rafael Gava <rafael.olive...@venturus.org.br <mailto: >> rafael.olive...@venturus.org.br>> >> >> --- >> src/openvpn/options.c | 21 +++++++++++++++++++-- >> 1 file changed, 19 insertions(+), 2 deletions(-) >> >> diff --git a/src/openvpn/options.c b/src/openvpn/options.c >> index 1a012e4..4d73d87 100755 >> --- a/src/openvpn/options.c >> +++ b/src/openvpn/options.c >> @@ -236,7 +236,9 @@ static const char usage_message[] = >> " the default gateway. Useful when pushing private >> subnets.\n" >> #ifdef ENABLE_CLIENT_NAT >> "--client-nat snat|dnat network netmask alias : on client add 1-to-1 >> NAT rule.\n" >> - "--enable-nat-ftp-support : Enable NAT FTP Support, updating the IP >> address on FTP PORT commands or PASV responses\n" + >> "--enable-nat-ftp-support : Enable NAT FTP Support, replacing the IP >> address on FTP PORT commands or PASV responses?\n" + " >> 'no' -- No, disable this feature.\n" >> + " 'yes' -- Yes, enable this feature (Enabled by >> default on Windows).\n" >> #endif >> #ifdef ENABLE_PUSH_PEER_INFO >> "--push-peer-info : (client only) push client info to server.\n" >> @@ -792,8 +794,12 @@ init_options (struct options *o, const bool init_gc) >> o->proto_force = -1; >> #ifdef ENABLE_CLIENT_NAT >> +#ifdef WIN32 >> + o->enable_nat_ftp_support = true; >> +#else >> o->enable_nat_ftp_support = false; >> #endif >> +#endif >> #ifdef ENABLE_OCC >> o->occ = true; >> @@ -5297,7 +5303,18 @@ add_option (struct options *options, >> } >> else if (streq (p[0], "enable-nat-ftp-support")) >> { >> - options->enable_nat_ftp_support = true; >> + if (p[1]) >> + { >> + if (streq (p[1], "yes")) >> + options->enable_nat_ftp_support = true; >> + else if (streq (p[1], "no")) >> + options->enable_nat_ftp_support = false; >> + else >> + { >> + msg (msglevel, "bad enable-nat-ftp-support option: %s -- >> must be 'yes' or 'no'", p[1]); >> + goto err; >> + } >> + } >> } >> #endif >> else if (streq (p[0], "route") && p[1]) >> -- >> 1.7.9.5 >> >> >> ------------------------------------------------------------------------ >> >> >> ------------------------------------------------------------------------------ >> ------------------------------------------------------------------------ >> >> _______________________________________________ >> Openvpn-devel mailing list >> Openvpn-devel@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/openvpn-devel >> >> > >