void eth_get_protocols(const struct iovec *iov, int iovcnt,

                       bool *isip4, bool *isip6,

                       bool *isudp, bool *istcp,

                       size_t *l3hdr_off,

                       size_t *l4hdr_off,

                       size_t *l5hdr_off,

                       eth_ip6_hdr_info *ip6hdr_info,

                       eth_ip4_hdr_info *ip4hdr_info,

                       eth_l4_hdr_info  *l4hdr_info)

{

    int proto;

    bool fragment = false;

    size_t l2hdr_len = eth_get_l2_hdr_length_iov(iov, iovcnt);

    size_t input_size = iov_size(iov, iovcnt);

    size_t copied;



    *isip4 = *isip6 = *isudp = *istcp = false;



    proto = eth_get_l3_proto(iov, iovcnt, l2hdr_len);



    *l3hdr_off = l2hdr_len;



    if (proto == ETH_P_IP) {

        struct ip_header *iphdr = &ip4hdr_info->ip4_hdr;



        if (input_size < l2hdr_len) {

            return;

        }



        copied = iov_to_buf(iov, iovcnt, l2hdr_len, iphdr, sizeof(*iphdr));



        *isip4 = true;



        if (copied < sizeof(*iphdr)) {

            return;

        }



        if (IP_HEADER_VERSION(iphdr) == IP_HEADER_VERSION_4) {

            if (iphdr->ip_p == IP_PROTO_TCP) {

                *istcp = true;

            } else if (iphdr->ip_p == IP_PROTO_UDP) {

                *isudp = true;

            }

        }



        ip4hdr_info->fragment = IP4_IS_FRAGMENT(iphdr);

        *l4hdr_off = l2hdr_len + IP_HDR_GET_LEN(iphdr);



        fragment = ip4hdr_info->fragment;

    } else if (proto == ETH_P_IPV6) {



        *isip6 = true;

        if (eth_parse_ipv6_hdr(iov, iovcnt, l2hdr_len,

                               ip6hdr_info)) {

            if (ip6hdr_info->l4proto == IP_PROTO_TCP) {

                *istcp = true;

            } else if (ip6hdr_info->l4proto == IP_PROTO_UDP) {

                *isudp = true;

            }

        } else {

            return;

        }



        *l4hdr_off = l2hdr_len + ip6hdr_info->full_hdr_len;

        fragment = ip6hdr_info->fragment;

    }



    if (!fragment) {

        if (*istcp) {

            *istcp = _eth_copy_chunk(input_size,

                                     iov, iovcnt,

                                     *l4hdr_off, sizeof(l4hdr_info->hdr.tcp),

                                     &l4hdr_info->hdr.tcp);



            if (istcp) {

                *l5hdr_off = *l4hdr_off +

                    TCP_HEADER_DATA_OFFSET(&l4hdr_info->hdr.tcp);



                l4hdr_info->has_tcp_data =

                    _eth_tcp_has_data(proto == ETH_P_IP,

                                      &ip4hdr_info->ip4_hdr,

                                      &ip6hdr_info->ip6_hdr,

                                      *l4hdr_off - *l3hdr_off,

                                      &l4hdr_info->hdr.tcp);

            }

        } else if (*isudp) {

            *isudp = _eth_copy_chunk(input_size,

                                     iov, iovcnt,

                                     *l4hdr_off, sizeof(l4hdr_info->hdr.udp),

                                     &l4hdr_info->hdr.udp);

            *l5hdr_off = *l4hdr_off + sizeof(l4hdr_info->hdr.udp);

        }

    }

}

void eth_get_protocols(const struct iovec *iov, int iovcnt,

                       bool *isip4, bool *isip6,

                       bool *isudp, bool *istcp,

                       size_t *l3hdr_off,

                       size_t *l4hdr_off,

                       size_t *l5hdr_off,

                       eth_ip6_hdr_info *ip6hdr_info,

                       eth_ip4_hdr_info *ip4hdr_info,

                       eth_l4_hdr_info  *l4hdr_info)

{

    int proto;

    bool fragment = false;

    size_t l2hdr_len = eth_get_l2_hdr_length_iov(iov, iovcnt);

    size_t input_size = iov_size(iov, iovcnt);

    size_t copied;



    *isip4 = *isip6 = *isudp = *istcp = false;



    proto = eth_get_l3_proto(iov, iovcnt, l2hdr_len);



    *l3hdr_off = l2hdr_len;



    if (proto == ETH_P_IP) {

        struct ip_header *iphdr = &ip4hdr_info->ip4_hdr;



        if (input_size < l2hdr_len) {

            return;

        }



        copied = iov_to_buf(iov, iovcnt, l2hdr_len, iphdr, sizeof(*iphdr));



        *isip4 = true;



        if (copied < sizeof(*iphdr)) {

            return;

        }



        if (IP_HEADER_VERSION(iphdr) == IP_HEADER_VERSION_4) {

            if (iphdr->ip_p == IP_PROTO_TCP) {

                *istcp = true;

            } else if (iphdr->ip_p == IP_PROTO_UDP) {

                *isudp = true;

            }

        }



        ip4hdr_info->fragment = IP4_IS_FRAGMENT(iphdr);

        *l4hdr_off = l2hdr_len + IP_HDR_GET_LEN(iphdr);



        fragment = ip4hdr_info->fragment;

    } else if (proto == ETH_P_IPV6) {



        *isip6 = true;

        if (eth_parse_ipv6_hdr(iov, iovcnt, l2hdr_len,

                               ip6hdr_info)) {

            if (ip6hdr_info->l4proto == IP_PROTO_TCP) {

                *istcp = true;

            } else if (ip6hdr_info->l4proto == IP_PROTO_UDP) {

                *isudp = true;

            }

        } else {

            return;

        }



        *l4hdr_off = l2hdr_len + ip6hdr_info->full_hdr_len;

        fragment = ip6hdr_info->fragment;

    }



    if (!fragment) {

        if (*istcp) {

            *istcp = _eth_copy_chunk(input_size,

                                     iov, iovcnt,

                                     *l4hdr_off, sizeof(l4hdr_info->hdr.tcp),

                                     &l4hdr_info->hdr.tcp);



            if (istcp) {

                *l5hdr_off = *l4hdr_off +

                    TCP_HEADER_DATA_OFFSET(&l4hdr_info->hdr.tcp);



                l4hdr_info->has_tcp_data =

                    _eth_tcp_has_data(proto == ETH_P_IP,

                                      &ip4hdr_info->ip4_hdr,

                                      &ip6hdr_info->ip6_hdr,

                                      *l4hdr_off - *l3hdr_off,

                                      &l4hdr_info->hdr.tcp);

            }

        } else if (*isudp) {

            *isudp = _eth_copy_chunk(input_size,

                                     iov, iovcnt,

                                     *l4hdr_off, sizeof(l4hdr_info->hdr.udp),

                                     &l4hdr_info->hdr.udp);

            *l5hdr_off = *l4hdr_off + sizeof(l4hdr_info->hdr.udp);

        }

    }

}

void FUNC_0(const struct iovec *VAR_0, int VAR_1,

                       bool *VAR_2, bool *VAR_3,

                       bool *VAR_4, bool *VAR_5,

                       size_t *VAR_6,

                       size_t *VAR_7,

                       size_t *VAR_8,

                       eth_ip6_hdr_info *VAR_9,

                       eth_ip4_hdr_info *VAR_10,

                       eth_l4_hdr_info  *VAR_11)

{

    int VAR_12;

    bool fragment = false;

    size_t l2hdr_len = eth_get_l2_hdr_length_iov(VAR_0, VAR_1);

    size_t input_size = iov_size(VAR_0, VAR_1);

    size_t copied;



    *VAR_2 = *VAR_3 = *VAR_4 = *VAR_5 = false;



    VAR_12 = eth_get_l3_proto(VAR_0, VAR_1, l2hdr_len);



    *VAR_6 = l2hdr_len;



    if (VAR_12 == ETH_P_IP) {

        struct ip_header *VAR_13 = &VAR_10->ip4_hdr;



        if (input_size < l2hdr_len) {

            return;

        }



        copied = iov_to_buf(VAR_0, VAR_1, l2hdr_len, VAR_13, sizeof(*VAR_13));



        *VAR_2 = true;



        if (copied < sizeof(*VAR_13)) {

            return;

        }



        if (IP_HEADER_VERSION(VAR_13) == IP_HEADER_VERSION_4) {

            if (VAR_13->ip_p == IP_PROTO_TCP) {

                *VAR_5 = true;

            } else if (VAR_13->ip_p == IP_PROTO_UDP) {

                *VAR_4 = true;

            }

        }



        VAR_10->fragment = IP4_IS_FRAGMENT(VAR_13);

        *VAR_7 = l2hdr_len + IP_HDR_GET_LEN(VAR_13);



        fragment = VAR_10->fragment;

    } else if (VAR_12 == ETH_P_IPV6) {



        *VAR_3 = true;

        if (eth_parse_ipv6_hdr(VAR_0, VAR_1, l2hdr_len,

                               VAR_9)) {

            if (VAR_9->l4proto == IP_PROTO_TCP) {

                *VAR_5 = true;

            } else if (VAR_9->l4proto == IP_PROTO_UDP) {

                *VAR_4 = true;

            }

        } else {

            return;

        }



        *VAR_7 = l2hdr_len + VAR_9->full_hdr_len;

        fragment = VAR_9->fragment;

    }



    if (!fragment) {

        if (*VAR_5) {

            *VAR_5 = _eth_copy_chunk(input_size,

                                     VAR_0, VAR_1,

                                     *VAR_7, sizeof(VAR_11->hdr.tcp),

                                     &VAR_11->hdr.tcp);



            if (VAR_5) {

                *VAR_8 = *VAR_7 +

                    TCP_HEADER_DATA_OFFSET(&VAR_11->hdr.tcp);



                VAR_11->has_tcp_data =

                    _eth_tcp_has_data(VAR_12 == ETH_P_IP,

                                      &VAR_10->ip4_hdr,

                                      &VAR_9->ip6_hdr,

                                      *VAR_7 - *VAR_6,

                                      &VAR_11->hdr.tcp);

            }

        } else if (*VAR_4) {

            *VAR_4 = _eth_copy_chunk(input_size,

                                     VAR_0, VAR_1,

                                     *VAR_7, sizeof(VAR_11->hdr.udp),

                                     &VAR_11->hdr.udp);

            *VAR_8 = *VAR_7 + sizeof(VAR_11->hdr.udp);

        }

    }

}

void FUNC_0(const struct iovec *VAR_0, int VAR_1,
bool *VAR_2, bool *VAR_3,
bool *VAR_4, bool *VAR_5,
size_t *VAR_6,
size_t *VAR_7,
size_t *VAR_8,
eth_ip6_hdr_info *VAR_9,
eth_ip4_hdr_info *VAR_10,
eth_l4_hdr_info  *VAR_11)
{ int VAR_12; bool fragment = false; size_t l2hdr_len = eth_get_l2_hdr_length_iov(VAR_0, VAR_1); size_t input_size = iov_size(VAR_0, VAR_1); size_t copied; *VAR_2 = *VAR_3 = *VAR_4 = *VAR_5 = false; VAR_12 = eth_get_l3_proto(VAR_0, VAR_1, l2hdr_len); *VAR_6 = l2hdr_len; if (VAR_12 == ETH_P_IP) { struct ip_header *VAR_13 = &VAR_10->ip4_hdr; if (input_size < l2hdr_len) { return; } copied = iov_to_buf(VAR_0, VAR_1, l2hdr_len, VAR_13, sizeof(*VAR_13)); *VAR_2 = true; if (copied < sizeof(*VAR_13)) { return; } if (IP_HEADER_VERSION(VAR_13) == IP_HEADER_VERSION_4) { if (VAR_13->ip_p == IP_PROTO_TCP) { *VAR_5 = true; } else if (VAR_13->ip_p == IP_PROTO_UDP) { *VAR_4 = true; } } VAR_10->fragment = IP4_IS_FRAGMENT(VAR_13); *VAR_7 = l2hdr_len + IP_HDR_GET_LEN(VAR_13); fragment = VAR_10->fragment; } else if (VAR_12 == ETH_P_IPV6) { *VAR_3 = true; if (eth_parse_ipv6_hdr(VAR_0, VAR_1, l2hdr_len,
VAR_9)) { if (VAR_9->l4proto == IP_PROTO_TCP) { *VAR_5 = true; } else if (VAR_9->l4proto == IP_PROTO_UDP) { *VAR_4 = true; } } else { return; } *VAR_7 = l2hdr_len + VAR_9->full_hdr_len; fragment = VAR_9->fragment; } if (!fragment) { if (*VAR_5) { *VAR_5 = _eth_copy_chunk(input_size,
VAR_0, VAR_1,
*VAR_7, sizeof(VAR_11->hdr.tcp),
&VAR_11->hdr.tcp); if (VAR_5) { *VAR_8 = *VAR_7 +
TCP_HEADER_DATA_OFFSET(&VAR_11->hdr.tcp); VAR_11->has_tcp_data =
_eth_tcp_has_data(VAR_12 == ETH_P_IP,
&VAR_10->ip4_hdr,
&VAR_9->ip6_hdr,
*VAR_7 - *VAR_6,
&VAR_11->hdr.tcp); } } else if (*VAR_4) { *VAR_4 = _eth_copy_chunk(input_size,
VAR_0, VAR_1,
*VAR_7, sizeof(VAR_11->hdr.udp),
&VAR_11->hdr.udp); *VAR_8 = *VAR_7 + sizeof(VAR_11->hdr.udp); } } }