summaryrefslogtreecommitdiff
path: root/scanner/scanner_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'scanner/scanner_module.c')
-rw-r--r--scanner/scanner_module.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/scanner/scanner_module.c b/scanner/scanner_module.c
new file mode 100644
index 0000000..0ecb6c8
--- /dev/null
+++ b/scanner/scanner_module.c
@@ -0,0 +1,270 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <uuid/uuid.h>
+#include <sys/ioctl.h>
+
+#include "uthash/utarray.h"
+#include <yyjson/yyjson.h>
+
+#include "stellar/utils.h"
+#include "stellar/scanner.h"
+#include "stellar/session.h"
+
+#include "scanner_toml.h"
+#include "scanner_maat.h"
+#include "scanner_module.h"
+#include "packet_based_scanner.h"
+#include "session_based_scanner.h"
+
+void device_sn_value_parser(char *filename, char *device_sn, size_t device_sn_sz)
+{
+ if(filename==NULL || device_sn==NULL || device_sn_sz==0)
+ {
+ return ;
+ }
+
+ // using yyjson_read_file yyjson parser device_sn
+ yyjson_doc *doc=yyjson_read_file(filename, 0, NULL, NULL);
+ if(doc==NULL)
+ {
+ return ;
+ }
+
+ yyjson_val *root=yyjson_doc_get_root(doc);
+ if(root==NULL)
+ {
+ goto ERROR;
+ }
+
+ yyjson_val *sn=yyjson_obj_get(root, "sn");
+ if(sn==NULL)
+ {
+ goto ERROR;
+ }
+
+ size_t sn_sz=yyjson_get_len(sn);
+ memcpy(device_sn, yyjson_get_str(sn), MIN(sn_sz, device_sn_sz-1));
+
+ERROR:
+ yyjson_doc_free(doc);
+ doc=NULL;
+}
+
+int device_nic_name_to_ipv4(const char *nic_name, char *ipv4, size_t ipv4_sz, struct logger *logger)
+{
+ int fd=socket(AF_INET, SOCK_DGRAM, 0);
+ if(fd<0)
+ {
+ STELLAR_LOG_FATAL(logger, SCANNER_MODULE_NAME, "device_nic_name_to_ipv4(%s), socket: %s", nic_name, strerror(errno));
+ return -1;
+ }
+
+ struct ifreq ifr;
+ memset(ifr.ifr_ifrn.ifrn_name, 0, sizeof(ifr.ifr_ifrn.ifrn_name));
+ strncpy(ifr.ifr_ifrn.ifrn_name, nic_name, sizeof(ifr.ifr_ifrn.ifrn_name));
+ if(ioctl(fd, SIOCGIFADDR, &ifr)==-1)
+ {
+ STELLAR_LOG_FATAL(logger, SCANNER_MODULE_NAME, "device_nic_name_to_ipv4(%s), ioctl SIOCGIFADDR: %s", nic_name, strerror(errno));
+ }
+ else
+ {
+ // inet_ntop(AF_INET, &((ifr.ifr_ifru.ifru_addr)->sin_addr.s_addr), ipv4, ipv4_sz);
+ inet_ntop(AF_INET, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr, ipv4, ipv4_sz);
+ }
+
+ close(fd);
+
+ return 1;
+}
+
+void global_parameter_get(struct logger *logger, const char *toml_path, const char *table_key, struct global_parameter *para)
+{
+ toml_int_get(logger, toml_path, table_key, "traffic_vsystem_id", &(para->traffic_vsystem_id));
+ toml_int_get(logger, toml_path, table_key, "default_unknown_app_id", &(para->default_unknown_app_id));
+ toml_int_get(logger, toml_path, table_key, "session_record_enabled", &(para->session_record_enabled));
+
+ toml_string_get(logger, toml_path, table_key, "device_tag", para->device_tag, sizeof(para->device_tag));
+ toml_string_get(logger, toml_path, table_key, "device_group", para->device_group, sizeof(para->device_group));
+ toml_string_get(logger, toml_path, table_key, "data_center", para->data_center, sizeof(para->data_center));
+
+ char override_sled_ip[NAME_MAX]={0};
+ toml_string_get(logger, toml_path, table_key, "override_sled_ip", override_sled_ip, sizeof(override_sled_ip));
+ char *sled_ip=getenv(override_sled_ip);
+ if(sled_ip==NULL)
+ {
+ char nic_name[32]={0};
+ toml_string_get(logger, toml_path, table_key, "nic_name", nic_name, sizeof(nic_name));
+ device_nic_name_to_ipv4(nic_name, para->sled_ip,sizeof(para->sled_ip), logger);
+ }
+ else
+ {
+ memcpy(para->sled_ip, sled_ip, MIN(sizeof(para->sled_ip)-1, strlen(sled_ip)));
+ }
+
+ char device_sn_filename[NAME_MAX]={0};
+ toml_string_get(logger, toml_path, table_key, "device_sn_filename", device_sn_filename, sizeof(device_sn_filename));
+ device_sn_value_parser(device_sn_filename, para->device_sn, sizeof(para->device_sn));
+}
+
+void scanner_print_debug_hit_rule(struct scanner *scanner, const char *readable_addr, const char *tablename, uuid_t *rule_uuid_list, size_t rule_uuid_num)
+{
+ if(rule_uuid_num==0)
+ {
+ return ;
+ }
+
+ yyjson_mut_doc *doc=yyjson_mut_doc_new(NULL);
+ yyjson_mut_val *root=yyjson_mut_obj(doc);
+ yyjson_mut_doc_set_root(doc, root);
+ yyjson_mut_obj_add_str(doc, root, "addr", ((readable_addr!=NULL) ? readable_addr : ""));
+ yyjson_mut_val *rule_array=yyjson_mut_arr(doc);
+ for(size_t i=0; i<rule_uuid_num; i++)
+ {
+ char rule_uuid_str[UUID_STR_LEN]={0};
+ uuid_unparse_lower(rule_uuid_list[i], rule_uuid_str);
+ yyjson_mut_arr_add_strcpy(doc, rule_array, rule_uuid_str);
+ }
+
+ yyjson_mut_obj_add_val(doc, root, tablename, rule_array);
+
+ char *json_str=yyjson_mut_write(doc, 0, NULL);
+ yyjson_mut_doc_free(doc);
+ STELLAR_LOG_INFO(scanner->logger, SCANNER_MODULE_NAME, "debug_hitted_rule_print: %s", json_str);
+ FREE(json_str);
+}
+
+void scanner_print_debug_hit_object(struct scanner *scanner, const char *readable_addr, struct maat_hit_object *hit_object_list, size_t hit_object_num)
+{
+ if(hit_object_num==0)
+ {
+ return ;
+ }
+
+ yyjson_mut_doc *doc=yyjson_mut_doc_new(NULL);
+ yyjson_mut_val *root=yyjson_mut_obj(doc);
+ yyjson_mut_doc_set_root(doc, root);
+ yyjson_mut_obj_add_str(doc, root, "addr", ((readable_addr!=NULL) ? readable_addr : ""));
+ yyjson_mut_val *hit_object_array=yyjson_mut_arr(doc);
+ for(size_t i=0; i<hit_object_num; i++)
+ {
+ yyjson_mut_val *hit_object_object=yyjson_mut_obj(doc);
+
+ if(uuid_is_null(hit_object_list[i].item_uuid)==0)
+ {
+ char item_uuid_str[UUID_STR_LEN]={0};
+ uuid_unparse_lower(hit_object_list[i].item_uuid, item_uuid_str);
+ yyjson_mut_obj_add_strcpy(doc, hit_object_object, "item_uuid", item_uuid_str);
+ }
+
+ char object_uuid_str[UUID_STR_LEN]={0};
+ uuid_unparse_lower(hit_object_list[i].object_uuid, object_uuid_str);
+ yyjson_mut_obj_add_strcpy(doc, hit_object_object, "object_uuid", object_uuid_str);
+
+ if(hit_object_list[i].attribute_name!=NULL)
+ {
+ yyjson_mut_obj_add_str(doc, hit_object_object, "attribute_name", hit_object_list[i].attribute_name);
+ }
+
+ yyjson_mut_arr_add_val(hit_object_array, hit_object_object);
+ }
+
+ yyjson_mut_obj_add_val(doc, root, "hits_object", hit_object_array);
+
+ char *json_str=yyjson_mut_write(doc, 0, NULL);
+ yyjson_mut_doc_free(doc);
+ STELLAR_LOG_INFO(scanner->logger, SCANNER_MODULE_NAME, "debug_hit_object_print: %s", json_str);
+ FREE(json_str);
+}
+
+uuid_t *scanner_get_ip_protocol_object_uuid(struct scanner *scanner, enum IP_PROTOCOL ipproto)
+{
+ switch(ipproto)
+ {
+ case IP_PROTOCOL_TCP:
+ case IP_PROTOCOL_UDP:
+ case IP_PROTOCOL_ICMP:
+ return &(scanner->default_para.ip_protocol_object_uuid[ipproto]);
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+uuid_t *scanner_get0_boolean_object_uuid(struct scanner *scanner, bool value)
+{
+ return ((value==true) ? &(scanner->default_para.boolean_true_object_uuid) : &(scanner->default_para.boolean_false_object_uuid));
+}
+
+void scanner_default_parameter_init(struct default_parameter *para)
+{
+ uuid_parse("00000000-0000-0000-0000-000000000002", para->boolean_true_object_uuid);
+ uuid_parse("00000000-0000-0000-0000-000000000003", para->boolean_false_object_uuid);
+
+ uuid_parse("00000000-0000-0000-0000-000000000005", para->ip_protocol_object_uuid[IP_PROTOCOL_ICMP]);
+ uuid_parse("00000000-0000-0000-0000-000000000006", para->ip_protocol_object_uuid[IP_PROTOCOL_TCP]);
+ uuid_parse("00000000-0000-0000-0000-000000000007", para->ip_protocol_object_uuid[IP_PROTOCOL_UDP]);
+}
+
+struct maat *scanner_get_maat_instance(struct scanner *scanner)
+{
+ if(scanner==NULL)
+ {
+ return NULL;
+ }
+
+ return scanner_cm_maat_get_feather(scanner->cm_maat);
+}
+
+struct scanner *scanner_module_to_scanner(struct module *mod)
+{
+ if(mod==NULL)return NULL;
+ if(strcmp(module_get_name(mod), SCANNER_MODULE_NAME)!=0)return NULL;
+ return (struct scanner *)module_get_ctx(mod);
+}
+
+void scanner_module_exit(struct module_manager *mod_mgr, struct module *mod)
+{
+ if(mod_mgr==NULL)return;
+ if(mod)
+ {
+ struct scanner *scanner=(struct scanner *)module_get_ctx(mod);
+ FREE(scanner);
+ module_free(mod);
+ }
+}
+
+struct module *scanner_module_init(struct module_manager *mod_mgr)
+{
+ if(mod_mgr==NULL)return NULL;
+
+ struct scanner *scanner=CALLOC(struct scanner, 1);
+ struct module *mod=module_new(SCANNER_MODULE_NAME, (void *)scanner);
+ if(mod==NULL)
+ {
+ goto INIT_ERROR;
+ }
+
+ scanner->mod_mgr=mod_mgr;
+ scanner->logger=module_manager_get_logger(mod_mgr);
+ scanner_default_parameter_init(&(scanner->default_para));
+ attribute_schema_init(scanner->attr_schema, ATTRIBUTE_SCHEMA_MAX);
+
+ const char *toml_path=module_manager_get_toml_path(mod_mgr);
+ global_parameter_get(scanner->logger, toml_path, "scanner", &(scanner->global_para));
+
+ scanner->pkt_scanner=packet_scanner_new(scanner);
+ scanner->sess_scanner=session_scanner_new(scanner);
+
+ return mod;
+
+INIT_ERROR:
+ scanner_module_exit(mod_mgr, mod);
+ exit(-1);
+ return NULL;
+} \ No newline at end of file