2008年12月29日星期一

ini文件解析例子

1.主程序:demo.c

#include
#include
#include
#include
#include

main(int argc,char *argv[])
{
dictionary * ini;
char * ini_name;

if(argc<2) {
ini_name = "demo.ini";
} else {
ini_name = argv[1];
}

ini = iniparser_load(ini_name);
iniparser_dump(ini,stdout);
iniparser_freedict(ini);

return 0;

}

2.Makefile文件
iniparser tests Makefile
#

CC = gcc
CFLAGS = -g -I./src
LFLAGS = -L.. -liniparser
SRC = -I./src
AR = ar
ARFLAGS = rcv
RM = rm -f


default: all

all: demo


demo: demo.c
$(CC) -g -I./src -o demo demo.c -I./src -L.. -liniparser


clean veryclean:
$(RM) demo


3.ini 文件:demo.ini

[bvcom]
t1 = 1
t2 = 2
t3 = 3

4.建立src文件夹:
下有四个文件:dictionary.c dictionary.h iniparser.c iniparser.h
在http://ndevilla.free.fr/iniparser/ 可下载得到

5.编译运行:
slg@slg-desktop:~/snmpan/testing$ ls
demo.c demo.ini Makefile src
slg@slg-desktop:~/snmpan/testing$ make
gcc -g -I./src -o demo demo.c -I./src -L.. -liniparser
slg@slg-desktop:~/snmpan/testing$ ls
demo demo.c demo.ini Makefile src
slg@slg-desktop:~/snmpan/testing$ sudo ./demo
[sudo] password for slg:
[bvcom]=UNDEF
[bvcom:t1]=[1]
[bvcom:t2]=[2]
[bvcom:t3]=[3]

cross compile net snmp for mips(转自boeder)

cross compile net snmp for mips

By: Bian Jiang (borderj@gmail.com)
From: http://www.b0rder.com
Date: 2008.11.17

I'm trying to cross-compile NetSNMP 5.4.2 for running on an embedded system(mips).

由于我使用的CPU是little endian 交叉编译工具是 mipsel-linux

如果你用的是Big endian,交叉编译用具就可能是 mips-linux

1. 设置环境变量::

TOOLCHAIN=mipsel-linux-
CC=${TOOLCHAIN}gcc
CPP=${TOOLCHAIN}cpp
AR=${TOOLCHAIN}ar
STRIP=${TOOLCHAIN}strip
RANLIB=${TOOLCHAIN}ranlib
LD=${TOOLCHAIN}ld

2. 编译安装::

../net-snmp-5.4.2.1/configure --build=i686-linux --host=mipsel-linux --target=mipsel-linux --with-transports="UDP" --prefix=/opt/rootfs/snmp --with-endianness=little --with-persistent-directory=/var/net-snmp/ --with-default-snmp-version="2" --enable-mini-agent --without-kmem-usage --disable-debugging --disable-embedded-perl --without-perl-modules

make
make install

PS:
1. 如果你采用的是 Big endian, --with-endianness=little 应该改为 --with-endianness=big
2. 如果不想对openssl 的支持,用 --without-openssl

3. 测试::

border@ubuntu:/opt/rootfs/snmp/sbin$ pwd
/opt/rootfs/snmp/sbin
border@ubuntu:/opt/rootfs/snmp/sbin$ file snmpd
snmpd: ELF 32-bit LSB executable, MIPS, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
border@ubuntu:/opt/rootfs/snmp/sbin$ file snmptrapd
snmptrapd: ELF 32-bit LSB executable, MIPS, version 1 (SYSV), dynamically linked (uses shared libs), not stripped


参考:
1. http://fixunix.com/snmp/175765-multiple-warning-cross-compiling-net-snmp-mips-linux.html
2. http://mhonarc.axis.se/dev-etrax/msg09220.html

--Bian Jiang

--EOF--

2008年12月25日星期四

移植shttpd Web服务器到ARM-Linux系统

移植shttpd Web服务器到ARM-Linux系统
一、下载并解压
下载的官方主页:http://shttpd.sourceforge.net/
我下的是目前最新的shttpd-1.39.tar.gz
解压:
[tekkamanninja@Tekkaman-Ninja source]$ tar zxvf shttpd-1.39.tar.gz

二、配置和交叉编译
[tekkamanninja@Tekkaman-Ninja source]$ cd shttpd-1.39
[tekkamanninja@Tekkaman-Ninja shttpd-1.39]$ cd src/
[tekkamanninja@Tekkaman-Ninja src]$ kwrite Makefile

只需在前面加上交叉编译器路径就好:
CC = /home/tekkamanninja/working/gcc4.1.1/gcc-4.1.1-glibc-2.3.2/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-gcc
AR = /home/tekkamanninja/working/gcc4.1.1/gcc-4.1.1-glibc-2.3.2/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-ar
CFLAGS = -DNO_SSL

加上CFLAGS = -DNO_SSL,是因为如果编译SSL支持,会因符号未定义而无法通过。所以我去除了SSL 支持。

交叉编译:
[tekkamanninja@Tekkaman-Ninja src]$ make unix
开看程序需要那些动态库:
[tekkamanninja@Tekkaman-Ninja src]$ ~/working/gcc4.1.1/gcc-4.1.1-glibc-2.3.2/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-readelf -d shttpd
Dynamic section at offset 0x12cc8 contains 20 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0x9180
0x0000000d (FINI) 0x18708
0x00000004 (HASH) 0x8128
0x00000005 (STRTAB) 0x8a5c
0x00000006 (SYMTAB) 0x843c
0x0000000a (STRSZ) 807 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x22d90
0x00000002 (PLTRELSZ) 704 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x8ec0
0x00000011 (REL) 0x8e88
0x00000012 (RELSZ) 56 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0x8e48
0x6fffffff (VERNEEDNUM) 1
0x6ffffff0 (VERSYM) 0x8d84
0x00000000 (NULL) 0x0

将编译好的程序放入开发板的文件系统下:
[tekkamanninja@Tekkaman-Ninja src]$ cp shttpd /home/tekkamanninja/working/nfs/rootfs/sbin/

三、运行shttpd
因为shttpd 没有配置文件,所以配置是由启动参数加的,比如我在开发板中操作如下:
[root@~]#shttpd -root /var/www -ports 80 &
意思是Web 根目录为/var/www 用80端口提供服务。

还有别的参数如下:
[root@~]#shttpd --help
SHTTPD version 1.39 (c) Sergey Lyubka
usage: shttpd [options] [config_file]
-A
-root Web root directory (default: .)
-index_files Index files (default: index.html,index.htm,index.php,index.cgi)
-ports Listening ports (default: 80)
-dir_list Directory listing (default: 1)
-cfg_uri Config uri
-protect URI to htpasswd mapping
-cgi_ext CGI extensions (default: cgi,pl,php)
-cgi_interp CGI interpreter
-cgi_env Additional CGI env vars
-ssi_ext SSI extensions (default: shtml,shtm)
-auth_realm Authentication domain name (default: mydomain.com)
-auth_gpass Global passwords file
-auth_PUT PUT,DELETE auth file
-access_log Access log file
-error_log Error log file
-mime_types Additional mime types list
-aliases Path=URI mappings
-acl Allow/deny IP addresses/subnets
-inetd Inetd mode (default: 0)
-uid Run as user

这里说明一下 -cgi_ext :shttpd没有CGI 目录的概念,它是通过认文件扩展名来识别的。要运行CGI 程序,默认情况下就要在编译好的程序后面加上 “.cgi””pl””php”等后缀。而 -cgi_ext 是你可以自定义其后缀。
四、开发板测试

静态网页测试
在开发板的 /var/www(由-root指定的根目录)放入测试网页:index.html
在HOST的浏览器中输入开发板地址,测试通过!

CGI测试
在 /var/www (由-root指定的根目录)放入测试 CGI 程序:helloworldCGI.cgi
在流览器中输入(开发板地址)192.168.1.2/helloworldCGI.cgi ,测试通过!

2008年12月24日星期三

用NET-SNMP软件包开发客户端代理(续)-string类型实现

以下是定义string类型变量,它提供了get_XXX()和set_XXX()函数来完成数据的获取和设置,需要手工实现。
一、
1.重新建立MIBS 其中包括一个string类型的变量。
+--bvcom(26814)
|
+--ipq6800(6800)
|
+--bvcomAgentModules(1)
|
+-- -RW- Integer32 bvcomAgentModuleObject(1)
+-- -RW- Integer32 bvcomAgentSubagentObject(2)
+-- -RW- String bvcomAgentIpaddressObject(3)
Textual Convention: DisplayString
Size: 0..255

2.用mib2c.scalar.conf生成.c 和 .h文件:mib2c -c mib2c.scalar.conf bvcomAgentModules

GIVE MY
3.更改bvcomAgentModules.c文件:
(1)节点的声明:string类型是后生成的,所以需要重新声明,语句如下:
#define STRLENGTH 256
long bvcomAgentModuleObject = 4560; /* XXX: set default value */
long bvcomAgentSubagentObject = 0; /* XXX: set default value */
char bvcomAgentIpaddressObject [STRLENGTH];
bvcomAgentIpaddressObject[0] = '\0';
(2) 修改handle_bvcomAgentModuleObject():
case MODE_GET:


snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
(u_char *)&bvcomAgentModuleObject /* XXX: a pointer to the scalar's data */,
sizeof(bvcomAgentModuleObject)/* XXX: the length of the data in bytes */);
break;
其中 &bvcomAgentModuleObject 和 sizeof(bvcomAgentModuleObject) 是后面添加的语句。

case MODE_SET_ACTION:
bvcomAgentModuleObject= *(requests->requestvb->val.integer);



/* XXX: perform the value change here */
if (0/* XXX: error? */) {
netsnmp_set_request_error(reqinfo, requests,-1 /* some error */);
}
break;
其中 bvcomAgentModuleObject= *(requests->requestvb->val.integer);为后添加的语句。

其他如遇/* XXX if malloc, or whatever, failed: */或是/* XXX: error? */则添加 0。遇/* some error */添加 -1。
(3) 修改handle_bvcomAgentSubagentObject(),因是INT类型的所以同理(2)。

(4)修改handle_bvcomAgentIpaddressObject():由于是string类型的,所以修饰时候有所不同,如下:
case MODE_GET:
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
(u_char *)&bvcomAgentIpaddressObject[0]/* XXX: a pointer to the scalar's data */,
sizeof(char) * STRLENGTH/* XXX: the length of the data in bytes */);
break;
其中&bvcomAgentIpaddressObject[0] 和 sizeof(char) * STRLENGTH 为后添加的语句。
case MODE_SET_ACTION:
/* XXX: perform the value change here */
strcpy(&bvcomAgentIpaddressObject[0], requests->requestvb->val.string);
if (0/* XXX: error? */) {
netsnmp_set_request_error(reqinfo, requests, -1/* some error */);
}
break;
其中strcpy(&bvcomAgentIpaddressObject[0], requests->requestvb->val.string);为后添加的语句。

4.编译运行:sudo makes
sudo ./agent-snmp

5.调试执行snmp语句:
slg@slg-desktop:~/snmpan/agent-snmp$ snmpget -v 1 -c public localhost bvcomAgentIpaddressObject.0
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentIpaddressObject.0 = STRING
slg@slg-desktop:~/snmpan/agent-snmp$ snmpset -v 1 -c public localhost bvcomAgentIpaddressObject.0 s "zhangcl"
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentIpaddressObject.0 = STRING: zhangcl
slg@slg-desktop:~/snmpan/agent-snmp$ snmpget -v 1 -c public localhost bvcomAgentIpaddressObject.0
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentIpaddressObject.0 = STRING: zhangcl

用NET-SNMP软件包开发简单客户端代理

用NET-SNMP软件包开发简单客户端代理
1.SNMP协议简介

作为一个完备的系统,必须有一套反馈机制来调整系统的运行。简单网络管理协议产生的目的,就是为了使松散的网络更加有效地运行。它广泛的应用于监测网络的状态、网络设备的运行情况、各种电脑设备以及一些辅助的外围设备,使得网络管理员通过对节点的查询和设置,发现并定位故障,进而采取相应措施维护网络。网络管理的研究已经发展了许多年,对于日益纷繁的需求,简捷性和扩展性仍是研究的主题。本文档的目的是关于客户端代理的开发,不是对协议发展的探讨。

1.1网络管理协议结构

SNMP的网络管理模型包括以下关键元素:管理端、代理端、管理信息库、网络管理协议。它基于tcp/ip协议,属于应用层协议,通过udp协议通信。管理端与代理端的通信原语包括:Get,Getnext,Set,Trap.

1.2 管理信息库
SNMP以MIB(管理信息结构)为基础来描述被监管资源,由此建立的数据集和称之为MIB库。它是一种树型结构的数据库,被监管的对象都处于叶子节点上。每个被监管对象都由一个唯一的对象标识符来识别。对象信息的存储结构由MIB定义的简单变量和表来构造,它一般包含描述名(对象标识符)、数据类型、读写规则、功能描述、状态。MIB的定义可以查询RFC1155,它定义了四种基本数据类型:INTEGER,OCTET STRING,OBJECT IDENTIFIER和NULL。由这四种基本类型通过SEQUENCE构造列和表,以及新类型如:NetworkAddress、IpAddress、Counter、Gauge、TimeTicks、Opaque等,以及宏定义。当然,根据需要还可以构造自己的数据类型。

1.3 SNMP的版本

目前SNMP有三个版本snmpV1、snmpV2、snmpV3。针对原始的V1版,93版的v2加入了安全机制,但用户对其并不感兴趣,在96版的v2中又删除了安全机制,99年开始酝酿的v3版开始提出一个snmp的统一架构,采用User-based安全模型和View-based访问控制模型提供SNMP网络管理的安全性。安全机制是SNMPv3的最具特色的内容。

2. SNMP开发软件包

2.1 软件安装见另一个文档(netsnmp installition)

2.2 NET-SNMP代理的配置

运行net-snmp之前先要进行环境设置,否则无法查询到结果。环境配置文件由snmpconf命令交互生成。运行snmpconf后,提示有三个配置文件:snmpd.conf,snmptraps.conf,snmp.conf。
其中,snmpd.conf用来配置代理和管理端通信时的参数,只需设置两个参数就可正常运行程序了,一是community name,有只读rocommunity和读写rwcommunity之分,相当于访问账号,这里设rocommunity为public(常用);另一个是访问端口,设为snmp协议默认的161端口。
Snmp.conf是与mib库设置相关的配置文件。
Snmptraps.conf用来设置代理陷阱,本文没有讨论陷阱。配置文件可以放在三个地方,一是盘符根目录下,二是~\usr\local\share\snmp目录下,三是~/.snmp按标准路径最好是第二种方式。

2.3 NET-SNMP工具的使用

当环境设置好后,运行snmpd.exe,即snmp代理进程,就可以使用管理工具查询其中的信息了。Net-snmp提供的查询工具有很多,这里只介绍常用的几个,而且大部分查询命令的格式都大同小异。这里以.iso.org.dod.internet.mgmt.mib-2.system为例,其Oid为:.1.3.6.1.2.1.1。结构如下:

………system .1.3.6.1.2.1.1

|——sysDescr .1.3.6.1.2.1.1.1

|——sysObjectID .1.3.6.1.2.1.1.2

……

1) snmpget.exe——snmpget [OPTIONS] AGENT OID [OID]...用来查询叶子节点

实例:snmpget –v2c –c public localhost .1.3.6.1.2.1.1.5.0

-v2c: 使用的是2c的snmp版本,可选1|2c|3

-c public:community 名为public

localhost: 代理的地址,这里因为代理运行在本机上,所以可用localhost

.1.3…….0:这里查询的是.iso.org.dod.internet.mgmt.mib-2.system.sysName,其Oid为.1.3.6.1.2.1.1.5,使用这个命令使叶子节点要在后面加.0。

2) snmpgetnext.exe——snmpgetnext [OPTIONS] AGENT OID [OID]...通过父节点查询叶子节点

实例:snmpgetnext –v2c –c public localhost .1.3.6.1.2.1.1

这个命令假设不知道叶子节点,但知道父节点,则可遍历到第一个叶子节点。此例结果等同于上一个例子。Oid也可输入.1.3.6.1.2,因为它是按字典顺序遍历的。

3) snmptable.exe——snmptable [OPTIONS] AGENT TABLE-OID 用来查询表对象

实例:snmptable –v2c –c public localhost .1.3.6.1.2.1.4.20

这个命令查询表对象,本例中查询的是.iso.org.dod.internet.mgmt.mib-2.ip.ipAddrTable

4)snmpset.exe——snmpset [OPTIONS] AGENT OID TYPE VALUE [OID TYPE VALUE]...修改数据

实例:snmpset –v2c –c public localhost .1.3.6.1.2.1.4.21.1.3.x i 99

x:在这里是索引值,表示表项中某一列的第几个数据,根据要求设定

i: 这里是列数据类型,包括i: INTEGER, u: unsigned INTEGER, t: TIMETICKS,

a: IPADDRESS o: OBJID, s: STRING, x: HEX STRING,

d: DECIMAL STRING, b: BITS U: unsigned int64,

I: signed int64, F: float, D: double

5) mib2c 用来把mib库文件编译成.c和.h模版。具体使用会在一个例子中体现出来。


3.example 制作过程:

1. 写mib 库文件 BVCOM-SYSTEMUPTIME-MIB.txt
BVCOM-SYSTEMUPTIME-MIB DEFINITIONS ::= BEGIN

IMPORTS
TimeTicks FROM SNMPv2-SMI
enterprises FROM SNMPv2-SMI
OBJECT-TYPE, Integer32, MODULE-IDENTITY FROM SNMPv2-SMI;

bvcom OBJECT IDENTIFIER ::= { enterprises 26814 }

ipq6800 OBJECT IDENTIFIER ::= { bvcom 6800 }

bvcomAgentModules OBJECT IDENTIFIER ::= { ipq6800 1 }

bvcomAgentModuleObject OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"This is an object that simply supports a writable integer
when compiled into the agent. See
http://www.net-snmp.org/tutorial-5/toolkit/XXX for further
implementation details."
DEFVAL { 1 }
::= { bvcomAgentModules 1 }

bvcomAgentSubagentObject OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"This is an object that simply supports a writable integer
when attached to the agent. The object should be accessible
when the agentx subagent containing this object is attached.
See http://www.net-snmp.org/tutorial-5/toolkit/XXX for
further implementation details."
DEFVAL { 2 }
::= { bvcomAgentModules 2 }

bvcomAgentPluginObject OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"This is an object that simply supports a writable integer
when attached to the agent. This object should be accessible
when the dynamic plugin has been loaded into the agent. See
http://www.net-snmp.org/tutorial-5/toolkit/XXX for further
implementation details."
DEFVAL { 3 }
::= { bvcomAgentModules 3 }

END

2. 复制mib库文件到/usr/local/share/snmp/mibs/
sudo cp BVCOM-SYSTEMUPTIME-MIB.txt /usr/local/share/snmp/mibs/

3. 加载mib库(修改snmp.conf文件)
cat /usr/local/share/snmp/snmp.conf
mibs +BVCOM-SYSTEMUPTIME-MIB

4. 检查mib是否正常加载
border@debian:/work/border/snmp/example-demon$ snmptranslate -IR -Tp bvcom
+--bvcom(26814)
|
+--ipq6800(6800)
|
+--bvcomAgentModules(1)
|
+-- -RW- Integer32 bvcomAgentModuleObject(1)
+-- -RW- Integer32 bvcomAgentSubagentObject(2)
+-- -RW- Integer32 bvcomAgentPluginObject(3)

5. 查看mib2c支持的模板
border@debian:/work/border/snmp/example-demon$ ls /usr/local/share/snmp/
mib2c.access_functions.conf mib2c.create-dataset.conf mib2c.scalar.conf
mib2c.array-user.conf mib2c-data mib2c.table_data.conf
mib2c.check_values.conf mib2c.genhtml.conf mibs
mib2c.check_values_local.conf mib2c.int_watch.conf snmp.conf
mib2c.column_defines.conf mib2c.iterate_access.conf snmp.conf~
mib2c.column_enums.conf mib2c.iterate.conf snmpconf-data
mib2c.column_storage.conf mib2c.mfd.conf snmpd.conf
mib2c.conf mib2c.notify.conf snmp_perl.pl
mib2c.container.conf mib2c.old-api.conf snmp_perl_trapd.pl

6. 通过模板生成.c 和 .h 文件(因为自定义的mib库中的变量都是int类型的所以模板选择int_watch.conf,不同的模板功能不同)
border@debian:/work/border/snmp/example-demon$ mib2c -c mib2c.int_watch.conf bvcomAgentModules
writing to -
*** Warning: only generating code for nodes of MIB type INTEGER
writing to bvcomAgentModules.h
writing to bvcomAgentModules.c
running indent on bvcomAgentModules.c
running indent on bvcomAgentModules.h

7. 通过 snmp_agent_api 编写守护程序 example-demon.c(程序的名字应该于文件夹的名字一致)

#include
#include
#include
#include
#include "bvcomAgentModules.h"

static int keep_running;

RETSIGTYPE
stop_server(int a) {
keep_running = 0;
}

int
main (int argc, char **argv) {

int agentx_subagent=0; /* change this if you want to be a SNMP master agent */
int background = 0; /* change this if you want to run in the background */
int syslog = 0; /* change this if you want to use syslog */

/* print log errors to syslog or stderr */

if (syslog)
snmp_enable_calllog();
else
snmp_enable_stderrlog();

/* we're an agentx subagent? */
if (agentx_subagent) {
/* make us a agentx client. */
netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
}

/* run in background, if requested */
if (background && netsnmp_daemonize(1, !syslog))
exit(1);


/* Initialize tcpip, if necessary */
SOCK_STARTUP;

/* Initialize the agent library */
init_agent("example-demon"); // 配置文件名

/* Initialize our mib code here */
printf("Before init bvcomAgentModules \n");

init_bvcomAgentModules(); // 加载节点信息

printf("End init bvcomAgentModules \n");

/* initialize vacm/usm access control */
if (!agentx_subagent) {
void init_vacm_vars();
void init_usmUser();
}

/* Example-demon will be used to read example-demon.conf files. */
init_snmp("example-demon");

/* If we're going to be a snmp master agent, initial the ports */
if (!agentx_subagent)
init_master_agent(); /* open the port to listen on (defaults to udp:161) */

printf("---------------------\n");
/* In case we recevie a request to stop (kill -TERM or kill -INT) */
keep_running = 1;
signal(SIGTERM, stop_server);

signal(SIGINT, stop_server);

snmp_log(LOG_INFO,"example-demon is up and running.\n");

/* your main loop here... */
while(keep_running) {
/* if you use select(), see snmp_select_info() in snmp_api(3) */
/* --- OR --- */
agent_check_and_process(1); /* 0 == don't block */

}

/* at shutdown time */
snmp_shutdown("example-demon");
SOCK_CLEANUP;
return 0;
}

8. 编写Makefile文件,应用于编译。主要是make时候用到。

CC=gcc

OBJS2=example-demon.o bvcomAgentModules.o
TARGETS=example-demon

CFLAGS=-I. `net-snmp-config --cflags`
BUILDLIBS=`net-snmp-config --libs`
BUILDAGENTLIBS=`net-snmp-config --agent-libs`

# shared library flags (assumes gcc)
DLFLAGS=-fPIC -shared

all: $(TARGETS)

example-demon: $(OBJS2)
$(CC) -o example-demon $(OBJS2) $(BUILDAGENTLIBS)

clean:
rm $(OBJS2) $(OBJS2) $(TARGETS)


9. 编写配置文件example-demon.conf,加入161端口

###############################################################################
# Access Control
###############################################################################

# sec.name source community
com2sec local localhost public
com2sec mynetwork 192.168.0.0/24 public

####
# Second, map the security names into group names:

# sec.model sec.name
group MyRWGroup v1 local
group MyRWGroup v2c local
group MyRWGroup usm local
group MyROGroup v1 mynetwork
group MyROGroup v2c mynetwork
group MyROGroup usm mynetwork

####
# Third, create a view for us to let the groups have rights to:

# incl/excl subtree mask
view all included .1 80

####
# Finally, grant the 2 groups access to the 1 view with different
# write permissions:

# context sec.model sec.level match read write notif
access MyROGroup "" any noauth exact all none none
access MyRWGroup "" any noauth exact all all none

agentaddress 161

10. 运行example-demon 时要用超级管理员运行,不然会出错。
sudo make
sudo ./example-demon

a. 没有用超级管理员时,报的错误:
border@debian:/work/border/snmp/example-demon$ ./example-demon
netsnmp_assert !"registration != duplicate" failed agent_registry.c:535 netsnmp_subtree_load()
netsnmp_assert !"registration != duplicate" failed agent_registry.c:535 netsnmp_subtree_load()
netsnmp_assert !"registration != duplicate" failed agent_registry.c:535 netsnmp_subtree_load()
Before init bvcomAgentModules
End init bvcomAgentModules
Error opening specified endpoint "161"
---------------------
example-demon is up and running.
read_config_store open failure on /var/net-snmp/example-demon.conf
read_config_store open failure on /var/net-snmp/example-demon.conf
read_config_store open failure on /var/net-snmp/example-demon.conf

b. 如果 报Error opening specified endpoint ""错,说明example-demon.conf配置文件没有agentaddress 161

c.如果 报Before init bvcomAgentModules
End init bvcomAgentModules
Error opening specified endpoint "udp:161"
则说明有一个snmpd 正在运行,需关闭后再执行
查看 :用 netstat -l
ps aux
然后 : sudo killall snmpd 再ps aux
确认关闭后在sudo ./example-demon

11. 拷贝配置文件到 ~/.snmp/目录下
cp example-demon.conf /home/border/.snmp/

12. sudo ./example-demon

border@debian:~$ snmpwalk -v1 -c public localhost bvcom
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentModuleObject.0 = INTEGER: 68001
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentSubagentObject.0 = INTEGER: 68002
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentPluginObject.0 = INTEGER: 68003
End of MIB


13.在另一个窗口执行查询命令。
border@debian:~$ snmpget -v2c -c public localhost bvcomAgentModuleObject.0
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentModuleObject.0 = INTEGER: 68001

border@debian:~$ snmpgetnext -v2c -c public localhost bvcomAgentModuleObject.0
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentSubagentObject.0 = INTEGER: 68002

-v2c表示查询的是v2版本, -c 表示要求输入安全体(相等于密码) ,public 就是安全体(密码),127.0.0.1 是执行snmpd客户端的机器的IP地址,bvcomAgentModuleObject.0 表示要查询的变量,当然也可以通过对应的oid来查询,记得要在最后加上".0"哦!其它参数自己查看一下资料。

14.完成set命令:
如更改bvcomAgentModuleObject节点

更改前:
slg@slg-desktop:~/snmpan/agent-snmp$ snmpget -v 1 -c public localhost bvcomAgentModuleObject.0
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentModuleObject.0 = INTEGER: 1

进行set更改:
slg@slg-desktop:~/snmpan/agent-snmp$ snmpset -v 1 -c public localhost bvcomAgentModuleObject.0 i 12
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentModuleObject.0 = INTEGER: 12

更改后:
slg@slg-desktop:~/snmpan/agent-snmp$ snmpget -v 1 -c public localhost bvcomAgentModuleObject.0
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentModuleObject.0 = INTEGER: 12








参考:
1. 用NET-SNMP软件包开发简单客户端代理 http://b0rder.com/wiki/NetSnmp/NetSnmpSimpleAgentMib
2. snmpd.examples 配置信息相关 http://www.net-snmp.org/docs/man/snmpd.examples.html
3. snmp_agent_api http://www.net-snmp.org/docs/man/snmp_agent_api.html
4. Tutorial http://www.nwsmith.net/HintsTips/net-snmp-tutorial.htm

读写INI文件

读写INI文件

1.生成一个文件test.ini:建立GenerateIniFIle.c
#include
main()
{
gnome_config_set_string("=test.ini=test=t1", "sunligang");
gnome_config_set_string("=test.ini=test=t2", "2");
gnome_config_set_string("=test.ini=test=t3", "3");
gnome_config_sync();
}
gcc GenerateIniFIle.c `pkg-config --cflags --libs libgnome-2.0`
sudo ./a.out

打开test.ini:
[test]
t1=sunligang
t2=2
t3=3



2.新建一个文件test.c
#include
#include

main()
{
int *handle;

handle = gnome_config_init_iterator("=test.ini=test"); // 算是打开SECTION吧
char *key, *value;
while (handle) // 如果有值
{
/* 读取下一个Ident */
handle = gnome_config_iterator_next(handle, &key, &value);
if (! key) // 不为NULL
break;
printf("%s,%s\n", key, value); // 打出来看看
}

}

3.编译: gcc test.c `pkg-config --cflags --libs libgnome-2.0`

4.运行:sudo ./a.out

5.结果:
t3,3
t2,3
t1,sunligang


说明:
一 、写INI文件

/* 第一个参数为的test.ini为文件名称,www为section,qwe为ident
第二个参数为值
它们之间用=分割,则会在程序当前目录生成INI文件
据说用/分割会在 ~/.gnome或~/.gnome_private目录下生成INI文件
不知道为什么,我改成/后运行出错,我的系统为FC6
*/
gnome_config_set_string("=test.ini=www=qwe", "test123");
/* 必须调用下面这句,否则将些不成功 */
gnome_config_sync();

二、读INI文件
char *str = gnome_config_get_string("=test.ini=www=qwe");
// 另一种读法
// 后面多出来的为默认值,
// 通过执行gnome_config_get_string_with_default函数
// 如果在INI文件中读出qwe的值,则o为0否则为1
int o;
char *str = gnome_config_get_string_with_default("=test.ini=www=qwe=oo", &o);
printf("%s;%d", str, o);


记得要
#include

编译,因为对linux不熟悉,编译它让我费了很大的精力

gcc 文件.c `pkg-config --cflags --libs libgnome-2.0`









三、例子:读取某一个SECTION下面的所有节(Ident)
例如:
[test]
t1=1
t2=3
t3=3
如何在不知道t1"t2"t3的情况下,读出它们呢?

int *handle;

handle = gnome_config_init_iterator("=test.ini=test"); // 算是打开SECTION吧
char *key, *value;
while (handle) // 如果有值
{
/* 读取下一个Ident */
handle = gnome_config_iterator_next(handle, &key, &value);
if (! key) // 不为NULL
break;
printf("%s;%s"r"n", key, value); // 打出来看看
}

需要注意的是,这么读出来的顺序不是t1,t2,t3而是t3,t2,t1。

开博了

弄了一个博客,以后可以存放技术文档