添加cmsg信息时,对IP报文长度进行检查

This commit is contained in:
崔一鸣
2019-06-14 21:40:04 +08:00
parent 02abbae3d9
commit 65b81fb457
3 changed files with 32 additions and 20 deletions

View File

@@ -95,6 +95,7 @@ enum kni_field{
KNI_FIELD_IPV6HDR_PARSE_FAIL, KNI_FIELD_IPV6HDR_PARSE_FAIL,
KNI_FIELD_KEEPALIVE_REPLAY_ADD_SUCC, KNI_FIELD_KEEPALIVE_REPLAY_ADD_SUCC,
KNI_FIELD_KEEPALIVE_REPLAY_ADD_FAIL, KNI_FIELD_KEEPALIVE_REPLAY_ADD_FAIL,
KNI_FIELD_EXCEED_MTU,
}; };
struct kni_field_stat_handle{ struct kni_field_stat_handle{

View File

@@ -306,7 +306,7 @@ MESA_htable_handle kni_create_htable(const char *profile, const char *section, v
return htable; return htable;
} }
char* kni_ipv4_errmsg_get(int _errno){ char* kni_ipv4_errmsg_get(enum kni_ipv4hdr_parse_error _errno){
switch(_errno){ switch(_errno){
case KNI_IPV4HDR_PARSE_ERROR_NULL_PACKET: case KNI_IPV4HDR_PARSE_ERROR_NULL_PACKET:
return (char*)"null packet"; return (char*)"null packet";
@@ -315,7 +315,7 @@ char* kni_ipv4_errmsg_get(int _errno){
} }
} }
char* kni_ipv6_errmsg_get(int _errno){ char* kni_ipv6_errmsg_get(enum kni_ipv6hdr_parse_error _errno){
switch(_errno){ switch(_errno){
case KNI_IPV6HDR_PARSE_ERROR_NULL_PACKET: case KNI_IPV6HDR_PARSE_ERROR_NULL_PACKET:
return (char*)"null packet"; return (char*)"null packet";

View File

@@ -40,6 +40,7 @@ enum stream_error{
STREAM_ERROR_IPV4HDR_PARSE_FAIL = -7, STREAM_ERROR_IPV4HDR_PARSE_FAIL = -7,
STREAM_ERROR_IPV6HDR_PARSE_FAIL = -8, STREAM_ERROR_IPV6HDR_PARSE_FAIL = -8,
STREAM_ERROR_DUP_STREAM = -9, STREAM_ERROR_DUP_STREAM = -9,
STREAM_ERROR_EXCEED_MTU = -10,
}; };
struct http_project{ struct http_project{
@@ -180,11 +181,13 @@ static char* stream_errmsg_get(enum stream_error _errno){
case STREAM_ERROR_INVALID_ACTION: case STREAM_ERROR_INVALID_ACTION:
return (char*)"invalid aciton"; return (char*)"invalid aciton";
case STREAM_ERROR_NO_DATA: case STREAM_ERROR_NO_DATA:
return (char*)""; return (char*)"no data";
case STREAM_ERROR_IPV4HDR_PARSE_FAIL: case STREAM_ERROR_IPV4HDR_PARSE_FAIL:
return (char*)"ipv4 header parse fail"; return (char*)"ipv4 header parse fail";
case STREAM_ERROR_IPV6HDR_PARSE_FAIL: case STREAM_ERROR_IPV6HDR_PARSE_FAIL:
return (char*)"ipv6 header parse fail"; return (char*)"ipv6 header parse fail";
case STREAM_ERROR_EXCEED_MTU:
return (char*)"exceed mtu(1500)";
default: default:
return (char*)"unknown error"; return (char*)"unknown error";
} }
@@ -652,7 +655,7 @@ static char* add_cmsg_to_packet(struct pme_info *pmeinfo, struct pkt_info *pktin
return new_pkt; return new_pkt;
} }
static int send_to_tfe(struct kni_marsio_handle *handle, char *raw_data, uint16_t raw_len, int thread_seq, int tfe_id){ static int send_to_tfe(struct kni_marsio_handle *handle, char *raw_data, uint16_t raw_len, int thread_seq, int tfe_id, addr_type_t addr_type){
void *logger = g_kni_handle->local_logger; void *logger = g_kni_handle->local_logger;
marsio_buff_t *tx_buffs[BURST_MAX]; marsio_buff_t *tx_buffs[BURST_MAX];
struct mr_vdev *dev_eth_handler = handle->tfe_instance_list[tfe_id]->dev_eth_handler; struct mr_vdev *dev_eth_handler = handle->tfe_instance_list[tfe_id]->dev_eth_handler;
@@ -673,7 +676,12 @@ static int send_to_tfe(struct kni_marsio_handle *handle, char *raw_data, uint16_
struct ethhdr *ether_hdr = (struct ethhdr*)dst_data; struct ethhdr *ether_hdr = (struct ethhdr*)dst_data;
memcpy(ether_hdr->h_dest, dst_mac, sizeof(ether_hdr->h_dest)); memcpy(ether_hdr->h_dest, dst_mac, sizeof(ether_hdr->h_dest));
memcpy(ether_hdr->h_source, src_mac, sizeof(ether_hdr->h_source)); memcpy(ether_hdr->h_source, src_mac, sizeof(ether_hdr->h_source));
if(addr_type == ADDR_TYPE_IPV6){
ether_hdr->h_proto = htons(ETH_P_IPV6);
}
else{
ether_hdr->h_proto = htons(ETH_P_IP); ether_hdr->h_proto = htons(ETH_P_IP);
}
memcpy((char*)dst_data + sizeof(*ether_hdr), raw_data, raw_len); memcpy((char*)dst_data + sizeof(*ether_hdr), raw_data, raw_len);
} }
marsio_send_burst(dev_eth_sendpath, thread_seq, tx_buffs, nr_send); marsio_send_burst(dev_eth_sendpath, thread_seq, tx_buffs, nr_send);
@@ -809,10 +817,13 @@ static int first_data_intercept(const struct streaminfo *stream, struct pme_info
//action = KNI_ACTION_INTERCEPT, sendto tfe //action = KNI_ACTION_INTERCEPT, sendto tfe
int len = 0; int len = 0;
char *buf = add_cmsg_to_packet(pmeinfo, pktinfo, &len); char *buf = add_cmsg_to_packet(pmeinfo, pktinfo, &len);
ret = send_to_tfe(g_kni_handle->marsio_handle, buf, len, thread_seq, pmeinfo->tfe_id); ret = send_to_tfe(g_kni_handle->marsio_handle, buf, len, thread_seq, pmeinfo->tfe_id, pmeinfo->addr_type);
if(ret < 0){ if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at send first packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); KNI_LOG_ERROR(logger, "Failed at send first packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid);
} }
else{
KNI_LOG_DEBUG(logger, "Succeed at send first packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid);
}
FREE(&buf); FREE(&buf);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_PKT], 0, FS_OP_ADD, 1); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_PKT], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_STM], 0, FS_OP_ADD, 1); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_STM], 0, FS_OP_ADD, 1);
@@ -848,7 +859,7 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein
ipv4_hdr = (struct iphdr*)a_packet; ipv4_hdr = (struct iphdr*)a_packet;
len = ntohs(ipv4_hdr->tot_len); len = ntohs(ipv4_hdr->tot_len);
} }
ret = send_to_tfe(g_kni_handle->marsio_handle, (char*)a_packet, len, thread_seq, pmeinfo->tfe_id); ret = send_to_tfe(g_kni_handle->marsio_handle, (char*)a_packet, len, thread_seq, pmeinfo->tfe_id, pmeinfo->addr_type);
if(ret < 0){ if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at send continue packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); KNI_LOG_ERROR(logger, "Failed at send continue packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid);
} }
@@ -867,23 +878,26 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein
if(ret < 0){ if(ret < 0){
return APP_STATE_FAWPKT | APP_STATE_DROPME; return APP_STATE_FAWPKT | APP_STATE_DROPME;
} }
//first data > 1500, bypass and dropme
if(pktinfo.ip_totlen > KNI_DEFAULT_MTU){
pmeinfo->error = STREAM_ERROR_EXCEED_MTU;
KNI_LOG_ERROR(logger, "first data packet exceed MTU(1500), bypass and dropme");
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_EXCEED_MTU], 0, FS_OP_ADD, 1);
return APP_STATE_FAWPKT | APP_STATE_DROPME;
}
// syn/ack // syn/ack
if(pktinfo.tcphdr->syn && pktinfo.tcphdr->ack){ if(pktinfo.tcphdr->syn && pktinfo.tcphdr->ack){
pmeinfo->server_window = pktinfo.tcphdr->window; pmeinfo->server_window = pktinfo.tcphdr->window;
pmeinfo->server_tcpopt = kni_get_tcpopt(pktinfo.tcphdr, pktinfo.tcphdr_len); pmeinfo->server_tcpopt = kni_get_tcpopt(pktinfo.tcphdr, pktinfo.tcphdr_len);
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1);
return APP_STATE_FAWPKT | APP_STATE_GIVEME; return APP_STATE_FAWPKT | APP_STATE_GIVEME;
} }
//no data, maybe ack //no data, maybe ack
if(pktinfo.data_len <= 0){ if(pktinfo.data_len <= 0){
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1);
return APP_STATE_FAWPKT | APP_STATE_GIVEME; return APP_STATE_FAWPKT | APP_STATE_GIVEME;
} }
//not double dir, bypass and dropme //not double dir, bypass and dropme
if(stream->dir != DIR_DOUBLE){ if(stream->dir != DIR_DOUBLE){
KNI_LOG_INFO(logger, "dir is %d, bypass, stream addr is %s", stream->dir, stream_addr); KNI_LOG_INFO(logger, "dir is %d, bypass, stream addr is %s", stream->dir, stream_addr);
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1);
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1);
pmeinfo->error = STREAM_ERROR_SINGLE_DIR; pmeinfo->error = STREAM_ERROR_SINGLE_DIR;
return APP_STATE_FAWPKT | APP_STATE_DROPME; return APP_STATE_FAWPKT | APP_STATE_DROPME;
} }
@@ -896,8 +910,6 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein
case KNI_PROTOCOL_UNKNOWN: case KNI_PROTOCOL_UNKNOWN:
KNI_LOG_INFO(logger, "Failed at protocol_identify, bypass and dropme, stream addr is %s\n", KNI_LOG_INFO(logger, "Failed at protocol_identify, bypass and dropme, stream addr is %s\n",
pmeinfo->protocol, stream_addr); pmeinfo->protocol, stream_addr);
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1);
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_UNKNOWN_STM], 0, FS_OP_ADD, 1); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_UNKNOWN_STM], 0, FS_OP_ADD, 1);
pmeinfo->error = STREAM_ERROR_PROTOCOL_UNKNOWN; pmeinfo->error = STREAM_ERROR_PROTOCOL_UNKNOWN;
return APP_STATE_FAWPKT | APP_STATE_DROPME; return APP_STATE_FAWPKT | APP_STATE_DROPME;
@@ -917,15 +929,13 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein
thread_seq, &(pmeinfo->policy_id), &(pmeinfo->maat_hit)); thread_seq, &(pmeinfo->policy_id), &(pmeinfo->maat_hit));
//policy scan log //policy scan log
char *action_str = kni_maat_action_trans(pmeinfo->action); char *action_str = kni_maat_action_trans(pmeinfo->action);
KNI_LOG_DEBUG(logger, "intercept_policy_scan: %s, %s, policy_id = %d, action = %d(%s), maat_hit = %d", KNI_LOG_DEBUG(logger, "intercept_policy_scan: %s, %s, policy_id = %d, action = %d(%s), maat_hit = %d, stream traceid is %s",
stream_addr, protocol_identify_res.domain, pmeinfo->policy_id, pmeinfo->action, action_str, pmeinfo->maat_hit); stream_addr, protocol_identify_res.domain, pmeinfo->policy_id, pmeinfo->action, action_str, pmeinfo->maat_hit, pmeinfo->stream_traceid);
//receive client hello, but no syn/ack, bypass and dropme //receive client hello, but no syn/ack, bypass and dropme
if(pmeinfo->client_tcpopt == NULL || pmeinfo->server_tcpopt == NULL){ if(pmeinfo->client_tcpopt == NULL || pmeinfo->server_tcpopt == NULL){
KNI_LOG_ERROR(logger, "Failed at intercept, %s, %s, stream traceid is %s", pmeinfo->client_tcpopt == NULL ? "no syn" : "have syn", KNI_LOG_ERROR(logger, "Failed at intercept, %s, %s, stream traceid is %s", pmeinfo->client_tcpopt == NULL ? "no syn" : "have syn",
pmeinfo->server_tcpopt == NULL ? "no syn/ack" : "have syn/ack", pmeinfo->stream_traceid); pmeinfo->server_tcpopt == NULL ? "no syn/ack" : "have syn/ack", pmeinfo->stream_traceid);
FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NO_SA_EXP], 0, FS_OP_ADD, 1); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NO_SA_EXP], 0, FS_OP_ADD, 1);
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1);
//FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1);
pmeinfo->error = STREAM_ERROR_NO_SYN_ACK; pmeinfo->error = STREAM_ERROR_NO_SYN_ACK;
return APP_STATE_FAWPKT | APP_STATE_DROPME; return APP_STATE_FAWPKT | APP_STATE_DROPME;
} }
@@ -961,10 +971,10 @@ static char close_opstate(const struct streaminfo *stream, struct pme_info *pmei
strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid))); strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid)));
return APP_STATE_DROPPKT | APP_STATE_DROPME; return APP_STATE_DROPPKT | APP_STATE_DROPME;
case KNI_ACTION_BYPASS: case KNI_ACTION_BYPASS:
KNI_LOG_DEBUG(logger, "set tfe_release = 1, stream_trace_id is %s", pmeinfo->stream_traceid); KNI_LOG_DEBUG(logger, "action is bypass, set tfe_release = 1, stream_trace_id is %s", pmeinfo->stream_traceid);
pmeinfo->tfe_release = 1; pmeinfo->tfe_release = 1;
return APP_STATE_FAWPKT | APP_STATE_DROPME; return APP_STATE_FAWPKT | APP_STATE_DROPME;
//stream has only syn, ack. not data. do not send to tfe //stream has only syn, ack. no data.
default: default:
char *action_str = kni_maat_action_trans(pmeinfo->action); char *action_str = kni_maat_action_trans(pmeinfo->action);
pmeinfo->error = STREAM_ERROR_NO_DATA; pmeinfo->error = STREAM_ERROR_NO_DATA;
@@ -1178,7 +1188,7 @@ static long keepalive_replay_search_cb(void *data, const uchar *key, uint size,
replay_packet_iphdr->saddr, replay_packet_iphdr->daddr); replay_packet_iphdr->saddr, replay_packet_iphdr->daddr);
} }
//send to tfe: thread_seq = g_iThreadNum //send to tfe: thread_seq = g_iThreadNum
int ret = send_to_tfe(marsio_handle, replay_packet, tot_len, g_iThreadNum + thread_seq, tfe_id); int ret = send_to_tfe(marsio_handle, replay_packet, tot_len, g_iThreadNum + thread_seq, tfe_id, args->addr_type);
if(ret < 0){ if(ret < 0){
KNI_LOG_ERROR(logger, "Failed at send keepalive replay packet to tfe"); KNI_LOG_ERROR(logger, "Failed at send keepalive replay packet to tfe");
} }
@@ -1616,6 +1626,7 @@ static struct kni_field_stat_handle * fs_init(const char *profile){
fs_handle->fields[KNI_FIELD_IPV6HDR_PARSE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ipv6hdr_parse_fail"); fs_handle->fields[KNI_FIELD_IPV6HDR_PARSE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ipv6hdr_parse_fail");
fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "kaReplay_add_fail"); fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "kaReplay_add_fail");
fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "kaReplay_add_succ"); fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "kaReplay_add_succ");
fs_handle->fields[KNI_FIELD_EXCEED_MTU] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "exceed_mtu");
fs_handle->handle = handle; fs_handle->handle = handle;
FS_start(handle); FS_start(handle);
return fs_handle; return fs_handle;