~ubuntu-branches/ubuntu/trusty/net-snmp/trusty

« back to all changes in this revision

Viewing changes to agent/mibgroup/notification/snmpNotifyTable.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-09-13 12:06:21 UTC
  • Revision ID: james.westby@ubuntu.com-20040913120621-g952ntonlleihcvm
Tags: upstream-5.1.1
ImportĀ upstreamĀ versionĀ 5.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file was generated by mib2c and is intended for use as
 
3
 * a mib module for the ucd-snmp snmpd agent. 
 
4
 */
 
5
 
 
6
 
 
7
/*
 
8
 * This should always be included first before anything else 
 
9
 */
 
10
#include <net-snmp/net-snmp-config.h>
 
11
 
 
12
#include <sys/types.h>
 
13
#if HAVE_WINSOCK_H
 
14
#include <winsock.h>
 
15
#endif
 
16
#if HAVE_STDLIB_H
 
17
#include <stdlib.h>
 
18
#endif
 
19
#if HAVE_STRING_H
 
20
#include <string.h>
 
21
#else
 
22
#include <strings.h>
 
23
#endif
 
24
 
 
25
/*
 
26
 * minimal include directives 
 
27
 */
 
28
#include <net-snmp/net-snmp-includes.h>
 
29
#include <net-snmp/agent/net-snmp-agent-includes.h>
 
30
 
 
31
#include "header_complex.h"
 
32
#include "snmpNotifyTable.h"
 
33
#include "target/snmpTargetParamsEntry.h"
 
34
#include "target/snmpTargetAddrEntry.h"
 
35
#include "target/target.h"
 
36
#include <net-snmp/agent/agent_callbacks.h>
 
37
#include <net-snmp/agent/agent_trap.h>
 
38
 
 
39
SNMPCallback    store_snmpNotifyTable;
 
40
 
 
41
/*
 
42
 * snmpNotifyTable_variables_oid:
 
43
 *   this is the top level oid that we want to register under.  This
 
44
 *   is essentially a prefix, with the suffix appearing in the
 
45
 *   variable below.
 
46
 */
 
47
 
 
48
 
 
49
oid             snmpNotifyTable_variables_oid[] =
 
50
    { 1, 3, 6, 1, 6, 3, 13, 1, 1 };
 
51
 
 
52
 
 
53
/*
 
54
 * variable2 snmpNotifyTable_variables:
 
55
 *   this variable defines function callbacks and type return information 
 
56
 *   for the snmpNotifyTable mib section 
 
57
 */
 
58
 
 
59
 
 
60
struct variable2 snmpNotifyTable_variables[] = {
 
61
    /*
 
62
     * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
 
63
     */
 
64
#define   SNMPNOTIFYTAG         4
 
65
    {SNMPNOTIFYTAG, ASN_OCTET_STR, RWRITE, var_snmpNotifyTable, 2, {1, 2}},
 
66
#define   SNMPNOTIFYTYPE        5
 
67
    {SNMPNOTIFYTYPE, ASN_INTEGER, RWRITE, var_snmpNotifyTable, 2, {1, 3}},
 
68
#define   SNMPNOTIFYSTORAGETYPE  6
 
69
    {SNMPNOTIFYSTORAGETYPE, ASN_INTEGER, RWRITE, var_snmpNotifyTable, 2,
 
70
     {1, 4}},
 
71
#define   SNMPNOTIFYROWSTATUS   7
 
72
    {SNMPNOTIFYROWSTATUS, ASN_INTEGER, RWRITE, var_snmpNotifyTable, 2,
 
73
     {1, 5}},
 
74
 
 
75
};
 
76
/*
 
77
 * (L = length of the oidsuffix) 
 
78
 */
 
79
 
 
80
 
 
81
/*
 
82
 * global storage of our data, saved in and configured by header_complex() 
 
83
 */
 
84
static struct header_complex_index *snmpNotifyTableStorage = NULL;
 
85
 
 
86
int
 
87
send_notifications(int major, int minor, void *serverarg, void *clientarg)
 
88
{
 
89
    struct header_complex_index *hptr;
 
90
    struct snmpNotifyTable_data *nptr;
 
91
    netsnmp_session *sess, *sptr;
 
92
    netsnmp_pdu    *template_pdu = (netsnmp_pdu *) serverarg;
 
93
 
 
94
    DEBUGMSGTL(("send_notifications", "starting: pdu=%x, vars=%x\n",
 
95
                template_pdu, template_pdu->variables));
 
96
 
 
97
    for (hptr = snmpNotifyTableStorage; hptr; hptr = hptr->next) {
 
98
        nptr = (struct snmpNotifyTable_data *) hptr->data;
 
99
        if (nptr->snmpNotifyRowStatus != RS_ACTIVE)
 
100
            continue;
 
101
        if (!nptr->snmpNotifyTag)
 
102
            continue;
 
103
 
 
104
        sess = get_target_sessions(nptr->snmpNotifyTag, NULL, NULL);
 
105
 
 
106
        /*
 
107
         * XXX: filter appropriately 
 
108
         */
 
109
 
 
110
        for (sptr = sess; sptr; sptr = sptr->next) {
 
111
            if (sptr->version == SNMP_VERSION_1 &&
 
112
                minor == SNMPD_CALLBACK_SEND_TRAP1) {
 
113
                send_trap_to_sess(sptr, template_pdu);
 
114
            } else if (sptr->version != SNMP_VERSION_1 &&
 
115
                       minor == SNMPD_CALLBACK_SEND_TRAP2) {
 
116
                if (nptr->snmpNotifyType == SNMPNOTIFYTYPE_INFORM) {
 
117
                    template_pdu->command = SNMP_MSG_INFORM;
 
118
                } else {
 
119
                    template_pdu->command = SNMP_MSG_TRAP2;
 
120
                }
 
121
                send_trap_to_sess(sptr, template_pdu);
 
122
            }
 
123
        }
 
124
    }
 
125
    return 0;
 
126
}
 
127
 
 
128
#define MAX_ENTRIES 1024
 
129
 
 
130
int
 
131
notifyTable_register_notifications(int major, int minor,
 
132
                                   void *serverarg, void *clientarg)
 
133
{
 
134
    struct targetAddrTable_struct *ptr;
 
135
    struct targetParamTable_struct *pptr;
 
136
    struct snmpNotifyTable_data *nptr;
 
137
    int             confirm, i;
 
138
    char            buf[SNMP_MAXBUF_SMALL];
 
139
    netsnmp_transport *t = NULL;
 
140
    struct agent_add_trap_args *args =
 
141
        (struct agent_add_trap_args *) serverarg;
 
142
    netsnmp_session *ss;
 
143
 
 
144
    if (!args || !(args->ss)) {
 
145
        return (0);
 
146
    }
 
147
    confirm = args->confirm;
 
148
    ss = args->ss;
 
149
 
 
150
    /*
 
151
     * XXX: START move target creation to target code 
 
152
     */
 
153
    for (i = 0; i < MAX_ENTRIES; i++) {
 
154
        sprintf(buf, "internal%d", i);
 
155
        if (get_addrForName(buf) == NULL && get_paramEntry(buf) == NULL)
 
156
            break;
 
157
    }
 
158
    if (i == MAX_ENTRIES) {
 
159
        snmp_log(LOG_ERR,
 
160
                 "Can't register new trap destination: max limit reached: %d",
 
161
                 MAX_ENTRIES);
 
162
        snmp_sess_close(ss);
 
163
        return (0);
 
164
    }
 
165
 
 
166
    /*
 
167
     * address 
 
168
     */
 
169
    ptr = snmpTargetAddrTable_create();
 
170
    ptr->name = strdup(buf);
 
171
    t = snmp_sess_transport(snmp_sess_pointer(ss));
 
172
    memcpy(ptr->tDomain, t->domain, t->domain_length * sizeof(oid));
 
173
    ptr->tDomainLen = t->domain_length;
 
174
    ptr->tAddressLen = t->remote_length;
 
175
    ptr->tAddress = t->remote;
 
176
 
 
177
    ptr->timeout = ss->timeout / 1000;
 
178
    ptr->retryCount = ss->retries;
 
179
    SNMP_FREE(ptr->tagList);
 
180
    ptr->tagList = strdup(ptr->name);
 
181
    ptr->params = strdup(ptr->name);
 
182
    ptr->storageType = ST_READONLY;
 
183
    ptr->rowStatus = RS_ACTIVE;
 
184
    ptr->sess = ss;
 
185
    DEBUGMSGTL(("trapsess", "adding to trap table\n"));
 
186
    snmpTargetAddrTable_add(ptr);
 
187
 
 
188
    /*
 
189
     * param 
 
190
     */
 
191
    pptr = snmpTargetParamTable_create();
 
192
    pptr->paramName = strdup(buf);
 
193
    pptr->mpModel = ss->version;
 
194
    if (ss->version == SNMP_VERSION_3) {
 
195
        pptr->secModel = ss->securityModel;
 
196
        pptr->secLevel = ss->securityLevel;
 
197
        pptr->secName = (char *) malloc(ss->securityNameLen + 1);
 
198
        memcpy((void *) pptr->secName, (void *) ss->securityName,
 
199
               ss->securityNameLen);
 
200
        pptr->secName[ss->securityNameLen] = 0;
 
201
    } else {
 
202
        pptr->secModel = ss->version == SNMP_VERSION_1 ?
 
203
            SNMP_SEC_MODEL_SNMPv1 : SNMP_SEC_MODEL_SNMPv2c;
 
204
        pptr->secLevel = SNMP_SEC_LEVEL_NOAUTH;
 
205
        pptr->secName = NULL;
 
206
        if (ss->community && (ss->community_len > 0)) {
 
207
            pptr->secName = (char *) malloc(ss->community_len + 1);
 
208
            memcpy((void *) pptr->secName, (void *) ss->community,
 
209
                   ss->community_len);
 
210
            pptr->secName[ss->community_len] = 0;
 
211
        }
 
212
    }
 
213
    pptr->storageType = ST_READONLY;
 
214
    pptr->rowStatus = RS_ACTIVE;
 
215
    snmpTargetParamTable_add(pptr);
 
216
    /*
 
217
     * XXX: END move target creation to target code 
 
218
     */
 
219
 
 
220
    /*
 
221
     * notify table 
 
222
     */
 
223
    nptr = SNMP_MALLOC_STRUCT(snmpNotifyTable_data);
 
224
    nptr->snmpNotifyName = strdup(buf);
 
225
    nptr->snmpNotifyNameLen = strlen(buf);
 
226
    nptr->snmpNotifyTag = strdup(buf);
 
227
    nptr->snmpNotifyTagLen = strlen(buf);
 
228
    nptr->snmpNotifyType = confirm ?
 
229
        SNMPNOTIFYTYPE_INFORM : SNMPNOTIFYTYPE_TRAP;
 
230
    nptr->snmpNotifyStorageType = ST_READONLY;
 
231
    nptr->snmpNotifyRowStatus = RS_ACTIVE;
 
232
 
 
233
    snmpNotifyTable_add(nptr);
 
234
    return 0;
 
235
}
 
236
 
 
237
 
 
238
/*
 
239
 * XXX: this really needs to be done for the target mib entries too.
 
240
 * But we can only trust that we've added stuff here and we don't want
 
241
 * to destroy other valid entries in the target tables, so...  Don't
 
242
 * do too many kill -HUPs to your agent as re reading the config file
 
243
 * will be a slow memory leak in the target mib. 
 
244
 */
 
245
int
 
246
notifyTable_unregister_notifications(int major, int minor,
 
247
                                     void *serverarg, void *clientarg)
 
248
{
 
249
    struct header_complex_index *hptr, *nhptr;
 
250
    struct snmpNotifyTable_data *nptr;
 
251
 
 
252
    for (hptr = snmpNotifyTableStorage; hptr; hptr = nhptr) {
 
253
        nptr = (struct snmpNotifyTable_data *) hptr->data;
 
254
        nhptr = hptr->next;
 
255
        if (nptr->snmpNotifyStorageType == ST_READONLY) {
 
256
            header_complex_extract_entry(&snmpNotifyTableStorage, hptr);
 
257
            SNMP_FREE(nptr->snmpNotifyName);
 
258
            SNMP_FREE(nptr->snmpNotifyTag);
 
259
            SNMP_FREE(nptr);
 
260
        }
 
261
    }
 
262
    return (0);
 
263
}
 
264
 
 
265
/*
 
266
 * init_snmpNotifyTable():
 
267
 *   Initialization routine.  This is called when the agent starts up.
 
268
 *   At a minimum, registration of your variables should take place here.
 
269
 */
 
270
void
 
271
init_snmpNotifyTable(void)
 
272
{
 
273
    DEBUGMSGTL(("snmpNotifyTable", "initializing...  "));
 
274
 
 
275
 
 
276
    /*
 
277
     * register ourselves with the agent to handle our mib tree 
 
278
     */
 
279
    REGISTER_MIB("snmpNotifyTable", snmpNotifyTable_variables, variable2,
 
280
                 snmpNotifyTable_variables_oid);
 
281
 
 
282
 
 
283
    /*
 
284
     * register our config handler(s) to deal with registrations 
 
285
     */
 
286
    snmpd_register_config_handler("snmpNotifyTable", parse_snmpNotifyTable,
 
287
                                  NULL, NULL);
 
288
 
 
289
 
 
290
    /*
 
291
     * we need to be called back later to store our data 
 
292
     */
 
293
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
 
294
                           store_snmpNotifyTable, NULL);
 
295
 
 
296
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
 
297
                           SNMPD_CALLBACK_SEND_TRAP1, send_notifications,
 
298
                           NULL);
 
299
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
 
300
                           SNMPD_CALLBACK_SEND_TRAP2, send_notifications,
 
301
                           NULL);
 
302
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
 
303
                           SNMPD_CALLBACK_REGISTER_NOTIFICATIONS,
 
304
                           notifyTable_register_notifications, NULL);
 
305
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
 
306
                           SNMPD_CALLBACK_PRE_UPDATE_CONFIG,
 
307
                           notifyTable_unregister_notifications, NULL);
 
308
 
 
309
    /*
 
310
     * place any other initialization junk you need here 
 
311
     */
 
312
 
 
313
 
 
314
    DEBUGMSGTL(("snmpNotifyTable", "done.\n"));
 
315
}
 
316
 
 
317
 
 
318
/*
 
319
 * snmpNotifyTable_add(): adds a structure node to our data set 
 
320
 */
 
321
int
 
322
snmpNotifyTable_add(struct snmpNotifyTable_data *thedata)
 
323
{
 
324
    netsnmp_variable_list *vars = NULL;
 
325
 
 
326
 
 
327
    DEBUGMSGTL(("snmpNotifyTable", "adding data...  "));
 
328
    /*
 
329
     * add the index variables to the varbind list, which is 
 
330
     * used by header_complex to index the data 
 
331
     */
 
332
 
 
333
 
 
334
    snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, (u_char *) thedata->snmpNotifyName, thedata->snmpNotifyNameLen);      /* snmpNotifyName */
 
335
 
 
336
 
 
337
 
 
338
    header_complex_add_data(&snmpNotifyTableStorage, vars, thedata);
 
339
    DEBUGMSGTL(("snmpNotifyTable", "registered an entry\n"));
 
340
 
 
341
 
 
342
    DEBUGMSGTL(("snmpNotifyTable", "done.\n"));
 
343
    return SNMPERR_SUCCESS;
 
344
}
 
345
 
 
346
 
 
347
/*
 
348
 * parse_snmpNotifyTable():
 
349
 *   parses .conf file entries needed to configure the mib.
 
350
 */
 
351
void
 
352
parse_snmpNotifyTable(const char *token, char *line)
 
353
{
 
354
    size_t          tmpint;
 
355
    struct snmpNotifyTable_data *StorageTmp =
 
356
        SNMP_MALLOC_STRUCT(snmpNotifyTable_data);
 
357
 
 
358
 
 
359
    DEBUGMSGTL(("snmpNotifyTable", "parsing config...  "));
 
360
 
 
361
 
 
362
    if (StorageTmp == NULL) {
 
363
        config_perror("malloc failure");
 
364
        return;
 
365
    }
 
366
 
 
367
    line =
 
368
        read_config_read_data(ASN_OCTET_STR, line,
 
369
                              &StorageTmp->snmpNotifyName,
 
370
                              &StorageTmp->snmpNotifyNameLen);
 
371
    if (StorageTmp->snmpNotifyName == NULL) {
 
372
        config_perror("invalid specification for snmpNotifyName");
 
373
        return;
 
374
    }
 
375
 
 
376
    line =
 
377
        read_config_read_data(ASN_OCTET_STR, line,
 
378
                              &StorageTmp->snmpNotifyTag,
 
379
                              &StorageTmp->snmpNotifyTagLen);
 
380
    if (StorageTmp->snmpNotifyTag == NULL) {
 
381
        config_perror("invalid specification for snmpNotifyTag");
 
382
        return;
 
383
    }
 
384
 
 
385
    line =
 
386
        read_config_read_data(ASN_INTEGER, line,
 
387
                              &StorageTmp->snmpNotifyType, &tmpint);
 
388
 
 
389
    line =
 
390
        read_config_read_data(ASN_INTEGER, line,
 
391
                              &StorageTmp->snmpNotifyStorageType, &tmpint);
 
392
 
 
393
    line =
 
394
        read_config_read_data(ASN_INTEGER, line,
 
395
                              &StorageTmp->snmpNotifyRowStatus, &tmpint);
 
396
 
 
397
 
 
398
 
 
399
 
 
400
    snmpNotifyTable_add(StorageTmp);
 
401
 
 
402
 
 
403
    DEBUGMSGTL(("snmpNotifyTable", "done.\n"));
 
404
}
 
405
 
 
406
 
 
407
 
 
408
 
 
409
/*
 
410
 * store_snmpNotifyTable():
 
411
 *   stores .conf file entries needed to configure the mib.
 
412
 */
 
413
int
 
414
store_snmpNotifyTable(int majorID, int minorID, void *serverarg,
 
415
                      void *clientarg)
 
416
{
 
417
    char            line[SNMP_MAXBUF];
 
418
    char           *cptr;
 
419
    size_t          tmpint;
 
420
    struct snmpNotifyTable_data *StorageTmp;
 
421
    struct header_complex_index *hcindex;
 
422
 
 
423
 
 
424
    DEBUGMSGTL(("snmpNotifyTable", "storing data...  "));
 
425
 
 
426
 
 
427
    for (hcindex = snmpNotifyTableStorage; hcindex != NULL;
 
428
         hcindex = hcindex->next) {
 
429
        StorageTmp = (struct snmpNotifyTable_data *) hcindex->data;
 
430
 
 
431
        if (StorageTmp->snmpNotifyStorageType == ST_NONVOLATILE) {
 
432
 
 
433
            memset(line, 0, sizeof(line));
 
434
            strcat(line, "snmpNotifyTable ");
 
435
            cptr = line + strlen(line);
 
436
 
 
437
            cptr =
 
438
                read_config_store_data(ASN_OCTET_STR, cptr,
 
439
                                       &StorageTmp->snmpNotifyName,
 
440
                                       &StorageTmp->snmpNotifyNameLen);
 
441
            cptr =
 
442
                read_config_store_data(ASN_OCTET_STR, cptr,
 
443
                                       &StorageTmp->snmpNotifyTag,
 
444
                                       &StorageTmp->snmpNotifyTagLen);
 
445
            cptr =
 
446
                read_config_store_data(ASN_INTEGER, cptr,
 
447
                                       &StorageTmp->snmpNotifyType,
 
448
                                       &tmpint);
 
449
            cptr =
 
450
                read_config_store_data(ASN_INTEGER, cptr,
 
451
                                       &StorageTmp->snmpNotifyStorageType,
 
452
                                       &tmpint);
 
453
            cptr =
 
454
                read_config_store_data(ASN_INTEGER, cptr,
 
455
                                       &StorageTmp->snmpNotifyRowStatus,
 
456
                                       &tmpint);
 
457
 
 
458
            snmpd_store_config(line);
 
459
        }
 
460
    }
 
461
    DEBUGMSGTL(("snmpNotifyTable", "done.\n"));
 
462
    return 0;
 
463
}
 
464
 
 
465
 
 
466
 
 
467
 
 
468
/*
 
469
 * var_snmpNotifyTable():
 
470
 *   Handle this table separately from the scalar value case.
 
471
 *   The workings of this are basically the same as for var_snmpNotifyTable above.
 
472
 */
 
473
unsigned char  *
 
474
var_snmpNotifyTable(struct variable *vp,
 
475
                    oid * name,
 
476
                    size_t * length,
 
477
                    int exact,
 
478
                    size_t * var_len, WriteMethod ** write_method)
 
479
{
 
480
    struct snmpNotifyTable_data *StorageTmp = NULL;
 
481
    int             found = 1;
 
482
 
 
483
    DEBUGMSGTL(("snmpNotifyTable",
 
484
                "var_snmpNotifyTable: Entering...  \n"));
 
485
    /*
 
486
     * this assumes you have registered all your data properly
 
487
     */
 
488
    if ((StorageTmp = (struct snmpNotifyTable_data *)
 
489
         header_complex((struct header_complex_index *)
 
490
                        snmpNotifyTableStorage, vp, name, length, exact,
 
491
                        var_len, write_method)) == NULL) {
 
492
        found = 0;
 
493
    }
 
494
 
 
495
    switch (vp->magic) {
 
496
    case SNMPNOTIFYTAG:
 
497
        *write_method = write_snmpNotifyTag;
 
498
        break;
 
499
    case SNMPNOTIFYTYPE:
 
500
        *write_method = write_snmpNotifyType;
 
501
        break;
 
502
    case SNMPNOTIFYSTORAGETYPE:
 
503
        *write_method = write_snmpNotifyStorageType;
 
504
        break;
 
505
    case SNMPNOTIFYROWSTATUS:
 
506
        *write_method = write_snmpNotifyRowStatus;
 
507
        break;
 
508
    default:
 
509
        *write_method = NULL;
 
510
    }
 
511
 
 
512
    if (!found) {
 
513
        return NULL;
 
514
    }
 
515
 
 
516
    switch (vp->magic) {
 
517
    case SNMPNOTIFYTAG:
 
518
        *var_len = StorageTmp->snmpNotifyTagLen;
 
519
        return (u_char *) StorageTmp->snmpNotifyTag;
 
520
 
 
521
    case SNMPNOTIFYTYPE:
 
522
        *var_len = sizeof(StorageTmp->snmpNotifyType);
 
523
        return (u_char *) & StorageTmp->snmpNotifyType;
 
524
 
 
525
    case SNMPNOTIFYSTORAGETYPE:
 
526
        *var_len = sizeof(StorageTmp->snmpNotifyStorageType);
 
527
        return (u_char *) & StorageTmp->snmpNotifyStorageType;
 
528
 
 
529
    case SNMPNOTIFYROWSTATUS:
 
530
        *var_len = sizeof(StorageTmp->snmpNotifyRowStatus);
 
531
        return (u_char *) & StorageTmp->snmpNotifyRowStatus;
 
532
 
 
533
    default:
 
534
        ERROR_MSG("");
 
535
    }
 
536
    return NULL;
 
537
}
 
538
 
 
539
static int
 
540
is_delim(const char c)
 
541
{
 
542
    return (c == 0x020 || c == 0x09 || c == 0x0d || c == 0x0b);
 
543
}
 
544
 
 
545
int
 
546
snmpTagValid(const char *tag, const size_t tagLen)
 
547
{
 
548
    size_t          i = 0;
 
549
 
 
550
 
 
551
    for (i = 0; i < tagLen; i++) {
 
552
        if (is_delim(tag[i])) {
 
553
            /*
 
554
             * Delimeters aren't allowed.  
 
555
             */
 
556
            return 0;
 
557
        }
 
558
    }
 
559
    return 1;
 
560
}
 
561
 
 
562
static struct snmpNotifyTable_data *StorageNew;
 
563
 
 
564
int
 
565
write_snmpNotifyTag(int action,
 
566
                    u_char * var_val,
 
567
                    u_char var_val_type,
 
568
                    size_t var_val_len,
 
569
                    u_char * statP, oid * name, size_t name_len)
 
570
{
 
571
    static char    *tmpvar;
 
572
    struct snmpNotifyTable_data *StorageTmp = NULL;
 
573
    static size_t   tmplen;
 
574
    size_t          newlen =
 
575
        name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
 
576
                    3 - 1);
 
577
 
 
578
 
 
579
    DEBUGMSGTL(("snmpNotifyTable",
 
580
                "write_snmpNotifyTag entering action=%d...  \n", action));
 
581
    if (action != RESERVE1 &&
 
582
        (StorageTmp = (struct snmpNotifyTable_data *)
 
583
         header_complex((struct header_complex_index *)
 
584
                        snmpNotifyTableStorage, NULL,
 
585
                        &name[sizeof(snmpNotifyTable_variables_oid) /
 
586
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
 
587
                        NULL)) == NULL) {
 
588
        if ((StorageTmp = StorageNew) == NULL)
 
589
            return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
 
590
    }
 
591
 
 
592
 
 
593
    switch (action) {
 
594
    case RESERVE1:
 
595
        if (var_val_type != ASN_OCTET_STR) {
 
596
            return SNMP_ERR_WRONGTYPE;
 
597
        }
 
598
        if (var_val_len < 0 || var_val_len > 255) {
 
599
            return SNMP_ERR_WRONGLENGTH;
 
600
        }
 
601
        if (!snmpTagValid(var_val, var_val_len)) {
 
602
            return SNMP_ERR_WRONGVALUE;
 
603
        }
 
604
        break;
 
605
 
 
606
 
 
607
    case RESERVE2:
 
608
        /*
 
609
         * memory reseveration, final preparation... 
 
610
         */
 
611
        break;
 
612
 
 
613
 
 
614
    case FREE:
 
615
        /*
 
616
         * Release any resources that have been allocated 
 
617
         */
 
618
        break;
 
619
 
 
620
 
 
621
    case ACTION:
 
622
        tmpvar = StorageTmp->snmpNotifyTag;
 
623
        tmplen = StorageTmp->snmpNotifyTagLen;
 
624
        memdup((u_char **) & StorageTmp->snmpNotifyTag, var_val,
 
625
               var_val_len);
 
626
        StorageTmp->snmpNotifyTagLen = var_val_len;
 
627
        break;
 
628
 
 
629
 
 
630
    case UNDO:
 
631
        /*
 
632
         * Back out any changes made in the ACTION case 
 
633
         */
 
634
        SNMP_FREE(StorageTmp->snmpNotifyTag);
 
635
        StorageTmp->snmpNotifyTag = tmpvar;
 
636
        StorageTmp->snmpNotifyTagLen = tmplen;
 
637
        tmpvar = NULL;
 
638
        break;
 
639
 
 
640
 
 
641
    case COMMIT:
 
642
        /*
 
643
         * Things are working well, so it's now safe to make the change
 
644
         * permanently.  Make sure that anything done here can't fail! 
 
645
         */
 
646
        SNMP_FREE(tmpvar);
 
647
        break;
 
648
    }
 
649
 
 
650
    return SNMP_ERR_NOERROR;
 
651
}
 
652
 
 
653
 
 
654
 
 
655
int
 
656
write_snmpNotifyType(int action,
 
657
                     u_char * var_val,
 
658
                     u_char var_val_type,
 
659
                     size_t var_val_len,
 
660
                     u_char * statP, oid * name, size_t name_len)
 
661
{
 
662
    static int      tmpvar;
 
663
    struct snmpNotifyTable_data *StorageTmp = NULL;
 
664
    long            value = *((long *) var_val);
 
665
    size_t          newlen =
 
666
        name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
 
667
                    3 - 1);
 
668
 
 
669
 
 
670
    DEBUGMSGTL(("snmpNotifyTable",
 
671
                "write_snmpNotifyType entering action=%d...  \n", action));
 
672
    if (action != RESERVE1 &&
 
673
        (StorageTmp = (struct snmpNotifyTable_data *)
 
674
         header_complex((struct header_complex_index *)
 
675
                        snmpNotifyTableStorage, NULL,
 
676
                        &name[sizeof(snmpNotifyTable_variables_oid) /
 
677
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
 
678
                        NULL)) == NULL) {
 
679
        if ((StorageTmp = StorageNew) == NULL)
 
680
            return SNMP_ERR_NOSUCHNAME;
 
681
    }
 
682
 
 
683
    switch (action) {
 
684
    case RESERVE1:
 
685
        if (var_val_type != ASN_INTEGER) {
 
686
            return SNMP_ERR_WRONGTYPE;
 
687
        }
 
688
        if (var_val_len != sizeof(long)) {
 
689
            return SNMP_ERR_WRONGLENGTH;
 
690
        }
 
691
        if (value < 1 || value > 2) {
 
692
            return SNMP_ERR_WRONGVALUE;
 
693
        }
 
694
        break;
 
695
 
 
696
    case ACTION:
 
697
        tmpvar = StorageTmp->snmpNotifyType;
 
698
        StorageTmp->snmpNotifyType = value;
 
699
        break;
 
700
 
 
701
    case UNDO:
 
702
        /*
 
703
         * Back out any changes made in the ACTION case 
 
704
         */
 
705
        StorageTmp->snmpNotifyType = tmpvar;
 
706
        break;
 
707
    }
 
708
 
 
709
    return SNMP_ERR_NOERROR;
 
710
}
 
711
 
 
712
 
 
713
 
 
714
int
 
715
write_snmpNotifyStorageType(int action,
 
716
                            u_char * var_val,
 
717
                            u_char var_val_type,
 
718
                            size_t var_val_len,
 
719
                            u_char * statP, oid * name, size_t name_len)
 
720
{
 
721
    static int      tmpvar;
 
722
    long            value = *((long *) var_val);
 
723
    struct snmpNotifyTable_data *StorageTmp = NULL;
 
724
    size_t          newlen =
 
725
        name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
 
726
                    3 - 1);
 
727
 
 
728
 
 
729
    DEBUGMSGTL(("snmpNotifyTable",
 
730
                "write_snmpNotifyStorageType entering action=%d...  \n",
 
731
                action));
 
732
    if (action != RESERVE1 &&
 
733
        (StorageTmp = (struct snmpNotifyTable_data *)
 
734
         header_complex((struct header_complex_index *)
 
735
                        snmpNotifyTableStorage, NULL,
 
736
                        &name[sizeof(snmpNotifyTable_variables_oid) /
 
737
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
 
738
                        NULL)) == NULL) {
 
739
        if ((StorageTmp = StorageNew) == NULL)
 
740
            return SNMP_ERR_NOSUCHNAME;
 
741
    }
 
742
 
 
743
 
 
744
    switch (action) {
 
745
    case RESERVE1:
 
746
        if (var_val_type != ASN_INTEGER) {
 
747
            return SNMP_ERR_WRONGTYPE;
 
748
        }
 
749
        if (var_val_len != sizeof(long)) {
 
750
            return SNMP_ERR_WRONGLENGTH;
 
751
        }
 
752
        if (value != SNMP_STORAGE_OTHER && value != SNMP_STORAGE_VOLATILE
 
753
            && value != SNMP_STORAGE_NONVOLATILE) {
 
754
            return SNMP_ERR_WRONGVALUE;
 
755
        }
 
756
        break;
 
757
 
 
758
    case ACTION:
 
759
        tmpvar = StorageTmp->snmpNotifyStorageType;
 
760
        StorageTmp->snmpNotifyStorageType = value;
 
761
        break;
 
762
 
 
763
    case UNDO:
 
764
        StorageTmp->snmpNotifyStorageType = tmpvar;
 
765
        break;
 
766
    }
 
767
    return SNMP_ERR_NOERROR;
 
768
}
 
769
 
 
770
 
 
771
 
 
772
int
 
773
write_snmpNotifyRowStatus(int action,
 
774
                          u_char * var_val,
 
775
                          u_char var_val_type,
 
776
                          size_t var_val_len,
 
777
                          u_char * statP, oid * name, size_t name_len)
 
778
{
 
779
    struct snmpNotifyTable_data *StorageTmp = NULL;
 
780
    static struct snmpNotifyTable_data *StorageDel;
 
781
    size_t          newlen =
 
782
        name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
 
783
                    3 - 1);
 
784
    static int      old_value;
 
785
    int             set_value = *((long *) var_val);
 
786
    static netsnmp_variable_list *vars, *vp;
 
787
    struct header_complex_index *hciptr;
 
788
 
 
789
 
 
790
    DEBUGMSGTL(("snmpNotifyTable",
 
791
                "write_snmpNotifyRowStatus entering action=%d...  \n",
 
792
                action));
 
793
    StorageTmp = (struct snmpNotifyTable_data *)
 
794
        header_complex((struct header_complex_index *)
 
795
                       snmpNotifyTableStorage, NULL,
 
796
                       &name[sizeof(snmpNotifyTable_variables_oid) /
 
797
                             sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);
 
798
 
 
799
    switch (action) {
 
800
    case RESERVE1:
 
801
        if (var_val_type != ASN_INTEGER || var_val == NULL) {
 
802
            return SNMP_ERR_WRONGTYPE;
 
803
        }
 
804
        if (var_val_len != sizeof(long)) {
 
805
            return SNMP_ERR_WRONGLENGTH;
 
806
        }
 
807
        if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) {
 
808
            return SNMP_ERR_WRONGVALUE;
 
809
        }
 
810
        if (StorageTmp == NULL) {
 
811
            /*
 
812
             * create the row now? 
 
813
             */
 
814
            /*
 
815
             * ditch illegal values now 
 
816
             */
 
817
            if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
 
818
                return SNMP_ERR_INCONSISTENTVALUE;
 
819
            }
 
820
        } else {
 
821
            /*
 
822
             * row exists.  Check for a valid state change 
 
823
             */
 
824
            if (set_value == RS_CREATEANDGO
 
825
                || set_value == RS_CREATEANDWAIT) {
 
826
                /*
 
827
                 * can't create a row that exists 
 
828
                 */
 
829
                return SNMP_ERR_INCONSISTENTVALUE;
 
830
            }
 
831
            /*
 
832
             * XXX: interaction with row storage type needed 
 
833
             */
 
834
        }
 
835
 
 
836
        /*
 
837
         * memory reseveration, final preparation... 
 
838
         */
 
839
        if (StorageTmp == NULL &&
 
840
            (set_value == RS_CREATEANDGO
 
841
             || set_value == RS_CREATEANDWAIT)) {
 
842
            /*
 
843
             * creation 
 
844
             */
 
845
            vars = NULL;
 
846
 
 
847
            snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, NULL, 0);     /* snmpNotifyName */
 
848
 
 
849
            if (header_complex_parse_oid
 
850
                (&
 
851
                 (name
 
852
                  [sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
 
853
                   2]), newlen, vars) != SNMPERR_SUCCESS) {
 
854
                /*
 
855
                 * XXX: free, zero vars 
 
856
                 */
 
857
                snmp_free_var(vars);
 
858
                return SNMP_ERR_INCONSISTENTNAME;
 
859
            }
 
860
            vp = vars;
 
861
 
 
862
 
 
863
            StorageNew = SNMP_MALLOC_STRUCT(snmpNotifyTable_data);
 
864
            if (StorageNew == NULL) {
 
865
                return SNMP_ERR_RESOURCEUNAVAILABLE;
 
866
            }
 
867
            memdup((u_char **) & (StorageNew->snmpNotifyName),
 
868
                   vp->val.string, vp->val_len);
 
869
            if (StorageNew->snmpNotifyName == NULL) {
 
870
                return SNMP_ERR_RESOURCEUNAVAILABLE;
 
871
            }
 
872
            StorageNew->snmpNotifyNameLen = vp->val_len;
 
873
            vp = vp->next_variable;
 
874
 
 
875
            /*
 
876
             * default values 
 
877
             */
 
878
            StorageNew->snmpNotifyStorageType = ST_NONVOLATILE;
 
879
            StorageNew->snmpNotifyType = SNMPNOTIFYTYPE_TRAP;
 
880
            StorageNew->snmpNotifyTagLen = 0;
 
881
            StorageNew->snmpNotifyTag = (char *) calloc(sizeof(char), 1);
 
882
            if (StorageNew->snmpNotifyTag == NULL) {
 
883
                return SNMP_ERR_RESOURCEUNAVAILABLE;
 
884
            }
 
885
 
 
886
            StorageNew->snmpNotifyRowStatus = set_value;
 
887
            snmp_free_var(vars);
 
888
        }
 
889
        break;
 
890
 
 
891
    case RESERVE2:
 
892
        break;
 
893
 
 
894
    case FREE:
 
895
        if (StorageNew != NULL) {
 
896
            SNMP_FREE(StorageNew->snmpNotifyTag);
 
897
            SNMP_FREE(StorageNew->snmpNotifyName);
 
898
            free(StorageNew);
 
899
            StorageNew = NULL;
 
900
        }
 
901
        break;
 
902
 
 
903
    case ACTION:
 
904
        if (StorageTmp == NULL && (set_value == RS_CREATEANDGO ||
 
905
                                   set_value == RS_CREATEANDWAIT)) {
 
906
            /*
 
907
             * row creation, so add it 
 
908
             */
 
909
            if (StorageNew != NULL) {
 
910
                snmpNotifyTable_add(StorageNew);
 
911
            }
 
912
        } else if (set_value != RS_DESTROY) {
 
913
            /*
 
914
             * set the flag? 
 
915
             */
 
916
            old_value = StorageTmp->snmpNotifyRowStatus;
 
917
            StorageTmp->snmpNotifyRowStatus = *((long *) var_val);
 
918
        } else {
 
919
            /*
 
920
             * destroy...  extract it for now 
 
921
             */
 
922
            if (StorageTmp) {
 
923
                hciptr = header_complex_find_entry(snmpNotifyTableStorage,
 
924
                                                   StorageTmp);
 
925
                StorageDel = (struct snmpNotifyTable_data *)
 
926
                    header_complex_extract_entry((struct
 
927
                                                  header_complex_index **)
 
928
                                                 &snmpNotifyTableStorage,
 
929
                                                 hciptr);
 
930
            }
 
931
        }
 
932
        break;
 
933
 
 
934
    case UNDO:
 
935
        /*
 
936
         * Back out any changes made in the ACTION case 
 
937
         */
 
938
        if (StorageTmp == NULL && (set_value == RS_CREATEANDGO ||
 
939
                                   set_value == RS_CREATEANDWAIT)) {
 
940
            /*
 
941
             * row creation, so remove it again 
 
942
             */
 
943
            hciptr = header_complex_find_entry(snmpNotifyTableStorage,
 
944
                                               StorageNew);
 
945
            StorageDel = (struct snmpNotifyTable_data *)
 
946
                header_complex_extract_entry((struct header_complex_index
 
947
                                              **) &snmpNotifyTableStorage,
 
948
                                             hciptr);
 
949
            /*
 
950
             * XXX: free it 
 
951
             */
 
952
        } else if (StorageDel != NULL) {
 
953
            /*
 
954
             * row deletion, so add it again 
 
955
             */
 
956
            snmpNotifyTable_add(StorageDel);
 
957
        } else if (set_value != RS_DESTROY) {
 
958
            StorageTmp->snmpNotifyRowStatus = old_value;
 
959
        }
 
960
        break;
 
961
 
 
962
    case COMMIT:
 
963
        if (StorageDel != NULL) {
 
964
            SNMP_FREE(StorageDel->snmpNotifyTag);
 
965
            SNMP_FREE(StorageDel->snmpNotifyName);
 
966
            free(StorageDel);
 
967
            StorageDel = NULL;
 
968
        }
 
969
        if (StorageTmp
 
970
            && StorageTmp->snmpNotifyRowStatus == RS_CREATEANDGO) {
 
971
            StorageTmp->snmpNotifyRowStatus = RS_ACTIVE;
 
972
            StorageNew = NULL;
 
973
        } else if (StorageTmp &&
 
974
                   StorageTmp->snmpNotifyRowStatus == RS_CREATEANDWAIT) {
 
975
            StorageTmp->snmpNotifyRowStatus = RS_NOTINSERVICE;
 
976
            StorageNew = NULL;
 
977
        }
 
978
        break;
 
979
    }
 
980
    return SNMP_ERR_NOERROR;
 
981
}