TSG-13042 构造三次握手报文,通过原始套接字注入tap_client和tap_server
This commit is contained in:
@@ -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)
|
||||
|
||||
44
common/include/packet_construct.h
Normal file
44
common/include/packet_construct.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef _CONSTRUCT_PACKET_H
|
||||
#define _CONSTRUCT_PACKET_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#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
|
||||
31
common/include/raw_socket.h
Normal file
31
common/include/raw_socket.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef _RAW_SOCKET_H
|
||||
#define _RAW_SOCKET_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <net/ethernet.h>
|
||||
|
||||
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
|
||||
385
common/src/packet_construct.cpp
Normal file
385
common/src/packet_construct.cpp
Normal file
@@ -0,0 +1,385 @@
|
||||
#include <string.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/ether.h>
|
||||
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
}
|
||||
101
common/src/raw_socket.cpp
Normal file
101
common/src/raw_socket.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pcap/pcap.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <tfe_tcp_restore.h>
|
||||
#include <MESA/MESA_prof_load.h>
|
||||
#include <watchdog_3rd_device.h>
|
||||
#include <raw_socket.h>
|
||||
#include <packet_construct.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user