00001 /* 00002 * snmp_vars.c - return a pointer to the named variable. 00003 */ 00009 /* Portions of this file are subject to the following copyright(s). See 00010 * the Net-SNMP's COPYING file for more details and other copyrights 00011 * that may apply: 00012 */ 00013 /* Portions of this file are subject to the following copyright(s). See 00014 * the Net-SNMP's COPYING file for more details and other copyrights 00015 * that may apply: 00016 */ 00017 /*********************************************************** 00018 Copyright 1988, 1989, 1990 by Carnegie Mellon University 00019 Copyright 1989 TGV, Incorporated 00020 00021 All Rights Reserved 00022 00023 Permission to use, copy, modify, and distribute this software and its 00024 documentation for any purpose and without fee is hereby granted, 00025 provided that the above copyright notice appear in all copies and that 00026 both that copyright notice and this permission notice appear in 00027 supporting documentation, and that the name of CMU and TGV not be used 00028 in advertising or publicity pertaining to distribution of the software 00029 without specific, written prior permission. 00030 00031 CMU AND TGV DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 00032 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 00033 EVENT SHALL CMU OR TGV BE LIABLE FOR ANY SPECIAL, INDIRECT OR 00034 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 00035 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 00036 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00037 PERFORMANCE OF THIS SOFTWARE. 00038 ******************************************************************/ 00039 /* 00040 * Portions of this file are copyrighted by: 00041 * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. 00042 * Use is subject to license terms specified in the COPYING file 00043 * distributed with the Net-SNMP package. 00044 */ 00045 00046 /* 00047 * additions, fixes and enhancements for Linux by Erik Schoenfelder 00048 * (schoenfr@ibr.cs.tu-bs.de) 1994/1995. 00049 * Linux additions taken from CMU to UCD stack by Jennifer Bray of Origin 00050 * (jbray@origin-at.co.uk) 1997 00051 */ 00052 /* 00053 * Portions of this file are copyrighted by: 00054 * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. 00055 * Use is subject to license terms specified in the COPYING file 00056 * distributed with the Net-SNMP package. 00057 */ 00058 00059 /* 00060 * XXXWWW merge todo: incl/excl range changes in differences between 00061 * 1.194 and 1.199 00062 */ 00063 00064 #include <net-snmp/net-snmp-config.h> 00065 #if HAVE_STRING_H 00066 #include <string.h> 00067 #endif 00068 #if HAVE_STDLIB_H 00069 #include <stdlib.h> 00070 #endif 00071 #include <sys/types.h> 00072 #include <stdio.h> 00073 #include <fcntl.h> 00074 00075 #if TIME_WITH_SYS_TIME 00076 # ifdef WIN32 00077 # include <sys/timeb.h> 00078 # else 00079 # include <sys/time.h> 00080 # endif 00081 # include <time.h> 00082 #else 00083 # if HAVE_SYS_TIME_H 00084 # include <sys/time.h> 00085 # else 00086 # include <time.h> 00087 # endif 00088 #endif 00089 #if HAVE_WINSOCK_H 00090 # include <winsock.h> 00091 #endif 00092 #if HAVE_SYS_SOCKET_H 00093 # include <sys/socket.h> 00094 #endif 00095 #if HAVE_SYS_STREAM_H 00096 # ifdef sysv5UnixWare7 00097 # define _KMEMUSER 1 /* <sys/stream.h> needs this for queue_t */ 00098 # endif 00099 #include <sys/stream.h> 00100 #endif 00101 #if HAVE_SYS_SOCKETVAR_H 00102 # include <sys/socketvar.h> 00103 #endif 00104 #if HAVE_NETINET_IN_H 00105 #include <netinet/in.h> 00106 #endif 00107 #if HAVE_NETINET_IN_SYSTM_H 00108 #include <netinet/in_systm.h> 00109 #endif 00110 #if HAVE_NETINET_IP_H 00111 #include <netinet/ip.h> 00112 #endif 00113 #ifdef NETSNMP_ENABLE_IPV6 00114 #if HAVE_NETINET_IP6_H 00115 #include <netinet/ip6.h> 00116 #endif 00117 #endif 00118 #if HAVE_SYS_QUEUE_H 00119 #include <sys/queue.h> 00120 #endif 00121 #if HAVE_NET_ROUTE_H 00122 #include <net/route.h> 00123 #endif 00124 #if HAVE_NETINET_IP_VAR_H 00125 #include <netinet/ip_var.h> 00126 #endif 00127 #ifdef NETSNMP_ENABLE_IPV6 00128 #if HAVE_NETNETSNMP_ENABLE_IPV6_IP6_VAR_H 00129 #include <netinet6/ip6_var.h> 00130 #endif 00131 #endif 00132 #if HAVE_NETINET_IN_PCB_H 00133 #include <netinet/in_pcb.h> 00134 #endif 00135 #if HAVE_INET_MIB2_H 00136 #include <inet/mib2.h> 00137 #endif 00138 00139 #include <net-snmp/net-snmp-includes.h> 00140 #include <net-snmp/agent/net-snmp-agent-includes.h> 00141 #include <net-snmp/agent/mib_modules.h> 00142 #include <net-snmp/agent/agent_sysORTable.h> 00143 #include "kernel.h" 00144 00145 #include "mibgroup/struct.h" 00146 #include "snmpd.h" 00147 #include "agentx/agentx_config.h" 00148 #include "agentx/subagent.h" 00149 #include "net-snmp/agent/all_helpers.h" 00150 #include "agent_module_includes.h" 00151 #include "mib_module_includes.h" 00152 #include "net-snmp/library/container.h" 00153 00154 #include "snmp_perl.h" 00155 00156 #ifndef MIN 00157 #define MIN(a,b) (((a) < (b)) ? (a) : (b)) 00158 #endif 00159 00160 static char done_init_agent = 0; 00161 00162 struct module_init_list *initlist = NULL; 00163 struct module_init_list *noinitlist = NULL; 00164 00165 /* 00166 * mib clients are passed a pointer to a oid buffer. Some mib clients 00167 * * (namely, those first noticed in mibII/vacm.c) modify this oid buffer 00168 * * before they determine if they really need to send results back out 00169 * * using it. If the master agent determined that the client was not the 00170 * * right one to talk with, it will use the same oid buffer to pass to the 00171 * * rest of the clients, which may not longer be valid. This should be 00172 * * fixed in all clients rather than the master. However, its not a 00173 * * particularily easy bug to track down so this saves debugging time at 00174 * * the expense of a few memcpy's. 00175 */ 00176 #define MIB_CLIENTS_ARE_EVIL 1 00177 00178 extern netsnmp_subtree *subtrees; 00179 00180 /* 00181 * Each variable name is placed in the variable table, without the 00182 * terminating substring that determines the instance of the variable. When 00183 * a string is found that is lexicographicly preceded by the input string, 00184 * the function for that entry is called to find the method of access of the 00185 * instance of the named variable. If that variable is not found, NULL is 00186 * returned, and the search through the table continues (it will probably 00187 * stop at the next entry). If it is found, the function returns a character 00188 * pointer and a length or a function pointer. The former is the address 00189 * of the operand, the latter is a write routine for the variable. 00190 * 00191 * u_char * 00192 * findVar(name, length, exact, var_len, write_method) 00193 * oid *name; IN/OUT - input name requested, output name found 00194 * int length; IN/OUT - number of sub-ids in the in and out oid's 00195 * int exact; IN - TRUE if an exact match was requested. 00196 * int len; OUT - length of variable or 0 if function returned. 00197 * int write_method; OUT - pointer to function to set variable, 00198 * otherwise 0 00199 * 00200 * The writeVar function is returned to handle row addition or complex 00201 * writes that require boundary checking or executing an action. 00202 * This routine will be called three times for each varbind in the packet. 00203 * The first time for each varbind, action is set to RESERVE1. The type 00204 * and value should be checked during this pass. If any other variables 00205 * in the MIB depend on this variable, this variable will be stored away 00206 * (but *not* committed!) in a place where it can be found by a call to 00207 * writeVar for a dependent variable, even in the same PDU. During 00208 * the second pass, action is set to RESERVE2. If this variable is dependent 00209 * on any other variables, it will check them now. It must check to see 00210 * if any non-committed values have been stored for variables in the same 00211 * PDU that it depends on. Sometimes resources will need to be reserved 00212 * in the first two passes to guarantee that the operation can proceed 00213 * during the third pass. During the third pass, if there were no errors 00214 * in the first two passes, writeVar is called for every varbind with action 00215 * set to COMMIT. It is now that the values should be written. If there 00216 * were errors during the first two passes, writeVar is called in the third 00217 * pass once for each varbind, with the action set to FREE. An opportunity 00218 * is thus provided to free those resources reserved in the first two passes. 00219 * 00220 * writeVar(action, var_val, var_val_type, var_val_len, statP, name, name_len) 00221 * int action; IN - RESERVE1, RESERVE2, COMMIT, or FREE 00222 * u_char *var_val; IN - input or output buffer space 00223 * u_char var_val_type; IN - type of input buffer 00224 * int var_val_len; IN - input and output buffer len 00225 * u_char *statP; IN - pointer to local statistic 00226 * oid *name IN - pointer to name requested 00227 * int name_len IN - number of sub-ids in the name 00228 */ 00229 00230 long long_return; 00231 #ifndef ibm032 00232 u_char return_buf[258]; 00233 #else 00234 u_char return_buf[256]; /* nee 64 */ 00235 #endif 00236 00237 struct timeval starttime; 00238 00239 int callback_master_num = -1; 00240 00241 #ifdef NETSNMP_TRANSPORT_CALLBACK_DOMAIN 00242 netsnmp_session *callback_master_sess = NULL; 00243 00244 static void 00245 _init_agent_callback_transport(void) 00246 { 00247 /* 00248 * always register a callback transport for internal use 00249 */ 00250 callback_master_sess = netsnmp_callback_open(0, handle_snmp_packet, 00251 netsnmp_agent_check_packet, 00252 netsnmp_agent_check_parse); 00253 if (callback_master_sess) 00254 callback_master_num = callback_master_sess->local_port; 00255 } 00256 #else 00257 #define _init_agent_callback_transport() 00258 #endif 00259 00272 int 00273 init_agent(const char *app) 00274 { 00275 int r = 0; 00276 00277 if(++done_init_agent > 1) { 00278 snmp_log(LOG_WARNING, "ignoring extra call to init_agent (%d)\n", 00279 done_init_agent); 00280 return r; 00281 } 00282 00283 /* 00284 * get current time (ie, the time the agent started) 00285 */ 00286 gettimeofday(&starttime, NULL); 00287 starttime.tv_sec--; 00288 starttime.tv_usec += 1000000L; 00289 00290 /* 00291 * we handle alarm signals ourselves in the select loop 00292 */ 00293 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 00294 NETSNMP_DS_LIB_ALARM_DONT_USE_SIG, 1); 00295 00296 #ifdef NETSNMP_CAN_USE_NLIST 00297 init_kmem("/dev/kmem"); 00298 #endif 00299 00300 setup_tree(); 00301 00302 init_agent_read_config(app); 00303 00304 #ifdef TESTING 00305 auto_nlist_print_tree(-2, 0); 00306 #endif 00307 00308 _init_agent_callback_transport(); 00309 00310 netsnmp_init_helpers(); 00311 init_traps(); 00312 netsnmp_container_init_list(); 00313 init_agent_sysORTable(); 00314 00315 #if defined(USING_AGENTX_SUBAGENT_MODULE) || defined(USING_AGENTX_MASTER_MODULE) 00316 /* 00317 * initialize agentx configs 00318 */ 00319 agentx_config_init(); 00320 if(netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 00321 NETSNMP_DS_AGENT_ROLE) == SUB_AGENT) 00322 subagent_init(); 00323 #endif 00324 00325 /* 00326 * Register configuration tokens from transport modules. 00327 */ 00328 #ifdef NETSNMP_TRANSPORT_UDP_DOMAIN 00329 netsnmp_udp_agent_config_tokens_register(); 00330 #endif 00331 #ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN 00332 netsnmp_udp6_agent_config_tokens_register(); 00333 #endif 00334 #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN 00335 netsnmp_unix_agent_config_tokens_register(); 00336 #endif 00337 00338 #ifdef NETSNMP_EMBEDDED_PERL 00339 init_perl(); 00340 #endif 00341 00342 #ifdef USING_AGENTX_SUBAGENT_MODULE 00343 /* 00344 * don't init agent modules for a sub-agent 00345 */ 00346 if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 00347 NETSNMP_DS_AGENT_ROLE) == SUB_AGENT) 00348 return r; 00349 #endif 00350 00351 # include "agent_module_inits.h" 00352 00353 return r; 00354 } /* end init_agent() */ 00355 00356 oid nullOid[] = { 0, 0 }; 00357 int nullOidLen = sizeof(nullOid); 00358 00359 void 00360 shutdown_agent(void) { 00361 00362 /* probably some of this can be called as shutdown callback */ 00363 shutdown_tree(); 00364 clear_context(); 00365 netsnmp_clear_callback_list(); 00366 netsnmp_clear_tdomain_list(); 00367 netsnmp_clear_handler_list(); 00368 shutdown_agent_sysORTable(); 00369 netsnmp_container_free_list(); 00370 clear_sec_mod(); 00371 clear_snmp_enum(); 00372 clear_callback(); 00373 clear_user_list(); 00374 netsnmp_addrcache_destroy(); 00375 00376 done_init_agent = 0; 00377 } 00378 00379 00380 void 00381 add_to_init_list(char *module_list) 00382 { 00383 struct module_init_list *newitem, **list; 00384 char *cp; 00385 char *st; 00386 00387 if (module_list == NULL) { 00388 return; 00389 } else { 00390 cp = (char *) module_list; 00391 } 00392 00393 if (*cp == '-' || *cp == '!') { 00394 cp++; 00395 list = &noinitlist; 00396 } else { 00397 list = &initlist; 00398 } 00399 00400 cp = strtok_r(cp, ", :", &st); 00401 while (cp) { 00402 newitem = (struct module_init_list *) calloc(1, sizeof(*initlist)); 00403 newitem->module_name = strdup(cp); 00404 newitem->next = *list; 00405 *list = newitem; 00406 cp = strtok_r(NULL, ", :", &st); 00407 } 00408 } 00409 00410 int 00411 should_init(const char *module_name) 00412 { 00413 struct module_init_list *listp; 00414 00415 /* 00416 * a definitive list takes priority 00417 */ 00418 if (initlist) { 00419 listp = initlist; 00420 while (listp) { 00421 if (strcmp(listp->module_name, module_name) == 0) { 00422 DEBUGMSGTL(("mib_init", "initializing: %s\n", 00423 module_name)); 00424 return DO_INITIALIZE; 00425 } 00426 listp = listp->next; 00427 } 00428 DEBUGMSGTL(("mib_init", "skipping: %s\n", module_name)); 00429 return DONT_INITIALIZE; 00430 } 00431 00432 /* 00433 * initialize it only if not on the bad list (bad module, no bone) 00434 */ 00435 if (noinitlist) { 00436 listp = noinitlist; 00437 while (listp) { 00438 if (strcmp(listp->module_name, module_name) == 0) { 00439 DEBUGMSGTL(("mib_init", "skipping: %s\n", 00440 module_name)); 00441 return DONT_INITIALIZE; 00442 } 00443 listp = listp->next; 00444 } 00445 } 00446 DEBUGMSGTL(("mib_init", "initializing: %s\n", module_name)); 00447 00448 /* 00449 * initialize it 00450 */ 00451 return DO_INITIALIZE; 00452 }
Last modified: Wednesday, 01-Aug-2018 04:41:28 UTC
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.