mib2sys.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * Copyright 2007 by egnite Software GmbH
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. */
  32. #include <sys/version.h>
  33. #include <sys/confos.h>
  34. #include <sys/confnet.h>
  35. #include <sys/environ.h>
  36. #include <pro/snmp.h>
  37. #include <pro/snmp_api.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <ctype.h>
  41. #include <time.h>
  42. #include "mib2sys.h"
  43. #if defined(STK501)
  44. #define BOARD_NAME "STK 501"
  45. #elif defined(INTECH21)
  46. #define BOARD_NAME "Intech 21"
  47. #elif defined(XNUT_100)
  48. #define BOARD_NAME "XNUT 100"
  49. #elif defined(XNUT_105)
  50. #define BOARD_NAME "XNUT 105"
  51. #elif defined(AT91SAM7X_EK)
  52. #define BOARD_NAME "AT91SAM7X-EK"
  53. #elif defined(AT91SAM9260_EK)
  54. #define BOARD_NAME "AT91SAM9260-EK"
  55. #elif defined(CHARON2)
  56. #define BOARD_NAME "Charon 2"
  57. #elif defined(ARTHERNET1)
  58. #define BOARD_NAME "Arthernet 1"
  59. #elif defined(MMNET02)
  60. #define BOARD_NAME "MMNET02"
  61. #elif defined(ETHERNUT1)
  62. #define BOARD_NAME "Ethernut 1"
  63. #elif defined(ETHERNUT2)
  64. #define BOARD_NAME "Ethernut 2"
  65. #elif defined(ETHERNUT3)
  66. #define BOARD_NAME "Ethernut 3"
  67. #elif defined(ETHERNUT5)
  68. #define BOARD_NAME "Ethernut 5"
  69. #else
  70. #define BOARD_NAME "Custom"
  71. #endif
  72. #define MAG_SYS_DESCR 1
  73. #define MAG_SYS_OID 2
  74. #define MAG_SYS_UPTIME 3
  75. #define MAG_SYS_CONTACT 4
  76. #define MAG_SYS_NAME 5
  77. #define MAG_SYS_LOCATION 6
  78. #define MAG_SYS_SERVICES 7
  79. static uint8_t *MibVarsSysGet(const SNMPVAR *, OID *, size_t *, int, size_t *, WMETHOD **);
  80. static OID base_oid[] = { SNMP_OID_MIB2, 1 };
  81. static size_t base_oidlen = sizeof(base_oid) / sizeof(OID);
  82. static SNMPVAR mib_variables[] = {
  83. {MAG_SYS_DESCR, ASN_OCTET_STR, ACL_RONLY, MibVarsSysGet, 1, {1}},
  84. {MAG_SYS_OID, ASN_OBJECT_ID, ACL_RONLY, MibVarsSysGet, 1, {2}},
  85. {MAG_SYS_UPTIME, ASN_TIMETICKS, ACL_RONLY, MibVarsSysGet, 1, {3}},
  86. {MAG_SYS_CONTACT, ASN_OCTET_STR, ACL_RWRITE, MibVarsSysGet, 1, {4}},
  87. {MAG_SYS_NAME, ASN_OCTET_STR, ACL_RWRITE, MibVarsSysGet, 1, {5}},
  88. {MAG_SYS_LOCATION, ASN_OCTET_STR, ACL_RWRITE, MibVarsSysGet, 1, {6}},
  89. {MAG_SYS_SERVICES, ASN_INTEGER, ACL_RONLY, MibVarsSysGet, 1, {7}}
  90. };
  91. static char sys_descr[MAX_SYSSTR_LEN];
  92. static char *sys_contact;
  93. static char *sys_name;
  94. static char *sys_location;
  95. static time_t sys_starttime;
  96. static long sys_uptime;
  97. static long sys_services = 72;
  98. static OID sys_oid[] = {
  99. SNMP_OID_ENTERPRISES,
  100. 3444, /* egnite */
  101. 2, /* egnite products=1 local=2 experimental=3 */
  102. 6, /* egnite Nut/OS */
  103. };
  104. static char *UpdateStringEnv(char *name, char *var, char *value)
  105. {
  106. if (var) {
  107. free(var);
  108. }
  109. if ((var = malloc(strlen(value) + 1)) != NULL) {
  110. strcpy(var, value);
  111. if (name) {
  112. setenv(name, value, 1);
  113. }
  114. }
  115. return var;
  116. }
  117. /*!
  118. * \brief Register MIB II system variables.
  119. *
  120. * \note Preliminary code with hard coded values.
  121. */
  122. int MibRegisterSysVars(void)
  123. {
  124. char *cp;
  125. strcpy(sys_descr, BOARD_NAME);
  126. strcat(sys_descr, " Nut/OS ");
  127. strcat(sys_descr, NutVersionString());
  128. if ((cp = getenv("SYSCONTACT")) != NULL) {
  129. sys_contact = UpdateStringEnv(NULL, sys_contact, cp);
  130. }
  131. if ((cp = getenv("SYSNAME")) != NULL) {
  132. sys_name = UpdateStringEnv(NULL, sys_name, cp);
  133. } else {
  134. sys_name = UpdateStringEnv(NULL, sys_name, confos.hostname);
  135. }
  136. if ((cp = getenv("SYSLOCATION")) != NULL) {
  137. sys_location = UpdateStringEnv(NULL, sys_location, cp);
  138. }
  139. sys_starttime = time(NULL);
  140. return SnmpMibRegister(base_oid, base_oidlen, mib_variables, sizeof(mib_variables) / sizeof(SNMPVAR));
  141. }
  142. static int MibVarsSysSet(int action, uint8_t * var_val, uint8_t var_val_type, size_t var_val_len, OID * name, size_t name_len)
  143. {
  144. size_t len = SNMP_MAX_LEN;
  145. uint8_t *value;
  146. uint8_t *cp;
  147. size_t size;
  148. if (action != SNMP_ACT_COMMIT) {
  149. return 0;
  150. }
  151. if (var_val_type != ASN_OCTET_STR) {
  152. return SNMP_ERR_WRONGTYPE;
  153. }
  154. if (var_val_len > MAX_SYSSTR_LEN) {
  155. return SNMP_ERR_WRONGLENGTH;
  156. }
  157. size = MAX_SYSSTR_LEN;
  158. if ((value = (uint8_t *)malloc(MAX_SYSSTR_LEN) + 1) == NULL) {
  159. return SNMP_ERR_RESOURCEUNAVAILABLE;
  160. }
  161. AsnOctetStringParse(var_val, &len, &var_val_type, value, &size);
  162. value[size] = 0;
  163. for (cp = value; *cp; cp++) {
  164. if (!isprint(*cp)) {
  165. free(value);
  166. return SNMP_ERR_WRONGVALUE;
  167. }
  168. }
  169. if (action == SNMP_ACT_COMMIT) {
  170. switch (name[7]) {
  171. case 4:
  172. sys_contact = UpdateStringEnv("SYSCONTACT", sys_contact, (char *) value);
  173. break;
  174. case 5:
  175. sys_name = UpdateStringEnv("SYSNAME", sys_name, (char *) value);
  176. break;
  177. case 6:
  178. sys_location = UpdateStringEnv("SYSLOCATION", sys_location, (char *) value);
  179. break;
  180. }
  181. }
  182. free(value);
  183. return 0;
  184. }
  185. /*!
  186. * \brief Access the specified MIB variable.
  187. *
  188. * \param vp
  189. * \param name Contains the name to look for, either exact or one that
  190. * is in front. On return the exact name is stored here.
  191. * \param namelen Number of sub identifiers in the name upon entry. On
  192. * return the length of the exact name is stored here.
  193. * \param exact If not zero, the name must match exactly. Otherwise we
  194. * want the first name that is following the given one.
  195. * \param varlen Size of the variable.
  196. */
  197. static uint8_t *MibVarsSysGet(const SNMPVAR * vp, OID * name, size_t * namelen, int exact, size_t * varlen, WMETHOD ** wmethod)
  198. {
  199. static uint8_t empty[1];
  200. int rc;
  201. OID *fullname;
  202. size_t fullnamelen = base_oidlen + vp->var_namelen + 1;
  203. fullname = malloc(fullnamelen * sizeof(OID));
  204. memcpy(fullname, base_oid, base_oidlen * sizeof(OID));
  205. memcpy(fullname + base_oidlen, vp->var_name, vp->var_namelen * sizeof(OID));
  206. *(fullname + fullnamelen - 1) = 0;
  207. rc = SnmpOidCmp(name, *namelen, fullname, fullnamelen);
  208. if ((exact && rc) || (!exact && rc >= 0)) {
  209. free(fullname);
  210. return NULL;
  211. }
  212. memcpy(name, fullname, fullnamelen * sizeof(OID));
  213. free(fullname);
  214. *namelen = fullnamelen;
  215. *wmethod = NULL;
  216. *varlen = sizeof(long);
  217. switch (vp->var_magic) {
  218. case MAG_SYS_DESCR:
  219. *varlen = strlen(sys_descr);
  220. return (uint8_t *) sys_descr;
  221. case MAG_SYS_OID:
  222. *varlen = sizeof(sys_oid);
  223. return (uint8_t *) sys_oid;
  224. case MAG_SYS_UPTIME:
  225. sys_uptime = time(NULL) - sys_starttime;
  226. sys_uptime *= 100;
  227. return (uint8_t *) & sys_uptime;
  228. case MAG_SYS_CONTACT:
  229. *wmethod = MibVarsSysSet;
  230. if (sys_contact) {
  231. *varlen = strlen(sys_contact);
  232. return (uint8_t *) sys_contact;
  233. }
  234. *varlen = 0;
  235. return empty;
  236. case MAG_SYS_NAME:
  237. *wmethod = MibVarsSysSet;
  238. if (sys_name) {
  239. *varlen = strlen(sys_name);
  240. return (uint8_t *) sys_name;
  241. }
  242. *varlen = 0;
  243. return empty;
  244. case MAG_SYS_LOCATION:
  245. *wmethod = MibVarsSysSet;
  246. if (sys_location) {
  247. *varlen = strlen(sys_location);
  248. return (uint8_t *) sys_location;
  249. }
  250. *varlen = 0;
  251. return empty;
  252. case MAG_SYS_SERVICES:
  253. return (uint8_t *) & sys_services;
  254. }
  255. return NULL;
  256. }