#include <config.h>
#include <sys/types.h>
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <errno.h>
#include <dmalloc.h>
#include "mibincl.h"
#include "snmp_client.h"
#include "snmp_alarm.h"
#include "snmpd.h"
#include "mibgroup/struct.h"
#include "mibgroup/util_funcs.h"
#include "mib_module_config.h"
#include "default_store.h"
#include "system.h"
#include "ds_agent.h"
#include "snmp_agent.h"
#include "vacm.h"
#include "snmp_transport.h"
#include "snmpUDPDomain.h"
#include "snmpCallbackDomain.h"
#include "snmpUnixDomain.h"
#include "snmpTCPDomain.h"
#include "agentx/protocol.h"
#include "agentx/master.h"
Go to the source code of this file.
Data Structures | |
struct | _agent_nsap |
struct | addrCache |
struct | agent_set_cache_s |
struct | saved_var_data |
Defines | |
#define | SNMP_NEED_REQUEST_LIST |
#define | SNMP_ADDRCACHE_SIZE 10 |
Typedefs | |
typedef _agent_nsap | agent_nsap |
typedef agent_set_cache_s | agent_set_cache |
Functions | |
int | snmp_check_packet (struct snmp_session *, struct _snmp_transport *, void *, int) |
int | snmp_check_parse (struct snmp_session *, struct snmp_pdu *, int) |
void | delete_subtree_cache (struct agent_snmp_session *asp) |
int | handle_pdu (struct agent_snmp_session *asp) |
int | wrap_up_request (struct agent_snmp_session *asp, int status) |
int | check_delayed_request (struct agent_snmp_session *asp) |
int | handle_getnext_loop (struct agent_snmp_session *asp) |
repeatedly calls getnext handlers looking for an answer till all requests are satisified. More... | |
int | handle_set_loop (struct agent_snmp_session *asp) |
agent_set_cache * | save_set_cache (struct agent_snmp_session *asp) |
void | get_set_cache (struct agent_snmp_session *asp) |
int | getNextSessID () |
int | agent_check_and_process (int block) |
void | snmp_addrcache_initialise (void) |
void | snmp_addrcache_age (void) |
int | snmp_check_packet (struct snmp_session *session, snmp_transport *transport, void *transport_data, int transport_data_length) |
int | register_agent_nsap (snmp_transport *t) |
void | deregister_agent_nsap (int handle) |
int | init_master_agent (void) |
agent_snmp_session * | init_agent_snmp_session (struct snmp_session *session, struct snmp_pdu *pdu) |
void | free_agent_snmp_session (struct agent_snmp_session *asp) |
int | check_for_delegated (struct agent_snmp_session *asp) |
void | dump_sess_list (void) |
void | remove_and_free_agent_snmp_session (struct agent_snmp_session *asp) |
void | free_agent_snmp_session_by_session (struct snmp_session *sess, void(*free_request)(struct request_list *)) |
int | handle_snmp_packet (int op, struct snmp_session *session, int reqid, struct snmp_pdu *pdu, void *magic) |
handles an incoming SNMP packet into the agent. More... | |
int | add_varbind_to_cache (struct agent_snmp_session *asp, int vbcount, struct variable_list *varbind_ptr, struct subtree *tp) |
int | check_acm (struct agent_snmp_session *asp, u_char type) |
int | create_subtree_cache (struct agent_snmp_session *asp) |
int | reassign_requests (struct agent_snmp_session *asp) |
void | delete_request_infos (request_info *reqlist) |
int | check_requests_status (struct agent_snmp_session *asp, request_info *requests) |
int | check_all_requests_status (struct agent_snmp_session *asp) |
int | handle_var_requests (struct agent_snmp_session *asp) |
void | check_outstanding_agent_requests (int status) |
int | check_transaction_id (int transaction_id) |
Decide if the requested transaction_id is still being processed within the agent. More... | |
int | check_getnext_results (struct agent_snmp_session *asp) |
returns 1 if there are valid GETNEXT requests left. More... | |
int | handle_set (struct agent_snmp_session *asp) |
int | set_request_error (agent_request_info *reqinfo, request_info *request, int error_value) |
int | set_mode_request_error (int mode, request_info *request, int error_value) |
int | set_all_requests_error (agent_request_info *reqinfo, request_info *requests, int error_value) |
int | marker_uptime (marker_t pm) |
int | timeval_uptime (struct timeval *tv) |
int | get_agent_uptime (void) |
void | agent_add_list_data (agent_request_info *ari, data_list *node) |
void * | agent_get_list_data (agent_request_info *ari, const char *name) |
void | free_agent_data_set (agent_request_info *ari) |
void | free_agent_data_sets (agent_request_info *ari) |
void | free_agent_request_info (agent_request_info *ari) |
Variables | |
int | lastAddrAge = 0 |
int | log_addresses = 0 |
agent_snmp_session * | agent_delegated_list = NULL |
snmp_session * | main_session = NULL |
timeval | starttime |
|
Definition at line 112 of file snmp_agent.c. |
|
Definition at line 72 of file snmp_agent.c. |
|
|
|
|
|
Definition at line 1125 of file snmp_agent.c. Referenced by create_subtree_cache(), and reassign_requests().
01126 { 01127 request_info *request; 01128 int cacheid; 01129 tree_cache *tmpc; 01130 01131 if (tp == NULL) { 01132 /* no appropriate registration found */ 01133 /* make up the response ourselves */ 01134 switch(asp->pdu->command) { 01135 case SNMP_MSG_GETNEXT: 01136 case SNMP_MSG_GETBULK: 01137 varbind_ptr->type = SNMP_ENDOFMIBVIEW; 01138 break; 01139 01140 case SNMP_MSG_SET: 01141 return SNMP_NOSUCHOBJECT; 01142 01143 case SNMP_MSG_GET: 01144 varbind_ptr->type = SNMP_NOSUCHOBJECT; 01145 break; 01146 01147 default: 01148 return SNMPERR_GENERR; /* shouldn't get here */ 01149 } 01150 } else { 01151 if (!MODE_IS_SET(asp->pdu->command)) 01152 varbind_ptr->type = ASN_NULL; 01153 01154 /* malloc the request structure */ 01155 request = SNMP_MALLOC_TYPEDEF(request_info); 01156 if (request == NULL) 01157 return SNMP_ERR_GENERR; 01158 request->index = vbcount; 01159 01160 /* place them in a cache */ 01161 if (tp->cacheid > -1 && tp->cacheid <= asp->treecache_num && 01162 asp->treecache[tp->cacheid]->subtree == tp) { 01163 /* we have already added a request to this tree 01164 pointer before */ 01165 cacheid = tp->cacheid; 01166 01167 } else { 01168 cacheid = ++(asp->treecache_num); 01169 /* new slot needed */ 01170 if (asp->treecache_num >= asp->treecache_len) { 01171 /* exapand cache array */ 01172 /* WWW: non-linear expansion needed (with cap) */ 01173 asp->treecache_len = (asp->treecache_len + 16); 01174 asp->treecache = realloc(asp->treecache, 01175 sizeof(tree_cache *) * 01176 asp->treecache_len); 01177 if (asp->treecache == NULL) 01178 return SNMP_ERR_GENERR; 01179 } 01180 tmpc = (tree_cache *) calloc(1, sizeof(tree_cache)); 01181 asp->treecache[cacheid] = tmpc; 01182 asp->treecache[cacheid]->subtree = tp; 01183 asp->treecache[cacheid]->requests_begin = request; 01184 tp->cacheid = cacheid; 01185 } 01186 01187 /* if this is a search type, get the ending range oid as well */ 01188 if (asp->pdu->command == SNMP_MSG_GETNEXT || 01189 asp->pdu->command == SNMP_MSG_GETBULK) { 01190 request->range_end = tp->end; 01191 request->range_end_len = tp->end_len; 01192 } 01193 01194 /* link into chain */ 01195 if (asp->treecache[cacheid]->requests_end) 01196 asp->treecache[cacheid]->requests_end->next = request; 01197 request->prev = 01198 asp->treecache[cacheid]->requests_end; 01199 asp->treecache[cacheid]->requests_end = request; 01200 01201 /* add the given request to the list of requests they need 01202 to handle results for */ 01203 request->requestvb = varbind_ptr; 01204 } 01205 return SNMP_ERR_NOERROR; 01206 } |
|
Definition at line 1939 of file snmp_agent.c. 01940 { 01941 if (ari) { 01942 if (ari->agent_data) 01943 add_list_data(&ari->agent_data, node); 01944 else 01945 ari->agent_data = node; 01946 } 01947 } |
|
Definition at line 256 of file snmp_agent.c. 00256 { 00257 int numfds; 00258 fd_set fdset; 00259 struct timeval timeout = { LONG_MAX, 0 }, *tvp = &timeout; 00260 int count; 00261 int fakeblock=0; 00262 00263 numfds = 0; 00264 FD_ZERO(&fdset); 00265 snmp_select_info(&numfds, &fdset, tvp, &fakeblock); 00266 if (block != 0 && fakeblock != 0) { 00267 /* There are no alarms registered, and the caller asked for blocking, so 00268 let select() block forever. */ 00269 00270 tvp = NULL; 00271 } else if (block != 0 && fakeblock == 0) { 00272 /* The caller asked for blocking, but there is an alarm due sooner than 00273 LONG_MAX seconds from now, so use the modified timeout returned by 00274 snmp_select_info as the timeout for select(). */ 00275 00276 } else if (block == 0) { 00277 /* The caller does not want us to block at all. */ 00278 00279 tvp->tv_sec = 0; 00280 tvp->tv_usec = 0; 00281 } 00282 00283 count = select(numfds, &fdset, 0, 0, tvp); 00284 00285 if (count > 0) { 00286 /* packets found, process them */ 00287 snmp_read(&fdset); 00288 } else switch(count) { 00289 case 0: 00290 snmp_timeout(); 00291 break; 00292 case -1: 00293 if (errno != EINTR) { 00294 snmp_log_perror("select"); 00295 } 00296 return -1; 00297 default: 00298 snmp_log(LOG_ERR, "select returned %d\n", count); 00299 return -1; 00300 } /* endif -- count>0 */ 00301 00302 /* Run requested alarms. */ 00303 run_alarms(); 00304 00305 return count; 00306 } |
|
Definition at line 1950 of file snmp_agent.c. 01951 { 01952 if (ari) 01953 return get_list_data(ari->agent_data,name); 01954 return NULL; 01955 } |
|
Definition at line 1214 of file snmp_agent.c. Referenced by handle_getnext_loop(), and handle_pdu().
01214 { 01215 int view; 01216 int i; 01217 request_info *request; 01218 int ret = 0; 01219 struct variable_list *vb; 01220 01221 for(i = 0; i <= asp->treecache_num; i++) { 01222 for(request = asp->treecache[i]->requests_begin; 01223 request; request = request->next) { 01224 /* for each request, run it through in_a_view() */ 01225 vb = request->requestvb; 01226 if (vb->type == ASN_NULL) /* not yet processed */ 01227 continue; 01228 view = in_a_view(vb->name, &vb->name_length, asp->pdu, vb->type); 01229 01230 /* if a ACM error occurs, mark it as type passed in */ 01231 if (view != VACM_SUCCESS) { 01232 ret++; 01233 snmp_set_var_typed_value(vb, type, NULL, 0); 01234 } 01235 } 01236 } 01237 return ret; 01238 } |
|
Definition at line 1396 of file snmp_agent.c. Referenced by check_delayed_request().
01396 { 01397 int i; 01398 for(i = 0; i <= asp->treecache_num; i++) { 01399 check_requests_status(asp, asp->treecache[i]->requests_begin); 01400 } 01401 return asp->status; 01402 } |
|
Definition at line 1501 of file snmp_agent.c. Referenced by check_outstanding_agent_requests().
01501 { 01502 int status = SNMP_ERR_NOERROR; 01503 01504 check_all_requests_status(asp); /* update the asp->status */ 01505 01506 switch(asp->mode) { 01507 case SNMP_MSG_GETNEXT: 01508 handle_getnext_loop(asp); 01509 break; 01510 01511 case SNMP_MSG_GETBULK: 01512 /* WWW */ 01513 break; 01514 01515 case MODE_SET_BEGIN: 01516 case MODE_SET_RESERVE1: 01517 case MODE_SET_RESERVE2: 01518 case MODE_SET_ACTION: 01519 case MODE_SET_COMMIT: 01520 case MODE_SET_FREE: 01521 case MODE_SET_UNDO: 01522 handle_set_loop(asp); 01523 if (asp->mode != FINISHED_SUCCESS && 01524 asp->mode != FINISHED_FAILURE) { 01525 01526 if (check_for_delegated(asp)) { 01527 /* add to delegated request chain */ 01528 if (!asp->status) 01529 asp->status = status; 01530 asp->next = agent_delegated_list; 01531 agent_delegated_list = asp; 01532 } 01533 01534 return SNMP_ERR_NOERROR; 01535 } 01536 break; 01537 01538 default: 01539 break; 01540 } 01541 01542 /* if we don't have anything outstanding (delegated), wrap up */ 01543 if (!check_for_delegated(asp)) 01544 return wrap_up_request(asp, status); 01545 01546 return 1; 01547 } |
|
Definition at line 858 of file snmp_agent.c. Referenced by check_delayed_request(), check_outstanding_agent_requests(), handle_getnext_loop(), handle_set_loop(), and handle_snmp_packet().
00858 { 00859 int i; 00860 request_info *request; 00861 00862 for(i = 0; i <= asp->treecache_num; i++) { 00863 for(request = asp->treecache[i]->requests_begin; request; 00864 request = request->next) { 00865 if (request->delegated) 00866 return 1; 00867 } 00868 } 00869 return 0; 00870 } |
|
returns 1 if there are valid GETNEXT requests left. Returns 0 if not. Definition at line 1551 of file snmp_agent.c. Referenced by handle_getnext_loop().
01551 { 01552 /* get old info */ 01553 tree_cache **old_treecache = asp->treecache; 01554 int old_treecache_num = asp->treecache_num; 01555 int count = 0; 01556 int i; 01557 request_info *request; 01558 01559 for(i = 0; i <= old_treecache_num; i++) { 01560 for(request = old_treecache[i]->requests_begin; request; 01561 request = request->next) { 01562 01563 /* out of range? */ 01564 if (snmp_oid_compare(request->requestvb->name, 01565 request->requestvb->name_length, 01566 request->range_end, 01567 request->range_end_len) > 0) { 01568 /* ack, it's beyond the accepted end of range. */ 01569 /* fix it by setting the oid to the end of range oid instead */ 01570 DEBUGMSGTL(("check_getnext_results", 01571 "request response %d out of range", request->index)); 01572 01573 snmp_set_var_objid(request->requestvb, 01574 request->range_end, request->range_end_len); 01575 snmp_set_var_typed_value(request->requestvb, ASN_NULL, 01576 NULL, 0); 01577 } 01578 01579 /* mark any existent requests with illegal results as NULL */ 01580 if (request->requestvb->type == SNMP_ENDOFMIBVIEW) { 01581 /* illegal response from a subagent. Change it back to NULL */ 01582 request->requestvb->type = ASN_NULL; 01583 } 01584 01585 if (request->requestvb->type == ASN_NULL || 01586 request->requestvb->type == ASN_PRIV_RETRY) 01587 count++; 01588 } 01589 } 01590 return count; 01591 } |
|
Definition at line 1455 of file snmp_agent.c. 01455 { 01456 struct agent_snmp_session *asp, *prev_asp = NULL, *next_asp = NULL; 01457 01458 for(asp = agent_delegated_list; asp; prev_asp = asp, asp = next_asp) { 01459 next_asp = asp->next; /* save in case we clean up asp */ 01460 if (!check_for_delegated(asp)) { 01461 01462 /* we're done with this one, remove from queue */ 01463 if (prev_asp != NULL) 01464 prev_asp->next = asp->next; 01465 else 01466 agent_delegated_list = asp->next; 01467 01468 /* continue processing or finish up */ 01469 check_delayed_request(asp); 01470 } 01471 } 01472 } |
|
Definition at line 1381 of file snmp_agent.c. Referenced by check_all_requests_status(), and handle_var_requests().
01381 { 01382 /* find any errors marked in the requests */ 01383 while(requests) { 01384 if (requests->status != SNMP_ERR_NOERROR && 01385 (asp->index == 0 || 01386 requests->index < asp->index)) { 01387 asp->index = requests->index; 01388 asp->status = requests->status; 01389 } 01390 requests = requests->next; 01391 } 01392 return asp->status; 01393 } |
|
Decide if the requested transaction_id is still being processed within the agent. This is used to validate whether a delayed cache (containing possibly freed pointers) is still usable. returns SNMPERR_SUCCESS if it's still valid, or SNMPERR_GENERR if not. Definition at line 1480 of file snmp_agent.c. 01481 { 01482 struct agent_snmp_session *asp, *prev_asp = NULL; 01483 01484 for(asp = agent_delegated_list; asp; prev_asp = asp, asp = asp->next) { 01485 if (asp->pdu->transid == transaction_id) 01486 return SNMPERR_SUCCESS; 01487 } 01488 return SNMPERR_GENERR; 01489 } |
|
Definition at line 1242 of file snmp_agent.c. Referenced by handle_pdu().
01242 { 01243 struct subtree *tp; 01244 struct variable_list *varbind_ptr; 01245 int ret; 01246 int view; 01247 int vbcount = 0; 01248 01249 if (asp->treecache == NULL && 01250 asp->treecache_len == 0) { 01251 asp->treecache_len = 16; 01252 asp->treecache = malloc(sizeof(tree_cache *) * asp->treecache_len); 01253 if (asp->treecache == NULL) 01254 return SNMP_ERR_GENERR; 01255 } 01256 asp->treecache_num = -1; 01257 01258 /* collect varbinds into their registered trees */ 01259 01260 for(varbind_ptr = asp->start; varbind_ptr; 01261 varbind_ptr = varbind_ptr->next_variable) { 01262 01263 /* count the varbinds */ 01264 ++vbcount; 01265 01266 if (varbind_ptr->type != ASN_NULL && /* skip previously answered */ 01267 !(MODE_IS_SET(asp->pdu->command))) 01268 continue; 01269 01270 /* find the owning tree */ 01271 tp = find_subtree(varbind_ptr->name, varbind_ptr->name_length, NULL, 01272 asp->pdu->contextName); /* WWW: only v3 pdu's have */ 01273 01274 /* check access control */ 01275 switch(asp->pdu->command) { 01276 case SNMP_MSG_GET: 01277 view = in_a_view(varbind_ptr->name, &varbind_ptr->name_length, 01278 asp->pdu, varbind_ptr->type); 01279 if (view != VACM_SUCCESS) 01280 snmp_set_var_typed_value(varbind_ptr, SNMP_NOSUCHOBJECT, 01281 NULL, 0); 01282 break; 01283 01284 case SNMP_MSG_SET: 01285 view = in_a_view(varbind_ptr->name, &varbind_ptr->name_length, 01286 asp->pdu, varbind_ptr->type); 01287 if (view != VACM_SUCCESS) 01288 return SNMP_ERR_NOTWRITABLE; 01289 break; 01290 01291 case SNMP_MSG_GETNEXT: 01292 default: 01293 view = VACM_SUCCESS; 01294 /* WWW: check VACM here to see if "tp" is even worthwhile */ 01295 } 01296 if (view == VACM_SUCCESS) { 01297 ret = add_varbind_to_cache(asp, vbcount, varbind_ptr, tp); 01298 if (ret != SNMP_ERR_NOERROR) 01299 return ret; 01300 } 01301 } 01302 01303 return SNMPERR_SUCCESS; 01304 } |
|
Definition at line 1357 of file snmp_agent.c. Referenced by delete_subtree_cache().
01357 { 01358 request_info *saveit; 01359 while(reqlist) { 01360 /* don't delete varbind */ 01361 saveit = reqlist; 01362 reqlist = reqlist->next; 01363 if (saveit->parent_data) 01364 free_all_list_data(saveit->parent_data); 01365 free(saveit); 01366 } 01367 } |
|
Definition at line 1370 of file snmp_agent.c. Referenced by free_agent_snmp_session().
01370 { 01371 while(asp->treecache_num >= 0) { 01372 /* don't delete subtrees */ 01373 delete_request_infos(asp->treecache[asp->treecache_num] 01374 ->requests_begin); 01375 free(asp->treecache[asp->treecache_num]); 01376 asp->treecache_num--; 01377 } 01378 } |
|
Definition at line 580 of file snmp_agent.c. 00581 { 00582 agent_nsap *a = NULL, **prevNext = &agent_nsap_list; 00583 int main_session_deregistered = 0; 00584 00585 DEBUGMSGTL(("deregister_agent_nsap", "handle %d\n", handle)); 00586 00587 for (a = agent_nsap_list; a != NULL && a->handle < handle; a = a->next) { 00588 prevNext = &(a->next); 00589 } 00590 00591 if (a != NULL && a->handle == handle) { 00592 *prevNext = a->next; 00593 if (main_session == snmp_sess_session(a->s)) { 00594 main_session_deregistered = 1; 00595 } 00596 snmp_close(snmp_sess_session(a->s)); 00597 /* The above free()s the transport and session pointers. */ 00598 free(a); 00599 } 00600 00601 /* If we've deregistered the session that main_session used to point to, 00602 then make it point to another one, or in the last resort, make it equal 00603 to NULL. Basically this shouldn't ever happen in normal operation 00604 because main_session starts off pointing at the first session added by 00605 init_master_agent(), which then discards the handle. */ 00606 00607 if (main_session_deregistered) { 00608 if (agent_nsap_list != NULL) { 00609 DEBUGMSGTL(("snmp_agent", 00610 "WARNING: main_session pointer changed from %p to %p\n", 00611 main_session, snmp_sess_session(agent_nsap_list->s))); 00612 main_session = snmp_sess_session(agent_nsap_list->s); 00613 } else { 00614 DEBUGMSGTL(("snmp_agent", 00615 "WARNING: main_session pointer changed from %p to NULL\n", 00616 main_session)); 00617 main_session = NULL; 00618 } 00619 } 00620 } |
|
Definition at line 972 of file snmp_agent.c. 00973 { 00974 struct agent_snmp_session *a; 00975 00976 DEBUGMSGTL(("snmp_agent", "DUMP agent_sess_list -> ")); 00977 for (a = agent_session_list; a != NULL; a = a->next) { 00978 DEBUGMSG(("snmp_agent", "%08p[session %08p] -> ", a, a->session)); 00979 } 00980 DEBUGMSG(("snmp_agent", "[NIL]\n")); 00981 } |
|
Definition at line 1958 of file snmp_agent.c. 01959 { 01960 if (ari) 01961 free_list_data(ari->agent_data); 01962 } |
|
Definition at line 1965 of file snmp_agent.c. 01966 { 01967 if (ari) 01968 free_all_list_data(ari->agent_data); 01969 } |
|
Definition at line 1972 of file snmp_agent.c. 01973 { 01974 if (ari) { 01975 if (ari->agent_data) 01976 free_all_list_data(ari->agent_data); 01977 free(ari); 01978 } 01979 } |
|
Definition at line 840 of file snmp_agent.c. 00841 { 00842 if (!asp) 00843 return; 00844 if (asp->orig_pdu) 00845 snmp_free_pdu(asp->orig_pdu); 00846 if (asp->pdu) 00847 snmp_free_pdu(asp->pdu); 00848 if (asp->reqinfo) 00849 free_agent_request_info(asp->reqinfo); 00850 if (asp->treecache) { 00851 delete_subtree_cache(asp); 00852 free(asp->treecache); 00853 } 00854 free(asp); 00855 } |
|
Definition at line 1009 of file snmp_agent.c. 01011 { 01012 struct agent_snmp_session *a, *next, **prevNext = &agent_session_list; 01013 01014 DEBUGMSGTL(("snmp_agent", "REMOVE session == %08p\n", sess)); 01015 01016 for (a = agent_session_list; a != NULL; a = next) { 01017 if (a->session == sess) { 01018 *prevNext = a->next; 01019 next = a->next; 01020 free_agent_snmp_session(a); 01021 } else { 01022 prevNext = &(a->next); 01023 next = a->next; 01024 } 01025 } 01026 } |
|
Definition at line 248 of file snmp_agent.c. 00249 { 00250 static int SessionID = 0; 00251 00252 return ++SessionID; 00253 } |
|
Definition at line 1928 of file snmp_agent.c. 01928 { 01929 01930 struct timeval now; 01931 gettimeofday(&now, NULL); 01932 01933 return timeval_uptime( &now ); 01934 } |
|
Definition at line 219 of file snmp_agent.c. Referenced by handle_pdu().
00220 { 00221 agent_set_cache *ptr, *prev=NULL; 00222 00223 for ( ptr=Sets ; ptr != NULL ; ptr=ptr->next ) { 00224 if ( ptr->sess == asp->session && ptr->transID == asp->pdu->transid ) { 00225 if ( prev ) 00226 prev->next = ptr->next; 00227 else 00228 Sets = ptr->next; 00229 00230 /* found it. Get the needed data */ 00231 asp->treecache = ptr->treecache; 00232 asp->treecache_len = ptr->treecache_len; 00233 asp->treecache_num = ptr->treecache_num; 00234 if (!asp->reqinfo) { 00235 asp->reqinfo = SNMP_MALLOC_TYPEDEF(agent_request_info); 00236 if (asp->reqinfo) { 00237 asp->reqinfo->asp = asp; 00238 asp->reqinfo->agent_data = ptr->agent_data; 00239 } 00240 } 00241 free(ptr); 00242 return; 00243 } 00244 prev = ptr; 00245 } 00246 } |
|
repeatedly calls getnext handlers looking for an answer till all requests are satisified. It's expected that one pass has been made before entering this function Definition at line 1597 of file snmp_agent.c. Referenced by check_delayed_request(), and handle_pdu().
01597 { 01598 int status; 01599 struct variable_list *var_ptr; 01600 int count; 01601 01602 /* loop */ 01603 while (1) { 01604 01605 /* bail for now if anything is delegated. */ 01606 if (check_for_delegated(asp)) { 01607 return SNMP_ERR_NOERROR; 01608 } 01609 01610 /* check vacm against results */ 01611 check_acm(asp, ASN_PRIV_RETRY); 01612 01613 /* need to keep going we're not done yet. */ 01614 if (!check_getnext_results(asp)) 01615 /* nothing left, quit now */ 01616 break; 01617 01618 /* never had a request (empty pdu), quit now */ 01619 /* XXXWWW: huh? this would be too late, no? shouldn't we 01620 catch this earlier? */ 01621 /* if (count == 0) 01622 break; */ 01623 01624 DEBUGIF("results") { 01625 DEBUGMSGTL(("results","getnext results, before next pass: \n")); 01626 for(var_ptr = asp->pdu->variables; var_ptr; 01627 var_ptr = var_ptr->next_variable) { 01628 char buf[SPRINT_MAX_LEN]; 01629 sprint_variable(buf, var_ptr->name, var_ptr->name_length, var_ptr); 01630 DEBUGMSGTL(("results"," %s\n", buf)); 01631 } 01632 } 01633 01634 reassign_requests(asp); 01635 status = handle_var_requests(asp); 01636 if (status != SNMP_ERR_NOERROR) { 01637 return status; /* should never really happen */ 01638 } 01639 } 01640 return SNMP_ERR_NOERROR; 01641 } |
|
Definition at line 1738 of file snmp_agent.c. Referenced by handle_snmp_packet().
01738 { 01739 int status; 01740 01741 /* for illegal requests, mark all nodes as ASN_NULL */ 01742 switch(asp->pdu->command) { 01743 01744 case SNMP_MSG_INTERNAL_SET_RESERVE2: 01745 case SNMP_MSG_INTERNAL_SET_ACTION: 01746 case SNMP_MSG_INTERNAL_SET_COMMIT: 01747 case SNMP_MSG_INTERNAL_SET_FREE: 01748 case SNMP_MSG_INTERNAL_SET_UNDO: 01749 get_set_cache(asp); 01750 break; 01751 01752 case SNMP_MSG_GET: 01753 case SNMP_MSG_GETNEXT: 01754 case SNMP_MSG_GETBULK: 01755 snmp_reset_var_types(asp->pdu->variables, ASN_NULL); 01756 /* fall through */ 01757 01758 case SNMP_MSG_INTERNAL_SET_BEGIN: 01759 case SNMP_MSG_INTERNAL_SET_RESERVE1: 01760 default: 01761 /* collect varbinds */ 01762 status = create_subtree_cache(asp); 01763 if (status != SNMP_ERR_NOERROR) 01764 return status; 01765 } 01766 01767 asp->mode = asp->pdu->command; 01768 switch(asp->mode) { 01769 case SNMP_MSG_GET: 01770 /* increment the message type counter */ 01771 snmp_increment_statistic(STAT_SNMPINGETREQUESTS); 01772 01773 /* check vacm ahead of time */ 01774 check_acm(asp, SNMP_NOSUCHOBJECT); 01775 01776 /* get the results */ 01777 status = handle_var_requests(asp); 01778 01779 /* deal with unhandled results -> noSuchObject */ 01780 if (status == SNMP_ERR_NOERROR) 01781 snmp_replace_var_types(asp->pdu->variables, ASN_NULL, 01782 SNMP_NOSUCHOBJECT); 01783 break; 01784 01785 case SNMP_MSG_GETNEXT: 01786 /* increment the message type counter */ 01787 snmp_increment_statistic(STAT_SNMPINGETNEXTS); 01788 01789 /* loop through our mib tree till we find an 01790 appropriate response to return to the caller. */ 01791 01792 /* first pass */ 01793 status = handle_var_requests(asp); 01794 if (status != SNMP_ERR_NOERROR) { 01795 return status; /* should never really happen */ 01796 } 01797 01798 handle_getnext_loop(asp); 01799 break; 01800 01801 case SNMP_MSG_SET: 01802 /* check access permissions first */ 01803 if (check_acm(asp, SNMP_NOSUCHOBJECT)) 01804 return SNMP_ERR_NOTWRITABLE; 01805 01806 asp->mode = MODE_SET_BEGIN; 01807 status = handle_set_loop(asp); 01808 01809 break; 01810 01811 case SNMP_MSG_INTERNAL_SET_BEGIN: 01812 case SNMP_MSG_INTERNAL_SET_RESERVE1: 01813 case SNMP_MSG_INTERNAL_SET_RESERVE2: 01814 case SNMP_MSG_INTERNAL_SET_ACTION: 01815 case SNMP_MSG_INTERNAL_SET_COMMIT: 01816 case SNMP_MSG_INTERNAL_SET_FREE: 01817 case SNMP_MSG_INTERNAL_SET_UNDO: 01818 asp->pdu->flags |= UCD_MSG_FLAG_ONE_PASS_ONLY; 01819 status = handle_set_loop(asp); 01820 /* asp related cache is saved in cleanup */ 01821 break; 01822 01823 case SNMP_MSG_GETBULK: 01824 break; 01825 /* WWW */ 01826 01827 case SNMP_MSG_RESPONSE: 01828 snmp_increment_statistic(STAT_SNMPINGETRESPONSES); 01829 return SNMP_ERR_NOERROR; 01830 01831 case SNMP_MSG_TRAP: 01832 case SNMP_MSG_TRAP2: 01833 snmp_increment_statistic(STAT_SNMPINTRAPS); 01834 return SNMP_ERR_NOERROR; 01835 01836 default: 01837 /* WWW: are reports counted somewhere ? */ 01838 snmp_increment_statistic(STAT_SNMPINASNPARSEERRS); 01839 return SNMPERR_GENERR; /* shouldn't get here */ 01840 /* WWW */ 01841 } 01842 return status; 01843 } |
|
Definition at line 1644 of file snmp_agent.c. Referenced by handle_set_loop().
01644 { 01645 int status; 01646 /* 01647 * SETS require 3-4 passes through the var_op_list. 01648 * The first two 01649 * passes verify that all types, lengths, and values are valid 01650 * and may reserve resources and the third does the set and a 01651 * fourth executes any actions. Then the identical GET RESPONSE 01652 * packet is returned. 01653 * If either of the first two passes returns an error, another 01654 * pass is made so that any reserved resources can be freed. 01655 * If the third pass returns an error, another pass is 01656 * made so that 01657 * any changes can be reversed. 01658 * If the fourth pass (or any of the error handling passes) 01659 * return an error, we'd rather not know about it! 01660 */ 01661 if (!(asp->pdu->flags & UCD_MSG_FLAG_ONE_PASS_ONLY)) { 01662 switch (asp->mode) { 01663 case MODE_SET_BEGIN: 01664 snmp_increment_statistic(STAT_SNMPINSETREQUESTS); 01665 asp->rw = WRITE; /* WWW: still needed? */ 01666 asp->mode = MODE_SET_RESERVE1; 01667 asp->status = SNMP_ERR_NOERROR; 01668 break; 01669 01670 case MODE_SET_RESERVE1: 01671 01672 if ( asp->status != SNMP_ERR_NOERROR ) 01673 asp->mode = MODE_SET_FREE; 01674 else 01675 asp->mode = MODE_SET_RESERVE2; 01676 break; 01677 01678 case MODE_SET_RESERVE2: 01679 if ( asp->status != SNMP_ERR_NOERROR ) 01680 asp->mode = MODE_SET_FREE; 01681 else 01682 asp->mode = MODE_SET_ACTION; 01683 break; 01684 01685 case MODE_SET_ACTION: 01686 if ( asp->status != SNMP_ERR_NOERROR ) 01687 asp->mode = MODE_SET_UNDO; 01688 else 01689 asp->mode = MODE_SET_COMMIT; 01690 break; 01691 01692 case MODE_SET_COMMIT: 01693 if ( asp->status != SNMP_ERR_NOERROR ) { 01694 asp->status = SNMP_ERR_COMMITFAILED; 01695 asp->mode = FINISHED_FAILURE; 01696 } 01697 else 01698 asp->mode = FINISHED_SUCCESS; 01699 break; 01700 01701 case MODE_SET_UNDO: 01702 if (asp->status != SNMP_ERR_NOERROR ) 01703 asp->status = SNMP_ERR_UNDOFAILED; 01704 01705 asp->mode = FINISHED_FAILURE; 01706 break; 01707 01708 case MODE_SET_FREE: 01709 asp->mode = FINISHED_FAILURE; 01710 break; 01711 } 01712 } 01713 01714 if (asp->mode != FINISHED_SUCCESS && asp->mode != FINISHED_FAILURE) { 01715 DEBUGMSGTL(("agent_set","doing set mode = %d\n",asp->mode)); 01716 status = handle_var_requests( asp ); 01717 if (status != SNMP_ERR_NOERROR && asp->status == SNMP_ERR_NOERROR) 01718 asp->status = status; 01719 DEBUGMSGTL(("agent_set","did set mode = %d, status = %d\n", 01720 asp->mode, asp->status)); 01721 } 01722 return asp->status; 01723 } |
|
Definition at line 1726 of file snmp_agent.c. Referenced by check_delayed_request(), and handle_pdu().
01726 { 01727 while(asp->mode != FINISHED_FAILURE && asp->mode != FINISHED_SUCCESS) { 01728 handle_set(asp); 01729 if (check_for_delegated(asp)) 01730 return SNMP_ERR_NOERROR; 01731 if (asp->pdu->flags & UCD_MSG_FLAG_ONE_PASS_ONLY) 01732 return asp->status; 01733 } 01734 return asp->status; 01735 } |
|
handles an incoming SNMP packet into the agent.
Definition at line 1030 of file snmp_agent.c. 01032 { 01033 struct agent_snmp_session *asp; 01034 int status, access_ret; 01035 struct variable_list *var_ptr; 01036 01037 /* we only support receiving here */ 01038 if (op != SNMP_CALLBACK_OP_RECEIVED_MESSAGE) { 01039 return 1; 01040 } 01041 01042 /* new request */ 01043 asp = init_agent_snmp_session( session, pdu ); 01044 status = SNMP_ERR_NOERROR; 01045 01046 /* initial access check. Is request user/community allowed to do 01047 anything at all? If not, abondon all hope here. */ 01048 if ((access_ret = check_access(pdu)) != 0) { 01049 if (access_ret == VACM_NOSUCHCONTEXT) { 01050 /* rfc2573 section 3.2, step 5 says that we increment the 01051 counter but don't return a response of any kind */ 01052 01053 /* we currently don't support unavailable contexts, as 01054 there is no reason to that I currently know of */ 01055 snmp_increment_statistic(STAT_SNMPUNKNOWNCONTEXTS); 01056 01057 /* drop the request */ 01058 remove_and_free_agent_snmp_session( asp ); 01059 return 0; 01060 } else { 01061 /* access control setup is incorrect */ 01062 send_easy_trap(SNMP_TRAP_AUTHFAIL, 0); 01063 if (asp->pdu->version != SNMP_VERSION_1 && 01064 asp->pdu->version != SNMP_VERSION_2c) { 01065 asp->pdu->errstat = SNMP_ERR_AUTHORIZATIONERROR; 01066 asp->pdu->command = SNMP_MSG_RESPONSE; 01067 snmp_increment_statistic(STAT_SNMPOUTPKTS); 01068 if (! snmp_send( asp->session, asp->pdu )) 01069 snmp_free_pdu(asp->pdu); 01070 asp->pdu = NULL; 01071 remove_and_free_agent_snmp_session(asp); 01072 return 1; 01073 } else { 01074 /* drop the request */ 01075 remove_and_free_agent_snmp_session( asp ); 01076 return 0; 01077 } 01078 } 01079 } 01080 01081 /* process the request */ 01082 status = handle_pdu(asp); 01083 01084 /* print the results in approrpiate debugging mode */ 01085 DEBUGIF("results") { 01086 DEBUGMSGTL(("results","request results (status = %d): \n", status)); 01087 for(var_ptr = asp->pdu->variables; var_ptr; 01088 var_ptr = var_ptr->next_variable) { 01089 char buf[SPRINT_MAX_LEN]; 01090 sprint_variable(buf, var_ptr->name, var_ptr->name_length, var_ptr); 01091 DEBUGMSGTL(("results"," %s\n", buf)); 01092 } 01093 } 01094 01095 /* check for uncompleted requests */ 01096 if (check_for_delegated(asp)) { 01097 /* add to delegated request chain */ 01098 asp->status = status; 01099 asp->next = agent_delegated_list; 01100 agent_delegated_list = asp; 01101 } else { 01102 /* if we don't have anything outstanding (delegated), wrap up */ 01103 return wrap_up_request(asp, status); 01104 } 01105 01106 /* done */ 01107 DEBUGMSGTL(("snmp_agent", "end of handle_snmp_packet, asp = %08p\n", asp)); 01108 return 1; 01109 } |
|
Definition at line 1405 of file snmp_agent.c. Referenced by handle_getnext_loop(), handle_pdu(), and handle_set().
01405 { 01406 int i, retstatus = SNMP_ERR_NOERROR, 01407 status = SNMP_ERR_NOERROR, final_status = SNMP_ERR_NOERROR; 01408 handler_registration *reginfo; 01409 01410 /* create the agent_request_info data */ 01411 if (!asp->reqinfo) { 01412 asp->reqinfo = SNMP_MALLOC_TYPEDEF(agent_request_info); 01413 if (!asp->reqinfo) 01414 return SNMP_ERR_GENERR; 01415 } 01416 01417 asp->reqinfo->asp = asp; 01418 asp->reqinfo->mode = asp->mode; 01419 01420 /* now, have the subtrees in the cache go search for their results */ 01421 for(i=0; i <= asp->treecache_num; i++) { 01422 reginfo = asp->treecache[i]->subtree->reginfo; 01423 status = call_handlers(reginfo, asp->reqinfo, 01424 asp->treecache[i]->requests_begin); 01425 01426 /* find any errors marked in the requests */ 01427 retstatus = 01428 check_requests_status(asp, asp->treecache[i]->requests_begin); 01429 01430 /* always take lowest varbind if possible */ 01431 if (retstatus != SNMP_ERR_NOERROR) 01432 status = retstatus; 01433 01434 /* other things we know less about (no index) */ 01435 /* WWW: drop support for this? */ 01436 if (final_status == SNMP_ERR_NOERROR && 01437 status != SNMP_ERR_NOERROR) { 01438 /* we can't break here, since some processing needs to be 01439 done for all requests anyway (IE, SET handling for UNDO 01440 needs to be called regardless of previous status 01441 results. 01442 WWW: This should be predictable though and 01443 breaking should be possible in some cases (eg GET, 01444 GETNEXT, ...) */ 01445 final_status = status; 01446 } 01447 } 01448 01449 return final_status; 01450 } |
|
Definition at line 812 of file snmp_agent.c. 00813 { 00814 struct agent_snmp_session *asp; 00815 00816 asp = (struct agent_snmp_session *) calloc(1, sizeof( struct agent_snmp_session )); 00817 00818 if ( asp == NULL ) 00819 return NULL; 00820 asp->session = session; 00821 asp->pdu = snmp_clone_pdu(pdu); 00822 asp->orig_pdu = snmp_clone_pdu(pdu); 00823 asp->rw = READ; 00824 asp->exact = TRUE; 00825 asp->next = NULL; 00826 asp->mode = RESERVE1; 00827 asp->status = SNMP_ERR_NOERROR; 00828 asp->index = 0; 00829 00830 asp->start = asp->pdu->variables; 00831 asp->end = asp->pdu->variables; 00832 if ( asp->end != NULL ) 00833 while ( asp->end->next_variable != NULL ) 00834 asp->end = asp->end->next_variable; 00835 00836 return asp; 00837 } |
|
Definition at line 648 of file snmp_agent.c. Referenced by main().
00649 { 00650 snmp_transport *transport; 00651 char *cptr, *cptr2; 00652 char buf[SPRINT_MAX_LEN]; 00653 00654 if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE) != MASTER_AGENT) { 00655 DEBUGMSGTL(("snmp_agent", "init_master_agent; not master agent\n")); 00656 return 0; /* No error if ! MASTER_AGENT */ 00657 } 00658 00659 #ifdef USING_AGENTX_MASTER_MODULE 00660 if ( ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_AGENTX_MASTER) == 1 ) 00661 real_init_master(); 00662 #endif 00663 00664 /* Have specific agent ports been specified? */ 00665 cptr = ds_get_string(DS_APPLICATION_ID, DS_AGENT_PORTS); 00666 00667 if (cptr) { 00668 sprintf(buf, "%s", cptr); 00669 } else { 00670 /* No, so just specify the default port. */ 00671 if (ds_get_int(DS_APPLICATION_ID, DS_AGENT_FLAGS) & 00672 SNMP_FLAGS_STREAM_SOCKET) { 00673 sprintf(buf, "tcp:%d", SNMP_PORT); 00674 } else { 00675 sprintf(buf, "udp:%d", SNMP_PORT); 00676 } 00677 } 00678 00679 DEBUGMSGTL(("snmp_agent", "final port spec: %s\n", buf)); 00680 cptr = strtok(buf, ","); 00681 while (cptr) { 00682 /* Specification format: 00683 00684 NONE: (a pseudo-transport) 00685 UDP:[address:]port (also default if no transport is specified) 00686 TCP:[address:]port (if supported) 00687 Unix:pathname (if supported) 00688 AAL5PVC:itf.vpi.vci (if supported) 00689 IPX:[network]:node[/port] (if supported) 00690 00691 */ 00692 00693 DEBUGMSGTL(("snmp_agent", "installing master agent on port %s\n", cptr)); 00694 00695 if (!cptr || !(*cptr)) { 00696 snmp_log(LOG_ERR, "improper port specification\n"); 00697 return 1; 00698 } 00699 00700 /* Transport type specifier? */ 00701 00702 if ((cptr2 = strchr(cptr, ':')) != NULL) { 00703 if (strncasecmp(cptr, "none", 4) == 0) { 00704 DEBUGMSGTL(("snmp_agent", 00705 "init_master_agent; pseudo-transport \"none\" requested\n")); 00706 return 0; 00707 } else if (strncasecmp(cptr, "tcp", 3) == 0) { 00708 #ifdef SNMP_TRANSPORT_TCP_DOMAIN 00709 struct sockaddr_in addr; 00710 if (snmp_sockaddr_in(&addr, cptr2+1, 0)) { 00711 transport = snmp_tcp_transport(&addr, 1); 00712 } else { 00713 snmp_log(LOG_ERR, 00714 "Badly formatted IP address (should be [a.b.c.d:]p)\n"); 00715 return 1; 00716 } 00717 #else 00718 snmp_log(LOG_ERR, "No support for requested TCP domain\n"); 00719 return 1; 00720 #endif 00721 } else if (strncasecmp(cptr, "ipx", 3) == 0) { 00722 #ifdef SNMP_TRANSPORT_IPX_DOMAIN 00723 struct sockaddr_ipx addr; 00724 if (snmp_sockaddr_ipx(&addr, cptr2+1)) { 00725 transport = snmp_ipx_transport(&addr, 1); 00726 } else { 00727 snmp_log(LOG_ERR, 00728 "Badly formatted IPX address (should be [net]:node[/port])\n"); 00729 return 1; 00730 } 00731 #else 00732 snmp_log(LOG_ERR, "No support for requested IPX domain\n"); 00733 #endif 00734 } else if (strncasecmp(cptr, "aal5pvc", 7) == 0) { 00735 #ifdef SNMP_TRANSPORT_AAL5PVC_DOMAIN 00736 struct sockaddr_atmpvc addr; 00737 if (sscanf(cptr2+1, "%d.%d.%d", &(addr.sap_addr.itf), 00738 &(addr.sap_addr.vpi), &(addr.sap_addr.vci))==3) { 00739 addr.sap_family = AF_ATMPVC; 00740 transport = snmp_aal5pvc_transport(&addr, 1); 00741 } else { 00742 snmp_log(LOG_ERR, 00743 "Badly formatted AAL5 PVC address (should be itf.vpi.vci)\n"); 00744 return 1; 00745 } 00746 #else 00747 snmp_log(LOG_ERR, "No support for requested AAL5 PVC domain\n"); 00748 return 1; 00749 #endif 00750 } else if (strncasecmp(cptr, "unix", 4) == 0) { 00751 #ifdef SNMP_TRANSPORT_UNIX_DOMAIN 00752 struct sockaddr_un addr; 00753 addr.sun_family = AF_UNIX; 00754 strncpy(addr.sun_path, cptr2+1, 00755 sizeof(addr) - (size_t) (((struct sockaddr_un *)0)->sun_path)); 00756 transport = snmp_unix_transport(&addr, 1); 00757 #else 00758 snmp_log(LOG_ERR, "No support for requested Unix domain\n"); 00759 return 1; 00760 #endif 00761 } else if (strncasecmp(cptr, "udp", 3) == 0) { 00762 struct sockaddr_in addr; 00763 if (snmp_sockaddr_in(&addr, cptr2+1, 0)) { 00764 transport = snmp_udp_transport(&addr, 1); 00765 } else { 00766 snmp_log(LOG_ERR, 00767 "Badly formatted IP address (should be [a.b.c.d:]p)\n"); 00768 return 1; 00769 } 00770 } else { 00771 snmp_log(LOG_ERR, "Unknown transport domain \"%s\"\n", cptr); 00772 return 1; 00773 } 00774 } else { 00775 /* No transport type specifier; default to UDP. */ 00776 struct sockaddr_in addr; 00777 if (snmp_sockaddr_in(&addr, cptr, 0)) { 00778 transport = snmp_udp_transport(&addr, 1); 00779 } else { 00780 snmp_log(LOG_ERR, 00781 "Badly formatted IP address (should be [a.b.c.d:]p)\n"); 00782 return 1; 00783 } 00784 } 00785 00786 if (transport == NULL) { 00787 snmp_log(LOG_ERR, "Error opening specified transport \"%s\"\n", cptr); 00788 return 1; 00789 } 00790 00791 if (register_agent_nsap(transport) == 0) { 00792 snmp_log(LOG_ERR, 00793 "Error registering specified transport \"%s\" as an agent NSAP\n", 00794 cptr); 00795 return 1; 00796 } else { 00797 DEBUGMSGTL(("snmp_agent", 00798 "init_master_agent; \"%s\" registered as an agent NSAP\n", 00799 cptr)); 00800 } 00801 00802 /* Next transport please... */ 00803 cptr = strtok(NULL, ","); 00804 } 00805 00806 return 0; 00807 } |
|
Definition at line 1911 of file snmp_agent.c. 01912 { 01913 int res; 01914 marker_t start = (marker_t)&starttime; 01915 01916 res = atime_diff( start, pm ); 01917 return res/10; /* atime_diff works in msec, not csec */ 01918 } |
|
Definition at line 1308 of file snmp_agent.c. Referenced by handle_getnext_loop().
01308 { 01309 /* assume all the requests have been filled or rejected by the 01310 subtrees, so reassign the rejected ones to the next subtree in 01311 the chain */ 01312 01313 int i, ret; 01314 request_info *request, *lastreq = NULL; 01315 01316 /* get old info */ 01317 tree_cache **old_treecache = asp->treecache; 01318 int old_treecache_num = asp->treecache_num; 01319 01320 /* malloc new space */ 01321 asp->treecache = 01322 (tree_cache **) malloc(sizeof(tree_cache *) * asp->treecache_len); 01323 asp->treecache_num = -1; 01324 01325 for(i = 0; i <= old_treecache_num; i++) { 01326 for(request = old_treecache[i]->requests_begin; request; 01327 request = request->next) { 01328 01329 if (lastreq) 01330 free(lastreq); 01331 lastreq = request; 01332 01333 if (request->requestvb->type == ASN_NULL) { 01334 ret = add_varbind_to_cache(asp, request->index, 01335 request->requestvb, 01336 old_treecache[i]->subtree->next); 01337 if (ret != SNMP_ERR_NOERROR) 01338 return ret; /* WWW: mem leak */ 01339 } else if (request->requestvb->type == ASN_PRIV_RETRY) { 01340 /* re-add the same subtree */ 01341 request->requestvb->type = ASN_NULL; 01342 ret = add_varbind_to_cache(asp, request->index, 01343 request->requestvb, 01344 old_treecache[i]->subtree); 01345 if (ret != SNMP_ERR_NOERROR) 01346 return ret; /* WWW: mem leak */ 01347 } 01348 } 01349 } 01350 if (lastreq) 01351 free(lastreq); 01352 free(old_treecache); 01353 return SNMP_ERR_NOERROR; 01354 } |
|
Definition at line 508 of file snmp_agent.c. 00509 { 00510 struct snmp_session *s, *sp = NULL; 00511 agent_nsap *a = NULL, *n = NULL, **prevNext = &agent_nsap_list; 00512 int handle = 0; 00513 void *isp = NULL; 00514 00515 if (t == NULL) { 00516 return -1; 00517 } 00518 00519 DEBUGMSGTL(("register_agent_nsap", "fd %d\n", t->sock)); 00520 00521 n = (agent_nsap *)malloc(sizeof(agent_nsap)); 00522 if (n == NULL) { 00523 return -1; 00524 } 00525 s = (struct snmp_session *)malloc(sizeof(struct snmp_session)); 00526 if (s == NULL) { 00527 free(n); 00528 return -1; 00529 } 00530 memset(s, 0, sizeof(struct snmp_session)); 00531 snmp_sess_init(s); 00532 00533 /* Set up the session appropriately for an agent. */ 00534 00535 s->version = SNMP_DEFAULT_VERSION; 00536 s->callback = handle_snmp_packet; 00537 s->authenticator = NULL; 00538 s->flags = ds_get_int(DS_APPLICATION_ID, DS_AGENT_FLAGS); 00539 s->isAuthoritative = SNMP_SESS_AUTHORITATIVE; 00540 00541 sp = snmp_add(s, t, snmp_check_packet, snmp_check_parse); 00542 if (sp == NULL) { 00543 free(s); 00544 free(n); 00545 return -1; 00546 } 00547 00548 isp = snmp_sess_pointer(sp); 00549 if (isp == NULL) { /* over-cautious */ 00550 free(s); 00551 free(n); 00552 return -1; 00553 } 00554 00555 n->s = isp; 00556 n->t = t; 00557 00558 if (main_session == NULL) { 00559 main_session = snmp_sess_session(isp); 00560 } 00561 00562 for (a = agent_nsap_list; a != NULL && handle+1 >= a->handle; a = a->next) { 00563 handle = a->handle; 00564 prevNext = &(a->next); 00565 } 00566 00567 if (handle < INT_MAX) { 00568 n->handle = handle + 1; 00569 n->next = a; 00570 *prevNext = n; 00571 free(s); 00572 return n->handle; 00573 } else { 00574 free(s); 00575 free(n); 00576 return -1; 00577 } 00578 } |
|
Definition at line 984 of file snmp_agent.c. 00985 { 00986 struct agent_snmp_session *a, **prevNext = &agent_session_list; 00987 00988 DEBUGMSGTL(("snmp_agent", "REMOVE %08p\n", asp)); 00989 00990 for (a = agent_session_list; a != NULL; a = *prevNext) { 00991 if (a == asp) { 00992 *prevNext = a->next; 00993 a->next = NULL; 00994 free_agent_snmp_session(a); 00995 asp = NULL; 00996 break; 00997 } else { 00998 prevNext = &(a->next); 00999 } 01000 } 01001 01002 if (a == NULL && asp != NULL) { 01003 /* We coulnd't find it on the list, so free it anyway. */ 01004 free_agent_snmp_session(asp); 01005 } 01006 } |
|
Definition at line 192 of file snmp_agent.c. Referenced by wrap_up_request().
00193 { 00194 agent_set_cache *ptr; 00195 00196 ptr = SNMP_MALLOC_TYPEDEF(agent_set_cache); 00197 if (ptr == NULL ) 00198 return NULL; 00199 00200 /* Save the important information */ 00201 ptr->transID = asp->pdu->transid; 00202 ptr->sess = asp->session; 00203 ptr->treecache = asp->treecache; 00204 ptr->treecache_len = asp->treecache_len; 00205 ptr->treecache_num = asp->treecache_num; 00206 ptr->agent_data = asp->reqinfo->agent_data; 00207 00208 /* make the agent forget about what we've saved */ 00209 asp->treecache = NULL; 00210 asp->reqinfo->agent_data = NULL; 00211 00212 ptr->next = Sets; 00213 Sets = ptr; 00214 00215 return ptr; 00216 } |
|
Definition at line 1898 of file snmp_agent.c. 01899 { 01900 while(requests) { 01901 set_request_error(reqinfo, requests, error_value); 01902 requests = requests->next; 01903 } 01904 return error_value; 01905 } |
|
Definition at line 1853 of file snmp_agent.c. 01854 { 01855 if (!request) 01856 return error_value; 01857 01858 request->processed = 1; 01859 01860 switch(error_value) { 01861 case SNMP_NOSUCHOBJECT: 01862 case SNMP_NOSUCHINSTANCE: 01863 case SNMP_ENDOFMIBVIEW: 01864 /* these are exceptions that should be put in the varbind 01865 in the case of a GET but should be translated for a SET 01866 into a real error status code and put in the request */ 01867 switch (mode) { 01868 case MODE_GET: 01869 request->requestvb->type = error_value; 01870 return error_value; 01871 01872 case MODE_GETNEXT: 01873 case MODE_GETBULK: 01874 /* ignore these. They're illegal to set by the 01875 client APIs for these modes */ 01876 return error_value; 01877 01878 default: 01879 request->status = SNMP_ERR_NOSUCHNAME; /* WWW: correct? */ 01880 return error_value; 01881 } 01882 break; /* never get here */ 01883 01884 default: 01885 if (request->status < 0) { 01886 /* illegal local error code. translate to generr */ 01887 /* WWW: full translation map? */ 01888 request->status = SNMP_ERR_GENERR; 01889 } else { 01890 /* WWW: translations and mode checking? */ 01891 request->status = error_value; 01892 } 01893 return error_value; 01894 } 01895 return error_value; 01896 } |
|
Definition at line 1845 of file snmp_agent.c. 01846 { 01847 if (!request || !reqinfo) 01848 return error_value; 01849 01850 return set_mode_request_error(reqinfo->mode, request, error_value); 01851 } |
|
Definition at line 325 of file snmp_agent.c. Referenced by main().
00326 { 00327 int i = 0; 00328 00329 lastAddrAge = 0; 00330 for (i = 0; i < SNMP_ADDRCACHE_SIZE; i++) { 00331 if (addrCache[i].status == SNMP_ADDRCACHE_OLD) { 00332 addrCache[i].status = SNMP_ADDRCACHE_UNUSED; 00333 if (addrCache[i].addr != NULL) { 00334 free(addrCache[i].addr); 00335 addrCache[i].addr = NULL; 00336 } 00337 } 00338 if (addrCache[i].status == SNMP_ADDRCACHE_USED) { 00339 addrCache[i].status = SNMP_ADDRCACHE_OLD; 00340 } 00341 } 00342 } |
|
Definition at line 311 of file snmp_agent.c. Referenced by main().
00312 { 00313 int i = 0; 00314 00315 for (i = 0; i < SNMP_ADDRCACHE_SIZE; i++) { 00316 addrCache[i].addr = NULL; 00317 addrCache[i].status = SNMP_ADDRCACHE_UNUSED; 00318 } 00319 } |
|
Definition at line 361 of file snmp_agent.c. 00363 { 00364 char *addr_string = NULL; 00365 int i = 0; 00366 00367 /* 00368 * Log the message and/or dump the message. 00369 * Optionally cache the network address of the sender. 00370 */ 00371 00372 if (transport != NULL && transport->f_fmtaddr != NULL) { 00373 /* Okay I do know how to format this address for logging. */ 00374 addr_string = transport->f_fmtaddr(transport, transport_data, 00375 transport_data_length); 00376 /* Don't forget to free() it. */ 00377 } else { 00378 /* Don't know how to format the address for logging. */ 00379 addr_string = strdup("<UNKNOWN>"); 00380 } 00381 00382 #ifdef USE_LIBWRAP 00383 if (hosts_ctl("snmpd", addr_string, addr_string, STRING_UNKNOWN)) { 00384 snmp_log(allow_severity, "Connection from %s\n", addr_string); 00385 } else { 00386 snmp_log(deny_severity, "Connection from %s REFUSED\n", addr_string); 00387 if (addr_string != NULL) { 00388 free(addr_string); 00389 } 00390 return 0; 00391 } 00392 #endif/*USE_LIBWRAP*/ 00393 00394 snmp_increment_statistic(STAT_SNMPINPKTS); 00395 00396 if (log_addresses || ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE)) { 00397 00398 for (i = 0; i < SNMP_ADDRCACHE_SIZE; i++) { 00399 if ((addrCache[i].status != SNMP_ADDRCACHE_UNUSED) && 00400 (strcmp(addrCache[i].addr, addr_string) == 0)) { 00401 break; 00402 } 00403 } 00404 00405 if (i >= SNMP_ADDRCACHE_SIZE || 00406 ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE)){ 00407 /* Address wasn't in the cache, so log the packet... */ 00408 snmp_log(LOG_INFO, "Received SNMP packet(s) from %s\n", addr_string); 00409 /* ...and try to cache the address. */ 00410 for (i = 0; i < SNMP_ADDRCACHE_SIZE; i++) { 00411 if (addrCache[i].status == SNMP_ADDRCACHE_UNUSED) { 00412 if (addrCache[i].addr != NULL) { 00413 free(addrCache[i].addr); 00414 } 00415 addrCache[i].addr = addr_string; 00416 addrCache[i].status = SNMP_ADDRCACHE_USED; 00417 addr_string = NULL; /* Don't free this 'temporary' string 00418 since it's now part of the cache */ 00419 break; 00420 } 00421 } 00422 if (i >= SNMP_ADDRCACHE_SIZE) { 00423 /* We didn't find a free slot to cache the address. Perhaps we 00424 should be using an LRU replacement policy here or something. Oh 00425 well. */ 00426 DEBUGMSGTL(("snmp_check_packet", "cache overrun")); 00427 } 00428 } else { 00429 addrCache[i].status = SNMP_ADDRCACHE_USED; 00430 } 00431 } 00432 00433 if (addr_string != NULL) { 00434 free(addr_string); 00435 addr_string = NULL; 00436 } 00437 return 1; 00438 } |
|
|
|
Definition at line 441 of file snmp_agent.c. 00443 { 00444 if (result == 0) { 00445 if (ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE) && 00446 snmp_get_do_logging()) { 00447 struct variable_list *var_ptr; 00448 00449 switch (pdu->command) { 00450 case SNMP_MSG_GET: 00451 snmp_log(LOG_DEBUG, " GET message\n"); break; 00452 case SNMP_MSG_GETNEXT: 00453 snmp_log(LOG_DEBUG, " GETNEXT message\n"); break; 00454 case SNMP_MSG_RESPONSE: 00455 snmp_log(LOG_DEBUG, " RESPONSE message\n"); break; 00456 case SNMP_MSG_SET: 00457 snmp_log(LOG_DEBUG, " SET message\n"); break; 00458 case SNMP_MSG_TRAP: 00459 snmp_log(LOG_DEBUG, " TRAP message\n"); break; 00460 case SNMP_MSG_GETBULK: 00461 snmp_log(LOG_DEBUG, " GETBULK message, non-rep=%d, max_rep=%d\n", 00462 pdu->errstat, pdu->errindex); break; 00463 case SNMP_MSG_INFORM: 00464 snmp_log(LOG_DEBUG, " INFORM message\n"); break; 00465 case SNMP_MSG_TRAP2: 00466 snmp_log(LOG_DEBUG, " TRAP2 message\n"); break; 00467 case SNMP_MSG_REPORT: 00468 snmp_log(LOG_DEBUG, " REPORT message\n"); break; 00469 } 00470 00471 for (var_ptr = pdu->variables; var_ptr != NULL; 00472 var_ptr=var_ptr->next_variable) { 00473 size_t c_oidlen = 256, c_outlen = 0; 00474 u_char *c_oid = (u_char *)malloc(c_oidlen); 00475 00476 if (c_oid) { 00477 if (!sprint_realloc_objid(&c_oid, &c_oidlen, &c_outlen, 1, 00478 var_ptr->name, var_ptr->name_length)) { 00479 snmp_log(LOG_DEBUG, " -- %s [TRUNCATED]\n", c_oid); 00480 } else { 00481 snmp_log(LOG_DEBUG, " -- %s\n", c_oid); 00482 } 00483 free(c_oid); 00484 } 00485 } 00486 } 00487 return 1; 00488 } 00489 return 0; /* XXX: does it matter what the return value is? Yes: if we 00490 return 0, then the PDU is dumped. */ 00491 } |
|
Definition at line 1921 of file snmp_agent.c. 01922 { 01923 return marker_uptime((marker_t)tv); 01924 } |
|
Definition at line 874 of file snmp_agent.c. Referenced by check_delayed_request(), and handle_snmp_packet().
00874 { 00875 struct variable_list *var_ptr; 00876 int i; 00877 00878 /* some stuff needs to be saved in special subagent cases */ 00879 switch(asp->pdu->command) { 00880 case SNMP_MSG_INTERNAL_SET_BEGIN: 00881 case SNMP_MSG_INTERNAL_SET_RESERVE1: 00882 case SNMP_MSG_INTERNAL_SET_RESERVE2: 00883 case SNMP_MSG_INTERNAL_SET_ACTION: 00884 case SNMP_MSG_INTERNAL_SET_COMMIT: 00885 case SNMP_MSG_INTERNAL_SET_FREE: 00886 case SNMP_MSG_INTERNAL_SET_UNDO: 00887 save_set_cache(asp); 00888 break; 00889 } 00890 00891 /* 00892 * May need to "dumb down" a SET error status for a 00893 * v1 query. See RFC2576 - section 4.3 00894 */ 00895 if (( asp->pdu ) && 00896 ( asp->pdu->command == SNMP_MSG_SET ) && 00897 ( asp->pdu->version == SNMP_VERSION_1 )) { 00898 switch ( status ) { 00899 case SNMP_ERR_WRONGVALUE: 00900 case SNMP_ERR_WRONGENCODING: 00901 case SNMP_ERR_WRONGTYPE: 00902 case SNMP_ERR_WRONGLENGTH: 00903 case SNMP_ERR_INCONSISTENTVALUE: 00904 status = SNMP_ERR_BADVALUE; 00905 break; 00906 case SNMP_ERR_NOACCESS: 00907 case SNMP_ERR_NOTWRITABLE: 00908 case SNMP_ERR_NOCREATION: 00909 case SNMP_ERR_INCONSISTENTNAME: 00910 case SNMP_ERR_AUTHORIZATIONERROR: 00911 status = SNMP_ERR_NOSUCHNAME; 00912 break; 00913 case SNMP_ERR_RESOURCEUNAVAILABLE: 00914 case SNMP_ERR_COMMITFAILED: 00915 case SNMP_ERR_UNDOFAILED: 00916 status = SNMP_ERR_GENERR; 00917 break; 00918 } 00919 } 00920 /* 00921 * Similarly we may need to "dumb down" v2 exception 00922 * types to throw an error for a v1 query. 00923 * See RFC2576 - section 4.1.2.3 00924 */ 00925 if (( asp->pdu ) && 00926 ( asp->pdu->command != SNMP_MSG_SET ) && 00927 ( asp->pdu->version == SNMP_VERSION_1 )) { 00928 for ( var_ptr = asp->pdu->variables, i=1 ; 00929 var_ptr != NULL ; 00930 var_ptr = var_ptr->next_variable, i++ ) { 00931 switch ( var_ptr->type ) { 00932 case SNMP_NOSUCHOBJECT: 00933 case SNMP_NOSUCHINSTANCE: 00934 case SNMP_ENDOFMIBVIEW: 00935 case ASN_COUNTER64: 00936 status = SNMP_ERR_NOSUCHNAME; 00937 asp->index=i; 00938 break; 00939 } 00940 } 00941 } 00942 if (( status == SNMP_ERR_NOERROR ) && ( asp->pdu )) { 00943 snmp_increment_statistic_by( 00944 (asp->pdu->command == SNMP_MSG_SET ? 00945 STAT_SNMPINTOTALSETVARS : STAT_SNMPINTOTALREQVARS ), 00946 count_varbinds( asp->pdu->variables )); 00947 } 00948 else { 00949 /* 00950 * Use a copy of the original request 00951 * to report failures. 00952 */ 00953 snmp_free_pdu( asp->pdu ); 00954 asp->pdu = asp->orig_pdu; 00955 asp->orig_pdu = NULL; 00956 } 00957 if ( asp->pdu ) { 00958 asp->pdu->command = SNMP_MSG_RESPONSE; 00959 asp->pdu->errstat = asp->status; 00960 asp->pdu->errindex = asp->index; 00961 if (! snmp_send( asp->session, asp->pdu )) 00962 snmp_free_pdu(asp->pdu); 00963 snmp_increment_statistic(STAT_SNMPOUTPKTS); 00964 snmp_increment_statistic(STAT_SNMPOUTGETRESPONSES); 00965 asp->pdu = NULL; 00966 remove_and_free_agent_snmp_session(asp); 00967 } 00968 return 1; 00969 } |
|
Definition at line 136 of file snmp_agent.c. |
|
Definition at line 122 of file snmp_agent.c. |
|
Definition at line 123 of file snmp_agent.c. |
|
Definition at line 500 of file snmp_agent.c. |
|
Definition at line 1907 of file snmp_agent.c. |
Last modified: Wednesday, 01-Aug-2018 04:41:28 UTC
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.