snmp_core.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:38k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: snmp_core.c,v 1.34.2.1 1999/02/14 08:35:01 wessels Exp $
  3.  *
  4.  * DEBUG: section 49    SNMP support
  5.  * AUTHOR: Glenn Chisholm
  6.  *
  7.  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
  8.  * ----------------------------------------------------------
  9.  *
  10.  *  Squid is the result of efforts by numerous individuals from the
  11.  *  Internet community.  Development is led by Duane Wessels of the
  12.  *  National Laboratory for Applied Network Research and funded by the
  13.  *  National Science Foundation.  Squid is Copyrighted (C) 1998 by
  14.  *  Duane Wessels and the University of California San Diego.  Please
  15.  *  see the COPYRIGHT file for full details.  Squid incorporates
  16.  *  software developed and/or copyrighted by other sources.  Please see
  17.  *  the CREDITS file for full details.
  18.  *
  19.  *  This program is free software; you can redistribute it and/or modify
  20.  *  it under the terms of the GNU General Public License as published by
  21.  *  the Free Software Foundation; either version 2 of the License, or
  22.  *  (at your option) any later version.
  23.  *
  24.  *  This program is distributed in the hope that it will be useful,
  25.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27.  *  GNU General Public License for more details.
  28.  *
  29.  *  You should have received a copy of the GNU General Public License
  30.  *  along with this program; if not, write to the Free Software
  31.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  32.  *
  33.  */
  34. #include "squid.h"
  35. #include "cache_snmp.h"
  36. #define SNMP_REQUEST_SIZE 4096
  37. #define MAX_PROTOSTAT 5
  38. struct _mib_tree_entry {
  39.     oid *name;
  40.     int len;
  41.     oid_ParseFn *parsefunction;
  42.     int children;
  43.     struct _mib_tree_entry **leaves;
  44.     struct _mib_tree_entry *parent;
  45. };
  46. typedef struct _mib_tree_entry mib_tree_entry;
  47. mib_tree_entry *mib_tree_head;
  48. #if STDC_HEADERS
  49. static mib_tree_entry *snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, int children,...);
  50. static oid *snmpCreateOid(int length,...);
  51. #else
  52. static mib_tree_entry *snmpAddNode();
  53. static oid *snmpCreateOid();
  54. #endif
  55. extern void (*snmplib_debug_hook) (int, char *);
  56. static void snmpDecodePacket(snmp_request_t * rq);
  57. static void snmpConstructReponse(snmp_request_t * rq);
  58. static struct snmp_pdu *snmpAgentResponse(struct snmp_pdu *PDU);
  59. static oid_ParseFn *snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen);
  60. static oid_ParseFn *snmpTreeGet(oid * Current, snint CurrentLen);
  61. static mib_tree_entry *snmpTreeEntry(oid entry, snint len, mib_tree_entry * current);
  62. static mib_tree_entry *snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current);
  63. static oid *snmpOidDup(oid * A, snint ALen);
  64. static void snmpSnmplibDebug(int lvl, char *buf);
  65. /*
  66.  * The functions used during startup:
  67.  * snmpInit
  68.  * snmpConnectionOpen
  69.  * snmpConnectionShutdown
  70.  * snmpConnectionClose
  71.  */
  72. /*
  73.  * Turns the MIB into a Tree structure. Called during the startup process.
  74.  */
  75. void
  76. snmpInit(void)
  77. {
  78.     debug(49, 5) ("snmpInit: Called.n");
  79.     debug(49, 5) ("snmpInit: Building SNMP mib tree structuren");
  80.     snmplib_debug_hook = snmpSnmplibDebug;
  81.     mib_tree_head = snmpAddNode(snmpCreateOid(1, 1),
  82. 1, NULL, 1,
  83. snmpAddNode(snmpCreateOid(2, 1, 3),
  84.     2, NULL, 1,
  85.     snmpAddNode(snmpCreateOid(3, 1, 3, 6),
  86. 3, NULL, 1,
  87. snmpAddNode(snmpCreateOid(4, 1, 3, 6, 1),
  88.     4, NULL, 1,
  89.     snmpAddNode(snmpCreateOid(5, 1, 3, 6, 1, 4),
  90. 5, NULL, 1,
  91. snmpAddNode(snmpCreateOid(6, 1, 3, 6, 1, 4, 1),
  92.     6, NULL, 1,
  93.     snmpAddNode(snmpCreateOid(7, 1, 3, 6, 1, 4, 1, 3495),
  94. 7, NULL, 1,
  95. snmpAddNode(snmpCreateOid(LEN_SQUIDMIB, SQUIDMIB),
  96.     8, NULL, 5,
  97.     snmpAddNode(snmpCreateOid(LEN_SQ_SYS, SQ_SYS),
  98. LEN_SQ_SYS, NULL, 3,
  99. snmpAddNode(snmpCreateOid(LEN_SQ_SYS + 1, SQ_SYS, 1),
  100.     LEN_SQ_SYS + 1, snmp_sysFn, 1,
  101.     snmpAddNode(snmpCreateOid(LEN_SQ_SYS + 2, SQ_SYS, 1, 0),
  102. LEN_SQ_SYS + 2, snmp_sysFn, 0)),
  103. snmpAddNode(snmpCreateOid(LEN_SQ_SYS + 1, SQ_SYS, 2),
  104.     LEN_SQ_SYS + 1, snmp_sysFn, 1,
  105.     snmpAddNode(snmpCreateOid(LEN_SQ_SYS + 2, SQ_SYS, 2, 0),
  106. LEN_SQ_SYS + 2, snmp_sysFn, 0)),
  107. snmpAddNode(snmpCreateOid(LEN_SQ_SYS + 1, SQ_SYS, 3),
  108.     LEN_SQ_SYS + 1, snmp_sysFn, 1,
  109.     snmpAddNode(snmpCreateOid(LEN_SQ_SYS + 2, SQ_SYS, 3, 0),
  110. LEN_SQ_SYS + 2, snmp_sysFn, 0))),
  111.     snmpAddNode(snmpCreateOid(LEN_SQ_CONF, SQ_CONF),
  112. LEN_SQ_CONF, NULL, 5,
  113. snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 1, SQ_CONF, 1),
  114.     LEN_SQ_CONF + 1, snmp_confFn, 1,
  115.     snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 1, 0),
  116. LEN_SQ_CONF + 2, snmp_confFn, 0)),
  117. snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 1, SQ_CONF, 2),
  118.     LEN_SQ_CONF + 1, snmp_confFn, 1,
  119.     snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 2, 0),
  120. LEN_SQ_CONF + 2, snmp_confFn, 0)),
  121. snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 1, SQ_CONF, 3),
  122.     LEN_SQ_CONF + 1, snmp_confFn, 1,
  123.     snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 3, 0),
  124. LEN_SQ_CONF + 2, snmp_confFn, 0)),
  125. snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 1, SQ_CONF, 4),
  126.     LEN_SQ_CONF + 1, snmp_confFn, 1,
  127.     snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 4, 0),
  128. LEN_SQ_CONF + 2, snmp_confFn, 0)),
  129. snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 1, SQ_CONF, 5),
  130.     LEN_SQ_CONF + 1, NULL, 4,
  131.     snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 5, 1),
  132. LEN_SQ_CONF + 2, snmp_confFn, 1,
  133. snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 3, SQ_CONF, 5, 1, 0),
  134.     LEN_SQ_CONF + 3, snmp_confFn, 0)),
  135.     snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 5, 2),
  136. LEN_SQ_CONF + 2, snmp_confFn, 1,
  137. snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 3, SQ_CONF, 5, 2, 0),
  138.     LEN_SQ_CONF + 3, snmp_confFn, 0)),
  139.     snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 5, 3),
  140. LEN_SQ_CONF + 2, snmp_confFn, 1,
  141. snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 3, SQ_CONF, 5, 3, 0),
  142.     LEN_SQ_CONF + 3, snmp_confFn, 0)),
  143.     snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 2, SQ_CONF, 5, 4),
  144. LEN_SQ_CONF + 2, snmp_confFn, 1,
  145. snmpAddNode(snmpCreateOid(LEN_SQ_CONF + 3, SQ_CONF, 5, 4, 0),
  146.     LEN_SQ_CONF + 3, snmp_confFn, 0)))),
  147.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF, SQ_PRF),
  148. LEN_SQ_PRF, NULL, 2,
  149. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, 1),
  150.     LEN_SQ_PRF + 1, NULL, 11,
  151.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 1),
  152. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  153. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 1, 0),
  154.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0)),
  155.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 2),
  156. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  157. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 2, 0),
  158.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0)),
  159.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 3),
  160. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  161. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 3, 0),
  162.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0)),
  163.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 4),
  164. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  165. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 4, 0),
  166.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0)),
  167.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 5),
  168. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  169. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 5, 0),
  170.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0)),
  171.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 6),
  172. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  173. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 6, 0),
  174.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0)),
  175.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 7),
  176. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  177. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 7, 0),
  178.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0)),
  179.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 8),
  180. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  181. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 8, 0),
  182.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0)),
  183.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 9),
  184. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  185. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 9, 0),
  186.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0)),
  187.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 10),
  188. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  189. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 10, 0),
  190.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0)),
  191.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 1, 11),
  192. LEN_SQ_PRF + 2, snmp_prfSysFn, 1,
  193. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 1, 11, 0),
  194.     LEN_SQ_PRF + 3, snmp_prfSysFn, 0))),
  195. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 1, SQ_PRF, 2),
  196.     LEN_SQ_PRF + 1, NULL, 2,
  197.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 2, 1),
  198. LEN_SQ_PRF + 2, NULL, 15,
  199. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 1),
  200.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  201.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 1, 0),
  202. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  203. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 2),
  204.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  205.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 2, 0),
  206. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  207. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 3),
  208.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  209.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 3, 0),
  210. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  211. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 4),
  212.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  213.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 4, 0),
  214. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  215. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 5),
  216.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  217.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 5, 0),
  218. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  219. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 6),
  220.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  221.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 6, 0),
  222. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  223. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 7),
  224.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  225.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 7, 0),
  226. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  227. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 8),
  228.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  229.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 8, 0),
  230. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  231. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 9),
  232.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  233.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 9, 0),
  234. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  235. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 10),
  236.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  237.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 10, 0),
  238. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  239. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 11),
  240.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  241.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 11, 0),
  242. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  243. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 12),
  244.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  245.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 12, 0),
  246. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  247. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 13),
  248.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  249.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 13, 0),
  250. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  251. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 14),
  252.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  253.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 14, 0),
  254. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0)),
  255. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 1, 15),
  256.     LEN_SQ_PRF + 3, snmp_prfProtoFn, 1,
  257.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 1, 15, 0),
  258. LEN_SQ_PRF + 4, snmp_prfProtoFn, 0))),
  259.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 2, SQ_PRF, 2, 2),
  260. LEN_SQ_PRF + 2, NULL, 1,
  261. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 3, SQ_PRF, 2, 2, 1),
  262.     LEN_SQ_PRF + 3, NULL, 10,
  263.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 1),
  264. LEN_SQ_PRF + 4, NULL, 3,
  265. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 1, 1),
  266.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  267. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 1, 5),
  268.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  269. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 1, 60),
  270.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0)),
  271.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 2),
  272. LEN_SQ_PRF + 4, NULL, 3,
  273. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 2, 1),
  274.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  275. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 2, 5),
  276.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  277. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 2, 60),
  278.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0)),
  279.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 3),
  280. LEN_SQ_PRF + 4, NULL, 3,
  281. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 3, 1),
  282.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  283. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 3, 5),
  284.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  285. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 3, 60),
  286.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0)),
  287.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 4),
  288. LEN_SQ_PRF + 4, NULL, 3,
  289. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 4, 1),
  290.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  291. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 4, 5),
  292.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  293. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 4, 60),
  294.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0)),
  295.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 5),
  296. LEN_SQ_PRF + 4, NULL, 3,
  297. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 5, 1),
  298.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  299. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 5, 5),
  300.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  301. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 5, 60),
  302.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0)),
  303.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 6),
  304. LEN_SQ_PRF + 4, NULL, 3,
  305. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 6, 1),
  306.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  307. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 6, 5),
  308.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  309. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 6, 60),
  310.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0)),
  311.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 7),
  312. LEN_SQ_PRF + 4, NULL, 3,
  313. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 7, 1),
  314.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  315. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 7, 5),
  316.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  317. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 7, 60),
  318.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0)),
  319.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 8),
  320. LEN_SQ_PRF + 4, NULL, 3,
  321. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 8, 1),
  322.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  323. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 8, 5),
  324.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  325. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 8, 60),
  326.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0)),
  327.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 9),
  328. LEN_SQ_PRF + 4, NULL, 3,
  329. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 9, 1),
  330.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  331. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 9, 5),
  332.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  333. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 9, 60),
  334.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0)),
  335.     snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 4, SQ_PRF, 2, 2, 1, 10),
  336. LEN_SQ_PRF + 4, NULL, 3,
  337. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 10, 1),
  338.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  339. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 10, 5),
  340.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0),
  341. snmpAddNode(snmpCreateOid(LEN_SQ_PRF + 5, SQ_PRF, 2, 2, 1, 10, 60),
  342.     LEN_SQ_PRF + 5, snmp_prfProtoFn, 0)))))),
  343.     snmpAddNode(snmpCreateOid(LEN_SQ_NET, SQ_NET),
  344. LEN_SQ_NET, NULL, 3,
  345. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, 1),
  346.     LEN_SQ_NET + 1, NULL, 8,
  347.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 1),
  348. LEN_SQ_NET + 2, snmp_netIpFn, 1,
  349. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 1, 1, 0),
  350.     LEN_SQ_NET + 3, snmp_netIpFn, 0)),
  351.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 2),
  352. LEN_SQ_NET + 2, snmp_netIpFn, 1,
  353. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 1, 2, 0),
  354.     LEN_SQ_NET + 3, snmp_netIpFn, 0)),
  355.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 3),
  356. LEN_SQ_NET + 2, snmp_netIpFn, 1,
  357. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 1, 3, 0),
  358.     LEN_SQ_NET + 3, snmp_netIpFn, 0)),
  359.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 4),
  360. LEN_SQ_NET + 2, snmp_netIpFn, 1,
  361. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 1, 4, 0),
  362.     LEN_SQ_NET + 3, snmp_netIpFn, 0)),
  363.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 5),
  364. LEN_SQ_NET + 2, snmp_netIpFn, 1,
  365. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 1, 5, 0),
  366.     LEN_SQ_NET + 3, snmp_netIpFn, 0)),
  367.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 6),
  368. LEN_SQ_NET + 2, snmp_netIpFn, 1,
  369. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 1, 6, 0),
  370.     LEN_SQ_NET + 3, snmp_netIpFn, 0)),
  371.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 7),
  372. LEN_SQ_NET + 2, snmp_netIpFn, 1,
  373. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 1, 7, 0),
  374.     LEN_SQ_NET + 3, snmp_netIpFn, 0)),
  375.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 1, 8),
  376. LEN_SQ_NET + 2, snmp_netIpFn, 1,
  377. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 1, 8, 0),
  378.     LEN_SQ_NET + 3, snmp_netIpFn, 0))),
  379. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, 2),
  380.     LEN_SQ_NET + 1, NULL, 7,
  381.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 1),
  382. LEN_SQ_NET + 2, snmp_netFqdnFn, 1,
  383. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 2, 1, 0),
  384.     LEN_SQ_NET + 3, snmp_netFqdnFn, 0)),
  385.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 2),
  386. LEN_SQ_NET + 2, snmp_netFqdnFn, 1,
  387. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 2, 2, 0),
  388.     LEN_SQ_NET + 3, snmp_netFqdnFn, 0)),
  389.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 3),
  390. LEN_SQ_NET + 2, snmp_netFqdnFn, 1,
  391. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 2, 3, 0),
  392.     LEN_SQ_NET + 3, snmp_netFqdnFn, 0)),
  393.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 4),
  394. LEN_SQ_NET + 2, snmp_netFqdnFn, 1,
  395. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 2, 4, 0),
  396.     LEN_SQ_NET + 3, snmp_netFqdnFn, 0)),
  397.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 5),
  398. LEN_SQ_NET + 2, snmp_netFqdnFn, 1,
  399. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 2, 5, 0),
  400.     LEN_SQ_NET + 3, snmp_netFqdnFn, 0)),
  401.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 6),
  402. LEN_SQ_NET + 2, snmp_netFqdnFn, 1,
  403. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 2, 6, 0),
  404.     LEN_SQ_NET + 3, snmp_netFqdnFn, 0)),
  405.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 2, 7),
  406. LEN_SQ_NET + 2, snmp_netFqdnFn, 1,
  407. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 2, 7, 0),
  408.     LEN_SQ_NET + 3, snmp_netFqdnFn, 0))),
  409. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 1, SQ_NET, 3),
  410.     LEN_SQ_NET + 1, NULL, 3,
  411.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 3, 1),
  412. LEN_SQ_NET + 2, snmp_netDnsFn, 1,
  413. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 3, 1, 0),
  414.     LEN_SQ_NET + 3, snmp_netDnsFn, 0)),
  415.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 3, 2),
  416. LEN_SQ_NET + 2, snmp_netDnsFn, 1,
  417. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 3, 2, 0),
  418.     LEN_SQ_NET + 3, snmp_netDnsFn, 0)),
  419.     snmpAddNode(snmpCreateOid(LEN_SQ_NET + 2, SQ_NET, 3, 3),
  420. LEN_SQ_NET + 2, snmp_netDnsFn, 1,
  421. snmpAddNode(snmpCreateOid(LEN_SQ_NET + 3, SQ_NET, 3, 3, 0),
  422.     LEN_SQ_NET + 3, snmp_netDnsFn, 0)))),
  423.     snmpAddNode(snmpCreateOid(LEN_SQ_MESH, SQ_MESH),
  424. LEN_SQ_MESH, NULL, 2,
  425. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 1),
  426.     LEN_SQ_MESH + 1, NULL, 1,
  427.     snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 1, 1),
  428. LEN_SQ_MESH + 2, NULL, 13,
  429. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 1),
  430.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  431. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 2),
  432.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  433. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 3),
  434.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  435. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 4),
  436.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  437. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 5),
  438.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  439. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 6),
  440.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  441. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 7),
  442.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  443. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 8),
  444.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  445. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 9),
  446.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  447. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 10),
  448.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  449. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 11),
  450.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  451. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 12),
  452.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0),
  453. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 1, 1, 13),
  454.     LEN_SQ_MESH + 3, snmp_meshPtblFn, 0))),
  455. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 1, SQ_MESH, 2),
  456.     LEN_SQ_MESH + 1, NULL, 1,
  457.     snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 2, SQ_MESH, 2, 1),
  458. LEN_SQ_MESH + 2, NULL, 9,
  459. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 1),
  460.     LEN_SQ_MESH + 3, snmp_meshCtblFn, 0),
  461. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 2),
  462.     LEN_SQ_MESH + 3, snmp_meshCtblFn, 0),
  463. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 3),
  464.     LEN_SQ_MESH + 3, snmp_meshCtblFn, 0),
  465. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 4),
  466.     LEN_SQ_MESH + 3, snmp_meshCtblFn, 0),
  467. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 5),
  468.     LEN_SQ_MESH + 3, snmp_meshCtblFn, 0),
  469. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 6),
  470.     LEN_SQ_MESH + 3, snmp_meshCtblFn, 0),
  471. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 7),
  472.     LEN_SQ_MESH + 3, snmp_meshCtblFn, 0),
  473. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 8),
  474.     LEN_SQ_MESH + 3, snmp_meshCtblFn, 0),
  475. snmpAddNode(snmpCreateOid(LEN_SQ_MESH + 3, SQ_MESH, 2, 1, 9),
  476.     LEN_SQ_MESH + 3, snmp_meshCtblFn, 0))))
  477. )
  478.     )
  479. )
  480.     )
  481. )
  482.     )
  483. )
  484. );
  485.     debug(49, 9) ("snmpInit: Completed SNMP mib tree structuren");
  486. }
  487. void
  488. snmpConnectionOpen(void)
  489. {
  490.     u_short port;
  491.     struct sockaddr_in xaddr;
  492.     socklen_t len;
  493.     int x;
  494.     debug(49, 5) ("snmpConnectionOpen: Calledn");
  495.     if ((port = Config.Port.snmp) > (u_short) 0) {
  496. enter_suid();
  497. theInSnmpConnection = comm_open(SOCK_DGRAM,
  498.     0,
  499.     Config.Addrs.snmp_incoming,
  500.     port,
  501.     COMM_NONBLOCKING,
  502.     "SNMP Port");
  503. leave_suid();
  504. if (theInSnmpConnection < 0)
  505.     fatal("Cannot open snmp Port");
  506. commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
  507. debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.n",
  508.     (int) port, theInSnmpConnection);
  509. if (Config.Addrs.snmp_outgoing.s_addr != no_addr.s_addr) {
  510.     enter_suid();
  511.     theOutSnmpConnection = comm_open(SOCK_DGRAM,
  512. 0,
  513. Config.Addrs.snmp_outgoing,
  514. port,
  515. COMM_NONBLOCKING,
  516. "SNMP Port");
  517.     leave_suid();
  518.     if (theOutSnmpConnection < 0)
  519. fatal("Cannot open Outgoing SNMP Port");
  520.     commSetSelect(theOutSnmpConnection,
  521. COMM_SELECT_READ,
  522. snmpHandleUdp,
  523. NULL, 0);
  524.     debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.n",
  525. (int) port, theOutSnmpConnection);
  526.     fd_note(theOutSnmpConnection, "Outgoing SNMP socket");
  527.     fd_note(theInSnmpConnection, "Incoming SNMP socket");
  528. } else {
  529.     theOutSnmpConnection = theInSnmpConnection;
  530. }
  531. memset(&theOutSNMPAddr, '', sizeof(struct in_addr));
  532. len = sizeof(struct sockaddr_in);
  533. memset(&xaddr, '', len);
  534. x = getsockname(theOutSnmpConnection,
  535.     (struct sockaddr *) &xaddr, &len);
  536. if (x < 0)
  537.     debug(51, 1) ("theOutSnmpConnection FD %d: getsockname: %sn",
  538. theOutSnmpConnection, xstrerror());
  539. else
  540.     theOutSNMPAddr = xaddr.sin_addr;
  541.     }
  542. }
  543. void
  544. snmpConnectionShutdown(void)
  545. {
  546.     if (theInSnmpConnection < 0)
  547. return;
  548.     if (theInSnmpConnection != theOutSnmpConnection) {
  549. debug(49, 1) ("FD %d Closing SNMP socketn", theInSnmpConnection);
  550. comm_close(theInSnmpConnection);
  551.     }
  552.     /*
  553.      * Here we set 'theInSnmpConnection' to -1 even though the SNMP 'in'
  554.      * and 'out' sockets might be just one FD.  This prevents this
  555.      * function from executing repeatedly.  When we are really ready to
  556.      * exit or restart, main will comm_close the 'out' descriptor.
  557.      */ theInSnmpConnection = -1;
  558.     /*
  559.      * Normally we only write to the outgoing SNMP socket, but we
  560.      * also have a read handler there to catch messages sent to that
  561.      * specific interface.  During shutdown, we must disable reading
  562.      * on the outgoing socket.
  563.      */
  564.     assert(theOutSnmpConnection > -1);
  565.     commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0);
  566. }
  567. void
  568. snmpConnectionClose(void)
  569. {
  570.     snmpConnectionShutdown();
  571.     if (theOutSnmpConnection > -1) {
  572. debug(49, 1) ("FD %d Closing SNMP socketn", theOutSnmpConnection);
  573. comm_close(theOutSnmpConnection);
  574.     }
  575. }
  576. /*
  577.  * Functions for handling the requests.
  578.  */
  579. /*
  580.  * Accept the UDP packet
  581.  */
  582. void
  583. snmpHandleUdp(int sock, void *not_used)
  584. {
  585.     LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE);
  586.     struct sockaddr_in from;
  587.     socklen_t from_len;
  588.     snmp_request_t *snmp_rq;
  589.     int len;
  590.     debug(49, 5) ("snmpHandleUdp: Called.n");
  591.     commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
  592.     from_len = sizeof(struct sockaddr_in);
  593.     memset(&from, '', from_len);
  594.     Counter.syscalls.sock.recvfroms++;
  595.     len = recvfrom(sock,
  596. buf,
  597. SNMP_REQUEST_SIZE,
  598. 0,
  599. (struct sockaddr *) &from,
  600. &from_len);
  601.     if (len > 0) {
  602. buf[len] = '';
  603. debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.n",
  604.     sock,
  605.     len,
  606.     inet_ntoa(from.sin_addr));
  607. snmp_rq = xcalloc(1, sizeof(snmp_request_t));
  608. snmp_rq->buf = (u_char *) buf;
  609. snmp_rq->len = len;
  610. snmp_rq->sock = sock;
  611. snmp_rq->outbuf = xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE);
  612. xmemcpy(&snmp_rq->from, &from, sizeof(struct sockaddr_in));
  613. snmpDecodePacket(snmp_rq);
  614. xfree(snmp_rq);
  615.     } else {
  616. debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %sn", sock, xstrerror());
  617.     }
  618. }
  619. /*
  620.  * Turn SNMP packet into a PDU, check available ACL's
  621.  */
  622. void
  623. snmpDecodePacket(snmp_request_t * rq)
  624. {
  625.     struct snmp_pdu *PDU;
  626.     struct snmp_session Session;
  627.     aclCheck_t checklist;
  628.     u_char *Community;
  629.     u_char *buf = rq->buf;
  630.     int len = rq->len;
  631.     int allow = 0;
  632.     debug(49, 5) ("snmpDecodePacket: Called.n");
  633.     /* Now that we have the data, turn it into a PDU */
  634.     PDU = snmp_pdu_create(0);
  635.     Session.Version = SNMP_VERSION_1;
  636.     Community = snmp_parse(&Session, PDU, buf, len);
  637.     checklist.src_addr = rq->from.sin_addr;
  638.     checklist.snmp_community = (char *) Community;
  639.     allow = aclCheckFast(Config.accessList.snmp, &checklist);
  640.     if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) {
  641. rq->community = Community;
  642. rq->PDU = PDU;
  643. debug(49, 5) ("snmpAgentParse: reqid=[%d]n", PDU->reqid);
  644. snmpConstructReponse(rq);
  645.     } else {
  646. debug(49, 0) ("Failed SNMP agent query from : %s.n",
  647.     inet_ntoa(rq->from.sin_addr));
  648. snmp_free_pdu(PDU);
  649.     }
  650. }
  651. /*
  652.  * Packet OK, ACL Check OK, Create reponse.
  653.  */
  654. void
  655. snmpConstructReponse(snmp_request_t * rq)
  656. {
  657.     struct snmp_session Session;
  658.     struct snmp_pdu *RespPDU;
  659.     int ret;
  660.     debug(49, 5) ("snmpConstructReponse: Called.n");
  661.     RespPDU = snmpAgentResponse(rq->PDU);
  662.     snmp_free_pdu(rq->PDU);
  663.     if (RespPDU != NULL) {
  664. Session.Version = SNMP_VERSION_1;
  665. Session.community = rq->community;
  666. Session.community_len = strlen((char *) rq->community);
  667. ret = snmp_build(&Session, RespPDU, rq->outbuf, &rq->outlen);
  668. sendto(rq->sock, rq->outbuf, rq->outlen, 0, (struct sockaddr *) &rq->from, sizeof(rq->from));
  669. snmp_free_pdu(RespPDU);
  670. xfree(rq->outbuf);
  671.     }
  672. }
  673. /*
  674.  * Decide how to respond to the request, construct a response and
  675.  * return the response to the requester.
  676.  * 
  677.  * If configured forward any reponses which are not for this agent.
  678.  */
  679. struct snmp_pdu *
  680. snmpAgentResponse(struct snmp_pdu *PDU)
  681. {
  682.     struct snmp_pdu *Answer = NULL;
  683.     oid_ParseFn *ParseFn = NULL;
  684.     variable_list *VarPtr, *VarNew = NULL, **VarPtrP;
  685.     int index = 0;
  686.     debug(49, 5) ("snmpAgentResponse: Called.n");
  687.     if ((Answer = snmp_pdu_create(SNMP_PDU_RESPONSE))) {
  688. Answer->reqid = PDU->reqid;
  689. Answer->errindex = 0;
  690. if (PDU->command == SNMP_PDU_GET) {
  691.     variable_list **RespVars;
  692.     RespVars = &(Answer->variables);
  693.     /* Loop through all variables */
  694.     for (VarPtrP = &(PDU->variables);
  695. *VarPtrP;
  696. VarPtrP = &((*VarPtrP)->next_variable)) {
  697. VarPtr = *VarPtrP;
  698. index++;
  699. /* Find the parsing function for this variable */
  700. ParseFn = snmpTreeGet(VarPtr->name, VarPtr->name_length);
  701. if (ParseFn == NULL) {
  702.     Answer->errstat = SNMP_ERR_NOSUCHNAME;
  703.     debug(49, 5) ("snmpAgentResponse: No such oid. ");
  704. } else
  705.     VarNew = (*ParseFn) (VarPtr, (snint *) & (Answer->errstat));
  706. /* Was there an error? */
  707. if ((Answer->errstat != SNMP_ERR_NOERROR) ||
  708.     (VarNew == NULL)) {
  709.     Answer->errindex = index;
  710.     debug(49, 5) ("snmpAgentParse: successful.n");
  711.     /* Just copy the rest of the variables.  Quickly. */
  712.     *RespVars = VarPtr;
  713.     *VarPtrP = NULL;
  714.     return (Answer);
  715. }
  716. /* No error.  Insert this var at the end, and move on to the next.
  717.  */
  718. *RespVars = VarNew;
  719. RespVars = &(VarNew->next_variable);
  720.     }
  721.     return (Answer);
  722. } else if (PDU->command == SNMP_PDU_GETNEXT) {
  723.     oid *NextOidName = NULL;
  724.     int NextOidNameLen = 0;
  725.     ParseFn = snmpTreeNext(PDU->variables->name, PDU->variables->name_length,
  726. &(NextOidName), (snint *) & NextOidNameLen);
  727.     if (ParseFn == NULL) {
  728. Answer->errstat = SNMP_ERR_NOSUCHNAME;
  729. debug(49, 5) ("snmpAgentResponse: No such oid: ");
  730. snmpDebugOid(5, PDU->variables->name, PDU->variables->name_length);
  731.     } else {
  732. xfree(PDU->variables->name);
  733. PDU->variables->name = NextOidName;
  734. PDU->variables->name_length = NextOidNameLen;
  735. VarNew = (*ParseFn) (PDU->variables, (snint *) & Answer->errstat);
  736.     }
  737.     /* Was there an error? */
  738.     if (Answer->errstat != SNMP_ERR_NOERROR) {
  739. Answer->errindex = 1;
  740. Answer->variables = PDU->variables;
  741. PDU->variables = NULL;
  742.     } else {
  743. Answer->variables = VarNew;
  744.     }
  745. } else {
  746.     snmp_free_pdu(Answer);
  747.     Answer = NULL;
  748. }
  749.     }
  750.     return (Answer);
  751. }
  752. oid_ParseFn *
  753. snmpTreeGet(oid * Current, snint CurrentLen)
  754. {
  755.     oid_ParseFn *Fn = NULL;
  756.     mib_tree_entry *mibTreeEntry = NULL;
  757.     int count = 0;
  758.     debug(49, 5) ("snmpTreeGet: Calledn");
  759.     debug(49, 6) ("snmpTreeGet: Current : n");
  760.     snmpDebugOid(6, Current, CurrentLen);
  761.     mibTreeEntry = mib_tree_head;
  762.     if (Current[count] == mibTreeEntry->name[count]) {
  763. count++;
  764. while ((mibTreeEntry) && (count < CurrentLen)) {
  765.     mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
  766.     count++;
  767. }
  768.     }
  769.     if (mibTreeEntry) {
  770. Fn = mibTreeEntry->parsefunction;
  771.     }
  772.     debug(49, 5) ("snmpTreeGet: returnn");
  773.     return (Fn);
  774. }
  775. oid_ParseFn *
  776. snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen)
  777. {
  778.     oid_ParseFn *Fn = NULL;
  779.     mib_tree_entry *mibTreeEntry = NULL, *nextoid = NULL;
  780.     int count = 0;
  781.     debug(49, 5) ("snmpTreeNext: Calledn");
  782.     debug(49, 6) ("snmpTreeNext: Current : n");
  783.     snmpDebugOid(6, Current, CurrentLen);
  784.     mibTreeEntry = mib_tree_head;
  785.     if (Current[count] == mibTreeEntry->name[count]) {
  786. count++;
  787. while ((mibTreeEntry) && (count < CurrentLen)) {
  788.     mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);
  789.     count++;
  790. }
  791. debug(49, 5) ("snmpTreeNext: Recursed down to requested objectn");
  792. if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {
  793.     count--;
  794.     nextoid = snmpTreeSiblingEntry(Current[count], count, mibTreeEntry->parent);
  795.     if (nextoid) {
  796. mibTreeEntry = nextoid;
  797. count++;
  798.     } else {
  799. debug(49, 5) ("snmpTreeNext: Attempting to recurse up for next objectn");
  800. while (!nextoid) {
  801.     count--;
  802.     nextoid = mibTreeEntry->parent;
  803.     mibTreeEntry = snmpTreeEntry(Current[count] + 1, count, nextoid->parent);
  804.     if (!mibTreeEntry) {
  805. mibTreeEntry = nextoid;
  806. nextoid = NULL;
  807.     }
  808. }
  809.     }
  810. }
  811. debug(49, 5) ("snmpTreeNext: Past Secondn");
  812. while ((mibTreeEntry) && (!mibTreeEntry->parsefunction)) {
  813.     mibTreeEntry = mibTreeEntry->leaves[0];
  814. }
  815. if ((mibTreeEntry) && (mibTreeEntry->children == 1))
  816.     mibTreeEntry = mibTreeEntry->leaves[0];
  817.     }
  818.     if (mibTreeEntry) {
  819. *Next = snmpOidDup(mibTreeEntry->name, mibTreeEntry->len);
  820. *NextLen = mibTreeEntry->len;
  821. Fn = mibTreeEntry->parsefunction;
  822.     }
  823.     debug(49, 5) ("snmpTreeNext: returnn");
  824.     return (Fn);
  825. }
  826. mib_tree_entry *
  827. snmpTreeSiblingEntry(oid entry, snint len, mib_tree_entry * current)
  828. {
  829.     mib_tree_entry *next = NULL;
  830.     int count = 0;
  831.     while ((!next) && (count < current->children)) {
  832. if (current->leaves[count]->name[len] == entry) {
  833.     next = current->leaves[count];
  834. }
  835. count++;
  836.     }
  837.     if (count < current->children) {
  838. next = current->leaves[count];
  839.     } else {
  840. next = NULL;
  841.     }
  842.     return (next);
  843. }
  844. mib_tree_entry *
  845. snmpTreeEntry(oid entry, snint len, mib_tree_entry * current)
  846. {
  847.     mib_tree_entry *next = NULL;
  848.     int count = 0;
  849.     while ((!next) && (count < current->children)) {
  850. if (current->leaves[count]->name[len] == entry) {
  851.     next = current->leaves[count];
  852. }
  853. count++;
  854.     }
  855.     return (next);
  856. }
  857. /*
  858.  * Utility functions
  859.  */
  860. /*
  861.  * Tree utility functions. 
  862.  */
  863. /*
  864.  * Adds a node to the MIB tree structure and adds the appropriate children
  865.  */
  866. mib_tree_entry *
  867. #if STDC_HEADERS
  868. snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, int children,...)
  869. #else
  870. snmpAddNode(va_alist)
  871.      va_dcl
  872. #endif
  873. {
  874. #if STDC_HEADERS
  875.     va_list args;
  876.     int loop;
  877.     mib_tree_entry *entry = NULL;
  878.     va_start(args, children);
  879. #else
  880.     va_list args;
  881.     oid *name = NULL;
  882.     int len = 0, children = 0, loop;
  883.     oid_ParseFn *parsefunction = NULL;
  884.     mib_tree_entry *entry = NULL;
  885.     va_start(args);
  886.     name = va_arg(args, oid *);
  887.     len = va_arg(args, int);
  888.     parsefunction = va_arg(args, oid_ParseFn *);
  889.     children = va_arg(args, int);
  890. #endif
  891.     debug(49, 6) ("snmpAddNode: Children : %d, Oid : n", children);
  892.     snmpDebugOid(6, name, len);
  893.     va_start(args, children);
  894.     entry = xmalloc(sizeof(mib_tree_entry));
  895.     entry->name = snmpOidDup(name, len);
  896.     entry->len = len;
  897.     entry->parsefunction = parsefunction;
  898.     entry->children = children;
  899.     if (children > 0) {
  900. entry->leaves = xmalloc(sizeof(mib_tree_entry *) * children);
  901. for (loop = 0; loop < children; loop++) {
  902.     entry->leaves[loop] = va_arg(args, mib_tree_entry *);
  903.     entry->leaves[loop]->parent = entry;
  904. }
  905.     }
  906.     return (entry);
  907. }
  908. /* End of tree utility functions */
  909. /* 
  910.  * Returns the list of parameters in an oid
  911.  */
  912. oid *
  913. #if STDC_HEADERS
  914. snmpCreateOid(int length,...)
  915. #else
  916. snmpCreateOid(va_alist)
  917.      va_dcl
  918. #endif
  919. {
  920. #if STDC_HEADERS
  921.     va_list args;
  922.     oid *new_oid;
  923.     int loop;
  924.     va_start(args, length);
  925. #else
  926.     va_list args;
  927.     int length = 0, loop;
  928.     oid *new_oid;
  929.     va_start(args);
  930.     length va_arg(args, int);
  931. #endif
  932.     new_oid = xmalloc(sizeof(oid) * length);
  933.     if (length > 0) {
  934. for (loop = 0; loop < length; loop++) {
  935.     new_oid[loop] = va_arg(args, int);
  936. }
  937.     }
  938.     return (new_oid);
  939. }
  940. /*
  941.  * Allocate space for, and copy, an OID.  Returns new oid.
  942.  */
  943. oid *
  944. snmpOidDup(oid * A, snint ALen)
  945. {
  946.     oid *Ans = xmalloc(sizeof(oid) * ALen);
  947.     xmemcpy(Ans, A, (sizeof(oid) * ALen));
  948.     return Ans;
  949. }
  950. /*
  951.  * Debug calls, prints out the OID for debugging purposes.
  952.  */
  953. void
  954. snmpDebugOid(int lvl, oid * Name, snint Len)
  955. {
  956.     char mbuf[16], objid[1024];
  957.     int x;
  958.     objid[0] = '';
  959.     for (x = 0; x < Len; x++) {
  960. snprintf(mbuf, sizeof(mbuf), ".%u", (unsigned int) Name[x]);
  961. strncat(objid, mbuf, sizeof(objid));
  962.     }
  963.     debug(49, lvl) ("   oid = %sn", objid);
  964. }
  965. static void
  966. snmpSnmplibDebug(int lvl, char *buf)
  967. {
  968.     debug(49, lvl) ("%s", buf);
  969. }