【网络编程】——ne-snmp开发实例1
2016-02-21 17:04
495 查看
net-snmp扩展有多种方式,在此只介绍两种——动态库扩展,静态库扩展。
在做net-snmp开发之前,首先确定net-snmp相关的软件是否安装。
1:编写MIB库。
2:根据MIB库生成源代码。可以使用mib2c工具。
3:编译。
4:修改配置文件。
Table code
除了这些还需要有一个common.c把所有的代码连接到一起。
注:init_动态库名 和生成的动态库名字有联系,如果动态库名字不为 diskcheck.so net-snmp有可能无法识别。
把编译好的diskcheck.so拷贝到 /usr/lib (32位系统) /usr/lib64 (64位系统)中.
2:/etc/snmp/snmpd.conf 中加上
dlmod 动态库名 动态库绝对路径 —— dlmod diskcheck /usr/lib/diskcheck.so
view systemview .1
Ps: 在/etc/snmp/snmpd.conf 中添加
view systemview included .1.3.6.1.4.1
有些系统在访问节点的时候有错误,例如在redhat as5.8 中有问题,而CentOS6.4中没问题【有可能是我的配置问题】。需要改成步骤二中的配置。
在做net-snmp开发之前,首先确定net-snmp相关的软件是否安装。
rpm -qa | grep snmp net-snmp-5.3.1-19.el5 net-snmp-perl-5.3.1-19.el5 net-snmp-libs-5.3.1-19.el5 net-snmp-utils-5.3.1-19.el5 net-snmp-devel-5.3.1-19.el5
动态库扩展
使用动态库扩展net-snmp有4个步骤,分别是:1:编写MIB库。
2:根据MIB库生成源代码。可以使用mib2c工具。
3:编译。
4:修改配置文件。
编写MIB库
假设我们现在需要使用snmp来获取某个服务器上的硬盘使用情况——df命令显示的数据。首先我们需要一个字段来表示HostName,然后我们需要一个表来存放磁盘的信息DiskInfoTable。/* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.17 2005/05/09 08:13:45 dts12 Exp $ */ #include <net-snmp/net-snmp-config.h> #include <net-snmp/net-snmp-includes.h> #include <net-snmp/agent/net-snmp-agent-includes.h> #include "DiskInfoTable.h" typedef struct _disk_info { char filesystem[64]; char size[64]; char used[64]; char avail[64]; char capacity[64]; char mountedOn[64]; }disk_info_t; disk_info_t disk_info[MAX_DISK] = { {"/dev/mapper", "19G", "2.6G", "15G", "15%", "/"}, {"/dev/sda1", "99M", "12M", "83M", "13%", "/boot"}, {"tmpfs", "252M", "0", "252M", "0%", "/dev/shm"}, {"/dev/scd1", "2.8G", "2.8G", "0", "100%", "/media/"}, }; /** Initializes the DiskInfoTable module */ void init_DiskInfoTable(void) { /* * here we initialize all the tables we're planning on supporting */ initialize_table_DiskInfoTable(); } /** Initialize the DiskInfoTable table by defining its contents and how it's structured */ void initialize_table_DiskInfoTable(void) { static oid DiskInfoTable_oid[] = { 1, 3, 6, 1, 4, 1, 888888, 1, 2 }; size_t DiskInfoTable_oid_len = OID_LENGTH(DiskInfoTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration("DiskInfoTable", DiskInfoTable_handler, DiskInfoTable_oid, DiskInfoTable_oid_len, HANDLER_CAN_RONLY); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); netsnmp_table_helper_add_indexes(table_info, ASN_OCTET_STR, /* index: Filesystem */ 0); table_info->min_column = COLUMN_FILESYSTEM; table_info->max_column = COLUMN_MOUNTEDON; iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->get_first_data_point = DiskInfoTable_get_first_data_point; iinfo->get_next_data_point = DiskInfoTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator(reg, iinfo); /* * Initialise the contents of the table here */ } /* * Typical data structure for a row entry */ struct DiskInfoTable_entry { /* * Column values */ char Filesystem[16]; char size[8]; char used[8]; char avail[8]; char capacity[8]; char mountedOn[16]; /* * Illustrate using a simple linked list */ int valid; struct DiskInfoTable_entry *next; }; struct DiskInfoTable_entry *DiskInfoTable_head; /* * create a new row in the (unsorted) table */ struct DiskInfoTable_entry * DiskInfoTable_createEntry(char *Filesystem) { struct DiskInfoTable_entry *entry; entry = SNMP_MALLOC_TYPEDEF(struct DiskInfoTable_entry); if (!entry) return NULL; //entry->Filesystem = Filesystem; strncpy(entry->Filesystem, Filesystem, strlen(Filesystem)); entry->next = DiskInfoTable_head; DiskInfoTable_head = entry; return entry; } /* * remove a row from the table */ void DiskInfoTable_removeEntry(struct DiskInfoTable_entry *entry) { struct DiskInfoTable_entry *ptr, *prev; if (!entry) return; /* Nothing to remove */ for (ptr = DiskInfoTable_head, prev = NULL; ptr != NULL; prev = ptr, ptr = ptr->next) { if (ptr == entry) break; } if (!ptr) return; /* Can't find it */ if (prev == NULL) DiskInfoTable_head = ptr->next; else prev->next = ptr->next; SNMP_FREE(entry); /* XXX - release any other internal resources */ } static void fill_diskinfotable_entry(struct DiskInfoTable_entry *entry) { int i; for (i = 0; i < MAX_DISK; i++) { if (!strcmp(disk_info[i].filesystem, entry->Filesystem)) { strncpy(entry->size, disk_info[i].size, strlen(disk_info[i].size)); //strcpy(entry->size, "444G"); strncpy(entry->used, disk_info[i].used, strlen(disk_info[i].used)); strncpy(entry->avail, disk_info[i].avail, strlen(disk_info[i].avail)); strncpy(entry->capacity, disk_info[i].capacity, strlen(disk_info[i].capacity)); strncpy(entry->mountedOn, disk_info[i].mountedOn, strlen(disk_info[i].mountedOn)); } } } static void read_data(void) { int i = 0; struct DiskInfoTable_entry *entry = NULL; if(DiskInfoTable_head == NULL){ for (i = 0; i < MAX_DISK; i++) { DiskInfoTable_createEntry(disk_info[i].filesystem); } } entry = DiskInfoTable_head; while (entry) { fill_diskinfotable_entry(entry); entry = entry->next; } } /* * Example iterator hook routines - using 'get_next' to do most of the work */ netsnmp_variable_list * DiskInfoTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list * put_index_data, netsnmp_iterator_info *mydata) { read_data(); *my_loop_context = DiskInfoTable_head; *my_data_context = DiskInfoTable_head; return DiskInfoTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } netsnmp_variable_list * DiskInfoTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list * put_index_data, netsnmp_iterator_info *mydata) { struct DiskInfoTable_entry *entry = (struct DiskInfoTable_entry *) *my_loop_context; netsnmp_variable_list *idx = put_index_data; if (entry) { snmp_set_var_value(idx, (u_char *)entry->Filesystem, sizeof(entry->Filesystem)); idx = idx->next_variable; *my_data_context = (void *) entry; *my_loop_context = (void *) entry->next; } else { return NULL; } return put_index_data; } /** handles requests for the DiskInfoTable table */ int DiskInfoTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct DiskInfoTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { table_entry = (struct DiskInfoTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case COLUMN_FILESYSTEM: if (table_entry == NULL) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->Filesystem, sizeof(table_entry->Filesystem)); break; case COLUMN_SIZE: if (table_entry == NULL) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->size, sizeof(table_entry->size)); break; case COLUMN_USED: if (table_entry == NULL) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->used, sizeof(table_entry->used)); break; case COLUMN_AVAIL: if (table_entry == NULL) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->avail, sizeof(table_entry->avail)); break; case COLUMN_CAPACITY: if (table_entry == NULL) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->capacity, sizeof(table_entry->capacity)); break; case COLUMN_MOUNTEDON: if (table_entry == NULL) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)table_entry->mountedOn, sizeof(table_entry->mountedOn)); break; default: continue; //netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); } } break; } return SNMP_ERR_NOERROR; }
Table code
除了这些还需要有一个common.c把所有的代码连接到一起。
#include "HostName.h" #include "DiskInfoTable.h" void init_diskcheck(void) { init_HostName(); init_DiskInfoTable(); }
注:init_动态库名 和生成的动态库名字有联系,如果动态库名字不为 diskcheck.so net-snmp有可能无法识别。
编译
编译这块主要是利用net-snmp给的命令,直接给出Makefile好了。CC = gcc DIR = HostName DiskInfoTable #DIR = HostName vpath %.c ./ vpath %.c $(DIR) INCLUDE = -I./ INCLUDE += $(foreach x, $(DIR), -I./$(x)) CFLAGS = -fPIC -shared -O3 CFLAGS += $(shell net-snmp-config --cflags) LDFLAGS = $(shell net-snmp-config --libs) SRC = common.c SRC += $(foreach x, $(DIR), $(x).c) OBJS = $(SRC:.c=.o) TARGET = diskcheck.so all:$(TARGET) $(TARGET):$(OBJS) $(CC) $^ -o $@ $(CFLAGS) $(LDFLAGS) $(OBJS):%.o:%.c $(CC) -c $^ -o $@ $(CFLAGS) $(INCLUDE) .PHONY:clean clean: rm *.o $(TARGET)
把编译好的diskcheck.so拷贝到 /usr/lib (32位系统) /usr/lib64 (64位系统)中.
修改配置文件
1:/etc/snmp/snmp.conf 中加上 mibs +MIB文件的名字(不带后缀)2:/etc/snmp/snmpd.conf 中加上
dlmod 动态库名 动态库绝对路径 —— dlmod diskcheck /usr/lib/diskcheck.so
view systemview .1
Ps: 在/etc/snmp/snmpd.conf 中添加
view systemview included .1.3.6.1.4.1
有些系统在访问节点的时候有错误,例如在redhat as5.8 中有问题,而CentOS6.4中没问题【有可能是我的配置问题】。需要改成步骤二中的配置。
相关文章推荐
- iOS SDK9下对网络请求的url进行UTF8编码
- HDU4292-Food-网络流
- android 网络框架性能优化分析
- HTTP协议详解(真的很经典)
- 和我一起学《HTTP权威指南》——客户端识别与cookie机制
- HTTP 加密
- 李少鹏的网络日志移步到lishaopeng.com
- ANDROID_MARS学习笔记_S04_003_用HttpClent发http请求
- Java实现简单的RPC调用(基于TCP协议)
- C#关于HttpClient的应用(二):极光推送IM集成
- C#关于HttpClient的应用(二):融云IM集成
- C#关于HttpClient的应用(一):获取IP所在的地理位置信息
- C#关于HttpClient的统一配置(一)
- Linux命令行学习之路(十)——网络初探
- 如何让你的网络平台成为一个巨大磁场
- 新建MAVEN工程,JSP页面报The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- Linux 网络环境查看命令
- http-关于application/x-www-form-urlencoded等字符编码的解释说明
- 对象化的Http和请求对象HttpRequest
- android webview 访问https页面 SslError 处理