1 //==========================================================================
3 // ./agent/current/src/mibgroup/mibII/system_mib.c
6 //==========================================================================
7 //####ECOSGPLCOPYRIGHTBEGIN####
8 // -------------------------------------------
9 // This file is part of eCos, the Embedded Configurable Operating System.
10 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // eCos is free software; you can redistribute it and/or modify it under
13 // the terms of the GNU General Public License as published by the Free
14 // Software Foundation; either version 2 or (at your option) any later version.
16 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 // You should have received a copy of the GNU General Public License along
22 // with eCos; if not, write to the Free Software Foundation, Inc.,
23 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 // As a special exception, if other files instantiate templates or use macros
26 // or inline functions from this file, or you compile this file and link it
27 // with other works to produce a work based on this file, this file does not
28 // by itself cause the resulting work to be covered by the GNU General Public
29 // License. However the source code for this file must still be made available
30 // in accordance with section (3) of the GNU General Public License.
32 // This exception does not invalidate any other reasons why a work based on
33 // this file might be covered by the GNU General Public License.
35 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
36 // at http://sources.redhat.com/ecos/ecos-license/
37 // -------------------------------------------
38 //####ECOSGPLCOPYRIGHTEND####
39 //####UCDSNMPCOPYRIGHTBEGIN####
41 // -------------------------------------------
43 // Portions of this software may have been derived from the UCD-SNMP
44 // project, <http://ucd-snmp.ucdavis.edu/> from the University of
45 // California at Davis, which was originally based on the Carnegie Mellon
46 // University SNMP implementation. Portions of this software are therefore
47 // covered by the appropriate copyright disclaimers included herein.
49 // The release used was version 4.1.2 of May 2000. "ucd-snmp-4.1.2"
50 // -------------------------------------------
52 //####UCDSNMPCOPYRIGHTEND####
53 //==========================================================================
54 //#####DESCRIPTIONBEGIN####
59 // Purpose: Port of UCD-SNMP distribution to eCos.
63 //####DESCRIPTIONEND####
65 //==========================================================================
66 /********************************************************************
67 Copyright 1989, 1991, 1992 by Carnegie Mellon University
70 Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
74 Permission to use, copy, modify and distribute this software and its
75 documentation for any purpose and without fee is hereby granted,
76 provided that the above copyright notice appears in all copies and
77 that both that copyright notice and this permission notice appear in
78 supporting documentation, and that the name of CMU and The Regents of
79 the University of California not be used in advertising or publicity
80 pertaining to distribution of the software without specific written
83 CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
84 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
85 WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL CMU OR
86 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
87 INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
88 FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
89 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
90 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
91 *********************************************************************/
93 * System MIB group implementation - system.c
114 #include <sys/time.h>
121 #if HAVE_SYS_UTSNAME_H
122 #include <sys/utsname.h>
125 #if HAVE_NETINET_IN_H
126 #include <netinet/in.h>
134 #include "mibgroup/mibII/system_mib.h"
135 #include "mibgroup/struct.h"
136 #include "mibgroup/util_funcs.h"
137 #include "read_config.h"
138 #include "agent_read_config.h"
140 #include "mibgroup/mibII/sysORTable.h"
143 /*********************
145 * Kernel & interface information,
146 * and internal forward declarations
148 *********************/
150 #define SYS_STRING_LEN 256
151 char version_descr[ SYS_STRING_LEN ] = VERS_DESC;
152 char sysContact[ SYS_STRING_LEN ] = SYS_CONTACT;
153 char sysName[ SYS_STRING_LEN ] = SYS_NAME;
154 char sysLocation[ SYS_STRING_LEN ] = SYS_LOC;
156 char oldversion_descr[ SYS_STRING_LEN ];
157 char oldsysContact[ SYS_STRING_LEN ];
158 char oldsysName[ SYS_STRING_LEN ];
159 char oldsysLocation[ SYS_STRING_LEN ];
162 int sysServicesConfiged=0;
164 extern oid version_id[];
165 extern int version_id_len;
167 extern struct timeval starttime;
169 WriteMethod writeSystem;
170 int header_system(struct variable *,oid *, size_t *, int, size_t *, WriteMethod **);
172 /* snmpd.conf config parsing */
174 void system_parse_config_sysloc(const char *token,
179 if (strlen(cptr) < sizeof(sysLocation)) {
180 strcpy(sysLocation,cptr);
182 sprintf(tmpbuf, "syslocation token too long (must be < %d):\n\t%s",
183 sizeof(sysLocation), cptr);
184 config_perror(tmpbuf);
188 void system_parse_config_sysServices(const char *token, char *cptr)
190 sysServices = atoi(cptr);
191 sysServicesConfiged = 1;
194 void system_parse_config_syscon(const char *token,
199 if (strlen(cptr) < sizeof(sysContact)) {
200 strcpy(sysContact,cptr);
202 sprintf(tmpbuf, "syscontact token too long (must be < %d):\n\t%s",
203 sizeof(sysContact), cptr);
204 config_perror(tmpbuf);
209 /*********************
211 * Initialisation & common implementation functions
213 *********************/
215 /* define the structure we're going to ask the agent to register our
217 struct variable2 system_variables[] = {
218 {VERSION_DESCR, ASN_OCTET_STR, RONLY, var_system, 1, {1}},
219 {VERSIONID, ASN_OBJECT_ID, RONLY, var_system, 1, {2}},
220 {UPTIME, ASN_TIMETICKS, RONLY, var_system, 1, {3}},
221 {SYSCONTACT, ASN_OCTET_STR, RWRITE, var_system, 1, {4}},
222 {SYSTEMNAME, ASN_OCTET_STR, RWRITE, var_system, 1, {5}},
223 {SYSLOCATION, ASN_OCTET_STR, RWRITE, var_system, 1, {6}},
224 {SYSSERVICES, ASN_INTEGER, RONLY, var_system, 1, {7}},
225 {SYSORLASTCHANGE, ASN_TIMETICKS, RONLY, var_system, 1, {8}}
227 /* Define the OID pointer to the top of the mib tree that we're
228 registering underneath */
229 oid system_variables_oid[] = { SNMP_OID_MIB2,1 };
230 oid system_module_oid[] = { SNMP_OID_SNMPMODULES,1 };
231 int system_module_oid_len = sizeof( system_module_oid ) / sizeof( oid );
232 int system_module_count = 0;
234 void init_system_mib(void)
238 struct utsname utsName;
241 sprintf(version_descr, "%s %s %s %s %s", utsName.sysname, utsName.nodename,
242 utsName.release, utsName.version, utsName.machine);
245 struct extensible extmp;
247 /* set default values of system stuff */
248 sprintf(extmp.command,"%s -a",UNAMEPROG);
250 extmp.type = EXECPROC;
252 exec_command(&extmp);
253 strncpy(version_descr,extmp.output, sizeof(version_descr));
254 version_descr[strlen(version_descr)-1] = 0; /* chomp new line */
257 sysServicesConfiged = 1; // May as well return the dummy value
260 #endif // !HAVE_EXECV
261 #endif // !HAVE_UNAME
263 #ifdef HAVE_GETHOSTNAME
264 gethostname(sysName,sizeof(sysName));
267 strncpy(sysName,utsName.nodename,sizeof(sysName));
270 sprintf(extmp.command,"%s -n",UNAMEPROG);
272 extmp.type = EXECPROC;
274 exec_command(&extmp);
275 strncpy(sysName,extmp.output, sizeof(sysName));
276 sysName[strlen(sysName)-1] = 0; /* chomp new line */
277 #endif /* HAVE_EXECV */
278 #endif /* HAVE_UNAME */
279 #endif /* HAVE_GETHOSTNAME */
281 /* register ourselves with the agent to handle our mib tree */
282 REGISTER_MIB("mibII/system", system_variables, variable2, \
283 system_variables_oid);
285 if ( ++system_module_count == 3 )
286 REGISTER_SYSOR_ENTRY( system_module_oid,
287 "The MIB module for SNMPv2 entities");
289 /* register our config handlers */
290 snmpd_register_config_handler("syslocation", system_parse_config_sysloc,
292 snmpd_register_config_handler("syscontact", system_parse_config_syscon,
293 NULL,"contact-name");
294 snmpd_register_config_handler("sysservices", system_parse_config_sysServices,
302 vp IN - pointer to variable entry that points here
303 name IN/OUT - IN/name requested, OUT/name found
304 length IN/OUT - length of IN/OUT oid's
305 exact IN - TRUE if an exact match was requested
306 var_len OUT - length of variable or 0 if function returned
312 header_system(struct variable *vp,
317 WriteMethod **write_method)
319 #define SYSTEM_NAME_LENGTH 8
320 oid newname[MAX_OID_LEN];
323 DEBUGMSGTL(("mibII/system", "var_system: "));
324 DEBUGMSGOID(("mibII/system", name, *length));
325 DEBUGMSG(("mibII/system"," %d\n", exact));
327 memcpy((char *)newname, (char *)vp->name, vp->namelen * sizeof(oid));
328 newname[SYSTEM_NAME_LENGTH] = 0;
329 result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
330 if ((exact && (result != 0)) || (!exact && (result >= 0)))
331 return(MATCH_FAILED);
332 memcpy( (char *)name,(char *)newname, (vp->namelen + 1) * sizeof(oid));
333 *length = vp->namelen + 1;
336 *var_len = sizeof(long); /* default to 'long' results */
337 return(MATCH_SUCCEEDED);
340 /*********************
342 * System specific implementation functions
345 *********************/
347 #ifdef USING_MIBII_SYSORTABLE_MODULE
348 extern struct timeval sysOR_lastchange;
352 var_system(struct variable *vp,
357 WriteMethod **write_method)
360 struct timeval now, diff;
362 if (header_system(vp, name, length, exact, var_len, write_method) == MATCH_FAILED )
367 *var_len = strlen(version_descr);
368 *write_method = writeSystem;
369 return (u_char *)version_descr;
371 *var_len = version_id_len*sizeof(version_id[0]);
372 return (u_char *)version_id;
374 gettimeofday(&now, NULL);
376 now.tv_usec += 1000000L;
377 diff.tv_sec = now.tv_sec - starttime.tv_sec;
378 diff.tv_usec = now.tv_usec - starttime.tv_usec;
379 if (diff.tv_usec > 1000000L){
380 diff.tv_usec -= 1000000L;
383 long_return = ((diff.tv_sec * 100) + (diff.tv_usec / 10000));
384 return ((u_char *) &long_return);
386 *var_len = strlen(sysContact);
387 *write_method = writeSystem;
388 return (u_char *)sysContact;
390 *var_len = strlen(sysName);
391 *write_method = writeSystem;
392 return (u_char *)sysName;
394 *var_len = strlen(sysLocation);
395 *write_method = writeSystem;
396 return (u_char *)sysLocation;
399 if (!sysServicesConfiged)
402 long_return = sysServices;
403 return (u_char *)&long_return;
405 #ifdef USING_MIBII_SYSORTABLE_MODULE
406 case SYSORLASTCHANGE:
407 diff.tv_sec = sysOR_lastchange.tv_sec - 1 - starttime.tv_sec;
409 sysOR_lastchange.tv_usec + 1000000L - starttime.tv_usec;
410 if (diff.tv_usec > 1000000L){
411 diff.tv_usec -= 1000000L;
414 if ((diff.tv_sec * 100) + (diff.tv_usec / 10000) < 0)
417 long_return = ((diff.tv_sec * 100) + (diff.tv_usec / 10000));
418 return ((u_char *) &long_return);
422 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_system\n", vp->magic));
430 writeSystem(int action,
439 char *buf = NULL, *oldbuf = NULL;
442 switch((char)name[7]){
445 oldbuf = oldversion_descr;
449 oldbuf = oldsysContact;
457 oldbuf = oldsysLocation;
460 return SNMP_ERR_GENERR; /* ??? */
464 case RESERVE1: /* Check values for acceptability */
465 if (var_val_type != ASN_OCTET_STR){
466 snmp_log(LOG_ERR, "not string\n");
467 return SNMP_ERR_WRONGTYPE;
469 if (var_val_len > sizeof(version_descr)-1){
470 snmp_log(LOG_ERR, "bad length\n");
471 return SNMP_ERR_WRONGLENGTH;
474 for(cp = var_val, count = 0; count < (int)var_val_len; count++, cp++){
476 snmp_log(LOG_ERR, "not print %x\n", *cp);
477 return SNMP_ERR_WRONGVALUE;
482 case RESERVE2: /* Allocate memory and similar resources */
484 /* Using static strings, so nothing needs to be done */
487 case ACTION: /* Perform the SET action (if reversible) */
489 /* Save the old value, in case of UNDO */
490 strcpy( oldbuf, buf);
491 memcpy( buf, var_val, var_val_len);
492 buf[var_val_len] = 0;
495 case UNDO: /* Reverse the SET action and free resources */
497 strcpy( buf, oldbuf);
501 case COMMIT: /* Confirm the SET, performing any irreversible actions,
502 and free resources */
503 case FREE: /* Free any resources allocated */
505 /* No resources have been allocated, but "empty" the 'oldbuf' */
509 return SNMP_ERR_NOERROR;
510 } /* end of writeSystem */
512 /*********************
514 * Internal implementation functions - None
516 *********************/