217 lines
11 KiB
C++
217 lines
11 KiB
C++
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/mman.h>
|
|
#include <msgpack.h>
|
|
|
|
#include "tfe_cmsg.h"
|
|
#include "tfe_utils.h"
|
|
#include "tfe_ctrl_packet.h"
|
|
|
|
enum ctr_pkt_index
|
|
{
|
|
INDEX_TSYNC = 0,
|
|
INDEX_SESSION_ID,
|
|
INDEX_STATE,
|
|
INDEX_METHOD,
|
|
INDEX_SCE,
|
|
INDEX_SHAPER,
|
|
INDEX_PROXY,
|
|
INDEX_MAX
|
|
};
|
|
|
|
struct mpack_mmap_id2type
|
|
{
|
|
int id;
|
|
enum tfe_cmsg_tlv_type type;
|
|
char *str_name;
|
|
int size;
|
|
}mpack_table[] = {
|
|
{.id = 0, .type = TFE_CMSG_POLICY_ID, .str_name = "TFE_CMSG_POLICY_ID", .size = 8},
|
|
{.id = 1, .type = TFE_CMSG_TCP_RESTORE_SEQ, .str_name = "TFE_CMSG_TCP_RESTORE_SEQ", .size = 4},
|
|
{.id = 2, .type = TFE_CMSG_TCP_RESTORE_ACK, .str_name = "TFE_CMSG_TCP_RESTORE_ACK", .size = 4},
|
|
{.id = 3, .type = TFE_CMSG_TCP_RESTORE_MSS_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_MSS_CLIENT", .size = 2},
|
|
{.id = 4, .type = TFE_CMSG_TCP_RESTORE_MSS_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_MSS_SERVER", .size = 2},
|
|
{.id = 5, .type = TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT", .size = 1},
|
|
{.id = 6, .type = TFE_CMSG_TCP_RESTORE_WSACLE_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_WSACLE_SERVER", .size = 1},
|
|
{.id = 7, .type = TFE_CMSG_TCP_RESTORE_SACK_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_SACK_CLIENT", .size = 1},
|
|
{.id = 8, .type = TFE_CMSG_TCP_RESTORE_SACK_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_SACK_SERVER", .size = 1},
|
|
{.id = 9, .type = TFE_CMSG_TCP_RESTORE_TS_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_TS_CLIENT", .size = 1},
|
|
{.id = 10, .type = TFE_CMSG_TCP_RESTORE_TS_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_TS_SERVER", .size = 1},
|
|
{.id = 11, .type = TFE_CMSG_TCP_RESTORE_PROTOCOL, .str_name = "TFE_CMSG_TCP_RESTORE_PROTOCOL", .size = 1},
|
|
{.id = 12, .type = TFE_CMSG_TCP_RESTORE_WINDOW_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_WINDOW_CLIENT", .size = 2},
|
|
{.id = 13, .type = TFE_CMSG_TCP_RESTORE_WINDOW_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_WINDOW_SERVER", .size = 2},
|
|
{.id = 14, .type = TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL, .str_name = "TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL", .size = 4},
|
|
{.id = 15, .type = TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL, .str_name = "TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL", .size = 4},
|
|
{.id = 16, .type = TFE_CMSG_TCP_RESTORE_INFO_PACKET_CUR_DIR, .str_name = "TFE_CMSG_TCP_RESTORE_INFO_PACKET_CUR_DIR", .size = 1},
|
|
{.id = 17, .type = TFE_CMSG_SRC_SUB_ID, .str_name = "TFE_CMSG_SRC_SUB_ID", .size = 256},
|
|
{.id = 18, .type = TFE_CMSG_DST_SUB_ID, .str_name = "TFE_CMSG_DST_SUB_ID", .size = 256},
|
|
{.id = 19, .type = TFE_CMSG_SRC_ASN, .str_name = "TFE_CMSG_SRC_ASN", .size = 64},
|
|
{.id = 20, .type = TFE_CMSG_DST_ASN, .str_name = "TFE_CMSG_DST_ASN", .size = 64},
|
|
{.id = 21, .type = TFE_CMSG_SRC_ORGANIZATION, .str_name = "TFE_CMSG_SRC_ORGANIZATION", .size = 256},
|
|
{.id = 22, .type = TFE_CMSG_DST_ORGANIZATION, .str_name = "TFE_CMSG_DST_ORGANIZATION", .size = 256},
|
|
{.id = 23, .type = TFE_CMSG_SRC_IP_LOCATION_COUNTRY, .str_name = "TFE_CMSG_SRC_IP_LOCATION_COUNTRY", .size = 256},
|
|
{.id = 24, .type = TFE_CMSG_DST_IP_LOCATION_COUNTRY, .str_name = "TFE_CMSG_DST_IP_LOCATION_COUNTRY", .size = 256},
|
|
{.id = 25, .type = TFE_CMSG_SRC_IP_LOCATION_PROVINE, .str_name = "TFE_CMSG_SRC_IP_LOCATION_PROVINE", .size = 256},
|
|
{.id = 26, .type = TFE_CMSG_DST_IP_LOCATION_PROVINE, .str_name = "TFE_CMSG_DST_IP_LOCATION_PROVINE", .size = 256},
|
|
{.id = 27, .type = TFE_CMSG_SRC_IP_LOCATION_CITY, .str_name = "TFE_CMSG_SRC_IP_LOCATION_CITY", .size = 256},
|
|
{.id = 28, .type = TFE_CMSG_DST_IP_LOCATION_CITY, .str_name = "TFE_CMSG_DST_IP_LOCATION_CITY", .size = 256},
|
|
{.id = 29, .type = TFE_CMSG_SRC_IP_LOCATION_SUBDIVISION, .str_name = "TFE_CMSG_SRC_IP_LOCATION_SUBDIVISION", .size = 256},
|
|
{.id = 30, .type = TFE_CMSG_DST_IP_LOCATION_SUBDIVISION, .str_name = "TFE_CMSG_DST_IP_LOCATION_SUBDIVISION", .size = 256},
|
|
{.id = 31, .type = TFE_CMSG_SSL_CLIENT_JA3_FINGERPRINT, .str_name = "TFE_CMSG_SSL_CLIENT_JA3_FINGERPRINT", .size = 32},
|
|
{.id = 32, .type = TFE_CMSG_FQDN_CAT_ID_VAL, .str_name = "TFE_CMSG_FQDN_CAT_ID_VAL", .size = 4}
|
|
};
|
|
|
|
static int proxy_parse_messagepack(msgpack_object obj, void *ctx)
|
|
{
|
|
struct ctrl_pkt_parser *handler = (struct ctrl_pkt_parser *)ctx;
|
|
uint32_t fqdn_val[8] = {0};
|
|
|
|
for (unsigned int i = 0; i < obj.via.array.size; i++) {
|
|
msgpack_object ptr = obj.via.array.ptr[i];
|
|
|
|
if (i == 0) {
|
|
if (ptr.type == MSGPACK_OBJECT_ARRAY) {
|
|
handler->tfe_policy_id_num = ptr.via.array.size;
|
|
for (uint32_t j = 0; j < ptr.via.array.size; j++) {
|
|
handler->tfe_policy_ids[j] = ptr.via.array.ptr[j].via.u64;
|
|
}
|
|
tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)&handler->tfe_policy_ids[0], sizeof(uint64_t));
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: interger msgpack cmsg: [%s] num: [%d]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, handler->tfe_policy_id_num);
|
|
for (int j = 0; j < handler->tfe_policy_id_num; j++) {
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: policy id:%lu ", LOG_TAG_CTRLPKT, handler->tfe_policy_ids[j]);
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
|
|
switch (ptr.type) {
|
|
case MSGPACK_OBJECT_POSITIVE_INTEGER:
|
|
tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)&ptr.via.u64, mpack_table[i].size);
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: interger msgpack cmsg: [%s] -> [%lu]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, ptr.via.u64);
|
|
break;
|
|
case MSGPACK_OBJECT_STR:
|
|
tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)ptr.via.str.ptr, ptr.via.str.size);
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: string msgpack cmsg: [%s] -> [%s]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, ptr.via.str.ptr);
|
|
break;
|
|
case MSGPACK_OBJECT_ARRAY:
|
|
if (i == 32) {
|
|
tfe_cmsg_set(handler->cmsg, TFE_CMSG_FQDN_CAT_ID_NUM, (const unsigned char *)&ptr.via.array.size, sizeof(uint32_t));
|
|
for (uint32_t j = 0; j < ptr.via.array.size; j++) {
|
|
fqdn_val[j] = ptr.via.array.ptr[j].via.u64;
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: array msgpack cmsg: [%s] -> [%lu]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, ptr.via.array.ptr[j].via.u64);
|
|
}
|
|
tfe_cmsg_set(handler->cmsg ,TFE_CMSG_FQDN_CAT_ID_VAL, (const unsigned char*)fqdn_val, ptr.via.array.size * sizeof(uint32_t));
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int parse_messagepack(const char* data, size_t length, void *ctx)
|
|
{
|
|
struct ctrl_pkt_parser *handler = (struct ctrl_pkt_parser *)ctx;
|
|
size_t off = 0;
|
|
|
|
msgpack_unpacked unpacked;
|
|
msgpack_unpacked_init(&unpacked);
|
|
|
|
msgpack_unpack_return ret = msgpack_unpack_next(&unpacked, data, length, &off);
|
|
if (ret != MSGPACK_UNPACK_SUCCESS) {
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: data[%s]", LOG_TAG_CTRLPKT, data);
|
|
return -1;
|
|
}
|
|
|
|
msgpack_object obj = unpacked.data;
|
|
if (obj.type != MSGPACK_OBJECT_ARRAY || obj.via.array.size < INDEX_PROXY) {
|
|
// TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: msgpack type[%02x], array size:%d", LOG_TAG_CTRLPKT, obj.type, obj.via.array.size);
|
|
return -1;
|
|
}
|
|
|
|
for (unsigned int i = 0; i < obj.via.array.size; i++) {
|
|
msgpack_object ptr = obj.via.array.ptr[i];
|
|
switch (i) {
|
|
case INDEX_TSYNC:
|
|
if (ptr.type == MSGPACK_OBJECT_STR) {
|
|
memcpy(handler->tsync, ptr.via.str.ptr, ptr.via.str.size);
|
|
}
|
|
else {
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid tsync type) %02x", LOG_TAG_CTRLPKT, ptr.type);
|
|
}
|
|
break;
|
|
case INDEX_SESSION_ID:
|
|
if (ptr.type == MSGPACK_OBJECT_STR) {
|
|
char session_id[64] = {0};
|
|
memcpy(session_id, ptr.via.str.ptr, ptr.via.str.size);
|
|
handler->session_id = atoll(session_id);
|
|
}
|
|
else {
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid session id type) %02x", LOG_TAG_CTRLPKT, ptr.type);
|
|
}
|
|
break;
|
|
case INDEX_STATE:
|
|
if (ptr.type == MSGPACK_OBJECT_STR) {
|
|
if (strncasecmp(ptr.via.str.ptr, "opening", ptr.via.str.size) == 0)
|
|
{
|
|
handler->state = SESSION_STATE_OPENING;
|
|
}
|
|
else if (strncasecmp(ptr.via.str.ptr, "active", ptr.via.str.size) == 0)
|
|
{
|
|
handler->state = SESSION_STATE_ACTIVE;
|
|
}
|
|
else if (strncasecmp(ptr.via.str.ptr, "closing", ptr.via.str.size) == 0)
|
|
{
|
|
handler->state = SESSION_STATE_CLOSING;
|
|
}
|
|
else if (strncasecmp(ptr.via.str.ptr, "resetall", ptr.via.str.size) == 0)
|
|
{
|
|
handler->state = SESSION_STATE_RESETALL;
|
|
}
|
|
else
|
|
{
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid state value) %s", LOG_TAG_CTRLPKT, ptr.via.str.ptr);
|
|
}
|
|
}
|
|
else {
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid state type) %02x", LOG_TAG_CTRLPKT, ptr.type);
|
|
}
|
|
break;
|
|
case INDEX_METHOD:
|
|
if (ptr.type == MSGPACK_OBJECT_STR) {
|
|
memcpy(handler->method, ptr.via.str.ptr, ptr.via.str.size);
|
|
}
|
|
else {
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid method type) %02x", LOG_TAG_CTRLPKT, ptr.type);
|
|
}
|
|
break;
|
|
case INDEX_SCE:
|
|
if (ptr.type == MSGPACK_OBJECT_ARRAY) {
|
|
msgpack_object rule_id = ptr.via.array.ptr[0];
|
|
handler->sce_policy_id_num = rule_id.via.array.size;
|
|
for (uint32_t j = 0; j < rule_id.via.array.size; j++) {
|
|
handler->sce_policy_ids[j] = rule_id.via.array.ptr[j].via.u64;
|
|
}
|
|
}
|
|
break;
|
|
case INDEX_SHAPER:
|
|
break;
|
|
case INDEX_PROXY:
|
|
if (ptr.type == MSGPACK_OBJECT_ARRAY) {
|
|
proxy_parse_messagepack(ptr, handler);
|
|
}
|
|
else {
|
|
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid proxy type) %02x", LOG_TAG_CTRLPKT, ptr.type);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|