1 /*
2  * SNMPStats Module
3  * Copyright (C) 2006 SOMA Networks, INC.
4  * Written by: Jeffrey Magder (jmagder@somanetworks.com)
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21  * USA
22  *
23  * The file implements the kamailioSIPStatusCodesTable.  For a full description
24  * of the table, please see the KAMAILIO-SIP-COMMON-MIB.
25  *
26  * This file is much larger and more complicated than the files for other
27  * tables.  This is because the table is settable, bringing a lot of SNMP
28  * overhead.  Most of the file consists of the original auto-generated
29  * code (aside from white space and comment changes).
30  *
31  * The functions that have been modified to implement this table are the
32  * following:
33  *
34  * 1) kamailioSIPStatusCodesTable_create_row()
35  *
36  *    - The row structure has been modified from its default to store the
37  *      number of messages that have been received and sent with a certain
38  *      status code, at the time this row was created.  This function
39  *      populates that data.
40  *
41  * 2) kamailioSIPStatusCodesTable_extract_index()
42  *
43  *    - Modified to fail if the index is invalid.  The index is invalid if it
44  *      does not match up with the global userLookupCounter.
45  *
46  * 3) kamailioSIPStatusCodesTable_can_[activate|deactivate|delete]()
47  *
48  *    - Simplified to always allow activation/deactivation/deletion.
49  *
50  * 4) kamailioSIPStatusCodesTable_set_reserve1()
51  *
52  *    - The reserve1 phase passes if the row is new, and the rowStatus column
53  *      is being set to 'createAndGo'
54  *
55  *    - The reserve1 phase passes if the row is not new, and the rowStatus
56  *      column is being set to 'destroy'
57  *
58  * 5) kamailioSIPStatusCodesTable_get_value()
59  *
60  *    - Instead of returning a variable binding to either
61  *      kamailioSIPStatusCodeIns or kamailioSIPStatusCodeOuts, the function
62  *      returns a variable binding equal to the current value as per the
63  *      statistics framework, minus either kamailioSIPStatusCodeIns or
64  *      kamailioSIPStatusCodeOuts
65  *
66  * You can safely ignore the other functions.
67  *
68  */
69 
70 #include <net-snmp/net-snmp-config.h>
71 #include <net-snmp/net-snmp-includes.h>
72 #include <net-snmp/agent/net-snmp-agent-includes.h>
73 
74 #include <net-snmp/library/snmp_assert.h>
75 
76 #include "snmpSIPStatusCodesTable.h"
77 #include "snmpstats_globals.h"
78 #include "snmp_statistics.h"
79 
80 static netsnmp_handler_registration *my_handler = NULL;
81 static netsnmp_table_array_callbacks cb;
82 
83 oid kamailioSIPStatusCodesTable_oid[] = {kamailioSIPStatusCodesTable_TABLE_OID};
84 
85 size_t kamailioSIPStatusCodesTable_oid_len =
86 		OID_LENGTH(kamailioSIPStatusCodesTable_oid);
87 
88 
89 /*
90  * Initializes the kamailioSIPStatusCodesTable module.  This step is easier
91  * than in the other tables because there is no table population.  All table
92  * population takes place during run time.
93  */
init_kamailioSIPStatusCodesTable(void)94 void init_kamailioSIPStatusCodesTable(void)
95 {
96 	initialize_table_kamailioSIPStatusCodesTable();
97 }
98 
99 
100 /* the *_row_copy routine */
kamailioSIPStatusCodesTable_row_copy(kamailioSIPStatusCodesTable_context * dst,kamailioSIPStatusCodesTable_context * src)101 static int kamailioSIPStatusCodesTable_row_copy(
102 		kamailioSIPStatusCodesTable_context *dst,
103 		kamailioSIPStatusCodesTable_context *src)
104 {
105 	if(!dst || !src)
106 		return 1;
107 
108 
109 	/* copy index, if provided */
110 	if(dst->index.oids) {
111 		free(dst->index.oids);
112 	}
113 
114 	if(snmp_clone_mem((void *)&dst->index.oids, src->index.oids,
115 			   src->index.len * sizeof(oid))) {
116 		dst->index.oids = NULL;
117 		return 1;
118 	}
119 
120 	dst->index.len = src->index.len;
121 
122 
123 	/* copy components into the context structure */
124 	dst->kamailioSIPStatusCodeMethod = src->kamailioSIPStatusCodeMethod;
125 	dst->kamailioSIPStatusCodeValue = src->kamailioSIPStatusCodeValue;
126 	dst->kamailioSIPStatusCodeIns = src->kamailioSIPStatusCodeIns;
127 	dst->kamailioSIPStatusCodeOuts = src->kamailioSIPStatusCodeOuts;
128 	dst->kamailioSIPStatusCodeRowStatus = src->kamailioSIPStatusCodeRowStatus;
129 
130 	return 0;
131 }
132 
133 /*
134  * the *_extract_index routine (Mostly auto-generated)
135  *
136  * This routine is called when a set request is received for an index that
137  * was not found in the table container. Here, we parse the oid in the
138  * individual index components and copy those indexes to the context. Then
139  * we make sure the indexes for the new row are valid.
140  *
141  * It has been modified from its original form in that the indexes aren't
142  * returned if they are invalid.  An index is invalid if it is not between
143  * 100 and 699 (Inclusive).
144  */
kamailioSIPStatusCodesTable_extract_index(kamailioSIPStatusCodesTable_context * ctx,netsnmp_index * hdr)145 int kamailioSIPStatusCodesTable_extract_index(
146 		kamailioSIPStatusCodesTable_context *ctx, netsnmp_index *hdr)
147 {
148 
149 	/*
150 	 * temporary local storage for extracting oid index
151 	 *
152 	 * extract index uses varbinds (netsnmp_variable_list) to parse
153 	 * the index OID into the individual components for each index part.
154 	 */
155 	netsnmp_variable_list var_kamailioSIPStatusCodeMethod;
156 	netsnmp_variable_list var_kamailioSIPStatusCodeValue;
157 	int err;
158 
159 	/*
160 	 * copy index, if provided
161 	 */
162 	if(hdr) {
163 		netsnmp_assert(ctx->index.oids == NULL);
164 		if((hdr->len > MAX_OID_LEN)
165 				|| snmp_clone_mem((void *)&ctx->index.oids, hdr->oids,
166 						   hdr->len * sizeof(oid))) {
167 			return -1;
168 		}
169 
170 		ctx->index.len = hdr->len;
171 	}
172 
173 	/* Initialize the two variables responsible for holding our two indices.
174 	 */
175 	memset(&var_kamailioSIPStatusCodeMethod, 0x00,
176 			sizeof(var_kamailioSIPStatusCodeMethod));
177 
178 	memset(&var_kamailioSIPStatusCodeValue, 0x00,
179 			sizeof(var_kamailioSIPStatusCodeValue));
180 
181 	var_kamailioSIPStatusCodeMethod.type = ASN_UNSIGNED;
182 	var_kamailioSIPStatusCodeValue.type = ASN_UNSIGNED;
183 
184 	var_kamailioSIPStatusCodeMethod.next_variable =
185 			&var_kamailioSIPStatusCodeValue;
186 
187 	var_kamailioSIPStatusCodeValue.next_variable = NULL;
188 
189 	if(hdr) {
190 		/* parse the oid into the individual index components */
191 		err = parse_oid_indexes(
192 				hdr->oids, hdr->len, &var_kamailioSIPStatusCodeMethod);
193 
194 		if(err == SNMP_ERR_NOERROR) {
195 
196 			/* copy index components into the context structure */
197 			ctx->kamailioSIPStatusCodeMethod =
198 					*var_kamailioSIPStatusCodeMethod.val.integer;
199 			ctx->kamailioSIPStatusCodeValue =
200 					*var_kamailioSIPStatusCodeValue.val.integer;
201 
202 
203 			if(*var_kamailioSIPStatusCodeMethod.val.integer < 1) {
204 				err = -1;
205 			}
206 
207 			if(*var_kamailioSIPStatusCodeValue.val.integer < 100
208 					|| *var_kamailioSIPStatusCodeValue.val.integer > 699) {
209 				err = -1;
210 			}
211 		}
212 
213 		/* parsing may have allocated memory. free it. */
214 		snmp_reset_var_buffers(&var_kamailioSIPStatusCodeMethod);
215 
216 		return err;
217 	}
218 
219 	return -1;
220 }
221 
222 
223 /*
224  * This is an auto-generated function.  In general the *_can_activate routine
225  * is called when a row is changed to determine if all the values set are
226  * consistent with the row's rules for a row status of ACTIVE.  If not, then 0
227  * can be returned to prevent the row status from becomming final.
228  *
229  * For our purposes, we have no need for this check, so we always return 1.
230  */
kamailioSIPStatusCodesTable_can_activate(kamailioSIPStatusCodesTable_context * undo_ctx,kamailioSIPStatusCodesTable_context * row_ctx,netsnmp_request_group * rg)231 int kamailioSIPStatusCodesTable_can_activate(
232 		kamailioSIPStatusCodesTable_context *undo_ctx,
233 		kamailioSIPStatusCodesTable_context *row_ctx, netsnmp_request_group *rg)
234 {
235 	return 1;
236 }
237 
238 
239 /*
240  * This is an auto-generated function.  In general the *_can_deactivate routine
241  * is called when a row that is currently ACTIVE is set to a state other than
242  * ACTIVE. If there are conditions in which a row should not be allowed to
243  * transition out of the ACTIVE state (such as the row being referred to by
244  * another row or table), check for them here.
245  *
246  * Since this table has no reason why this shouldn't be allowed, we always
247  * return 1;
248  */
kamailioSIPStatusCodesTable_can_deactivate(kamailioSIPStatusCodesTable_context * undo_ctx,kamailioSIPStatusCodesTable_context * row_ctx,netsnmp_request_group * rg)249 int kamailioSIPStatusCodesTable_can_deactivate(
250 		kamailioSIPStatusCodesTable_context *undo_ctx,
251 		kamailioSIPStatusCodesTable_context *row_ctx, netsnmp_request_group *rg)
252 {
253 	return 1;
254 }
255 
256 
257 /*
258  * This is an auto-generated function.  In general the *_can_delete routine is
259  * called to determine if a row can be deleted.  This usually involved checking
260  * if it can be deactivated, and if it can be, then checking for other
261  * conditions.
262  *
263  * Since this table ha no reason why row deletion shouldn't be allowed, we
264  * always return 1, unless we can't deactivate.
265  */
kamailioSIPStatusCodesTable_can_delete(kamailioSIPStatusCodesTable_context * undo_ctx,kamailioSIPStatusCodesTable_context * row_ctx,netsnmp_request_group * rg)266 int kamailioSIPStatusCodesTable_can_delete(
267 		kamailioSIPStatusCodesTable_context *undo_ctx,
268 		kamailioSIPStatusCodesTable_context *row_ctx, netsnmp_request_group *rg)
269 {
270 	if(kamailioSIPStatusCodesTable_can_deactivate(undo_ctx, row_ctx, rg) != 1)
271 		return 0;
272 
273 	return 1;
274 }
275 
276 /*
277  * (Mostly auto-generated function)
278  *
279  * The *_create_row routine is called by the table handler to create a new row
280  * for a given index. This is the first stage of the row creation process.  The
281  * *_set_reserve_* functions can be used to prevent the row from being inserted
282  * into the table even if the row passes any preliminary checks set here.
283  *
284  * Returns a newly allocated kamailioSIPRegUserLookupTable_context structure (a
285  * row in the table) if the indexes are legal.  NULL will be returned otherwise.
286  *
287  * The function has been modified from its original form, in that it will store
288  * the number of messages 'in' to the system, and the number of messages 'out'
289  * of the system, that had a status code matching this rows status code, at the
290  * time this row was created.
291  *
292  * This value will be used in the future to calculate the delta between now and
293  * the time this row has been read.
294  * */
kamailioSIPStatusCodesTable_create_row(netsnmp_index * hdr)295 kamailioSIPStatusCodesTable_context *kamailioSIPStatusCodesTable_create_row(
296 		netsnmp_index *hdr)
297 {
298 	stat_var *in_status_code;
299 	stat_var *out_status_code;
300 
301 	kamailioSIPStatusCodesTable_context *ctx =
302 			SNMP_MALLOC_TYPEDEF(kamailioSIPStatusCodesTable_context);
303 	if(!ctx)
304 		return NULL;
305 
306 	/* The *_extract_index funtion already validates the indices, so we
307 	 * don't need to do any further evaluations here.  */
308 	if(kamailioSIPStatusCodesTable_extract_index(ctx, hdr)) {
309 		if(NULL != ctx->index.oids)
310 			free(ctx->index.oids);
311 		free(ctx);
312 		return NULL;
313 	}
314 
315 
316 	/* The indices were already set up in the extract_index function
317 	 * above. */
318 	ctx->kamailioSIPStatusCodeIns = 0;
319 	ctx->kamailioSIPStatusCodeOuts = 0;
320 	ctx->kamailioSIPStatusCodeRowStatus = 0;
321 
322 	/* Retrieve the index for the status code, and then assign the starting
323 	 * values.  The starting values will be used to calculate deltas during
324 	 * the next snmpget/snmpwalk/snmptable/etc. */
325 	int codeIndex = ctx->kamailioSIPStatusCodeValue;
326 
327 	ctx->startingInStatusCodeValue = 0;
328 	ctx->startingOutStatusCodeValue = 0;
329 
330 	in_status_code = get_stat_var_from_num_code(codeIndex, 0);
331 	out_status_code = get_stat_var_from_num_code(codeIndex, 1);
332 
333 	if(in_status_code != NULL) {
334 		ctx->startingInStatusCodeValue = get_stat_val(in_status_code);
335 	}
336 
337 	if(out_status_code != NULL) {
338 		ctx->startingOutStatusCodeValue = get_stat_val(out_status_code);
339 	}
340 
341 	return ctx;
342 }
343 
344 
345 /*
346  * Auto-generated function.  The *_duplicate row routine
347  */
kamailioSIPStatusCodesTable_duplicate_row(kamailioSIPStatusCodesTable_context * row_ctx)348 kamailioSIPStatusCodesTable_context *kamailioSIPStatusCodesTable_duplicate_row(
349 		kamailioSIPStatusCodesTable_context *row_ctx)
350 {
351 	kamailioSIPStatusCodesTable_context *dup;
352 
353 	if(!row_ctx)
354 		return NULL;
355 
356 	dup = SNMP_MALLOC_TYPEDEF(kamailioSIPStatusCodesTable_context);
357 	if(!dup)
358 		return NULL;
359 
360 	if(kamailioSIPStatusCodesTable_row_copy(dup, row_ctx)) {
361 		free(dup);
362 		dup = NULL;
363 	}
364 
365 	return dup;
366 }
367 
368 
369 /*
370  * The *_delete_row method is auto-generated, and is called to delete a row.
371  *
372  * This will not be called if earlier checks said that this row can't be
373  * deleted.  However, in our implementation there is never a reason why this
374  * function can't be called.
375  */
kamailioSIPStatusCodesTable_delete_row(kamailioSIPStatusCodesTable_context * ctx)376 netsnmp_index *kamailioSIPStatusCodesTable_delete_row(
377 		kamailioSIPStatusCodesTable_context *ctx)
378 {
379 	if(ctx->index.oids)
380 		free(ctx->index.oids);
381 
382 	free(ctx);
383 
384 	return NULL;
385 }
386 
387 
388 /*
389  * Large parts of this function have been auto-generated.  The functions purpose
390  * is to check to make sure all SNMP set values for the given row, have been
391  * valid.  If not, then the process is supposed to be aborted.  Otherwise, we
392  * pass on to the *_reserve2 function.
393  *
394  * For our purposes, our only check is to make sure that either of the following
395  * conditions are true:
396  *
397  * 1) If this row already exists, then the SET request is setting the rowStatus
398  *    column to 'destroy'.
399  *
400  * 2) If this row does not already exist, then the SET request is setting the
401  *    rowStatus to 'createAndGo'.
402  *
403  * Since the MIB specified there are to be no other modifications to the row,
404  * any other condition is considered illegal, and will result in an SNMP error
405  * being returned.
406  */
kamailioSIPStatusCodesTable_set_reserve1(netsnmp_request_group * rg)407 void kamailioSIPStatusCodesTable_set_reserve1(netsnmp_request_group *rg)
408 {
409 	kamailioSIPStatusCodesTable_context *row_ctx =
410 			(kamailioSIPStatusCodesTable_context *)rg->existing_row;
411 
412 	netsnmp_variable_list *var;
413 	netsnmp_request_group_item *current;
414 
415 	int rc;
416 
417 	/* Loop through the specified columns, and make sure that all values are
418 	 * valid. */
419 	for(current = rg->list; current; current = current->next) {
420 
421 		var = current->ri->requestvb;
422 		rc = SNMP_ERR_NOERROR;
423 
424 		switch(current->tri->colnum) {
425 			case COLUMN_KAMAILIOSIPSTATUSCODEROWSTATUS:
426 
427 				/** RowStatus = ASN_INTEGER */
428 				rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER,
429 						sizeof(row_ctx->kamailioSIPStatusCodeRowStatus));
430 
431 				/* Want to make sure that if it already exists that it
432 				 * is setting it to 'destroy', or if it doesn't exist,
433 				 * that it is setting it to 'createAndGo' */
434 				if(row_ctx->kamailioSIPStatusCodeRowStatus == 0
435 						&& *var->val.integer != TC_ROWSTATUS_CREATEANDGO) {
436 					rc = SNMP_ERR_BADVALUE;
437 				}
438 
439 				else if(row_ctx->kamailioSIPStatusCodeRowStatus
440 								== TC_ROWSTATUS_ACTIVE
441 						&& *var->val.integer != TC_ROWSTATUS_DESTROY) {
442 					rc = SNMP_ERR_BADVALUE;
443 				}
444 
445 
446 				break;
447 
448 			default: /** We shouldn't get here */
449 				rc = SNMP_ERR_GENERR;
450 				snmp_log(LOG_ERR, "unknown column in kamailioSIP"
451 								  "StatusCodesTable_set_reserve1\n");
452 		}
453 
454 		if(rc) {
455 			netsnmp_set_mode_request_error(MODE_SET_BEGIN, current->ri, rc);
456 		}
457 
458 		rg->status = SNMP_MAX(rg->status, current->ri->status);
459 	}
460 }
461 
462 /*
463  * Auto-generated function.  The function is supposed to check for any
464  * last-minute conditions not being met.  However, we don't have any such
465  * conditions, so we leave the default function as is.
466  */
kamailioSIPStatusCodesTable_set_reserve2(netsnmp_request_group * rg)467 void kamailioSIPStatusCodesTable_set_reserve2(netsnmp_request_group *rg)
468 {
469 	kamailioSIPStatusCodesTable_context *undo_ctx =
470 			(kamailioSIPStatusCodesTable_context *)rg->undo_info;
471 
472 	netsnmp_request_group_item *current;
473 
474 	int rc;
475 
476 	rg->rg_void = rg->list->ri;
477 
478 	for(current = rg->list; current; current = current->next) {
479 
480 		rc = SNMP_ERR_NOERROR;
481 
482 		switch(current->tri->colnum) {
483 
484 			case COLUMN_KAMAILIOSIPSTATUSCODEROWSTATUS:
485 				/** RowStatus = ASN_INTEGER */
486 				rc = netsnmp_check_vb_rowstatus(current->ri->requestvb,
487 						undo_ctx ? undo_ctx->kamailioSIPStatusCodeRowStatus
488 								 : 0);
489 
490 				rg->rg_void = current->ri;
491 				break;
492 
493 			default:			   /** We shouldn't get here */
494 				netsnmp_assert(0); /** why wasn't this caught in reserve1? */
495 		}
496 
497 		if(rc) {
498 			netsnmp_set_mode_request_error(MODE_SET_BEGIN, current->ri, rc);
499 		}
500 	}
501 }
502 
503 /*
504  * This function is called only when all the *_reserve[1|2] functions were
505  * succeful.  Its purpose is to make any changes to the row before it is
506  * inserted into the table.
507  *
508  * In our case, we don't require any changes.  So we leave the original
509  * auto-generated code as is.
510  */
kamailioSIPStatusCodesTable_set_action(netsnmp_request_group * rg)511 void kamailioSIPStatusCodesTable_set_action(netsnmp_request_group *rg)
512 {
513 	netsnmp_variable_list *var;
514 
515 	kamailioSIPStatusCodesTable_context *row_ctx =
516 			(kamailioSIPStatusCodesTable_context *)rg->existing_row;
517 
518 	kamailioSIPStatusCodesTable_context *undo_ctx =
519 			(kamailioSIPStatusCodesTable_context *)rg->undo_info;
520 
521 	netsnmp_request_group_item *current;
522 
523 	int row_err = 0;
524 
525 	/* Depending on what the snmpset was, set the row to be created or
526 	 * deleted.   */
527 	for(current = rg->list; current; current = current->next) {
528 		var = current->ri->requestvb;
529 
530 		switch(current->tri->colnum) {
531 			case COLUMN_KAMAILIOSIPSTATUSCODEROWSTATUS:
532 
533 				/** RowStatus = ASN_INTEGER */
534 				row_ctx->kamailioSIPStatusCodeRowStatus = *var->val.integer;
535 
536 				if(*var->val.integer == TC_ROWSTATUS_CREATEANDGO) {
537 					rg->row_created = 1;
538 				} else if(*var->val.integer == TC_ROWSTATUS_DESTROY) {
539 					rg->row_deleted = 1;
540 				} else {
541 					/* We should never be here, because the RESERVE
542 					 * functions should have taken care of all other
543 					 * values. */
544 					LM_ERR("Invalid RowStatus in "
545 						   "kamailioSIPStatusCodesTable\n");
546 				}
547 
548 				break;
549 
550 			default:			   /** We shouldn't get here */
551 				netsnmp_assert(0); /** why wasn't this caught in reserve1? */
552 		}
553 	}
554 
555 /*
556 	 * done with all the columns. Could check row related
557 	 * requirements here.
558 	 */
559 #ifndef kamailioSIPStatusCodesTable_CAN_MODIFY_ACTIVE_ROW
560 	if(undo_ctx && RS_IS_ACTIVE(undo_ctx->kamailioSIPStatusCodeRowStatus)
561 			&& row_ctx
562 			&& RS_IS_ACTIVE(row_ctx->kamailioSIPStatusCodeRowStatus)) {
563 		row_err = 1;
564 	}
565 #endif
566 
567 	LM_DBG("stage row_err = %d\n", row_err);
568 
569 	/*
570 	 * check activation/deactivation
571 	 */
572 	row_err = netsnmp_table_array_check_row_status(&cb, rg,
573 			row_ctx ? &row_ctx->kamailioSIPStatusCodeRowStatus : NULL,
574 			undo_ctx ? &undo_ctx->kamailioSIPStatusCodeRowStatus : NULL);
575 	if(row_err) {
576 		netsnmp_set_mode_request_error(
577 				MODE_SET_BEGIN, (netsnmp_request_info *)rg->rg_void, row_err);
578 		return;
579 	}
580 }
581 
582 
583 /*
584  * The COMMIT phase is used to do any extra processing after the ACTION phase.
585  * In our table, there is nothing to do, so the function body is empty.
586  */
kamailioSIPStatusCodesTable_set_commit(netsnmp_request_group * rg)587 void kamailioSIPStatusCodesTable_set_commit(netsnmp_request_group *rg)
588 {
589 }
590 
591 
592 /*
593  * This function is called if the *_reserve[1|2] calls failed.  Its supposed to
594  * free up any resources allocated earlier.  However, we already take care of
595  * all these resources in earlier functions.  So for our purposes, the function
596  * body is empty.
597  */
kamailioSIPStatusCodesTable_set_free(netsnmp_request_group * rg)598 void kamailioSIPStatusCodesTable_set_free(netsnmp_request_group *rg)
599 {
600 }
601 
602 
603 /*
604  * This function is called if an ACTION phase fails, to do extra clean-up work.
605  * We don't have anything complicated enough to warrant putting anything in this
606  * function.  Therefore, its just left with an empty function body.
607  */
kamailioSIPStatusCodesTable_set_undo(netsnmp_request_group * rg)608 void kamailioSIPStatusCodesTable_set_undo(netsnmp_request_group *rg)
609 {
610 }
611 
612 
613 /*
614  * Initialize the kamailioSIPStatusCodesTable table by defining how it is
615  * structured.
616  *
617  * This function is mostly auto-generated.
618  */
initialize_table_kamailioSIPStatusCodesTable(void)619 void initialize_table_kamailioSIPStatusCodesTable(void)
620 {
621 	netsnmp_table_registration_info *table_info;
622 
623 	if(my_handler) {
624 		snmp_log(LOG_ERR, "initialize_table_kamailioSIPStatusCodes"
625 						  "Table_handler called again\n");
626 		return;
627 	}
628 
629 	memset(&cb, 0x00, sizeof(cb));
630 
631 	/** create the table structure itself */
632 	table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
633 	if(!table_info) {
634 		snmp_log(LOG_ERR, "failed to allocate table_info\n");
635 		return;
636 	}
637 
638 	my_handler = netsnmp_create_handler_registration(
639 			"kamailioSIPStatusCodesTable", netsnmp_table_array_helper_handler,
640 			kamailioSIPStatusCodesTable_oid,
641 			kamailioSIPStatusCodesTable_oid_len, HANDLER_CAN_RWRITE);
642 
643 	if(!my_handler) {
644 		SNMP_FREE(table_info);
645 		snmp_log(LOG_ERR, "malloc failed in initialize_table_kamailioSIP"
646 						  "StatusCodesTable_handler\n");
647 		return; /** mallocs failed */
648 	}
649 
650 	/** index: kamailioSIPStatusCodeMethod */
651 	netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED);
652 	/** index: kamailioSIPStatusCodeValue */
653 	netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED);
654 
655 	table_info->min_column = kamailioSIPStatusCodesTable_COL_MIN;
656 	table_info->max_column = kamailioSIPStatusCodesTable_COL_MAX;
657 
658 	/***************************************************
659 	 * registering the table with the master agent
660 	 */
661 	cb.get_value = kamailioSIPStatusCodesTable_get_value;
662 
663 	cb.container = netsnmp_container_find("kamailioSIPStatusCodesTable_primary:"
664 										  "kamailioSIPStatusCodesTable:"
665 										  "table_container");
666 
667 #ifdef kamailioSIPStatusCodesTable_CUSTOM_SORT
668 	netsnmp_container_add_index(cb.container,
669 			netsnmp_container_find("kamailioSIPStatusCodesTable_custom:"
670 								   "kamailioSIPStatusCodesTable:"
671 								   "table_container"));
672 
673 	cb.container->next->compare = kamailioSIPStatusCodesTable_cmp;
674 #endif
675 	cb.can_set = 1;
676 
677 	cb.create_row = (UserRowMethod *)kamailioSIPStatusCodesTable_create_row;
678 
679 	cb.duplicate_row =
680 			(UserRowMethod *)kamailioSIPStatusCodesTable_duplicate_row;
681 
682 	cb.delete_row = (UserRowMethod *)kamailioSIPStatusCodesTable_delete_row;
683 
684 	cb.row_copy =
685 			(Netsnmp_User_Row_Operation *)kamailioSIPStatusCodesTable_row_copy;
686 
687 	cb.can_activate =
688 			(Netsnmp_User_Row_Action *)kamailioSIPStatusCodesTable_can_activate;
689 
690 	cb.can_deactivate = (Netsnmp_User_Row_Action *)
691 			kamailioSIPStatusCodesTable_can_deactivate;
692 
693 	cb.can_delete =
694 			(Netsnmp_User_Row_Action *)kamailioSIPStatusCodesTable_can_delete;
695 
696 	cb.set_reserve1 = kamailioSIPStatusCodesTable_set_reserve1;
697 	cb.set_reserve2 = kamailioSIPStatusCodesTable_set_reserve2;
698 
699 	cb.set_action = kamailioSIPStatusCodesTable_set_action;
700 	cb.set_commit = kamailioSIPStatusCodesTable_set_commit;
701 
702 	cb.set_free = kamailioSIPStatusCodesTable_set_free;
703 	cb.set_undo = kamailioSIPStatusCodesTable_set_undo;
704 
705 	DEBUGMSGTL(("initialize_table_kamailioSIPStatusCodesTable",
706 			"Registering table kamailioSIPStatusCodesTable "
707 			"as a table array\n"));
708 
709 	netsnmp_table_container_register(
710 			my_handler, table_info, &cb, cb.container, 1);
711 }
712 
713 /*
714  * This function is called to handle SNMP GET requests.
715  *
716  * The row which this function is called with, will store a message code.  The
717  * function will retrieve the 'number of messages in' and 'number of messages
718  * out' statistic for this particular message code from the statistics
719  * framework.
720  *
721  * The function will then subtract from this value the value it was initialized
722  * with when the row was first created.  In this sense, the row shows how many
723  * ins and how many outs have been received (With respect to the message code)
724  * since this row was created.
725  */
kamailioSIPStatusCodesTable_get_value(netsnmp_request_info * request,netsnmp_index * item,netsnmp_table_request_info * table_info)726 int kamailioSIPStatusCodesTable_get_value(netsnmp_request_info *request,
727 		netsnmp_index *item, netsnmp_table_request_info *table_info)
728 {
729 	stat_var *the_stat;
730 
731 	netsnmp_variable_list *var = request->requestvb;
732 
733 	kamailioSIPStatusCodesTable_context *context =
734 			(kamailioSIPStatusCodesTable_context *)item;
735 
736 	/* Retrieve the statusCodeIdx so we can calculate deltas between current
737 	 * values and previous values. */
738 	int statusCodeIdx = context->kamailioSIPStatusCodeValue;
739 
740 	switch(table_info->colnum) {
741 		case COLUMN_KAMAILIOSIPSTATUSCODEINS:
742 
743 			context->kamailioSIPStatusCodeIns = 0;
744 
745 			the_stat = get_stat_var_from_num_code(statusCodeIdx, 0);
746 
747 			if(the_stat != NULL) {
748 				/* Calculate the Delta */
749 				context->kamailioSIPStatusCodeIns =
750 						get_stat_val(the_stat)
751 						- context->startingInStatusCodeValue;
752 			}
753 
754 			snmp_set_var_typed_value(var, ASN_COUNTER,
755 					(unsigned char *)&context->kamailioSIPStatusCodeIns,
756 					sizeof(context->kamailioSIPStatusCodeIns));
757 			break;
758 
759 		case COLUMN_KAMAILIOSIPSTATUSCODEOUTS:
760 
761 			context->kamailioSIPStatusCodeOuts = 0;
762 
763 			the_stat = get_stat_var_from_num_code(statusCodeIdx, 1);
764 
765 			if(the_stat != NULL) {
766 				/* Calculate the Delta */
767 				context->kamailioSIPStatusCodeOuts =
768 						get_stat_val(the_stat)
769 						- context->startingOutStatusCodeValue;
770 			}
771 			snmp_set_var_typed_value(var, ASN_COUNTER,
772 					(unsigned char *)&context->kamailioSIPStatusCodeOuts,
773 					sizeof(context->kamailioSIPStatusCodeOuts));
774 			break;
775 
776 		case COLUMN_KAMAILIOSIPSTATUSCODEROWSTATUS:
777 			/** RowStatus = ASN_INTEGER */
778 			snmp_set_var_typed_value(var, ASN_INTEGER,
779 					(unsigned char *)&context->kamailioSIPStatusCodeRowStatus,
780 					sizeof(context->kamailioSIPStatusCodeRowStatus));
781 			break;
782 
783 		default: /** We shouldn't get here */
784 			snmp_log(LOG_ERR, "unknown column in "
785 							  "kamailioSIPStatusCodesTable_get_value\n");
786 			return SNMP_ERR_GENERR;
787 	}
788 	return SNMP_ERR_NOERROR;
789 }
790 
791 /*
792  * kamailioSIPRegUserLookupTable_get_by_idx
793  */
794 const kamailioSIPStatusCodesTable_context *
kamailioSIPStatusCodesTable_get_by_idx(netsnmp_index * hdr)795 kamailioSIPStatusCodesTable_get_by_idx(netsnmp_index *hdr)
796 {
797 	return (const kamailioSIPStatusCodesTable_context *)CONTAINER_FIND(
798 			cb.container, hdr);
799 }
800