diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index dc21822..e5c286d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,4 +1,7 @@ - add_library(common src/tfe_utils.cpp src/tfe_types.cpp src/tfe_future.cpp src/tfe_http.cpp src/tfe_plugin.cpp src/tfe_rpc.cpp src/tfe_cmsg.cpp src/tfe_kafka_logger.cpp src/tfe_resource.cpp src/tfe_scan.cpp src/tfe_pkt_util.cpp src/tfe_tcp_restore.cpp) + add_library( + common src/tfe_utils.cpp src/tfe_types.cpp src/tfe_future.cpp src/tfe_http.cpp src/tfe_plugin.cpp + src/tfe_rpc.cpp src/tfe_cmsg.cpp src/tfe_kafka_logger.cpp src/tfe_resource.cpp src/tfe_scan.cpp + src/tfe_pkt_util.cpp src/tfe_tcp_restore.cpp src/raw_socket.cpp src/packet_construct.cpp) target_include_directories(common PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) target_link_libraries(common PUBLIC libevent-static libevent-static-openssl libevent-static-pthreads rdkafka) target_link_libraries(common PUBLIC MESA_handle_logger cjson) diff --git a/common/include/packet_construct.h b/common/include/packet_construct.h new file mode 100644 index 0000000..16ca00d --- /dev/null +++ b/common/include/packet_construct.h @@ -0,0 +1,44 @@ +#ifndef _CONSTRUCT_PACKET_H +#define _CONSTRUCT_PACKET_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include +#include + +#define TCP_URG_FLAG 0x20 +#define TCP_ACK_FLAG 0x10 +#define TCP_PSH_FLAG 0x08 +#define TCP_RST_FLAG 0x04 +#define TCP_SYN_FLAG 0x02 +#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_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); + + 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); + +#ifdef __cpluscplus +} +#endif + +#endif diff --git a/common/include/raw_socket.h b/common/include/raw_socket.h new file mode 100644 index 0000000..7e924e8 --- /dev/null +++ b/common/include/raw_socket.h @@ -0,0 +1,31 @@ +#ifndef _RAW_SOCKET_H +#define _RAW_SOCKET_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include +#include +#include +#include + +struct raw_socket +{ + int sockfd; + char interface[64]; + struct ether_addr mac_addr; + struct sockaddr_ll sockaddr; +}; + +struct raw_socket *raw_socket_create(const char *interface, int fd_so_mask); +void raw_socket_destory(struct raw_socket *raw); +int raw_socket_send(struct raw_socket *raw, const char *data, int data_len); +int raw_socket_recv(struct raw_socket *raw, char *buff, int buff_size); + +#ifdef __cpluscplus +} +#endif + +#endif diff --git a/common/src/packet_construct.cpp b/common/src/packet_construct.cpp new file mode 100644 index 0000000..2ee24cf --- /dev/null +++ b/common/src/packet_construct.cpp @@ -0,0 +1,385 @@ +#include +#include +#include +#include +#include + +/****************************************************************************** + * Struct + ******************************************************************************/ + +struct tcp_hdr +{ + uint16_t src_port; + uint16_t dst_port; + uint32_t sent_seq; + uint32_t recv_ack; + uint8_t data_off; + uint8_t flags; + uint16_t rx_window; + uint16_t checksum; + uint16_t urgent_ptr; +} __attribute__((__packed__)); + +struct vlan_hdr +{ + uint16_t vlan_tci; // Priority (3) + CFI (1) + Identifier Code (12) + uint16_t eth_proto; // Ethernet type of encapsulated frame +} __attribute__((__packed__)); + +/****************************************************************************** + * CheckSum + ******************************************************************************/ + +static uint16_t ipv4_checksum(const struct iphdr *ipv4_hdr, uint16_t hdr_len) +{ + uint32_t sum = 0; + const uint16_t *ip1 = (const uint16_t *)ipv4_hdr; + + while (hdr_len > 1) + { + sum += *ip1++; + if (sum & 0x80000000) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + hdr_len -= 2; + } + + while (sum >> 16) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + + return (~sum); +} + +static uint16_t tcp_checksum_v4(const void *l4_hdr, uint16_t l4_len, struct in_addr *src_addr, struct in_addr *dst_addr) +{ + uint16_t *ip_src = (uint16_t *)src_addr; + uint16_t *ip_dst = (uint16_t *)dst_addr; + const uint16_t *buffer = (u_int16_t *)l4_hdr; + + uint32_t sum = 0; + size_t len = l4_len; + + while (len > 1) + { + sum += *buffer++; + if (sum & 0x80000000) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + len -= 2; + } + + if (len & 1) + { + sum += *((uint8_t *)buffer); + } + + sum += *(ip_src++); + sum += *ip_src; + sum += *(ip_dst++); + sum += *ip_dst; + sum += htons(IPPROTO_TCP); + sum += htons(l4_len); + + while (sum >> 16) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + + return ((uint16_t)(~sum)); +} + +static uint16_t tcp_checksum_v6(const void *l4_hdr, uint16_t l4_len, struct in6_addr *src_addr, struct in6_addr *dst_addr) +{ + uint16_t *ip_src = (uint16_t *)src_addr; + uint16_t *ip_dst = (uint16_t *)dst_addr; + const uint16_t *buffer = (u_int16_t *)l4_hdr; + + uint32_t sum = 0; + size_t len = l4_len; + + while (len > 1) + { + sum += *buffer++; + if (sum & 0x80000000) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + len -= 2; + } + + if (len & 1) + { + sum += *((uint8_t *)buffer); + } + + for (int i = 0; i < 8; i++) + { + sum += *ip_src; + ip_src++; + } + + for (int i = 0; i < 8; i++) + { + sum += *ip_dst; + ip_dst++; + } + sum += htons(IPPROTO_TCP); + sum += htons(l4_len); + + while (sum >> 16) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + + return ((uint16_t)(~sum)); +} + +/****************************************************************************** + * TCP header + ******************************************************************************/ + +/* + * TCP Header Format + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Source Port | Destination Port | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Acknowledgment Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Data | |U|A|P|R|S|F| | + * | Offset| Reserved |R|C|S|S|Y|I| Window | + * | | |G|K|H|T|N|N| | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Checksum | Urgent Pointer | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Options | Padding | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | data | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +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) +{ + struct tcp_hdr *tcp_hdr = (struct tcp_hdr *)buffer; + + tcp_hdr->src_port = src_port; + 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->flags = flags; + tcp_hdr->rx_window = htons(window); + tcp_hdr->checksum = 0; + tcp_hdr->urgent_ptr = urgent; + + return sizeof(struct tcp_hdr); +} + +/****************************************************************************** + * IPv4 header + ******************************************************************************/ + +/* + * Internet Header Format + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Version| IHL |Type of Service| Total Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Identification |Flags| Fragment Offset | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Time to Live | Protocol | Header Checksum | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Source Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Destination Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Options | Padding | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +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) +{ + struct iphdr *ip_hdr = (struct iphdr *)buffer; + + ip_hdr->version = 4; + ip_hdr->ihl = 5; + ip_hdr->tos = tos; + ip_hdr->tot_len = htons(sizeof(struct iphdr) + carry_layer_len); + ip_hdr->id = htons(id); + ip_hdr->frag_off = 0; + ip_hdr->ttl = ttl; + ip_hdr->protocol = protocol; + ip_hdr->check = 0; + ip_hdr->saddr = *(uint32_t *)src_addr; + ip_hdr->daddr = *(uint32_t *)dst_addr; + + ip_hdr->check = ipv4_checksum(ip_hdr, sizeof(struct iphdr)); + + return sizeof(struct iphdr); +} + +/****************************************************************************** + * IPv6 header + ******************************************************************************/ + +/* + * IPv6 Header Format + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Version| Traffic Class | Flow Label | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Payload Length | Next Header | Hop Limit | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + + + * | | + * + Source Address + + * | | + * + + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + + + * | | + * + Destination Address + + * | | + * + + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +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) +{ + struct ip6_hdr *ip6_hdr = (struct ip6_hdr *)buffer; + + ip6_hdr->ip6_flow = 0; + ip6_hdr->ip6_plen = htons(carry_layer_len); + ip6_hdr->ip6_nxt = protocol; + ip6_hdr->ip6_hlim = ttl; + ip6_hdr->ip6_vfc &= 0x0F; + ip6_hdr->ip6_vfc |= (6U << 4U); + + ip6_hdr->ip6_src = *src_addr; + ip6_hdr->ip6_dst = *dst_addr; + + return sizeof(struct ip6_hdr); +} + +/****************************************************************************** + * Vlan header + ******************************************************************************/ + +int vlan_header_construct(char *buffer, uint16_t tci, uint16_t type) +{ + struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)buffer; + + vlan_hdr->vlan_tci = htons(tci); + vlan_hdr->eth_proto = htons(type); + + return sizeof(struct vlan_hdr); +} + +/****************************************************************************** + * Ether header + ******************************************************************************/ + +int ether_header_construct(char *buffer, struct ether_addr *src_mac, struct ether_addr *dst_mac, uint16_t type) +{ + struct ethhdr *eth_hdr = (struct ethhdr *)buffer; + + memcpy(eth_hdr->h_dest, (u_char *)dst_mac, ETHER_ADDR_LEN); + memcpy(eth_hdr->h_source, (u_char *)src_mac, ETHER_ADDR_LEN); + eth_hdr->h_proto = htons(type); + + return sizeof(struct ethhdr); +} + +/****************************************************************************** + * Build Ether + IPv4 + TCP Packet + ******************************************************************************/ + +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 length = 0; + + // Ethernet header + uint16_t eth_protocol = vlan_tci > 0 ? ETH_P_8021Q : l3_protocol; + length += ether_header_construct(buffer + length, src_mac, dst_mac, eth_protocol); + + // VLAN header + if (vlan_tci > 0) + { + length += vlan_header_construct(buffer + length, vlan_tci, l3_protocol); + } + + // 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); + + // 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); + 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); + + return length; +} + +/****************************************************************************** + * Build Ether + IPv6 + TCP Packet + ******************************************************************************/ + +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 length = 0; + + // Ethernet header + uint16_t eth_protocol = vlan_tci > 0 ? ETH_P_8021Q : l3_protocol; + length += ether_header_construct(buffer + length, src_mac, dst_mac, eth_protocol); + + // VLAN header + if (vlan_tci > 0) + { + length += vlan_header_construct(buffer + length, vlan_tci, l3_protocol); + } + + // IPv6 Header + u_char protocol = IPPROTO_TCP; + length += ipv6_header_construct(buffer + length, payload_len + sizeof(struct tcphdr), 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); + 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); + + return length; +} diff --git a/common/src/raw_socket.cpp b/common/src/raw_socket.cpp new file mode 100644 index 0000000..177dfbb --- /dev/null +++ b/common/src/raw_socket.cpp @@ -0,0 +1,101 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "raw_socket.h" +#include "packet_construct.h" + +void raw_socket_destory(struct raw_socket *raw) +{ + if (raw) + { + if (raw->sockfd) + { + close(raw->sockfd); + } + free(raw); + raw = NULL; + } +} + +struct raw_socket *raw_socket_create(const char *interface, int fd_so_mask) +{ + struct ifreq ifr = {0}; + + struct raw_socket *raw = (struct raw_socket *)calloc(1, sizeof(struct raw_socket)); + memcpy(raw->interface, interface, strlen(interface)); + + raw->sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (raw->sockfd < 0) + { + printf("socket() failed, (%d: %s)", errno, strerror(errno)); + goto error; + } + + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", raw->interface); + if (ioctl(raw->sockfd, SIOCGIFHWADDR, &ifr) < 0) + { + printf("ioctl(SIOCGIFHWADDR) failed, (%d: %s)", errno, strerror(errno)); + goto error; + } + memcpy(&(raw->mac_addr), ifr.ifr_hwaddr.sa_data, 6); + + raw->sockaddr.sll_ifindex = if_nametoindex(interface); + if (raw->sockaddr.sll_ifindex == 0) + { + printf("if_nametoindex() failed, (%d: %s)", errno, strerror(errno)); + goto error; + } + raw->sockaddr.sll_family = AF_PACKET; + memcpy((void *)&(raw->sockaddr.sll_addr), (void *)&(raw->mac_addr), 6); + raw->sockaddr.sll_halen = 6; + + if (setsockopt(raw->sockfd, SOL_SOCKET, SO_MARK, (char *)&fd_so_mask, sizeof(fd_so_mask)) < 0) + { + printf("setsockopt(SO_MARK) failed, (%d: %s)", errno, strerror(errno)); + goto error; + } + + return raw; + +error: + raw_socket_destory(raw); + + return NULL; +} + +int raw_socket_send(struct raw_socket *raw, const char *data, int data_len) +{ + int ret = sendto(raw->sockfd, data, data_len, 0, (struct sockaddr *)&raw->sockaddr, sizeof(raw->sockaddr)); + if (ret < 0) + { + printf("sendto() failed, (%d: %s)", errno, strerror(errno)); + } + + return ret; +} + +int raw_socket_recv(struct raw_socket *raw, char *buff, int buff_size) +{ + socklen_t addr_len = sizeof(raw->sockaddr); + int ret = recvfrom(raw->sockfd, buff, buff_size, 0, (struct sockaddr *)&raw->sockaddr, &addr_len); + if (ret < 0) + { + printf("sendto() failed, (%d: %s)", errno, strerror(errno)); + } + + return ret; +} \ No newline at end of file diff --git a/platform/src/acceptor_kni_v3.cpp b/platform/src/acceptor_kni_v3.cpp index ac9f4f9..3915f67 100644 --- a/platform/src/acceptor_kni_v3.cpp +++ b/platform/src/acceptor_kni_v3.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include #define TCP_RESTORE_TCPOPT_KIND 88 @@ -276,6 +278,105 @@ static void tcp_restore_info_parse_from_pkt(struct pkt_info *pktinfo, struct tcp } } +static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *restore_info) +{ + char buffer[1500] = {0}; + int length = 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); + struct raw_socket *raw_socket_s = raw_socket_create(proxy->traffic_steering_options.device_server, proxy->traffic_steering_options.so_mask_server); + if (raw_socket_c == NULL || raw_socket_s == NULL) + { + raw_socket_destory(raw_socket_c); + raw_socket_destory(raw_socket_s); + + return -1; + } + + uint32_t c_seq = client->seq - 1; + uint32_t s_seq = server->seq - 1; + + if (client->addr.ss_family == AF_INET6) + { + struct sockaddr_in6 *sk_client = (struct sockaddr_in6 *)&client->addr; + struct sockaddr_in6 *sk_server = (struct sockaddr_in6 *)&server->addr; + uint16_t port_client = sk_client->sin6_port; + uint16_t port_server = sk_server->sin6_port; + + // C -> S + length = tcp_packet_v6_construct( + 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); + raw_socket_send(raw_socket_c, buffer, length); + c_seq += 1; + + // S -> C + length = tcp_packet_v6_construct( + 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); + raw_socket_send(raw_socket_s, buffer, length); + s_seq += 1; + + // C -> S + length = tcp_packet_v6_construct( + 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); + raw_socket_send(raw_socket_c, buffer, length); + } + else + { + struct sockaddr_in *sk_client = (struct sockaddr_in *)&client->addr; + struct sockaddr_in *sk_server = (struct sockaddr_in *)&server->addr; + uint16_t port_client = sk_client->sin_port; + uint16_t port_server = sk_server->sin_port; + + // C -> S + length = tcp_packet_v4_construct( + 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 + NULL, 0); + raw_socket_send(raw_socket_c, buffer, length); + c_seq += 1; + + // S -> C + length = tcp_packet_v4_construct( + 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 + NULL, 0); + raw_socket_send(raw_socket_s, buffer, length); + s_seq += 1; + + // C -> S + length = tcp_packet_v4_construct( + 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 + NULL, 0); + raw_socket_send(raw_socket_c, buffer, length); + } + + raw_socket_destory(raw_socket_c); + raw_socket_destory(raw_socket_s); + + return 0; +} + /* * nfmsg : message objetc that contains the packet * nfad : Netlink packet data handle @@ -424,6 +525,12 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s if (__ctx->proxy->traffic_steering_options.enable && steering_device_is_available()) { + if (fake_tcp_handshake(__ctx->proxy, &restore_info) == -1) + { + TFE_LOG_ERROR(g_default_logger, "Failed at fake_tcp_handshake()"); + goto end; + } + fd_fake_c = tfe_tcp_restore_fd_create(&(restore_info.client), &(restore_info.server), __ctx->proxy->traffic_steering_options.device_client, __ctx->proxy->traffic_steering_options.so_mask_client); if (fd_fake_c < 0) {