1 /* snmp-ups.h - NUT Meta SNMP driver (support different MIBS) 2 * 3 * Based on NET-SNMP API (Simple Network Management Protocol V1-2) 4 * 5 * Copyright (C) 6 * 2002-2010 Arnaud Quette <arnaud.quette@free.fr> 7 * 2002-2006 Dmitry Frolov <frolov@riss-telecom.ru> 8 * J.W. Hoogervorst <jeroen@hoogervorst.net> 9 * Niels Baggesen <niels@baggesen.net> 10 * 11 * Sponsored by MGE UPS SYSTEMS <http://opensource.mgeups.com/> 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, write to the Free Software 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 * 27 */ 28 29 /* TODO list: 30 - add syscontact/location (to all mib.h or centralized?) 31 - complete shutdown 32 - add enum values to OIDs. 33 - optimize network flow by: 34 1) caching OID values (as in usbhid-ups) with timestamping and lifetime 35 2) constructing one big packet (calling snmp_add_null_var 36 for each OID request we made), instead of sending many small packets 37 - add support for registration and traps (manager mode) 38 => Issue: 1 trap listener for N snmp-ups drivers! 39 - complete mib2nut data (add all OID translation to NUT) 40 - externalize mib2nut data in .m2n files and load at driver startup using parseconf()... 41 - adjust information logging. 42 43 - move numeric OIDs into th mib2nut tables and remove defines 44 - move mib2nut into c files (à la usbhid-ups)? 45 - add a claim function and move to usbhid-ups style for specific processing 46 - rework the flagging system 47 */ 48 49 #ifndef SNMP_UPS_H 50 #define SNMP_UPS_H 51 52 /* FIXME: still needed? 53 * workaround for buggy Net-SNMP config */ 54 #ifdef PACKAGE_BUGREPORT 55 #undef PACKAGE_BUGREPORT 56 #endif 57 58 #ifdef PACKAGE_NAME 59 #undef PACKAGE_NAME 60 #endif 61 62 #ifdef PACKAGE_VERSION 63 #undef PACKAGE_VERSION 64 #endif 65 66 #ifdef PACKAGE_STRING 67 #undef PACKAGE_STRING 68 #endif 69 70 #ifdef PACKAGE_TARNAME 71 #undef PACKAGE_TARNAME 72 #endif 73 74 #ifdef HAVE_DMALLOC_H 75 #undef HAVE_DMALLOC_H 76 #endif 77 78 #include <net-snmp/net-snmp-config.h> 79 #include <net-snmp/net-snmp-includes.h> 80 81 /* Force numeric OIDs by disabling MIB loading */ 82 #define DISABLE_MIB_LOADING 1 83 84 /* Parameters default values */ 85 #define DEFAULT_POLLFREQ 30 /* in seconds */ 86 #define DEFAULT_NETSNMP_RETRIES 5 87 #define DEFAULT_NETSNMP_TIMEOUT 1 /* in seconds */ 88 89 /* use explicit booleans */ 90 #ifndef FALSE 91 typedef enum ebool { FALSE, TRUE } bool_t; 92 #else 93 typedef int bool_t; 94 #endif 95 96 /* Common SNMP data and lookup definitions */ 97 /* special functions to interpret items: 98 take UPS answer, return string to set in INFO, max len 99 100 NOTE: FFE means For Future Extensions 101 102 */ 103 104 /* typedef void (*interpreter)(char *, char *, int); */ 105 106 /* for lookup between OID values and INFO_ value */ 107 typedef struct { 108 int oid_value; /* OID value */ 109 const char *info_value; /* INFO_* value */ 110 } info_lkp_t; 111 112 /* Structure containing info about one item that can be requested 113 from UPS and set in INFO. If no interpreter functions is defined, 114 use sprintf with given format string. If unit is not NONE, values 115 are converted according to the multiplier table 116 */ 117 typedef struct { 118 const char *info_type; /* INFO_ or CMD_ element */ 119 int info_flags; /* flags to set in addinfo */ 120 double info_len; /* length of strings if STR, 121 * cmd value if CMD, multiplier otherwise. */ 122 const char *OID; /* SNMP OID or NULL */ 123 const char *dfl; /* default value */ 124 unsigned long flags; /* my flags */ 125 info_lkp_t *oid2info; /* lookup table between OID and NUT values */ 126 int *setvar; /* variable to set for SU_FLAG_SETINT */ 127 } snmp_info_t; 128 129 #define SU_FLAG_OK (1 << 0) /* show element to upsd. */ 130 #define SU_FLAG_STATIC (1 << 1) /* retrieve info only once. */ 131 #define SU_FLAG_ABSENT (1 << 2) /* data is absent in the device, 132 * use default value. */ 133 #define SU_FLAG_STALE (1 << 3) /* data stale, don't try too often. */ 134 #define SU_FLAG_NEGINVALID (1 << 4) /* Invalid if negative value */ 135 #define SU_FLAG_UNIQUE (1 << 5) /* There can be only be one 136 * provider of this info, 137 * disable the other providers */ 138 #define SU_FLAG_SETINT (1 << 6) /* save value */ 139 #define SU_OUTLET (1 << 7) /* outlet template definition */ 140 #define SU_CMD_OFFSET (1 << 8) /* Add +1 to the OID index */ 141 /* Notes on outlet templates usage: 142 * - outlet.count MUST exist and MUST be declared before any outlet template 143 * Otherwise, the driver will try to determine it by itself... 144 * - the first outlet template MUST NOT be a server side variable (ie MUST have 145 * a valid OID) in order to detect the base SNMP index (0 or 1) 146 */ 147 148 /* status string components 149 * FIXME: these should be removed, since there is no added value. 150 * Ie, this can be guessed from info->type! */ 151 152 #define SU_STATUS_PWR (0 << 8) /* indicates power status element */ 153 #define SU_STATUS_BATT (1 << 8) /* indicates battery status element */ 154 #define SU_STATUS_CAL (2 << 8) /* indicates calibration status element */ 155 #define SU_STATUS_RB (3 << 8) /* indicates replace battery status element */ 156 #define SU_STATUS_NUM_ELEM 4 157 #define SU_STATUS_INDEX(t) (((t) >> 8) & 7) 158 159 #define SU_OUTLET_GROUP (1 << 10) /* outlet group template definition */ 160 161 /* Phase specific data */ 162 #define SU_PHASES (0x3F << 12) 163 #define SU_INPHASES (0x3 << 12) 164 #define SU_INPUT_1 (1 << 12) /* only if 1 input phase */ 165 #define SU_INPUT_3 (1 << 13) /* only if 3 input phases */ 166 #define SU_OUTPHASES (0x3 << 14) 167 #define SU_OUTPUT_1 (1 << 14) /* only if 1 output phase */ 168 #define SU_OUTPUT_3 (1 << 15) /* only if 3 output phases */ 169 #define SU_BYPPHASES (0x3 << 16) 170 #define SU_BYPASS_1 (1 << 16) /* only if 1 bypass phase */ 171 #define SU_BYPASS_3 (1 << 17) /* only if 3 bypass phases */ 172 /* FIXME: use input.phases and output.phases to replace this */ 173 174 175 /* hints for su_ups_set, applicable only to rw vars */ 176 #define SU_TYPE_INT (0 << 18) /* cast to int when setting value */ 177 #define SU_TYPE_STRING (1 << 18) /* cast to string. FIXME: redundant with ST_FLAG_STRING */ 178 #define SU_TYPE_TIME (2 << 18) /* cast to int */ 179 #define SU_TYPE_CMD (3 << 18) /* instant command */ 180 #define SU_TYPE(t) ((t)->flags & (7 << 18)) 181 182 #define SU_VAR_COMMUNITY "community" 183 #define SU_VAR_VERSION "snmp_version" 184 #define SU_VAR_RETRIES "snmp_retries" 185 #define SU_VAR_TIMEOUT "snmp_timeout" 186 #define SU_VAR_MIBS "mibs" 187 #define SU_VAR_POLLFREQ "pollfreq" 188 /* SNMP v3 related parameters */ 189 #define SU_VAR_SECLEVEL "secLevel" 190 #define SU_VAR_SECNAME "secName" 191 #define SU_VAR_AUTHPASSWD "authPassword" 192 #define SU_VAR_PRIVPASSWD "privPassword" 193 #define SU_VAR_AUTHPROT "authProtocol" 194 #define SU_VAR_PRIVPROT "privProtocol" 195 196 197 #define SU_INFOSIZE 128 198 #define SU_BUFSIZE 32 199 #define SU_LARGEBUF 256 200 201 #define SU_STALE_RETRY 10 /* retry to retrieve stale element */ 202 /* after this number of iterations. */ 203 /* FIXME: this is for *all* elements */ 204 /* modes to snmp_ups_walk. */ 205 #define SU_WALKMODE_INIT 0 206 #define SU_WALKMODE_UPDATE 1 207 208 /* log spew limiters */ 209 #define SU_ERR_LIMIT 10 /* start limiting after this many errors in a row */ 210 #define SU_ERR_RATE 100 /* only print every nth error once limiting starts */ 211 212 typedef struct { 213 const char * OID; 214 const char *status_value; /* when not NULL, set ups.status to this */ 215 const char *alarm_value; /* when not NULL, set ups.alarm to this */ 216 } alarms_info_t; 217 218 typedef struct { 219 const char *mib_name; 220 const char *mib_version; 221 const char *oid_pwr_status; 222 const char *oid_auto_check; /* FIXME: rename to SysOID */ 223 snmp_info_t *snmp_info; /* pointer to the good Snmp2Nut lookup data */ 224 const char *sysOID; /* OID to match against sysOID, aka MIB 225 * main entry point */ 226 alarms_info_t *alarms_info; 227 } mib2nut_info_t; 228 229 /* Common SNMP functions */ 230 void nut_snmp_init(const char *type, const char *hostname); 231 void nut_snmp_cleanup(void); 232 struct snmp_pdu *nut_snmp_get(const char *OID); 233 bool_t nut_snmp_get_str(const char *OID, char *buf, size_t buf_len, 234 info_lkp_t *oid2info); 235 bool_t nut_snmp_get_int(const char *OID, long *pval); 236 bool_t nut_snmp_set(const char *OID, char type, const char *value); 237 bool_t nut_snmp_set_str(const char *OID, const char *value); 238 bool_t nut_snmp_set_int(const char *OID, long value); 239 void nut_snmp_perror(struct snmp_session *sess, int status, 240 struct snmp_pdu *response, const char *fmt, ...) 241 __attribute__ ((__format__ (__printf__, 4, 5))); 242 243 void su_startup(void); 244 void su_cleanup(void); 245 void su_init_instcmds(void); 246 void su_setuphandlers(void); /* need to deal with external function ptr */ 247 void su_setinfo(snmp_info_t *su_info_p, const char *value); 248 void su_status_set(snmp_info_t *, long value); 249 snmp_info_t *su_find_info(const char *type); 250 bool_t snmp_ups_walk(int mode); 251 bool_t su_ups_get(snmp_info_t *su_info_p); 252 253 bool_t load_mib2nut(const char *mib); 254 255 const char *su_find_infoval(info_lkp_t *oid2info, long value); 256 long su_find_valinfo(info_lkp_t *oid2info, const char* value); 257 258 int su_setvar(const char *varname, const char *val); 259 int su_instcmd(const char *cmdname, const char *extradata); 260 void su_shutdown_ups(void); 261 262 void read_mibconf(char *mib); 263 264 extern struct snmp_session g_snmp_sess, *g_snmp_sess_p; 265 extern const char *OID_pwr_status; 266 extern int g_pwr_battery; 267 extern int pollfreq; /* polling frequency */ 268 extern int input_phases, output_phases, bypass_phases; 269 270 #endif /* SNMP_UPS_H */ 271 272