|
@@ -136,7 +136,7 @@ _eth_tcp_has_data(bool is_ip4,
|
|
return l4len > TCP_HEADER_DATA_OFFSET(tcp);
|
|
return l4len > TCP_HEADER_DATA_OFFSET(tcp);
|
|
}
|
|
}
|
|
|
|
|
|
-void eth_get_protocols(const struct iovec *iov, int iovcnt,
|
|
|
|
|
|
+void eth_get_protocols(const struct iovec *iov, size_t iovcnt, size_t iovoff,
|
|
bool *hasip4, bool *hasip6,
|
|
bool *hasip4, bool *hasip6,
|
|
size_t *l3hdr_off,
|
|
size_t *l3hdr_off,
|
|
size_t *l4hdr_off,
|
|
size_t *l4hdr_off,
|
|
@@ -147,26 +147,24 @@ void eth_get_protocols(const struct iovec *iov, int iovcnt,
|
|
{
|
|
{
|
|
int proto;
|
|
int proto;
|
|
bool fragment = false;
|
|
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 input_size = iov_size(iov, iovcnt);
|
|
size_t copied;
|
|
size_t copied;
|
|
uint8_t ip_p;
|
|
uint8_t ip_p;
|
|
|
|
|
|
*hasip4 = *hasip6 = false;
|
|
*hasip4 = *hasip6 = false;
|
|
|
|
+ *l3hdr_off = iovoff + eth_get_l2_hdr_length_iov(iov, iovcnt, iovoff);
|
|
l4hdr_info->proto = ETH_L4_HDR_PROTO_INVALID;
|
|
l4hdr_info->proto = ETH_L4_HDR_PROTO_INVALID;
|
|
|
|
|
|
- proto = eth_get_l3_proto(iov, iovcnt, l2hdr_len);
|
|
|
|
-
|
|
|
|
- *l3hdr_off = l2hdr_len;
|
|
|
|
|
|
+ proto = eth_get_l3_proto(iov, iovcnt, *l3hdr_off);
|
|
|
|
|
|
if (proto == ETH_P_IP) {
|
|
if (proto == ETH_P_IP) {
|
|
struct ip_header *iphdr = &ip4hdr_info->ip4_hdr;
|
|
struct ip_header *iphdr = &ip4hdr_info->ip4_hdr;
|
|
|
|
|
|
- if (input_size < l2hdr_len) {
|
|
|
|
|
|
+ if (input_size < *l3hdr_off) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- copied = iov_to_buf(iov, iovcnt, l2hdr_len, iphdr, sizeof(*iphdr));
|
|
|
|
|
|
+ copied = iov_to_buf(iov, iovcnt, *l3hdr_off, iphdr, sizeof(*iphdr));
|
|
if (copied < sizeof(*iphdr) ||
|
|
if (copied < sizeof(*iphdr) ||
|
|
IP_HEADER_VERSION(iphdr) != IP_HEADER_VERSION_4) {
|
|
IP_HEADER_VERSION(iphdr) != IP_HEADER_VERSION_4) {
|
|
return;
|
|
return;
|
|
@@ -175,17 +173,17 @@ void eth_get_protocols(const struct iovec *iov, int iovcnt,
|
|
*hasip4 = true;
|
|
*hasip4 = true;
|
|
ip_p = iphdr->ip_p;
|
|
ip_p = iphdr->ip_p;
|
|
ip4hdr_info->fragment = IP4_IS_FRAGMENT(iphdr);
|
|
ip4hdr_info->fragment = IP4_IS_FRAGMENT(iphdr);
|
|
- *l4hdr_off = l2hdr_len + IP_HDR_GET_LEN(iphdr);
|
|
|
|
|
|
+ *l4hdr_off = *l3hdr_off + IP_HDR_GET_LEN(iphdr);
|
|
|
|
|
|
fragment = ip4hdr_info->fragment;
|
|
fragment = ip4hdr_info->fragment;
|
|
} else if (proto == ETH_P_IPV6) {
|
|
} else if (proto == ETH_P_IPV6) {
|
|
- if (!eth_parse_ipv6_hdr(iov, iovcnt, l2hdr_len, ip6hdr_info)) {
|
|
|
|
|
|
+ if (!eth_parse_ipv6_hdr(iov, iovcnt, *l3hdr_off, ip6hdr_info)) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
*hasip6 = true;
|
|
*hasip6 = true;
|
|
ip_p = ip6hdr_info->l4proto;
|
|
ip_p = ip6hdr_info->l4proto;
|
|
- *l4hdr_off = l2hdr_len + ip6hdr_info->full_hdr_len;
|
|
|
|
|
|
+ *l4hdr_off = *l3hdr_off + ip6hdr_info->full_hdr_len;
|
|
fragment = ip6hdr_info->fragment;
|
|
fragment = ip6hdr_info->fragment;
|
|
} else {
|
|
} else {
|
|
return;
|
|
return;
|