net-snmp 5.7
kernel.c
Go to the documentation of this file.
00001 /***********************************************************************
00002    Net-SNMP - Simple Network Management Protocol agent library.
00003  ***********************************************************************/
00010 /* Copyrights:
00011  *     Copyright holders are listed in README file.
00012  *     Redistribution and use in source and binary forms, with or
00013  *     without modification, are permitted. License terms are specified
00014  *     in COPYING file distributed with the Net-SNMP package.
00015  */
00016 /***********************************************************************/
00017 
00018 #include <net-snmp/net-snmp-config.h>
00019 
00020 #ifdef NETSNMP_CAN_USE_NLIST
00021 
00022 #include <sys/types.h>
00023 #if HAVE_STDLIB_H
00024 #include <stdlib.h>
00025 #endif
00026 #if HAVE_UNISTD_H
00027 #include <unistd.h>
00028 #endif
00029 #include <stdio.h>
00030 #include <errno.h>
00031 #if HAVE_STRING_H
00032 #include <string.h>
00033 #endif
00034 #if HAVE_FCNTL_H
00035 #include <fcntl.h>
00036 #endif
00037 #if HAVE_NETINET_IN_H
00038 #include <netinet/in.h>
00039 #endif
00040 #if HAVE_KVM_H
00041 #include <kvm.h>
00042 #endif
00043 
00044 #include <net-snmp/net-snmp-includes.h>
00045 
00046 #include "kernel.h"
00047 #include <net-snmp/agent/ds_agent.h>
00048 
00049 #ifndef NULL
00050 #define NULL 0
00051 #endif
00052 
00053 
00054 #if HAVE_KVM_H
00055 kvm_t *kd = NULL;
00056 
00059 void
00060 init_kmem(const char *file)
00061 {
00062 #if HAVE_KVM_OPENFILES
00063     char            err[4096];
00064     kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, err);
00065     if (kd == NULL && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00066                                            NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00067         snmp_log(LOG_CRIT, "init_kmem: kvm_openfiles failed: %s\n", err);
00068         exit(1);
00069     }
00070 #else
00071     kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);
00072     if (!kd && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00073                                        NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00074         snmp_log(LOG_CRIT, "init_kmem: kvm_open failed: %s\n",
00075                  strerror(errno));
00076         exit(1);
00077     }
00078 #endif                          /* HAVE_KVM_OPENFILES */
00079 }
00080 
00093 int
00094 klookup(unsigned long off, char *target, int siz)
00095 {
00096     int             result;
00097     if (kd == NULL)
00098         return 0;
00099     result = kvm_read(kd, off, target, siz);
00100     if (result != siz) {
00101 #if HAVE_KVM_OPENFILES
00102         snmp_log(LOG_ERR, "kvm_read(*, %lx, %p, %d) = %d: %s\n", off,
00103                  target, siz, result, kvm_geterr(kd));
00104 #else
00105         snmp_log(LOG_ERR, "kvm_read(*, %lx, %p, %d) = %d: ", off, target,
00106                  siz, result);
00107         snmp_log_perror("klookup");
00108 #endif
00109         return 0;
00110     }
00111     return 1;
00112 }
00113 
00116 void
00117 free_kmem(void)
00118 {
00119     if (kd != NULL)
00120     {
00121       kvm_close(kd);
00122       kd = NULL;
00123     }
00124 }
00125 
00126 #else                           /* HAVE_KVM_H */
00127 
00128 static off_t    klseek(off_t);
00129 static int      klread(char *, int);
00130 int             swap=0, mem=0, kmem=0;
00131 
00134 void
00135 init_kmem(const char *file)
00136 {
00137     kmem = open(file, O_RDONLY);
00138     if (kmem < 0 && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00139                                             NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00140         snmp_log_perror(file);
00141         exit(1);
00142     }
00143     fcntl(kmem, F_SETFD, 1);
00144     mem = open("/dev/mem", O_RDONLY);
00145     if (mem < 0 && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00146                                            NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00147         snmp_log_perror("/dev/mem");
00148         exit(1);
00149     }
00150     fcntl(mem, F_SETFD, 1);
00151 #ifdef DMEM_LOC
00152     swap = open(DMEM_LOC, O_RDONLY);
00153     if (swap < 0 && !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00154                                             NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00155         snmp_log_perror(DMEM_LOC);
00156         exit(1);
00157     }
00158     fcntl(swap, F_SETFD, 1);
00159 #endif
00160 }
00161 
00165 static off_t
00166 klseek(off_t base)
00167 {
00168     return (lseek(kmem, (off_t) base, SEEK_SET));
00169 }
00170 
00174 static int
00175 klread(char *buf, int buflen)
00176 {
00177     return (read(kmem, buf, buflen));
00178 }
00179 
00192 int
00193 klookup(unsigned long off, char *target, int siz)
00194 {
00195     long            retsiz;
00196 
00197     if (kmem < 0)
00198         return 0;
00199 
00200     if ((retsiz = klseek((off_t) off)) != off) {
00201         snmp_log(LOG_ERR, "klookup(%lx, %p, %d): ", off, target, siz);
00202         snmp_log_perror("klseek");
00203 #ifdef NETSNMP_EXIT_ON_BAD_KLREAD
00204         exit(1);
00205 #endif
00206         return (0);
00207     }
00208     if ((retsiz = klread(target, siz)) != siz) {
00209         if (snmp_get_do_debugging()) {
00210             /*
00211              * these happen too often on too many architectures to print them
00212              * unless we're in debugging mode. People get very full log files. 
00213              */
00214             snmp_log(LOG_ERR, "klookup(%lx, %p, %d): ", off, target, siz);
00215             snmp_log_perror("klread");
00216         }
00217 #ifdef NETSNMP_EXIT_ON_BAD_KLREAD
00218         exit(1);
00219 #endif
00220         return (0);
00221     }
00222     DEBUGMSGTL(("verbose:kernel:klookup", "klookup(%lx, %p, %d) succeeded", off, target, siz));
00223     return (1);
00224 }
00225 
00228 void
00229 free_kmem(void)
00230 {
00231     if (swap) {
00232       close(swap);
00233       swap = 0;
00234     }
00235     if (mem) {
00236       close(mem);
00237       mem = 0;
00238     }
00239     if (kmem) {
00240       close(kmem);
00241       kmem = 0;
00242     }
00243 }
00244 
00245 #endif                          /* HAVE_KVM_H */
00246 
00247 #else
00248 int unused;     /* Suppress "empty translation unit" warning */
00249 #endif                          /* NETSNMP_CAN_USE_NLIST */