• opendpi 源码分析(一)


    先贴会有用的相关内容:

    struct iphdr {
    #if BYTE_ORDER == LITTLE_ENDIAN
    uint8_t ihl:
    4, version:4;
    #elif BYTE_ORDER == BIG_ENDIAN
    uint8_t version:
    4, ihl:4;
    #else
    # error
    "BYTE_ORDER must be defined"
    #endif
    uint8_t tos;
    uint16_t tot_len;
    uint16_t id;
    uint16_t frag_off;
    uint8_t ttl;
    uint8_t protocol;
    uint16_t check;
    uint32_t saddr;
    uint32_t daddr;
    };

    因为dpi是对包处理,所以这个数据结构很重要。

    #define IPOQUE_USE_ASYMMETRIC_DETECTION 0
    #define IPQ_SELECTION_BITMASK_PROTOCOL_SIZE u32

    #define IPQ_SELECTION_BITMASK_PROTOCOL_IP (1<<0)
    #define IPQ_SELECTION_BITMASK_PROTOCOL_INT_TCP (1<<1)
    #define IPQ_SELECTION_BITMASK_PROTOCOL_INT_UDP (1<<2)
    #define IPQ_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP (1<<3)
    #define IPQ_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD (1<<4)
    #define IPQ_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION (1<<5)
    #define IPQ_SELECTION_BITMASK_PROTOCOL_IPV6 (1<<6)
    #define IPQ_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6 (1<<7)
    #define IPQ_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC (1<<8)


    #define IPOQUE_SAVE_AS_BITMASK(bitmask,value) (bitmask)=(((IPOQUE_PROTOCOL_BITMASK)1)<<(value))
    #define IPOQUE_BITMASK_COMPARE(a,b) ((a) & (b))
    #define IPOQUE_BITMASK_MATCH(x,y) ((x) == (y))

    #define IPOQUE_PROTOCOL_BITMASK u64

    一些用用的宏,标识包的协议

    typedef struct ipoque_packet_struct {
    const struct iphdr *iph;
    const struct tcphdr *tcp;
    const struct udphdr *udp;
    const u8 *generic_l4_ptr; /* is set only for non tcp-udp traffic */
    const u8 *payload;

    IPOQUE_TIMESTAMP_COUNTER_SIZE tick_timestamp;


    u32 detected_protocol;

    struct ipoque_int_one_line_struct line[IPOQUE_MAX_PARSE_LINES_PER_PACKET];
    struct ipoque_int_one_line_struct
    unix_line[IPOQUE_MAX_PARSE_LINES_PER_PACKET];
    struct ipoque_int_one_line_struct host_line;
    struct ipoque_int_one_line_struct referer_line;
    struct ipoque_int_one_line_struct content_line;
    struct ipoque_int_one_line_struct accept_line;
    struct ipoque_int_one_line_struct user_agent_line;
    struct ipoque_int_one_line_struct http_url_name;
    struct ipoque_int_one_line_struct http_encoding;
    struct ipoque_int_one_line_struct http_transfer_encoding;
    struct ipoque_int_one_line_struct http_contentlen;
    struct ipoque_int_one_line_struct http_cookie;
    struct ipoque_int_one_line_struct http_x_session_type;


    u16 l3_packet_len;
    u16 l4_packet_len;
    u16 payload_packet_len;
    u16 actual_payload_len;
    u16 num_retried_bytes;
    u16 parsed_lines;
    u16 parsed_unix_lines;
    u16 empty_line_position;
    u8 tcp_retransmission;
    u8 detected_sub_protocol;
    u8 l4_protocol;

    u8 packet_lines_parsed_complete;
    u8 packet_unix_lines_parsed_complete;
    u8 empty_line_position_set;
    u8 packet_direction:
    1;
    }ipoque_packet_struct_t;

    这是对数据包处理所需要的结构体,实际上opendpi中有一个数据结构为struct ipoque_detection_module_struct 是对所有的

    包和flow 处理的。

    从例子程序中运行情况看:

    第一步:

    static unsigned int packet_processing(const uint64_t time, const struct iphdr *iph, uint16_t ipsize, uint16_t rawsize)

    进行包处理,其中调用get_osdpi_flow()函数    从数据包中取出里IP首部等相关信息。

    第二步:调用

    ipoque_detection_process_packet(ipoque_struct, ipq_flow, (uint8_t *) iph, ipsize, time, src, dst);

    正式地处理每个数据包,其中调用 ipoque_connection_tracking()函数 设置了包的连接信息,这个函数还没怎么看明白,明天在详细看。

    第三步:在ipoque_detection_process_packet中使用如下来处理具体协议:

    /* build ipq_selction packet bitmask */
    ipq_selection_packet
    = IPQ_SELECTION_BITMASK_PROTOCOL_COMPLETE_TRAFFIC;
    if (ipoque_struct->packet.iph != NULL) {
    ipq_selection_packet
    |= IPQ_SELECTION_BITMASK_PROTOCOL_IP | IPQ_SELECTION_BITMASK_PROTOCOL_IPV4_OR_IPV6;

    }
    if (ipoque_struct->packet.tcp != NULL) {
    ipq_selection_packet
    |=
    (IPQ_SELECTION_BITMASK_PROTOCOL_INT_TCP
    | IPQ_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);

    }
    if (ipoque_struct->packet.udp != NULL) {
    ipq_selection_packet
    |=
    (IPQ_SELECTION_BITMASK_PROTOCOL_INT_UDP
    | IPQ_SELECTION_BITMASK_PROTOCOL_INT_TCP_OR_UDP);
    }
    if (ipoque_struct->packet.payload_packet_len != 0) {
    ipq_selection_packet
    |= IPQ_SELECTION_BITMASK_PROTOCOL_HAS_PAYLOAD;
    }

    if (ipoque_struct->packet.tcp_retransmission == 0) {
    ipq_selection_packet
    |= IPQ_SELECTION_BITMASK_PROTOCOL_NO_TCP_RETRANSMISSION;

    }


    IPOQUE_SAVE_AS_BITMASK(detection_bitmask, ipoque_struct
    ->packet.detected_protocol);

    在如下代码中调用了http.c等匹配信息对包进行具体处理。

    if (flow != NULL && ipoque_struct->packet.tcp != NULL) {
    if (ipoque_struct->packet.payload_packet_len != 0) {
    for (a = 0; a < ipoque_struct->callback_buffer_size_tcp_payload; a++) {
    if ((ipoque_struct->callback_buffer_tcp_payload[a].ipq_selection_bitmask & ipq_selection_packet) ==
    ipoque_struct
    ->callback_buffer_tcp_payload[a].ipq_selection_bitmask
    && IPOQUE_BITMASK_COMPARE(ipoque_struct->flow->excluded_protocol_bitmask,
    ipoque_struct
    ->callback_buffer_tcp_payload[a].excluded_protocol_bitmask) == 0
    && IPOQUE_BITMASK_COMPARE(ipoque_struct->callback_buffer_tcp_payload[a].detection_bitmask,
    detection_bitmask)
    != 0) {
    ipoque_struct
    ->callback_buffer_tcp_payload[a].func(ipoque_struct);
    }
    }

    这就是对一个包处理的过程,明天在细节上看看。

    我还不懂,希望大家指教。

  • 相关阅读:
    ES6:Iterator遍历器
    前端:对BFC的理解
    前端:性能优化之防抖与节流
    ES6新增数据类型Symbol
    ajax和fetch、aixos的区别
    我对js数据类型的理解和深浅(copy)的应用场景
    egg的基本使用
    前端:css3的过渡与动画的基础知识
    Java基础篇之类
    JAVA基础篇之Scanner
  • 原文地址:https://www.cnblogs.com/lxgeek/p/2020164.html
Copyright © 2020-2023  润新知