修正Decrypted Traffic TCP hanshake Packet的TCP Option

This commit is contained in:
luwenpeng
2023-11-15 18:18:23 +08:00
parent c3b887f1c5
commit c9623b5ccd

View File

@@ -6,11 +6,27 @@
#include <arpa/inet.h>
#include <linux/tcp.h>
#include <net/if.h>
#include <stdlib.h>
#include <netinet/ether.h>
#include <tfe_utils.h>
#include <tfe_tcp_restore.h>
#include <packet_construct.h>
static uint16_t tfe_get_ipid()
{
static __thread uint16_t ipid = 0;
if (ipid == 0)
{
ipid = random();
}
else
{
ipid++;
}
return ipid;
}
void tfe_tcp_restore_info_dump(const struct tcp_restore_info *info)
{
char str_client_addr[64] = {0};
@@ -325,7 +341,7 @@ int tfe_tcp_restore_syn_packet(struct tcp_restore_info *restore_info, struct eth
* +---------+---------+---------+
* 1 1 2
*/
if (client->mss && server->mss)
if (client->mss)
{
struct tcp_option_mss *option = (struct tcp_option_mss *)(tcp_option_buff + tcp_option_len);
option->kind = 2;
@@ -341,7 +357,7 @@ int tfe_tcp_restore_syn_packet(struct tcp_restore_info *restore_info, struct eth
* +---------+---------+---------+
* 1 1 1
*/
if (client->wscale_perm && server->wscale_perm)
if (client->wscale_perm)
{
// padding
memset(tcp_option_buff + tcp_option_len, 1, 1);
@@ -361,7 +377,7 @@ int tfe_tcp_restore_syn_packet(struct tcp_restore_info *restore_info, struct eth
* +---------+---------+
* 1 1
*/
if (client->sack_perm && server->sack_perm)
if (client->sack_perm)
{
// padding
memset(tcp_option_buff + tcp_option_len, 1, 2);
@@ -380,7 +396,7 @@ int tfe_tcp_restore_syn_packet(struct tcp_restore_info *restore_info, struct eth
* +---------+---------+-----+-----+
* 1 1 4 4
*/
if (client->timestamp_perm && server->timestamp_perm)
if (client->timestamp_perm)
{
// padding
memset(tcp_option_buff + tcp_option_len, 1, 2);
@@ -419,11 +435,11 @@ int tfe_tcp_restore_syn_packet(struct tcp_restore_info *restore_info, struct eth
// C -> S
length = tcp_packet_v4_construct(
buffer, // buffer
client_mac, server_mac, 0, ETH_P_IP, // Ether
&sk_client->sin_addr, &sk_server->sin_addr, 0, TFE_FAKE_C_DEFAULT_TTL, 0x11, // IPv4
port_client, port_server, c_seq, 0, TCP_SYN_FLAG, client->window, // TCP Header
tcp_option_buff, tcp_option_len, // TCP Options
buffer, // buffer
client_mac, server_mac, 0, ETH_P_IP, // Ether
&sk_client->sin_addr, &sk_server->sin_addr, 0, TFE_FAKE_C_DEFAULT_TTL, tfe_get_ipid(), // IPv4
port_client, port_server, c_seq, 0, TCP_SYN_FLAG, client->window, // TCP Header
tcp_option_buff, tcp_option_len, // TCP Options
NULL, 0);
}
@@ -449,7 +465,7 @@ int tfe_tcp_restore_synack_packet(struct tcp_restore_info *restore_info, struct
* +---------+---------+---------+
* 1 1 2
*/
if (client->mss && server->mss)
if (server->mss)
{
struct tcp_option_mss *option = (struct tcp_option_mss *)(tcp_option_buff + tcp_option_len);
option->kind = 2;
@@ -465,7 +481,7 @@ int tfe_tcp_restore_synack_packet(struct tcp_restore_info *restore_info, struct
* +---------+---------+---------+
* 1 1 1
*/
if (client->wscale_perm && server->wscale_perm)
if (server->wscale_perm)
{
// padding
memset(tcp_option_buff + tcp_option_len, 1, 1);
@@ -485,7 +501,7 @@ int tfe_tcp_restore_synack_packet(struct tcp_restore_info *restore_info, struct
* +---------+---------+
* 1 1
*/
if (client->sack_perm && server->sack_perm)
if (server->sack_perm)
{
// padding
memset(tcp_option_buff + tcp_option_len, 1, 2);
@@ -504,7 +520,7 @@ int tfe_tcp_restore_synack_packet(struct tcp_restore_info *restore_info, struct
* +---------+---------+-----+-----+
* 1 1 4 4
*/
if (client->timestamp_perm && server->timestamp_perm)
if (server->timestamp_perm)
{
// padding
memset(tcp_option_buff + tcp_option_len, 1, 2);
@@ -514,7 +530,7 @@ int tfe_tcp_restore_synack_packet(struct tcp_restore_info *restore_info, struct
option->kind = 8;
option->length = 10;
option->tsval = htonl(server->ts_val);
option->tsecr = htonl(client->ts_val);
option->tsecr = client->timestamp_perm ? htonl(client->ts_val) : htonl(0);
tcp_option_len += sizeof(struct tcp_option_time_stamp);
}
@@ -547,11 +563,11 @@ int tfe_tcp_restore_synack_packet(struct tcp_restore_info *restore_info, struct
// S -> C
length = tcp_packet_v4_construct(
buffer, // buffer
server_mac, client_mac, 0, ETH_P_IP, // Ether
&sk_server->sin_addr, &sk_client->sin_addr, 0, TFE_FAKE_S_DEFAULT_TTL, 0x12, // IPv4
port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP Header
tcp_option_buff, tcp_option_len, // TCP Options
buffer, // buffer
server_mac, client_mac, 0, ETH_P_IP, // Ether
&sk_server->sin_addr, &sk_client->sin_addr, 0, TFE_FAKE_S_DEFAULT_TTL, tfe_get_ipid(), // IPv4
port_server, port_client, s_seq, c_seq, TCP_SYN_FLAG | TCP_ACK_FLAG, server->window, // TCP Header
tcp_option_buff, tcp_option_len, // TCP Options
NULL, 0);
}
@@ -570,6 +586,7 @@ int tfe_tcp_restore_ack_packet(struct tcp_restore_info *restore_info, struct eth
uint32_t c_seq = client->seq - 1;
uint32_t s_seq = server->seq - 1;
uint16_t ack_window = 0;
/*
* Time Stamp option: Kind: 8, Length: 10
@@ -592,6 +609,12 @@ int tfe_tcp_restore_ack_packet(struct tcp_restore_info *restore_info, struct eth
tcp_option_len += sizeof(struct tcp_option_time_stamp);
}
ack_window = MIN(client->window, server->window);
if (client->wscale_perm && server->wscale_perm)
{
ack_window = ack_window / (1 << server->wscale);
}
if (client->addr.ss_family == AF_INET6)
{
struct sockaddr_in6 *sk_client = (struct sockaddr_in6 *)&client->addr;
@@ -607,7 +630,7 @@ int tfe_tcp_restore_ack_packet(struct tcp_restore_info *restore_info, struct eth
buffer, // buffer
client_mac, server_mac, 0, ETH_P_IPV6, // Ether
&sk_client->sin6_addr, &sk_server->sin6_addr, TFE_FAKE_C_DEFAULT_TTL, // IPv6
port_client, port_server, c_seq, s_seq, TCP_ACK_FLAG, client->window, // TCP Header
port_client, port_server, c_seq, s_seq, TCP_ACK_FLAG, ack_window, // TCP Header
tcp_option_buff, tcp_option_len, // TCP Options
NULL, 0); // Payload
}
@@ -623,11 +646,11 @@ int tfe_tcp_restore_ack_packet(struct tcp_restore_info *restore_info, struct eth
// C -> S
length = tcp_packet_v4_construct(
buffer, // buffer
client_mac, server_mac, 0, ETH_P_IP, // Ether
&sk_client->sin_addr, &sk_server->sin_addr, 0, TFE_FAKE_C_DEFAULT_TTL, 0x13, // IPv4
port_client, port_server, c_seq, s_seq, TCP_ACK_FLAG, client->window, // TCP Header
tcp_option_buff, tcp_option_len, // TCP Options
buffer, // buffer
client_mac, server_mac, 0, ETH_P_IP, // Ether
&sk_client->sin_addr, &sk_server->sin_addr, 0, TFE_FAKE_C_DEFAULT_TTL, tfe_get_ipid(), // IPv4
port_client, port_server, c_seq, s_seq, TCP_ACK_FLAG, ack_window, // TCP Header
tcp_option_buff, tcp_option_len, // TCP Options
NULL, 0);
}