]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/net/snmp/agent/v2_0/src/mibgroup/mibII/system_mib.c
Initial revision
[karo-tx-redboot.git] / packages / net / snmp / agent / v2_0 / src / mibgroup / mibII / system_mib.c
1 //==========================================================================
2 //
3 //      ./agent/current/src/mibgroup/mibII/system_mib.c
4 //
5 //
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.
11 //
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.
15 //
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
19 // for more details.
20 //
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.
24 //
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.
31 //
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.
34 //
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####
40 //
41 // -------------------------------------------
42 //
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.
48 //
49 // The release used was version 4.1.2 of May 2000.  "ucd-snmp-4.1.2"
50 // -------------------------------------------
51 //
52 //####UCDSNMPCOPYRIGHTEND####
53 //==========================================================================
54 //#####DESCRIPTIONBEGIN####
55 //
56 // Author(s):    hmt
57 // Contributors: hmt
58 // Date:         2000-05-30
59 // Purpose:      Port of UCD-SNMP distribution to eCos.
60 // Description:  
61 //              
62 //
63 //####DESCRIPTIONEND####
64 //
65 //==========================================================================
66 /********************************************************************
67        Copyright 1989, 1991, 1992 by Carnegie Mellon University
68
69                           Derivative Work -
70 Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
71
72                          All Rights Reserved
73
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
81 permission.
82
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 *********************************************************************/
92 /*
93  *  System MIB group implementation - system.c
94  *
95  */
96
97 #include <config.h>
98 #if HAVE_STDLIB_H
99 #include <stdlib.h>
100 #endif
101 #if HAVE_UNISTD_H
102 #include <unistd.h>
103 #endif
104 #if HAVE_STRING_H
105 #include <string.h>
106 #else
107 #include <strings.h>
108 #endif
109 #if HAVE_WINSOCK_H
110 #include <winsock.h>
111 #endif
112
113 #if HAVE_SYS_TIME_H
114 #include <sys/time.h>
115 #endif
116
117 #include <ctype.h>
118 #if HAVE_UTSNAME_H
119 #include <utsname.h>
120 #else
121 #if HAVE_SYS_UTSNAME_H
122 #include <sys/utsname.h>
123 #endif
124 #endif
125 #if HAVE_NETINET_IN_H
126 #include <netinet/in.h>
127 #endif
128
129 #if HAVE_DMALLOC_H
130 #include <dmalloc.h>
131 #endif
132
133 #include "mibincl.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"
139 #include "system.h"
140 #include "mibgroup/mibII/sysORTable.h"
141
142
143         /*********************
144          *
145          *  Kernel & interface information,
146          *   and internal forward declarations
147          *
148          *********************/
149
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;
155
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 ];
160
161 int sysServices=72;
162 int sysServicesConfiged=0;
163
164 extern oid version_id[];
165 extern int version_id_len;
166
167 extern struct timeval starttime;
168
169 WriteMethod writeSystem;
170 int header_system(struct variable *,oid *, size_t *, int, size_t *, WriteMethod **);
171
172 /* snmpd.conf config parsing */
173
174 void system_parse_config_sysloc(const char *token, 
175                                 char *cptr)
176 {
177   char tmpbuf[1024];
178   
179   if (strlen(cptr) < sizeof(sysLocation)) {
180     strcpy(sysLocation,cptr);
181   } else {
182     sprintf(tmpbuf, "syslocation token too long (must be < %d):\n\t%s",
183                  sizeof(sysLocation), cptr);
184     config_perror(tmpbuf);
185   }
186 }
187
188 void system_parse_config_sysServices(const char *token, char *cptr)
189 {
190   sysServices = atoi(cptr);
191   sysServicesConfiged = 1;
192 }
193
194 void system_parse_config_syscon(const char *token, 
195                                 char *cptr)
196 {
197   char tmpbuf[1024];
198
199   if (strlen(cptr) < sizeof(sysContact)) {
200     strcpy(sysContact,cptr);
201   } else {
202     sprintf(tmpbuf, "syscontact token too long (must be < %d):\n\t%s",
203                  sizeof(sysContact), cptr);
204     config_perror(tmpbuf);
205   }
206 }
207
208
209         /*********************
210          *
211          *  Initialisation & common implementation functions
212          *
213          *********************/
214
215 /* define the structure we're going to ask the agent to register our
216    information at */
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}}
226 };
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;
233
234 void init_system_mib(void)
235 {
236
237 #ifdef HAVE_UNAME
238   struct utsname utsName;
239
240   uname(&utsName);
241   sprintf(version_descr, "%s %s %s %s %s", utsName.sysname, utsName.nodename,
242           utsName.release, utsName.version, utsName.machine);
243 #else
244 #if HAVE_EXECV
245   struct extensible extmp;
246
247   /* set default values of system stuff */
248   sprintf(extmp.command,"%s -a",UNAMEPROG);
249   /* setup defaults */
250   extmp.type = EXECPROC;
251   extmp.next = NULL;
252   exec_command(&extmp);
253   strncpy(version_descr,extmp.output, sizeof(version_descr));
254   version_descr[strlen(version_descr)-1] = 0; /* chomp new line */
255 #else
256 #ifdef __ECOS
257   sysServicesConfiged = 1; // May as well return the dummy value
258 #else
259 #endif // !__ECOS
260 #endif // !HAVE_EXECV
261 #endif // !HAVE_UNAME
262
263 #ifdef HAVE_GETHOSTNAME
264   gethostname(sysName,sizeof(sysName));
265 #else
266 #ifdef HAVE_UNAME
267   strncpy(sysName,utsName.nodename,sizeof(sysName));
268 #else
269 #if HAVE_EXECV
270   sprintf(extmp.command,"%s -n",UNAMEPROG);
271   /* setup defaults */
272   extmp.type = EXECPROC;
273   extmp.next = NULL;
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 */
280
281   /* register ourselves with the agent to handle our mib tree */
282   REGISTER_MIB("mibII/system", system_variables, variable2, \
283                system_variables_oid);
284
285   if ( ++system_module_count == 3 )
286         REGISTER_SYSOR_ENTRY( system_module_oid,
287                 "The MIB module for SNMPv2 entities");
288   
289   /* register our config handlers */
290   snmpd_register_config_handler("syslocation", system_parse_config_sysloc,
291                                 NULL, "location");
292   snmpd_register_config_handler("syscontact", system_parse_config_syscon,
293                                 NULL,"contact-name");
294   snmpd_register_config_handler("sysservices", system_parse_config_sysServices,
295                                 NULL,"NUMBER");
296
297 }
298
299 /*
300   header_system(...
301   Arguments:
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
307   write_method
308   
309 */
310
311 int
312 header_system(struct variable *vp,
313               oid *name,
314               size_t *length,
315               int exact,
316               size_t *var_len,
317               WriteMethod **write_method)
318 {
319 #define SYSTEM_NAME_LENGTH      8
320     oid newname[MAX_OID_LEN];
321     int result;
322
323     DEBUGMSGTL(("mibII/system", "var_system: "));
324     DEBUGMSGOID(("mibII/system", name, *length));
325     DEBUGMSG(("mibII/system"," %d\n", exact));
326
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;
334
335     *write_method = 0;
336     *var_len = sizeof(long);    /* default to 'long' results */
337     return(MATCH_SUCCEEDED);
338 }
339
340         /*********************
341          *
342          *  System specific implementation functions
343          *      (actually common!)
344          *
345          *********************/
346
347 #ifdef USING_MIBII_SYSORTABLE_MODULE
348 extern struct timeval sysOR_lastchange;
349 #endif
350
351 u_char  *
352 var_system(struct variable *vp,
353            oid *name,
354            size_t *length,
355            int exact,
356            size_t *var_len,
357            WriteMethod **write_method)
358 {
359
360   struct timeval now, diff;
361
362     if (header_system(vp, name, length, exact, var_len, write_method) == MATCH_FAILED )
363         return NULL;
364
365     switch (vp->magic){
366         case VERSION_DESCR:
367             *var_len = strlen(version_descr);
368             *write_method = writeSystem;
369             return (u_char *)version_descr;
370         case VERSIONID:
371             *var_len = version_id_len*sizeof(version_id[0]);
372             return (u_char *)version_id;
373         case UPTIME:
374             gettimeofday(&now, NULL);
375             now.tv_sec--;
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;
381                 diff.tv_sec++;
382             }
383             long_return = ((diff.tv_sec * 100) + (diff.tv_usec / 10000));
384             return ((u_char *) &long_return);
385         case SYSCONTACT:
386             *var_len = strlen(sysContact);
387             *write_method = writeSystem;
388             return (u_char *)sysContact;
389         case SYSTEMNAME:
390             *var_len = strlen(sysName);
391             *write_method = writeSystem;
392             return (u_char *)sysName;
393         case SYSLOCATION:
394             *var_len = strlen(sysLocation);
395             *write_method = writeSystem;
396             return (u_char *)sysLocation;
397         case SYSSERVICES:
398 #if NO_DUMMY_VALUES
399             if (!sysServicesConfiged)
400                 return NULL;
401 #endif
402             long_return = sysServices;
403             return (u_char *)&long_return;
404
405 #ifdef USING_MIBII_SYSORTABLE_MODULE
406         case SYSORLASTCHANGE:
407               diff.tv_sec = sysOR_lastchange.tv_sec - 1 - starttime.tv_sec;
408               diff.tv_usec =
409                 sysOR_lastchange.tv_usec + 1000000L - starttime.tv_usec;
410               if (diff.tv_usec > 1000000L){
411                 diff.tv_usec -= 1000000L;
412                 diff.tv_sec++;
413               }
414               if ((diff.tv_sec * 100) + (diff.tv_usec / 10000) < 0)
415                 long_return = 0;
416               else
417                 long_return = ((diff.tv_sec * 100) + (diff.tv_usec / 10000));
418               return ((u_char *) &long_return);
419 #endif
420               
421         default:
422             DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_system\n", vp->magic));
423     }
424     return NULL;
425 }
426
427
428
429 int
430 writeSystem(int action,      
431             u_char *var_val,
432             u_char var_val_type,
433             size_t var_val_len,
434             u_char *statP,
435             oid *name,
436             size_t name_len)
437 {
438     u_char *cp;
439     char *buf = NULL, *oldbuf = NULL;
440     int count;
441
442     switch((char)name[7]){
443       case VERSION_DESCR:
444         buf    = version_descr;
445         oldbuf = oldversion_descr;
446         break;
447       case SYSCONTACT:
448         buf    = sysContact;
449         oldbuf = oldsysContact;
450         break;
451       case SYSTEMNAME:
452         buf    = sysName;
453         oldbuf = oldsysName;
454         break;
455       case SYSLOCATION:
456         buf    = sysLocation;
457         oldbuf = oldsysLocation;
458         break;
459       default:
460         return SNMP_ERR_GENERR;         /* ??? */
461     }
462
463     switch ( action ) {
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;
468             }
469             if (var_val_len > sizeof(version_descr)-1){
470                 snmp_log(LOG_ERR, "bad length\n");
471                 return SNMP_ERR_WRONGLENGTH;
472             }
473             
474             for(cp = var_val, count = 0; count < (int)var_val_len; count++, cp++){
475                 if (!isprint(*cp)){
476                     snmp_log(LOG_ERR, "not print %x\n", *cp);
477                     return SNMP_ERR_WRONGVALUE;
478                 }
479             }
480             break;
481
482         case RESERVE2:          /* Allocate memory and similar resources */
483
484                 /* Using static strings, so nothing needs to be done */
485             break;
486
487         case ACTION:            /* Perform the SET action (if reversible) */
488
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;
493             break;
494
495         case UNDO:              /* Reverse the SET action and free resources */
496
497             strcpy( buf, oldbuf);
498             oldbuf[0] = 0;
499             break;
500
501         case COMMIT:            /* Confirm the SET, performing any irreversible actions,
502                                         and free resources */
503         case FREE:              /* Free any resources allocated */
504
505                 /* No resources have been allocated, but "empty" the 'oldbuf' */
506             oldbuf[0] = 0;
507             break;
508     }
509     return SNMP_ERR_NOERROR;
510 } /* end of writeSystem */
511
512         /*********************
513          *
514          *  Internal implementation functions - None
515          *
516          *********************/
517