TSG-13157 Decrypted Traffic Steering构造的SYN/SYN ACK支持窗口扩大选项

This commit is contained in:
luwenpeng
2022-12-26 14:31:22 +08:00
parent da468bbf67
commit 29a75b1d9c
3 changed files with 106 additions and 55 deletions

View File

@@ -17,7 +17,7 @@ extern "C"
#define TCP_FIN_FLAG 0x01 #define TCP_FIN_FLAG 0x01
#define TCP_FLAG_ALL 0x3F #define TCP_FLAG_ALL 0x3F
int tcp_header_construct(char *buffer, uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, uint16_t urgent); int tcp_header_construct(char *buffer, uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, uint16_t urgent, const char *options, uint16_t options_len);
int ipv4_header_construct(char *buffer, uint16_t carry_layer_len, struct in_addr *src_addr, struct in_addr *dst_addr, u_char tos, uint16_t id, uint16_t frag, u_char ttl, u_char protocol); int ipv4_header_construct(char *buffer, uint16_t carry_layer_len, struct in_addr *src_addr, struct in_addr *dst_addr, u_char tos, uint16_t id, uint16_t frag, u_char ttl, u_char protocol);
int ipv6_header_construct(char *buffer, uint16_t carry_layer_len, struct in6_addr *src_addr, struct in6_addr *dst_addr, u_char ttl, u_char protocol); int ipv6_header_construct(char *buffer, uint16_t carry_layer_len, struct in6_addr *src_addr, struct in6_addr *dst_addr, u_char ttl, u_char protocol);
int vlan_header_construct(char *buffer, uint16_t tci, uint16_t type); int vlan_header_construct(char *buffer, uint16_t tci, uint16_t type);
@@ -27,15 +27,17 @@ extern "C"
char *buffer, // buffer char *buffer, // buffer
struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t vlan_tci, uint16_t l3_protocol, // Ether struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t vlan_tci, uint16_t l3_protocol, // Ether
struct in_addr *src_addr, struct in_addr *dst_addr, u_char tos, u_char ttl, uint16_t id, // IPv4 struct in_addr *src_addr, struct in_addr *dst_addr, u_char tos, u_char ttl, uint16_t id, // IPv4
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP Header
const char *payload, uint16_t payload_len); const char *tcp_options, uint16_t tcp_options_len, // TCP Options
const char *payload, uint16_t payload_len); // Payload
int tcp_packet_v6_construct( int tcp_packet_v6_construct(
char *buffer, // buffer char *buffer, // buffer
struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t vlan_tci, uint16_t l3_protocol, // Ether struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t vlan_tci, uint16_t l3_protocol, // Ether
struct in6_addr *src_addr, struct in6_addr *dst_addr, u_char ttl, // IPv6 struct in6_addr *src_addr, struct in6_addr *dst_addr, u_char ttl, // IPv6
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP Header
const char *payload, uint16_t payload_len); const char *tcp_options, uint16_t tcp_options_len, // TCP Options
const char *payload, uint16_t payload_len); // Payload
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -167,7 +167,7 @@ static uint16_t tcp_checksum_v6(const void *l4_hdr, uint16_t l4_len, struct in6_
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/ */
int tcp_header_construct(char *buffer, uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, uint16_t urgent) int tcp_header_construct(char *buffer, uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, uint16_t urgent, const char *options, uint16_t options_len)
{ {
struct tcp_hdr *tcp_hdr = (struct tcp_hdr *)buffer; struct tcp_hdr *tcp_hdr = (struct tcp_hdr *)buffer;
@@ -175,13 +175,14 @@ int tcp_header_construct(char *buffer, uint16_t src_port, uint16_t dst_port, uin
tcp_hdr->dst_port = dst_port; tcp_hdr->dst_port = dst_port;
tcp_hdr->sent_seq = htonl(seq); tcp_hdr->sent_seq = htonl(seq);
tcp_hdr->recv_ack = htonl(ack); tcp_hdr->recv_ack = htonl(ack);
tcp_hdr->data_off = 0x50; tcp_hdr->data_off = (sizeof(struct tcp_hdr) + options_len) << 2;
tcp_hdr->flags = flags; tcp_hdr->flags = flags;
tcp_hdr->rx_window = htons(window); tcp_hdr->rx_window = htons(window);
tcp_hdr->checksum = 0; tcp_hdr->checksum = 0;
tcp_hdr->urgent_ptr = urgent; tcp_hdr->urgent_ptr = urgent;
memcpy(buffer + sizeof(struct tcp_hdr), options, options_len);
return sizeof(struct tcp_hdr); return sizeof(struct tcp_hdr) + options_len;
} }
/****************************************************************************** /******************************************************************************
@@ -315,8 +316,9 @@ int tcp_packet_v4_construct(
char *buffer, // buffer char *buffer, // buffer
struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t vlan_tci, uint16_t l3_protocol, // Ether struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t vlan_tci, uint16_t l3_protocol, // Ether
struct in_addr *src_addr, struct in_addr *dst_addr, u_char tos, u_char ttl, uint16_t id, // IPv4 struct in_addr *src_addr, struct in_addr *dst_addr, u_char tos, u_char ttl, uint16_t id, // IPv4
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP Header
const char *payload, uint16_t payload_len) // APP const char *tcp_options, uint16_t tcp_options_len, // TCP Options
const char *payload, uint16_t payload_len) // Payload
{ {
uint16_t length = 0; uint16_t length = 0;
@@ -333,15 +335,15 @@ int tcp_packet_v4_construct(
// IPv4 Header // IPv4 Header
u_char protocol = IPPROTO_TCP; u_char protocol = IPPROTO_TCP;
uint16_t frag = 0; uint16_t frag = 0;
length += ipv4_header_construct(buffer + length, payload_len + sizeof(struct tcphdr), src_addr, dst_addr, tos, id, frag, ttl, protocol); length += ipv4_header_construct(buffer + length, sizeof(struct tcphdr) + tcp_options_len + payload_len, src_addr, dst_addr, tos, id, frag, ttl, protocol);
// TCP header and payload // TCP header and payload
uint16_t urgent = 0; uint16_t urgent = 0;
struct tcp_hdr *tcp_hdr = (struct tcp_hdr *)(buffer + length); struct tcp_hdr *tcp_hdr = (struct tcp_hdr *)(buffer + length);
length += tcp_header_construct((char *)tcp_hdr, src_port, dst_port, seq, ack, flags, window, urgent); length += tcp_header_construct((char *)tcp_hdr, src_port, dst_port, seq, ack, flags, window, urgent, tcp_options, tcp_options_len);
memcpy(buffer + length, payload, payload_len); memcpy(buffer + length, payload, payload_len);
length += payload_len; length += payload_len;
tcp_hdr->checksum = tcp_checksum_v4((void *)tcp_hdr, sizeof(struct tcp_hdr) + payload_len, src_addr, dst_addr); tcp_hdr->checksum = tcp_checksum_v4((void *)tcp_hdr, sizeof(struct tcp_hdr) + tcp_options_len + payload_len, src_addr, dst_addr);
return length; return length;
} }
@@ -354,8 +356,9 @@ int tcp_packet_v6_construct(
char *buffer, // buffer char *buffer, // buffer
struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t vlan_tci, uint16_t l3_protocol, // Ether struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t vlan_tci, uint16_t l3_protocol, // Ether
struct in6_addr *src_addr, struct in6_addr *dst_addr, u_char ttl, // IPv6 struct in6_addr *src_addr, struct in6_addr *dst_addr, u_char ttl, // IPv6
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP Header
const char *payload, uint16_t payload_len) // APP const char *tcp_options, uint16_t tcp_options_len, // TCP Options
const char *payload, uint16_t payload_len) // Payload
{ {
uint16_t length = 0; uint16_t length = 0;
@@ -371,15 +374,15 @@ int tcp_packet_v6_construct(
// IPv6 Header // IPv6 Header
u_char protocol = IPPROTO_TCP; u_char protocol = IPPROTO_TCP;
length += ipv6_header_construct(buffer + length, payload_len + sizeof(struct tcphdr), src_addr, dst_addr, ttl, protocol); length += ipv6_header_construct(buffer + length, sizeof(struct tcphdr) + tcp_options_len + payload_len, src_addr, dst_addr, ttl, protocol);
// TCP header and payload // TCP header and payload
uint16_t urgent = 0; uint16_t urgent = 0;
struct tcp_hdr *tcp_hdr = (struct tcp_hdr *)(buffer + length); struct tcp_hdr *tcp_hdr = (struct tcp_hdr *)(buffer + length);
length += tcp_header_construct((char *)tcp_hdr, src_port, dst_port, seq, ack, flags, window, urgent); length += tcp_header_construct((char *)tcp_hdr, src_port, dst_port, seq, ack, flags, window, urgent, tcp_options, tcp_options_len);
memcpy(buffer + length, payload, payload_len); memcpy(buffer + length, payload, payload_len);
length += payload_len; length += payload_len;
tcp_hdr->checksum = tcp_checksum_v6((void *)tcp_hdr, sizeof(struct tcp_hdr) + payload_len, src_addr, dst_addr); tcp_hdr->checksum = tcp_checksum_v6((void *)tcp_hdr, sizeof(struct tcp_hdr) + tcp_options_len + payload_len, src_addr, dst_addr);
return length; return length;
} }

View File

@@ -278,11 +278,23 @@ static void tcp_restore_info_parse_from_pkt(struct pkt_info *pktinfo, struct tcp
} }
} }
struct tcp_option_window_scale{
uint8_t kind;
uint8_t length;
uint8_t shift_count;
};
static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *restore_info) static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *restore_info)
{ {
char buffer[1500] = {0}; char buffer[1500] = {0};
int length = 0; int length = 0;
char tcp_option_buffer_c[40] = {0};
char tcp_option_buffer_s[40] = {0};
int tcp_option_length_c = 0;
int tcp_option_length_s = 0;
int options_padding_size = 0;
const struct tcp_restore_endpoint *client = &restore_info->client; const struct tcp_restore_endpoint *client = &restore_info->client;
const struct tcp_restore_endpoint *server = &restore_info->server; const struct tcp_restore_endpoint *server = &restore_info->server;
struct raw_socket *raw_socket_c = raw_socket_create(proxy->traffic_steering_options.device_client, proxy->traffic_steering_options.so_mask_client); struct raw_socket *raw_socket_c = raw_socket_create(proxy->traffic_steering_options.device_client, proxy->traffic_steering_options.so_mask_client);
@@ -298,6 +310,34 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
uint32_t c_seq = client->seq - 1; uint32_t c_seq = client->seq - 1;
uint32_t s_seq = server->seq - 1; uint32_t s_seq = server->seq - 1;
/*
* Window Scale option (WSopt): Kind: 3, Length: 3
* +---------+---------+---------+
* | Kind=3 |Length=3 |shift.cnt|
* +---------+---------+---------+
* 1 1 1
*/
if (client->wscale_perm && server->wscale_perm)
{
// padding
memset(tcp_option_buffer_c + tcp_option_length_c, 1, 1);
tcp_option_length_c += 1;
memset(tcp_option_buffer_s + tcp_option_length_s, 1, 1);
tcp_option_length_s += 1;
struct tcp_option_window_scale *option_c = (struct tcp_option_window_scale *)(tcp_option_buffer_c + tcp_option_length_c);
option_c->kind = 3;
option_c->length = 3;
option_c->shift_count = client->wscale;
tcp_option_length_c += sizeof(struct tcp_option_window_scale);
struct tcp_option_window_scale *option_s = (struct tcp_option_window_scale *)(tcp_option_buffer_s + tcp_option_length_s);
option_s->kind = 3;
option_s->length = 3;
option_s->shift_count = server->wscale;
tcp_option_length_s += sizeof(struct tcp_option_window_scale);
}
if (client->addr.ss_family == AF_INET6) if (client->addr.ss_family == AF_INET6)
{ {
struct sockaddr_in6 *sk_client = (struct sockaddr_in6 *)&client->addr; struct sockaddr_in6 *sk_client = (struct sockaddr_in6 *)&client->addr;
@@ -310,8 +350,9 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
buffer, // buffer buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IPV6, // Ether &raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IPV6, // Ether
&sk_client->sin6_addr, &sk_server->sin6_addr, 55, // IPv6 &sk_client->sin6_addr, &sk_server->sin6_addr, 55, // IPv6
port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP port_client, port_server, c_seq, 0, TCP_SYN_FLAG, client->window, // TCP Header
NULL, 0); tcp_option_buffer_c, tcp_option_length_c, // TCP Options
NULL, 0); // Payload
raw_socket_send(raw_socket_c, buffer, length); raw_socket_send(raw_socket_c, buffer, length);
c_seq += 1; c_seq += 1;
@@ -320,8 +361,9 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
buffer, // buffer buffer, // buffer
&raw_socket_s->mac_addr, &raw_socket_c->mac_addr, 0, ETH_P_IPV6, // Ether &raw_socket_s->mac_addr, &raw_socket_c->mac_addr, 0, ETH_P_IPV6, // Ether
&sk_server->sin6_addr, &sk_client->sin6_addr, 65, // IPv6 &sk_server->sin6_addr, &sk_client->sin6_addr, 65, // IPv6
port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP Header
NULL, 0); tcp_option_buffer_s, tcp_option_length_s, // TCP Options
NULL, 0); // Payload
raw_socket_send(raw_socket_s, buffer, length); raw_socket_send(raw_socket_s, buffer, length);
s_seq += 1; s_seq += 1;
@@ -330,8 +372,9 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
buffer, // buffer buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IPV6, // Ether &raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IPV6, // Ether
&sk_client->sin6_addr, &sk_server->sin6_addr, 55, // IPv6 &sk_client->sin6_addr, &sk_server->sin6_addr, 55, // IPv6
port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP Header
NULL, 0); NULL, 0, // TCP Options
NULL, 0); // Payload
raw_socket_send(raw_socket_c, buffer, length); raw_socket_send(raw_socket_c, buffer, length);
} }
else else
@@ -346,7 +389,8 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
buffer, // buffer buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IP, // Ether &raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IP, // Ether
&sk_client->sin_addr, &sk_server->sin_addr, 0, 55, 0x11, // IPv4 &sk_client->sin_addr, &sk_server->sin_addr, 0, 55, 0x11, // IPv4
port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP port_client, port_server, c_seq, 0, TCP_SYN_FLAG, client->window, // TCP Header
tcp_option_buffer_c, tcp_option_length_c, // TCP Options
NULL, 0); NULL, 0);
raw_socket_send(raw_socket_c, buffer, length); raw_socket_send(raw_socket_c, buffer, length);
c_seq += 1; c_seq += 1;
@@ -356,7 +400,8 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
buffer, // buffer buffer, // buffer
&raw_socket_s->mac_addr, &raw_socket_c->mac_addr, 0, ETH_P_IP, // Ether &raw_socket_s->mac_addr, &raw_socket_c->mac_addr, 0, ETH_P_IP, // Ether
&sk_server->sin_addr,&sk_client->sin_addr, 0, 65, 0x12, // IPv4 &sk_server->sin_addr,&sk_client->sin_addr, 0, 65, 0x12, // IPv4
port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP Header
tcp_option_buffer_s, tcp_option_length_s, // TCP Options
NULL, 0); NULL, 0);
raw_socket_send(raw_socket_s, buffer, length); raw_socket_send(raw_socket_s, buffer, length);
s_seq += 1; s_seq += 1;
@@ -366,7 +411,8 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
buffer, // buffer buffer, // buffer
&raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IP, // Ether &raw_socket_c->mac_addr, &raw_socket_s->mac_addr, 0, ETH_P_IP, // Ether
&sk_client->sin_addr, &sk_server->sin_addr, 0, 55, 0x13, // IPv4 &sk_client->sin_addr, &sk_server->sin_addr, 0, 55, 0x13, // IPv4
port_client, port_server, c_seq, s_seq, TCP_ACK_FLAG, client->window, // TCP port_client, port_server, c_seq, s_seq, TCP_ACK_FLAG, client->window, // TCP Header
NULL, 0, // TCP Options
NULL, 0); NULL, 0);
raw_socket_send(raw_socket_c, buffer, length); raw_socket_send(raw_socket_c, buffer, length);
} }