From 47b513b95dc848fb7ddf69b4af4932336643242c Mon Sep 17 00:00:00 2001 From: jli Date: Tue, 3 Aug 2010 08:16:13 +0000 Subject: [PATCH] the NIC Monitor git-svn-id: http://172.17.0.253/svn/soft_pkgs/sys_nicmonitor@78 09c3743a-b0dd-45d3-b506-aa74c7a2a6ef --- .../dotconf#1.0.13-1.pkg.tar.gz | Bin 0 -> 22735 bytes ...onitor#1.0-x86_64-linx-Rocky4.2.pkg.tar.gz | Bin 0 -> 17864 bytes sys_nicmonitor_1.0.13/代码/Pkgfile | 20 + sys_nicmonitor_1.0.13/代码/post_add.sh | 7 + sys_nicmonitor_1.0.13/代码/post_mk.sh | 10 + .../代码/sys_nicmonitor-1.0/Makefile | 28 + .../代码/sys_nicmonitor-1.0/Makefile.config | 16 + .../代码/sys_nicmonitor-1.0/const.h | 51 + .../代码/sys_nicmonitor-1.0/mnic.c | 1430 +++++++++++++++++ .../代码/sys_nicmonitor-1.0/mnic.h | 44 + .../代码/sys_nicmonitor-1.0/nicinfo_shm.c | 188 +++ .../代码/sys_nicmonitor-1.0/nicinfo_shm.h | 52 + .../代码/sys_nicmonitor-1.0/proc_inv.h | 198 +++ .../代码/sys_nicmonitor-1.0/read_netcard.c | 133 ++ .../代码/sys_nicmonitor-1.0/send_alarm.c | 37 + .../代码/sys_nicmonitor-1.0/sys_netcard.h | 88 + sys_nicmonitor_1.0.13/代码/test/Makefile | 8 + sys_nicmonitor_1.0.13/代码/test/dotconf.h | 264 +++ sys_nicmonitor_1.0.13/代码/test/getmem.c | 82 + sys_nicmonitor_1.0.13/代码/test/mnic.h | 66 + sys_nicmonitor_1.0.13/代码/test/nicinfo_shm.h | 18 + sys_nicmonitor_1.0.13/代码/test/read_shm.c | 127 ++ sys_nicmonitor_1.0.13/代码/test/recv_msg.c | 72 + sys_nicmonitor_1.0.13/代码/test/sys_netcard.h | 87 + 24 files changed, 3026 insertions(+) create mode 100644 sys_nicmonitor_1.0.13/dotconf#1.0.13-1.pkg.tar.gz create mode 100644 sys_nicmonitor_1.0.13/sys_nicmonitor#1.0-x86_64-linx-Rocky4.2.pkg.tar.gz create mode 100644 sys_nicmonitor_1.0.13/代码/Pkgfile create mode 100644 sys_nicmonitor_1.0.13/代码/post_add.sh create mode 100644 sys_nicmonitor_1.0.13/代码/post_mk.sh create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/Makefile create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/Makefile.config create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/const.h create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/mnic.c create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/mnic.h create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/nicinfo_shm.c create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/nicinfo_shm.h create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/proc_inv.h create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/read_netcard.c create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/send_alarm.c create mode 100644 sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/sys_netcard.h create mode 100644 sys_nicmonitor_1.0.13/代码/test/Makefile create mode 100644 sys_nicmonitor_1.0.13/代码/test/dotconf.h create mode 100644 sys_nicmonitor_1.0.13/代码/test/getmem.c create mode 100644 sys_nicmonitor_1.0.13/代码/test/mnic.h create mode 100644 sys_nicmonitor_1.0.13/代码/test/nicinfo_shm.h create mode 100644 sys_nicmonitor_1.0.13/代码/test/read_shm.c create mode 100644 sys_nicmonitor_1.0.13/代码/test/recv_msg.c create mode 100644 sys_nicmonitor_1.0.13/代码/test/sys_netcard.h diff --git a/sys_nicmonitor_1.0.13/dotconf#1.0.13-1.pkg.tar.gz b/sys_nicmonitor_1.0.13/dotconf#1.0.13-1.pkg.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a10b81a04febb8e45e3e3a054e8d9b9d6e91b23b GIT binary patch literal 22735 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

lxC9 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 literal 0 HcmV?d00001 diff --git a/sys_nicmonitor_1.0.13/代码/Pkgfile b/sys_nicmonitor_1.0.13/代码/Pkgfile new file mode 100644 index 0000000..89d0355 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/Pkgfile @@ -0,0 +1,20 @@ +# Description: A system to store and display time-series data. +# URL: http://oss.oetiker.ch/rrdtool/index.en.html +# Maintainer: Danny Rawlins, monster dot romster at gmail dot com +# Packager: Younes Hafri, ycrux at club-internet dot fr +# Depends on: libart_lgpl libcgi libgd pango python tcl intltool + +name=sys_nicmonitor +version=1.0 +release=x86_64-linx-Rocky4.2 +source=(http://172.16.0.73/mnic/$name-$version.tar.gz) + +build() { + cd $name-$version + + make + make DESTDIR=$PKG install + mkdir -p $PKG/var/log/netcard + chmod 777 $PKG/var/log/netcard +} + diff --git a/sys_nicmonitor_1.0.13/代码/post_add.sh b/sys_nicmonitor_1.0.13/代码/post_add.sh new file mode 100644 index 0000000..cfa35f8 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/post_add.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +mv /usr/lib64/libnic_shm.so ~d5000/lib +mv /usr/bin/sys_nicmonitor ~d5000/bin + +chown d5000.d5000 ~d5000/lib/libnic_shm.so +chown d5000.d5000 ~d5000/bin/sys_nicmonitor diff --git a/sys_nicmonitor_1.0.13/代码/post_mk.sh b/sys_nicmonitor_1.0.13/代码/post_mk.sh new file mode 100644 index 0000000..642b9a9 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/post_mk.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +PWD=`pwd` +#pkg=`basename $PWD` +pkg=sys_nicmonitor + +# install the script which is run just after pkgadd or +# when booting from disk first time +mkdir -p $PKG/$PI_DIR +install -m 755 post_add.sh $PKG/$PI_DIR/${pkg}.post_add diff --git a/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/Makefile b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/Makefile new file mode 100644 index 0000000..5cccc77 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/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/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/Makefile.config b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/Makefile.config new file mode 100644 index 0000000..7a2d8e6 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/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/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/const.h b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/const.h new file mode 100644 index 0000000..e2ebfa5 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/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/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/mnic.c b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/mnic.c new file mode 100644 index 0000000..5a12025 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/mnic.c @@ -0,0 +1,1430 @@ +#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.2" + +#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]; + +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, 1) == -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; + char error_str[200]; + + lock.sem_num = 0; + lock.sem_op = -1; + lock.sem_flg = SEM_UNDO; + + while(semop(semid, &lock, 1)){ + 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){ + strncpy(conf.nic[card_info_index].ping_ip[i-1], cmd->data.list[i], strlen(cmd->data.list[i]) >= IPLEN ? IPLEN-1 : strlen(cmd->data.list[i])); + i++; + } + } + conf.nic[card_info_index].gw_num = i-1; + } + } + + //"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_FILE); + + configfile = dotconf_create(buf, 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_logdir(void) +{ + int ret = 0; + + strcpy(log_path, LOG_PATH); + mode_t mask_tmp; + mask_tmp = umask(0000); + if(mkdir(log_path, 0777) != 0){ + if(errno != EEXIST){ + strcpy(log_path, "/tmp/"); + } + } + if((ret = open(SEM_PATH, O_RDWR | O_CREAT, 0666)) != -1){ + close(ret); + } + umask(mask_tmp); +} + + /* create netcard name list */ +int create_name_list(NET_NAME_ST *all_name_list, NET_NAME_ST *opt_name_list) +{ + int i, count_t, err_val = 0; + NET_NAME_ST *curr, *node; + char error_str[200]; + + for(i = 0, count_t = 0; conf.nic[i].dev_name[0] != 0 && (i < MAXNICNUM); i++){ + curr = all_name_list->next; + 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; + proc_invocation prcm; + + 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); + + /* log file path */ + create_logdir(); + + /* 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(); + + /* 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/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/mnic.h b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/mnic.h new file mode 100644 index 0000000..d7a6390 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/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/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/nicinfo_shm.c b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/nicinfo_shm.c new file mode 100644 index 0000000..9eb5b45 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/nicinfo_shm.c @@ -0,0 +1,188 @@ +#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]; +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; + + lock.sem_num = 0; + lock.sem_op = -1; + lock.sem_flg = SEM_UNDO; + + while(semop(semid, &lock, 1)){ + 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]; + + tamp = time(NULL); + localtime_r(&tamp, &tmptr); + strcpy(log_path, LOG_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; + } + 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; + } + } + 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/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/nicinfo_shm.h b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/nicinfo_shm.h new file mode 100644 index 0000000..cd74135 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/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/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/proc_inv.h b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/proc_inv.h new file mode 100644 index 0000000..945622c --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/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/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/read_netcard.c b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/read_netcard.c new file mode 100644 index 0000000..c745f48 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/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/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/send_alarm.c b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/send_alarm.c new file mode 100644 index 0000000..e88635f --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/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/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/sys_netcard.h b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/sys_netcard.h new file mode 100644 index 0000000..0d7746c --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/sys_nicmonitor-1.0/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/sys_nicmonitor_1.0.13/代码/test/Makefile b/sys_nicmonitor_1.0.13/代码/test/Makefile new file mode 100644 index 0000000..0cd95f9 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/test/Makefile @@ -0,0 +1,8 @@ + +all:read_shm recv_msg getmem + +getmem:getmem.c +# g++ -g -L ../dynamic_lib -lnic_shm -o $@ $^ + g++ -g -lnic_shm -o $@ $^ +clean: + rm getmem read_shm recv_msg diff --git a/sys_nicmonitor_1.0.13/代码/test/dotconf.h b/sys_nicmonitor_1.0.13/代码/test/dotconf.h new file mode 100644 index 0000000..e802508 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/test/dotconf.h @@ -0,0 +1,264 @@ +#ifndef DOTCONF_H +#define DOTCONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* stdio.h should be included by the application - as the manual page says */ +#ifndef _STDIO_H +#include /* needed for FILE* */ +#endif + +#ifdef WIN32 +# ifndef R_OK +#define R_OK 0 +# endif +#endif + +/* some buffersize definitions */ +#define CFG_BUFSIZE 4096 /* max length of one line */ +#define CFG_MAX_OPTION 32 /* max length of any option name */ +#define CFG_MAX_VALUE 4064 /* max length of any options value */ +#define CFG_MAX_FILENAME 256 /* max length of a filename */ +#define CFG_VALUES 16 /* max # of arguments an option takes */ + +#define CFG_INCLUDEPATH_ENV "DC_INCLUDEPATH" +#define WILDCARDS "*?" /* list of supported wild-card characters */ + +/* constants for type of option */ +#define ARG_TOGGLE 0 /* TOGGLE on,off; yes,no; 1, 0; */ +#define ARG_INT 1 /* callback wants an integer */ +#define ARG_STR 2 /* callback expects a \0 terminated str */ +#define ARG_LIST 3 /* wants list of strings */ +#define ARG_NAME 4 /* wants option name plus ARG_LIST stuff */ +#define ARG_RAW 5 /* wants raw argument data */ +#define ARG_NONE 6 /* does not expect ANY args */ + +#define CTX_ALL 0 /* context: option can be used anywhere */ + +/* for convenience of terminating the dotconf_options list */ +#define LAST_OPTION { "", 0, NULL, NULL } +#define LAST_CONTEXT_OPTION { "", 0, NULL, NULL, 0 } + +#define DOTCONF_CB(__name) const char *__name(command_t *cmd, \ + context_t *ctx) +#define FUNC_ERRORHANDLER(_name) int _name(configfile_t * configfile, \ + int type, long dc_errno, const char *msg) + + +/* some flags that change the runtime behaviour of dotconf */ +#define NONE 0 +#define CASE_INSENSITIVE 1<<0 /* match option names case insensitive */ +#define DONT_SUBSTITUTE 1<<1 /* do not call substitute_env after read_arg */ +#define NO_INLINE_COMMENTS 1<<2 /* do not allow inline comments */ +#define DUPLICATE_OPTION_NAMES 1<<3 /* allow for duplicate option names */ + +/* syslog style errors as suggested by Sander Steffann */ +#ifdef HAVE_SYSLOG +#include + +#define DCLOG_EMERG LOG_EMERG /* system is unusable */ +#define DCLOG_ALERT LOG_ALERT /* action must be taken immediately */ +#define DCLOG_CRIT LOG_CRIT /* critical conditions */ +#define DCLOG_ERR LOG_ERR /* error conditions */ +#define DCLOG_WARNING LOG_WARNING /* warning conditions */ +#define DCLOG_NOTICE LOG_NOTICE /* normal but significant condition */ +#define DCLOG_INFO LOG_INFO /* informational */ +#define DCLOG_DEBUG LOG_DEBUG /* debug-level messages */ + +#define DCLOG_LEVELMASK LOG_PRIMASK /* mask off the level value */ + +#else /* HAVE_SYSLOG */ + +#define DCLOG_EMERG 0 /* system is unusable */ +#define DCLOG_ALERT 1 /* action must be taken immediately */ +#define DCLOG_CRIT 2 /* critical conditions */ +#define DCLOG_ERR 3 /* error conditions */ +#define DCLOG_WARNING 4 /* warning conditions */ +#define DCLOG_NOTICE 5 /* normal but significant condition */ +#define DCLOG_INFO 6 /* informational */ +#define DCLOG_DEBUG 7 /* debug-level messages */ + +#define DCLOG_LEVELMASK 7 /* mask off the level value */ + +#endif /* HAVE_SYSLOG */ + +/* callback types for dotconf_callback */ + +/* error constants */ +#define ERR_NOERROR 0x0000 +#define ERR_PARSE_ERROR 0x0001 +#define ERR_UNKNOWN_OPTION 0x0002 +#define ERR_WRONG_ARG_COUNT 0x0003 +#define ERR_INCLUDE_ERROR 0x0004 +#define ERR_NOACCESS 0x0005 +#define ERR_USER 0x1000 /* base for userdefined errno's */ + +/* i needed this to check an ARG_LIST entry if it's toggled in one of my apps; maybe you do too */ +#define CFG_TOGGLED(_val) ( (_val[0] == 'Y' \ + || _val[0] == 'y') \ + || (_val[0] == '1') \ + || ((_val[0] == 'o' \ + || _val[0] == 'O') \ + && (_val[1] == 'n' \ + || _val[1] == 'N'))) + +enum callback_types +{ + ERROR_HANDLER = 1, + CONTEXT_CHECKER +}; + +typedef enum callback_types callback_types; +typedef struct configfile_t configfile_t; +typedef struct configoption_t configoption_t; +typedef struct configoption_t ConfigOption; +typedef struct command_t command_t; +typedef void context_t; +typedef void info_t; + +typedef const char *(*dotconf_callback_t)(command_t *, context_t *); +typedef int (*dotconf_errorhandler_t)(configfile_t *, int, unsigned long, const char *); +typedef const char *(*dotconf_contextchecker_t)(command_t *, unsigned long); + +struct configfile_t +{ + /* ------ the fields in configfile_t are provided to the app via command_t's ; READ ONLY! --- */ + + FILE *stream; + char eof; /* end of file reached ? */ + size_t size; /* file size; cached on-demand for here-documents */ + + context_t *context; + + configoption_t const **config_options; + int config_option_count; + + /* ------ misc read-only fields ------------------------------------------------------------- */ + char *filename; /* name of file this option was found in */ + unsigned long line; /* line number we're currently at */ + unsigned long flags; /* runtime flags given to dotconf_open */ + + char *includepath; + + /* ------ some callbacks for interactivity -------------------------------------------------- */ + dotconf_errorhandler_t errorhandler; + dotconf_contextchecker_t contextchecker; + + int (*cmp_func)(const char *, const char *, size_t); +}; + +struct configoption_t +{ + const char *name; /* name of configuration option */ + int type; /* for possible values, see above */ + dotconf_callback_t callback; /* callback function */ + info_t *info; /* additional info for multi-option callbacks */ + unsigned long context; /* context sensitivity flags */ +}; + +struct command_t +{ + const char *name; /* name of the command */ + configoption_t *option; /* the option as given in the app; READ ONLY */ + + /* ------ argument data filled in for each line / command ----------------------------------- */ + struct { + long value; /* ARG_INT, ARG_TOGGLE */ + char *str; /* ARG_STR */ + char **list; /* ARG_LIST */ + } data; + int arg_count; /* number of arguments (in data.list) */ + + /* ------ misc context information ---------------------------------------------------------- */ + configfile_t *configfile; + context_t *context; +}; + +/* ------ dotconf_create() - create the configfile_t needed for further dot.conf fun ------------ */ +configfile_t *dotconf_create(char *, const configoption_t *, context_t *, unsigned long); + +/* ------ dotconf_cleanup() - tidy up behind dotconf_create and the parser dust ----------------- */ +void dotconf_cleanup(configfile_t *configfile); + +/* ------ dotconf_command_loop() - iterate through each line of file and handle the commands ---- */ +int dotconf_command_loop(configfile_t *configfile); + +/* ------ dotconf_command_loop_until_error() - like continue_line but return on the first error - */ +const char *dotconf_command_loop_until_error(configfile_t *configfile); + +/* ------ dotconf_continue_line() - check if line continuation is to be handled ----------------- */ +int dotconf_continue_line(char *buffer, size_t length); + +/* ------ dotconf_get_next_line() - read in the next line of the configfile_t ------------------- */ +int dotconf_get_next_line(char *buffer, size_t bufsize, configfile_t *configfile); + +/* ------ dotconf_get_here_document() - read the here document until delimit is found ----------- */ +char *dotconf_get_here_document(configfile_t *configfile, const char *delimit); + +/* ------ dotconf_invoke_command() - call the callback for command_t ---------------------------- */ +const char *dotconf_invoke_command(configfile_t *configfile, command_t *cmd); + +/* ------ dotconf_find_command() - iterate through all registered options trying to match ------- */ +configoption_t *dotconf_find_command(configfile_t *configfile, const char *command); + +/* ------ dotconf_read_arg() - read one argument from the line handling quoting and escaping ---- */ +/* + side effects: the char* returned by dotconf_read_arg is malloc() before, hence that pointer + will have to be free()ed later. +*/ +char *dotconf_read_arg(configfile_t *configfile, signed char **line); + +/* ------ dotconf_handle_command() - parse, substitute, find, invoke the command found in buffer */ +const char *dotconf_handle_command(configfile_t *configfile, char *buffer); + +/* ------ dotconf_register_option() - add a new option table to the list of commands ------------ */ +void dotconf_register_options(configfile_t *configfile, const configoption_t *options); + +/* ------ dotconf_warning() - handle the dispatch of error messages of various levels ----------- */ +int dotconf_warning(configfile_t *configfile, int level, unsigned long errnum, const char *, ...); + +/* ------ dotconf_callback() - register a special callback -------------------------------------- */ +void dotconf_callback(configfile_t *configfile, callback_types type, dotconf_callback_t); + +/* ------ dotconf_substitute_env() - handle the substitution on environment variables ----------- */ +char *dotconf_substitute_env(configfile_t *, char *); + +/* ------ internal utility function that verifies if a character is in the WILDCARDS list -- */ +int dotconf_is_wild_card(char value); + +/* ------ internal utility function that calls the appropriate routine for the wildcard passed in -- */ +int dotconf_handle_wild_card(command_t* cmd, char wild_card, char* path, char* pre, char* ext); + +/* ------ internal utility function that frees allocated memory from dotcont_find_wild_card -- */ +void dotconf_wild_card_cleanup(char* path, char* pre); + +/* ------ internal utility function to check for wild cards in file path -- */ +/* ------ path and pre must be freed by the developer ( dotconf_wild_card_cleanup) -- */ +int dotconf_find_wild_card(char* filename, char* wildcard, char** path, char** pre, char** ext); + +/* ------ internal utility function that compares two stings from back to front -- */ +int dotconf_strcmp_from_back(const char* s1, const char* s2); + +/* ------ internal utility function that determins if a string matches the '?' criteria -- */ +int dotconf_question_mark_match(char* dir_name, char* pre, char* ext); + +/* ------ internal utility function that determins if a string matches the '*' criteria -- */ +int dotconf_star_match(char* dir_name, char* pre, char* ext); + +/* ------ internal utility function that determins matches for filenames with -- */ +/* ------ a '?' in name and calls the Internal Include function on that filename -- */ +int dotconf_handle_question_mark(command_t* cmd, char* path, char* pre, char* ext); + +/* ------ internal utility function that determins matches for filenames with -- */ +/* ------ a '*' in name and calls the Internal Include function on that filename -- */ +int dotconf_handle_star(command_t* cmd, char* path, char* pre, char* ext); + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* DOTCONF_H */ diff --git a/sys_nicmonitor_1.0.13/代码/test/getmem.c b/sys_nicmonitor_1.0.13/代码/test/getmem.c new file mode 100644 index 0000000..e9c31b3 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/test/getmem.c @@ -0,0 +1,82 @@ +#include +#include +#include + +#include "nicinfo_shm.h" + +typedef struct net_info{ + NETCARD_INFO info[MAXNICNUM]; +}SHM; + +int main(int argc, char **argv) +{ + int ret; + NETCARD_INFO net; +#if 0 + char shm_path[1024]; + char sem_path[1024]; + + memset(shm_path, 0, sizeof(shm_path)); + memset(sem_path, 0, sizeof(sem_path)); + + strcpy(shm_path, getenv("D5000_HOME")); + strcat(shm_path, "/conf/nic/shm_sys_netcard_info"); + strcpy(sem_path, getenv("D5000_HOME")); + strcat(sem_path, "/conf/nic/sem_sys_netcard_info"); + if((ret = init_nic_info(shm_path, sem_path)) == -1){ + fprintf(stderr, "shm or sem path error!\n"); + return -1; + } +#endif + memset(&net, 0, sizeof(NETCARD_INFO)); + if(argc != 2){ + fprintf(stderr, "Usage:%s netcard\n", argv[0]); + return -1; + } + while((ret = get_nic_info(argv[1], &net)) != -1){ + fprintf(stdout, "==========================网卡信息==============================\n"); + fprintf(stdout,"DEVICE NAME : %s\nIPADDR : %d.%d.%d.%d\nBROADCAST : %d.%d.%d.%d\nNETMASK : %d.%d.%d.%d\nHWADDR : %02x:%02x:%02x:%02x:%02x:%02x\nFLAGS = %d\nMTU = %d\nTx_queue_len = %d\nTime_stamp = %d\n\nReceive bytes:%llu\nReceive packets:%llu\nReceive errors:%lu\nReceive dropped:%lu\nReceive multicast:%lu\nReceive fifo:%lu\n\nTransmit bytes:%llu\nTransmit packets:%llu\nTransmit errors:%lu\nTransmit dropped:%lu\nTransmit fifo:%lu\nTransmit collisions:%lu\nTransmit carrier:%lu\n\nAverage flow:%d\n", + net.charname, + (unsigned char)net.addr.sa_data[2], + (unsigned char)net.addr.sa_data[3], + (unsigned char)net.addr.sa_data[4], + (unsigned char)net.addr.sa_data[5], + (unsigned char)net.broadaddr.sa_data[2], + (unsigned char)net.broadaddr.sa_data[3], + (unsigned char)net.broadaddr.sa_data[4], + (unsigned char)net.broadaddr.sa_data[5], + (unsigned char)net.netmask.sa_data[2], + (unsigned char)net.netmask.sa_data[3], + (unsigned char)net.netmask.sa_data[4], + (unsigned char)net.netmask.sa_data[5], + (unsigned char)net.hwaddr.sa_data[0], + (unsigned char)net.hwaddr.sa_data[1], + (unsigned char)net.hwaddr.sa_data[2], + (unsigned char)net.hwaddr.sa_data[3], + (unsigned char)net.hwaddr.sa_data[4], + (unsigned char)net.hwaddr.sa_data[5], + net.flags, + net.mtu, + net.tx_queue_len, + net.time_stamp, + net.rx_bytes, + net.rx_packets, + net.rx_errors, + net.rx_dropped, + net.rx_multicast, + net.rx_fifo_errors, + net.tx_bytes, + net.tx_packets, + net.tx_errors, + net.tx_dropped, + net.tx_fifo_errors, + net.collisions, + net.tx_carrier_errors, + net.average_flow); + getchar(); + } + fprintf(stderr, "No information of %s !\n", argv[1]); + +// rls_nic_info(); + return 0; +} diff --git a/sys_nicmonitor_1.0.13/代码/test/mnic.h b/sys_nicmonitor_1.0.13/代码/test/mnic.h new file mode 100644 index 0000000..d6255d5 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/test/mnic.h @@ -0,0 +1,66 @@ +#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 + +#include "sys_netcard.h" +#include "dotconf.h" + +#define IPSIZE 16 +#define PATH_SIZE 256 + +DOTCONF_CB(cb_str); +DOTCONF_CB(cb_int); + +typedef struct __config_file_st{ + unsigned char domain; + short serv; + short event; + int udpport; + char sys_netcard_shm_path[PATH_SIZE]; + char sys_netcard_sem_path[PATH_SIZE]; + int monitor_interval; + int write_interval; + int flow_interval; + int flow_limit; + int flow_peak; + char udp[NIC_NAME_LEN]; + char nic[MAXNICNUM][NIC_NAME_LEN]; + char ip[IPSIZE] ; +}CONFIG_FILE_ST; + + +char *get_name(char *, char *); +int if_fetch(NETCARD_INFO *); +int ioc_get_name(NETCARD_INFO *); +int get_dev_fields(char *p, NETCARD_INFO *); +void send_alarm(D5000_NIC_ALARM *, int , char *, char *); +void record_log(void); + +#endif diff --git a/sys_nicmonitor_1.0.13/代码/test/nicinfo_shm.h b/sys_nicmonitor_1.0.13/代码/test/nicinfo_shm.h new file mode 100644 index 0000000..14c1aec --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/test/nicinfo_shm.h @@ -0,0 +1,18 @@ +#ifndef NIC_SHM_H +#define NIC_SHM_H + +#include "sys_netcard.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int init_nic_info(char *share_path, char *sem_path); +int get_nic_info(char *nic_name, NETCARD_INFO *net_info); +void rls_nic_info(void); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/sys_nicmonitor_1.0.13/代码/test/read_shm.c b/sys_nicmonitor_1.0.13/代码/test/read_shm.c new file mode 100644 index 0000000..d2aec3b --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/test/read_shm.c @@ -0,0 +1,127 @@ +#include "mnic.h" + +typedef struct net_info{ + NETCARD_INFO info[MAXNICNUM]; +}SHM; + +void get_sem(int semid) +{ + struct sembuf lock; + + lock.sem_num = 0; + lock.sem_op = -1; + lock.sem_flg = SEM_UNDO; + + while(semop(semid, &lock, 1)){ + if (errno == EINTR) { + continue; + } + perror("semop()"); + } +} + +void release_sem(int semid) +{ + int ret; + struct sembuf unlock; + + unlock.sem_num = 0; + unlock.sem_op = 1; + unlock.sem_flg = SEM_UNDO; + + if((ret = semop(semid, &unlock, 1)) == -1){ + perror("semop()"); + } +} + + +int main(void) +{ + int fd = -1; + int i; + int semid; + key_t key; + SHM *p; + struct timespec s_time, os_time; + char shm_path[1024]; + char sem_path[1024]; + + memset(shm_path, 0, sizeof(shm_path)); + memset(sem_path, 0, sizeof(sem_path)); + + strcpy(shm_path, "/tmp/sys_netcard_shm_path"); + strcpy(sem_path, "/tmp/sys_netcard_sem_path"); + + s_time.tv_sec = 1; + s_time.tv_nsec = 0; + + if ((key=ftok(sem_path, SEM_PROJ_ID)) == -1) { + perror("ftok()"); + exit(1); + } + if((semid = semget(key, 1, IPC_CREAT)) == -1){ + fprintf(stderr, "Create semaphore error\n"); + exit(1); + } + + if((fd = open(shm_path, O_RDWR)) == -1){ + fprintf(stderr, "open():%s\n", strerror(errno)); + return -1; + } + p = mmap(NULL, sizeof(SHM), PROT_READ, MAP_SHARED, fd, 0); + if(p == MAP_FAILED){ + perror("mmap"); + return -1; + } + perror("mmap"); + while(1){ + get_sem(semid); + for(i = 0; p->info[i].charname[0] != 0; i++){ + fprintf(stdout, "==========================网卡信息 [%d]==============================\n", (i + 1)); + fprintf(stdout,"KEYID = %ld\nBONDING:%s\nDEVICE NAME : %s\nIPADDR : %d.%d.%d.%d\nBROADCAST : %d.%d.%d.%d\nNETMASK : %d.%d.%d.%d\nHWADDR : %02x:%02x:%02x:%02x:%02x:%02x\nFLAGS = %d\nMTU = %d\nTx_queue_len = %d\nTime_stamp = %d\n\nReceive bytes:%llu\nReceive packets:%llu\nReceive errors:%lu\nReceive dropped:%lu\nReceive multicast:%lu\nReceive fifo:%lu\n\nTransmit bytes:%llu\nTransmit packets:%llu\nTransmit errors:%lu\nTransmit dropped:%lu\nTransmit fifo:%lu\nTransmit collisions:%lu\nTransmit carrier:%lu\nAverage flow : %lld\n", + p->info[i].ID, + p->info[i].descr, + p->info[i].charname, + (unsigned char)p->info[i].addr.sa_data[2], + (unsigned char)p->info[i].addr.sa_data[3], + (unsigned char)p->info[i].addr.sa_data[4], + (unsigned char)p->info[i].addr.sa_data[5], + (unsigned char)p->info[i].broadaddr.sa_data[2], + (unsigned char)p->info[i].broadaddr.sa_data[3], + (unsigned char)p->info[i].broadaddr.sa_data[4], + (unsigned char)p->info[i].broadaddr.sa_data[5], + (unsigned char)p->info[i].netmask.sa_data[2], + (unsigned char)p->info[i].netmask.sa_data[3], + (unsigned char)p->info[i].netmask.sa_data[4], + (unsigned char)p->info[i].netmask.sa_data[5], + (unsigned char)p->info[i].hwaddr.sa_data[0], + (unsigned char)p->info[i].hwaddr.sa_data[1], + (unsigned char)p->info[i].hwaddr.sa_data[2], + (unsigned char)p->info[i].hwaddr.sa_data[3], + (unsigned char)p->info[i].hwaddr.sa_data[4], + (unsigned char)p->info[i].hwaddr.sa_data[5], + p->info[i].flags, + p->info[i].mtu, + p->info[i].tx_queue_len, + p->info[i].time_stamp, + p->info[i].rx_bytes, + p->info[i].rx_packets, + p->info[i].rx_errors, + p->info[i].rx_dropped, + p->info[i].rx_multicast, + p->info[i].rx_fifo_errors, + p->info[i].tx_bytes, + p->info[i].tx_packets, + p->info[i].tx_errors, + p->info[i].tx_dropped, + p->info[i].tx_fifo_errors, + p->info[i].collisions, + p->info[i].tx_carrier_errors, + p->info[i].average_flow); + } + nanosleep(&s_time, &os_time); + release_sem(semid); + } + close(fd); + return 0; +} diff --git a/sys_nicmonitor_1.0.13/代码/test/recv_msg.c b/sys_nicmonitor_1.0.13/代码/test/recv_msg.c new file mode 100644 index 0000000..a9326bf --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/test/recv_msg.c @@ -0,0 +1,72 @@ +#include "mnic.h" +#define IP4STRSIZE 16 + +int +main(int argc, char **argv) +{ + int ret, value; + int sock_sd, sock_port = 15000; + D5000_NIC_ALARM mesg; + struct sockaddr_in myend, hisend; + socklen_t hisend_len; + fd_set rset; + char ip4str[IP4STRSIZE]; + + if(argc > 1){ + sock_port = atoi(argv[1]); + if(sock_port <= 1024 || sock_port > 65535){ + fprintf(stderr, "Invalid socket port!\n"); + exit(1); + } + } + + sock_sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock_sd==-1) { + perror("socket()"); + exit(1); + } + + value=1; + ret = setsockopt(sock_sd, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value)); + if (ret==-1) { + perror("setsockopt()"); + exit(1); + } + + myend.sin_family = AF_INET; + myend.sin_port = htons(sock_port); + inet_pton(AF_INET, "0.0.0.0", &myend.sin_addr); + + ret = bind(sock_sd, (struct sockaddr*)&myend, sizeof(myend)); + if (ret==-1) { + perror("bind()"); + exit(1); + } + + hisend_len = sizeof(hisend); + while (1) { + FD_ZERO(&rset); + FD_SET(sock_sd, &rset); + ret = select(sock_sd+1, &rset, NULL, NULL, NULL); + if (ret==-1) { + perror("select()"); + continue; + } + ret = recvfrom(sock_sd, &mesg, sizeof(mesg), 0, (struct sockaddr*)&hisend, &hisend_len); + inet_ntop(AF_INET, &hisend.sin_addr, ip4str, IP4STRSIZE); + fprintf(stdout, "===========Recieved from %s============\n", ip4str); + fprintf(stdout, "message length : %d\nsend sequence : %d\nservices ID : %d\nenevt ID : %d\ndomain ID : %d\n", mesg.tMsgFrame.len, mesg.tMsgFrame.seqno, mesg.tMsgFrame.serv, mesg.tMsgFrame.event, mesg.tMsgFrame.domain); + if(mesg.tSysNetcardAlarm.flags == NETCARD_ALARM_SWITCH) + fprintf(stdout, "切换网卡名: %s\n", mesg.tSysNetcardAlarm.switch_devname); + else if(mesg.tSysNetcardAlarm.flags == NETCARD_ALARM_RESUME) + fprintf(stdout, "恢复网卡名: %s\n", mesg.tSysNetcardAlarm.fault_devname); + else + fprintf(stdout, "故障网卡名: %s\n", mesg.tSysNetcardAlarm.fault_devname); + fprintf(stdout, "状态标记: %d\n", mesg.tSysNetcardAlarm.flags); + fprintf(stdout, "重发次数: %d\n", mesg.tSysNetcardAlarm.retrytimes); + } + close(sock_sd); + + exit(0); +} + diff --git a/sys_nicmonitor_1.0.13/代码/test/sys_netcard.h b/sys_nicmonitor_1.0.13/代码/test/sys_netcard.h new file mode 100644 index 0000000..9d97950 --- /dev/null +++ b/sys_nicmonitor_1.0.13/代码/test/sys_netcard.h @@ -0,0 +1,87 @@ +#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; + int 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 +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 +