ldap-agent.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. /* --- BEGIN COPYRIGHT BLOCK ---
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2005 Red Hat, Inc.
  35. * All rights reserved.
  36. * --- END COPYRIGHT BLOCK --- */
  37. #ifdef HAVE_CONFIG_H
  38. # include <config.h>
  39. #endif
  40. #include <stdio.h>
  41. #include <time.h>
  42. #include "ldap-agent.h"
  43. static netsnmp_handler_registration *ops_handler = NULL;
  44. static netsnmp_handler_registration *entries_handler = NULL;
  45. static netsnmp_handler_registration *entity_handler = NULL;
  46. static netsnmp_table_array_callbacks ops_cb;
  47. static netsnmp_table_array_callbacks entries_cb;
  48. static netsnmp_table_array_callbacks entity_cb;
  49. extern server_instance *server_head;
  50. /* Set table oids */
  51. oid dsOpsTable_oid[] = { dsOpsTable_TABLE_OID };
  52. size_t dsOpsTable_oid_len = OID_LENGTH(dsOpsTable_oid);
  53. oid dsEntriesTable_oid[] = { dsEntriesTable_TABLE_OID };
  54. size_t dsEntriesTable_oid_len = OID_LENGTH(dsEntriesTable_oid);
  55. oid dsEntityTable_oid[] = {dsEntityTable_TABLE_OID };
  56. size_t dsEntityTable_oid_len = OID_LENGTH(dsEntityTable_oid);
  57. /* Set trap oids */
  58. oid snmptrap_oid[] = { snmptrap_OID };
  59. size_t snmptrap_oid_len = OID_LENGTH(snmptrap_oid);
  60. oid enterprise_oid[] = { enterprise_OID };
  61. size_t enterprise_oid_len = OID_LENGTH(enterprise_oid);
  62. /************************************************************
  63. * init_ldap_agent
  64. *
  65. * Initializes the agent and populates the stats table
  66. * with initial data.
  67. */
  68. void
  69. init_ldap_agent(void)
  70. {
  71. server_instance *serv_p = NULL;
  72. stats_table_context *new_row = NULL;
  73. /* Define and create the table */
  74. initialize_stats_table();
  75. /* Initialize data for each server in conf file */
  76. for (serv_p = server_head; serv_p != NULL; serv_p = serv_p->next) {
  77. /* Check if this row already exists. */
  78. if ((new_row = stats_table_find_row(serv_p->port)) == NULL) {
  79. /* Create a new row */
  80. if ((new_row = stats_table_create_row(serv_p->port)) != NULL) {
  81. /* Set pointer for entity table */
  82. new_row->entity_tbl = serv_p;
  83. /* Set previous state of server to unknown */
  84. serv_p->server_state = STATE_UNKNOWN;
  85. /* Insert new row into the table */
  86. snmp_log(LOG_DEBUG, "Inserting row for server: %d\n", serv_p->port);
  87. CONTAINER_INSERT(ops_cb.container, new_row);
  88. } else {
  89. /* error during malloc of row */
  90. snmp_log(LOG_ERR, "Error creating row for server: %d\n",
  91. serv_p->port);
  92. }
  93. }
  94. }
  95. /* Force load data into stats table */
  96. load_stats_table(NULL, NULL);
  97. }
  98. /************************************************************
  99. * initialize_stats_table
  100. *
  101. * Initializes the stats table by defining its contents,
  102. * how it's structured, and registering callbacks.
  103. */
  104. void
  105. initialize_stats_table(void)
  106. {
  107. netsnmp_table_registration_info *ops_table_info = NULL;
  108. netsnmp_table_registration_info *entries_table_info = NULL;
  109. netsnmp_table_registration_info *entity_table_info = NULL;
  110. /* This is a hacky way of figuring out if we are on Net-SNMP 5.2 or later */
  111. #ifdef NETSNMP_CACHE_AUTO_RELOAD
  112. netsnmp_cache *stats_table_cache = NULL;
  113. #endif
  114. if (ops_handler || entries_handler || entity_handler) {
  115. snmp_log(LOG_ERR, "initialize_stats_table called more than once.\n");
  116. return;
  117. }
  118. memset(&ops_cb, 0x00, sizeof(ops_cb));
  119. memset(&entries_cb, 0x00, sizeof(entries_cb));
  120. memset(&entity_cb, 0x00, sizeof(entity_cb));
  121. /* create table structures */
  122. ops_table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
  123. entries_table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
  124. entity_table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
  125. /* create handlers */
  126. ops_handler = netsnmp_create_handler_registration("dsOpsTable",
  127. netsnmp_table_array_helper_handler,
  128. dsOpsTable_oid,
  129. dsOpsTable_oid_len,
  130. HANDLER_CAN_RONLY);
  131. entries_handler = netsnmp_create_handler_registration("dsEntriesTable",
  132. netsnmp_table_array_helper_handler,
  133. dsEntriesTable_oid,
  134. dsEntriesTable_oid_len,
  135. HANDLER_CAN_RONLY);
  136. entity_handler = netsnmp_create_handler_registration("dsEntityTable",
  137. netsnmp_table_array_helper_handler,
  138. dsEntityTable_oid,
  139. dsEntityTable_oid_len,
  140. HANDLER_CAN_RONLY);
  141. if (!ops_handler || !entries_handler || !entity_handler ||
  142. !ops_table_info || !entries_table_info || !entity_table_info) {
  143. /* malloc failed */
  144. snmp_log(LOG_ERR, "malloc failed in initialize_stats_table\n");
  145. return;
  146. }
  147. /* define table structures */
  148. netsnmp_table_helper_add_index(ops_table_info, ASN_INTEGER);
  149. netsnmp_table_helper_add_index(entries_table_info, ASN_INTEGER);
  150. netsnmp_table_helper_add_index(entity_table_info, ASN_INTEGER);
  151. ops_table_info->min_column = dsOpsTable_COL_MIN;
  152. ops_table_info->max_column = dsOpsTable_COL_MAX;
  153. entries_table_info->min_column = dsEntriesTable_COL_MIN;
  154. entries_table_info->max_column = dsEntriesTable_COL_MAX;
  155. entity_table_info->min_column = dsEntityTable_COL_MIN;
  156. entity_table_info->max_column = dsEntityTable_COL_MAX;
  157. /*
  158. * Define callbacks and the container. We only use one container that
  159. * all of the tables use.
  160. */
  161. ops_cb.get_value = dsOpsTable_get_value;
  162. ops_cb.container = netsnmp_container_find("dsOpsTable_primary:"
  163. "dsOpsTable:" "table_container");
  164. entries_cb.get_value = dsEntriesTable_get_value;
  165. entries_cb.container = ops_cb.container;
  166. entity_cb.get_value = dsEntityTable_get_value;
  167. entity_cb.container = ops_cb.container;
  168. /* registering the tables with the master agent */
  169. netsnmp_table_container_register(ops_handler, ops_table_info, &ops_cb,
  170. ops_cb.container, 1);
  171. netsnmp_table_container_register(entries_handler, entries_table_info, &entries_cb,
  172. entries_cb.container, 1);
  173. netsnmp_table_container_register(entity_handler, entity_table_info, &entity_cb,
  174. entity_cb.container, 1);
  175. /* Setup cache for auto reloading of stats */
  176. #ifdef NETSNMP_CACHE_AUTO_RELOAD
  177. /* This is new api as of Net-SNMP 5.2 */
  178. stats_table_cache = netsnmp_cache_create(CACHE_REFRESH_INTERVAL, load_stats_table,
  179. NULL, dsOpsTable_oid, dsOpsTable_oid_len);
  180. stats_table_cache->flags |= NETSNMP_CACHE_DONT_FREE_EXPIRED;
  181. stats_table_cache->flags |= NETSNMP_CACHE_DONT_AUTO_RELEASE;
  182. stats_table_cache->flags |= NETSNMP_CACHE_AUTO_RELOAD;
  183. netsnmp_inject_handler(ops_handler, netsnmp_cache_handler_get(stats_table_cache));
  184. #else
  185. /* Do things the old way. This is only needed for Net-SNMP 5.1 and earlier. */
  186. netsnmp_inject_handler(ops_handler, netsnmp_get_cache_handler(CACHE_REFRESH_INTERVAL, load_stats_table,
  187. free_stats_table, dsOpsTable_oid, dsOpsTable_oid_len));
  188. #endif
  189. }
  190. /************************************************************
  191. * stats_table_create_row
  192. *
  193. * Creates a new table row using the supplied port number as
  194. * the index, then returns a pointer to the new row.
  195. */
  196. stats_table_context *
  197. stats_table_create_row(unsigned long portnum)
  198. {
  199. netsnmp_index index;
  200. stats_table_context *ctx = SNMP_MALLOC_TYPEDEF(stats_table_context);
  201. oid *index_oid = (oid *)malloc(sizeof(oid) * MAX_OID_LEN);
  202. /* Create index using port number */
  203. index_oid[0] = portnum;
  204. index.oids = index_oid;
  205. index.len = 1;
  206. /* Copy index into row structure */
  207. if (ctx && index_oid) {
  208. memcpy(&ctx->index, &index, sizeof(index));
  209. return ctx;
  210. } else {
  211. /* Error during malloc */
  212. snmp_log(LOG_ERR, "malloc failed in stats_table_create_row\n");
  213. return NULL;
  214. }
  215. }
  216. /************************************************************
  217. * stats_table_find_row
  218. *
  219. * Searches for a row by the port number. Returns NULL if
  220. * the row doesn't exist.
  221. */
  222. stats_table_context *
  223. stats_table_find_row(unsigned long portnum)
  224. {
  225. netsnmp_index index;
  226. oid index_oid[MAX_OID_LEN];
  227. index_oid[0] = portnum;
  228. index.oids = index_oid;
  229. index.len = 1;
  230. return (stats_table_context *)
  231. CONTAINER_FIND(ops_cb.container, &index);
  232. }
  233. /************************************************************
  234. * load_stats_table
  235. *
  236. * Reloads the stats into the table. This is called
  237. * automatically from the cache handler. This function
  238. * does not reload the entity table since it's static
  239. * information. We also check if any traps need to
  240. * be sent here.
  241. */
  242. int
  243. load_stats_table(netsnmp_cache *cache, void *foo)
  244. {
  245. server_instance *serv_p = NULL;
  246. stats_table_context *ctx = NULL;
  247. time_t previous_start;
  248. int previous_state;
  249. int stats_hdl = -1;
  250. snmp_log(LOG_INFO, "Reloading stats.\n");
  251. /* Initialize data for each server in conf file */
  252. for (serv_p = server_head; serv_p != NULL; serv_p = serv_p->next) {
  253. if ((ctx = stats_table_find_row(serv_p->port)) != NULL) {
  254. /* Save previous state of the server to
  255. * see if a trap needs to be sent */
  256. previous_state = serv_p->server_state;
  257. previous_start = ctx->hdr_tbl.startTime;
  258. snmp_log(LOG_INFO, "Opening stats file (%s) for server: %d\n",
  259. serv_p->stats_file, serv_p->port);
  260. /* Open the stats file */
  261. if ( agt_mopen_stats(serv_p->stats_file, O_RDONLY, &stats_hdl) != 0 ) {
  262. /* Server must be down */
  263. serv_p->server_state = SERVER_DOWN;
  264. /* Zero out the ops and entries tables */
  265. memset(&ctx->ops_tbl, 0x00, sizeof(ctx->ops_tbl));
  266. memset(&ctx->entries_tbl, 0x00, sizeof(ctx->entries_tbl));
  267. if (previous_state != SERVER_DOWN)
  268. snmp_log(LOG_INFO, "Unable to open stats file (%s) for server: %d\n",
  269. serv_p->stats_file, serv_p->port);
  270. } else {
  271. /* Initialize ops table */
  272. if ( agt_mread_stats(stats_hdl, &ctx->hdr_tbl, &ctx->ops_tbl,
  273. &ctx->entries_tbl) != 0 )
  274. snmp_log(LOG_ERR, "Unable to read stats file: %s\n",
  275. serv_p->stats_file);
  276. /* Close stats file */
  277. if ( agt_mclose_stats(stats_hdl) != 0 )
  278. snmp_log(LOG_ERR, "Error closing stats file: %s\n",
  279. serv_p->stats_file);
  280. /* Server must be down if the stats file hasn't been
  281. * updated in a while */
  282. if (difftime(time(NULL), ctx->hdr_tbl.updateTime) >= UPDATE_THRESHOLD) {
  283. serv_p->server_state = SERVER_DOWN;
  284. if (previous_state != SERVER_DOWN)
  285. snmp_log(LOG_INFO, "Stats file for server %d hasn't been updated"
  286. " in %d seconds.\n", serv_p->port, UPDATE_THRESHOLD);
  287. } else {
  288. serv_p->server_state = SERVER_UP;
  289. }
  290. }
  291. /* If the state of the server changed since the last
  292. * load of the stats, send a trap. */
  293. if (previous_state != STATE_UNKNOWN) {
  294. if (serv_p->server_state != previous_state) {
  295. if (serv_p->server_state == SERVER_UP) {
  296. snmp_log(LOG_INFO, "Detected start of server: %d\n",
  297. serv_p->port);
  298. send_DirectoryServerStart_trap(serv_p);
  299. } else {
  300. send_DirectoryServerDown_trap(serv_p);
  301. /* Zero out the ops and entries tables */
  302. memset(&ctx->ops_tbl, 0x00, sizeof(ctx->ops_tbl));
  303. memset(&ctx->entries_tbl, 0x00, sizeof(ctx->entries_tbl));
  304. }
  305. } else if (ctx->hdr_tbl.startTime != previous_start) {
  306. /* Send traps if the server has restarted since the last load */
  307. snmp_log(LOG_INFO, "Detected restart of server: %d\n", serv_p->port);
  308. send_DirectoryServerDown_trap(serv_p);
  309. send_DirectoryServerStart_trap(serv_p);
  310. }
  311. }
  312. } else {
  313. /* Can't find our row. This shouldn't ever happen. */
  314. snmp_log(LOG_ERR, "Row not found for server: %d\n",
  315. serv_p->port);
  316. }
  317. }
  318. return 0;
  319. }
  320. /************************************************************
  321. * free_stats_table
  322. *
  323. * This function doesn't need to free anything since the
  324. * load_stats_table function doesn't allocate any memory
  325. * itself. The cache handler requires us to have a callback
  326. * function for freeing the cache, so here it is.
  327. */
  328. void
  329. free_stats_table(netsnmp_cache *cache, void *foo)
  330. {
  331. return;
  332. }
  333. /************************************************************
  334. * dsOpsTable_get_value
  335. *
  336. * This routine is called for get requests to copy the data
  337. * from the context to the varbind for the request. If the
  338. * context has been properly maintained, you don't need to
  339. * change in code in this fuction.
  340. */
  341. int
  342. dsOpsTable_get_value(netsnmp_request_info *request,
  343. netsnmp_index * item,
  344. netsnmp_table_request_info *table_info)
  345. {
  346. netsnmp_variable_list *var = request->requestvb;
  347. stats_table_context *context = (stats_table_context *) item;
  348. switch (table_info->colnum) {
  349. case COLUMN_DSANONYMOUSBINDS:
  350. snmp_set_var_typed_value(var, ASN_COUNTER,
  351. (u_char *) &context->ops_tbl.dsAnonymousBinds,
  352. sizeof(context->ops_tbl.dsAnonymousBinds));
  353. break;
  354. case COLUMN_DSUNAUTHBINDS:
  355. snmp_set_var_typed_value(var, ASN_COUNTER,
  356. (u_char *) &context->ops_tbl.dsUnAuthBinds,
  357. sizeof(context->ops_tbl.dsUnAuthBinds));
  358. break;
  359. case COLUMN_DSSIMPLEAUTHBINDS:
  360. snmp_set_var_typed_value(var, ASN_COUNTER,
  361. (u_char *) &context->ops_tbl.dsSimpleAuthBinds,
  362. sizeof(context->ops_tbl.dsSimpleAuthBinds));
  363. break;
  364. case COLUMN_DSSTRONGAUTHBINDS:
  365. snmp_set_var_typed_value(var, ASN_COUNTER,
  366. (u_char *) &context->ops_tbl.dsStrongAuthBinds,
  367. sizeof(context->ops_tbl.dsStrongAuthBinds));
  368. break;
  369. case COLUMN_DSBINDSECURITYERRORS:
  370. snmp_set_var_typed_value(var, ASN_COUNTER,
  371. (u_char *) &context->ops_tbl.dsBindSecurityErrors,
  372. sizeof(context->ops_tbl.dsBindSecurityErrors));
  373. break;
  374. case COLUMN_DSINOPS:
  375. snmp_set_var_typed_value(var, ASN_COUNTER,
  376. (u_char *) &context->ops_tbl.dsInOps,
  377. sizeof(context->ops_tbl.dsInOps));
  378. break;
  379. case COLUMN_DSREADOPS:
  380. snmp_set_var_typed_value(var, ASN_COUNTER,
  381. (u_char *) &context->ops_tbl.dsReadOps,
  382. sizeof(context->ops_tbl.dsReadOps));
  383. break;
  384. case COLUMN_DSCOMPAREOPS:
  385. snmp_set_var_typed_value(var, ASN_COUNTER,
  386. (u_char *) &context->ops_tbl.dsCompareOps,
  387. sizeof(context->ops_tbl.dsCompareOps));
  388. break;
  389. case COLUMN_DSADDENTRYOPS:
  390. snmp_set_var_typed_value(var, ASN_COUNTER,
  391. (u_char *) &context->ops_tbl.dsAddEntryOps,
  392. sizeof(context->ops_tbl.dsAddEntryOps));
  393. break;
  394. case COLUMN_DSREMOVEENTRYOPS:
  395. snmp_set_var_typed_value(var, ASN_COUNTER,
  396. (u_char *) &context->ops_tbl.dsRemoveEntryOps,
  397. sizeof(context->ops_tbl.dsRemoveEntryOps));
  398. break;
  399. case COLUMN_DSMODIFYENTRYOPS:
  400. snmp_set_var_typed_value(var, ASN_COUNTER,
  401. (u_char *) &context->ops_tbl.dsModifyEntryOps,
  402. sizeof(context->ops_tbl.dsModifyEntryOps));
  403. break;
  404. case COLUMN_DSMODIFYRDNOPS:
  405. snmp_set_var_typed_value(var, ASN_COUNTER,
  406. (u_char *) &context->ops_tbl.dsModifyRDNOps,
  407. sizeof(context->ops_tbl.dsModifyRDNOps));
  408. break;
  409. case COLUMN_DSLISTOPS:
  410. snmp_set_var_typed_value(var, ASN_COUNTER,
  411. (u_char *) &context->ops_tbl.dsListOps,
  412. sizeof(context->ops_tbl.dsListOps));
  413. break;
  414. case COLUMN_DSSEARCHOPS:
  415. snmp_set_var_typed_value(var, ASN_COUNTER,
  416. (u_char *) &context->ops_tbl.dsSearchOps,
  417. sizeof(context->ops_tbl.dsSearchOps));
  418. break;
  419. case COLUMN_DSONELEVELSEARCHOPS:
  420. snmp_set_var_typed_value(var, ASN_COUNTER,
  421. (u_char *) &context->ops_tbl.dsOneLevelSearchOps,
  422. sizeof(context->ops_tbl.dsOneLevelSearchOps));
  423. break;
  424. case COLUMN_DSWHOLESUBTREESEARCHOPS:
  425. snmp_set_var_typed_value(var, ASN_COUNTER,
  426. (u_char *) &context->ops_tbl.dsWholeSubtreeSearchOps,
  427. sizeof(context->ops_tbl.dsWholeSubtreeSearchOps));
  428. break;
  429. case COLUMN_DSREFERRALS:
  430. snmp_set_var_typed_value(var, ASN_COUNTER,
  431. (u_char *) &context->ops_tbl.dsReferrals,
  432. sizeof(context->ops_tbl.dsReferrals));
  433. break;
  434. case COLUMN_DSCHAININGS:
  435. snmp_set_var_typed_value(var, ASN_COUNTER,
  436. (u_char *) &context->ops_tbl.dsChainings,
  437. sizeof(context->ops_tbl.dsChainings));
  438. break;
  439. case COLUMN_DSSECURITYERRORS:
  440. snmp_set_var_typed_value(var, ASN_COUNTER,
  441. (u_char *) &context->ops_tbl.dsSecurityErrors,
  442. sizeof(context->ops_tbl.dsSecurityErrors));
  443. break;
  444. case COLUMN_DSERRORS:
  445. snmp_set_var_typed_value(var, ASN_COUNTER,
  446. (u_char *) &context->ops_tbl.dsErrors,
  447. sizeof(context->ops_tbl.dsErrors));
  448. break;
  449. default:/* We shouldn't get here */
  450. snmp_log(LOG_ERR, "Unknown column in dsOpsTable_get_value\n");
  451. return SNMP_ERR_GENERR;
  452. }
  453. return SNMP_ERR_NOERROR;
  454. }
  455. /************************************************************
  456. * dsEntriesTable_get_value
  457. *
  458. * This routine is called for get requests to copy the data
  459. * from the context to the varbind for the request. If the
  460. * context has been properly maintained, you don't need to
  461. * change in code in this fuction.
  462. */
  463. int
  464. dsEntriesTable_get_value(netsnmp_request_info *request,
  465. netsnmp_index * item,
  466. netsnmp_table_request_info *table_info)
  467. {
  468. netsnmp_variable_list *var = request->requestvb;
  469. stats_table_context *context = (stats_table_context *) item;
  470. switch (table_info->colnum) {
  471. case COLUMN_DSMASTERENTRIES:
  472. snmp_set_var_typed_value(var, ASN_GAUGE,
  473. (u_char *) &context->entries_tbl.dsMasterEntries,
  474. sizeof(context->entries_tbl.dsMasterEntries));
  475. break;
  476. case COLUMN_DSCOPYENTRIES:
  477. snmp_set_var_typed_value(var, ASN_GAUGE,
  478. (u_char *) &context->entries_tbl.dsCopyEntries,
  479. sizeof(context->entries_tbl.dsCopyEntries));
  480. break;
  481. case COLUMN_DSCACHEENTRIES:
  482. snmp_set_var_typed_value(var, ASN_GAUGE,
  483. (u_char *) &context->entries_tbl.dsCacheEntries,
  484. sizeof(context->entries_tbl.dsCacheEntries));
  485. break;
  486. case COLUMN_DSCACHEHITS:
  487. snmp_set_var_typed_value(var, ASN_COUNTER,
  488. (u_char *) &context->entries_tbl.dsCacheHits,
  489. sizeof(context->entries_tbl.dsCacheHits));
  490. break;
  491. case COLUMN_DSSLAVEHITS:
  492. snmp_set_var_typed_value(var, ASN_COUNTER,
  493. (u_char *) &context->entries_tbl.dsSlaveHits,
  494. sizeof(context->entries_tbl.dsSlaveHits));
  495. break;
  496. default:/* We shouldn't get here */
  497. snmp_log(LOG_ERR, "Unknown column in dsEntriesTable_get_value\n");
  498. return SNMP_ERR_GENERR;
  499. }
  500. return SNMP_ERR_NOERROR;
  501. }
  502. /************************************************************
  503. * dsEntityTable_get_value
  504. *
  505. * This routine is called for get requests to copy the data
  506. * from the context to the varbind for the request. If the
  507. * context has been properly maintained, you don't need to
  508. * change in code in this fuction.
  509. */
  510. int
  511. dsEntityTable_get_value(netsnmp_request_info *request,
  512. netsnmp_index * item,
  513. netsnmp_table_request_info *table_info)
  514. {
  515. netsnmp_variable_list *var = request->requestvb;
  516. stats_table_context *context = (stats_table_context *) item;
  517. switch (table_info->colnum) {
  518. case COLUMN_DSENTITYDESCR:
  519. snmp_set_var_typed_value(var, ASN_OCTET_STR,
  520. (u_char *) context->hdr_tbl.dsDescription,
  521. strlen(context->hdr_tbl.dsDescription));
  522. break;
  523. case COLUMN_DSENTITYVERS:
  524. snmp_set_var_typed_value(var, ASN_OCTET_STR,
  525. (u_char *) context->hdr_tbl.dsVersion,
  526. strlen(context->hdr_tbl.dsVersion));
  527. break;
  528. case COLUMN_DSENTITYORG:
  529. snmp_set_var_typed_value(var, ASN_OCTET_STR,
  530. (u_char *) context->hdr_tbl.dsOrganization,
  531. strlen(context->hdr_tbl.dsOrganization));
  532. break;
  533. case COLUMN_DSENTITYLOCATION:
  534. snmp_set_var_typed_value(var, ASN_OCTET_STR,
  535. (u_char *) context->hdr_tbl.dsLocation,
  536. strlen(context->hdr_tbl.dsLocation));
  537. break;
  538. case COLUMN_DSENTITYCONTACT:
  539. snmp_set_var_typed_value(var, ASN_OCTET_STR,
  540. (u_char *) context->hdr_tbl.dsContact,
  541. strlen(context->hdr_tbl.dsContact));
  542. break;
  543. case COLUMN_DSENTITYNAME:
  544. snmp_set_var_typed_value(var, ASN_OCTET_STR,
  545. (u_char *) context->hdr_tbl.dsName,
  546. strlen(context->hdr_tbl.dsName));
  547. break;
  548. default:/* We shouldn't get here */
  549. snmp_log(LOG_ERR, "Unknown column in dsEntityTable_get_value\n");
  550. return SNMP_ERR_GENERR;
  551. }
  552. return SNMP_ERR_NOERROR;
  553. }
  554. /************************************************************
  555. * send_DirectoryServerDown_trap
  556. *
  557. * Sends off the server down trap.
  558. */
  559. int
  560. send_DirectoryServerDown_trap(server_instance *serv_p)
  561. {
  562. netsnmp_variable_list *var_list = NULL;
  563. stats_table_context *ctx = NULL;
  564. /* Define the oids for the trap */
  565. oid DirectoryServerDown_oid[] = { DirectoryServerDown_OID };
  566. oid dsEntityDescr_oid[] = { dsEntityTable_TABLE_OID, 1, COLUMN_DSENTITYDESCR, 0 };
  567. oid dsEntityVers_oid[] = { dsEntityTable_TABLE_OID, 1, COLUMN_DSENTITYVERS, 0 };
  568. oid dsEntityLocation_oid[] = { dsEntityTable_TABLE_OID, 1, COLUMN_DSENTITYLOCATION, 0 };
  569. oid dsEntityContact_oid[] = { dsEntityTable_TABLE_OID, 1, COLUMN_DSENTITYCONTACT, 0 };
  570. dsEntityDescr_oid[3] = serv_p->port;
  571. dsEntityVers_oid[3] = serv_p->port;
  572. dsEntityLocation_oid[3] = serv_p->port;
  573. dsEntityContact_oid[3] = serv_p->port;
  574. snmp_log(LOG_INFO, "Sending down trap for server: %d\n", serv_p->port);
  575. /* Lookup row to get version string */
  576. if ((ctx = stats_table_find_row(serv_p->port)) == NULL) {
  577. snmp_log(LOG_ERR, "Malloc error finding row for server: %d\n", serv_p->port);
  578. return 1;
  579. }
  580. /* Setup the variable list to send with the trap */
  581. snmp_varlist_add_variable(&var_list,
  582. snmptrap_oid, OID_LENGTH(snmptrap_oid),
  583. ASN_OBJECT_ID,
  584. (u_char *) &DirectoryServerDown_oid,
  585. sizeof(DirectoryServerDown_oid));
  586. snmp_varlist_add_variable(&var_list,
  587. dsEntityDescr_oid,
  588. OID_LENGTH(dsEntityDescr_oid), ASN_OCTET_STR,
  589. (u_char *) ctx->hdr_tbl.dsDescription,
  590. strlen(ctx->hdr_tbl.dsDescription));
  591. snmp_varlist_add_variable(&var_list,
  592. dsEntityVers_oid,
  593. OID_LENGTH(dsEntityVers_oid), ASN_OCTET_STR,
  594. (u_char *) ctx->hdr_tbl.dsVersion,
  595. strlen(ctx->hdr_tbl.dsVersion));
  596. snmp_varlist_add_variable(&var_list,
  597. dsEntityLocation_oid,
  598. OID_LENGTH(dsEntityLocation_oid),
  599. ASN_OCTET_STR,
  600. (u_char *) ctx->hdr_tbl.dsLocation,
  601. strlen(ctx->hdr_tbl.dsLocation));
  602. snmp_varlist_add_variable(&var_list,
  603. dsEntityContact_oid,
  604. OID_LENGTH(dsEntityContact_oid),
  605. ASN_OCTET_STR,
  606. (u_char *) ctx->hdr_tbl.dsContact,
  607. strlen(ctx->hdr_tbl.dsContact));
  608. /* Send the trap */
  609. send_v2trap(var_list);
  610. snmp_free_varbind(var_list);
  611. return SNMP_ERR_NOERROR;
  612. }
  613. /************************************************************
  614. * send_DirectoryServerStart_trap
  615. *
  616. * Sends off the server start trap.
  617. */
  618. int
  619. send_DirectoryServerStart_trap(server_instance *serv_p)
  620. {
  621. netsnmp_variable_list *var_list = NULL;
  622. stats_table_context *ctx = NULL;
  623. /* Define the oids for the trap */
  624. oid DirectoryServerStart_oid[] = { DirectoryServerStart_OID };
  625. oid dsEntityDescr_oid[] = { dsEntityTable_TABLE_OID, 1, COLUMN_DSENTITYDESCR, 0 };
  626. oid dsEntityVers_oid[] = { dsEntityTable_TABLE_OID, 1, COLUMN_DSENTITYVERS, 0 };
  627. oid dsEntityLocation_oid[] = { dsEntityTable_TABLE_OID, 1, COLUMN_DSENTITYLOCATION, 0 };
  628. dsEntityDescr_oid[3] = serv_p->port;
  629. dsEntityVers_oid[3] = serv_p->port;
  630. dsEntityLocation_oid[3] = serv_p->port;
  631. snmp_log(LOG_INFO, "Sending start trap for server: %d\n", serv_p->port);
  632. /* Lookup row to get version string */
  633. if ((ctx = stats_table_find_row(serv_p->port)) == NULL) {
  634. snmp_log(LOG_ERR, "Malloc error finding row for server: %d\n", serv_p->port);
  635. return 1;
  636. }
  637. /* Setup the variable list to send with the trap */
  638. snmp_varlist_add_variable(&var_list,
  639. snmptrap_oid, OID_LENGTH(snmptrap_oid),
  640. ASN_OBJECT_ID,
  641. (u_char *) &DirectoryServerStart_oid,
  642. sizeof(DirectoryServerStart_oid));
  643. snmp_varlist_add_variable(&var_list,
  644. dsEntityDescr_oid,
  645. OID_LENGTH(dsEntityDescr_oid), ASN_OCTET_STR,
  646. (u_char *) ctx->hdr_tbl.dsDescription,
  647. strlen(ctx->hdr_tbl.dsDescription));
  648. snmp_varlist_add_variable(&var_list,
  649. dsEntityVers_oid,
  650. OID_LENGTH(dsEntityVers_oid), ASN_OCTET_STR,
  651. (u_char *) ctx->hdr_tbl.dsVersion,
  652. strlen(ctx->hdr_tbl.dsVersion));
  653. snmp_varlist_add_variable(&var_list,
  654. dsEntityLocation_oid,
  655. OID_LENGTH(dsEntityLocation_oid),
  656. ASN_OCTET_STR,
  657. (u_char *) ctx->hdr_tbl.dsLocation,
  658. strlen(ctx->hdr_tbl.dsLocation));
  659. /* Send the trap */
  660. send_v2trap(var_list);
  661. snmp_free_varbind(var_list);
  662. return SNMP_ERR_NOERROR;
  663. }