net: tcp2: Add support for a IPv6
In order to support IPv4/IPv6, work with packet through net_pkt_ip_hdr_len(), net_pkt_ip_opts_len() which account for IPv4/IPv6, IPv4 options and IPv6 extension headers. Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
This commit is contained in:
parent
6be5935f17
commit
f5c1ee03b8
1 changed files with 20 additions and 45 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2019 Intel Corporation
|
* Copyright (c) 2018-2020 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -31,6 +31,7 @@ static K_MEM_SLAB_DEFINE(tcp_conns_slab, sizeof(struct tcp),
|
||||||
NET_BUF_POOL_DEFINE(tcp_nbufs, 64/*count*/, CONFIG_NET_BUF_DATA_SIZE, 0, NULL);
|
NET_BUF_POOL_DEFINE(tcp_nbufs, 64/*count*/, CONFIG_NET_BUF_DATA_SIZE, 0, NULL);
|
||||||
|
|
||||||
static void tcp_in(struct tcp *conn, struct net_pkt *pkt);
|
static void tcp_in(struct tcp *conn, struct net_pkt *pkt);
|
||||||
|
static size_t tcp_data_len(struct net_pkt *pkt);
|
||||||
|
|
||||||
int (*tcp_send_cb)(struct net_pkt *pkt) = NULL;
|
int (*tcp_send_cb)(struct net_pkt *pkt) = NULL;
|
||||||
|
|
||||||
|
@ -77,40 +78,19 @@ static void tcp_nbufs_unreserve(struct tcp *conn)
|
||||||
NET_DBG("%zu->%zu", rsv_bytes_old, conn->rsv_bytes);
|
NET_DBG("%zu->%zu", rsv_bytes_old, conn->rsv_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: IPv4 options may enlarge the IPv4 header */
|
|
||||||
static struct tcphdr *th_get(struct net_pkt *pkt)
|
static struct tcphdr *th_get(struct net_pkt *pkt)
|
||||||
{
|
{
|
||||||
struct tcphdr *th = NULL;
|
NET_PKT_DATA_ACCESS_DEFINE(th_access, struct tcphdr);
|
||||||
ssize_t len;
|
|
||||||
|
|
||||||
if (pkt == NULL) {
|
net_pkt_cursor_init(pkt);
|
||||||
goto out;
|
net_pkt_set_overwrite(pkt, true);
|
||||||
}
|
|
||||||
|
|
||||||
len = net_pkt_get_len(pkt);
|
/* net_pkt_ip_hdr_len(), net_pkt_ip_opts_len() account for IPv4/IPv6 */
|
||||||
|
|
||||||
switch (pkt->family) {
|
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
||||||
case AF_INET:
|
net_pkt_ip_opts_len(pkt));
|
||||||
if (len < (sizeof(struct net_ipv4_hdr) +
|
|
||||||
sizeof(struct tcphdr))) {
|
return net_pkt_get_data(pkt, &th_access);
|
||||||
NET_WARN("Undersized IPv4 packet: %zd byte(s)", len);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
th = (struct tcphdr *)(ip_get(pkt) + 1);
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
if (len < (sizeof(struct net_ipv6_hdr) +
|
|
||||||
sizeof(struct tcphdr))) {
|
|
||||||
NET_WARN("Undersized IPv6 packet: %zd byte(s)", len);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
th = (struct tcphdr *)((u8_t *)ip6_get(pkt) + 1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
return th;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t tcp_endpoint_len(sa_family_t af)
|
static size_t tcp_endpoint_len(sa_family_t af)
|
||||||
|
@ -238,14 +218,8 @@ static const char *tcp_th(struct net_pkt *pkt)
|
||||||
" Ack=%u", th_ack(th));
|
" Ack=%u", th_ack(th));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
len += snprintk(buf + len, BUF_SIZE - len,
|
||||||
struct net_ipv4_hdr *ip = ip_get(pkt);
|
" Len=%ld", (long)tcp_data_len(pkt));
|
||||||
ssize_t data_len = ntohs(ip->len) -
|
|
||||||
(sizeof(*ip) + th->th_off * 4);
|
|
||||||
|
|
||||||
len += snprintk(buf + len, BUF_SIZE - len,
|
|
||||||
" Len=%ld", (long int)data_len);
|
|
||||||
}
|
|
||||||
end:
|
end:
|
||||||
#undef BUF_SIZE
|
#undef BUF_SIZE
|
||||||
return buf;
|
return buf;
|
||||||
|
@ -570,12 +544,13 @@ end:
|
||||||
|
|
||||||
static size_t tcp_data_len(struct net_pkt *pkt)
|
static size_t tcp_data_len(struct net_pkt *pkt)
|
||||||
{
|
{
|
||||||
struct net_ipv4_hdr *ip = ip_get(pkt);
|
|
||||||
struct tcphdr *th = th_get(pkt);
|
struct tcphdr *th = th_get(pkt);
|
||||||
u8_t off = th->th_off;
|
size_t tcp_options_len = (th->th_off - 5) * 4;
|
||||||
ssize_t len = ntohs(ip->len) - sizeof(*ip) - off * 4;
|
ssize_t len = net_pkt_get_len(pkt) - net_pkt_ip_hdr_len(pkt) -
|
||||||
|
net_pkt_ip_opts_len(pkt) - sizeof(*th) - tcp_options_len;
|
||||||
|
|
||||||
if (off > 5 && false == tcp_options_check((th + 1), (off - 5) * 4)) {
|
if (tcp_options_len && tcp_options_check((th + 1), tcp_options_len)
|
||||||
|
== false) {
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +559,6 @@ static size_t tcp_data_len(struct net_pkt *pkt)
|
||||||
|
|
||||||
static size_t tcp_data_get(struct tcp *conn, struct net_pkt *pkt)
|
static size_t tcp_data_get(struct tcp *conn, struct net_pkt *pkt)
|
||||||
{
|
{
|
||||||
struct net_ipv4_hdr *ip = ip_get(pkt);
|
|
||||||
struct tcphdr *th = th_get(pkt);
|
struct tcphdr *th = th_get(pkt);
|
||||||
ssize_t len = tcp_data_len(pkt);
|
ssize_t len = tcp_data_len(pkt);
|
||||||
|
|
||||||
|
@ -598,7 +572,7 @@ static size_t tcp_data_get(struct tcp *conn, struct net_pkt *pkt)
|
||||||
|
|
||||||
buf = tcp_malloc(len);
|
buf = tcp_malloc(len);
|
||||||
|
|
||||||
net_pkt_skip(pkt, sizeof(*ip) + th->th_off * 4);
|
net_pkt_skip(pkt, th->th_off * 4);
|
||||||
|
|
||||||
net_pkt_read(pkt, buf, len);
|
net_pkt_read(pkt, buf, len);
|
||||||
|
|
||||||
|
@ -615,7 +589,8 @@ static size_t tcp_data_get(struct tcp *conn, struct net_pkt *pkt)
|
||||||
|
|
||||||
net_pkt_cursor_init(up);
|
net_pkt_cursor_init(up);
|
||||||
net_pkt_set_overwrite(up, true);
|
net_pkt_set_overwrite(up, true);
|
||||||
net_pkt_skip(up, 40);
|
|
||||||
|
net_pkt_skip(up, net_pkt_get_len(up) - len);
|
||||||
|
|
||||||
net_context_packet_received(
|
net_context_packet_received(
|
||||||
(struct net_conn *)conn->context->conn_handler,
|
(struct net_conn *)conn->context->conn_handler,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue