diff options
Diffstat (limited to 'scanner/packet_based_scanner.c')
| -rw-r--r-- | scanner/packet_based_scanner.c | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/scanner/packet_based_scanner.c b/scanner/packet_based_scanner.c new file mode 100644 index 0000000..a2ad540 --- /dev/null +++ b/scanner/packet_based_scanner.c @@ -0,0 +1,357 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "stellar/utils.h" +#include "stellar/packet.h" + +#include "scanner_maat.h" +#include "attribute_kv.h" +#include "attribute_schema.h" +#include "scanner_module.h" +#include "packet_based_scanner.h" + +struct packet_scanner +{ + int exdata_idx; +}; + +int32_t is_duplicate_tag_uuid(uuid_t *tag_uuids, size_t tag_uuids_num, uuid_t tag_uuid) +{ + if(tag_uuids==NULL || tag_uuids_num==0) + { + return FALSE; + } + + for(size_t i=0; i<tag_uuids_num; i++) + { + if(uuid_compare(tag_uuids[i], tag_uuid)==0) + { + return TRUE; + } + } + + return FALSE; +} + +static void ip4_format_to_maat(const struct ip *ip4, struct ip_addr *c_net_addr, struct ip_addr *s_net_addr) +{ + if(ip4==NULL || c_net_addr==NULL || s_net_addr==NULL) + { + return ; + } + + c_net_addr->ip_type=4; + s_net_addr->ip_type=4; + c_net_addr->ipv4=ip4->ip_src.s_addr; + s_net_addr->ipv4=ip4->ip_dst.s_addr; +} + +static void ip6_format_to_maat(const struct ip6_hdr *ip6, struct ip_addr *c_net_addr, struct ip_addr *s_net_addr) +{ + if(ip6==NULL || c_net_addr==NULL || s_net_addr==NULL) + { + return ; + } + + c_net_addr->ip_type=6; + s_net_addr->ip_type=6; + memcpy(c_net_addr->ipv6, ip6->ip6_src.s6_addr, sizeof(c_net_addr->ipv6)); + memcpy(s_net_addr->ipv6, ip6->ip6_dst.s6_addr, sizeof(s_net_addr->ipv6)); +} + +// static void packet_scanner_exdata_free(int idx __unused, void *ex_ptr, void *arg __unused) +// { +// if(ex_ptr==NULL)return; +// FREE(ex_ptr); +// } + +const struct utable_kv *packet_scanner_get_attribute(struct packet_scanner *pkt_scanner, struct packet *pkt, enum ATTRIBUTE_KV_INDEX index) +{ + if(pkt_scanner==NULL || pkt==NULL || index>=ATTRIBUTE_KV_MAX || index<=ATTRIBUTE_KV_UNKNOWN) + { + return NULL; + } + + return attribute_kv_get((struct attribute_kv *)packet_get_exdata(pkt, pkt_scanner->exdata_idx), index); +} + +void attribute_scratch_scan(struct scanner_maat *cm_maat, struct maat_state *scan_state, const char *readable_addr, struct maat_stream **stream_handle, struct attribute_scratch *attribute, size_t n_attribute) +{ + if(cm_maat==NULL || scan_state==NULL || attribute==NULL || n_attribute==0) + { + return ; + } + + for(size_t i=0; i<n_attribute; i++) + { + if(attribute[i].schema==NULL) + { + continue; + } + + switch(attribute[i].value_type) + { + case ATTRIBUTE_VALUE_TYPE_STRING: + scanner_scan_string_attribute(cm_maat, scan_state, attribute[i].string.value, readable_addr, attribute[i].schema->scan_attribute_name, attribute[i].string.value_sz); + break; + case ATTRIBUTE_VALUE_TYPE_INTEGER: + scanner_scan_integer_attribute(cm_maat, scan_state, readable_addr, attribute[i].schema->scan_attribute_name, attribute[i].integer); + break; + case ATTRIBUTE_VALUE_TYPE_FLAG: + scanner_scan_flag_attribute(cm_maat, scan_state, readable_addr, attribute[i].schema->scan_attribute_name, attribute[i].flag); + break; + case ATTRIBUTE_VALUE_TYPE_MAAT_OBJECT: + scanner_scan_object_attribute(cm_maat, scan_state, readable_addr, attribute[i].schema->scan_attribute_name, attribute[i].maat_object.object_uuid, attribute[i].maat_object.item_uuid, attribute[i].maat_object.n_uuid); + break; + case ATTRIBUTE_VALUE_TYPE_IPV4: + scanner_scan_ipv4_attribute(cm_maat, scan_state, readable_addr, attribute[i].schema->scan_attribute_name, attribute[i].ipv4_port.ipv4, attribute[i].ipv4_port.port); + break; + case ATTRIBUTE_VALUE_TYPE_IPV6: + scanner_scan_ipv6_attribute(cm_maat, scan_state, readable_addr, attribute[i].schema->scan_attribute_name, (uint8_t *)(attribute[i].ipv6_port.ipv6), attribute[i].ipv6_port.port); + break; + case ATTRIBUTE_VALUE_TYPE_NOT_LOGIC: + scanner_scan_stream_attribute(cm_maat, scan_state, readable_addr, attribute[i].schema->scan_attribute_name, stream_handle, attribute[i].chunk.value, attribute[i].chunk.value_sz); + break; + default: + break; + } + + if(attribute[i].schema->scan_not_logic_flag==TRUE) + { + scanner_scan_not_logic_attribute(cm_maat, scan_state, readable_addr, attribute[i].schema->scan_attribute_name); + } + } +} + +size_t ipaddr_entry_tag_uuid_get(struct scanner_maat *cm_maat, struct ip_addr *net_ipaddr, uuid_t *tag_uuids, size_t n_tag_uuids) +{ + size_t n_ipaddr_exdata=n_tag_uuids; + struct plugin_entry *ipaddr_exdata[n_ipaddr_exdata]; + int n_exdata=scanner_maat_get0_data_ipaddr_entry(cm_maat, net_ipaddr, ipaddr_exdata, n_ipaddr_exdata); + if(n_exdata==0) + { + return 0; + } + + size_t tag_ids_offset=0; + + for(int i=0; i<n_exdata; i++) + { + if(ipaddr_exdata[i]==NULL || ipaddr_exdata[i]->n_tag_uuids==0) + { + continue; + } + + for(size_t j=0; j<ipaddr_exdata[i]->n_tag_uuids; j++) + { + if(is_duplicate_tag_uuid(tag_uuids, tag_ids_offset, ipaddr_exdata[i]->tag_uuids[j])==TRUE) + { + continue; + } + + if(tag_ids_offset>=n_tag_uuids) + { + break; + } + + uuid_copy(tag_uuids[tag_ids_offset++], ipaddr_exdata[i]->tag_uuids[j]); + } + } + + return tag_ids_offset; +} + +void cs_ipport_attribute_get_from_packet_layer(struct attribute_scratch *attr, size_t attr_max, size_t *attr_offset, struct scanner_maat *cm_maat, struct attribute_schema *attr_schema, const struct layer *layers, int layer_count) +{ + if(attr==NULL || (*attr_offset)>=attr_max || layers==NULL || layer_count<=0) + { + return ; + } + + int32_t c_port=-1, s_port=-1; + struct ip *ip4=NULL; + struct ip6_hdr *ip6=NULL; + struct tcphdr *tcp=NULL; + struct udphdr *udp=NULL; + // uuid_t *ip_protocol_object_uuid=NULL; + struct ip_addr c_net_addr={0}, s_net_addr={0}; + + for(int j=0; j<layer_count; j++) + { + switch(layers[j].proto) + { + case LAYER_PROTO_IPV4: + ip4=(struct ip *)layers[j].hdr.ip4; + ip4_format_to_maat(ip4, &c_net_addr, &s_net_addr); + break; + case LAYER_PROTO_IPV6: + ip6=(struct ip6_hdr *)layers[j].hdr.ip6; + ip6_format_to_maat(ip6, &c_net_addr, &s_net_addr); + break; + case LAYER_PROTO_TCP: + // TODO: implement + // ip_protocol_object_uuid=plugin_shared_ip_protocol_object_uuid_get(ip_proto); + tcp=(struct tcphdr *)layers[j].hdr.tcp; + if(tcp!=NULL) + { + c_port=ntohs(tcp->th_sport); + s_port=ntohs(tcp->th_dport); + } + break; + case LAYER_PROTO_UDP: + // TODO: implement + // ip_protocol_object_uuid=plugin_shared_ip_protocol_object_uuid_get(ip_proto); + udp=(struct udphdr *)layers[j].hdr.udp; + if(udp!=NULL) + { + c_port=ntohs(udp->uh_sport); + s_port=ntohs(udp->uh_dport); + } + break; + case LAYER_PROTO_ICMP: + case LAYER_PROTO_ICMP6: + // TODO: implement + // ip_protocol_object_uuid=plugin_shared_ip_protocol_object_uuid_get(ip_proto); + break; + default: + continue; + } + } + + size_t max_tag_ids=MAX_TAG_IDS_NUM; + uuid_t tag_uuids[max_tag_ids]; + size_t n_tag_uuids=ipaddr_entry_tag_uuid_get(cm_maat, &c_net_addr, tag_uuids, max_tag_ids); + attribute_scratch_maat_object_fill(attr, attr_max, attr_offset, FREE_FALSE, &(attr_schema[ATTRIBUTE_SCHEMA_CLIENT_IP_TAG_UUIDS]), FREE_FALSE, NULL, tag_uuids, n_tag_uuids); + + n_tag_uuids=ipaddr_entry_tag_uuid_get(cm_maat, &s_net_addr, tag_uuids, max_tag_ids); + attribute_scratch_maat_object_fill(attr, attr_max, attr_offset, FREE_FALSE, &(attr_schema[ATTRIBUTE_SCHEMA_SERVER_IP_TAG_UUIDS]), FREE_FALSE, NULL, tag_uuids, n_tag_uuids); + + if(ip4!=NULL) + { + attribute_scratch_ipv4_fill(attr, attr_max, attr_offset, FREE_FALSE, &(attr_schema[ATTRIBUTE_SCHEMA_CLIENT_IP]), FREE_FALSE, ip4->ip_src.s_addr, c_port); + attribute_scratch_ipv4_fill(attr, attr_max, attr_offset, FREE_FALSE, &(attr_schema[ATTRIBUTE_SCHEMA_SERVER_IP]), FREE_FALSE, ip4->ip_dst.s_addr, s_port); + } + + if(ip6!=NULL) + { + attribute_scratch_ipv6_fill(attr, attr_max, attr_offset, FREE_FALSE, &(attr_schema[ATTRIBUTE_SCHEMA_CLIENT_IP]), FREE_FALSE, ip6->ip6_src.s6_addr, c_port); + attribute_scratch_ipv6_fill(attr, attr_max, attr_offset, FREE_FALSE, &(attr_schema[ATTRIBUTE_SCHEMA_SERVER_IP]), FREE_FALSE, ip6->ip6_dst.s6_addr, s_port); + } + + if(c_port!=-1 && s_port!=-1) + { + attribute_scratch_integer_fill(attr, attr_max, attr_offset, FREE_FALSE, &(attr_schema[ATTRIBUTE_SCHEMA_CLIENT_PORT]), FREE_FALSE, (long long)c_port); + attribute_scratch_integer_fill(attr, attr_max, attr_offset, FREE_FALSE, &(attr_schema[ATTRIBUTE_SCHEMA_SERVER_PORT]), FREE_FALSE, (long long)s_port); + } + + // TODO: IP protocol + // if(ip_protocol_object_uuid!=NULL) + // { + // attribute_scratch_maat_object_fill(attr, attr_max, attr_offset, FREE_FALSE, &(attr_schema[ATTRIBUTE_SCHEMA_IP_PROTOCOL]), FREE_FALSE, NULL, &ip_protocol_object_uuid, 1); + // } +} + +void packet_based_scanner_node_entry(struct packet *rawpkt, struct module *mod_scanner) +{ + if(rawpkt==NULL || mod_scanner==NULL) + { + return ; + } + + struct scanner *scanner=(struct scanner *)module_get_ctx(mod_scanner); + if(scanner==NULL) + { + return ; + } + + int pkt_layer_count=packet_get_layer_count(rawpkt); + const struct layer *innermost_layer=packet_get_layer_by_idx(rawpkt, pkt_layer_count-1); + if(innermost_layer==NULL || pkt_layer_count<2) + { + return ; + } + + switch(innermost_layer->proto) + { + case LAYER_PROTO_UDP: + case LAYER_PROTO_TCP: + //TODO: lookup session + break; + case LAYER_PROTO_ICMP: + case LAYER_PROTO_ICMP6: + break; + default: + return ; + } + + struct attribute_kv *attr_kv=attribute_kv_new(); + packet_set_exdata(rawpkt, scanner->pkt_scanner->exdata_idx, (void *)attr_kv); + + struct maat_state *scan_state=maat_state_new(scanner_cm_maat_get_feather(scanner->cm_maat), 1); + + size_t attr_max=128; + size_t attr_offset=0; + struct attribute_scratch attr[attr_max]; + int layers_count=2; + const struct layer *layers=packet_get_layer_by_idx(rawpkt, pkt_layer_count-layers_count); + cs_ipport_attribute_get_from_packet_layer(attr, attr_max, &(attr_offset), scanner->cm_maat, scanner->attr_schema, layers, layers_count); + attribute_scratch_scan(scanner->cm_maat, scan_state, NULL, NULL, attr, attr_offset); + attribute_scratch_reset(attr, attr_offset); + attr_offset=0; + + // TODO: internal external + //int is_client_internal=(packet_get_direction(rawpkt)==PACKET_DIRECTION_OUTGOING) ? TRUE : FALSE; + + attribute_scratch_not_logic_fill(attr, attr_max, &attr_offset, FREE_FALSE, &(scanner->attr_schema[ATTRIBUTE_SCHEMA_CLIENT_IP_COMMIT]), FREE_FALSE); + attribute_scratch_not_logic_fill(attr, attr_max, &attr_offset, FREE_FALSE, &(scanner->attr_schema[ATTRIBUTE_SCHEMA_SERVER_IP_COMMIT]), FREE_FALSE); + attribute_scratch_not_logic_fill(attr, attr_max, &attr_offset, FREE_FALSE, &(scanner->attr_schema[ATTRIBUTE_SCHEMA_CLIENT_PORT_COMMIT]), FREE_FALSE); + attribute_scratch_not_logic_fill(attr, attr_max, &attr_offset, FREE_FALSE, &(scanner->attr_schema[ATTRIBUTE_SCHEMA_SERVER_PORT_COMMIT]), FREE_FALSE); + + attribute_scratch_scan(scanner->cm_maat, scan_state, NULL, NULL, attr, attr_offset); + attribute_scratch_reset(attr, attr_offset); + + return ; +} + +struct maat_state *scanner_get_maat_state_from_packet(struct scanner *scanner, const struct packet *pkt) +{ + if(scanner==NULL || scanner->pkt_scanner==NULL || pkt==NULL) + { + return NULL; + } + + return (struct maat_state *)packet_get_exdata(pkt, scanner->pkt_scanner->exdata_idx); +} + +struct packet_scanner *packet_scanner_new(struct scanner *scanner) +{ + if(scanner==NULL) + { + return NULL; + } + + struct packet_scanner *pkt_scanner=CALLOC(struct packet_scanner, 1); +// // pkt_scanner->exdata_idx=packet_manager_new_packet_exdata_index(pkt_mgr, "SCANNER_EXDATA_SESSION", packet_scanner_exdata_free, (void *)scanner); +// // if(pkt_scanner->exdata_idx<0) +// // { +// // STELLAR_LOG_FATAL(scanner->logger, SCANNER_MODULE_NAME, "packet_scanner_new failed to create exdata index"); +// // goto INIT_ERROR; +// // } + + return pkt_scanner; + +// // INIT_ERROR: +// // packet_scanner_free(pkt_scanner); +// return NULL; +} + +void packet_scanner_free(struct packet_scanner *pkt_scanner) +{ + if(pkt_scanner==NULL) + { + return ; + } + + FREE(pkt_scanner); +}
\ No newline at end of file |
