#include #include #include #include #include #include #include #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; }