00001
00002
00003
00004
00005
00006 #include <net-snmp/net-snmp-config.h>
00007
00008 #ifdef CAN_USE_NLIST
00009
00010 #include <sys/types.h>
00011 #if HAVE_STDLIB_H
00012 #include <stdlib.h>
00013 #endif
00014 #if HAVE_UNISTD_H
00015 #include <unistd.h>
00016 #endif
00017 #include <stdio.h>
00018 #include <errno.h>
00019 #if HAVE_STRING_H
00020 #include <string.h>
00021 #endif
00022 #if HAVE_FCNTL_H
00023 #include <fcntl.h>
00024 #endif
00025 #if HAVE_NETINET_IN_H
00026 #include <netinet/in.h>
00027 #endif
00028 #if HAVE_KVM_H
00029 #include <kvm.h>
00030 #endif
00031
00032 #include <net-snmp/net-snmp-includes.h>
00033
00034 #include "kernel.h"
00035 #include <net-snmp/agent/ds_agent.h>
00036
00037 #ifndef NULL
00038 #define NULL 0
00039 #endif
00040
00041
00042 #if HAVE_KVM_H
00043 kvm_t *kd;
00044
00045 void
00046 init_kmem(const char *file)
00047 {
00048 #if HAVE_KVM_OPENFILES
00049 char err[4096];
00050 kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, err);
00051 if (kd == NULL && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00052 NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00053 snmp_log(LOG_CRIT, "init_kmem: kvm_openfiles failed: %s\n", err);
00054 exit(1);
00055 }
00056 #else
00057 kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);
00058 if (!kd && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00059 NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00060 snmp_log(LOG_CRIT, "init_kmem: kvm_open failed: %s\n",
00061 strerror(errno));
00062 exit(1);
00063 }
00064 #endif
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 int
00080 klookup(unsigned long off, char *target, int siz)
00081 {
00082 int result;
00083 if (kd == NULL)
00084 return 0;
00085 result = kvm_read(kd, off, target, siz);
00086 if (result != siz) {
00087 #if HAVE_KVM_OPENFILES
00088 snmp_log(LOG_ERR, "kvm_read(*, %lx, %p, %d) = %d: %s\n", off,
00089 target, siz, result, kvm_geterr(kd));
00090 #else
00091 snmp_log(LOG_ERR, "kvm_read(*, %lx, %p, %d) = %d: ", off, target,
00092 siz, result);
00093 snmp_log_perror("klookup");
00094 #endif
00095 return 0;
00096 }
00097 return 1;
00098 }
00099
00100 #else
00101
00102 static off_t klseek(off_t);
00103 static int klread(char *, int);
00104 int swap, mem, kmem;
00105
00106 void
00107 init_kmem(const char *file)
00108 {
00109 kmem = open(file, O_RDONLY);
00110 if (kmem < 0 && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00111 NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00112 snmp_log_perror(file);
00113 exit(1);
00114 }
00115 fcntl(kmem, F_SETFD, 1);
00116 mem = open("/dev/mem", O_RDONLY);
00117 if (mem < 0 && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00118 NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00119 snmp_log_perror("/dev/mem");
00120 exit(1);
00121 }
00122 fcntl(mem, F_SETFD, 1);
00123 #ifdef DMEM_LOC
00124 swap = open(DMEM_LOC, O_RDONLY);
00125 if (swap < 0 && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
00126 NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00127 snmp_log_perror(DMEM_LOC);
00128 exit(1);
00129 }
00130 fcntl(swap, F_SETFD, 1);
00131 #endif
00132 }
00133
00134
00135
00136
00137
00138 static off_t
00139 klseek(off_t base)
00140 {
00141 return (lseek(kmem, (off_t) base, SEEK_SET));
00142 }
00143
00144
00145
00146
00147
00148 static int
00149 klread(char *buf, int buflen)
00150 {
00151 return (read(kmem, buf, buflen));
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 int
00167 klookup(unsigned long off, char *target, int siz)
00168 {
00169 long retsiz;
00170
00171 if (kmem < 0)
00172 return 0;
00173
00174 if ((retsiz = klseek((off_t) off)) != off) {
00175 snmp_log(LOG_ERR, "klookup(%lx, %p, %d): ", off, target, siz);
00176 snmp_log_perror("klseek");
00177 #ifdef EXIT_ON_BAD_KLREAD
00178 exit(1);
00179 #endif
00180 return (0);
00181 }
00182 if ((retsiz = klread(target, siz)) != siz) {
00183 if (snmp_get_do_debugging()) {
00184
00185
00186
00187
00188 snmp_log(LOG_ERR, "klookup(%lx, %p, %d): ", off, target, siz);
00189 snmp_log_perror("klread");
00190 }
00191 #ifdef EXIT_ON_BAD_KLREAD
00192 exit(1);
00193 #endif
00194 return (0);
00195 }
00196 return (1);
00197 }
00198
00199 #endif
00200
00201 #endif