text: #include <net-snmp/net-snmp-config.h>
  #include <net-snmp/net-snmp-includes.h>
  #include <net-snmp/agent/net-snmp-agent-includes.h>
  #include <net-snmp/agent/auto_nlist.h>
  #include <net-snmp/agent/hardware/memory.h>
  #include "../../../kernel.h"
  
  #include <unistd.h>
  #include <sys/param.h>
  #include <sys/fcntl.h>
  #include <sys/sysctl.h>
  #include <sys/vmmeter.h>
  #include <kvm.h>
  
  #if HAVE_SYS_VMPARAM_H
  #include <sys/vmparam.h>
  #else
  #include <vm/vm_param.h>
  #endif
  
  #define SUM_SYMBOL       "cnt"
  #define BUFSPACE_SYMBOL  "bufspace"
  
  quad_t    swapTotal;
  quad_t    swapUsed;
  quad_t    swapFree;
  
  static int swapmode(long);
  
  
      /*
       * Load the latest memory usage statistics
       */
  int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) {
  
      netsnmp_memory_info *mem;
      long           pagesize;
      int            nswap;
  
  #if !defined(VM_TOTAL)
      unsigned int   free_mem;
      size_t         free_size = sizeof(free_mem);
      unsigned int   mem_pages;
  #else
      struct vmtotal total;
      size_t         total_size  = sizeof(total);
      int            total_mib[] = { CTL_VM, VM_TOTAL };
  #endif
  
      u_long         phys_mem;
      u_long         user_mem;
      unsigned int   cache_count;
      unsigned int   cache_max;
      unsigned int   bufspace;
      unsigned int   maxbufspace;
      unsigned int   inact_count;
      size_t         mem_size   = sizeof(phys_mem);
      size_t         cache_size = sizeof(cache_count);
      size_t         buf_size   = sizeof(bufspace);
      size_t         inact_size = sizeof(inact_count);
      int            phys_mem_mib[] = { CTL_HW, HW_PHYSMEM };
      int            user_mem_mib[] = { CTL_HW, HW_USERMEM };
  
      /*
       * Retrieve the memory information from the underlying O/S...
       */
  #if !defined(VM_TOTAL)
      sysctlbyname("vm.stats.vm.v_free_count", &free_mem,    &free_size,    NULL, 0);
      sysctlbyname("vm.stats.vm.v_page_count", &mem_pages,    &free_size,    NULL, 0);
  #else
      sysctl(total_mib,    2, &total,    &total_size,    NULL, 0);
  #endif
      sysctl(phys_mem_mib, 2, &phys_mem, &mem_size,      NULL, 0);
      sysctl(user_mem_mib, 2, &user_mem, &mem_size,      NULL, 0);
      sysctlbyname("vm.stats.vm.v_cache_count",    &cache_count, &cache_size, NULL, 0);
      sysctlbyname("vm.stats.vm.v_cache_max",      &cache_max,   &cache_size, NULL, 0);
      sysctlbyname("vm.stats.vm.v_inactive_count", &inact_count, &inact_size, NULL, 0);
      sysctlbyname("vfs.bufspace",    &bufspace,    &buf_size, NULL, 0);
      sysctlbyname("vfs.maxbufspace", &maxbufspace, &buf_size, NULL, 0);
  #ifndef freebsd4
      pagesize = 1024;
  #else
      pagesize = getpagesize();
  #endif
  
      /*
       * ... and save this in a standard form.
       */
      mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 1 );
      if (!mem) {
          snmp_log_perror("No Physical Memory info entry");
      } else {
          if (!mem->descr)
               mem->descr = strdup("Physical memory");
          mem->units = pagesize;
          mem->size  = phys_mem/pagesize;
  #if !defined(VM_TOTAL)
  	mem->free  = free_mem;
  #else
          mem->free  = total.t_free;
  #endif
      }
  
      mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_USERMEM, 1 );
      if (!mem) {
          snmp_log_perror("No (user) Memory info entry");
      } else {
          if (!mem->descr)
               mem->descr = strdup("Real memory");
          mem->units = pagesize;
  #if !defined(VM_TOTAL)
  	mem->size  = user_mem/pagesize;
  	mem->free  = free_mem;
  #else
          mem->size  = total.t_rm;
          mem->free  = total.t_rm - total.t_arm;
  #endif
      }
  
      mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_VIRTMEM, 1 );
      if (!mem) {
          snmp_log_perror("No Virtual Memory info entry");
      } else {
          if (!mem->descr)
               mem->descr = strdup("Virtual memory");
          mem->units = pagesize;
  #if !defined(VM_TOTAL)
  	mem->size  = mem_pages+swapTotal;
  	mem->free  = free_mem+swapFree;
  #else
          mem->size  = total.t_vm;
          mem->free  = total.t_vm - total.t_avm;
  #endif
      }
  
  #if defined(VM_TOTAL)
      mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SHARED, 1 );
      if (!mem) {
          snmp_log_perror("No Shared Memory info entry");
      } else {
          if (!mem->descr)
               mem->descr = strdup("Shared virtual memory");
          mem->units = pagesize;
          mem->size  = total.t_vmshr;
          mem->free  = total.t_vmshr - total.t_avmshr;
      }
  
      mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SHARED2, 1 );
      if (!mem) {
          snmp_log_perror("No Shared2 Memory info entry");
      } else {
          if (!mem->descr)
               mem->descr = strdup("Shared real memory");
          mem->units = pagesize;
          mem->size  = total.t_rmshr;
          mem->free  = total.t_rmshr - total.t_armshr;
      }
  #endif
  
      mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_CACHED, 1 );
      if (!mem) {
          snmp_log_perror("No Cached Memory info entry");
      } else {
          if (!mem->descr)
               mem->descr = strdup("Cached memory");
          mem->units = pagesize;
          mem->size  = cache_count;
          mem->free  = 0;
      }
  
      nswap = swapmode(pagesize);
      mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 1 );
      if (!mem) {
          snmp_log_perror("No Swap info entry");
      } else {
          if (!mem->descr)
               mem->descr = strdup( (nswap>1) ? "Swap space (total)"
                                              : "Swap space");
          mem->units = pagesize;
          mem->size  = swapTotal;
          mem->free  = swapFree;
      }
  
      mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_MBUF, 1 );
      if (!mem) {
          snmp_log_perror("No Buffer, etc info entry");
      } else {
          if (!mem->descr)
               mem->descr = strdup("Memory buffers");
          mem->units = 1024;
          mem->size  =  maxbufspace / 1024;
          mem->free  = (maxbufspace - bufspace)/1024;
      }
  
      return 0;
  }
  
  
  
  /*
   * Retained from UCD implementation
   */
  
  
  #ifndef freebsd4
  /*
   * Executes swapinfo and parses last line 
   * This is just way too ugly ;) 
   */
  
  static int
  swapmode(long pagesize)
  {
      struct extensible ext;
      int             fd;
      FILE           *file;
  
      strcpy(ext.command, "/usr/sbin/swapinfo -k");
  
      if ((fd = get_exec_output(&ext)) != -1) {
          file = fdopen(fd, "r");
  
          while (fgets(ext.output, sizeof(ext.output), file) != NULL);
  
          fclose(file);
          wait_on_exec(&ext);
  
          sscanf(ext.output, "%*s%*d%qd%qd", &swapUsed, &swapFree);
  
          swapTotal = swapUsed + swapFree;
      }
      return 1;
  }
  #else
  /*
   * swapmode is based on a program called swapinfo written
   * by Kevin Lahey <kml@rokkaku.atl.ga.us>.
   */
  
  #include <sys/conf.h>
  
  static int
  swapmode(long pagesize)
  {
      int             i, n;
      struct kvm_swap kswap[16];
      netsnmp_memory_info *mem;
      char buf[1024];
  
      n = kvm_getswapinfo(kd, kswap, sizeof(kswap) / sizeof(kswap[0]), 0);
  
      swapUsed = swapTotal = swapFree = 0;
  
      if ( n > 0 ) {
          /*
           * If there are multiple swap devices, then record
           *   the statistics for each one separately...
           */
          for (i = 0; i < n; ++i) {
              mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP+1+i, 1 );
              if (!mem)
                  continue;
              if (!mem->descr) {
                  sprintf(buf, "swap %s", kswap[i].ksw_devname);
                  mem->descr = strdup( buf );
              }
              mem->units = pagesize;
              mem->size  = kswap[i].ksw_total;
              mem->free  = kswap[i].ksw_total - kswap[i].ksw_used;
              /*
               *  ... and keep a running total for the overall swap stats
               */
              swapTotal += kswap[i].ksw_total;
              swapUsed  += kswap[i].ksw_used;
          }
      } else {
          /*
           * If there's only one swap device, then don't bother
           *   with individual statistics.
           */
          swapTotal += kswap[0].ksw_total;
          swapUsed  += kswap[0].ksw_used;
      }
  
      swapFree = swapTotal - swapUsed;
      return n;
  }
  #endif
  
  