ZBLOG

具体分析一下这段代码 static enum ftp_ctl_pkt process_ftp_ctl_v6(struct conntrack *ct, struct dp_packet *pkt, const struct conn *conn_for_expectation, struct ct_addr *v6_addr_rep, ch...

这段代码是一个处理FTP数据包的函数,根据不同的FTP控制命令和模式进行相应的处理。具体分析如下:

  1. 获取TCP头部信息
struct tcp_header *th = dp_packet_l4(pkt);
size_t tcp_hdr_len = TCP_OFFSET(th->tcp_ctl) * 4;
char *tcp_hdr = (char *) th;

通过dp_packet_l4()函数获取TCP头部信息,并计算TCP头部长度。

  1. 获取FTP控制命令信息
char ftp_msg[LARGEST_FTP_MSG_OF_INTEREST + 1] = {0};
get_ftp_ctl_msg(pkt, ftp_msg);

调用get_ftp_ctl_msg()函数,将pkt中的FTP控制命令信息存入ftp_msg中。

  1. 根据不同的控制命令和模式进行处理
if (!strncasecmp(ftp, FTP_EPRT_CMD, strlen(FTP_EPRT_CMD))) {
    // ACTIVE模式
} else {
    // PASSIVE模式
}

对于ACTIVE模式,先判断命令是否为EPRT,如果是则继续解析IP地址和端口号,并设置模式为ACTIVE。对于PASSIVE模式,则直接设置模式为PASSIVE。

  1. 解析IP地址和端口号
if (*ftp != FTP_AF_V6 || isdigit(ftp[1])) {
    return CT_FTP_CTL_INVALID;
}

/* Jump over delimiter. */
ftp += 2;

memset(&ip6_addr, 0, sizeof ip6_addr);
char *ip_addr_start = ftp;
*addr_offset_from_ftp_data_start = ip_addr_start - ftp_msg;
ftp = skip_ipv6_digits(ftp);
*ftp = 0;
*addr_size = ftp - ip_addr_start;
int rc2 = inet_pton(AF_INET6, ip_addr_start, &ip6_addr);
if (rc2 != 1) {
    return CT_FTP_CTL_INVALID;
}
ftp++;

对于ACTIVE模式,先判断IP地址是否为IPv6类型,并跳过分隔符。然后通过inet_pton()函数将IP地址转换为二进制格式,存储在ip6_addr中。

char *save_ftp = ftp;
ftp = terminate_number_str(ftp, MAX_EXT_FTP_PORT_DGTS);
if (!ftp) {
    return CT_FTP_CTL_INVALID;
}

int value;
if (!str_to_int(save_ftp, 10, &value)) {
    return CT_FTP_CTL_INVALID;
}
if (value > CT_MAX_L4_PORT) {
    return CT_FTP_CTL_INVALID;
}

uint16_t port_hs = value;
ovs_be16 port = htons(port_hs);

接着解析端口号,并将其转换为网络字节序存储在port中。

  1. 根据模式获取地址
switch (*mode) {
case CT_FTP_MODE_ACTIVE:
    *v6_addr_rep = conn_for_expectation->rev_key.dst.addr;
    if (memcmp(&ip6_addr, &v6_addr_rep->ipv6_aligned, sizeof ip6_addr) &&
        memcmp(&ip6_addr, &conn_for_expectation->key.src.addr.ipv6_aligned,
               sizeof ip6_addr)) {
        return CT_FTP_CTL_INVALID;
    }
    break;
case CT_FTP_MODE_PASSIVE:
    *v6_addr_rep = conn_for_expectation->key.dst.addr;
    break;
case CT_TFTP_MODE:
default:
    OVS_NOT_REACHED();
}

根据模式获取地址,对于ACTIVE模式,从期望连接的反向地址中获取;对于PASSIVE模式,则从期望连接的目标地址中获取。

  1. 创建期望连接
expectation_create(ct, port, conn_for_expectation,
                   !!(pkt->md.ct_state & CS_REPLY_DIR), false, false);

最后调用expectation_create()函数创建期望连接。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=417

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?