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

« back to all changes in this revision

Viewing changes to .pc/25_duplicate_iftable.patch/agent/mibgroup/if-mib/data_access/interface.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2010-06-28 14:59:36 UTC
  • mfrom: (1.2.3 upstream) (1.1.12 sid)
  • Revision ID: james.westby@ubuntu.com-20100628145936-cbiallic69pn044g
Tags: 5.4.3~dfsg-1ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Set Ubuntu maintainer address.
  - net-snmp-config: Use bash. (LP: #104738)
  - Removed multiuser option when calling update-rc.d. (LP: #254261)
  - debian/snmpd.init: LSBify the init script.
  - debian/patches/52_fix_snmpcmd_1_typo.patch: Adjust a typo in snmpcmd.1
    (LP: #250459)
  - debian/snmpd.postinst: source debconf before doing work, LP: #589056
  - debian/snmp.preinst, debian/snmp.prerm: kill any/all processes owned by
    snmp user before install/uninstall, LP: #573391
  - Add apport hook (LP: #533603):
  - debian/{snmp,snmpd}.apport: Added.
  - debian/control: Build-depends on dh-apport.
  - debian/rules: 
    + Add --with apport.
    + override_dh_apport to install hook on snmpd package only.
 * Dropped patches:
   - debian/patches/99-fix-ubuntu-div0.patch: Fix dvision by zero.. 

Show diffs side-by-side

added added

removed removed

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