~ubuntu-branches/ubuntu/wily/net-snmp/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/CVE-2012-6151.patch/agent/mibgroup/agentx/master_admin.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-04-08 08:17:14 UTC
  • Revision ID: package-import@ubuntu.com-20140408081714-31du0g3p3ggkwe9o
Tags: 5.7.2~dfsg-8.1ubuntu3
* SECURITY UPDATE: denial of service via AgentX subagent timeout
  - debian/patches/CVE-2012-6151.patch: track cancelled sessions in
    agent/mibgroup/agentx/{master.c,master_admin.c}, agent/snmp_agent.c,
    include/net-snmp/agent/snmp_agent.h.
  - CVE-2012-6151
* SECURITY UPDATE: denial of service when ICMP-MIB is in use
  - debian/patches/CVE-2014-2284.patch: fix ICMP mib table handling in
    agent/mibgroup/mibII/icmp.c, agent/mibgroup/mibII/kernel_linux.*.
  - CVE-2014-2284
* SECURITY UPDATE: denial of service in perl trap handler
  - debian/patches/CVE-2014-2285.patch: handle empty community string in
    perl/TrapReceiver/TrapReceiver.xs.
  - CVE-2014-2285

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  AgentX Administrative request handling
 
3
 */
 
4
#include <net-snmp/net-snmp-config.h>
 
5
#include <net-snmp/net-snmp-features.h>
 
6
 
 
7
#include <sys/types.h>
 
8
#ifdef HAVE_STRING_H
 
9
#include <string.h>
 
10
#else
 
11
#include <strings.h>
 
12
#endif
 
13
#ifdef HAVE_STDLIB_H
 
14
#include <stdlib.h>
 
15
#endif
 
16
#if TIME_WITH_SYS_TIME
 
17
# include <sys/time.h>
 
18
# include <time.h>
 
19
#else
 
20
# if HAVE_SYS_TIME_H
 
21
#  include <sys/time.h>
 
22
# else
 
23
#  include <time.h>
 
24
# endif
 
25
#endif
 
26
#if HAVE_NETINET_IN_H
 
27
#include <netinet/in.h>
 
28
#endif
 
29
#if HAVE_SYS_SOCKET_H
 
30
#include <sys/socket.h>
 
31
#endif
 
32
 
 
33
#include <net-snmp/net-snmp-includes.h>
 
34
#include <net-snmp/agent/net-snmp-agent-includes.h>
 
35
 
 
36
#include "agentx/protocol.h"
 
37
#include "agentx/client.h"
 
38
 
 
39
#include <net-snmp/agent/agent_index.h>
 
40
#include <net-snmp/agent/agent_trap.h>
 
41
#include <net-snmp/agent/agent_callbacks.h>
 
42
#include <net-snmp/agent/agent_sysORTable.h>
 
43
#include "master.h"
 
44
 
 
45
netsnmp_feature_require(unregister_mib_table_row)
 
46
netsnmp_feature_require(trap_vars_with_context)
 
47
netsnmp_feature_require(calculate_sectime_diff)
 
48
netsnmp_feature_require(allocate_globalcacheid)
 
49
netsnmp_feature_require(remove_index)
 
50
 
 
51
netsnmp_session *
 
52
find_agentx_session(netsnmp_session * session, int sessid)
 
53
{
 
54
    netsnmp_session *sp;
 
55
    for (sp = session->subsession; sp != NULL; sp = sp->next) {
 
56
        if (sp->sessid == sessid)
 
57
            return sp;
 
58
    }
 
59
    return NULL;
 
60
}
 
61
 
 
62
 
 
63
int
 
64
open_agentx_session(netsnmp_session * session, netsnmp_pdu *pdu)
 
65
{
 
66
    netsnmp_session *sp;
 
67
 
 
68
    DEBUGMSGTL(("agentx/master", "open %8p\n", session));
 
69
    sp = (netsnmp_session *) malloc(sizeof(netsnmp_session));
 
70
    if (sp == NULL) {
 
71
        session->s_snmp_errno = AGENTX_ERR_OPEN_FAILED;
 
72
        return -1;
 
73
    }
 
74
 
 
75
    memcpy(sp, session, sizeof(netsnmp_session));
 
76
    sp->sessid = snmp_get_next_sessid();
 
77
    sp->version = pdu->version;
 
78
    sp->timeout = pdu->time;
 
79
 
 
80
    /*
 
81
     * Be careful with fields: if these aren't zeroed, they will get free()d
 
82
     * more than once when the session is closed -- once in the main session,
 
83
     * and once in each subsession.  Basically, if it's not being used for
 
84
     * some AgentX-specific purpose, it ought to be zeroed here. 
 
85
     */
 
86
 
 
87
    sp->community = NULL;
 
88
    sp->peername = NULL;
 
89
    sp->contextEngineID = NULL;
 
90
    sp->contextName = NULL;
 
91
    sp->securityEngineID = NULL;
 
92
    sp->securityPrivProto = NULL;
 
93
 
 
94
    /*
 
95
     * This next bit utilises unused SNMPv3 fields
 
96
     *   to store the subagent OID and description.
 
97
     * This really ought to use AgentX-specific fields,
 
98
     *   but it hardly seems worth it for a one-off use.
 
99
     *
 
100
     * But I'm willing to be persuaded otherwise....  */
 
101
    sp->securityAuthProto = snmp_duplicate_objid(pdu->variables->name,
 
102
                                                 pdu->variables->
 
103
                                                 name_length);
 
104
    sp->securityAuthProtoLen = pdu->variables->name_length;
 
105
    sp->securityName = strdup((char *) pdu->variables->val.string);
 
106
    sp->engineTime = (uint32_t)((netsnmp_get_agent_runtime() + 50) / 100) & 0x7fffffffL;
 
107
 
 
108
    sp->subsession = session;   /* link back to head */
 
109
    sp->flags |= SNMP_FLAGS_SUBSESSION;
 
110
    sp->flags &= ~AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER;
 
111
    sp->flags |= (pdu->flags & AGENTX_MSG_FLAG_NETWORK_BYTE_ORDER);
 
112
    sp->next = session->subsession;
 
113
    session->subsession = sp;
 
114
    DEBUGMSGTL(("agentx/master", "opened %8p = %ld with flags = %02lx\n",
 
115
                sp, sp->sessid, sp->flags & AGENTX_MSG_FLAGS_MASK));
 
116
 
 
117
    return sp->sessid;
 
118
}
 
119
 
 
120
int
 
121
close_agentx_session(netsnmp_session * session, int sessid)
 
122
{
 
123
    netsnmp_session *sp, **prevNext;
 
124
 
 
125
    if (!session)
 
126
        return AGENTX_ERR_NOT_OPEN;
 
127
 
 
128
    DEBUGMSGTL(("agentx/master", "close %8p, %d\n", session, sessid));
 
129
    if (sessid == -1) {
 
130
        /*
 
131
         * The following is necessary to avoid locking up the agent when
 
132
         * a sugagent dies during a set request. We must clean up the
 
133
         * requests, so that the delegated request will be completed and
 
134
         * further requests can be processed
 
135
         */
 
136
        netsnmp_remove_delegated_requests_for_session(session);
 
137
        if (session->subsession != NULL) {
 
138
            netsnmp_session *subsession = session->subsession;
 
139
            for(; subsession; subsession = subsession->next) {
 
140
                netsnmp_remove_delegated_requests_for_session(subsession);
 
141
            }
 
142
        }
 
143
                
 
144
        unregister_mibs_by_session(session);
 
145
        unregister_index_by_session(session);
 
146
        unregister_sysORTable_by_session(session);
 
147
        SNMP_FREE(session->myvoid);
 
148
        return AGENTX_ERR_NOERROR;
 
149
    }
 
150
 
 
151
    prevNext = &(session->subsession);
 
152
 
 
153
    for (sp = session->subsession; sp != NULL; sp = sp->next) {
 
154
 
 
155
        if (sp->sessid == sessid) {
 
156
            unregister_mibs_by_session(sp);
 
157
            unregister_index_by_session(sp);
 
158
            unregister_sysORTable_by_session(sp);
 
159
 
 
160
            *prevNext = sp->next;
 
161
 
 
162
            if (sp->securityAuthProto != NULL) {
 
163
                free(sp->securityAuthProto);
 
164
            }
 
165
            if (sp->securityName != NULL) {
 
166
                free(sp->securityName);
 
167
            }
 
168
            free(sp);
 
169
            sp = NULL;
 
170
 
 
171
            DEBUGMSGTL(("agentx/master", "closed %8p, %d okay\n",
 
172
                        session, sessid));
 
173
            return AGENTX_ERR_NOERROR;
 
174
        }
 
175
 
 
176
        prevNext = &(sp->next);
 
177
    }
 
178
 
 
179
    DEBUGMSGTL(("agentx/master", "sessid %d not found\n", sessid));
 
180
    return AGENTX_ERR_NOT_OPEN;
 
181
}
 
182
 
 
183
int
 
184
register_agentx_list(netsnmp_session * session, netsnmp_pdu *pdu)
 
185
{
 
186
    netsnmp_session *sp;
 
187
    char            buf[128];
 
188
    oid             ubound = 0;
 
189
    u_long          flags = 0;
 
190
    netsnmp_handler_registration *reg;
 
191
    int             rc = 0;
 
192
    int             cacheid;
 
193
 
 
194
    DEBUGMSGTL(("agentx/master", "in register_agentx_list\n"));
 
195
 
 
196
    sp = find_agentx_session(session, pdu->sessid);
 
197
    if (sp == NULL)
 
198
        return AGENTX_ERR_NOT_OPEN;
 
199
 
 
200
    sprintf(buf, "AgentX subagent %ld, session %8p, subsession %8p",
 
201
            sp->sessid, session, sp);
 
202
    /*
 
203
     * * TODO: registration timeout
 
204
     * *   registration context
 
205
     */
 
206
    if (pdu->range_subid) {
 
207
        ubound = pdu->variables->val.objid[pdu->range_subid - 1];
 
208
    }
 
209
 
 
210
    if (pdu->flags & AGENTX_MSG_FLAG_INSTANCE_REGISTER) {
 
211
        flags = FULLY_QUALIFIED_INSTANCE;
 
212
    }
 
213
 
 
214
    reg = netsnmp_create_handler_registration(buf, agentx_master_handler, pdu->variables->name, pdu->variables->name_length, HANDLER_CAN_RWRITE | HANDLER_CAN_GETBULK); /* fake it */
 
215
    if (!session->myvoid) {
 
216
        session->myvoid = malloc(sizeof(cacheid));
 
217
        cacheid = netsnmp_allocate_globalcacheid();
 
218
        *((int *) session->myvoid) = cacheid;
 
219
    } else {
 
220
        cacheid = *((int *) session->myvoid);
 
221
    }
 
222
 
 
223
    reg->handler->myvoid = session;
 
224
    reg->global_cacheid = cacheid;
 
225
    if (NULL != pdu->community)
 
226
        reg->contextName = strdup((char *)pdu->community);
 
227
 
 
228
    /*
 
229
     * register mib. Note that for failure cases, the registration info
 
230
     * (reg) will be freed, and thus is no longer a valid pointer.
 
231
     */
 
232
    switch (netsnmp_register_mib(buf, NULL, 0, 1,
 
233
                                 pdu->variables->name,
 
234
                                 pdu->variables->name_length,
 
235
                                 pdu->priority, pdu->range_subid, ubound,
 
236
                                 sp, (char *) pdu->community, pdu->time,
 
237
                                 flags, reg, 1)) {
 
238
 
 
239
    case MIB_REGISTERED_OK:
 
240
        DEBUGMSGTL(("agentx/master", "registered ok\n"));
 
241
        return AGENTX_ERR_NOERROR;
 
242
 
 
243
    case MIB_DUPLICATE_REGISTRATION:
 
244
        DEBUGMSGTL(("agentx/master", "duplicate registration\n"));
 
245
        rc = AGENTX_ERR_DUPLICATE_REGISTRATION;
 
246
        break;
 
247
 
 
248
    case MIB_REGISTRATION_FAILED:
 
249
    default:
 
250
        rc = AGENTX_ERR_REQUEST_DENIED;
 
251
        DEBUGMSGTL(("agentx/master", "failed registration\n"));
 
252
    }
 
253
    return rc;
 
254
}
 
255
 
 
256
int
 
257
unregister_agentx_list(netsnmp_session * session, netsnmp_pdu *pdu)
 
258
{
 
259
    netsnmp_session *sp;
 
260
    int             rc = 0;
 
261
 
 
262
    sp = find_agentx_session(session, pdu->sessid);
 
263
    if (sp == NULL) {
 
264
        return AGENTX_ERR_NOT_OPEN;
 
265
    }
 
266
 
 
267
    if (pdu->range_subid != 0) {
 
268
        oid             ubound =
 
269
            pdu->variables->val.objid[pdu->range_subid - 1];
 
270
        rc = netsnmp_unregister_mib_table_row(pdu->variables->name,
 
271
                                              pdu->variables->name_length,
 
272
                                              pdu->priority,
 
273
                                              pdu->range_subid, ubound,
 
274
                                              (char *) pdu->community);
 
275
    } else {
 
276
        rc = unregister_mib_context(pdu->variables->name,
 
277
                                    pdu->variables->name_length,
 
278
                                    pdu->priority, 0, 0,
 
279
                                    (char *) pdu->community);
 
280
    }
 
281
 
 
282
    switch (rc) {
 
283
    case MIB_UNREGISTERED_OK:
 
284
        return AGENTX_ERR_NOERROR;
 
285
    case MIB_NO_SUCH_REGISTRATION:
 
286
        return AGENTX_ERR_UNKNOWN_REGISTRATION;
 
287
    case MIB_UNREGISTRATION_FAILED:
 
288
    default:
 
289
        return AGENTX_ERR_REQUEST_DENIED;
 
290
    }
 
291
}
 
292
 
 
293
int
 
294
allocate_idx_list(netsnmp_session * session, netsnmp_pdu *pdu)
 
295
{
 
296
    netsnmp_session *sp;
 
297
    netsnmp_variable_list *vp, *vp2, *next, *res;
 
298
    int             flags = 0;
 
299
 
 
300
    sp = find_agentx_session(session, pdu->sessid);
 
301
    if (sp == NULL)
 
302
        return AGENTX_ERR_NOT_OPEN;
 
303
 
 
304
    if (pdu->flags & AGENTX_MSG_FLAG_ANY_INSTANCE)
 
305
        flags |= ALLOCATE_ANY_INDEX;
 
306
    if (pdu->flags & AGENTX_MSG_FLAG_NEW_INSTANCE)
 
307
        flags |= ALLOCATE_NEW_INDEX;
 
308
 
 
309
    /*
 
310
     * XXX - what about errors?
 
311
     *
 
312
     *  If any allocations fail, then we need to
 
313
     *    *fully* release the earlier ones.
 
314
     *  (i.e. remove them completely from the index registry,
 
315
     *    not simply mark them as available for re-use)
 
316
     *
 
317
     * For now - assume they all succeed.
 
318
     */
 
319
    for (vp = pdu->variables; vp != NULL; vp = next) {
 
320
        next = vp->next_variable;
 
321
        res = register_index(vp, flags, session);
 
322
        if (res == NULL) {
 
323
            /*
 
324
             *  If any allocations fail, we need to *fully* release
 
325
             *      all previous ones (i.e. remove them completely
 
326
             *      from the index registry)
 
327
             */
 
328
            for (vp2 = pdu->variables; vp2 != vp; vp2 = vp2->next_variable) {
 
329
                remove_index(vp2, session);
 
330
            }
 
331
            return AGENTX_ERR_INDEX_NONE_AVAILABLE;     /* XXX */
 
332
        } else {
 
333
            (void) snmp_clone_var(res, vp);
 
334
            free(res);
 
335
        }
 
336
        vp->next_variable = next;
 
337
    }
 
338
    return AGENTX_ERR_NOERROR;
 
339
}
 
340
 
 
341
int
 
342
release_idx_list(netsnmp_session * session, netsnmp_pdu *pdu)
 
343
{
 
344
    netsnmp_session *sp;
 
345
    netsnmp_variable_list *vp, *vp2, *rv = NULL;
 
346
    int             res;
 
347
 
 
348
    sp = find_agentx_session(session, pdu->sessid);
 
349
    if (sp == NULL)
 
350
        return AGENTX_ERR_NOT_OPEN;
 
351
 
 
352
    for (vp = pdu->variables; vp != NULL; vp = vp->next_variable) {
 
353
        res = unregister_index(vp, TRUE, session);
 
354
        /*
 
355
         *  If any releases fail,
 
356
         *      we need to reinstate all previous ones.
 
357
         */
 
358
        if (res != SNMP_ERR_NOERROR) {
 
359
            for (vp2 = pdu->variables; vp2 != vp; vp2 = vp2->next_variable) {
 
360
                rv = register_index(vp2, ALLOCATE_THIS_INDEX, session);
 
361
                free(rv);
 
362
            }
 
363
            return AGENTX_ERR_INDEX_NOT_ALLOCATED;      /* Probably */
 
364
        }
 
365
    }
 
366
    return AGENTX_ERR_NOERROR;
 
367
}
 
368
 
 
369
int
 
370
add_agent_caps_list(netsnmp_session * session, netsnmp_pdu *pdu)
 
371
{
 
372
    netsnmp_session *sp;
 
373
    char* description;
 
374
 
 
375
    sp = find_agentx_session(session, pdu->sessid);
 
376
    if (sp == NULL)
 
377
        return AGENTX_ERR_NOT_OPEN;
 
378
 
 
379
    description = netsnmp_strdup_and_null(pdu->variables->val.string,
 
380
                                          pdu->variables->val_len);
 
381
    register_sysORTable_sess(pdu->variables->name, pdu->variables->name_length,
 
382
                             description, sp);
 
383
    free(description);
 
384
    return AGENTX_ERR_NOERROR;
 
385
}
 
386
 
 
387
int
 
388
remove_agent_caps_list(netsnmp_session * session, netsnmp_pdu *pdu)
 
389
{
 
390
    netsnmp_session *sp;
 
391
    int rc;
 
392
 
 
393
    sp = find_agentx_session(session, pdu->sessid);
 
394
    if (sp == NULL)
 
395
        return AGENTX_ERR_NOT_OPEN;
 
396
 
 
397
    rc = unregister_sysORTable_sess(pdu->variables->name,
 
398
                                    pdu->variables->name_length, sp);
 
399
 
 
400
    if (rc < 0)
 
401
      return AGENTX_ERR_UNKNOWN_AGENTCAPS;
 
402
 
 
403
    return AGENTX_ERR_NOERROR;
 
404
}
 
405
 
 
406
int
 
407
agentx_notify(netsnmp_session * session, netsnmp_pdu *pdu)
 
408
{
 
409
    netsnmp_session       *sp;
 
410
    netsnmp_variable_list *var;
 
411
    extern const oid       sysuptime_oid[], snmptrap_oid[];
 
412
    extern const size_t    sysuptime_oid_len, snmptrap_oid_len;
 
413
 
 
414
    sp = find_agentx_session(session, pdu->sessid);
 
415
    if (sp == NULL)
 
416
        return AGENTX_ERR_NOT_OPEN;
 
417
 
 
418
    var = pdu->variables;
 
419
    if (!var)
 
420
        return AGENTX_ERR_PROCESSING_ERROR;
 
421
 
 
422
    if (snmp_oid_compare(var->name, var->name_length,
 
423
                         sysuptime_oid, sysuptime_oid_len) == 0) {
 
424
        var = var->next_variable;
 
425
    }
 
426
 
 
427
    if (!var || snmp_oid_compare(var->name, var->name_length,
 
428
                                 snmptrap_oid, snmptrap_oid_len) != 0)
 
429
        return AGENTX_ERR_PROCESSING_ERROR;
 
430
 
 
431
    /*
 
432
     *  If sysUptime isn't the first varbind, don't worry.  
 
433
     *     send_trap_vars() will add it if necessary.
 
434
     *
 
435
     *  Note that if this behaviour is altered, it will
 
436
     *     be necessary to add sysUptime here,
 
437
     *     as this is valid AgentX syntax.
 
438
     */
 
439
 
 
440
        /* If a context name was specified, send the trap using that context.
 
441
         * Otherwise, send the trap without the context using the old method */
 
442
        if (pdu->contextName != NULL)
 
443
        {
 
444
        send_trap_vars_with_context(-1, -1, pdu->variables, 
 
445
                       pdu->contextName);
 
446
        }
 
447
        else
 
448
        {
 
449
        send_trap_vars(-1, -1, pdu->variables);
 
450
        }
 
451
 
 
452
    return AGENTX_ERR_NOERROR;
 
453
}
 
454
 
 
455
 
 
456
int
 
457
agentx_ping_response(netsnmp_session * session, netsnmp_pdu *pdu)
 
458
{
 
459
    netsnmp_session *sp;
 
460
 
 
461
    sp = find_agentx_session(session, pdu->sessid);
 
462
    if (sp == NULL)
 
463
        return AGENTX_ERR_NOT_OPEN;
 
464
    else
 
465
        return AGENTX_ERR_NOERROR;
 
466
}
 
467
 
 
468
int
 
469
handle_master_agentx_packet(int operation,
 
470
                            netsnmp_session * session,
 
471
                            int reqid, netsnmp_pdu *pdu, void *magic)
 
472
{
 
473
    netsnmp_agent_session *asp;
 
474
 
 
475
    if (operation == NETSNMP_CALLBACK_OP_DISCONNECT) {
 
476
        DEBUGMSGTL(("agentx/master",
 
477
                    "transport disconnect on session %8p\n", session));
 
478
        /*
 
479
         * Shut this session down gracefully.  
 
480
         */
 
481
        close_agentx_session(session, -1);
 
482
        return 1;
 
483
    } else if (operation == NETSNMP_CALLBACK_OP_CONNECT) {
 
484
        DEBUGMSGTL(("agentx/master",
 
485
                    "transport connect on session %8p\n", session));
 
486
        return 1;
 
487
    } else if (operation != NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
 
488
        DEBUGMSGTL(("agentx/master", "unexpected callback op %d\n",
 
489
                    operation));
 
490
        return 1;
 
491
    }
 
492
 
 
493
    /*
 
494
     * Okay, it's a NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE op.  
 
495
     */
 
496
 
 
497
    if (magic) {
 
498
        asp = (netsnmp_agent_session *) magic;
 
499
    } else {
 
500
        asp = init_agent_snmp_session(session, pdu);
 
501
    }
 
502
 
 
503
    DEBUGMSGTL(("agentx/master", "handle pdu (req=0x%lx,trans=0x%lx,sess=0x%lx)\n",
 
504
                (unsigned long)pdu->reqid, (unsigned long)pdu->transid,
 
505
                (unsigned long)pdu->sessid));
 
506
    
 
507
    switch (pdu->command) {
 
508
    case AGENTX_MSG_OPEN:
 
509
        asp->pdu->sessid = open_agentx_session(session, pdu);
 
510
        if (asp->pdu->sessid == -1)
 
511
            asp->status = session->s_snmp_errno;
 
512
        break;
 
513
 
 
514
    case AGENTX_MSG_CLOSE:
 
515
        asp->status = close_agentx_session(session, pdu->sessid);
 
516
        break;
 
517
 
 
518
    case AGENTX_MSG_REGISTER:
 
519
        asp->status = register_agentx_list(session, pdu);
 
520
        break;
 
521
 
 
522
    case AGENTX_MSG_UNREGISTER:
 
523
        asp->status = unregister_agentx_list(session, pdu);
 
524
        break;
 
525
 
 
526
    case AGENTX_MSG_INDEX_ALLOCATE:
 
527
        asp->status = allocate_idx_list(session, asp->pdu);
 
528
        if (asp->status != AGENTX_ERR_NOERROR) {
 
529
            snmp_free_pdu(asp->pdu);
 
530
            asp->pdu = snmp_clone_pdu(pdu);
 
531
        }
 
532
        break;
 
533
 
 
534
    case AGENTX_MSG_INDEX_DEALLOCATE:
 
535
        asp->status = release_idx_list(session, pdu);
 
536
        break;
 
537
 
 
538
    case AGENTX_MSG_ADD_AGENT_CAPS:
 
539
        asp->status = add_agent_caps_list(session, pdu);
 
540
        break;
 
541
 
 
542
    case AGENTX_MSG_REMOVE_AGENT_CAPS:
 
543
        asp->status = remove_agent_caps_list(session, pdu);
 
544
        break;
 
545
 
 
546
    case AGENTX_MSG_NOTIFY:
 
547
        asp->status = agentx_notify(session, pdu);
 
548
        break;
 
549
 
 
550
    case AGENTX_MSG_PING:
 
551
        asp->status = agentx_ping_response(session, pdu);
 
552
        break;
 
553
 
 
554
        /*
 
555
         * TODO: Other admin packets 
 
556
         */
 
557
 
 
558
    case AGENTX_MSG_GET:
 
559
    case AGENTX_MSG_GETNEXT:
 
560
    case AGENTX_MSG_GETBULK:
 
561
    case AGENTX_MSG_TESTSET:
 
562
    case AGENTX_MSG_COMMITSET:
 
563
    case AGENTX_MSG_UNDOSET:
 
564
    case AGENTX_MSG_CLEANUPSET:
 
565
    case AGENTX_MSG_RESPONSE:
 
566
        /*
 
567
         * Shouldn't be handled here 
 
568
         */
 
569
        break;
 
570
 
 
571
    default:
 
572
        asp->status = AGENTX_ERR_PARSE_FAILED;
 
573
        break;
 
574
    }
 
575
 
 
576
    asp->pdu->time = netsnmp_get_agent_uptime();
 
577
    asp->pdu->command = AGENTX_MSG_RESPONSE;
 
578
    asp->pdu->errstat = asp->status;
 
579
    DEBUGMSGTL(("agentx/master", "send response, stat %d (req=0x%lx,trans="
 
580
                "0x%lx,sess=0x%lx)\n",
 
581
                asp->status, (unsigned long)pdu->reqid,
 
582
                (unsigned long)pdu->transid, (unsigned long)pdu->sessid));
 
583
    if (!snmp_send(asp->session, asp->pdu)) {
 
584
        char           *eb = NULL;
 
585
        int             pe, pse;
 
586
        snmp_error(asp->session, &pe, &pse, &eb);
 
587
        snmp_free_pdu(asp->pdu);
 
588
        DEBUGMSGTL(("agentx/master", "FAILED %d %d %s\n", pe, pse, eb));
 
589
        free(eb);
 
590
    }
 
591
    asp->pdu = NULL;
 
592
    free_agent_snmp_session(asp);
 
593
 
 
594
    return 1;
 
595
}