diff options
| author | liuxueli <[email protected]> | 2019-11-01 18:02:52 +0800 |
|---|---|---|
| committer | liuxueli <[email protected]> | 2019-11-01 18:02:52 +0800 |
| commit | 0bcaeed0b040ceee1eba686c321dbe17db0fca5c (patch) | |
| tree | e632a733d963c55b9118c7464b4b32e8bb6af0e9 | |
create version
| -rw-r--r-- | bin/ntc_radius_plug.inf | 12 | ||||
| -rw-r--r-- | src/Makefile | 24 | ||||
| -rw-r--r-- | src/ntc_radius_plug.cpp | 357 | ||||
| -rw-r--r-- | src/ntc_radius_plug.h | 32 |
4 files changed, 425 insertions, 0 deletions
diff --git a/bin/ntc_radius_plug.inf b/bin/ntc_radius_plug.inf new file mode 100644 index 0000000..f883cb0 --- /dev/null +++ b/bin/ntc_radius_plug.inf @@ -0,0 +1,12 @@ +[PLUGINFO] +PLUGNAME=RADIUS +SO_PATH=./plug/business/radius/radius.so +INIT_FUNC=RADIUS_INIT +DESTROY_FUNC=RADIUS_DESTROY +FLAGCHANGE_FUNC=FLAG_CHANGE +FLAGSTATE_FUNC=PROT_FUNSTAT +GETPLUGID_FUNC=GET_PLUGID + +[UDP] +FUNC_FLAG=ALL +FUNC_NAME=RADIUS_ENTRY diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..29742d2 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,24 @@ +CC = g++ +CCC = g++ +CFLAGS = -Wall -g -fPIC +INC = -I/opt/MESA/include/MESA/ +LDFLAGS = -L/opt/MESA/lib/ +LIBS = -lMESA_handle_logger -lMESA_prof_load -lcjson +OBJ = ntc_radius_plug.o +TARGET = ntc_radius_plug.so + +.c.o: + $(CC) -c $(CFLAGS) $< $(INC) +.cpp.o: + $(CCC) -c $(CFLAGS) $(INC) $< + +all: $(TARGET) + +$(TARGET): $(OBJ) + $(CCC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS) -shared + cp $(TARGET) ../bin/ + +clean: + -rm -rf $(OBJ) $(TARGET) + +.PHONY:clean diff --git a/src/ntc_radius_plug.cpp b/src/ntc_radius_plug.cpp new file mode 100644 index 0000000..28f1c51 --- /dev/null +++ b/src/ntc_radius_plug.cpp @@ -0,0 +1,357 @@ +#include <stdio.h> +#include <string.h> +#include <sys/socket.h>//inet_addr +#include <netinet/in.h>//inet_addr +#include <arpa/inet.h>//inet_addr +#include <net/if.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <assert.h> + +#include <time.h> + +#include <arpa/inet.h> +#include <MESA/MESA_prof_load.h> +#include <MESA/MESA_handle_logger.h> +#include <MESA/stream.h> + +#include <MESA/Maat_rule.h> +#include <MESA/field_stat2.h> +#include <MESA/cJSON.h> + +#include <MESA/radius.h> +#include <MESA/rdkafka.h> + +#include "ntc_radius_plug.h" + +static int NTC_RADIUS_PLUG_VERSION_20191022=0; +const char *config_file="t1conf/main.conf"; +g_ntc_radius_plug_t g_ntc_radius_plug; + + +void set_one_maat_rule(Maat_rule_t *maat_rule) +{ + maat_rule->action=1; + maat_rule->config_id=0;//0 + maat_rule->do_blacklist=0; + maat_rule->do_log=1; + maat_rule->service_id=0xA2; +} + +static unsigned int get_ip_by_eth_name(const char *ifname) +{ + int sockfd; + struct ifreq ifr; + unsigned int ip; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (-1 == sockfd) { + goto error; + } + + strcpy(ifr.ifr_name,ifname); + if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) { + goto error; + } + + ip = ((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr.s_addr; + close(sockfd); + return ip; + +error: + close(sockfd); + return INADDR_NONE; +} + + +int get_radius_object_element(cJSON *radius_info_object, radius_header_t *radius_header, radius_body_t *radius_body) +{ + int i=0; + cJSON *radius_json_obj = radius_info_object; + + cJSON_AddNumberToObject(radius_json_obj, "CODE", radius_header->code); + + for(i=0; i<radius_body->attribute_num; i++) + { + switch(radius_body->attribute[i].type) + { + case RADIUS_USER_NAME: + cJSON_AddStringToObject(radius_json_obj, "user_name", (char *)(radius_body->attribute[i].value)); + break; + case CALLBACK_NUMBER: + cJSON_AddStringToObject(radius_json_obj, "CALLBACK_NUMBER", (char *)(radius_body->attribute[i].value)); + break; + case CALLBACK_ID: + cJSON_AddStringToObject(radius_json_obj, "CALLBACK_ID", (char *)(radius_body->attribute[i].value)); + break; + case CALLED_STATION_ID: + cJSON_AddStringToObject(radius_json_obj, "CALLED_STATION_ID", (char *)(radius_body->attribute[i].value)); + break; + case CALLING_STATION_ID: + cJSON_AddStringToObject(radius_json_obj, "CALLING_STATION_ID", (char *)(radius_body->attribute[i].value)); + break; + case ACCT_SESSION_ID: + cJSON_AddStringToObject(radius_json_obj, "ACCT_SESSION_ID", (char *)(radius_body->attribute[i].value)); + break; + case ACCT_MULTI_SESSION_ID: + cJSON_AddStringToObject(radius_json_obj, "ACCT_MULTI_SESSION_ID", (char *)(radius_body->attribute[i].value)); + break; + case NAS_IP_ADDRESS: + cJSON_AddStringToObject(radius_json_obj, "NAS_IP_ADDRESS", (char *)(radius_body->attribute[i].value)); + break; + case FRAMED_IP_ADDRESS: + cJSON_AddStringToObject(radius_json_obj, "FRAMED_IP_ADDRESS", (char *)(radius_body->attribute[i].value)); + break; + case FRAMED_IP_NETMASK: + cJSON_AddStringToObject(radius_json_obj, "FRAMED_IP_NETMASK", (char *)(radius_body->attribute[i].value)); + break; + case SERVICE_TYPE: + cJSON_AddNumberToObject(radius_json_obj, "SERVICE_TYPE", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case FRAMED_MTU: + cJSON_AddNumberToObject(radius_json_obj, "FRAMED_MTU", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case SESSION_TIMEOUT: + cJSON_AddNumberToObject(radius_json_obj, "SESSION_TIMEOUT", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case IDLE_TIMEOUT: + cJSON_AddNumberToObject(radius_json_obj, "IDLE_TIMEOUT", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case TERMINATION_ACTION: + cJSON_AddNumberToObject(radius_json_obj, "TERMINATION_ACTION", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case PROXY_STATE: + cJSON_AddNumberToObject(radius_json_obj, "PROXY_STATE", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case ACCT_STATUS_TYPE: + cJSON_AddNumberToObject(radius_json_obj, "ACCT_STATUS_TYPE", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case ACCT_INPUT_OCTETS: + cJSON_AddNumberToObject(radius_json_obj, "ACCT_INPUT_OCTETS", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case ACCT_OUTPUT_OCTETS: + cJSON_AddNumberToObject(radius_json_obj, "ACCT_OUTPUT_OCTETS", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case ACCT_INPUT_PACKETS: + cJSON_AddNumberToObject(radius_json_obj, "ACCT_INPUT_PACKETS", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case ACCT_OUTPUT_PACKETS: + cJSON_AddNumberToObject(radius_json_obj, "ACCT_OUTPUT_PACKETS", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case ACCT_TERMINATE_CAUSE: + cJSON_AddNumberToObject(radius_json_obj, "ACCT_TERMINATE_CAUSE", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case ACCT_LINK_COUNT: + cJSON_AddNumberToObject(radius_json_obj, "ACCT_LINK_COUNT", *(unsigned int *)(radius_body->attribute[i].value)); + break; + case ACCT_INTERIM_INTERVAL: + cJSON_AddNumberToObject(radius_json_obj, "ACCT_INTERIM_INTERVAL", *(unsigned int *)(radius_body->attribute[i].value)); + break; + default: + continue; + } + } + + return 0; +} + +static int streamInfo2jsonObject(cJSON *json_obj, const struct streaminfo *a_stream) +{ + int ret = 0; + const char *addr_proto = NULL; + unsigned short tunnel_type=0; + char nest_addr_buf[1024]; + int tunnel_type_size=sizeof(tunnel_type); + const struct layer_addr *addr=NULL; + char src_ip_str[128] = {0}, dst_ip_str[128] = {0}; + + cJSON_AddNumberToObject(json_obj, "stream_dir", a_stream->dir); + + addr=&(a_stream->addr); + switch(addr->addrtype) + { + case ADDR_TYPE_IPV4: + case __ADDR_TYPE_IP_PAIR_V4: + cJSON_AddNumberToObject(json_obj, "addr_type", 4); + inet_ntop(AF_INET, &addr->ipv4->saddr, src_ip_str, sizeof(src_ip_str)); + inet_ntop(AF_INET, &addr->ipv4->daddr, dst_ip_str, sizeof(dst_ip_str)); + cJSON_AddStringToObject(json_obj, "s_ip", src_ip_str); + cJSON_AddStringToObject(json_obj, "d_ip", dst_ip_str); + cJSON_AddNumberToObject(json_obj, "s_port", ntohs(addr->ipv4->source)); + cJSON_AddNumberToObject(json_obj, "d_port", ntohs(addr->ipv4->dest)); + break; + case ADDR_TYPE_IPV6: + case __ADDR_TYPE_IP_PAIR_V6: + cJSON_AddNumberToObject(json_obj, "addr_type", 6); + inet_ntop(AF_INET6, addr->ipv6->saddr, src_ip_str, sizeof(src_ip_str)); + inet_ntop(AF_INET6, addr->ipv6->daddr, dst_ip_str, sizeof(dst_ip_str)); + cJSON_AddStringToObject(json_obj, "s_ip", src_ip_str); + cJSON_AddStringToObject(json_obj, "d_ip", dst_ip_str); + cJSON_AddNumberToObject(json_obj, "s_port", ntohs(addr->ipv6->source)); + cJSON_AddNumberToObject(json_obj, "d_port", ntohs(addr->ipv6->dest)); + break; + default: + break; + } + + addr_proto = layer_addr_prefix_ntop(a_stream); + cJSON_AddStringToObject(json_obj, "trans_proto", addr_proto); + + ret=MESA_get_stream_opt(a_stream, MSO_STREAM_TUNNEL_TYPE, &tunnel_type, &tunnel_type_size); + assert(ret==0); + if(tunnel_type==STREAM_TUNNLE_NON) + { + layer_addr_ntop_r(a_stream,nest_addr_buf, sizeof(nest_addr_buf)); + } + else + { + stream_addr_list_ntop(a_stream,nest_addr_buf, sizeof(nest_addr_buf)); + } + + cJSON_AddStringToObject(json_obj, "addr_list", nest_addr_buf); + + return 0; +} + + +char NTC_RADIUS_PLUG_ENTRY(stSessionInfo *session_info, void **pme, int thread_seq, struct streaminfo *stream, void *a_packet) +{ + int ret=0,status=0; + int config_id=0; + int payload_len=0; + time_t cur_time; + char *payload=NULL; + struct vxlan_info vinfo; + int opt_val_len = sizeof(vinfo); + radius_info_t *radius_info=(radius_info_t *)session_info->app_info; + cJSON *radius_info_object=cJSON_CreateObject(); + + streamInfo2jsonObject(radius_info_object, stream); + get_radius_object_element(radius_info_object, &radius_info->header, &radius_info->body); + + cJSON_AddNumberToObject(radius_info_object, "cfg_id", config_id); + cJSON_AddNumberToObject(radius_info_object, "service", g_ntc_radius_plug.service_id); + + cur_time = time(NULL); + if(stream!=NULL && stream->ptcpdetail!=NULL) + { + cJSON_AddNumberToObject(radius_info_object, "recv_time", stream->ptcpdetail->createtime); + } + else + { + cJSON_AddNumberToObject(radius_info_object, "recv_time", cur_time); + } + cJSON_AddNumberToObject(radius_info_object, "found_time", cur_time); + + ret = MESA_get_stream_opt(stream, MSO_STREAM_VXLAN_INFO, &vinfo, &opt_val_len); + if(ret < 0) + { + MESA_handle_runtime_log(g_ntc_radius_plug.logger, RLOG_LV_FATAL, "DNS_COLLECT_LOG", "soq log: get vxlan info error, tuple4: %s", printaddr(&stream->addr, thread_seq)); + } + else + { + cJSON_AddNumberToObject(radius_info_object, "entrance_id", vinfo.entrance_id); + cJSON_AddNumberToObject(radius_info_object, "direction", vinfo.link_dir); + cJSON_AddNumberToObject(radius_info_object, "device_id", vinfo.dev_id); + cJSON_AddNumberToObject(radius_info_object, "encap_type", vinfo.encap_type); + cJSON_AddNumberToObject(radius_info_object, "link_id", vinfo.link_id); + + cJSON_AddStringToObject(radius_info_object, "inner_smac", (char *)vinfo.inner_smac); + cJSON_AddStringToObject(radius_info_object, "inner_dmac", (char *)vinfo.inner_dmac); + } + + cJSON_AddStringToObject(radius_info_object, "cap_ip", g_ntc_radius_plug.local_ip); + + + payload = cJSON_PrintUnformatted(radius_info_object); + payload_len = strlen(payload); + + + status = rd_kafka_produce(g_ntc_radius_plug.topic_rkt, RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_COPY, payload, payload_len, NULL, 0, NULL); + + if(status < 0) + { + MESA_handle_runtime_log(g_ntc_radius_plug.logger,RLOG_LV_INFO,"sendlog", "sendlog to kafka is error, status: %d, topic: %s payload: %s", status, g_ntc_radius_plug.topic_name, payload); + } + else + { + MESA_handle_runtime_log(g_ntc_radius_plug.logger,RLOG_LV_INFO,"sendlog", "topic: %s %s", g_ntc_radius_plug.topic_name, payload); + } + + + free(payload); + cJSON_Delete(radius_info_object); + radius_info_object = NULL; + + return APP_STATE_GIVEME; +} + +int NTC_RADIUS_PLUG_INIT(void) +{ + unsigned int local_ip_nr=0; + char nic_name[32]={0}; + char kafka_errstr[1024]; + rd_kafka_t *kafka_handle = NULL; + rd_kafka_conf_t *rdkafka_conf = NULL; + rd_kafka_topic_conf_t *topic_conf; + + memset(&g_ntc_radius_plug,0,sizeof(g_ntc_radius_plug_t)); + MESA_load_profile_string_def(config_file, "SYSTEM", "NIC_NAME", nic_name, sizeof(nic_name), "eth0"); + MESA_load_profile_string_def(config_file, "RADIUS","LOG_PATH",g_ntc_radius_plug.pathname, sizeof(g_ntc_radius_plug.pathname), "./t1log/ntc_radius_plug/ntc_radius_plug"); + MESA_load_profile_int_def(config_file, "RADIUS", "SERVICE_ID", &g_ntc_radius_plug.service_id, 0xA2); + MESA_load_profile_int_def(config_file, "RADIUS","LEVEL", &g_ntc_radius_plug.level, RLOG_LV_FATAL); + MESA_load_profile_string_def(config_file, "RADIUS", "COLLECT_TOPIC", g_ntc_radius_plug.topic_name, sizeof(g_ntc_radius_plug.topic_name), "eth0"); + MESA_load_profile_string_def(config_file, "RADIUS", "BROKERLIST", g_ntc_radius_plug.brokerlist, sizeof(g_ntc_radius_plug.brokerlist), "127.0.0.1:9092"); + + g_ntc_radius_plug.logger = MESA_create_runtime_log_handle(g_ntc_radius_plug.pathname, g_ntc_radius_plug.level); + if(g_ntc_radius_plug.logger == NULL) + { + printf("RADIUS MESA_create_runtime_log_handle failed ...\n"); + return -1; + } + + local_ip_nr=get_ip_by_eth_name(nic_name); + if(local_ip_nr==INADDR_NONE) + { + MESA_handle_runtime_log(g_ntc_radius_plug.logger, RLOG_LV_FATAL, "init_soq_sendlog","get NIC_NAME: %s error.", nic_name); + return -1; + } + + inet_ntop(AF_INET, &local_ip_nr, g_ntc_radius_plug.local_ip, sizeof(g_ntc_radius_plug.local_ip)); + + rdkafka_conf = rd_kafka_conf_new(); + rd_kafka_conf_set(rdkafka_conf, "queue.buffering.max.messages", "1000000", kafka_errstr, sizeof(kafka_errstr)); + rd_kafka_conf_set(rdkafka_conf, "topic.metadata.refresh.interval.ms", "600000",kafka_errstr, sizeof(kafka_errstr)); + rd_kafka_conf_set(rdkafka_conf, "request.required.acks", "1", kafka_errstr, sizeof(kafka_errstr)); + + if(!(kafka_handle=rd_kafka_new(RD_KAFKA_PRODUCER, rdkafka_conf, kafka_errstr, sizeof(kafka_errstr)))) + { + MESA_handle_runtime_log(g_ntc_radius_plug.logger, RLOG_LV_FATAL, "RADIUS_COLLECT", "rd_kafka_new is error"); + return -1; + } + + if(rd_kafka_brokers_add(kafka_handle, g_ntc_radius_plug.brokerlist) == 0) + { + MESA_handle_runtime_log(g_ntc_radius_plug.logger, RLOG_LV_FATAL, "RADIUS_COLLECT", "rd_kafka_brokers_add is error, broker_list: %s", g_ntc_radius_plug.brokerlist); + return -1; + } + + topic_conf = rd_kafka_topic_conf_new(); + g_ntc_radius_plug.topic_rkt = rd_kafka_topic_new(kafka_handle, g_ntc_radius_plug.topic_name, topic_conf); + if(g_ntc_radius_plug.topic_rkt==NULL) + { + MESA_handle_runtime_log(g_ntc_radius_plug.logger, RLOG_LV_FATAL, "RADIUS_COLLECT", "rd_kafka_topic_new is error, topic: %s", g_ntc_radius_plug.topic_name); + return -1; + } + + printf("INIT NTC_RADIUS_PLUG SUCCESS, VERSION: %d\n", NTC_RADIUS_PLUG_VERSION_20191022); + + return 0; +} + +void NTC_RADIUS_PLUG_DESTROY(void) +{ + +} + diff --git a/src/ntc_radius_plug.h b/src/ntc_radius_plug.h new file mode 100644 index 0000000..905056e --- /dev/null +++ b/src/ntc_radius_plug.h @@ -0,0 +1,32 @@ +#ifndef __NTC_RADIUS_PLUG_H__ +#define __NTC_RADIUS_PLUG_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +typedef struct _ntc_radius_plug +{ + int level; + int service_id; + void *logger; + char pathname[128]; + char topic_name[128]; + char brokerlist[128]; + char local_ip[128]; + rd_kafka_topic_t *topic_rkt; +}g_ntc_radius_plug_t; + +int NTC_RADIUS_PLUG_INIT(void); +void NTC_RADIUS_PLUG_DESTROY(void); +char NTC_RADIUS_PLUG_ENTRY(stSessionInfo *session_info, void **pme, int thread_seq, struct streaminfo *stream, void *a_packet); + + +#ifdef __cplusplus +} +#endif + +#endif + |
