added files
[bcm963xx.git] / userapps / opensource / net-snmp / agent / mibgroup / host / hr_storage.c
1 /*
2  *  Host Resources MIB - storage group implementation - hr_storage.c
3  *
4  */
5
6 #include <net-snmp/net-snmp-config.h>
7 #include <sys/types.h>
8 #include <sys/param.h>
9 #if HAVE_UNISTD_H
10 #include <unistd.h>
11 #endif
12 #if TIME_WITH_SYS_TIME
13 # ifdef WIN32
14 #  include <sys/timeb.h>
15 # else
16 #  include <sys/time.h>
17 # endif
18 # include <time.h>
19 #else
20 # if HAVE_SYS_TIME_H
21 #  include <sys/time.h>
22 # else
23 #  include <time.h>
24 # endif
25 #endif
26 #ifndef dynix
27 #if HAVE_SYS_VM_H
28 #include <sys/vm.h>
29 #if (!defined(KERNEL) || defined(MACH_USER_API)) && defined(HAVE_SYS_VMMETER_H) /*OS X does not #include <sys/vmmeter.h> if (defined(KERNEL) && !defined(MACH_USER_API)) */
30 #include <sys/vmmeter.h>
31 #endif
32 #else
33 #if HAVE_VM_VM_H
34 #include <vm/vm.h>
35 #if HAVE_MACHINE_TYPES_H
36 #include <machine/types.h>
37 #endif
38 #if HAVE_SYS_VMMETER_H
39 #include <sys/vmmeter.h>
40 #endif
41 #if HAVE_VM_VM_PARAM_H
42 #include <vm/vm_param.h>
43 #endif
44 #else
45 #if HAVE_SYS_VMPARAM_H
46 #include <sys/vmparam.h>
47 #endif
48 #if HAVE_SYS_VMMAC_H
49 #include <sys/vmmac.h>
50 #endif
51 #if HAVE_SYS_VMMETER_H
52 #include <sys/vmmeter.h>
53 #endif
54 #if HAVE_SYS_VMSYSTM_H
55 #include <sys/vmsystm.h>
56 #endif
57 #endif                          /* vm/vm.h */
58 #endif                          /* sys/vm.h */
59 #if HAVE_SYS_POOL_H
60 #if defined(MBPOOL_SYMBOL) && defined(MCLPOOL_SYMBOL)
61 #define __POOL_EXPOSE
62 #include <sys/pool.h>
63 #else
64 #undef HAVE_SYS_POOL_H
65 #endif
66 #endif
67 #if HAVE_SYS_MBUF_H
68 #include <sys/mbuf.h>
69 #endif
70 #if HAVE_SYS_SYSCTL_H
71 #include <sys/sysctl.h>
72 #if defined(CTL_HW) && defined(HW_PAGESIZE)
73 #define USE_SYSCTL
74 #endif
75 #if defined(CTL_VM) && defined(VM_METER)
76 #define USE_SYSCTL_VM
77 #endif
78 #endif
79 #endif                          /* ifndef dynix */
80
81 #include "host_res.h"
82 #include "hr_storage.h"
83 #include "hr_filesys.h"
84 #include <net-snmp/agent/auto_nlist.h>
85
86 #if HAVE_MNTENT_H
87 #include <mntent.h>
88 #endif
89 #if HAVE_SYS_MNTTAB_H
90 #include <sys/mnttab.h>
91 #endif
92 #if HAVE_SYS_STATVFS_H
93 #include <sys/statvfs.h>
94 #endif
95 #if HAVE_SYS_VFS_H
96 #include <sys/vfs.h>
97 #endif
98 #if HAVE_SYS_MOUNT_H
99 #ifdef __osf__
100 #undef m_next
101 #undef m_data
102 #endif
103 #include <sys/mount.h>
104 #endif
105 #ifdef HAVE_MACHINE_PARAM_H
106 #include <machine/param.h>
107 #endif
108 #include <sys/stat.h>
109
110 #if defined(hpux10) || defined(hpux11)
111 #include <sys/pstat.h>
112 #endif
113 #if defined(solaris2)
114 #if HAVE_SYS_SWAP_H
115 #include <sys/swap.h>
116 #endif
117 #endif
118
119 #if HAVE_STRING_H
120 #include <string.h>
121 #else
122 #include <strings.h>
123 #endif
124
125 #include <net-snmp/utilities.h>
126 #include <net-snmp/output_api.h>
127
128 #if solaris2
129 #include "kernel_sunos5.h"
130 #endif
131
132 #include <net-snmp/agent/agent_read_config.h>
133 #include <net-snmp/library/read_config.h>
134
135 #define HRSTORE_MONOTONICALLY_INCREASING
136
137         /*********************
138          *
139          *  Kernel & interface information,
140          *   and internal forward declarations
141          *
142          *********************/
143
144
145 #ifdef solaris2
146
147 extern struct mnttab *HRFS_entry;
148 #define HRFS_mount      mnt_mountp
149 #define HRFS_statfs     statvfs
150
151 #elif defined(HAVE_STATVFS)
152
153 extern struct mntent *HRFS_entry;
154 extern int      fscount;
155 #define HRFS_statfs     statvfs
156 #define HRFS_mount      mnt_dir
157
158 #elif defined(HAVE_GETFSSTAT)
159
160 extern struct statfs *HRFS_entry;
161 extern int      fscount;
162 #define HRFS_statfs     statfs
163 #define HRFS_mount      f_mntonname
164
165 #else
166
167 extern struct mntent *HRFS_entry;
168 #define HRFS_mount      mnt_dir
169 #define HRFS_statfs     statfs
170
171 #endif
172
173 static int      physmem, pagesize;
174 static void parse_storage_config(const char *, char *);
175
176         /*********************
177          *
178          *  Initialisation & common implementation functions
179          *
180          *********************/
181 int             Get_Next_HR_Store(void);
182 void            Init_HR_Store(void);
183 int             header_hrstore(struct variable *, oid *, size_t *, int,
184                                size_t *, WriteMethod **);
185 int             header_hrstoreEntry(struct variable *, oid *, size_t *,
186                                     int, size_t *, WriteMethod **);
187
188 #ifdef linux
189 int             linux_mem(int, int);
190 #endif
191
192 #ifdef solaris2
193 void            sol_get_swapinfo(int *, int *);
194 #endif
195
196 #define HRSTORE_MEMSIZE         1
197 #define HRSTORE_INDEX           2
198 #define HRSTORE_TYPE            3
199 #define HRSTORE_DESCR           4
200 #define HRSTORE_UNITS           5
201 #define HRSTORE_SIZE            6
202 #define HRSTORE_USED            7
203 #define HRSTORE_FAILS           8
204
205 struct variable4 hrstore_variables[] = {
206     {HRSTORE_MEMSIZE, ASN_INTEGER, RONLY, var_hrstore, 1, {2}},
207     {HRSTORE_INDEX, ASN_INTEGER, RONLY, var_hrstore, 3, {3, 1, 1}},
208     {HRSTORE_TYPE, ASN_OBJECT_ID, RONLY, var_hrstore, 3, {3, 1, 2}},
209     {HRSTORE_DESCR, ASN_OCTET_STR, RONLY, var_hrstore, 3, {3, 1, 3}},
210     {HRSTORE_UNITS, ASN_INTEGER, RONLY, var_hrstore, 3, {3, 1, 4}},
211     {HRSTORE_SIZE, ASN_INTEGER, RONLY, var_hrstore, 3, {3, 1, 5}},
212     {HRSTORE_USED, ASN_INTEGER, RONLY, var_hrstore, 3, {3, 1, 6}},
213     {HRSTORE_FAILS, ASN_COUNTER, RONLY, var_hrstore, 3, {3, 1, 7}}
214 };
215 oid             hrstore_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 2 };
216
217
218 void
219 init_hr_storage(void)
220 {
221 #ifdef USE_SYSCTL
222     int             mib[2];
223     size_t          len;
224 #elif defined(hpux10) || defined(hpux11)
225     struct pst_static pst_buf;
226 #endif
227
228 #ifdef USE_SYSCTL
229     mib[0] = CTL_HW;
230     mib[1] = HW_PHYSMEM;
231     len = sizeof(physmem);
232     if (sysctl(mib, 2, &physmem, &len, NULL, 0) == -1)
233         snmp_log_perror("sysctl: physmem");
234     mib[1] = HW_PAGESIZE;
235     len = sizeof(pagesize);
236     if (sysctl(mib, 2, &pagesize, &len, NULL, 0) == -1)
237         snmp_log_perror("sysctl: pagesize");
238     physmem /= pagesize;
239 #elif defined(hpux10) || defined(hpux11)
240     if (pstat_getstatic(&pst_buf, sizeof(struct pst_static), 1, 0) < 0) {
241         perror("pstat_getstatic");
242     } else {
243         physmem = pst_buf.physical_memory;
244         pagesize = pst_buf.page_size;
245     }
246 #else                           /* !USE_SYSCTL && !hpux10 && !hpux11 */
247 #ifdef HAVE_GETPAGESIZE
248     pagesize = getpagesize();
249 #elif defined(_SC_PAGESIZE)
250     pagesize = sysconf(_SC_PAGESIZE);
251 #elif defined(PGSHIFT)
252     pagesize = 1 << PGSHIFT;
253 #elif defined(PAGE_SHIFT)
254     pagesize = 1 << PAGE_SHIFT;
255 #elif defined(PAGE_SIZE)
256     pagesize = PAGE_SIZE;
257 #elif defined(linux)
258     {
259         struct stat     kc_buf;
260         stat("/proc/kcore", &kc_buf);
261         pagesize = kc_buf.st_size / 1024;       /* 4K too large ? */
262     }
263 #else
264     pagesize = PAGESIZE;
265 #endif
266 #ifdef _SC_PHYS_PAGES
267     physmem = sysconf(_SC_PHYS_PAGES);
268 #else
269 #ifdef dynix
270     physmem = sysconf(_SC_PHYSMEM);
271 #else
272     auto_nlist(PHYSMEM_SYMBOL, (char *) &physmem, sizeof(physmem));
273 #endif
274 #endif
275 #endif                          /* !USE_SYSCTL && !hpux10 && !hpux11 */
276 #ifdef TOTAL_MEMORY_SYMBOL
277     auto_nlist(TOTAL_MEMORY_SYMBOL, 0, 0);
278 #endif
279 #ifdef MBSTAT_SYMBOL
280     auto_nlist(MBSTAT_SYMBOL, 0, 0);
281 #endif
282
283     REGISTER_MIB("host/hr_storage", hrstore_variables, variable4,
284                  hrstore_variables_oid);
285
286     snmpd_register_config_handler("storageUseNFS", parse_storage_config, NULL,
287         "1 | 2\t\t(1 = enable, 2 = disable)");
288 }
289
290 static int storageUseNFS = 0;   /* initially disabled */
291
292 static void
293 parse_storage_config(const char *token, char *cptr)
294 {
295     char *val;
296     int ival;
297
298     val = strtok(cptr, " \t");
299     if (!val) {
300         config_perror("Missing FLAG parameter in storageUseNFS");
301         return;
302     }
303     ival = atoi(val);
304     if (ival < 1 || ival > 2) {
305         config_perror("storageUseNFS must be 1 or 2");
306         return;
307     }
308     storageUseNFS = (ival == 1) ? 1 : 0;
309 }
310
311 /*
312  * header_hrstore(...
313  * Arguments:
314  * vp     IN      - pointer to variable entry that points here
315  * name    IN/OUT  - IN/name requested, OUT/name found
316  * length  IN/OUT  - length of IN/OUT oid's 
317  * exact   IN      - TRUE if an exact match was requested
318  * var_len OUT     - length of variable or 0 if function returned
319  * write_method
320  * 
321  */
322
323 int
324 header_hrstore(struct variable *vp,
325                oid * name,
326                size_t * length,
327                int exact, size_t * var_len, WriteMethod ** write_method)
328 {
329 #define HRSTORE_NAME_LENGTH     9
330     oid             newname[MAX_OID_LEN];
331     int             result;
332
333     DEBUGMSGTL(("host/hr_storage", "var_hrstore: "));
334     DEBUGMSGOID(("host/hr_storage", name, *length));
335     DEBUGMSG(("host/hr_storage", " %d\n", exact));
336
337     memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
338     newname[HRSTORE_NAME_LENGTH] = 0;
339     result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
340     if ((exact && (result != 0)) || (!exact && (result >= 0)))
341         return (MATCH_FAILED);
342     memcpy((char *) name, (char *) newname,
343            (vp->namelen + 1) * sizeof(oid));
344     *length = vp->namelen + 1;
345
346     *write_method = 0;
347     *var_len = sizeof(long);    /* default to 'long' results */
348     return (MATCH_SUCCEEDED);
349 }
350
351 int
352 header_hrstoreEntry(struct variable *vp,
353                     oid * name,
354                     size_t * length,
355                     int exact,
356                     size_t * var_len, WriteMethod ** write_method)
357 {
358 #define HRSTORE_ENTRY_NAME_LENGTH       11
359     oid             newname[MAX_OID_LEN];
360     int             storage_idx, LowIndex = -1;
361     int             result;
362
363     DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: "));
364     DEBUGMSGOID(("host/hr_storage", name, *length));
365     DEBUGMSG(("host/hr_storage", " %d\n", exact));
366
367     memcpy((char *) newname, (char *) vp->name,
368            (int) vp->namelen * sizeof(oid));
369     /*
370      * Find "next" storage entry 
371      */
372
373     Init_HR_Store();
374     for (;;) {
375         storage_idx = Get_Next_HR_Store();
376         DEBUGMSG(("host/hr_storage", "(index %d ....", storage_idx));
377         if (storage_idx == -1)
378             break;
379         newname[HRSTORE_ENTRY_NAME_LENGTH] = storage_idx;
380         DEBUGMSGOID(("host/hr_storage", newname, *length));
381         DEBUGMSG(("host/hr_storage", "\n"));
382         result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
383         if (exact && (result == 0)) {
384             LowIndex = storage_idx;
385             /*
386              * Save storage status information 
387              */
388             break;
389         }
390         if ((!exact && (result < 0)) &&
391             (LowIndex == -1 || storage_idx < LowIndex)) {
392             LowIndex = storage_idx;
393             /*
394              * Save storage status information 
395              */
396 #ifdef HRSTORE_MONOTONICALLY_INCREASING
397             break;
398 #endif
399         }
400     }
401
402     if (LowIndex == -1) {
403         DEBUGMSGTL(("host/hr_storage", "... index out of range\n"));
404         return (MATCH_FAILED);
405     }
406
407     memcpy((char *) name, (char *) newname,
408            ((int) vp->namelen + 1) * sizeof(oid));
409     *length = vp->namelen + 1;
410     *write_method = 0;
411     *var_len = sizeof(long);    /* default to 'long' results */
412
413     DEBUGMSGTL(("host/hr_storage", "... get storage stats "));
414     DEBUGMSGOID(("host/hr_storage", name, *length));
415     DEBUGMSG(("host/hr_storage", "\n"));
416     return LowIndex;
417 }
418
419 oid             storage_type_id[] = { 1, 3, 6, 1, 2, 1, 25, 2, 1, 1 };  /* hrStorageOther */
420 int             storage_type_len =
421     sizeof(storage_type_id) / sizeof(storage_type_id[0]);
422
423         /*********************
424          *
425          *  System specific implementation functions
426          *
427          *********************/
428
429 static const char *hrs_descr[] = {
430     NULL,
431     "Real Memory",              /* HRS_TYPE_MEM */
432     "Swap Space",               /* HRS_TYPE_SWAP */
433     "Memory Buffers"            /* HRS_TYPE_MBUF */
434 };
435
436
437
438 u_char         *
439 var_hrstore(struct variable *vp,
440             oid * name,
441             size_t * length,
442             int exact, size_t * var_len, WriteMethod ** write_method)
443 {
444     int             store_idx = 0;
445 #if !defined(linux)
446 #if defined(solaris2)
447     int             freemem;
448     int             swap_total, swap_used;
449 #elif defined(hpux10) || defined(hpux11)
450     struct pst_dynamic pst_buf;
451 #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM)
452     struct vmtotal  memory_totals;
453 #endif
454 #if HAVE_SYS_POOL_H
455     struct pool     mbpool, mclpool;
456     int             i;
457 #endif
458 #ifdef MBSTAT_SYMBOL
459     struct mbstat   mbstat;
460 #endif
461 #endif                          /* !linux */
462     static char     string[100];
463     struct HRFS_statfs stat_buf;
464
465     if (vp->magic == HRSTORE_MEMSIZE) {
466         if (header_hrstore(vp, name, length, exact, var_len, write_method)
467             == MATCH_FAILED)
468             return NULL;
469     } else {
470
471         store_idx =
472             header_hrstoreEntry(vp, name, length, exact, var_len,
473                                 write_method);
474         if (store_idx == MATCH_FAILED)
475             return NULL;
476
477         if (store_idx < HRS_TYPE_FS_MAX) {
478             if (HRFS_statfs(HRFS_entry->HRFS_mount, &stat_buf) < 0)
479                 return NULL;
480         }
481 #if !defined(linux) && !defined(solaris2)
482         else
483             switch (store_idx) {
484             case HRS_TYPE_MEM:
485             case HRS_TYPE_SWAP:
486 #ifdef USE_SYSCTL_VM
487                 {
488                     int             mib[2];
489                     size_t          len = sizeof(memory_totals);
490                     mib[0] = CTL_VM;
491                     mib[1] = VM_METER;
492                     sysctl(mib, 2, &memory_totals, &len, NULL, 0);
493                 }
494 #elif defined(hpux10) || defined(hpux11)
495                 pstat_getdynamic(&pst_buf, sizeof(struct pst_dynamic), 1, 0);
496 #elif defined(TOTAL_MEMORY_SYMBOL)
497                 auto_nlist(TOTAL_MEMORY_SYMBOL, (char *) &memory_totals,
498                            sizeof(struct vmtotal));
499 #endif
500                 break;
501 #if !defined(hpux10) && !defined(hpux11)
502             case HRS_TYPE_MBUF:
503 #if HAVE_SYS_POOL_H
504                 auto_nlist(MBPOOL_SYMBOL, (char *) &mbpool,
505                            sizeof(mbpool));
506                 auto_nlist(MCLPOOL_SYMBOL, (char *) &mclpool,
507                            sizeof(mclpool));
508 #endif
509 #ifdef MBSTAT_SYMBOL
510                 auto_nlist(MBSTAT_SYMBOL, (char *) &mbstat,
511                            sizeof(mbstat));
512 #endif
513                 break;
514 #endif      /* !hpux10 && !hpux11 */
515             default:
516                 break;
517             }
518 #endif                          /* !linux && !solaris2 */
519     }
520
521
522
523     switch (vp->magic) {
524     case HRSTORE_MEMSIZE:
525         long_return = physmem * (pagesize / 1024);
526         return (u_char *) & long_return;
527
528     case HRSTORE_INDEX:
529         long_return = store_idx;
530         return (u_char *) & long_return;
531     case HRSTORE_TYPE:
532         if (store_idx < HRS_TYPE_FS_MAX)
533             if (storageUseNFS && Check_HR_FileSys_NFS())
534                 storage_type_id[storage_type_len - 1] = 10;     /* Network Disk */
535             else
536                 storage_type_id[storage_type_len - 1] = 4;      /* Assume fixed */
537         else
538             switch (store_idx) {
539             case HRS_TYPE_MEM:
540                 storage_type_id[storage_type_len - 1] = 2;      /* RAM */
541                 break;
542             case HRS_TYPE_SWAP:
543                 storage_type_id[storage_type_len - 1] = 3;      /* Virtual Mem */
544                 break;
545             case HRS_TYPE_MBUF:
546                 storage_type_id[storage_type_len - 1] = 1;      /* Other */
547                 break;
548             default:
549                 storage_type_id[storage_type_len - 1] = 1;      /* Other */
550                 break;
551             }
552         *var_len = sizeof(storage_type_id);
553         return (u_char *) storage_type_id;
554     case HRSTORE_DESCR:
555         if (store_idx < HRS_TYPE_FS_MAX) {
556             strncpy(string, HRFS_entry->HRFS_mount, sizeof(string)-1);
557             string[ sizeof(string)-1 ] = 0;
558             *var_len = strlen(string);
559             return (u_char *) string;
560         } else {
561             store_idx = store_idx - HRS_TYPE_FS_MAX;
562             *var_len = strlen(hrs_descr[store_idx]);
563             return (u_char *) hrs_descr[store_idx];
564         }
565     case HRSTORE_UNITS:
566         if (store_idx < HRS_TYPE_FS_MAX)
567 #if STRUCT_STATVFS_HAS_F_FRSIZE
568             long_return = stat_buf.f_frsize;
569 #else
570             long_return = stat_buf.f_bsize;
571 #endif
572         else
573             switch (store_idx) {
574             case HRS_TYPE_MEM:
575             case HRS_TYPE_SWAP:
576 #if defined(USE_SYSCTL) || defined(solaris2)
577                 long_return = pagesize;
578 #elif defined(NBPG)
579                 long_return = NBPG;
580 #else
581                 long_return = 1024;     /* Report in Kb */
582 #endif
583                 break;
584             case HRS_TYPE_MBUF:
585 #ifdef MSIZE
586                 long_return = MSIZE;
587 #else
588                 long_return = 256;
589 #endif
590                 break;
591             default:
592 #if NO_DUMMY_VALUES
593                 return NULL;
594 #endif
595                 long_return = 1024;     /* As likely as any! */
596                 break;
597             }
598         return (u_char *) & long_return;
599     case HRSTORE_SIZE:
600         if (store_idx < HRS_TYPE_FS_MAX)
601             long_return = stat_buf.f_blocks;
602         else
603             switch (store_idx) {
604 #if defined(linux)
605             case HRS_TYPE_MEM:
606             case HRS_TYPE_SWAP:
607                 long_return = linux_mem(store_idx, HRSTORE_SIZE);
608                 break;
609 #elif defined(solaris2)
610             case HRS_TYPE_MEM:
611                 long_return = physmem;
612                 break;
613             case HRS_TYPE_SWAP:
614                 sol_get_swapinfo(&swap_total, &swap_used);
615                 long_return = swap_total;
616                 break;
617 #elif defined(hpux10) || defined(hpux11)
618             case HRS_TYPE_MEM:
619                 long_return = pst_buf.psd_rm;
620                 break;
621             case HRS_TYPE_SWAP:
622                 long_return = pst_buf.psd_vm;
623                 break;
624 #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM)
625             case HRS_TYPE_MEM:
626                 long_return = memory_totals.t_rm;
627                 break;
628             case HRS_TYPE_SWAP:
629                 long_return = memory_totals.t_vm;
630                 break;
631 #else               /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */
632             case HRS_TYPE_MEM:
633                 long_return = physmem;
634                 break;
635             case HRS_TYPE_SWAP:
636 #if NO_DUMMY_VALUES
637                 return NULL;
638 #endif
639                 long_return = 0;
640                 break;
641             case HRS_TYPE_MBUF:
642 #if HAVE_SYS_POOL_H
643                 long_return = 0;
644                 for (i = 0;
645                      i <
646                      sizeof(mbstat.m_mtypes) / sizeof(mbstat.m_mtypes[0]);
647                      i++)
648                     long_return += mbstat.m_mtypes[i];
649 #elif defined(MBSTAT_SYMBOL)
650                 long_return = mbstat.m_mbufs;
651 #elif defined(NO_DUMMY_VALUES)
652                 return NULL;
653 #else
654                 long_return = 0;
655 #endif
656                 break;
657 #endif              /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */
658             default:
659 #if NO_DUMMY_VALUES
660                 return NULL;
661 #endif
662                 long_return = 1024;
663                 break;
664             }
665         return (u_char *) & long_return;
666     case HRSTORE_USED:
667         if (store_idx < HRS_TYPE_FS_MAX)
668             long_return = (stat_buf.f_blocks - stat_buf.f_bfree);
669         else
670             switch (store_idx) {
671 #if defined(linux)
672             case HRS_TYPE_MEM:
673             case HRS_TYPE_SWAP:
674                 long_return = linux_mem(store_idx, HRSTORE_USED);
675                 break;
676 #elif defined(solaris2)
677             case HRS_TYPE_MEM:
678                 getKstatInt("unix", "system_pages", "freemem", &freemem);
679                 long_return = physmem - freemem;
680                 break;
681             case HRS_TYPE_SWAP:
682                 sol_get_swapinfo(&swap_total, &swap_used);
683                 long_return = swap_used;
684                 break;
685 #elif defined(hpux10) || defined(hpux11)
686             case HRS_TYPE_MEM:
687                 long_return = pst_buf.psd_arm;
688                 break;
689             case HRS_TYPE_SWAP:
690                 long_return = pst_buf.psd_avm;
691                 break;
692 #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM)
693             case HRS_TYPE_MEM:
694                 long_return = memory_totals.t_arm;
695                 break;
696             case HRS_TYPE_SWAP:
697                 long_return = memory_totals.t_avm;
698                 break;
699 #endif              /* linux || solaris2 || hpux10 || hpux11 || ... */
700
701 #if !defined(linux) && !defined(solaris2) && !defined(hpux10) && !defined(hpux11)
702             case HRS_TYPE_MBUF:
703 #if HAVE_SYS_POOL_H
704                 long_return = (mbpool.pr_nget - mbpool.pr_nput)
705                     * mbpool.pr_size + (mclpool.pr_nget - mclpool.pr_nput)
706                     * mclpool.pr_size;
707 #elif defined(MBSTAT_SYMBOL)
708                 long_return = mbstat.m_clusters - mbstat.m_clfree;      /* unlikely, but... */
709 #elif defined(NO_DUMMY_VALUES)
710                 return NULL;
711 #else
712                 long_return = 0;
713 #endif
714                 break;
715 #endif                      /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */
716             default:
717 #if NO_DUMMY_VALUES
718                 return NULL;
719 #endif
720                 long_return = 1024;
721                 break;
722             }
723         return (u_char *) & long_return;
724     case HRSTORE_FAILS:
725         if (store_idx < HRS_TYPE_FS_MAX)
726             long_return = 0;
727         else
728             switch (store_idx) {
729             case HRS_TYPE_MEM:
730             case HRS_TYPE_SWAP:
731 #if NO_DUMMY_VALUES
732                 return NULL;
733 #endif
734                 long_return = 0;
735                 break;
736 #if !defined(linux) && !defined(solaris2) && !defined(hpux10) && !defined(hpux11)  && defined(MBSTAT_SYMBOL)
737             case HRS_TYPE_MBUF:
738                 long_return = mbstat.m_drops;
739                 break;
740 #endif                          /* !linux && !solaris2 && !hpux10 && !hpux11 && MBSTAT_SYMBOL */
741             default:
742 #if NO_DUMMY_VALUES
743                 return NULL;
744 #endif
745                 long_return = 0;
746                 break;
747             }
748         return (u_char *) & long_return;
749     default:
750         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrstore\n",
751                     vp->magic));
752     }
753     return NULL;
754 }
755
756
757         /*********************
758          *
759          *  Internal implementation functions
760          *
761          *********************/
762
763 static int      FS_storage;
764 static int      HRS_index;
765
766 void
767 Init_HR_Store(void)
768 {
769     HRS_index = -1;
770     Init_HR_FileSys();
771     FS_storage = 1;             /* Start with file-based storage */
772 }
773
774 int
775 Get_Next_HR_Store(void)
776 {
777     /*
778      * File-based storage 
779      */
780     long_return = -1;
781     if (FS_storage == 1) {
782         HRS_index = Get_Next_HR_FileSys();
783
784         if (HRS_index >= 0)
785             return HRS_index;
786         FS_storage = 0;         /* End of filesystems */
787         HRS_index = HRS_TYPE_FS_MAX;
788     }
789
790     /*
791      * 'Other' storage types 
792      */
793     ++HRS_index;
794 #if !defined(solaris2) && !defined(hpux10) && !defined(hpux11)
795     if (HRS_index < HRS_TYPE_MAX)
796         return HRS_index;
797     else
798 #else
799     if (HRS_index < HRS_TYPE_MBUF)
800         return HRS_index;
801     else
802 #endif
803         return -1;
804 }
805
806 #ifdef linux
807 int
808 linux_mem(int mem_type, int size_or_used)
809 {
810     FILE           *fp;
811     char            buf[100];
812     int             size = -1, used = -1;
813
814     if ((fp = fopen("/proc/meminfo", "r")) == NULL)
815         return -1;
816
817     while (fgets(buf, sizeof(buf), fp) != NULL) {
818         if ((!strncmp(buf, "Mem:", 4) && mem_type == HRS_TYPE_MEM) ||
819             (!strncmp(buf, "Swap:", 5) && mem_type == HRS_TYPE_SWAP)) {
820             sscanf(buf, "%*s %d %d", &size, &used);
821             break;
822         }
823     }
824
825     fclose(fp);
826     return (size_or_used == HRSTORE_SIZE ? size : used) / 1024;
827
828 }
829 #endif
830
831 #ifdef solaris2
832 void
833 sol_get_swapinfo(int *totalP, int *usedP)
834 {
835     struct anoninfo ainfo;
836
837     if (swapctl(SC_AINFO, &ainfo) < 0) {
838         *totalP = *usedP = 0;
839         return;
840     }
841
842     *totalP = ainfo.ani_max;
843     *usedP = ainfo.ani_resv;
844 }
845 #endif                          /* solaris2 */