From 91e5e24189b5d223f6b6000de787f0757353761b Mon Sep 17 00:00:00 2001 From: jli Date: Tue, 20 Sep 2011 00:40:47 +0000 Subject: [PATCH] V1.6 git-svn-id: http://172.17.0.253/svn/soft_pkgs/sys_nicmonitor@800 09c3743a-b0dd-45d3-b506-aa74c7a2a6ef --- branches/sys_nicmonitor-1.6/Makefile | 28 + branches/sys_nicmonitor-1.6/Makefile.config | 16 + branches/sys_nicmonitor-1.6/README1.5 | 32 + branches/sys_nicmonitor-1.6/const.h | 51 + branches/sys_nicmonitor-1.6/mnic.c | 1552 +++++++++++++++++++ branches/sys_nicmonitor-1.6/mnic.h | 44 + branches/sys_nicmonitor-1.6/nicinfo_shm.c | 209 +++ branches/sys_nicmonitor-1.6/nicinfo_shm.h | 52 + branches/sys_nicmonitor-1.6/proc_inv.h | 198 +++ branches/sys_nicmonitor-1.6/read_netcard.c | 133 ++ branches/sys_nicmonitor-1.6/send_alarm.c | 37 + branches/sys_nicmonitor-1.6/sys_netcard.h | 88 ++ branches/sys_nicmonitor-1.6/sys_nicmonitor | Bin 0 -> 47598 bytes 13 files changed, 2440 insertions(+) create mode 100644 branches/sys_nicmonitor-1.6/Makefile create mode 100644 branches/sys_nicmonitor-1.6/Makefile.config create mode 100644 branches/sys_nicmonitor-1.6/README1.5 create mode 100644 branches/sys_nicmonitor-1.6/const.h create mode 100755 branches/sys_nicmonitor-1.6/mnic.c create mode 100644 branches/sys_nicmonitor-1.6/mnic.h create mode 100644 branches/sys_nicmonitor-1.6/nicinfo_shm.c create mode 100644 branches/sys_nicmonitor-1.6/nicinfo_shm.h create mode 100644 branches/sys_nicmonitor-1.6/proc_inv.h create mode 100644 branches/sys_nicmonitor-1.6/read_netcard.c create mode 100644 branches/sys_nicmonitor-1.6/send_alarm.c create mode 100644 branches/sys_nicmonitor-1.6/sys_netcard.h create mode 100755 branches/sys_nicmonitor-1.6/sys_nicmonitor diff --git a/branches/sys_nicmonitor-1.6/Makefile b/branches/sys_nicmonitor-1.6/Makefile new file mode 100644 index 0000000..5cccc77 --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/Makefile.config b/branches/sys_nicmonitor-1.6/Makefile.config new file mode 100644 index 0000000..7a2d8e6 --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/README1.5 b/branches/sys_nicmonitor-1.6/README1.5 new file mode 100644 index 0000000..fa1087e --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/const.h b/branches/sys_nicmonitor-1.6/const.h new file mode 100644 index 0000000..e2ebfa5 --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/mnic.c b/branches/sys_nicmonitor-1.6/mnic.c new file mode 100755 index 0000000..2cb9309 --- /dev/null +++ b/branches/sys_nicmonitor-1.6/mnic.c @@ -0,0 +1,1552 @@ +#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) +{ + FILE *fp; + int i, j, k; + char buf[128]; + char getbuf[64]; + + i = find_nic_config(devname); + if( i == -1 ) + return 0; + + if(conf.nic[i].gw_num == 0) + return 0; + + for(k=0; kbond_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 0 + 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.6/mnic.h b/branches/sys_nicmonitor-1.6/mnic.h new file mode 100644 index 0000000..d7a6390 --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/nicinfo_shm.c b/branches/sys_nicmonitor-1.6/nicinfo_shm.c new file mode 100644 index 0000000..c8a8bf2 --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/nicinfo_shm.h b/branches/sys_nicmonitor-1.6/nicinfo_shm.h new file mode 100644 index 0000000..cd74135 --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/proc_inv.h b/branches/sys_nicmonitor-1.6/proc_inv.h new file mode 100644 index 0000000..945622c --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/read_netcard.c b/branches/sys_nicmonitor-1.6/read_netcard.c new file mode 100644 index 0000000..c745f48 --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/send_alarm.c b/branches/sys_nicmonitor-1.6/send_alarm.c new file mode 100644 index 0000000..e88635f --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/sys_netcard.h b/branches/sys_nicmonitor-1.6/sys_netcard.h new file mode 100644 index 0000000..0d7746c --- /dev/null +++ b/branches/sys_nicmonitor-1.6/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.6/sys_nicmonitor b/branches/sys_nicmonitor-1.6/sys_nicmonitor new file mode 100755 index 0000000000000000000000000000000000000000..5fa9b9a3e74fbb0ec50b66451fda2de9f3f5c559 GIT binary patch literal 47598 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