From d93d3a6040563487a8541964838529347dfd3c71 Mon Sep 17 00:00:00 2001 From: jli Date: Mon, 19 Sep 2011 02:06:39 +0000 Subject: [PATCH] add V1.5 git-svn-id: http://172.17.0.253/svn/soft_pkgs/sys_nicmonitor@798 09c3743a-b0dd-45d3-b506-aa74c7a2a6ef --- branches/sys_nicmonitor-1.5/Makefile | 28 + branches/sys_nicmonitor-1.5/Makefile.config | 16 + branches/sys_nicmonitor-1.5/README1.5 | 32 + branches/sys_nicmonitor-1.5/const.h | 51 + branches/sys_nicmonitor-1.5/mnic.c | 1541 +++++++++++++++++++ branches/sys_nicmonitor-1.5/mnic.h | 44 + branches/sys_nicmonitor-1.5/nicinfo_shm.c | 209 +++ branches/sys_nicmonitor-1.5/nicinfo_shm.h | 52 + branches/sys_nicmonitor-1.5/proc_inv.h | 198 +++ branches/sys_nicmonitor-1.5/read_netcard.c | 133 ++ branches/sys_nicmonitor-1.5/send_alarm.c | 37 + branches/sys_nicmonitor-1.5/sys_netcard.h | 88 ++ branches/sys_nicmonitor-1.5/sys_nicmonitor | Bin 0 -> 47706 bytes 13 files changed, 2429 insertions(+) create mode 100644 branches/sys_nicmonitor-1.5/Makefile create mode 100644 branches/sys_nicmonitor-1.5/Makefile.config create mode 100644 branches/sys_nicmonitor-1.5/README1.5 create mode 100644 branches/sys_nicmonitor-1.5/const.h create mode 100644 branches/sys_nicmonitor-1.5/mnic.c create mode 100644 branches/sys_nicmonitor-1.5/mnic.h create mode 100644 branches/sys_nicmonitor-1.5/nicinfo_shm.c create mode 100644 branches/sys_nicmonitor-1.5/nicinfo_shm.h create mode 100644 branches/sys_nicmonitor-1.5/proc_inv.h create mode 100644 branches/sys_nicmonitor-1.5/read_netcard.c create mode 100644 branches/sys_nicmonitor-1.5/send_alarm.c create mode 100644 branches/sys_nicmonitor-1.5/sys_netcard.h create mode 100755 branches/sys_nicmonitor-1.5/sys_nicmonitor diff --git a/branches/sys_nicmonitor-1.5/Makefile b/branches/sys_nicmonitor-1.5/Makefile new file mode 100644 index 0000000..5cccc77 --- /dev/null +++ b/branches/sys_nicmonitor-1.5/Makefile @@ -0,0 +1,28 @@ +#! /usr/bin/make -f + +DEFAULTS = Makefile.config + +include $(DEFAULTS) + +all:sys_nicmonitor libnic_shm.so + +CFLAGS += -Wall -Wformat=2 -Wno-format-extra-args -Wformat-security -Wformat-nonliteral #-g + +sys_nicmonitor:mnic.o read_netcard.o send_alarm.o + $(CC) -lman -ldotconf -lpthread -o $@ $^ +libnic_shm.so:nicinfo_shm.c + $(CC) -fpic -shared -o $@ $^ +clean: + $(RM) *.o + $(RM) libnic_shm.so sys_nicmonitor +install: + $(MKDIR) -p $(LIBDIR) + $(MKDIR) -p $(BINDIR) + $(MKDIR) -p $(INCDIR) + $(CP) libnic_shm.so $(LIBDIR) + $(CP) sys_nicmonitor $(BINDIR) + $(CP) nicinfo_shm.h $(INCDIR) +uninstall: + $(RM) -f $(LIBDIR)/libnic_shm.so + $(RM) -f $(BINDIR)/sys_nicmonitor + $(RM) -f $(INCDIR)/nicinfo_shm.h diff --git a/branches/sys_nicmonitor-1.5/Makefile.config b/branches/sys_nicmonitor-1.5/Makefile.config new file mode 100644 index 0000000..7a2d8e6 --- /dev/null +++ b/branches/sys_nicmonitor-1.5/Makefile.config @@ -0,0 +1,16 @@ + +PREFIX = $(DESTDIR) + +BINDIR = $(PREFIX)/usr/bin + +LIBDIR = $(PREFIX)/usr/lib64 + +INCDIR = $(PREFIX)/usr/include + +INSTALL_SH = ./install.sh + +CP = cp +RM = rm +#CC = gcc +CC = g++ +MKDIR = mkdir diff --git a/branches/sys_nicmonitor-1.5/README1.5 b/branches/sys_nicmonitor-1.5/README1.5 new file mode 100644 index 0000000..fa1087e --- /dev/null +++ b/branches/sys_nicmonitor-1.5/README1.5 @@ -0,0 +1,32 @@ + +lijin:/home/d5000/lijin/sys_nicmonitor # ./sys_nicmonitor +shm_path:/home/d5000/tmp/sys_netcard_shm_path +log_path:/home/d5000/var/log/netcard/20110110_sys_nicmonitor.log +udp    bond0 +nic    bond0 +nic    eth0 +nic    eth1 + +d5000@lijin:~ > cat var/log/netcard/20110110_sys_nicmonitor.log +2011-01-10 11:10:37.761 sys_nicmonitor NOTICE: sys_nicmonitor V1.5 is +started ! +2011-01-10 11:10:37.761 sys_nicmonitor +shm_path:/home/d5000/tmp/sys_netcard_shm_path +2011-01-10 11:10:37.761 sys_nicmonitor +log_path:/home/d5000/var/log/netcard/20110110_sys_nicmonitor.log +2011-01-10 11:10:37.761 sys_nicmonitor udp    bond0 +2011-01-10 11:10:37.761 sys_nicmonitor nic    bond0 +2011-01-10 11:10:37.761 sys_nicmonitor nic    eth0 +2011-01-10 11:10:37.762 sys_nicmonitor nic    eth1 +2011-01-10 11:10:37.762 sys_nicmonitor NOTICE: bond0 is NORMAL! +2011-01-10 11:10:37.763 sys_nicmonitor NOTICE: eth0 is NORMAL! +2011-01-10 11:10:37.763 sys_nicmonitor NOTICE: eth1 is NORMAL! + +与1.4不一样的地方在与增加log文件中的打印语句 +sys_nicmonitor started! version v1.4 +shm_path: /home/d5000/tmp +log_path: /home/d5000/ var/log/netcard +udp bond0 +nic bond0 +nic eth0 +nic eth1 diff --git a/branches/sys_nicmonitor-1.5/const.h b/branches/sys_nicmonitor-1.5/const.h new file mode 100644 index 0000000..e2ebfa5 --- /dev/null +++ b/branches/sys_nicmonitor-1.5/const.h @@ -0,0 +1,51 @@ +#ifndef _RTE_CONST_H +#define _RTE_CONST_H + +#include + + +#define MAX_STRING_LEN 24 +#define MAX_EXECMD_LEN 200 +#define MAX_FILENAME_LEN 200 + +#define MAX_CONTEXT 8 +#define MAX_HOSTNAME_LEN 24 +#define MAX_LOCAL_MESPROC 512 +#define MAX_LOCAL_PROCESS MAX_LOCAL_MESPROC +#define MAX_LOCAL_APP 32 +#define MAX_LOCAL_NODE 256 + +#define MAX_SET 256 //max num of event set +#define MAX_EVENT 1300 +#define MAX_REG_PROC 20 + +#define LEN_SHMBLK_BIG 4096 +#define MAX_MSGBUF_LEN 32767 +#define FREE_PAGE_SIZE 65536 +#define MAX_PAGE_NUM 1024 + +#define MAX_QUE MAX_LOCAL_MESPROC +#define MAX_SEMPHORE_SET MAX_LOCAL_MESPROC*2 +#define RTE_HAN 0 // queue number for event handeler0(RTE) +#define EX_EVENT_HAN RTE_HAN // queue number for extrnal event handeler + +#define DOMAIN_I 1 +#define DOMAIN_II 2 +#define DOMAIN_III 3 + +//Add 20090225 +const int PROC_TYPE_RPT =1; +const int PROC_TYPE_UNRPT =0; +//add end + + +//status for proc and app +const int NON_ACTIVE = 0; +const int ACTIVE = 1; +const int HANGUP = 2; +const int FAILURE = 5; +const int START = 6; +const int STOP = 7; + +#endif + diff --git a/branches/sys_nicmonitor-1.5/mnic.c b/branches/sys_nicmonitor-1.5/mnic.c new file mode 100644 index 0000000..c3bcf62 --- /dev/null +++ b/branches/sys_nicmonitor-1.5/mnic.c @@ -0,0 +1,1541 @@ +#include "mnic.h" +#include "dotconf.h" +#include +#include +#include "proc_inv.h" + +#define THRNR 10 +#define DAYS 25 +#define LINE_SIZE 2048 +#define HOST_NAME_SIZE 40 +#define BOND_PATH "/proc/net/bonding/*" +#define LOG_PATH "/var/log/netcard/" +#define SHM_PATH "/tmp/sys_netcard_shm_path" +#define SEM_PATH "/tmp/sys_netcard_sem_path" +#define MAX_GW 32 +#define DEV_MAXLEN 32 +#define IPLEN 16 +#define CONF_FILE "/conf/nic/sys_netcard_conf.txt" + +#define MNIC_VERSION "1.5" + +#define NIC_UNKNOWN 0 +#define NIC_DOWN 1 +#define NIC_UNRUNNING 2 +#define NIC_UNLINKABLE 3 +#define NIC_NORMAL 4 + +//网卡设备描述结构 +typedef struct __nic_dev{ + char dev_name[DEV_MAXLEN]; //网卡名称 + char ping_ip[MAX_GW][IPLEN]; //ping地址列表,最多32个 + int gw_num; //地址列表的长度 +}NIC_DEV; + +typedef struct __config_file_st{ + unsigned char domain; + short serv; + short event; + int udpport; + int monitor_interval; + int write_interval; + int flow_interval; + int flow_limit; + int flow_peak; + char udp[NIC_NAME_LEN]; + NIC_DEV nic[MAXNICNUM]; //被监视网卡的列表 + char ip[IPSIZE]; + int pingnum; //OPTIONAL!! How many times for once ping check? Default is 2. + int pinglap; //OPTIONAL!! How many seconds does ping wait for reply package? Default is 1. +}CONFIG_FILE_ST; + +typedef struct inc_name_node{ + char name[NIC_NAME_LEN]; + struct inc_name_node *next; +}NET_NAME_ST; + +typedef struct inc_info_node{ + NETCARD_INFO info; + int status; + struct inc_info_node *next; +}NETCARD_INFO_ST; + +typedef struct net_info{ + NETCARD_INFO info[MAXNICNUM]; +}SHM; + +typedef struct __thread_env_st{ + D5000_NIC_ALARM Malarm; + char bond_file_path[64]; + char host_name[HOST_NAME_SIZE]; + int host_name_size; + CONFIG_FILE_ST *conf; +}THENV; + +typedef struct __thread_mem_st{ + int semid; + SHM *shm_ptr; + NETCARD_INFO_ST *listp; + CONFIG_FILE_ST *conf; +}THMEM; + +typedef struct __thread_flow_st{ + THENV env; + THMEM mem; +}THFLOW; + +int find_nic_config(char *); + +static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; +static short seqno = 1; +static char log_flag = 1; +static int sem_id = 0; +static char process_name[64]; +char log_path[1024]; +char shm_path[1024]; +char sem_path[1024]; +char conf_path[1024]; + +int host_name_size = 0; +char host_name[HOST_NAME_SIZE]; +int semid = -1; +SHM *shm_ptr; + +//20100510 +int total_ping_time, elapsed_ping_time; +int get_netcard_status(NETCARD_INFO_ST *); + +/****dotconf****/ +static DOTCONF_CB(cb_str); +static DOTCONF_CB(cb_int); +int nicnum = 0; +CONFIG_FILE_ST conf; + +char myconf[][64] = { + "domain", // 0 + "serv", // 1 + "event", // 2 + "udpport", // 3 + "sys_netcard_shm_path", // 4 + "sys_netcard_sem_path", // 5 + "monitor_interval", // 6 + "write_interval", // 7 + "flow_interval", // 8 + "flow_limit", // 9 + "flow_peak", // 10 + "udp", // 11 + "nic", // 12 + "ping", // 13 + "pingnum", // 14 + "pinglap", // 15 + "" +}; + +static const configoption_t options[] = { + {myconf[0], ARG_INT, cb_int, NULL, CTX_ALL}, + {myconf[1], ARG_INT, cb_int, NULL, CTX_ALL}, + {myconf[2], ARG_INT, cb_int, NULL, CTX_ALL}, + {myconf[3], ARG_INT, cb_int, NULL, CTX_ALL}, + {myconf[4], ARG_STR, cb_str, NULL, CTX_ALL}, + {myconf[5], ARG_STR, cb_str, NULL, CTX_ALL}, + {myconf[6], ARG_INT, cb_int, NULL, CTX_ALL}, + {myconf[7], ARG_INT, cb_int, NULL, CTX_ALL}, + {myconf[8], ARG_INT, cb_int, NULL, CTX_ALL}, + {myconf[9], ARG_INT, cb_int, NULL, CTX_ALL}, + {myconf[10], ARG_INT, cb_int, NULL, CTX_ALL}, + {myconf[11], ARG_STR, cb_str, NULL, CTX_ALL}, + {myconf[12], ARG_STR, cb_str, NULL, CTX_ALL}, + {myconf[13], ARG_STR, cb_str, NULL, CTX_ALL}, + {myconf[14], ARG_INT, cb_int, NULL, CTX_ALL}, + {myconf[15], ARG_INT, cb_int, NULL, CTX_ALL}, + LAST_OPTION +}; +/****dotconf****/ + +/* write error in logfile */ +void record_log(char *str) +{ + time_t tamp; + char str_tm[4]; + char log_str[512]; + FILE *log_fp = NULL; + struct tm tmptr; + struct timeval tv; + struct timezone tz; + + if((log_fp = fopen(log_path, "a")) != NULL){ + tamp = time(NULL); + memset(str_tm, 0, sizeof(str_tm)); + memset(log_str, 0, sizeof(log_str)); + localtime_r(&tamp, &tmptr); + gettimeofday(&tv, &tz); + snprintf(str_tm, sizeof(str_tm), "%d", (int)tv.tv_usec/1000); + if(str_tm[1] == '\0')str_tm[1] = '0'; + if(str_tm[2] == '\0')str_tm[2] = '0'; + strftime(log_str, sizeof(log_str), "%F %T.", &tmptr); + strcat(log_str, str_tm); + strcat(log_str, " "); + strcat(log_str, process_name); + strcat(log_str, " "); + strcat(log_str, str); + if(fwrite(log_str, 1, strlen(log_str), log_fp) < 1){ + } + fclose(log_fp); + } +} + +static void init_sem(int *semid, CONFIG_FILE_ST *ptr) +{ + key_t key; + char error_str[200]; + +/* write error in logfile */ + memset(error_str, 0, sizeof(error_str)); + if ((key = ftok(sem_path, SEM_PROJ_ID)) == -1) { + snprintf(error_str, sizeof(error_str), "EMERG: ftok():%s\n", strerror(errno)); + record_log(error_str); + return; + } + if((*semid = semget(key, 1, IPC_CREAT|0666)) == -1){ + snprintf(error_str, sizeof(error_str), "EMERG: semget():%s\n", strerror(errno)); + record_log(error_str); + return; + } + if(semctl(*semid, 0, SETVAL, 0) == -1){ + snprintf(error_str, sizeof(error_str), "EMERG: semctl: %s !\n", strerror(errno)); + record_log(error_str); + semctl(*semid, 0, IPC_RMID); + return; + } +} + +static void init_shm(SHM **ptr, CONFIG_FILE_ST *p) +{ + int fd = -1; + char error_str[200]; + + mode_t mask_tmp; + mask_tmp = umask(0000); + if((fd = open(shm_path, O_RDWR|O_CREAT|O_TRUNC, 0666)) == -1){ + printf("could not create %s\n", shm_path); + return; + } + umask(mask_tmp); + lseek(fd, sizeof(SHM), SEEK_SET); + write(fd, "\0", 1); + *ptr = (SHM *)mmap(NULL, sizeof(SHM), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if(*ptr == MAP_FAILED){ + snprintf(error_str, sizeof(error_str), "EMERG: mmap():%s\n", strerror(errno)); + record_log(error_str); + return; + } + close(fd); + +} + +static void get_sem(int semid) +{ + struct sembuf lock[2]; + char error_str[200]; + + lock[0].sem_num = 0; + lock[0].sem_op = 0; + lock[0].sem_flg = SEM_UNDO; + + lock[1].sem_num = 0; + lock[1].sem_op = 1; + lock[1].sem_flg = SEM_UNDO; + + while(semop(semid, lock, 2)){ + if(errno == EINTR)continue; + snprintf(error_str, sizeof(error_str), "EMERG: get_sem semop():%s\n", strerror(errno)); + record_log(error_str); + return; + } +} + +static void release_sem(int semid) +{ + int ret; + char error_str[200]; + struct sembuf unlock; + + unlock.sem_num = 0; + unlock.sem_op = -1; + unlock.sem_flg = SEM_UNDO; + + if((ret = semop(semid, &unlock, 1)) == -1){ + snprintf(error_str, sizeof(error_str), "EMERG: rel_sem semop():%s\n", strerror(errno)); + record_log(error_str); + return; + } +} + +static void proc_get_name(NET_NAME_ST *nodep) +{ + char linebuf[LINE_SIZE]; + char error_str[200]; + char *retp = NULL; + int err_val=0; + NET_NAME_ST *node = NULL; + FILE *dev_fp; + + if((dev_fp = fopen("/proc/net/dev", "rb")) == NULL){ + snprintf(error_str, sizeof(error_str), "EMERG: Can't open dev file:%s\n", strerror(errno)); + record_log(error_str); + return; + } + memset(linebuf, 0, sizeof(linebuf)); + fgets(linebuf, sizeof(linebuf), dev_fp); + fgets(linebuf, sizeof(linebuf), dev_fp); + while((retp = fgets(linebuf, sizeof(linebuf), dev_fp)) != NULL){ + if((node = (NET_NAME_ST *)malloc(sizeof(NET_NAME_ST))) == NULL){ + err_val = 1; + break; + } + memset(node->name, 0, NIC_NAME_LEN); + get_name(node->name, retp); + node->next = nodep->next; + nodep->next = node; + } + if(err_val){ + NET_NAME_ST *curr = nodep->next; + while(curr != NULL){ + node = curr->next; + free(curr); + curr = node; + } + } + fclose(dev_fp); +} + +static void ioctl_get_name(NET_NAME_ST *nodep) +{ + int count = 0; + int inuse = 0; + int err_val = 0; + NETCARD_INFO net_name[MAXNICNUM]; + NET_NAME_ST *node = NULL, *curr = NULL; + + memset(net_name, 0, sizeof(net_name)); + if((count = ioc_get_name(net_name)) == 0)return; + if(nodep->next == NULL) + inuse = 1; + while(count > 0){ + curr = nodep->next; + while(curr != NULL){ + if(!strncmp(net_name[count - 1].charname, curr->name, NIC_NAME_LEN)){ + inuse = 0; + break; + } + inuse = 1; + curr = curr->next; + } + if(inuse){ + if((node = (NET_NAME_ST *)malloc(sizeof(NET_NAME_ST))) == NULL){ + err_val = 1; + break; + } + memset(node->name, 0, NIC_NAME_LEN); + strncpy(node->name, net_name[count - 1].charname, NIC_NAME_LEN); + node->next = nodep->next; + nodep->next = node; + } + count--; + } + if(err_val){ + curr = nodep->next; + while(curr != NULL){ + node = curr->next; + free(curr); + curr = node; + } + } +} + +static void get_all_name(NET_NAME_ST *nodep) +{ + proc_get_name(nodep); + ioctl_get_name(nodep); +} + +static void create_monit_list(NET_NAME_ST *nodep, NETCARD_INFO_ST *info_list, char *bond) +{ + int err_val = 0; + NETCARD_INFO_ST *info_node = NULL; + NET_NAME_ST *curr, *node; + + curr = nodep->next; + while(curr != NULL){ + if((info_node = (NETCARD_INFO_ST *)malloc(sizeof(NETCARD_INFO_ST))) == NULL){ + err_val = 1; + break; + } + memset(info_node, 0, sizeof(NETCARD_INFO_ST)); + strncpy(info_node->info.charname, curr->name, NIC_NAME_LEN); + strncpy(info_node->info.descr, bond, strlen(bond)); + info_node->next = info_list->next; + info_list->next = info_node; + curr = curr->next; + } + if(err_val){ + NETCARD_INFO_ST *info_curr = info_list->next; + while(info_curr != NULL){ + info_node = info_curr->next; + free(info_curr); + info_curr = info_node; + } + curr = nodep->next; + while(curr != NULL){ + node = curr->next; + free(curr); + curr = node; + } + } +} + +static int get_inc_info(NETCARD_INFO *net) +{ + return if_fetch(net); +} + +static void get_inc_stats(NETCARD_INFO *net) +{ + char linebuf[LINE_SIZE]; + char *retp = NULL; + char *str = NULL; + FILE *dev_fp; + + if((dev_fp = fopen("/proc/net/dev", "r")) == NULL)return; + memset(linebuf, 0, sizeof(linebuf)); + while((retp = fgets(linebuf, sizeof(linebuf), dev_fp)) != NULL){ + if((str = strstr(linebuf, net->charname)) != NULL){ + str +=strlen(net->charname) + 2; + get_dev_fields(str, net); + break; + } + } + fclose(dev_fp); +} + +static void send_inc_info_one(NETCARD_INFO *net, int semid, SHM *ptr) +{ + int i; + for(i = 0; ptr->info[i].charname[0] != 0; i++){ + if(!strncmp(ptr->info[i].charname, net->charname, NIC_NAME_LEN)){ + get_sem(semid); + memcpy(&ptr->info[i], net, sizeof(NETCARD_INFO)); + release_sem(semid); + } + } +} + +static void *send_inc_info(void *p) +{ + int i = 0; + int flags = 1; + char error_str[200]; + unsigned long long bytes[MAXNICNUM]; + THMEM *ptr = (THMEM *)p; + NETCARD_INFO_ST *curr; + struct timespec s_time, os_time; + + if((curr = ptr->listp->next) == NULL){ + pthread_mutex_lock(&mut); + snprintf(error_str, sizeof(error_str), "EMERG: Empty Netcard list!\n"); + record_log(error_str); + pthread_mutex_unlock(&mut); + return NULL; + } + s_time.tv_sec = ptr->conf->write_interval; + s_time.tv_nsec = 0; + + /* copy all net_info*/ + while(1){ + i = 0; + get_sem(ptr->semid); + memset(ptr->shm_ptr, 0, sizeof(SHM)); + curr = ptr->listp->next; + while(curr != NULL){ + get_inc_info(&curr->info); + if(curr->status == NIC_UNLINKABLE){ + curr->info.flags &= (~IFF_UP); + curr->info.flags &= (~IFF_RUNNING); + } + get_inc_stats(&curr->info); + if(flags){ + bytes[i] = curr->info.rx_bytes + curr->info.tx_bytes; + } + curr->info.average_flow =(unsigned long long)((curr->info.rx_bytes + curr->info.tx_bytes - bytes[i])/(ptr->conf->write_interval)); + memcpy(&ptr->shm_ptr->info[i], &curr->info, sizeof(NETCARD_INFO)); + bytes[i] = curr->info.rx_bytes + curr->info.tx_bytes; + i++; + curr = curr->next; + } + release_sem(ptr->semid); + flags = 0; + nanosleep(&s_time, &os_time); + } +} + +static int get_netcard_count(char *name) +{ + int count = 0; + FILE *fp = NULL; + char path[64] = "/proc/net/bonding/"; + char buf[LINE_SIZE]; + char *retp = NULL; + char *str = NULL; + + strncat(path, name, strlen(name)); + if((fp = fopen(path, "r")) == NULL)return 1; + + memset(buf, 0, sizeof(buf)); + fseek(fp, 65, SEEK_SET); + while((retp = fgets(buf, sizeof(buf), fp)) != NULL){ + if((str = strstr(buf, "active-backup")) != NULL){ + fclose(fp); + return 1; + } + if(!strncmp(buf, "Slave Interface:", 16))count++; + } + fclose(fp); + return count; +} + +static void *cacu_flow(void *p) +{ + int i = 0, count_t = 1; + int summit = 0; + int flags = 1; + int count_ok[MAXNICNUM]; + int count_no[MAXNICNUM]; + char error_str[200]; + unsigned long long bytes[MAXNICNUM]; + THFLOW *ptr = (THFLOW *)p; + NETCARD_INFO_ST *curr; + struct timespec s_time, os_time; + + if((curr = ptr->mem.listp->next) == NULL){ + pthread_mutex_lock(&mut); + snprintf(error_str, sizeof(error_str), "EMERG: Empty Netcard list!\n"); + record_log(error_str); + pthread_mutex_unlock(&mut); + return NULL; + } + s_time.tv_sec = ptr->mem.conf->flow_interval; + s_time.tv_nsec = 0; + + for(i = 0; i < MAXNICNUM ; i++){ + count_ok[i] = 0; + count_no[i] = 0; + } + while(1){ + i = 0; + curr = ptr->mem.listp->next; + while(curr != NULL){ + get_inc_info(&curr->info); + get_inc_stats(&curr->info); + if(flags){ + bytes[i] = curr->info.rx_bytes + curr->info.tx_bytes; + } + curr->info.average_flow =(unsigned long long)((curr->info.rx_bytes + curr->info.tx_bytes - bytes[i])/ptr->mem.conf->flow_interval); + if(!strncmp(curr->info.charname, "bond", 4)){ + count_t = get_netcard_count(curr->info.charname); + }else { + count_t = 1; + } + summit = (unsigned int)(curr->info.average_flow*8*100/1024/1024/ptr->mem.conf->flow_peak/count_t); +#if 0 + printf("%s:\tcount=%d\tsummit=%d\tflow_limit:%d\taverage_flow:%d\n", curr->info.charname, count_t, summit, conf.flow_limit, curr->info.average_flow); +#endif + if(summit >= ptr->mem.conf->flow_limit){ + memset(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, 0, NIC_NAME_LEN); + strncpy(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, ptr->env.host_name, ptr->env.host_name_size); + strncat(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, "-", 1); + strncat(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, curr->info.charname, (NIC_NAME_LEN - ptr->env.host_name_size - 1)); + ptr->env.Malarm.tSysNetcardAlarm.flags = NETCARD_ALARM_ABNORMAL; + ptr->env.Malarm.tSysNetcardAlarm.retrytimes = 0; + ptr->env.Malarm.tMsgFrame.len = sizeof(ptr->env.Malarm); + ptr->env.Malarm.tMsgFrame.seqno = seqno; + pthread_mutex_lock(&mut); + while(count_no[i] > 0){ + send_alarm(&ptr->env.Malarm, ptr->mem.conf->udpport, ptr->mem.conf->ip); + seqno++; + ptr->env.Malarm.tMsgFrame.seqno = seqno; + ptr->env.Malarm.tSysNetcardAlarm.retrytimes++; + count_no[i]--; + if(count_no[i] == 0){ + send_inc_info_one(&curr->info, ptr->mem.semid, ptr->mem.shm_ptr); + //snprintf(error_str, sizeof(error_str), "NOTICE: %s flow is abnormal, summit is %d, average flow is %lld !\n", curr->info.charname, summit, curr->info.average_flow); + snprintf(error_str, sizeof(error_str), "NOTICE: %s flow is abnormal !\n", curr->info.charname); + record_log(error_str); + } + } + pthread_mutex_unlock(&mut); + count_ok[i] = 3; + }else{ + memset(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, 0, NIC_NAME_LEN); + strncpy(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, ptr->env.host_name, ptr->env.host_name_size); + strncat(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, "-", 1); + strncat(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, curr->info.charname, (NIC_NAME_LEN - ptr->env.host_name_size - 1)); + ptr->env.Malarm.tSysNetcardAlarm.flags = NETCARD_ALARM_NORMAL; + ptr->env.Malarm.tSysNetcardAlarm.retrytimes = 0; + ptr->env.Malarm.tMsgFrame.len = sizeof(ptr->env.Malarm); + ptr->env.Malarm.tMsgFrame.seqno = seqno; + pthread_mutex_lock(&mut); + while(count_ok[i] > 0){ + send_alarm(&ptr->env.Malarm, ptr->mem.conf->udpport, ptr->mem.conf->ip); + seqno++; + ptr->env.Malarm.tMsgFrame.seqno = seqno; + ptr->env.Malarm.tSysNetcardAlarm.retrytimes++; + count_ok[i]--; + if(count_ok[i] == 0){ + send_inc_info_one(&curr->info, ptr->mem.semid, ptr->mem.shm_ptr); + snprintf(error_str, sizeof(error_str), "NOTICE: %s flow is normal now !\n", curr->info.charname); + record_log(error_str); + } + } + pthread_mutex_unlock(&mut); + count_no[i] = 3; + }/* end if(summit... */ + bytes[i] = curr->info.rx_bytes + curr->info.tx_bytes; + i++; + curr = curr->next; + }/* end while(curr...) */ + flags = 0; + nanosleep(&s_time, &os_time); + }/* end while(1) */ +} +static char *parse_str(char **s) +{ + char *retp = NULL; + char *p = *s; + + while(isspace(*p))p++; + retp = p; + while(!isspace(*p))p++; + *p = '\0'; + + return retp; +} + +int ping_gw(char *devname) +{ + int i, ret = -1, j, k; + char buf[64]; + + i = find_nic_config(devname); + if( i == -1 ) + return 0; + + if(conf.nic[i].gw_num == 0) + return 0; + + for(k=0; k /dev/null 2>&1", conf.pinglap,conf.nic[i].ping_ip[j]); + ret=system(buf); +#if 0 + if (WIFSIGNALED(ret) && + (WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT)) + exit(0); +#endif + if(ret == 0) + return 0; + + } + } + + return -1; +} + +static void *check_inc_switch(void *ptr) +{ + THENV *arg = (THENV *)ptr; + FILE *fp = NULL; + char name[NIC_NAME_LEN]; + struct timespec s_time, os_time; + int count = 0; + char linebuf[LINE_SIZE]; + char error_str[200]; + char *str = NULL; + char *retp = NULL; + + if((fp = fopen(arg->bond_file_path, "r")) == NULL){ + snprintf(error_str, sizeof(error_str), "EMERG: fopen():%s\n", strerror(errno)); + record_log(error_str); + free(ptr); + return NULL; + } + fseek(fp, 65, SEEK_SET); + memset(name, 0, sizeof(name)); + memset(linebuf, 0, sizeof(linebuf)); + if((retp = fgets(linebuf, sizeof(linebuf), fp)) != NULL){ + if((retp = strstr(linebuf, "active-backup")) == NULL){ + free(ptr); + fclose(fp); + return NULL; + } + } + + s_time.tv_sec = 0; + s_time.tv_nsec = 100000000; + + while(1){ + while((str = fgets(linebuf, sizeof(linebuf), fp)) != NULL){ + if(!strncmp(linebuf, "Currently Active Slave:", 23)){ + str += 23; + retp = parse_str(&str); + break; + } + } + if(name[0] == 0){ + strncpy(name, retp, strlen(retp)); + }else if(strncmp(name, retp, strlen(retp)) != 0){ + memset(arg->Malarm.tSysNetcardAlarm.switch_devname, 0, NIC_NAME_LEN); + strncpy(arg->Malarm.tSysNetcardAlarm.switch_devname, arg->host_name, arg->host_name_size); + strncat(arg->Malarm.tSysNetcardAlarm.switch_devname, "-", 1); + strncat(arg->Malarm.tSysNetcardAlarm.switch_devname, retp, (NIC_NAME_LEN - arg->host_name_size - 1)); + arg->Malarm.tSysNetcardAlarm.flags = NETCARD_ALARM_SWITCH; + arg->Malarm.tSysNetcardAlarm.retrytimes = 0; + arg->Malarm.tMsgFrame.len = sizeof(arg->Malarm); + arg->Malarm.tMsgFrame.seqno = seqno; + count = 3; + pthread_mutex_lock(&mut); + snprintf(error_str, sizeof(error_str), "NOTICE: Net card checking to %s!\n", retp); + record_log(error_str); + while(count > 0){ + send_alarm(&arg->Malarm, arg->conf->udpport, arg->conf->ip); + seqno++; + arg->Malarm.tMsgFrame.seqno = seqno; + arg->Malarm.tSysNetcardAlarm.retrytimes++; + count--; + } + pthread_mutex_unlock(&mut); + memset(name, 0, NIC_NAME_LEN); + strncpy(name, retp, strlen(retp)); + } + fclose(fp); + nanosleep(&s_time, &os_time); + if((fp = fopen(arg->bond_file_path, "r")) == NULL){ + free(ptr); + return NULL; + } + fseek(fp, 65, SEEK_SET); + } + free(ptr); + fclose(fp); + return NULL; +} + +static void *create_logfile(void *ptr) +{ + char buf[128]; + char del_file[DAYS][1024]; + char *s; + int head, tail, fd; + int flag = 0, del_flag = 0; + int old_mon = 0; + int old_day = 0; + time_t tamp; + struct tm tmptr; + struct timespec s_time, os_time; + + s_time.tv_sec = 1; + s_time.tv_nsec = 0; + head = tail = 0; + while(1){ + tamp = time(NULL); + localtime_r(&tamp, &tmptr); + if(old_mon != (tmptr.tm_mon + 1))flag = 1; + else if(old_day != tmptr.tm_mday)flag = 1; + else flag = 0; + if(flag){ + s = strrchr(log_path, '/'); + s++; + *s = '\0'; + memset(buf, 0, sizeof(buf)); + strftime(buf, sizeof(buf), "%Y%m%d_", &tmptr); + strcat(buf, process_name); + strcat(buf, ".log"); + strcat(log_path, buf); + mode_t mask_tmp; + mask_tmp = umask(0000); + if((fd = open(log_path, O_RDWR|O_CREAT, 0666)) != -1){ + log_flag = 0; + close(fd); + } + umask(mask_tmp); + old_mon = tmptr.tm_mon+1; + old_day = tmptr.tm_mday; + strcpy(del_file[head++], log_path); + if(head == DAYS){ + head = 0; + del_flag = 1; + } + if(del_flag){ + unlink(del_file[tail]); + tail++; + if(tail == DAYS)tail = 0; + } + } + nanosleep(&s_time, &os_time); + } +} + +void write_time(int semid, SHM *ptr) +{ + int i = 0; + int flag_time_stamp; + + flag_time_stamp = time(NULL); + + while(ptr->info[i].charname[0] != 0){ + ptr->info[i].time_stamp = flag_time_stamp; + i++; + } +} +#if 0 +char *parse(char *line) +{ + char *begin = NULL; + char *end = NULL; + + if((begin = strchr(line, '/')) != NULL){ + if((end = strstr(line, "bin")) != NULL){ + *end='\0'; + return begin; + } + } + return NULL; +} +#endif +void release_name_list(NET_NAME_ST *head) +{ + NET_NAME_ST *curr, *save; + + curr = head->next; + while(curr != NULL){ + save = curr->next; + free(curr); + curr = save; + } +} +int get_netcard(char *line, char *nic) +{ + char *begin, *retp; + + while(isspace(*line))line++; + begin = line; + while(!isspace(*line))line++; + *line++ = '\0'; + if(!strncmp(begin, "nic", 4)){ + if((retp = parse_str(&line)) != NULL){ + strncpy(nic, retp, MAXNICNUM); + return 1; + } + } + return 0; +} + +void sig_handler(int sig) +{ +// char err_str[200]; + +#if 0 + if(unlink(SHM_PATH) == -1){ + snprintf(err_str, sizeof(err_str), "NOTICE: error delete %s\n", strerror(errno)); + record_log(err_str); + } + if(unlink(SEM_PATH) == -1){ + snprintf(err_str, sizeof(err_str), "NOTICE: error delete %s\n", strerror(errno)); + record_log(err_str); + } +#endif +// semctl(sem_id, 0, IPC_RMID); + +// snprintf(err_str, sizeof(err_str), "NOTICE: process exit by signal %d\n", sig); +// record_log(err_str); + exit(0); +} + +/* + * 查看数据结构中是否有给定的网卡 + * 输入:网卡名称 + * 返回值:-1 表示没有 + * 非0值表示设备列表中的索引 + * + */ +int find_nic_config(char *dev_name){ + int i, index=-1; + + for(i=0; iname, myconf[13]) == 0) && (nicnum <= MAXNICNUM)){ + i = 1; + if(cmd->data.list[0] && cmd->data.list[1]){ + //查找设备列表中是否已有该网卡 + //如果没有则创建一项 + //如果已有则只要增加ping的地址和地址数量 + //一般都能找到,因为配置文件中一般总是先定义"nic",后定义"ping" + //如果没找到,则表明先定义了"ping",未定义"nic"或后定义"nic",而未定义"nic"应该是错误的 + index = find_nic_config(cmd->data.list[0]); + if(index == -1){ + strncpy(conf.nic[nicnum].dev_name, cmd->data.list[0], strlen(cmd->data.list[0]) >= IPLEN ? IPLEN-1 : strlen(cmd->data.list[0])); + card_info_index = nicnum; + nicnum++; + } + else + card_info_index = index; + + while(cmd->data.list[i]){ + if((int)(inet_addr(cmd->data.list[i])) == -1){ + sprintf(wrong_ip,"The wrong IP address:'%s'",cmd->data.list[i]); + strcat(wrong_ip,"\n"); + record_log(wrong_ip); + } else{ + strncpy(conf.nic[card_info_index].ping_ip[conf.nic[card_info_index].gw_num++], cmd->data.list[i], strlen(cmd->data.list[i]) >= IPLEN ? IPLEN-1 : strlen(cmd->data.list[i])); + } + i++; + } + } + } + + //"nic"选项的处理 + if((strcmp(cmd ->name, myconf[12]) == 0) && (nicnum <= MAXNICNUM)){ + //设备列表中没有给定的网卡设备,则添加一项 + //否则不必添加 + //对应配置文件中先指定"ping"后指定"nic"的情况 + index = find_nic_config(cmd->data.str); + if(index == -1){ + strncpy(conf.nic[nicnum].dev_name, cmd->data.str, strlen(cmd->data.str) >= NIC_NAME_LEN ? NIC_NAME_LEN-1 : strlen(cmd->data.str)); + nicnum++; + } + } + + if((strcmp(cmd ->name, myconf[11]) == 0)){ + strncpy(conf.udp, cmd->data.str, strlen(cmd->data.str)); + } + + return NULL; +} + +DOTCONF_CB(cb_int) +{ + if(strcmp(cmd ->name, myconf[0]) == 0){ + conf.domain = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[1]) == 0){ + conf.serv = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[2]) == 0){ + conf.event = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[3]) == 0){ + conf.udpport = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[6]) == 0){ + conf.monitor_interval = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[7]) == 0){ + conf.write_interval = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[8]) == 0){ + conf.flow_interval = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[9]) == 0){ + conf.flow_limit = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[10]) == 0){ + conf.flow_peak = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[14]) == 0){ + conf.pingnum = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[15]) == 0){ + conf.pinglap = cmd->data.value; + } + + return NULL; +} + +DOTCONF_CB(cb_list) +{ + return NULL; +} + +int get_conf() +{ +// int uid; +// char buf[1024]; +// int i; +// struct passwd *user; + configfile_t *configfile; + +// memset(buf, 0, sizeof(buf)); +// uid=getuid(); +// user = getpwnam("d5000"); +// user = getpwuid(uid); + +// sprintf(buf,"%s", user->pw_dir); +// strcat(buf,conf_path); + + configfile = dotconf_create(conf_path, options, NULL, CASE_INSENSITIVE); + if (!configfile) + { + record_log("Warning can't reading config file\n"); + return -1; + } + + if (dotconf_command_loop(configfile) == 0){ + record_log("Warning can't reading config file\n"); + return -1; + } + dotconf_cleanup(configfile); + + if(conf.domain == 0) + conf.domain = 10; + if(conf.serv == 0) + conf.serv = 1; + if(conf.event == 0) + conf.event = 2; + if(conf.udpport == 0) + conf.udpport = 15000; + if(conf.monitor_interval == 0) + conf.monitor_interval = 100; + if(conf.write_interval == 0) + conf.write_interval = 300; + if(conf.flow_interval == 0) + conf.flow_interval = 60; + if(conf.flow_limit == 0) + conf.flow_limit = 30; + if(conf.flow_peak == 0) + conf.flow_peak = 1000; + if(conf.udp[0] == 0) + strcpy(conf.udp, "bond0"); + if(conf.nic[0].dev_name[0] == 0) + strcpy(conf.nic[0].dev_name, "bond0"); + if(conf.pingnum == 0) + conf.pingnum = 2; + if(conf.pinglap == 0) + conf.pinglap = 1; + + return 0; +} + +int isrun(char *p) +{ + char buf[16]; + char cmdbuf[1024]; + FILE *fp; + + memset(buf, 0, sizeof(buf)); + memset(cmdbuf, 0, sizeof(cmdbuf)); + + snprintf(cmdbuf, sizeof(cmdbuf), "pidof %s", p); + fp=popen(cmdbuf, "r"); + fread(buf, sizeof(char), sizeof(buf), fp); + pclose(fp); + if(strchr(buf, ' ') != NULL) + return 1; + else + return 0; +} + +int get_broad_ip(void) +{ + char ip_p[4][4]; + char error_str[200]; + int skfd; + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + memset(ip_p, 0, sizeof(ip_p)); + + if((skfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)return -1; + strcpy(ifr.ifr_name, conf.udp); + if (!ioctl(skfd, SIOCGIFBRDADDR, &ifr)){ + sprintf(ip_p[0], "%d", (unsigned char)ifr.ifr_broadaddr.sa_data[2]); + sprintf(ip_p[1], "%d", (unsigned char)ifr.ifr_broadaddr.sa_data[3]); + sprintf(ip_p[2], "%d", (unsigned char)ifr.ifr_broadaddr.sa_data[4]); + sprintf(ip_p[3], "%d", (unsigned char)ifr.ifr_broadaddr.sa_data[5]); + }else{ + snprintf(error_str, sizeof(error_str), "EMERG: Invalid broadcast device -- %s\n", conf.udp); + record_log(error_str); + close(skfd); + return -1; + } + close(skfd); + strcat(conf.ip, ip_p[0]); + strcat(conf.ip, "."); + strcat(conf.ip, ip_p[1]); + strcat(conf.ip, "."); + strcat(conf.ip, ip_p[2]); + strcat(conf.ip, "."); + strcat(conf.ip, ip_p[3]); + + return 0; +} + +void create_dir(char *create_path) +{ + int i,len = strlen(create_path); + + len = strlen(create_path); + + for(i=1; inext; + while(curr != NULL){ + if(!strncmp(curr->name, conf.nic[i].dev_name, NIC_NAME_LEN)){ + if((node = (NET_NAME_ST *)malloc(sizeof(NET_NAME_ST))) == NULL){ + err_val = 1; + break; + } + memset(node->name, 0, NIC_NAME_LEN); + strncpy(node->name, conf.nic[i].dev_name, NIC_NAME_LEN); + node->next = opt_name_list->next; + opt_name_list->next = node; + count_t ++; + break; + } + curr = curr->next; + } + if(err_val)break; + } + if(count_t != i || err_val){ + for(curr = opt_name_list->next; curr != NULL; curr = curr->next)free(curr); + snprintf(error_str, sizeof(error_str), "EMERG: Invalid netcard name --\n"); + record_log(error_str); + return -1; + } + err_val = 0; + + return 0; +} + +int get_netcard_status(NETCARD_INFO_ST *listp) +{ + if((listp->info.flags & IFF_UP) != IFF_UP) + return NIC_DOWN; + + if((listp->info.flags & IFF_RUNNING) != IFF_RUNNING) + return NIC_UNRUNNING; + + //20100510 + if(elapsed_ping_time == total_ping_time){ + if(ping_gw(listp->info.charname) != 0) + return NIC_UNLINKABLE; + } + else{ + if(listp->status == NIC_UNLINKABLE) + return NIC_UNLINKABLE; + } + + return NIC_NORMAL; +} + +int do_alarm(NETCARD_INFO_ST *listp, int nic_status, D5000_NIC_ALARM *Malarm) +{ + int i; + char error_str[200]; + + memset(Malarm->tSysNetcardAlarm.fault_devname, 0, NIC_NAME_LEN); + strncpy(Malarm->tSysNetcardAlarm.fault_devname, host_name, host_name_size); + strncat(Malarm->tSysNetcardAlarm.fault_devname, "-", 1); + strncat(Malarm->tSysNetcardAlarm.fault_devname, listp->info.charname, NIC_NAME_LEN - host_name_size - 1); + Malarm->tSysNetcardAlarm.retrytimes = 0; + Malarm->tMsgFrame.len = sizeof(Malarm); + Malarm->tMsgFrame.seqno = seqno; + + switch(nic_status){ + case NIC_DOWN: + Malarm->tSysNetcardAlarm.flags = NETCARD_ALARM_FAULT; + snprintf(error_str, sizeof(error_str), "NOTICE: %s is DOWN!\n", listp->info.charname); + break; + case NIC_UNRUNNING: + Malarm->tSysNetcardAlarm.flags = NETCARD_ALARM_FAULT; + snprintf(error_str, sizeof(error_str), "NOTICE: %s is UP but UNRUNNING!\n", listp->info.charname); + break; + case NIC_UNLINKABLE: + Malarm->tSysNetcardAlarm.flags = NETCARD_ALARM_FAULT; + listp->info.flags &= (~IFF_UP); + listp->info.flags &= (~IFF_RUNNING); + snprintf(error_str, sizeof(error_str), "NOTICE: %s is RUNNING but UNLINKABLE!\n", listp->info.charname); + break; + case NIC_NORMAL: + Malarm->tSysNetcardAlarm.flags = NETCARD_ALARM_RESUME; + snprintf(error_str, sizeof(error_str), "NOTICE: %s is NORMAL!\n", listp->info.charname); + break; + } + pthread_mutex_lock(&mut); + for(i = 0; i < 3; i++){ + send_alarm(Malarm, conf.udpport, conf.ip); + seqno++; + Malarm->tMsgFrame.seqno = seqno; + Malarm->tSysNetcardAlarm.retrytimes++; + } + send_inc_info_one(&listp->info, semid, shm_ptr); + pthread_mutex_unlock(&mut); + record_log(error_str); + + return 0; +} + +int main(int argc, char ** argv) +{ + int ret = 0, proc_stat = 0; + unsigned int i = 0; + int nic_status; + int sys_time_stamp = 0; + char *retp = NULL; + char *str = NULL; + char bond[128]; + char error_str[200]; + char linebuf[LINE_SIZE]; + THENV *arg; + glob_t res; + FILE *bond_fp = NULL; + pthread_t tid[THRNR]; + pthread_t tid_mem; + pthread_t tid_flow; + pthread_t tid_time; + THMEM mem; + THFLOW flow; + struct timespec s_time, os_time, log_time; + NET_NAME_ST all_name_list, opt_name_list; + NETCARD_INFO_ST inc_info_list, *listp = NULL; + D5000_NIC_ALARM Malarm; + struct sigaction sig; + struct passwd *user; + proc_invocation prcm; + + char log_record[125]={0}; + + memset(&conf, 0, sizeof(CONFIG_FILE_ST)); + if(isrun(argv[0]) == 1){ + printf("the program is already started!\n"); + exit(0); + } +//process register +#if 1 + if((proc_stat=prcm.proc_init("sys","base_srv","sys_nicmonitor"))==-1){ + perror("proc_init()"); + exit(-1); + } +#endif + + sig.sa_handler = sig_handler; + sigemptyset(&sig.sa_mask); + sigaddset(&sig.sa_mask, SIGINT); + sigaddset(&sig.sa_mask, SIGTERM); + sig.sa_flags = 0; + sigaction(SIGTERM, &sig, NULL); + sigaction(SIGINT, &sig, NULL); + sigaction(SIGSEGV, &sig, NULL); + + /* create dir file path */ + if((user = getpwnam("d5000")) != NULL){ + sprintf(log_path,"%s",user->pw_dir); + sprintf(shm_path,"%s",user->pw_dir); + sprintf(sem_path,"%s",user->pw_dir); + sprintf(conf_path,"%s",user->pw_dir); + } + + strcat(log_path,LOG_PATH); + strcat(shm_path,SHM_PATH); + strcat(sem_path,SEM_PATH); + strcat(conf_path,CONF_FILE); + + create_semdir(); + create_shmdir(); + create_logdir(); + create_confdir(); + + /* get process name */ + memset(process_name, 0, sizeof(process_name)); + if((retp = strrchr(argv[0], '/')) != NULL){ + retp++; + strcpy(process_name, retp); + }else{ + strcpy(process_name, argv[0]); + } + /*create logfile thread */ + pthread_create(&tid_time, NULL, create_logfile, NULL); + + /* initialize some....*/ + memset(&all_name_list, 0, sizeof(NET_NAME_ST)); + all_name_list.next = NULL; + memset(&opt_name_list, 0, sizeof(NET_NAME_ST)); + opt_name_list.next = NULL; + + memset(&inc_info_list, 0, sizeof(NETCARD_INFO_ST)); + inc_info_list.next = NULL; + + + /* get all netcard by proc/net/dev and ioctl */ + get_all_name(&all_name_list); + + /* wait for create log thread */ + log_time.tv_sec = 0; + log_time.tv_nsec = 1000000; + while(log_flag)nanosleep(&log_time, NULL); + + /* sure the process is started */ + snprintf(error_str, sizeof(error_str), "NOTICE: %s V%s is started !\n", process_name, MNIC_VERSION); + record_log(error_str); + + get_conf(); + + if(shm_path){ + printf("shm_path:%s\n",shm_path); + sprintf(log_record,"shm_path:%s\n",shm_path); + record_log(log_record); + } + + if(log_path){ + printf("log_path:%s\n",log_path); + sprintf(log_record,"log_path:%s\n",log_path); + record_log(log_record); + } + + + if(conf.udp){ + printf("udp %s\n",conf.udp); + sprintf(log_record,"udp %s\n",conf.udp); + record_log(log_record); + } + + for(i=0;conf.nic[i].dev_name[0]!=0;i++){ + printf("nic %s\n",conf.nic[i].dev_name); + sprintf(log_record,"nic %s\n",conf.nic[i].dev_name); + record_log(log_record); + } + + /* get broadcast address*/ + if((ret = get_broad_ip()) != 0) + return -1; + if((ret = create_name_list(&all_name_list, &opt_name_list)) != 0) + return -1; + /* get hostname */ + if((ret = gethostname(host_name, sizeof(host_name))) != -1){ + host_name_size = strlen(host_name); + }else host_name_size = HOST_NAME_SIZE; + /* initialize Malarm */ + Malarm.tMsgFrame.serv = conf.serv; + Malarm.tMsgFrame.event = conf.event; + Malarm.tMsgFrame.domain = conf.domain; + + /* get bonding file */ + memset(bond, 0, sizeof(bond)); + memset(linebuf, 0, sizeof(linebuf)); + if((ret = glob(BOND_PATH, 0, NULL, &res)) != 0){ + snprintf(error_str, sizeof(error_str), "NOTICE: No bonding netcard !\n"); + record_log(error_str); + strcpy(bond, "No bonding netcard!"); + } + for (i = 0; i < res.gl_pathc; ++i) { + if((arg = (THENV *)malloc(sizeof(THENV))) != NULL){ + memset(arg, 0, sizeof(THENV)); + strncpy(arg->bond_file_path, res.gl_pathv[i], strlen(res.gl_pathv[i])); + arg->Malarm = Malarm; + strncpy(arg->host_name, host_name, host_name_size); + arg->host_name_size = host_name_size; + arg->conf = &conf; + if(pthread_create(tid+i, NULL, check_inc_switch, (void*)arg)){ + snprintf(error_str, sizeof(error_str), "EMERG: pthread_create(): %s\n", strerror(errno)); + record_log(error_str); + } + } + } + for(i = 0; i < res.gl_pathc; ++i){ + if((bond_fp = fopen(res.gl_pathv[i], "r")) == NULL){ + snprintf(error_str, sizeof(error_str), "EMERG: fopen(): %s\n", strerror(errno)); + record_log(error_str); + }else{ + retp = strrchr(res.gl_pathv[i], '/'); + retp++; + strcat(bond, retp); + strcat(bond, ":"); + while((str = fgets(linebuf, sizeof(linebuf), bond_fp)) != NULL){ + if(!strncmp(linebuf, "Slave Interface:", 16)){ + str += 16; + retp = parse_str(&str); + strcat(bond, retp); + strcat(bond, " "); + } + } + fclose(bond_fp); + } + } + + /* initialize time*/ + s_time.tv_sec = 0; + s_time.tv_nsec = conf.monitor_interval*1000*1000; + + /* initialize sem*/ + init_sem(&semid, &conf); + init_shm(&shm_ptr, &conf); + /* for IPC_RMID */ + sem_id = semid; + + /* create monitor netcard list */ + create_monit_list(&opt_name_list, &inc_info_list, bond); + release_name_list(&all_name_list); + release_name_list(&opt_name_list); + + mem.semid = semid; + mem.shm_ptr = shm_ptr; + mem.listp = &inc_info_list; + mem.conf = &conf; + if(pthread_create(&tid_mem, NULL, send_inc_info, (void *)&mem)){ + snprintf(error_str, sizeof(error_str), "EMERG: pthread_create(): %s\n", strerror(errno)); + record_log(error_str); + } + + /* create caculate flow thread*/ + flow.env.Malarm = Malarm; + strncpy(flow.env.host_name, host_name, host_name_size); + flow.env.host_name_size = host_name_size; + flow.mem.semid = semid; + flow.mem.shm_ptr = shm_ptr; + flow.mem.listp = &inc_info_list; + flow.mem.conf = &conf; + if(pthread_create(&tid_flow, NULL, cacu_flow, (void *)&flow)){ + snprintf(error_str, sizeof(error_str), "EMERG: pthread_create(): %s\n", strerror(errno)); + record_log(error_str); + } + + total_ping_time = 1000 / conf.monitor_interval; + if(total_ping_time == 0) + total_ping_time = 1; + elapsed_ping_time = 1; + + while(1){ + i = 0; + listp = inc_info_list.next; + for(i = 0; listp != NULL; i++){ + get_inc_info(&listp->info); + get_inc_stats(&listp->info); + nic_status = get_netcard_status(listp); + if(nic_status != listp->status){ + do_alarm(listp, nic_status, &Malarm); + listp->status = nic_status; + } + listp = listp->next; + } + + if(seqno > 32765)seqno = 0; + nanosleep(&s_time, &os_time); + + + //20100510 + ++elapsed_ping_time; + if(elapsed_ping_time > total_ping_time) + elapsed_ping_time = 1; + + sys_time_stamp += conf.monitor_interval; + if(sys_time_stamp >= 1000){ + sys_time_stamp = 0; + write_time(semid, shm_ptr); + } + } + for (i = 0; i < res.gl_pathc; i++) { + pthread_join(tid[i], NULL); + } + pthread_join(tid_mem, NULL); + pthread_join(tid_flow, NULL); + pthread_join(tid_time, NULL); + pthread_mutex_destroy(&mut); + globfree(&res); + munmap(shm_ptr, sizeof(SHM)); + return 0; +} diff --git a/branches/sys_nicmonitor-1.5/mnic.h b/branches/sys_nicmonitor-1.5/mnic.h new file mode 100644 index 0000000..d7a6390 --- /dev/null +++ b/branches/sys_nicmonitor-1.5/mnic.h @@ -0,0 +1,44 @@ +#ifndef __MNIC_H +#define __MNIC_H + +//#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sys_netcard.h" +#include +#include +#define IPSIZE 16 + +char *get_name(char *, char *); +int if_fetch(NETCARD_INFO *); +int ioc_get_name(NETCARD_INFO *); +int get_dev_fields(char *p, NETCARD_INFO *); +int get_user_home(int , char *); +void send_alarm(D5000_NIC_ALARM *, int , char *); +void record_log(char *); + +#endif diff --git a/branches/sys_nicmonitor-1.5/nicinfo_shm.c b/branches/sys_nicmonitor-1.5/nicinfo_shm.c new file mode 100644 index 0000000..c8a8bf2 --- /dev/null +++ b/branches/sys_nicmonitor-1.5/nicinfo_shm.c @@ -0,0 +1,209 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nicinfo_shm.h" + +#define SHM_PATH "/tmp/sys_netcard_shm_path" +#define SEM_PATH "/tmp/sys_netcard_sem_path" +#define LOG_PATH "/var/log/netcard/" + +typedef struct net_info{ + NETCARD_INFO info[MAXNICNUM]; +}SHM; + +static int semid = 0; +static char log_path[1024]; +static char shm_path[1024]; +static char sem_path[1024]; +SHM *ptr = NULL; + +/* write error in logfile */ +void record_log(char *str) +{ + time_t tamp; + char str_tm[4]; + char log_str[512]; + FILE *log_fp = NULL; + struct tm tmptr; + struct timeval tv; + struct timezone tz; + + if((log_fp = fopen(log_path, "a")) != NULL){ + tamp = time(NULL); + memset(str_tm, 0, sizeof(str_tm)); + memset(log_str, 0, sizeof(log_str)); + localtime_r(&tamp, &tmptr); + gettimeofday(&tv, &tz); + snprintf(str_tm, sizeof(str_tm), "%d", (int)tv.tv_usec/1000); + if(str_tm[1] == '\0')str_tm[1] = '0'; + if(str_tm[2] == '\0')str_tm[2] = '0'; + strftime(log_str, sizeof(log_str), "%F %T.", &tmptr); + strcat(log_str, str_tm); + strcat(log_str, " "); + strcat(log_str, "get_nic_info"); + strcat(log_str, " "); + strcat(log_str, str); + if(fwrite(log_str, 1, strlen(log_str), log_fp) < 1){ + } + fclose(log_fp); + } +} + +void get_sem(int semid) +{ + char err_str[200]; + struct sembuf lock[2]; + + lock[0].sem_num = 0; + lock[0].sem_op = 0; + lock[0].sem_flg = SEM_UNDO; + + lock[1].sem_num = 0; + lock[1].sem_op = 1; + lock[1].sem_flg = SEM_UNDO; + + while(semop(semid, lock, 2)){ + if (errno == EINTR) { + continue; + } + snprintf(err_str, sizeof(err_str), "EMERG: semop():\n", strerror(errno)); + record_log(err_str); + return; + } +} + +void release_sem(int semid) +{ + int ret; + char err_str[200]; + struct sembuf unlock; + + unlock.sem_num = 0; + unlock.sem_op = -1; + unlock.sem_flg = SEM_UNDO; + + if((ret = semop(semid, &unlock, 1)) == -1){ + snprintf(err_str, sizeof(err_str), "EMERG: semop():\n", strerror(errno)); + record_log(err_str); + return; + } +} + + +int init_nic_info(void) +{ + int fd = -1; + int sem_val; + char err_str[200]; + key_t key; + + + if ((key=ftok(sem_path, SEM_PROJ_ID)) == -1) { + snprintf(err_str, sizeof(err_str), "EMERG: ftok():%s\n", strerror(errno)); + record_log(err_str); + return -1; + } + if((semid = semget(key, 1, IPC_CREAT|0666)) == -1){ + snprintf(err_str, sizeof(err_str), "EMERG: Create semaphore error: %s\n", strerror(errno)); + record_log(err_str); + return -1; + } + /* + if((sem_val = semctl(semid, 0, GETVAL, 0)) == -1){ + snprintf(err_str, sizeof(err_str), "EMERG: semctl: %s !\n", strerror(errno)); + record_log(err_str); + semctl(semid, 0, IPC_RMID); + return -1; + } + if(!sem_val){ + if(semctl(semid, 0, SETVAL, 1) == -1){ + snprintf(err_str, sizeof(err_str), "EMERG: semctl: %s !\n", strerror(errno)); + record_log(err_str); + semctl(semid, 0, IPC_RMID); + return -1; + } + } + */ + if((fd = open(shm_path, O_RDONLY)) == -1){ + snprintf(err_str, sizeof(err_str), "EMERG: Error open %s: %s!\n",shm_path, strerror(errno)); + record_log(err_str); + return -1; + } + ptr = (SHM*)mmap(NULL, sizeof(SHM), PROT_READ, MAP_SHARED, fd, 0); + if(ptr == MAP_FAILED){ + snprintf(err_str, sizeof(err_str), "EMERG: mmap():%s\n", strerror(errno)); + record_log(err_str); + return -1; + } + close(fd); + + return 0; +} +int get_nic_info(char *nic_name, NETCARD_INFO *net_info) +{ + int i,ret; + time_t tamp; + struct tm tmptr; + DIR *dir; + char *s; + char buf[128]; + char err_str[200]; + struct passwd *user; + + tamp = time(NULL); + localtime_r(&tamp, &tmptr); + + if((user = getpwnam("d5000"))!= NULL){ + sprintf(log_path,"%s",user->pw_dir); + sprintf(shm_path,"%s",user->pw_dir); + sprintf(sem_path,"%s",user->pw_dir); + } + strcat(log_path,LOG_PATH); + strcat(shm_path,SHM_PATH); + strcat(sem_path,SEM_PATH); + + if((dir = opendir(log_path)) == NULL){ + if(errno == ENOENT){ + strcpy(log_path, "/tmp/"); + } + } + closedir(dir); + s = strrchr(log_path, '/'); + s++; + *s = '\0'; + memset(buf, 0, sizeof(buf)); + strftime(buf, sizeof(buf), "%Y%m%d_", &tmptr); + strcat(buf, "sys_nicmonitor"); + strcat(buf, ".log"); + strcat(log_path, buf); + if((ret = init_nic_info()) == -1){ + return -1; + } + get_sem(semid); + for(i = 0; ptr->info[i].charname[0] != 0; i++){ + if(!strcmp(ptr->info[i].charname, nic_name)){ + // get_sem(semid); + memcpy(net_info, &ptr->info[i], sizeof(NETCARD_INFO)); + release_sem(semid); + munmap(ptr, sizeof(SHM)); + return 0; + } + } + release_sem(semid); + snprintf(err_str, sizeof(err_str), "NOTICE: No information of %s !\n", nic_name); + record_log(err_str); + munmap(ptr, sizeof(SHM)); + return -1; +} diff --git a/branches/sys_nicmonitor-1.5/nicinfo_shm.h b/branches/sys_nicmonitor-1.5/nicinfo_shm.h new file mode 100644 index 0000000..cd74135 --- /dev/null +++ b/branches/sys_nicmonitor-1.5/nicinfo_shm.h @@ -0,0 +1,52 @@ +#ifndef NIC_SHM_H +#define NIC_SHM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NIC_NAME_LEN +#define NIC_NAME_LEN 64 +#endif +#define SEM_PROJ_ID 's' +#define MAXNICNUM 32 + +typedef long KEYID; +typedef struct _net_info +{ + KEYID ID; + char charname[NIC_NAME_LEN]; + char descr[128]; + struct sockaddr addr; + struct sockaddr broadaddr; + struct sockaddr netmask; + struct sockaddr hwaddr; + int time_stamp; + short flags; + int mtu; + int tx_queue_len; + unsigned long long average_flow; + unsigned long long rx_packets; + unsigned long long tx_packets; + unsigned long long rx_bytes; + unsigned long long tx_bytes; + unsigned long rx_errors; + unsigned long tx_errors; + unsigned long rx_dropped; + unsigned long tx_dropped; + unsigned long rx_multicast; + unsigned long collisions; + unsigned long rx_fifo_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; +}NETCARD_INFO; + +int get_nic_info(char *nic_name, NETCARD_INFO *net_info); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/branches/sys_nicmonitor-1.5/proc_inv.h b/branches/sys_nicmonitor-1.5/proc_inv.h new file mode 100644 index 0000000..945622c --- /dev/null +++ b/branches/sys_nicmonitor-1.5/proc_inv.h @@ -0,0 +1,198 @@ +//////////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Comets' Grp. of Kedong Corp 2008. All Rights Reserved. +// +// FileName : procconf.h +// +// Function : this class realize some basic functions for process managerment, +// such as initiate process, report status of process, check status of process, +// update status of process, get information of process +// +// Author : +// +// Date : +// +// Modify by : +// +// Mod Date : +// +//////////////////////////////////////////////////////////////////////////////////// + +#ifndef _PROCCONF_H +#define _PROCCONF_H + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + +#include "const.h" + +//for alarm ................................ +typedef struct MESS_BH +{ + unsigned char mtype; + int length; +}; +typedef struct PROCESS_ALM +{ + char context_name[MAX_STRING_LEN]; + char app_name[MAX_STRING_LEN]; + char proc_name[MAX_STRING_LEN]; + unsigned char status; +}; +//for alarm end ............................. + +//for mmi.................................... +const int MAX_BUFFER_LEN = 500; +typedef struct MESS_BLOCK +{ + unsigned char num; + char buffer[MAX_BUFFER_LEN]; +}; +typedef struct MESS_PROC +{ + char context_name[MAX_STRING_LEN]; + char app_name[MAX_STRING_LEN]; + char proc_name[MAX_STRING_LEN]; + char status; +}; +//for mmi end ................................ + +const int DEFAULT_PERIOD = 3; +const int COUNT_LIMIT = 2; +const int START_DEFAULT_PERIOD = 60; +const int START_COUNT_LIMIT = 5; +const int APP_COUNT_LIMIT = 1; + +//process critical level +//const int WST_CRITICAL = 1; // Shutdown and reboot workstation when failed +//const int SYS_CRITICAL = 2; // Shutdown and reboot the system on the wst when failed +//const int USER_CRITICAL = 3; // Shutdown and reboot the subsystem when failed +//const int GENERAL = 4; // reboot the process +const int CRUCIAL = 1; // crucial process +const int GENERAL = 0; // general process + + +extern int srv_init(char *service,int port); +extern int Tcp_close(int sockfd); +extern int Tcp_read(int fd,char *ptr,int nbytes); +extern int Tcp_write(int fd,char *ptr,int nbytes); +extern int srv_accept(int fd,struct sockaddr *cli_addr,int *clilen); +extern int client_tcp_open(char *host,char *service,int port); + +typedef struct +{ + char context_name[MAX_STRING_LEN]; + char app_name[MAX_STRING_LEN]; + char proc_name[MAX_STRING_LEN]; + pid_t proc_pid; +}PROC_ADM_INFO; + +//*************************************************************** +// structure name : PROC_INFO +// function : store process informatin +// author : +// date : +// modify by : +// modification : +// mod date : +//*************************************************************** +typedef struct +{ + int position; + char node_name[MAX_STRING_LEN]; + char context_name[MAX_STRING_LEN]; + char app_name[MAX_STRING_LEN]; + char proc_name[MAX_STRING_LEN]; + + unsigned char active_flag; + unsigned char master_flag; + + time_t startup_time; + time_t refresh_time; + short refresh_peri; + unsigned char monitor_type; + + pid_t proc_pid; + unsigned char auto_start; + unsigned char act_timer; + unsigned char start_timer; + unsigned char critical_level; + + char exefile_path[MAX_EXECMD_LEN]; + +}PROC_INFO; + +//*************************************************************** +// structure name : APP_INFO +// function : store application informatin +// author : +// date : +// modify by : +// modification : +// mod date : +//*************************************************************** +typedef struct +{ + int position; + char context_name[MAX_STRING_LEN]; + int context_id; + char app_name[MAX_STRING_LEN]; + int app_id; + unsigned char act_timer; + unsigned char active_flag; +}APP_INFO; + + +typedef struct +{ + int no_proc; + int semdes_cfg; + PROC_INFO proc[MAX_LOCAL_PROCESS]; + APP_INFO app[MAX_LOCAL_APP]; +}PROCCFG; + +class proc_invocation +{ + public: + int m_init; + PROCCFG *proccfg_p; + + public: + proc_invocation(); + ~proc_invocation(); + + int conf_create(); + //int check_proc_status(); + //int update_rtdb(); + //int kill_proc(pid_t pid); + //int start_proc(char *cmdline); + //int send_alarm(char *context_name, char *app_name, char *proc_name, unsigned char status); + //int update_proc_status(char *context_name, char *app_name, char *proc_name, char status); + + //int proc_init(char *context_name, char *app_name, char *proc_name, int critical_level);//exefile_path,auto_start + int proc_init(char *context_name, char *app_name, char *proc_name); + int proc_report(int pos, char status, int intertime=3); + int proc_exit(int proc_pos); + + int get_pos(char *context_name, char *app_name, char *proc_name); + int is_proc_exist(char *context_name, char *app_name, char *proc_name); + int conf_map(); + + int get_procinfo(int position, PROC_ADM_INFO *p_info); + int get_active_pid(int &num, int *p_pidlist); + int is_proc_run(pid_t pid); + int is_proc_run(char *context_name, char *app_name, char *proc_name); + +}; + +#endif + + + diff --git a/branches/sys_nicmonitor-1.5/read_netcard.c b/branches/sys_nicmonitor-1.5/read_netcard.c new file mode 100644 index 0000000..c745f48 --- /dev/null +++ b/branches/sys_nicmonitor-1.5/read_netcard.c @@ -0,0 +1,133 @@ +#include "mnic.h" + +static char *prase_digit(char **s) +{ + char *retp = NULL; + char *p = *s; + + if(!p)return NULL; + while(!isdigit(*p)){ + p++; + if(*p == '\0')return NULL; + } + retp = p; + while(isdigit(*p)){ + p++; + if(*p == '\0'){ + *s = NULL; + return retp; + } + } + *p = '\0'; + p++; + *s = p; + return retp; +} + + +char *get_name(char *name, char *p) +{ + while (isspace(*p)) + p++; + while (*p) { + if (isspace(*p)) + break; + if (*p == ':') { /* could be an alias */ + char *dot = p, *dotname = name; + *name++ = *p++; + while (isdigit(*p)) + *name++ = *p++; + if (*p != ':') { /* it wasn't, backup */ + p = dot; + name = dotname; + } + if (*p == '\0') + return NULL; + p++; + break; + } + *name++ = *p++; + } + *name++ = '\0'; + return p; +} + +int get_dev_fields(char *str, NETCARD_INFO *ife) +{ + int i = 0; + char *retp[16]; + + while((retp[i] = prase_digit(&str)) != NULL){i++;if(i > 15)break;} + ife->rx_bytes = atoll(retp[0]); + ife->rx_packets = atoll(retp[1]); + ife->rx_errors = atol(retp[2]); + ife->rx_dropped = atol(retp[3]); + ife->rx_fifo_errors = atol(retp[4]); + ife->rx_multicast = atol(retp[7]); + ife->tx_bytes = atoll(retp[8]); + ife->tx_packets = atoll(retp[9]); + ife->tx_errors = atol(retp[10]); + ife->tx_dropped = atol(retp[11]); + ife->tx_fifo_errors = atol(retp[12]); + ife->collisions = atol(retp[13]); + ife->tx_carrier_errors = atol(retp[14]); + return 0; +} + +int if_fetch(NETCARD_INFO *ife) +{ + int skfd; + struct ifreq ifr; + + if((skfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)return -1; + + strcpy(ifr.ifr_name, ife->charname); + if (!ioctl(skfd, SIOCGIFFLAGS, &ifr)) + ife->flags = ifr.ifr_flags; + + if (!ioctl(skfd, SIOCGIFHWADDR, &ifr)) + ife->hwaddr = ifr.ifr_hwaddr; + + if (!ioctl(skfd, SIOCGIFMTU, &ifr)) + ife->mtu = ifr.ifr_mtu; + + if (!ioctl(skfd, SIOCGIFTXQLEN, &ifr)) + ife->tx_queue_len = ifr.ifr_qlen; + + if (!ioctl(skfd, SIOCGIFADDR, &ifr)) + ife->addr = ifr.ifr_addr; + + if (!ioctl(skfd, SIOCGIFBRDADDR, &ifr)) + ife->broadaddr = ifr.ifr_broadaddr; + + if (!ioctl(skfd, SIOCGIFNETMASK, &ifr)) + ife->netmask = ifr.ifr_netmask; + + ife->time_stamp = time(NULL); + close(skfd); + return 0; +} + + +int ioc_get_name(NETCARD_INFO *name) +{ + int skfd; + int ifrnum; + int i = 0; + struct ifconf ifc; + struct ifreq buf[MAXNICNUM]; + + if((skfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)return -1; + memset(buf, 0, sizeof(buf)); + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = (caddr_t) buf; + ioctl(skfd, SIOCGIFCONF, &ifc); + ifrnum = ifc.ifc_len / sizeof(struct ifreq); + while(ifrnum-- > 0){ + strcpy(name[i].charname, buf[ifrnum].ifr_name); + i++; + } + close(skfd); + return i; +} + diff --git a/branches/sys_nicmonitor-1.5/send_alarm.c b/branches/sys_nicmonitor-1.5/send_alarm.c new file mode 100644 index 0000000..e88635f --- /dev/null +++ b/branches/sys_nicmonitor-1.5/send_alarm.c @@ -0,0 +1,37 @@ +#include "mnic.h" + +void send_alarm(D5000_NIC_ALARM *mesg, int socket_port, char *ipv4) +{ + int bytes; + int sock_sd; + int val; + char error_str[200]; + struct sockaddr_in recever; + socklen_t sock_len; + + if((sock_sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ + snprintf(error_str, sizeof(error_str), "EMERG: socket(): %s\n", strerror(errno)); + record_log(error_str); + return; + } + val=1; + if ((setsockopt(sock_sd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val))) == -1) { + snprintf(error_str, sizeof(error_str), "EMERG: setsockopt(): %s\n", strerror(errno)); + record_log(error_str); + return; + } + /* init socket*/ + recever.sin_family = AF_INET; + recever.sin_port = htons(socket_port); + inet_pton(AF_INET, ipv4, &recever.sin_addr); + sock_len = sizeof(recever); + /* send alarm*/ + if((bytes = sendto(sock_sd, mesg, sizeof(D5000_NIC_ALARM), 0, (const struct sockaddr *)&recever, sock_len)) < 1){ + snprintf(error_str, sizeof(error_str), "EMERG: sendto(): %s\n", strerror(errno)); + record_log(error_str); + return; + } + //snprintf(error_str, sizeof(error_str), "NOTICE: Alarm information has already send!\n"); + //record_log(error_str); + close(sock_sd); +} diff --git a/branches/sys_nicmonitor-1.5/sys_netcard.h b/branches/sys_nicmonitor-1.5/sys_netcard.h new file mode 100644 index 0000000..0d7746c --- /dev/null +++ b/branches/sys_nicmonitor-1.5/sys_netcard.h @@ -0,0 +1,88 @@ +#ifndef _SYS_NETCARD_H +#define _SYS_NETCARD_H + +#include + +#ifndef NIC_NAME_LEN +#define NIC_NAME_LEN 64 +#endif + +#define SEM_PROJ_ID 's' +#define MAXNICNUM 32 + +#ifdef __cplusplus +extern "C"{ +#endif + +typedef long KEYID; + +typedef struct _msg_frame // message frame +{ + short len; // message length + short seqno; // send sequence + short serv; // services ID + short event; // event ID + unsigned char domain; // domain ID + unsigned char ctxt; // Context ID + short stid; // SOURCE task id + short dtid; // DESTINATION task ID + unsigned char ver_coding; // 版本号 + 编码 + unsigned char mes_type; // 帧类型 +}MSG_FRAME, *LPMSG_FRAME; + +typedef struct _net_info +{ + KEYID ID; + char charname[NIC_NAME_LEN]; + char descr[128]; + struct sockaddr addr; + struct sockaddr broadaddr; + struct sockaddr netmask; + struct sockaddr hwaddr; + int time_stamp; + short flags; + int mtu; + int tx_queue_len; + unsigned long long average_flow; + unsigned long long rx_packets; + unsigned long long tx_packets; + unsigned long long rx_bytes; + unsigned long long tx_bytes; + unsigned long rx_errors; + unsigned long tx_errors; + unsigned long rx_dropped; + unsigned long tx_dropped; + unsigned long rx_multicast; + unsigned long collisions; + unsigned long rx_fifo_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; +}NETCARD_INFO, *LPNETCARD_INFO; + +#define NETCARD_ALARM_FAULT 1 +#define NETCARD_ALARM_RESUME 2 +#define NETCARD_ALARM_SWITCH 3 +#define NETCARD_ALARM_ABNORMAL 4 +#define NETCARD_ALARM_NORMAL 5 +typedef struct _sys_netcard_alarm +{ + char fault_devname[NIC_NAME_LEN]; /*故障设备名称 */ + char switch_devname[NIC_NAME_LEN]; /*切换设备名称 */ + short flags; /* 状态标记 : 1:网卡故障。2:网卡恢复。3:网卡切换。4:流量异常。*/ + short retrytimes; //0,1,2 重发次数 +}SYS_NETCARD_ALARM, *LPSYS_NETCARD_ALARM; + + +typedef struct _d5000_nic_alarm +{ + MSG_FRAME tMsgFrame ; + SYS_NETCARD_ALARM tSysNetcardAlarm ; +}D5000_NIC_ALARM, *LPD5000_NIC_ALARM; + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/branches/sys_nicmonitor-1.5/sys_nicmonitor b/branches/sys_nicmonitor-1.5/sys_nicmonitor new file mode 100755 index 0000000000000000000000000000000000000000..5e5d31c76dfc564295ecc692130f2b9f42990f4c GIT binary patch literal 47706 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 QR+TL4^a6=r3(V#DKhkv1a{vGU literal 0 HcmV?d00001