~ubuntu-branches/debian/lenny/net-snmp/lenny

« back to all changes in this revision

Viewing changes to agent/mibgroup/if-mib/data_access/interface_common.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-05-10 22:20:23 UTC
  • Revision ID: james.westby@ubuntu.com-20070510222023-3fr07xb9i17xvq32
Tags: upstream-5.3.1
ImportĀ upstreamĀ versionĀ 5.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  Interface MIB architecture support
3
 
 *
4
 
 * $Id: interface_common.c,v 1.20.2.2 2005/02/09 21:02:14 nba Exp $
5
 
 */
6
 
#include <net-snmp/net-snmp-config.h>
7
 
#include <net-snmp/net-snmp-includes.h>
8
 
#include "mibII/mibII_common.h"
9
 
#include "if-mib/ifTable/ifTable_constants.h"
10
 
 
11
 
#include <net-snmp/agent/net-snmp-agent-includes.h>
12
 
#include <net-snmp/library/snmp_enum.h>
13
 
#include "interface.h"
14
 
 
15
 
/**---------------------------------------------------------------------*/
16
 
/*
17
 
 * local static vars
18
 
 */
19
 
static netsnmp_conf_if_list *conf_list = NULL;
20
 
static int need_wrap_check = -1;
21
 
static int _access_interface_init = 0;
22
 
 
23
 
/*
24
 
 * local static prototypes
25
 
 */
26
 
static int _access_interface_entry_compare_name(const void *lhs,
27
 
                                                const void *rhs);
28
 
static void _access_interface_entry_release(netsnmp_interface_entry * entry,
29
 
                                            void *unused);
30
 
static void _access_interface_entry_save_name(const char *name, oid index);
31
 
static void _parse_interface_config(const char *token, char *cptr);
32
 
static void _free_interface_config(void);
33
 
 
34
 
/**---------------------------------------------------------------------*/
35
 
/*
36
 
 * external per-architecture functions prototypes
37
 
 *
38
 
 * These shouldn't be called by the general public, so they aren't in
39
 
 * the header file.
40
 
 */
41
 
#ifndef NETSNMP_ACCESS_INTERFACE_NOARCH
42
 
extern void netsnmp_arch_interface_init(void);
43
 
extern int
44
 
netsnmp_arch_interface_container_load(netsnmp_container* container,
45
 
                                      u_int load_flags);
46
 
extern int
47
 
netsnmp_arch_set_admin_status(netsnmp_interface_entry * entry,
48
 
                              int ifAdminStatus);
49
 
extern int netsnmp_arch_interface_index_find(const char*name);
50
 
#endif
51
 
 
52
 
 
53
 
/**---------------------------------------------------------------------*/
54
 
/*
55
 
 * initialization
56
 
 */
57
 
void
58
 
init_interface_common(void)
59
 
{
60
 
    snmpd_register_config_handler("interface", _parse_interface_config,
61
 
                                  _free_interface_config,
62
 
                                  "name type speed");
63
 
}
64
 
 
65
 
 
66
 
void
67
 
netsnmp_access_interface_init(void)
68
 
{
69
 
    netsnmp_assert(0 == _access_interface_init); /* who is calling twice? */
70
 
 
71
 
    if (1 == _access_interface_init)
72
 
        return;
73
 
 
74
 
    _access_interface_init = 1;
75
 
 
76
 
#ifndef NETSNMP_ACCESS_INTERFACE_NOARCH
77
 
    {
78
 
        netsnmp_container * ifcontainer;
79
 
 
80
 
        netsnmp_arch_interface_init();
81
 
        
82
 
        /*
83
 
         * load once to set up ifIndexes
84
 
         */
85
 
        ifcontainer = netsnmp_access_interface_container_load(NULL, 0);
86
 
        if(NULL != ifcontainer)
87
 
            netsnmp_access_interface_container_free(ifcontainer, 0);
88
 
    }
89
 
#endif
90
 
}
91
 
 
92
 
/**---------------------------------------------------------------------*/
93
 
/*
94
 
 * container functions
95
 
 */
96
 
/**
97
 
 * initialize interface container
98
 
 */
99
 
netsnmp_container *
100
 
netsnmp_access_interface_container_init(u_int flags)
101
 
{
102
 
    netsnmp_container *container1;
103
 
 
104
 
    DEBUGMSGTL(("access:interface:container", "init\n"));
105
 
 
106
 
    /*
107
 
     * create the containers. one indexed by ifIndex, the other
108
 
     * indexed by ifName.
109
 
     */
110
 
    container1 = netsnmp_container_find("access_interface:table_container");
111
 
    if (NULL == container1)
112
 
        return NULL;
113
 
 
114
 
    if (flags & NETSNMP_ACCESS_INTERFACE_INIT_ADDL_IDX_BY_NAME) {
115
 
        netsnmp_container *container2 =
116
 
            netsnmp_container_find("access_interface_by_name:access_interface:table_container");
117
 
        if (NULL == container2)
118
 
            return NULL;
119
 
 
120
 
        container2->compare = _access_interface_entry_compare_name;
121
 
        
122
 
        netsnmp_container_add_index(container1, container2);
123
 
    }
124
 
 
125
 
    return container1;
126
 
}
127
 
 
128
 
/**
129
 
 * load interface information in specified container
130
 
 *
131
 
 * @param container empty container, or NULL to have one created for you
132
 
 * @param load_flags flags to modify behaviour. Examples:
133
 
 *                   NETSNMP_ACCESS_INTERFACE_INIT_ADDL_IDX_BY_NAME
134
 
 *
135
 
 * @retval NULL  error
136
 
 * @retval !NULL pointer to container
137
 
 */
138
 
#ifndef NETSNMP_ACCESS_INTERFACE_NOARCH
139
 
netsnmp_container*
140
 
netsnmp_access_interface_container_load(netsnmp_container* container, u_int load_flags)
141
 
{
142
 
    int rc;
143
 
 
144
 
    DEBUGMSGTL(("access:interface:container", "load\n"));
145
 
    netsnmp_assert(1 == _access_interface_init);
146
 
 
147
 
    if (NULL == container)
148
 
        container = netsnmp_access_interface_container_init(load_flags);
149
 
    if (NULL == container) {
150
 
        snmp_log(LOG_ERR, "no container specified/found for access_interface\n");
151
 
        return NULL;
152
 
    }
153
 
 
154
 
    rc =  netsnmp_arch_interface_container_load(container, load_flags);
155
 
    if (0 != rc) {
156
 
        netsnmp_access_interface_container_free(container,
157
 
                                                NETSNMP_ACCESS_INTERFACE_FREE_NOFLAGS);
158
 
        container = NULL;
159
 
    }
160
 
 
161
 
    return container;
162
 
}
163
 
 
164
 
void
165
 
netsnmp_access_interface_container_free(netsnmp_container *container, u_int free_flags)
166
 
{
167
 
    DEBUGMSGTL(("access:interface:container", "free\n"));
168
 
 
169
 
    if (NULL == container) {
170
 
        snmp_log(LOG_ERR, "invalid container for netsnmp_access_interface_free\n");
171
 
        return;
172
 
    }
173
 
 
174
 
    if(! (free_flags & NETSNMP_ACCESS_INTERFACE_FREE_DONT_CLEAR)) {
175
 
        /*
176
 
         * free all items.
177
 
         */
178
 
        CONTAINER_CLEAR(container,
179
 
                        (netsnmp_container_obj_func*)_access_interface_entry_release,
180
 
                        NULL);
181
 
    }
182
 
 
183
 
    CONTAINER_FREE(container);
184
 
}
185
 
 
186
 
/**
187
 
 * @retval 0  interface not found
188
 
 */
189
 
oid
190
 
netsnmp_access_interface_index_find(const char *name)
191
 
{
192
 
    DEBUGMSGTL(("access:interface:find", "index\n"));
193
 
    netsnmp_assert(1 == _access_interface_init);
194
 
 
195
 
    return netsnmp_arch_interface_index_find(name);
196
 
}
197
 
#endif
198
 
 
199
 
/**---------------------------------------------------------------------*/
200
 
/*
201
 
 * ifentry functions
202
 
 */
203
 
/**
204
 
 */
205
 
netsnmp_interface_entry *
206
 
netsnmp_access_interface_entry_get_by_index(netsnmp_container *container, oid index)
207
 
{
208
 
    netsnmp_index   tmp;
209
 
 
210
 
    DEBUGMSGTL(("access:interface:entry", "by_index\n"));
211
 
    netsnmp_assert(1 == _access_interface_init);
212
 
 
213
 
    if (NULL == container) {
214
 
        snmp_log(LOG_ERR,
215
 
                 "invalid container for netsnmp_access_interface_entry_get_by_index\n");
216
 
        return NULL;
217
 
    }
218
 
 
219
 
    tmp.len = 1;
220
 
    tmp.oids = &index;
221
 
 
222
 
    return (netsnmp_interface_entry *) CONTAINER_FIND(container, &tmp);
223
 
}
224
 
 
225
 
/**
226
 
 */
227
 
netsnmp_interface_entry *
228
 
netsnmp_access_interface_entry_get_by_name(netsnmp_container *container,
229
 
                                const char *name)
230
 
{
231
 
    netsnmp_interface_entry tmp;
232
 
 
233
 
    DEBUGMSGTL(("access:interface:entry", "by_name\n"));
234
 
    netsnmp_assert(1 == _access_interface_init);
235
 
 
236
 
    if (NULL == container) {
237
 
        snmp_log(LOG_ERR,
238
 
                 "invalid container for netsnmp_access_interface_entry_get_by_name\n");
239
 
        return NULL;
240
 
    }
241
 
 
242
 
    if (NULL == container->next) {
243
 
        snmp_log(LOG_ERR,
244
 
                 "secondary index missing for netsnmp_access_interface_entry_get_by_name\n");
245
 
        return NULL;
246
 
    }
247
 
 
248
 
    tmp.name = name;
249
 
    return CONTAINER_FIND(container->next, &tmp);
250
 
}
251
 
 
252
 
/**
253
 
 * @retval NULL  index not found
254
 
 */
255
 
const char *
256
 
netsnmp_access_interface_name_find(oid index)
257
 
{
258
 
    DEBUGMSGTL(("access:interface:find", "name\n"));
259
 
    netsnmp_assert(1 == _access_interface_init);
260
 
 
261
 
    return se_find_label_in_slist("interfaces", index);
262
 
}
263
 
 
264
 
/**
265
 
 */
266
 
netsnmp_interface_entry *
267
 
netsnmp_access_interface_entry_create(const char *name, oid if_index)
268
 
{
269
 
    netsnmp_interface_entry *entry =
270
 
        SNMP_MALLOC_TYPEDEF(netsnmp_interface_entry);
271
 
 
272
 
    DEBUGMSGTL(("access:interface:entry", "create\n"));
273
 
    netsnmp_assert(1 == _access_interface_init);
274
 
 
275
 
    if(NULL == entry)
276
 
        return NULL;
277
 
 
278
 
    if(NULL != name)
279
 
        entry->name = strdup(name);
280
 
 
281
 
    /*
282
 
     * get if index, and save name for reverse lookup
283
 
     */
284
 
#ifndef NETSNMP_ACCESS_INTERFACE_NOARCH
285
 
    if (0 == if_index)
286
 
        entry->index = netsnmp_access_interface_index_find(name);
287
 
    else
288
 
#endif
289
 
        entry->index = if_index;
290
 
    _access_interface_entry_save_name(name, entry->index);
291
 
 
292
 
    /*
293
 
     * until we can get actual description, leave descr NULL.
294
 
     * The end user can decide what to do with it.
295
 
     */
296
 
    /* entry->descr = strdup("unknown"); */
297
 
 
298
 
    /*
299
 
     * make some assumptions
300
 
     */
301
 
    entry->connector_present = 1;
302
 
 
303
 
    entry->oid_index.len = 1;
304
 
    entry->oid_index.oids = (oid *) & entry->index;
305
 
 
306
 
    return entry;
307
 
}
308
 
 
309
 
/**
310
 
 */
311
 
void
312
 
netsnmp_access_interface_entry_free(netsnmp_interface_entry * entry)
313
 
{
314
 
    DEBUGMSGTL(("access:interface:entry", "free\n"));
315
 
 
316
 
    if (NULL == entry)
317
 
        return;
318
 
 
319
 
    /*
320
 
     * SNMP_FREE not needed, for any of these, 
321
 
     * since the whole entry is about to be freed
322
 
     */
323
 
 
324
 
    if (NULL != entry->old_stats)
325
 
        free(entry->old_stats);
326
 
 
327
 
    if (NULL != entry->name)
328
 
        free(entry->name);
329
 
 
330
 
    if (NULL != entry->descr)
331
 
        free(entry->descr);
332
 
 
333
 
    if (NULL != entry->paddr)
334
 
        free(entry->paddr);
335
 
 
336
 
    free(entry);
337
 
}
338
 
 
339
 
/**
340
 
 *
341
 
 * @retval 0   : success
342
 
 * @retval < 0 : error
343
 
 */
344
 
#ifndef NETSNMP_ACCESS_INTERFACE_NOARCH
345
 
int
346
 
netsnmp_access_interface_entry_set_admin_status(netsnmp_interface_entry * entry,
347
 
                                                int ifAdminStatus)
348
 
{
349
 
    int rc;
350
 
 
351
 
    DEBUGMSGTL(("access:interface:entry", "set_admin_status\n"));
352
 
 
353
 
    if (NULL == entry)
354
 
        return -1;
355
 
 
356
 
    if ((ifAdminStatus < IFADMINSTATUS_UP) ||
357
 
         (ifAdminStatus > IFADMINSTATUS_TESTING))
358
 
        return -2;
359
 
 
360
 
    rc = netsnmp_arch_set_admin_status(entry, ifAdminStatus);
361
 
    if (0 == rc) /* success */
362
 
        entry->admin_status = ifAdminStatus;
363
 
 
364
 
    return rc;
365
 
}
366
 
#endif
367
 
 
368
 
/**---------------------------------------------------------------------*/
369
 
/*
370
 
 * Utility routines
371
 
 */
372
 
 
373
 
/**
374
 
 */
375
 
static int
376
 
_access_interface_entry_compare_name(const void *lhs, const void *rhs)
377
 
{
378
 
    return strcmp(((const netsnmp_interface_entry *) lhs)->name,
379
 
                  ((const netsnmp_interface_entry *) rhs)->name);
380
 
}
381
 
 
382
 
/**
383
 
 */
384
 
static void
385
 
_access_interface_entry_release(netsnmp_interface_entry * entry, void *context)
386
 
{
387
 
    netsnmp_access_interface_entry_free(entry);
388
 
}
389
 
 
390
 
/**
391
 
 */
392
 
static void
393
 
_access_interface_entry_save_name(const char *name, oid index)
394
 
{
395
 
    oid tmp;
396
 
 
397
 
    if(NULL == name)
398
 
        return;
399
 
 
400
 
    tmp = se_find_value_in_slist("interfaces", name);
401
 
    if (tmp == SE_DNE) {
402
 
        se_add_pair_to_slist("interfaces", strdup(name), index);
403
 
        DEBUGMSGTL(("access:interface:ifIndex", "saved ifIndex %d for %s\n",
404
 
                    index, name));
405
 
    }
406
 
    else
407
 
        netsnmp_assert(index == tmp);
408
 
}
409
 
 
410
 
/**
411
 
 * update stats
412
 
 *
413
 
 * @retval  0 : success
414
 
 * @retval -1 : error
415
 
 */
416
 
int
417
 
netsnmp_access_interface_entry_update_stats(netsnmp_interface_entry * prev_vals,
418
 
                                            netsnmp_interface_entry * new_vals)
419
 
{
420
 
    DEBUGMSGTL(("access:interface", "check_wrap\n"));
421
 
    
422
 
    /*
423
 
     * sanity checks
424
 
     */
425
 
    if ((NULL == prev_vals) || (NULL == new_vals) ||
426
 
        (NULL == prev_vals->name) || (NULL == new_vals->name) ||
427
 
        (0 != strncmp(prev_vals->name, new_vals->name, strlen(prev_vals->name))))
428
 
        return -1;
429
 
 
430
 
    /*
431
 
     * if we've determined that we have 64 bit counters, just copy them.
432
 
     */
433
 
    if (0 == need_wrap_check) {
434
 
        memcpy(&prev_vals->stats, &new_vals->stats, sizeof(new_vals->stats));
435
 
        return 0;
436
 
    }
437
 
 
438
 
    if (NULL == prev_vals->old_stats) {
439
 
        /*
440
 
         * if we don't have old stats, copy previous stats
441
 
         */
442
 
        prev_vals->old_stats = SNMP_MALLOC_TYPEDEF(netsnmp_interface_stats);
443
 
        if (NULL == prev_vals->old_stats) {
444
 
            return -2;
445
 
        }
446
 
        memcpy(prev_vals->old_stats, &prev_vals->stats, sizeof(new_vals->stats));
447
 
    }
448
 
 
449
 
        netsnmp_c64_check32_and_update(&prev_vals->stats.ibytes,
450
 
                                       &new_vals->stats.ibytes,
451
 
                                       &prev_vals->old_stats->ibytes,
452
 
                                       &need_wrap_check);
453
 
        netsnmp_c64_check32_and_update(&prev_vals->stats.iucast,
454
 
                                       &new_vals->stats.iucast,
455
 
                                       &prev_vals->old_stats->iucast,
456
 
                                       &need_wrap_check);
457
 
        netsnmp_c64_check32_and_update(&prev_vals->stats.imcast,
458
 
                                       &new_vals->stats.imcast,
459
 
                                       &prev_vals->old_stats->imcast,
460
 
                                       &need_wrap_check);
461
 
        netsnmp_c64_check32_and_update(&prev_vals->stats.ibcast,
462
 
                                       &new_vals->stats.ibcast,
463
 
                                       &prev_vals->old_stats->ibcast,
464
 
                                       &need_wrap_check);
465
 
        netsnmp_c64_check32_and_update(&prev_vals->stats.obytes,
466
 
                                       &new_vals->stats.obytes,
467
 
                                       &prev_vals->old_stats->obytes,
468
 
                                       &need_wrap_check);
469
 
        netsnmp_c64_check32_and_update(&prev_vals->stats.oucast,
470
 
                                       &new_vals->stats.oucast,
471
 
                                       &prev_vals->old_stats->oucast,
472
 
                                       &need_wrap_check);
473
 
        netsnmp_c64_check32_and_update(&prev_vals->stats.omcast,
474
 
                                       &new_vals->stats.omcast,
475
 
                                       &prev_vals->old_stats->omcast,
476
 
                                       &need_wrap_check);
477
 
        netsnmp_c64_check32_and_update(&prev_vals->stats.obcast,
478
 
                                       &new_vals->stats.obcast,
479
 
                                       &prev_vals->old_stats->obcast,
480
 
                                       &need_wrap_check);
481
 
    
482
 
    /*
483
 
     * if we've decided we no longer need to check wraps, free old stats
484
 
     */
485
 
    if (0 == need_wrap_check) {
486
 
        SNMP_FREE(prev_vals->old_stats);
487
 
    }
488
 
    else {
489
 
        /*
490
 
         * update old stats from new stats.
491
 
         * careful - old_stats is a pointer to stats...
492
 
         */
493
 
        memcpy(prev_vals->old_stats, &new_vals->stats, sizeof(new_vals->stats));
494
 
    }
495
 
    
496
 
    return 0;
497
 
}
498
 
 
499
 
/**
500
 
 * copy interface entry data (after checking for counter wraps)
501
 
 *
502
 
 * @retval -2 : malloc failed
503
 
 * @retval -1 : interfaces not the same
504
 
 * @retval  0 : no error
505
 
 */
506
 
int
507
 
netsnmp_access_interface_entry_copy(netsnmp_interface_entry * lhs,
508
 
                                    netsnmp_interface_entry * rhs)
509
 
{
510
 
    DEBUGMSGTL(("access:interface", "copy\n"));
511
 
    
512
 
    if ((NULL == lhs) || (NULL == rhs) ||
513
 
        (NULL == lhs->name) || (NULL == rhs->name) ||
514
 
        (0 != strncmp(lhs->name, rhs->name, strlen(rhs->name))))
515
 
        return -1;
516
 
 
517
 
    /*
518
 
     * update stats
519
 
     */
520
 
    netsnmp_access_interface_entry_update_stats(lhs, rhs);
521
 
 
522
 
    /*
523
 
     * update data
524
 
     */
525
 
    lhs->ns_flags = rhs->ns_flags;
526
 
    if((NULL != lhs->descr) && (NULL != rhs->descr) &&
527
 
       (0 == strcmp(lhs->descr, rhs->descr)))
528
 
        ;
529
 
    else {
530
 
        if (NULL != lhs->descr)
531
 
            SNMP_FREE(lhs->descr);
532
 
        if (rhs->descr) {
533
 
            lhs->descr = strdup(rhs->descr);
534
 
            if(NULL == lhs->descr)
535
 
                return -2;
536
 
        }
537
 
    }
538
 
    lhs->type = rhs->type;
539
 
    lhs->speed = rhs->speed;
540
 
    lhs->speed_high = rhs->speed_high;
541
 
    lhs->mtu = rhs->mtu;
542
 
    lhs->discontinuity = rhs->discontinuity;
543
 
    lhs->oper_status = rhs->oper_status;
544
 
    lhs->promiscuous = rhs->promiscuous;
545
 
    lhs->connector_present = rhs->connector_present;
546
 
    lhs->os_flags = rhs->os_flags;
547
 
    if(lhs->paddr_len == rhs->paddr_len) {
548
 
        if(rhs->paddr_len)
549
 
            memcpy(lhs->paddr,rhs->paddr,rhs->paddr_len);
550
 
    } else {
551
 
        if (NULL != lhs->paddr)
552
 
            SNMP_FREE(lhs->paddr);
553
 
        if (rhs->paddr) {
554
 
            lhs->paddr = malloc(rhs->paddr_len);
555
 
            if(NULL == lhs->paddr)
556
 
                return -2;
557
 
            memcpy(lhs->paddr,rhs->paddr,rhs->paddr_len);
558
 
        }
559
 
    }
560
 
    lhs->paddr_len = rhs->paddr_len;
561
 
    
562
 
    return 0;
563
 
}
564
 
 
565
 
void
566
 
netsnmp_access_interface_entry_guess_speed(netsnmp_interface_entry *entry)
567
 
{
568
 
    if (entry->type == IANAIFTYPE_ETHERNETCSMACD)
569
 
        entry->speed = 10000000;
570
 
    else if (entry->type == IANAIFTYPE_SOFTWARELOOPBACK)
571
 
        entry->speed = 10000000;
572
 
    else if (entry->type == IANAIFTYPE_ISO88025TOKENRING)
573
 
        entry->speed = 4000000;
574
 
    else
575
 
        entry->speed = 0;
576
 
}
577
 
 
578
 
netsnmp_conf_if_list *
579
 
netsnmp_access_interface_entry_overrides_get(const char * name)
580
 
{
581
 
    netsnmp_conf_if_list * if_ptr;
582
 
 
583
 
    netsnmp_assert(1 == _access_interface_init);
584
 
    if(NULL == name)
585
 
        return NULL;
586
 
 
587
 
    for (if_ptr = conf_list; if_ptr; if_ptr = if_ptr->next)
588
 
        if (!strcmp(if_ptr->name, name))
589
 
            break;
590
 
 
591
 
    return if_ptr;
592
 
}
593
 
 
594
 
void
595
 
netsnmp_access_interface_entry_overrides(netsnmp_interface_entry *entry)
596
 
{
597
 
    netsnmp_conf_if_list * if_ptr;
598
 
 
599
 
    netsnmp_assert(1 == _access_interface_init);
600
 
    if (NULL == entry)
601
 
        return;
602
 
 
603
 
    /*
604
 
     * enforce mib size limit
605
 
     */
606
 
    if(entry->descr && (strlen(entry->descr) > 255))
607
 
        entry->descr[255] = 0;
608
 
 
609
 
    if_ptr =
610
 
        netsnmp_access_interface_entry_overrides_get(entry->name);
611
 
    if (if_ptr) {
612
 
        entry->type = if_ptr->type;
613
 
        entry->speed = if_ptr->speed;
614
 
    }
615
 
}
616
 
 
617
 
/**---------------------------------------------------------------------*/
618
 
/*
619
 
 * interface config token
620
 
 */
621
 
/**
622
 
 */
623
 
static void
624
 
_parse_interface_config(const char *token, char *cptr)
625
 
{
626
 
    netsnmp_conf_if_list   *if_ptr, *if_new;
627
 
    char                   *name, *type, *speed, *ecp;
628
 
    char                   *st;
629
 
 
630
 
    name = strtok_r(cptr, " \t", &st);
631
 
    if (!name) {
632
 
        config_perror("Missing NAME parameter");
633
 
        return;
634
 
    }
635
 
    type = strtok_r(NULL, " \t", &st);
636
 
    if (!type) {
637
 
        config_perror("Missing TYPE parameter");
638
 
        return;
639
 
    }
640
 
    speed = strtok_r(NULL, " \t", &st);
641
 
    if (!speed) {
642
 
        config_perror("Missing SPEED parameter");
643
 
        return;
644
 
    }
645
 
    if_ptr = conf_list;
646
 
    while (if_ptr)
647
 
        if (strcmp(if_ptr->name, name))
648
 
            if_ptr = if_ptr->next;
649
 
        else
650
 
            break;
651
 
    if (if_ptr)
652
 
        config_pwarn("Duplicate interface specification");
653
 
    if_new = SNMP_MALLOC_TYPEDEF(netsnmp_conf_if_list);
654
 
    if (!if_new) {
655
 
        config_perror("Out of memory");
656
 
        return;
657
 
    }
658
 
    if_new->speed = strtoul(speed, &ecp, 0);
659
 
    if (*ecp) {
660
 
        config_perror("Bad SPEED value");
661
 
        free(if_new);
662
 
        return;
663
 
    }
664
 
    if_new->type = strtol(type, &ecp, 0);
665
 
    if (*ecp || if_new->type < 0) {
666
 
        config_perror("Bad TYPE");
667
 
        free(if_new);
668
 
        return;
669
 
    }
670
 
    if_new->name = strdup(name);
671
 
    if (!if_new->name) {
672
 
        config_perror("Out of memory");
673
 
        free(if_new);
674
 
        return;
675
 
    }
676
 
    if_new->next = conf_list;
677
 
    conf_list = if_new;
678
 
}
679
 
 
680
 
static void
681
 
_free_interface_config(void)
682
 
{
683
 
    netsnmp_conf_if_list   *if_ptr = conf_list, *if_next;
684
 
    while (if_ptr) {
685
 
        if_next = if_ptr->next;
686
 
        free(if_ptr->name);
687
 
        free(if_ptr);
688
 
        if_ptr = if_next;
689
 
    }
690
 
    conf_list = NULL;
691
 
}