~ubuntu-branches/ubuntu/gutsy/net-snmp/gutsy-security

« back to all changes in this revision

Viewing changes to agent/mibgroup/agent/nsCache.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
#include <net-snmp/net-snmp-config.h>
 
2
#include <net-snmp/net-snmp-includes.h>
 
3
#include <net-snmp/agent/net-snmp-agent-includes.h>
 
4
#include <net-snmp/agent/scalar.h>
 
5
 
 
6
#ifdef HAVE_STRING_H
 
7
#include <string.h>
 
8
#else
 
9
#include <strings.h>
 
10
#endif
 
11
 
 
12
#include <net-snmp/agent/cache_handler.h>
 
13
#include "agent/nsCache.h"
 
14
#include "util_funcs.h"
 
15
 
 
16
 
 
17
 
 
18
/*
 
19
 * OIDs for the cacheging control scalar objects
 
20
 *
 
21
 * Note that these we're registering the full object rather
 
22
 *  than the (sole) valid instance in each case, in order
 
23
 *  to handle requests for invalid instances properly.
 
24
 */
 
25
oid nsCacheTimeout_oid[]    = { 1, 3, 6, 1, 4, 1, 8072, 1, 5, 1};
 
26
oid nsCacheEnabled_oid[]    = { 1, 3, 6, 1, 4, 1, 8072, 1, 5, 2};
 
27
 
 
28
/*
 
29
 * ... and for the cache table.
 
30
 */
 
31
 
 
32
#define  NSCACHE_TIMEOUT        2
 
33
#define  NSCACHE_STATUS         3
 
34
 
 
35
#define NSCACHE_STATUS_ENABLED  1
 
36
#define NSCACHE_STATUS_DISABLED 2
 
37
#define NSCACHE_STATUS_EMPTY    3
 
38
#define NSCACHE_STATUS_ACTIVE   4
 
39
#define NSCACHE_STATUS_EXPIRED  5
 
40
 
 
41
oid nsCacheTable_oid[]      = { 1, 3, 6, 1, 4, 1, 8072, 1, 5, 3};
 
42
 
 
43
 
 
44
void
 
45
init_nsCache(void)
 
46
{
 
47
    netsnmp_table_registration_info *table_info;
 
48
    netsnmp_iterator_info           *iinfo;
 
49
 
 
50
    /*
 
51
     * Register the scalar objects...
 
52
     */
 
53
    DEBUGMSGTL(("nsCacheScalars", "Initializing\n"));
 
54
    netsnmp_register_scalar(
 
55
        netsnmp_create_handler_registration(
 
56
            "nsCacheTimeout", handle_nsCacheTimeout,
 
57
            nsCacheTimeout_oid, OID_LENGTH(nsCacheTimeout_oid),
 
58
            HANDLER_CAN_RWRITE)
 
59
        );
 
60
    netsnmp_register_scalar(
 
61
        netsnmp_create_handler_registration(
 
62
            "nsCacheEnabled", handle_nsCacheEnabled,
 
63
            nsCacheEnabled_oid, OID_LENGTH(nsCacheEnabled_oid),
 
64
            HANDLER_CAN_RWRITE)
 
65
        );
 
66
 
 
67
    /*
 
68
     * ... and the table.
 
69
     * We need to define the column structure and indexing....
 
70
     */
 
71
 
 
72
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
 
73
    if (!table_info) {
 
74
        return;
 
75
    }
 
76
    netsnmp_table_helper_add_indexes(table_info, ASN_PRIV_IMPLIED_OBJECT_ID, 0);
 
77
    table_info->min_column = NSCACHE_TIMEOUT;
 
78
    table_info->max_column = NSCACHE_STATUS;
 
79
 
 
80
 
 
81
    /*
 
82
     * .... and the iteration information ....
 
83
     */
 
84
    iinfo      = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
 
85
    if (!iinfo) {
 
86
        return;
 
87
    }
 
88
    iinfo->get_first_data_point = get_first_cache_entry;
 
89
    iinfo->get_next_data_point  = get_next_cache_entry;
 
90
    iinfo->table_reginfo        = table_info;
 
91
 
 
92
 
 
93
    /*
 
94
     * .... and register the table with the agent.
 
95
     */
 
96
    netsnmp_register_table_iterator(
 
97
        netsnmp_create_handler_registration(
 
98
            "tzCacheTable", handle_nsCacheTable,
 
99
            nsCacheTable_oid, OID_LENGTH(nsCacheTable_oid),
 
100
            HANDLER_CAN_RWRITE),
 
101
        iinfo);
 
102
}
 
103
 
 
104
 
 
105
/*
 
106
 * nsCache scalar handling
 
107
 */
 
108
 
 
109
int
 
110
handle_nsCacheTimeout(netsnmp_mib_handler *handler,
 
111
                netsnmp_handler_registration *reginfo,
 
112
                netsnmp_agent_request_info *reqinfo,
 
113
                netsnmp_request_info *requests)
 
114
{
 
115
    extern long cache_default_timeout;
 
116
    netsnmp_request_info *request=NULL;
 
117
 
 
118
    switch (reqinfo->mode) {
 
119
 
 
120
    case MODE_GET:
 
121
        for (request = requests; request; request=request->next) {
 
122
            snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
 
123
                                     (u_char*)&cache_default_timeout,
 
124
                                        sizeof(cache_default_timeout));
 
125
        }
 
126
        break;
 
127
 
 
128
 
 
129
    case MODE_SET_RESERVE1:
 
130
        for (request = requests; request; request=request->next) {
 
131
            if ( request->status != 0 ) {
 
132
                return SNMP_ERR_NOERROR;        /* Already got an error */
 
133
            }
 
134
            if ( request->requestvb->type != ASN_INTEGER ) {
 
135
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
 
136
                return SNMP_ERR_WRONGTYPE;
 
137
            }
 
138
            if ( *request->requestvb->val.integer < 0 ) {
 
139
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
 
140
                return SNMP_ERR_WRONGVALUE;
 
141
            }
 
142
        }
 
143
        break;
 
144
 
 
145
    case MODE_SET_COMMIT:
 
146
        cache_default_timeout = *requests->requestvb->val.integer;
 
147
        break;
 
148
    }
 
149
 
 
150
    return SNMP_ERR_NOERROR;
 
151
}
 
152
 
 
153
 
 
154
int
 
155
handle_nsCacheEnabled(netsnmp_mib_handler *handler,
 
156
                netsnmp_handler_registration *reginfo,
 
157
                netsnmp_agent_request_info *reqinfo,
 
158
                netsnmp_request_info *requests)
 
159
{
 
160
    extern long caching_enabled;
 
161
    long enabled;
 
162
    netsnmp_request_info *request=NULL;
 
163
 
 
164
    switch (reqinfo->mode) {
 
165
 
 
166
    case MODE_GET:
 
167
        enabled =  (caching_enabled
 
168
                       ? NSCACHE_STATUS_ENABLED    /* Actually True/False */
 
169
                       : NSCACHE_STATUS_DISABLED );
 
170
        for (request = requests; request; request=request->next) {
 
171
            snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
 
172
                                     (u_char*)&enabled, sizeof(enabled));
 
173
        }
 
174
        break;
 
175
 
 
176
 
 
177
    case MODE_SET_RESERVE1:
 
178
        for (request = requests; request; request=request->next) {
 
179
            if ( request->status != 0 ) {
 
180
                return SNMP_ERR_NOERROR;        /* Already got an error */
 
181
            }
 
182
            if ( request->requestvb->type != ASN_INTEGER ) {
 
183
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
 
184
                return SNMP_ERR_WRONGTYPE;
 
185
            }
 
186
            if ((*request->requestvb->val.integer != NSCACHE_STATUS_ENABLED) &&
 
187
                (*request->requestvb->val.integer != NSCACHE_STATUS_DISABLED)) {
 
188
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
 
189
                return SNMP_ERR_WRONGVALUE;
 
190
            }
 
191
        }
 
192
        break;
 
193
 
 
194
    case MODE_SET_COMMIT:
 
195
        enabled = *requests->requestvb->val.integer;
 
196
        if (enabled == NSCACHE_STATUS_DISABLED)
 
197
            enabled = 0;
 
198
        caching_enabled = enabled;
 
199
        break;
 
200
    }
 
201
 
 
202
    return SNMP_ERR_NOERROR;
 
203
}
 
204
 
 
205
 
 
206
/*
 
207
 * nsCacheTable handling
 
208
 */
 
209
 
 
210
netsnmp_variable_list *
 
211
get_first_cache_entry(void **loop_context, void **data_context,
 
212
                      netsnmp_variable_list *index,
 
213
                      netsnmp_iterator_info *data)
 
214
{
 
215
    extern netsnmp_cache  *cache_head;
 
216
 
 
217
    if ( !cache_head )
 
218
        return NULL;
 
219
 
 
220
    snmp_set_var_value(index, (u_char*)cache_head->rootoid,
 
221
                         sizeof(oid) * cache_head->rootoid_len);
 
222
    *loop_context = (void*)cache_head;
 
223
    *data_context = (void*)cache_head;
 
224
    return index;
 
225
}
 
226
 
 
227
netsnmp_variable_list *
 
228
get_next_cache_entry(void **loop_context, void **data_context,
 
229
                      netsnmp_variable_list *index,
 
230
                      netsnmp_iterator_info *data)
 
231
{
 
232
    netsnmp_cache *cache = (netsnmp_cache *)*loop_context;
 
233
    cache = cache->next;
 
234
 
 
235
    if ( !cache )
 
236
        return NULL;
 
237
 
 
238
    snmp_set_var_value(index, (u_char*)cache->rootoid,
 
239
                         sizeof(oid) * cache->rootoid_len);
 
240
    *loop_context = (void*)cache;
 
241
    *data_context = (void*)cache;
 
242
    return index;
 
243
}
 
244
 
 
245
 
 
246
int
 
247
handle_nsCacheTable(netsnmp_mib_handler *handler,
 
248
                netsnmp_handler_registration *reginfo,
 
249
                netsnmp_agent_request_info *reqinfo,
 
250
                netsnmp_request_info *requests)
 
251
{
 
252
    long status;
 
253
    netsnmp_request_info       *request     = NULL;
 
254
    netsnmp_table_request_info *table_info  = NULL;
 
255
    netsnmp_cache              *cache_entry = NULL;
 
256
 
 
257
    switch (reqinfo->mode) {
 
258
 
 
259
    case MODE_GET:
 
260
        for (request=requests; request; request=request->next) {
 
261
            if (requests->processed != 0)
 
262
                continue;
 
263
 
 
264
            cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
 
265
            table_info  =                 netsnmp_extract_table_info(request);
 
266
 
 
267
            switch (table_info->colnum) {
 
268
            case NSCACHE_TIMEOUT:
 
269
                if (!cache_entry) {
 
270
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
 
271
                    continue;
 
272
                }
 
273
                snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
 
274
                                         (u_char*)&cache_entry->timeout,
 
275
                                            sizeof(cache_entry->timeout));
 
276
                break;
 
277
 
 
278
            case NSCACHE_STATUS:
 
279
                if (!cache_entry) {
 
280
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
 
281
                    continue;
 
282
                }
 
283
                status = (cache_entry->enabled ?
 
284
                           (cache_entry->timestamp ?
 
285
                             (!atime_ready(cache_entry->timestamp,
 
286
                                          1000*cache_entry->timeout) ?
 
287
                                NSCACHE_STATUS_ACTIVE:
 
288
                                NSCACHE_STATUS_EXPIRED) :
 
289
                              NSCACHE_STATUS_EMPTY) :
 
290
                            NSCACHE_STATUS_DISABLED);
 
291
                snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
 
292
                                         (u_char*)&status, sizeof(status));
 
293
                break;
 
294
 
 
295
            default:
 
296
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
 
297
                continue;
 
298
            }
 
299
        }
 
300
        break;
 
301
 
 
302
 
 
303
    case MODE_SET_RESERVE1:
 
304
        for (request=requests; request; request=request->next) {
 
305
            if (requests->processed != 0)
 
306
                continue;
 
307
            if ( request->status != 0 ) {
 
308
                return SNMP_ERR_NOERROR;        /* Already got an error */
 
309
            }
 
310
            cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
 
311
            table_info  =                 netsnmp_extract_table_info(request);
 
312
 
 
313
            switch (table_info->colnum) {
 
314
            case NSCACHE_TIMEOUT:
 
315
                if (!cache_entry) {
 
316
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
 
317
                    return SNMP_ERR_NOCREATION;
 
318
                }
 
319
                if ( request->requestvb->type != ASN_INTEGER ) {
 
320
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
 
321
                    return SNMP_ERR_WRONGTYPE;
 
322
                }
 
323
                if (*request->requestvb->val.integer < 0 ) {
 
324
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
 
325
                    return SNMP_ERR_WRONGVALUE;
 
326
                }
 
327
                break;
 
328
 
 
329
            case NSCACHE_STATUS:
 
330
                if (!cache_entry) {
 
331
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
 
332
                    return SNMP_ERR_NOCREATION;
 
333
                }
 
334
                if ( request->requestvb->type != ASN_INTEGER ) {
 
335
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
 
336
                    return SNMP_ERR_WRONGTYPE;
 
337
                }
 
338
                status = *request->requestvb->val.integer;
 
339
                if (!((status == NSCACHE_STATUS_ENABLED  ) ||
 
340
                      (status == NSCACHE_STATUS_DISABLED ) ||
 
341
                      (status == NSCACHE_STATUS_EMPTY  ))) {
 
342
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
 
343
                    return SNMP_ERR_WRONGVALUE;
 
344
                }
 
345
                break;
 
346
 
 
347
            default:
 
348
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION);
 
349
                return SNMP_ERR_NOCREATION;     /* XXX - is this right ? */
 
350
                continue;
 
351
            }
 
352
        }
 
353
        break;
 
354
 
 
355
 
 
356
    case MODE_SET_COMMIT:
 
357
        for (request=requests; request; request=request->next) {
 
358
            if (requests->processed != 0)
 
359
                continue;
 
360
            if ( request->status != 0 ) {
 
361
                return SNMP_ERR_NOERROR;        /* Already got an error */
 
362
            }
 
363
            cache_entry = (netsnmp_cache*)netsnmp_extract_iterator_context(request);
 
364
            if (!cache_entry) {
 
365
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_COMMITFAILED);
 
366
                return SNMP_ERR_COMMITFAILED;   /* Shouldn't happen! */
 
367
            }
 
368
            table_info  =                 netsnmp_extract_table_info(request);
 
369
 
 
370
            switch (table_info->colnum) {
 
371
            case NSCACHE_TIMEOUT:
 
372
                cache_entry->timeout = *request->requestvb->val.integer;
 
373
                break;
 
374
 
 
375
            case NSCACHE_STATUS:
 
376
                switch (*request->requestvb->val.integer) {
 
377
                    case NSCACHE_STATUS_ENABLED:
 
378
                        cache_entry->enabled = 1;
 
379
                        break;
 
380
                    case NSCACHE_STATUS_DISABLED:
 
381
                        cache_entry->enabled = 0;
 
382
                        break;
 
383
                    case NSCACHE_STATUS_EMPTY:
 
384
                        cache_entry->free_cache(cache_entry, cache_entry->magic);
 
385
                        free(cache_entry->timestamp);
 
386
                        cache_entry->timestamp = NULL;
 
387
                        break;
 
388
                }
 
389
                break;
 
390
            }
 
391
        }
 
392
        break;
 
393
    }
 
394
 
 
395
    return SNMP_ERR_NOERROR;
 
396
}