TSG-13157 Decrypted Traffic Steering构造的SYN/SYN ACK支持窗口扩大选项
This commit is contained in:
@@ -17,25 +17,27 @@ extern "C"
|
||||
#define TCP_FIN_FLAG 0x01
|
||||
#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 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 vlan_header_construct(char *buffer, uint16_t tci, uint16_t type);
|
||||
int ether_header_construct(char *buffer, struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t type);
|
||||
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 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 ether_header_construct(char *buffer, struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t type);
|
||||
|
||||
int tcp_packet_v4_construct(
|
||||
int tcp_packet_v4_construct(
|
||||
char *buffer, // buffer
|
||||
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
|
||||
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP
|
||||
const char *payload, uint16_t payload_len);
|
||||
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP Header
|
||||
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
|
||||
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
|
||||
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP
|
||||
const char *payload, uint16_t payload_len);
|
||||
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP Header
|
||||
const char *tcp_options, uint16_t tcp_options_len, // TCP Options
|
||||
const char *payload, uint16_t payload_len); // Payload
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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->sent_seq = htonl(seq);
|
||||
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->rx_window = htons(window);
|
||||
tcp_hdr->checksum = 0;
|
||||
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
|
||||
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
|
||||
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP
|
||||
const char *payload, uint16_t payload_len) // APP
|
||||
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP Header
|
||||
const char *tcp_options, uint16_t tcp_options_len, // TCP Options
|
||||
const char *payload, uint16_t payload_len) // Payload
|
||||
{
|
||||
uint16_t length = 0;
|
||||
|
||||
@@ -333,15 +335,15 @@ int tcp_packet_v4_construct(
|
||||
// IPv4 Header
|
||||
u_char protocol = IPPROTO_TCP;
|
||||
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
|
||||
uint16_t urgent = 0;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
@@ -354,8 +356,9 @@ int tcp_packet_v6_construct(
|
||||
char *buffer, // buffer
|
||||
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
|
||||
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP
|
||||
const char *payload, uint16_t payload_len) // APP
|
||||
uint16_t src_port, uint16_t dst_port, uint32_t seq, uint32_t ack, u_char flags, uint16_t window, // TCP Header
|
||||
const char *tcp_options, uint16_t tcp_options_len, // TCP Options
|
||||
const char *payload, uint16_t payload_len) // Payload
|
||||
{
|
||||
uint16_t length = 0;
|
||||
|
||||
@@ -371,15 +374,15 @@ int tcp_packet_v6_construct(
|
||||
|
||||
// IPv6 Header
|
||||
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
|
||||
uint16_t urgent = 0;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
char buffer[1500] = {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 *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);
|
||||
@@ -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 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)
|
||||
{
|
||||
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
|
||||
&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
|
||||
port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP
|
||||
NULL, 0);
|
||||
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); // Payload
|
||||
raw_socket_send(raw_socket_c, buffer, length);
|
||||
c_seq += 1;
|
||||
|
||||
@@ -320,8 +361,9 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
|
||||
buffer, // buffer
|
||||
&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
|
||||
port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP
|
||||
NULL, 0);
|
||||
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); // Payload
|
||||
raw_socket_send(raw_socket_s, buffer, length);
|
||||
s_seq += 1;
|
||||
|
||||
@@ -330,8 +372,9 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
|
||||
buffer, // buffer
|
||||
&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
|
||||
port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP
|
||||
NULL, 0);
|
||||
port_client, port_server, c_seq, s_seq, TCP_SYN_FLAG, client->window, // TCP Header
|
||||
NULL, 0, // TCP Options
|
||||
NULL, 0); // Payload
|
||||
raw_socket_send(raw_socket_c, buffer, length);
|
||||
}
|
||||
else
|
||||
@@ -346,7 +389,8 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
|
||||
buffer, // buffer
|
||||
&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
|
||||
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);
|
||||
raw_socket_send(raw_socket_c, buffer, length);
|
||||
c_seq += 1;
|
||||
@@ -356,7 +400,8 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
|
||||
buffer, // buffer
|
||||
&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
|
||||
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);
|
||||
raw_socket_send(raw_socket_s, buffer, length);
|
||||
s_seq += 1;
|
||||
@@ -366,7 +411,8 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
|
||||
buffer, // buffer
|
||||
&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
|
||||
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);
|
||||
raw_socket_send(raw_socket_c, buffer, length);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user