repl_ftp_v4_addr(struct dp_packet *pkt, ovs_be32 v4_addr_rep,
                 char *ftp_data_start,
                 size_t addr_offset_from_ftp_data_start)
{
    enum { MAX_FTP_V4_NAT_DELTA = 8 };

    /* Do conservative check for pathological MTU usage. */
    uint32_t orig_used_size = dp_packet_size(pkt);
    uint16_t allocated_size = dp_packet_get_allocated(pkt);
    if (orig_used_size + MAX_FTP_V4_NAT_DELTA > allocated_size) {
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
        VLOG_WARN_RL(&rl, "Unsupported effective MTU %u used with FTP",
                     allocated_size);
        return 0;
    }

    size_t remain_size = tcp_payload_length(pkt) -
                             addr_offset_from_ftp_data_start;

    int overall_delta = 0;
    char *byte_str = ftp_data_start + addr_offset_from_ftp_data_start;

    /* Replace the existing IPv4 address by the new one. */
    for (uint8_t i = 0; i < 4; i++) {
        /* Find the end of the string for this octet. */
        char *next_delim = memchr(byte_str, ',', 4);
        ovs_assert(next_delim);
        int substr_size = next_delim - byte_str;
        remain_size -= substr_size;

        /* Compose the new string for this octet, and replace it. */
        char rep_str[4];
        uint8_t rep_byte = get_v4_byte_be(v4_addr_rep, i);
        int replace_size = sprintf(rep_str, "%d", rep_byte);
        replace_substring(byte_str, substr_size, remain_size,
                          rep_str, replace_size);
        overall_delta += replace_size - substr_size;

        /* Advance past the octet and the following comma. */
        byte_str += replace_size + 1;
    }

    dp_packet_set_size(pkt, orig_used_size + overall_delta);
    return overall_delta;
}
repl_ftp_v4_addr(struct dp_packet *pkt, ovs_be32 v4_addr_rep,
                 char *ftp_data_start,
                 size_t addr_offset_from_ftp_data_start)
{
    enum { MAX_FTP_V4_NAT_DELTA = 8 };

     
    uint32_t orig_used_size = dp_packet_size(pkt);
    uint16_t allocated_size = dp_packet_get_allocated(pkt);
    if (orig_used_size + MAX_FTP_V4_NAT_DELTA > allocated_size) {
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
        VLOG_WARN_RL(&rl, "Unsupported effective MTU %u used with FTP",
                     allocated_size);
        return 0;
    }

    size_t remain_size = tcp_payload_length(pkt) -
                             addr_offset_from_ftp_data_start;

    int overall_delta = 0;
    char *byte_str = ftp_data_start + addr_offset_from_ftp_data_start;

     
    for (uint8_t i = 0; i < 4; i++) {
         
        char *next_delim = memchr(byte_str, ',', 4);
        ovs_assert(next_delim);
        int substr_size = next_delim - byte_str;
        remain_size -= substr_size;

         
        char rep_str[4];
        uint8_t rep_byte = get_v4_byte_be(v4_addr_rep, i);
        int replace_size = sprintf(rep_str, "%d", rep_byte);
        replace_substring(byte_str, substr_size, remain_size,
                          rep_str, replace_size);
        overall_delta += replace_size - substr_size;

         
        byte_str += replace_size + 1;
    }

    dp_packet_set_size(pkt, orig_used_size + overall_delta);
    return overall_delta;
}