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

« back to all changes in this revision

Viewing changes to agent/mibgroup/if-mib/ifXTable/ifXTable.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
1
/*
2
2
 * Note: this file originally auto-generated by mib2c using
3
 
 *       version : 1.32 $ of : mfd-top.m2c,v $ 
 
3
 *       version : 1.48 $ of : mfd-top.m2c,v $ 
4
4
 *
5
 
 * $Id: ifXTable.c,v 1.12.2.5 2006/01/15 14:16:06 rstory Exp $
 
5
 * $Id: ifXTable.c,v 1.20.2.3 2006/01/25 16:26:38 dts12 Exp $
6
6
 */
7
 
/** \mainpage MFD helper for ifXTable
 
7
/** \page MFD helper for ifXTable
8
8
 *
9
9
 * \section intro Introduction
10
10
 * Introductory text.
28
28
 
29
29
#include "ifXTable_interface.h"
30
30
 
31
 
#define LINE_TERM_CHAR '$'
32
 
 
33
31
/*
34
32
 * not sure if we want to support set for promiscuous mode, because
35
33
 * 1) careful thought should go into any settable object that performs
43
41
int             ifXTable_oid_size = OID_LENGTH(ifXTable_oid);
44
42
const char     *row_token = "ifXTable";
45
43
 
46
 
void            initialize_table_ifXTable(void);
47
 
 
48
 
static void     _ifXTable_restore(const char *token, char *buf);
49
 
static int      _ifXTable_save(int majorID, int minorID, void *serverarg,
50
 
                               void *clientarg);
51
 
 
52
 
extern netsnmp_container *_ifXTable_container_get(void);
 
44
ifXTable_registration ifXTable_user_context;
53
45
 
54
46
/**
55
47
 * Initializes the ifXTable module
66
58
    /*
67
59
     * here we initialize all the tables we're planning on supporting
68
60
     */
69
 
    if (should_init("ifXTable"))
70
 
        initialize_table_ifXTable();
 
61
    init_ifTable();
71
62
 
72
63
}                               /* init_ifXTable */
73
64
 
78
69
void
79
70
initialize_table_ifXTable(void)
80
71
{
81
 
    ifXTable_registration_ptr user_context;
 
72
    ifXTable_registration *user_context;
82
73
    u_long          flags;
83
 
    int             rc;
84
74
 
85
75
    DEBUGMSGTL(("verbose:ifXTable:initialize_table_ifXTable", "called\n"));
86
76
 
114
104
     * if there is no container, bail. otherwise, register the callbacks
115
105
     * for persistent storage.
116
106
     */
117
 
    if (NULL == _ifXTable_container_get())
118
 
        return; /* msg already logged */
119
 
 
120
 
    register_config_handler(NULL, "ifXTable", _ifXTable_restore, NULL,
121
 
                            NULL);
122
 
    rc = snmp_register_callback(SNMP_CALLBACK_LIBRARY,
123
 
                                SNMP_CALLBACK_STORE_DATA, _ifXTable_save,
124
 
                                _ifXTable_container_get());
125
 
    if (rc != SNMP_ERR_NOERROR)
126
 
        snmp_log(LOG_ERR, "error registering for STORE_DATA callback "
127
 
                 "in initialize_table_ifXTable\n");
 
107
    if (NULL == ifTable_container_get())
 
108
        return;                 /* msg already logged */
128
109
 
129
110
}                               /* initialize_table_ifXTable */
130
111
 
131
112
/**
132
 
 * extra context initialization
 
113
 * extra context initialization (eg default values)
133
114
 *
134
115
 * @param rowreq_ctx    : row request context
135
116
 * @param user_init_ctx : void pointer for user (parameter to rowreq_ctx_allocate)
146
127
    netsnmp_assert(NULL != rowreq_ctx);
147
128
 
148
129
    /*
149
 
     * TODO:210:o: |-> Perform extra ifXTable rowreq initialization.
 
130
     * TODO:210:o: |-> Perform extra ifXTable rowreq initialization. (eg DEFVALS)
150
131
     * should never get here - ifTable should handle this
151
132
     */
152
133
    netsnmp_assert(0);
153
134
 
154
 
    return MFD_SUCCESS;
 
135
    return MFD_ERROR;
155
136
}                               /* ifXTable_rowreq_ctx_init */
156
137
 
157
138
/**
176
157
}                               /* ifXTable_rowreq_ctx_cleanup */
177
158
 
178
159
/**
 
160
 * the *_should_save routine is called to determine if a row
 
161
 * should be stored persistently.
 
162
 *
 
163
 * Note that this is not a 'dirty' check (i.e. if a row has changed),
 
164
 * but a check for volatile rows that should not be saved between
 
165
 * restarts.
 
166
 *
 
167
 * @param rowreq_ctx
 
168
 * 
 
169
 * @return 1 if the row should be stored
 
170
 * @return 0 if the row should not be stored
 
171
 */
 
172
int
 
173
ifXTable_container_should_save(ifXTable_rowreq_ctx * rowreq_ctx)
 
174
{
 
175
 
 
176
    return 1;                   /* save the row */
 
177
}
 
178
 
 
179
/**
179
180
 * pre-request callback
180
181
 *
181
 
 *
 
182
 * @param user_context
182
183
 * @retval MFD_SUCCESS              : success.
183
184
 * @retval MFD_ERROR                : other error
184
185
 */
185
186
int
186
 
ifXTable_pre_request(ifXTable_registration_ptr user_context)
 
187
ifXTable_pre_request(ifXTable_registration * user_context)
187
188
{
188
189
    DEBUGMSGTL(("verbose:ifXTable:ifXTable_pre_request", "called\n"));
189
190
 
197
198
/**
198
199
 * post-request callback
199
200
 *
 
201
 * Note:
 
202
 *   New rows have been inserted into the container, and
 
203
 *   deleted rows have been removed from the container and
 
204
 *   released.
 
205
 *
 
206
 * @param user_context
 
207
 * @param rc : MFD_SUCCESS if all requests succeeded
200
208
 *
201
209
 * @retval MFD_SUCCESS : success.
202
210
 * @retval MFD_ERROR   : other error (ignored)
203
211
 */
204
212
int
205
 
ifXTable_post_request(ifXTable_registration_ptr user_context)
 
213
ifXTable_post_request(ifXTable_registration * user_context, int rc)
206
214
{
207
215
    DEBUGMSGTL(("verbose:ifXTable:ifXTable_post_request", "called\n"));
208
216
 
209
217
    /*
210
 
     * TODO:511:o: Perform ifXTable pos-request actions.
211
 
     */
 
218
     * TODO:511:o: Perform ifXTable post-request actions.
 
219
     */
 
220
 
 
221
    /*
 
222
     * check to set if any rows were changed.
 
223
     */
 
224
    if (ifXTable_dirty_get()) {
 
225
        /*
 
226
         * check if request was successful. If so, this would be
 
227
         * a good place to save data to its persistent store.
 
228
         */
 
229
        if (MFD_SUCCESS == rc) {
 
230
            /*
 
231
             * save changed rows, if you haven't already
 
232
             */
 
233
            snmp_store(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
 
234
                                             NETSNMP_DS_LIB_APPTYPE));
 
235
        }
 
236
 
 
237
        ifXTable_dirty_set(0);  /* clear table dirty flag */
 
238
    }
212
239
 
213
240
    return MFD_SUCCESS;
214
241
}                               /* ifXTable_post_request */
222
249
 **********************************************************************
223
250
 **********************************************************************/
224
251
/*
225
 
 * ifXTable is subid 1 of ifMIBObjects.
 
252
 * IF-MIB::ifXTable is subid 1 of ifMIBObjects.
226
253
 * Its status is Current.
227
254
 * OID: .1.3.6.1.2.1.31.1.1, length: 9
228
255
 */
229
256
 
 
257
/*
 
258
 * ---------------------------------------------------------------------
 
259
 * * TODO:200:r: Implement ifXTable data context functions.
 
260
 */
230
261
 
231
262
 
232
263
/**
233
264
 * set mib index(es)
234
265
 *
235
266
 * @param tbl_idx mib index structure
 
267
 * @param ifIndex_val
236
268
 *
237
269
 * @retval MFD_SUCCESS     : success.
238
270
 * @retval MFD_ERROR       : other error.
263
295
 * set row context indexes
264
296
 *
265
297
 * @param reqreq_ctx the row context that needs updated indexes
 
298
 * @param ifIndex_val
266
299
 *
267
300
 * @retval MFD_SUCCESS     : success.
268
301
 * @retval MFD_ERROR       : other error.
357
390
 */
358
391
int
359
392
ifName_get(ifXTable_rowreq_ctx * rowreq_ctx, char **ifName_val_ptr_ptr,
360
 
           size_t *ifName_val_ptr_len_ptr)
 
393
           size_t * ifName_val_ptr_len_ptr)
361
394
{
362
395
    int             tmp_len;
 
396
 
363
397
   /** we should have a non-NULL pointer and enough storage */
364
398
    netsnmp_assert((NULL != ifName_val_ptr_ptr)
365
399
                   && (NULL != *ifName_val_ptr_ptr));
372
406
 
373
407
    /*
374
408
     * TODO:231:o: |-> Extract the current value of the ifName data.
375
 
     * set (* ifName_val_ptr_ptr ) and (* ifName_val_ptr_len_ptr ) from rowreq_ctx->data
 
409
     * copy (* ifName_val_ptr_ptr ) data and (* ifName_val_ptr_len_ptr ) from rowreq_ctx->data
376
410
     */
377
411
    /*
378
412
     * make sure there is enough space for ifName data
379
413
     */
380
414
    tmp_len = strlen(rowreq_ctx->data.ifName);
381
 
    if ((NULL == (*ifName_val_ptr_ptr))
382
 
        || ((*ifName_val_ptr_len_ptr) < tmp_len)) {
 
415
    if ((NULL == (*ifName_val_ptr_ptr)) ||
 
416
        ((*ifName_val_ptr_len_ptr) < tmp_len)) {
383
417
        /*
384
418
         * allocate space for ifName data
385
419
         */
386
 
        (*ifName_val_ptr_ptr) =
387
 
            malloc(tmp_len * sizeof((*ifName_val_ptr_ptr)[0]));
 
420
        (*ifName_val_ptr_ptr) = malloc(tmp_len);
388
421
        if (NULL == (*ifName_val_ptr_ptr)) {
389
422
            snmp_log(LOG_ERR, "could not allocate memory\n");
390
423
            return MFD_ERROR;
391
424
        }
392
425
    }
393
426
    (*ifName_val_ptr_len_ptr) = tmp_len;
394
 
    memcpy((*ifName_val_ptr_ptr), rowreq_ctx->data.ifName,
395
 
           (*ifName_val_ptr_len_ptr) * sizeof((*ifName_val_ptr_ptr)[0]));
 
427
    memcpy((*ifName_val_ptr_ptr), rowreq_ctx->data.ifName, tmp_len);
396
428
 
397
429
    return MFD_SUCCESS;
398
430
}                               /* ifName_get */
451
483
 
452
484
    /*
453
485
     * TODO:231:o: |-> Extract the current value of the ifInMulticastPkts data.
454
 
     * set (* ifInMulticastPkts_val_ptr ) from rowreq_ctx->data
 
486
     * copy (* ifInMulticastPkts_val_ptr ) from rowreq_ctx->data
455
487
     */
456
488
    (*ifInMulticastPkts_val_ptr) = rowreq_ctx->data.ifInMulticastPkts;
457
489
 
510
542
 
511
543
    /*
512
544
     * TODO:231:o: |-> Extract the current value of the ifInBroadcastPkts data.
513
 
     * set (* ifInBroadcastPkts_val_ptr ) from rowreq_ctx->data
 
545
     * copy (* ifInBroadcastPkts_val_ptr ) from rowreq_ctx->data
514
546
     */
515
547
    (*ifInBroadcastPkts_val_ptr) = rowreq_ctx->data.ifInBroadcastPkts;
516
548
 
571
603
 
572
604
    /*
573
605
     * TODO:231:o: |-> Extract the current value of the ifOutMulticastPkts data.
574
 
     * set (* ifOutMulticastPkts_val_ptr ) from rowreq_ctx->data
 
606
     * copy (* ifOutMulticastPkts_val_ptr ) from rowreq_ctx->data
575
607
     */
576
608
    (*ifOutMulticastPkts_val_ptr) = rowreq_ctx->data.ifOutMulticastPkts;
577
609
 
632
664
 
633
665
    /*
634
666
     * TODO:231:o: |-> Extract the current value of the ifOutBroadcastPkts data.
635
 
     * set (* ifOutBroadcastPkts_val_ptr ) from rowreq_ctx->data
 
667
     * copy (* ifOutBroadcastPkts_val_ptr ) from rowreq_ctx->data
636
668
     */
637
669
    (*ifOutBroadcastPkts_val_ptr) = rowreq_ctx->data.ifOutBroadcastPkts;
638
670
 
1162
1194
 
1163
1195
    /*
1164
1196
     * TODO:231:o: |-> Extract the current value of the ifLinkUpDownTrapEnable data.
1165
 
     * set (* ifLinkUpDownTrapEnable_val_ptr ) from rowreq_ctx->data
 
1197
     * copy (* ifLinkUpDownTrapEnable_val_ptr ) from rowreq_ctx->data
1166
1198
     */
1167
1199
    (*ifLinkUpDownTrapEnable_val_ptr) =
1168
1200
        rowreq_ctx->data.ifLinkUpDownTrapEnable;
1222
1254
 
1223
1255
    /*
1224
1256
     * TODO:231:o: |-> Extract the current value of the ifHighSpeed data.
1225
 
     * set (* ifHighSpeed_val_ptr ) from rowreq_ctx->data
 
1257
     * copy (* ifHighSpeed_val_ptr ) from rowreq_ctx->data
1226
1258
     */
1227
1259
    (*ifHighSpeed_val_ptr) = rowreq_ctx->data.ifHighSpeed;
1228
1260
 
1284
1316
 
1285
1317
    /*
1286
1318
     * TODO:231:o: |-> Extract the current value of the ifPromiscuousMode data.
1287
 
     * set (* ifPromiscuousMode_val_ptr ) from rowreq_ctx->data
 
1319
     * copy (* ifPromiscuousMode_val_ptr ) from rowreq_ctx->data
1288
1320
     */
1289
1321
    /** this is coming from the interface entry, which is a boolean */
1290
1322
    if (rowreq_ctx->data.ifPromiscuousMode)
1343
1375
 
1344
1376
    /*
1345
1377
     * TODO:231:o: |-> Extract the current value of the ifConnectorPresent data.
1346
 
     * set (* ifConnectorPresent_val_ptr ) from rowreq_ctx->data
 
1378
     * copy (* ifConnectorPresent_val_ptr ) from rowreq_ctx->data
1347
1379
     */
1348
1380
    (*ifConnectorPresent_val_ptr) = rowreq_ctx->data.ifConnectorPresent;
1349
1381
 
1424
1456
 */
1425
1457
int
1426
1458
ifAlias_get(ifXTable_rowreq_ctx * rowreq_ctx, char **ifAlias_val_ptr_ptr,
1427
 
            size_t *ifAlias_val_ptr_len_ptr)
 
1459
            size_t * ifAlias_val_ptr_len_ptr)
1428
1460
{
1429
1461
   /** we should have a non-NULL pointer and enough storage */
1430
1462
    netsnmp_assert((NULL != ifAlias_val_ptr_ptr)
1438
1470
 
1439
1471
    /*
1440
1472
     * TODO:231:o: |-> Extract the current value of the ifAlias data.
1441
 
     * set (* ifAlias_val_ptr_ptr ) and (* ifAlias_val_ptr_len_ptr ) from rowreq_ctx->data
 
1473
     * copy (* ifAlias_val_ptr_ptr ) data and (* ifAlias_val_ptr_len_ptr ) from rowreq_ctx->data
1442
1474
     */
1443
1475
    /*
1444
1476
     * make sure there is enough space for ifAlias data
1445
1477
     */
1446
 
    if ((NULL == (*ifAlias_val_ptr_ptr))
1447
 
        || ((*ifAlias_val_ptr_len_ptr) < rowreq_ctx->data.ifAlias_len)) {
 
1478
    if ((NULL == (*ifAlias_val_ptr_ptr)) ||
 
1479
        ((*ifAlias_val_ptr_len_ptr) <
 
1480
         (rowreq_ctx->data.ifAlias_len *
 
1481
          sizeof(rowreq_ctx->data.ifAlias[0])))) {
1448
1482
        /*
1449
1483
         * allocate space for ifAlias data
1450
1484
         */
1451
1485
        (*ifAlias_val_ptr_ptr) =
1452
1486
            malloc(rowreq_ctx->data.ifAlias_len *
1453
 
                   sizeof((*ifAlias_val_ptr_ptr)[0]));
 
1487
                   sizeof(rowreq_ctx->data.ifAlias[0]));
1454
1488
        if (NULL == (*ifAlias_val_ptr_ptr)) {
1455
1489
            snmp_log(LOG_ERR, "could not allocate memory\n");
1456
1490
            return MFD_ERROR;
1457
1491
        }
1458
1492
    }
1459
 
    (*ifAlias_val_ptr_len_ptr) = rowreq_ctx->data.ifAlias_len;
 
1493
    (*ifAlias_val_ptr_len_ptr) =
 
1494
        rowreq_ctx->data.ifAlias_len * sizeof(rowreq_ctx->data.ifAlias[0]);
1460
1495
    memcpy((*ifAlias_val_ptr_ptr), rowreq_ctx->data.ifAlias,
1461
 
           (*ifAlias_val_ptr_len_ptr) * sizeof((*ifAlias_val_ptr_ptr)[0]));
 
1496
           rowreq_ctx->data.ifAlias_len *
 
1497
           sizeof(rowreq_ctx->data.ifAlias[0]));
1462
1498
 
1463
1499
    return MFD_SUCCESS;
1464
1500
}                               /* ifAlias_get */
1517
1553
 
1518
1554
    /*
1519
1555
     * TODO:231:o: |-> Extract the current value of the ifCounterDiscontinuityTime data.
1520
 
     * set (* ifCounterDiscontinuityTime_val_ptr ) from rowreq_ctx->data
 
1556
     * copy (* ifCounterDiscontinuityTime_val_ptr ) from rowreq_ctx->data
1521
1557
     */
1522
1558
    (*ifCounterDiscontinuityTime_val_ptr) =
1523
1559
        rowreq_ctx->data.ifCounterDiscontinuityTime;
1536
1572
 **********************************************************************
1537
1573
 **********************************************************************/
1538
1574
/*
1539
 
 * ifXTable is subid 1 of ifMIBObjects.
 
1575
 * IF-MIB::ifXTable is subid 1 of ifMIBObjects.
1540
1576
 * Its status is Current.
1541
1577
 * OID: .1.3.6.1.2.1.31.1.1, length: 9
1542
1578
 */
1645
1681
    /*
1646
1682
     * TODO:451:M: |-> Setup ifXTable undo.
1647
1683
     * set up ifXTable undo information, in preparation for a set.
 
1684
     * Undo storage is in (* ifCounterDiscontinuityTime_val_ptr )*
 
1685
     */
 
1686
 
 
1687
    return rc;
 
1688
}                               /* ifXTable_undo_setup */
 
1689
 
 
1690
/**
 
1691
 * Undo a set request.
 
1692
 *
 
1693
 * This function will be called before the individual node undo
 
1694
 * functions are called. If you need to do any undo that is not
 
1695
 * related to a specific column, you can do it here.
 
1696
 *
 
1697
 * Note that an individual node's undo function will only be called
 
1698
 * if that node is being set to a new value.
 
1699
 *
 
1700
 * If there is anything  specific to a particular column (e.g. releasing
 
1701
 * memory for a string), you should do that setup in the node's undo
 
1702
 * function, so it won't be done unless it is necessary.
 
1703
 *
 
1704
 * @param rowreq_ctx
 
1705
 *        Pointer to the table context (ifXTable_rowreq_ctx)
 
1706
 *
 
1707
 * @retval MFD_SUCCESS : success
 
1708
 * @retval MFD_ERROR   : error. set will fail.
 
1709
 */
 
1710
int
 
1711
ifXTable_undo(ifXTable_rowreq_ctx * rowreq_ctx)
 
1712
{
 
1713
    int             rc = MFD_SUCCESS;
 
1714
 
 
1715
    DEBUGMSGTL(("verbose:ifXTable:ifXTable_undo", "called\n"));
 
1716
 
 
1717
    /** we should have a non-NULL pointer */
 
1718
    netsnmp_assert(NULL != rowreq_ctx);
 
1719
 
 
1720
    /*
 
1721
     * TODO:451:M: |-> ifXTable undo.
 
1722
     * ifXTable undo information, in response to a failed set.
 
1723
     * Undo storage is in (* ifCounterDiscontinuityTime_val_ptr )*
1648
1724
     */
1649
1725
 
1650
1726
    return rc;
1679
1755
 
1680
1756
    /*
1681
1757
     * TODO:452:M: |-> Cleanup ifXTable undo.
 
1758
     * Undo storage is in (* ifCounterDiscontinuityTime_val_ptr )*
1682
1759
     */
1683
1760
 
1684
1761
    return rc;
1692
1769
 *
1693
1770
 * Should you need different behavior depending on which columns were
1694
1771
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
1695
 
 * set. The definitions for the FLAG_* bits can be found in
 
1772
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
1696
1773
 * ifXTable.h.
1697
1774
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
1698
1775
 *
1699
 
 * @param ifXTable_rowreq_ctx
 
1776
 * @param rowreq_ctx
1700
1777
 *        Pointer to the users context.
1701
1778
 *
1702
1779
 * @retval MFD_SUCCESS : success
1731
1808
     * nothing needs to be done. That leaves ifPromiscuosMode,
1732
1809
     * which I'm leery about implementing. Thus, at this point,
1733
1810
     * there is nothing to do except twiddle flag bits.
1734
 
     *
1735
 
     * in keeping with the net-snmp persistence policy, changes are kept
1736
 
     * in memory, and saved to disk when the agent shuts down.
1737
1811
     */
1738
 
    if (save_flags & FLAG_IFLINKUPDOWNTRAPENABLE) {
1739
 
        save_flags &= ~FLAG_IFLINKUPDOWNTRAPENABLE;     /* clear ifLinkUpDownTrapEnable */
 
1812
    if (save_flags & COLUMN_IFLINKUPDOWNTRAPENABLE_FLAG) {
 
1813
        save_flags &= ~COLUMN_IFLINKUPDOWNTRAPENABLE_FLAG;      /* clear ifLinkUpDownTrapEnable */
1740
1814
        /*
1741
1815
         * TODO:482:o: |-> commit column ifLinkUpDownTrapEnable.
1742
1816
         */
1743
1817
        /*
1744
1818
         * set flag, in case we need to undo ifLinkUpDownTrapEnable
1745
1819
         */
1746
 
        rowreq_ctx->column_set_flags |= FLAG_IFLINKUPDOWNTRAPENABLE;
 
1820
        rowreq_ctx->column_set_flags |= COLUMN_IFLINKUPDOWNTRAPENABLE_FLAG;
1747
1821
    }
1748
 
 
1749
 
    if (save_flags & FLAG_IFPROMISCUOUSMODE) {
1750
 
        save_flags &= ~FLAG_IFPROMISCUOUSMODE;  /* clear ifPromiscuousMode */
1751
1822
#ifdef NETSNMP_ENABLE_PROMISCUOUSMODE_SET
 
1823
    if (save_flags & COLUMN_IFPROMISCUOUSMODE_FLAG) {
 
1824
        save_flags &= ~COLUMN_IFPROMISCUOUSMODE_FLAG;   /* clear ifPromiscuousMode */
1752
1825
        /*
1753
1826
         * TODO:482:o: |-> commit column ifPromiscuousMode.
1754
1827
         */
1760
1833
            /*
1761
1834
             * set flag, in case we need to undo ifPromiscuousMode
1762
1835
             */
1763
 
            rowreq_ctx->column_set_flags |= FLAG_IFPROMISCUOUSMODE;
 
1836
            rowreq_ctx->column_set_flags |= COLUMN_IFPROMISCUOUSMODE_FLAG;
1764
1837
        }
1765
 
#endif
1766
1838
    }
 
1839
#endif                          /* NETSNMP_ENABLE_PROMISCUOUSMODE_SET */
1767
1840
 
1768
 
    if (save_flags & FLAG_IFALIAS) {
1769
 
        save_flags &= ~FLAG_IFALIAS;    /* clear ifAlias */
1770
 
        /*
1771
 
         * TODO:482:o: |-> commit column ifAlias.
1772
 
         */
 
1841
    if (save_flags & COLUMN_IFALIAS_FLAG) {
 
1842
        save_flags &= ~COLUMN_IFALIAS_FLAG;     /* clear ifAlias */
1773
1843
        /*
1774
1844
         * set flag, in case we need to undo ifAlias
1775
1845
         */
1776
 
        rowreq_ctx->column_set_flags |= FLAG_IFALIAS;
 
1846
        rowreq_ctx->column_set_flags |= COLUMN_IFALIAS_FLAG;
 
1847
    }
 
1848
 
 
1849
    /*
 
1850
     * if we successfully commited this row, set the dirty flag.
 
1851
     */
 
1852
    if (MFD_SUCCESS == rc) {
 
1853
        rowreq_ctx->rowreq_flags |= MFD_ROW_DIRTY;
1777
1854
    }
1778
1855
 
1779
1856
    if (save_flags) {
1790
1867
 *
1791
1868
 * Should you need different behavior depending on which columns were
1792
1869
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
1793
 
 * set. The definitions for the FLAG_* bits can be found in
 
1870
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
1794
1871
 * ifXTable.h.
1795
1872
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
1796
1873
 *
1797
 
 * @param ifXTable_rowreq_ctx
 
1874
 * @param rowreq_ctx
1798
1875
 *        Pointer to the users context.
1799
1876
 *
1800
1877
 * @retval MFD_SUCCESS : success
1815
1892
     * check the column's flag in rowreq_ctx->column_set_flags to see
1816
1893
     * if it was set during commit, then undo it.
1817
1894
     *
1818
 
     * eg: if (rowreq_ctx->column_set_flags & FLAG_) {}
1819
 
     */
 
1895
     * eg: if (rowreq_ctx->column_set_flags & COLUMN__FLAG) {}
 
1896
     */
 
1897
 
 
1898
 
 
1899
    /*
 
1900
     * if we successfully un-commited this row, clear the dirty flag.
 
1901
     */
 
1902
    if (MFD_SUCCESS == rc) {
 
1903
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
 
1904
    }
1820
1905
 
1821
1906
    return rc;
1822
1907
}                               /* ifXTable_undo_commit */
1823
1908
 
1824
1909
/*
1825
 
 * TODO:420:r: Implement ifXTable index validation.
1826
 
 */
1827
 
/*---------------------------------------------------------------------
1828
 
 * IF-MIB::ifEntry.ifIndex
1829
 
 * ifIndex is subid 1 of ifEntry.
1830
 
 * Its status is Current, and its access level is ReadOnly.
1831
 
 * OID: .1.3.6.1.2.1.2.2.1.1
1832
 
 * Description:
1833
 
A unique value, greater than zero, for each interface.  It
1834
 
            is recommended that values are assigned contiguously
1835
 
            starting from 1.  The value for each interface sub-layer
1836
 
            must remain constant at least from one re-initialization of
1837
 
            the entity's network management system to the next re-
1838
 
            initialization.
1839
 
 *
1840
 
 * Attributes:
1841
 
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
1842
 
 *   readable   1     iscolumn 1     ranges 1      hashint   1
1843
 
 *   settable   0
1844
 
 *   hint: d
1845
 
 *
1846
 
 * Ranges:  1 - 2147483647;
1847
 
 *
1848
 
 * Its syntax is InterfaceIndex (based on perltype INTEGER32)
1849
 
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
1850
 
 */
1851
 
/*
1852
1910
 * TODO:440:M: Implement ifXTable node value checks.
1853
1911
 * TODO:450:M: Implement ifXTable undo functions.
1854
1912
 * TODO:460:M: Implement ifXTable set functions.
2297
2355
 *
2298
2356
 * The following checks have already been done for you:
2299
2357
 *    The syntax is ASN_OCTET_STR
 
2358
 *    The length is < sizeof(rowreq_ctx->data.ifAlias).
2300
2359
 *    The length is in (one of) the range set(s):  0 - 64
2301
2360
 *
2302
2361
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
2388
2447
     * TODO:461:M: |-> Set ifAlias value.
2389
2448
     * set ifAlias value in rowreq_ctx->data
2390
2449
     */
2391
 
    memcpy(rowreq_ctx->data.ifAlias, ifAlias_val_ptr,
2392
 
           ifAlias_val_ptr_len * sizeof(ifAlias_val_ptr[0]));
2393
 
    rowreq_ctx->data.ifAlias_len = ifAlias_val_ptr_len;
 
2450
    memcpy(rowreq_ctx->data.ifAlias, ifAlias_val_ptr, ifAlias_val_ptr_len);
 
2451
    /** convert bytes to number of char */
 
2452
    rowreq_ctx->data.ifAlias_len =
 
2453
        ifAlias_val_ptr_len / sizeof(ifAlias_val_ptr[0]);
2394
2454
 
2395
2455
    return MFD_SUCCESS;
2396
2456
}                               /* ifAlias_set */
2434
2494
 *
2435
2495
 * Should you need different behavior depending on which columns were
2436
2496
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
2437
 
 * set. The definitions for the FLAG_* bits can be found in
 
2497
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
2438
2498
 * ifXTable.h.
2439
2499
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
2440
2500
 *
2462
2522
 
2463
2523
/** @} */
2464
2524
/** @{ */
2465
 
 
2466
 
int
2467
 
_ifXTable_row_save(ifXTable_rowreq_ctx * rowreq_ctx, void *type)
2468
 
{
2469
 
    char           *buf, *line;
2470
 
    int             size;
2471
 
 
2472
 
    netsnmp_assert(NULL != rowreq_ctx);
2473
 
 
2474
 
    /*
2475
 
     * allocate space for data. Remeber, data will be stored in
2476
 
     * ASCII form, so you need to allow for that. Here are some
2477
 
     * general guidelines:
2478
 
     *
2479
 
     * Object ID :  12 * len (ASCII len of max int + 1 for .)
2480
 
     * Octet String: (2 * len) + 2 (2 ASCII chars per byte + "0x")
2481
 
     * Integers :  12 (ASCII len for smallest negative number)
2482
 
     */
2483
 
    size = sizeof(row_token) + 1 +      /* 'ifXTable ' */
2484
 
        13 +                    /* ifIndex value + ' ' */
2485
 
        13 +                    /* col #, + ':' */
2486
 
        (rowreq_ctx->data.ifAlias_len * 2) + 2 +      /* [0|1] + ' ' */
2487
 
        4;                      /* '\n\0' & possible quoting */
2488
 
 
2489
 
    /*
2490
 
     * allocate memory for the line
2491
 
     */
2492
 
    line = buf = calloc(1, size);
2493
 
    if (NULL == buf) {
2494
 
        snmp_log(LOG_ERR, "error allocating memory while saving row\n");
2495
 
        return SNMP_ERR_GENERR;
2496
 
    }
2497
 
 
2498
 
    /*
2499
 
     * build the line
2500
 
     */
2501
 
    buf += sprintf(buf, "%s ", row_token);
2502
 
    buf = read_config_save_objid(buf, rowreq_ctx->oid_idx.oids,
2503
 
                                 rowreq_ctx->oid_idx.len);
2504
 
    if (NULL == buf) {
2505
 
        snmp_log(LOG_ERR, "error saving row to persistent file\n");
2506
 
        free(line);
2507
 
        return SNMP_ERR_GENERR;
2508
 
    }
2509
 
    *buf++ = ' ';
2510
 
 
2511
 
    /*
2512
 
     * prefix with column number, so we don't ever depend on
2513
 
     * order saved.
2514
 
     */
2515
 
    buf += sprintf(buf, "%u:", COLUMN_IFALIAS);
2516
 
    buf = read_config_save_octet_string(buf, rowreq_ctx->data.ifAlias,
2517
 
                                        rowreq_ctx->data.ifAlias_len);
2518
 
    *buf++ = ' ';
2519
 
 
2520
 
    /*
2521
 
     * prefix with column number, so we don't ever depend on
2522
 
     * order saved.
2523
 
     */
2524
 
    buf += sprintf(buf, "%u:%1lu ", COLUMN_IFLINKUPDOWNTRAPENABLE,
2525
 
                   rowreq_ctx->data.ifLinkUpDownTrapEnable);
2526
 
 
2527
 
    /*
2528
 
     * terminate and store the line
2529
 
     */
2530
 
    sprintf(buf, "%c\n", LINE_TERM_CHAR);
2531
 
    DEBUGMSGTL(("ifXTable:save", "saving line '%s'\n", line));
2532
 
    read_config_store((char *) type, line);
2533
 
 
2534
 
    /*
2535
 
     * free memory
2536
 
     */
2537
 
    free(line);
2538
 
 
2539
 
    return SNMP_ERR_NOERROR;
2540
 
 
2541
 
}
2542
 
 
2543
 
static int
2544
 
_ifXTable_save(int majorID, int minorID, void *serverarg, void *clientarg)
2545
 
{
2546
 
    char           *appname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
2547
 
                                                    NETSNMP_DS_LIB_APPTYPE);
2548
 
 
2549
 
    /*
2550
 
     * save all rows
2551
 
     */
2552
 
    CONTAINER_FOR_EACH((netsnmp_container *) clientarg,
2553
 
                       (netsnmp_container_obj_func *)
2554
 
                       _ifXTable_row_save, appname);
2555
 
 
2556
 
    /*
2557
 
     * never fails 
2558
 
     */
2559
 
    return SNMPERR_SUCCESS;
2560
 
}
2561
 
 
2562
 
 
2563
 
static void
2564
 
_ifXTable_restore(const char *token, char *buf)
2565
 
{
2566
 
    ifXTable_rowreq_ctx *context;
2567
 
    netsnmp_container *container;
2568
 
    netsnmp_index   index;
2569
 
    u_int           col, len;
2570
 
 
2571
 
    if (strncmp(token, row_token, sizeof(row_token)) != 0) {
2572
 
        snmp_log(LOG_ERR, "unknown token in _ifXTable_restore\n");
2573
 
        return;
2574
 
    }
2575
 
 
2576
 
    container = _ifXTable_container_get();
2577
 
    if (NULL == container) {
2578
 
        snmp_log(LOG_ERR, "null container in _ifXTable_restore\n");
2579
 
        return;
2580
 
    }
2581
 
 
2582
 
    DEBUGMSGTL(("ifXTable:restore", "parsing line '%s'\n", buf));
2583
 
 
2584
 
    /*
2585
 
     * pull out index and find row
2586
 
     */
2587
 
    index.oids = NULL;
2588
 
    buf = read_config_read_objid(buf, &index.oids, &index.len);
2589
 
    if (NULL == buf) {
2590
 
        snmp_log(LOG_ERR,
2591
 
                 "error reading row index in _ifXTable_restore\n");
2592
 
        return;
2593
 
    }
2594
 
    context = CONTAINER_FIND(container, &index);
2595
 
    if (NULL == context) {
2596
 
        snmp_log(LOG_ERR,
2597
 
                 "error finding row index in _ifXTable_restore\n");
2598
 
        return;
2599
 
    }
2600
 
 
2601
 
    /*
2602
 
     * get each column
2603
 
     */
2604
 
    buf = skip_white(buf);
2605
 
    if ((NULL == buf) || !isdigit(*buf)) {
2606
 
        snmp_log(LOG_ERR, "unexpected format1 in _ifXTable_restore\n");
2607
 
        return;
2608
 
    }
2609
 
 
2610
 
    /*
2611
 
     * extract column, skip ':'
2612
 
     */
2613
 
    col = (u_int) strtol(buf, &buf, 10);
2614
 
    if ((NULL == buf) || (*buf != ':') || (COLUMN_IFALIAS != col)) {
2615
 
        snmp_log(LOG_ERR, "unexpected format2 in _ifXTable_restore\n");
2616
 
        return;
2617
 
    }
2618
 
    ++buf;                      /* skip : */
2619
 
 
2620
 
    /*
2621
 
     * parse value
2622
 
     */
2623
 
    DEBUGMSGTL(("ifXTable:restore", "parsing column %d\n", col));
2624
 
    context->data.ifAlias_len = sizeof(context->data.ifAlias);
2625
 
    buf = read_config_read_memory(ASN_OCTET_STR, buf,
2626
 
                                  (char *) &context->data.ifAlias,
2627
 
                                  (size_t *) &context->data.ifAlias_len);
2628
 
 
2629
 
    /*
2630
 
     * extract column, skip ':'
2631
 
     */
2632
 
    col = (u_int) strtol(buf, &buf, 10);
2633
 
    if ((NULL == buf) || (*buf != ':') ||
2634
 
        (COLUMN_IFLINKUPDOWNTRAPENABLE != col)) {
2635
 
        snmp_log(LOG_ERR, "unexpected format3 in _ifXTable_restore\n");
2636
 
        return;
2637
 
    }
2638
 
    ++buf;                      /* skip : */
2639
 
 
2640
 
    /*
2641
 
     * parse value
2642
 
     */
2643
 
    DEBUGMSGTL(("ifXTable:restore", "parsing column %d\n", col));
2644
 
    len = sizeof(context->data.ifLinkUpDownTrapEnable);
2645
 
    buf = read_config_read_memory(ASN_INTEGER, buf,
2646
 
                                  (char *) &context->data.
2647
 
                                  ifLinkUpDownTrapEnable, &len);
2648
 
 
2649
 
    /*
2650
 
     * if the pointer is NULL and we didn't reach the
2651
 
     * end of the line, something went wrong. Log message,
2652
 
     * delete the row and bail.
2653
 
     */
2654
 
    if ((buf == NULL) || (*buf != LINE_TERM_CHAR)) {
2655
 
        snmp_log(LOG_ERR, "unexpected format4 in _ifXTable_restore\n");
2656
 
        return;
2657
 
    }
2658
 
}