您的位置:首页 > 新闻 > 会展 > 小程序推广渠道_肇庆网站制作案例_新闻播报最新_唐山建站公司模板

小程序推广渠道_肇庆网站制作案例_新闻播报最新_唐山建站公司模板

2025/5/23 9:35:58 来源:https://blog.csdn.net/wit_yuan/article/details/143377579  浏览:    关键词:小程序推广渠道_肇庆网站制作案例_新闻播报最新_唐山建站公司模板
小程序推广渠道_肇庆网站制作案例_新闻播报最新_唐山建站公司模板

1.说明

1.1 介绍

这一篇是继两篇文章:

  • BMC SNMP开发
  • BMC snmp 开发二

之后的第三篇文章。主要是做基本的代码分析。

1.2 资源回顾

写这篇文章的时候,发现之前写的2篇文章,大致内容已经有人写过了:

  • 深入理解Net-SNMP,https://github.com/chansonZ/Understanding-the-Net-SNMP.,不过缺点是讲的内容都在应用,没有具体去分析代码。

2.SNMP代码分析基本流程

2.1 基于代码版本

当前基于snmpd版本5.10,基于linux平台做分析:

$ sudo snmpd -v      NET-SNMP version:  5.10
Web:               http://www.net-snmp.org/
Email:             net-snmp-coders@lists.sourceforge.net

2.2 基本大框架主要流程

分析:agent\snmpd.c,基本的大的程序流程如下:

main()
---> netsnmp_close_fds(2); //关闭大于2的所有描述符
---> snmp_log_syslogname(app_name); //设置syslog名字为snmpd
---> netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,NETSNMP_DS_LIB_APPTYPE, app_name);//设置为snmpd
---> snmpd_parse_options(&opts, argc, argv)//解析参数
---> snmp_enable_filelog()
---> init_agent(app_name)
---> init_mib_modules()
---> init_snmp(app_name)
---> init_master_agent()
---> netsnmp_daemonize()
---> snmp_store(app_name)
---> send_easy_trap(0, 0)
---> netsnmp_addrcache_initialise()
---> receive()
---> SnmpTrapNodeDown()

其中,init_agent()流程如下:

int init_agent(const char *app)
---> netsnmp_set_agent_starttime(NULL); //设置gettimeofday(&starttime, NULL);和netsnmp_get_monotonic_clock(&starttimeM);
---> setup_tree();
---> init_agent_read_config(app);---> register_app_config_handler()---> register_app_config_handler()---> register_app_config_handler()---> ...---> netsnmp_ds_register_config()---> netsnmp_ds_register_config()---> netsnmp_ds_register_config()---> ...---> netsnmp_init_handler_conf()---> snmpd_register_config_handler() ---> snmp_register_callback()---> se_add_pair_to_slist()
---> _init_agent_callback_transport()
---> netsnmp_init_helpers()---> netsnmp_init_debug_helper()---> netsnmp_init_serialize()---> netsnmp_init_read_only_helper()---> netsnmp_init_bulk_to_next_helper()---> netsnmp_init_table_dataset()---> register_app_config_handler"table", netsnmp_config_parse_table_set, NULL,"tableoid");---> register_app_config_handler("add_row", netsnmp_config_parse_add_row, NULL, "table_name indexes... values...");---> netsnmp_init_row_merge()---> netsnmp_init_stash_cache_helper()
---> init_traps()
---> netsnmp_container_init_list()
---> init_agent_sysORTable()
---> agentx_config_init()---> netsnmp_register_default_domain("agentx", "unix tcp");---> netsnmp_register_default_target("agentx", "unix", NETSNMP_AGENTX_SOCKET);  //"/var/agentx/master"---> netsnmp_register_default_target("agentx", "tcp", "localhost:" val(AGENTX_PORT)); // 705---> netsnmp_udp_agent_config_tokens_register()
---> netsnmp_udp6_agent_config_tokens_register()
---> netsnmp_unix_agent_config_tokens_register()
---> init_perl()
---> netsnmp_certs_agent_init()

这里面有一个函数setup_tree(),调用关系如下:

void setup_tree(void)
---> oid ccitt[1]           = { 0 };
---> oid iso[1]             = { 1 };
---> oid joint_ccitt_iso[1] = { 2 };
---> netsnmp_register_null(snmp_duplicate_objid(ccitt, 1), 1);---> netsnmp_register_null_context(loc, loc_len, NULL);---> reginfo = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);---> reginfo->handlerName = strdup("");---> reginfo->rootoid = loc;---> reginfo->rootoid_len = loc_len;---> reginfo->modes = HANDLER_CAN_DEFAULT | HANDLER_CAN_GETBULK;---> netsnmp_register_handler(reginfo);---> netsnmp_register_mib( ... )---> ...---> netsnmp_subtree_replace_first()---> add_subtree(new_tree, context_name);---> ...
---> netsnmp_register_null(snmp_duplicate_objid(iso, 1), 1);
---> netsnmp_register_null(snmp_duplicate_objid(joint_ccitt_iso, 1), 1);

完成添加根节点的subtree.

函数init_mib_modules()流程如下:

void init_mib_modules(void)
---> #  include "mib_module_inits.h"
---> snmp_register_callback( SNMP_CALLBACK_LIBRARY,SNMP_CALLBACK_SHUTDOWN,_shutdown_mib_modules,NULL);

这里面使用了include代码的方式,实际调用的内容为:

/* This file is automatically generated by configure.  Do not modify by hand. */if (should_init("snmpEngine")) init_snmpEngine();if (should_init("snmpMPDStats")) init_snmpMPDStats();if (should_init("usmStats")) init_usmStats();if (should_init("usmUser")) init_usmUser();if (should_init("system_mib")) init_system_mib();if (should_init("sysORTable")) init_sysORTable();if (should_init("snmp_mib")) init_snmp_mib();if (should_init("vacm_vars")) init_vacm_vars();if (should_init("setSerialNo")) init_setSerialNo();if (should_init("at")) init_at();if (should_init("ip")) init_ip();if (should_init("tcp")) init_tcp();if (should_init("udp")) init_udp();if (should_init("ipv6")) init_ipv6();if (should_init("icmp")) init_icmp();if (should_init("proc")) init_proc();if (should_init("versioninfo")) init_versioninfo();if (should_init("pass")) init_pass();if (should_init("pass_persist")) init_pass_persist();if (should_init("disk_hw")) init_disk_hw();if (should_init("loadave")) init_loadave();if (should_init("extend")) init_extend();if (should_init("errormib")) init_errormib();if (should_init("file")) init_file();if (should_init("dlmod")) init_dlmod();if (should_init("proxy")) init_proxy();if (should_init("logmatch")) init_logmatch();if (should_init("memory")) init_memory();if (should_init("vmstat")) init_vmstat();if (should_init("snmpNotifyTable")) init_snmpNotifyTable();if (should_init("snmpNotifyFilterProfileTable")) init_snmpNotifyFilterProfileTable();if (should_init("notification_log")) init_notification_log();if (should_init("snmpTargetAddrEntry")) init_snmpTargetAddrEntry();if (should_init("snmpTargetParamsEntry")) init_snmpTargetParamsEntry();if (should_init("target_counters")) init_target_counters();if (should_init("nsTransactionTable")) init_nsTransactionTable();if (should_init("nsModuleTable")) init_nsModuleTable();if (should_init("nsDebug")) init_nsDebug();if (should_init("nsCache")) init_nsCache();if (should_init("nsLogging")) init_nsLogging();if (should_init("nsVacmAccessTable")) init_nsVacmAccessTable();if (should_init("mteScalars")) init_mteScalars();if (should_init("mteTrigger")) init_mteTrigger();if (should_init("mteTriggerTable")) init_mteTriggerTable();if (should_init("mteTriggerDeltaTable")) init_mteTriggerDeltaTable();if (should_init("mteTriggerExistenceTable")) init_mteTriggerExistenceTable();if (should_init("mteTriggerBooleanTable")) init_mteTriggerBooleanTable();if (should_init("mteTriggerThresholdTable")) init_mteTriggerThresholdTable();if (should_init("mteTriggerConf")) init_mteTriggerConf();if (should_init("mteEvent")) init_mteEvent();if (should_init("mteEventTable")) init_mteEventTable();if (should_init("mteEventSetTable")) init_mteEventSetTable();if (should_init("mteEventNotificationTable")) init_mteEventNotificationTable();if (should_init("mteEventConf")) init_mteEventConf();if (should_init("mteObjects")) init_mteObjects();if (should_init("mteObjectsTable")) init_mteObjectsTable();if (should_init("mteObjectsConf")) init_mteObjectsConf();if (should_init("schedCore")) init_schedCore();if (should_init("schedConf")) init_schedConf();if (should_init("schedTable")) init_schedTable();if (should_init("override")) init_override();if (should_init("hr_system")) init_hr_system();if (should_init("hr_device")) init_hr_device();if (should_init("hr_other")) init_hr_other();if (should_init("hr_proc")) init_hr_proc();if (should_init("hr_network")) init_hr_network();if (should_init("hr_print")) init_hr_print();if (should_init("hr_disk")) init_hr_disk();if (should_init("hr_partition")) init_hr_partition();if (should_init("hrh_storage")) init_hrh_storage();if (should_init("hrh_filesys")) init_hrh_filesys();if (should_init("hrSWInstalledTable")) init_hrSWInstalledTable();if (should_init("hrSWRunTable")) init_hrSWRunTable();if (should_init("vacm_context")) init_vacm_context();if (should_init("var_route")) init_var_route();if (should_init("tcpTable")) init_tcpTable();if (should_init("udpTable")) init_udpTable();if (should_init("ip_scalars")) init_ip_scalars();if (should_init("snmpNotifyTable_data")) init_snmpNotifyTable_data();if (should_init("snmpNotifyFilterTable_data_storage")) init_snmpNotifyFilterTable_data_storage();if (should_init("snmpNotifyFilterTable")) init_snmpNotifyFilterTable();if (should_init("snmpNotifyFilterProfileTable_data")) init_snmpNotifyFilterProfileTable_data();if (should_init("snmpTargetAddrEntry_data")) init_snmpTargetAddrEntry_data();if (should_init("snmpTargetParamsEntry_data")) init_snmpTargetParamsEntry_data();if (should_init("swinst")) init_swinst();if (should_init("swrun")) init_swrun();if (should_init("hrSWRunPerfTable")) init_hrSWRunPerfTable();if (should_init("ifTable")) init_ifTable();if (should_init("ifXTable")) init_ifXTable();if (should_init("ipAddressTable")) init_ipAddressTable();if (should_init("ipAddressPrefixTable")) init_ipAddressPrefixTable();if (should_init("ipDefaultRouterTable")) init_ipDefaultRouterTable();if (should_init("inetNetToMediaTable")) init_inetNetToMediaTable();if (should_init("ipSystemStatsTable")) init_ipSystemStatsTable();if (should_init("ipv6ScopeZoneIndexTable")) init_ipv6ScopeZoneIndexTable();if (should_init("ipIfStatsTable")) init_ipIfStatsTable();if (should_init("ipCidrRouteTable")) init_ipCidrRouteTable();if (should_init("inetCidrRouteTable")) init_inetCidrRouteTable();if (should_init("tcpConnectionTable")) init_tcpConnectionTable();if (should_init("tcpListenerTable")) init_tcpListenerTable();if (should_init("udpEndpointTable")) init_udpEndpointTable();if (should_init("hw_fsys")) init_hw_fsys();if (should_init("hw_mem")) init_hw_mem();if (should_init("cpu")) init_cpu();if (should_init("cpu_linux")) init_cpu_linux();if (should_init("interface")) init_interface();

这些函数内容init_xx(),其实在之前的2篇文章中,可以参考它们。这些代码里面也会包含mib文件,可以参考并对照代码学习

函数init_snmp()调用关系如下:

void init_snmp(const char *type)
---> _init_snmp();---> netsnmp_init_mib_internals();---> netsnmp_tdomain_init();---> gettimeofday(&tv, (struct timezone *) 0);---> netsnmp_register_default_domain("snmp", "udp udp6");---> netsnmp_register_default_domain("snmptrap", "udp udp6");---> netsnmp_register_default_target("snmp", "udp", ":161");---> netsnmp_register_default_target("snmp", "tcp", ":161");---> netsnmp_register_default_target("snmp", "udp6", ":161");---> netsnmp_register_default_target("snmp", "tcp6", ":161");---> netsnmp_register_default_target("snmptrap", "udp", ":162");---> ...
---> setlocale(LC_CTYPE, "");
---> snmp_debug_init(); 
---> netsnmp_container_init_list();
---> init_callbacks()
---> init_snmp_logging();
---> snmp_init_statistics();
---> register_mib_handlers();---> register_prenetsnmp_mib_handler("snmp", "mibdirs", ...)---> register_prenetsnmp_mib_handler("snmp", "mibs", ...)--->  register_config_handler("snmp", "mibfile", handle_mibfile_conf, NULL, "mibfile-to-read");---> register_default_handlers();
---> init_snmp_transport();
---> init_snmpv3(type);
---> init_snmp_alarm();
---> init_snmp_enum(type);
---> init_vacm();
---> netsnmp_certs_init()
---> read_premib_configs();---> read_config_files(PREMIB_CONFIG);---> read_configs_optional(optional_config, PREMIB_CONFIG);---> netsnmp_config_process_memories_when(PREMIB_CONFIG, 0);
---> netsnmp_init_mib();---> netsnmp_init_mib_internals();---> netsnmp_fixup_mib_directory();---> add_mibdir(entry);---> add_mibfile(entry, NULL);---> read_all_mibs();---> read_mib(entry);---> netsnmp_read_module(entry);
---> read_configs();---> read_config_files(NORMAL_CONFIG);---> free_config();---> read_config_files_of_type(when, ctmp)---> read_configs_optional(optional_config, NORMAL_CONFIG);---> netsnmp_config_process_memories_when(NORMAL_CONFIG, 1);
```'
函数`netsnmp_init_mib_internals()`定义如下:
```c
static void _init_snmp(void)
---> void netsnmp_init_mib_internals(void)---> build_translation_table();---> static void init_tree_roots(void)---> tp = calloc(1, sizeof(struct tree));---> lasttp = tp;---> tp = calloc(1, sizeof(struct tree));---> tp->next_peer = lasttp;---> lasttp = tp;---> tp = calloc(1, sizeof(struct tree));---> tp->next_peer = lasttp;---> tree_head = tp;

其中,tree_head()snmp_add_var()调用:

int
snmp_add_var(netsnmp_pdu *pdu,const oid * name, size_t name_length, char type, const char *value)
---> tp = get_tree(name, name_length, get_tree_head());---> for (; subtree; subtree = subtree->next_peer) {---> if (*objid == subtree->subid)}

函数:handle_mibfile_conf()如下:

static void handle_mibfile_conf(const char *token, char *line)
---> read_mib(line);---> new_module(token, filename);---> netsnmp_read_module(token);---> status = read_module_internal(name);---> netsnmp_init_mib_internals();---> module_map_head = module_map;  //重要的mib对应关系名---> build_translation_table();---> case OBJID:---> case OCTETSTR:---> case INTEGER:---> case NETADDR:---> case IPADDR:---> case COUNTER:---> case GAUGE:---> case TIMETICKS:---> case INTEGER32:---> ...---> init_tree_roots();          /* Set up initial roots */---> base_modid = which_module("SNMPv2-SMI");---> base_modid = which_module("RFC1155-SMI");---> base_modid = which_module("RFC1213-MIB");---> tp->label = strdup("joint-iso-ccitt"); //joint-iso-ccitt .2---> tp->subid = 2;---> tp->label = strdup("ccitt");   //ccitt .0---> tp->subid = 0;---> tp->label = strdup("iso");     //iso .1---> tp->subid = 1; 

这里就是前面的mib文件中定义的几个根节点的OID:

ccitt           .0
iso             .1
joint-iso-ccitt .2

函数:init_master_agent()如下:

int init_master_agent(void)			
---> netsnmp_set_lookup_cache_size(-1);
---> netsnmp_agent_listen_on(cptr)		---> transport = netsnmp_transport_open_server("snmp", port);---> handle = netsnmp_register_agent_nsap(transport);
---> real_init_master();---> snmp_sess_init(&sess);	---> _init_snmp();---> netsnmp_unix_create_path_with_mode(agentx_dir_perm);---> netsnmp_unix_dont_create_path();---> _pdu_stats_init();

2.3 一个scalar例子的流程

按照之前文章中写到的scalar例子中,大致的代码流程为:

scalar:
init_WITYUANModule()const oid wityuanNode_oid[] = { 1,3,6,1,4,1,60000,1,1 };netsnmp_handler_registration reg;reg = netsnmp_create_handler_registration("wityuanNode", handle_wityuanNode,wityuanNode_oid, OID_LENGTH(wityuanNode_oid), HANDLER_CAN_RWRITE)---> netsnmp_mib_handler *handler = netsnmp_create_handler(name, handler_access_method);---> netsnmp_mib_handler *ret = SNMP_MALLOC_TYPEDEF(netsnmp_mib_handler);---> ret->access_method = handler_access_method;---> ret->handler_name = strdup(name);---> netsnmp_handler_registration_create(name, handler, reg_oid, reg_oid_len, modes);---> netsnmp_handler_registration *the_reg;---> the_reg->handler = handler;---> the_reg->handlerName = strdup(name);---> the_reg->rootoid = snmp_duplicate_objid(reg_oid, reg_oid_len);netsnmp_register_scalar(reg)---> tmp = (oid*)realloc(reginfo->rootoid,(reginfo->rootoid_len+1) * sizeof(oid) );---> reginfo->rootoid = tmp;---> reginfo->rootoid[ reginfo->rootoid_len ] = 0;---> h1 = netsnmp_get_instance_handler();---> netsnmp_create_handler("instance",netsnmp_instance_helper_handler);---> netsnmp_mib_handler *ret = SNMP_MALLOC_TYPEDEF(netsnmp_mib_handler);---> ret->access_method = handler_access_method;---> ret->handler_name = strdup(name);---> h2 = netsnmp_get_scalar_handler();---> netsnmp_create_handler("scalar",netsnmp_scalar_helper_handler);---> netsnmp_mib_handler *ret = SNMP_MALLOC_TYPEDEF(netsnmp_mib_handler);---> ret->access_method = handler_access_method;---> ret->handler_name = strdup(name);---> netsnmp_inject_handler(reginfo, h1)handler2->next = reginfo->handler;  //h1->next=reginfo->handler;---> netsnmp_inject_handler(reginfo, h2)handler2->next = reginfo->handler; //h2->next=reginfo->handler; ---> netsnmp_register_serialize(reginfo);---> netsnmp_mib_handler *handler = netsnmp_get_serialize_handler();---> netsnmp_register_handler(reginfo);---> netsnmp_register_mib(reginfo->handlerName,....)

大致流图如下所示:

在这里插入图片描述
可以留意到3行代码:

    tmp = (oid*)realloc(reginfo->rootoid,(reginfo->rootoid_len+1) * sizeof(oid) );reginfo->rootoid = tmp;reginfo->rootoid[ reginfo->rootoid_len ] = 0;

因此,对于scalar,总体而言访问的话,其最后应该添加一个.0.

2.4 一个table例子的流程,TBD...

流程类似。

3.snmp oid构建方法,TBD...

后面有机会再来补充吧…

4.snmp parser,TBD...

后面有机会再来补充吧…

5.snmp over ssh

snmp over ssh可以参考如下2篇文章:

  • 1.http://www.net-snmp.org/wiki/index.php/SSH
  • 2.https://www.ietf.org/proceedings/67/slides/isms-3.pdf

6.snmptable的实现原理

snmptablenet-snmp提供的一个工具,调用关系如下:

int main(int argc, char *argv[])
---> netsnmp_set_line_buffering(stdout);
---> snmp_parse_oid(argv[optind], root, &rootlen)
---> get_field_names();
---> reverse_fields();
---> ss = snmp_open(&session);
---> if (use_getbulk) getbulk_table_entries(ss);---> pdu = snmp_pdu_create(SNMP_MSG_GETBULK); //使用bulk方式获取table数据
---> else get_table_entries(ss);---> pdu = snmp_pdu_create(SNMP_MSG_GETNEXT); //使用getnext方式获取table数据

因此,snmptable使用的是getbulk或者getnext方式获取table数据。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com