1195972f6Sopenharmony_ci/**
2195972f6Sopenharmony_ci * @file
3195972f6Sopenharmony_ci * Management Information Base II (RFC1213) INTERFACES objects and functions.
4195972f6Sopenharmony_ci */
5195972f6Sopenharmony_ci
6195972f6Sopenharmony_ci/*
7195972f6Sopenharmony_ci * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
8195972f6Sopenharmony_ci * All rights reserved.
9195972f6Sopenharmony_ci *
10195972f6Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
11195972f6Sopenharmony_ci * are permitted provided that the following conditions are met:
12195972f6Sopenharmony_ci *
13195972f6Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice,
14195972f6Sopenharmony_ci *    this list of conditions and the following disclaimer.
15195972f6Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice,
16195972f6Sopenharmony_ci *    this list of conditions and the following disclaimer in the documentation
17195972f6Sopenharmony_ci *    and/or other materials provided with the distribution.
18195972f6Sopenharmony_ci * 3. The name of the author may not be used to endorse or promote products
19195972f6Sopenharmony_ci *    derived from this software without specific prior written permission.
20195972f6Sopenharmony_ci *
21195972f6Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22195972f6Sopenharmony_ci * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23195972f6Sopenharmony_ci * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
24195972f6Sopenharmony_ci * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25195972f6Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26195972f6Sopenharmony_ci * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27195972f6Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28195972f6Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29195972f6Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30195972f6Sopenharmony_ci * OF SUCH DAMAGE.
31195972f6Sopenharmony_ci *
32195972f6Sopenharmony_ci * Author: Dirk Ziegelmeier <dziegel@gmx.de>
33195972f6Sopenharmony_ci *         Christiaan Simons <christiaan.simons@axon.tv>
34195972f6Sopenharmony_ci */
35195972f6Sopenharmony_ci
36195972f6Sopenharmony_ci#include "lwip/snmp.h"
37195972f6Sopenharmony_ci#include "lwip/apps/snmp.h"
38195972f6Sopenharmony_ci#include "lwip/apps/snmp_core.h"
39195972f6Sopenharmony_ci#include "lwip/apps/snmp_mib2.h"
40195972f6Sopenharmony_ci#include "lwip/apps/snmp_table.h"
41195972f6Sopenharmony_ci#include "lwip/apps/snmp_scalar.h"
42195972f6Sopenharmony_ci#include "lwip/netif.h"
43195972f6Sopenharmony_ci#include "lwip/stats.h"
44195972f6Sopenharmony_ci
45195972f6Sopenharmony_ci#include <string.h>
46195972f6Sopenharmony_ci
47195972f6Sopenharmony_ci#if LWIP_SNMP && SNMP_LWIP_MIB2
48195972f6Sopenharmony_ci
49195972f6Sopenharmony_ci#if SNMP_USE_NETCONN
50195972f6Sopenharmony_ci#define SYNC_NODE_NAME(node_name) node_name ## _synced
51195972f6Sopenharmony_ci#define CREATE_LWIP_SYNC_NODE(oid, node_name) \
52195972f6Sopenharmony_ci   static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
53195972f6Sopenharmony_ci#else
54195972f6Sopenharmony_ci#define SYNC_NODE_NAME(node_name) node_name
55195972f6Sopenharmony_ci#define CREATE_LWIP_SYNC_NODE(oid, node_name)
56195972f6Sopenharmony_ci#endif
57195972f6Sopenharmony_ci
58195972f6Sopenharmony_ci
59195972f6Sopenharmony_ci/* --- interfaces .1.3.6.1.2.1.2 ----------------------------------------------------- */
60195972f6Sopenharmony_ci
61195972f6Sopenharmony_cistatic s16_t
62195972f6Sopenharmony_ciinterfaces_get_value(struct snmp_node_instance *instance, void *value)
63195972f6Sopenharmony_ci{
64195972f6Sopenharmony_ci  if (instance->node->oid == 1) {
65195972f6Sopenharmony_ci    s32_t *sint_ptr = (s32_t *)value;
66195972f6Sopenharmony_ci    s32_t num_netifs = 0;
67195972f6Sopenharmony_ci
68195972f6Sopenharmony_ci    struct netif *netif;
69195972f6Sopenharmony_ci    NETIF_FOREACH(netif) {
70195972f6Sopenharmony_ci      num_netifs++;
71195972f6Sopenharmony_ci    }
72195972f6Sopenharmony_ci
73195972f6Sopenharmony_ci    *sint_ptr = num_netifs;
74195972f6Sopenharmony_ci    return sizeof(*sint_ptr);
75195972f6Sopenharmony_ci  }
76195972f6Sopenharmony_ci
77195972f6Sopenharmony_ci  return 0;
78195972f6Sopenharmony_ci}
79195972f6Sopenharmony_ci
80195972f6Sopenharmony_ci/* list of allowed value ranges for incoming OID */
81195972f6Sopenharmony_cistatic const struct snmp_oid_range interfaces_Table_oid_ranges[] = {
82195972f6Sopenharmony_ci  { 1, 0xff } /* netif->num is u8_t */
83195972f6Sopenharmony_ci};
84195972f6Sopenharmony_ci
85195972f6Sopenharmony_cistatic const u8_t iftable_ifOutQLen         = 0;
86195972f6Sopenharmony_ci
87195972f6Sopenharmony_cistatic const u8_t iftable_ifOperStatus_up   = 1;
88195972f6Sopenharmony_cistatic const u8_t iftable_ifOperStatus_down = 2;
89195972f6Sopenharmony_ci
90195972f6Sopenharmony_cistatic const u8_t iftable_ifAdminStatus_up             = 1;
91195972f6Sopenharmony_cistatic const u8_t iftable_ifAdminStatus_lowerLayerDown = 7;
92195972f6Sopenharmony_cistatic const u8_t iftable_ifAdminStatus_down           = 2;
93195972f6Sopenharmony_ci
94195972f6Sopenharmony_cistatic snmp_err_t
95195972f6Sopenharmony_ciinterfaces_Table_get_cell_instance(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, struct snmp_node_instance *cell_instance)
96195972f6Sopenharmony_ci{
97195972f6Sopenharmony_ci  u32_t ifIndex;
98195972f6Sopenharmony_ci  struct netif *netif;
99195972f6Sopenharmony_ci
100195972f6Sopenharmony_ci  LWIP_UNUSED_ARG(column);
101195972f6Sopenharmony_ci
102195972f6Sopenharmony_ci  /* check if incoming OID length and if values are in plausible range */
103195972f6Sopenharmony_ci  if (!snmp_oid_in_range(row_oid, row_oid_len, interfaces_Table_oid_ranges, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges))) {
104195972f6Sopenharmony_ci    return SNMP_ERR_NOSUCHINSTANCE;
105195972f6Sopenharmony_ci  }
106195972f6Sopenharmony_ci
107195972f6Sopenharmony_ci  /* get netif index from incoming OID */
108195972f6Sopenharmony_ci  ifIndex = row_oid[0];
109195972f6Sopenharmony_ci
110195972f6Sopenharmony_ci  /* find netif with index */
111195972f6Sopenharmony_ci  NETIF_FOREACH(netif) {
112195972f6Sopenharmony_ci    if (netif_to_num(netif) == ifIndex) {
113195972f6Sopenharmony_ci      /* store netif pointer for subsequent operations (get/test/set) */
114195972f6Sopenharmony_ci      cell_instance->reference.ptr = netif;
115195972f6Sopenharmony_ci      return SNMP_ERR_NOERROR;
116195972f6Sopenharmony_ci    }
117195972f6Sopenharmony_ci  }
118195972f6Sopenharmony_ci
119195972f6Sopenharmony_ci  /* not found */
120195972f6Sopenharmony_ci  return SNMP_ERR_NOSUCHINSTANCE;
121195972f6Sopenharmony_ci}
122195972f6Sopenharmony_ci
123195972f6Sopenharmony_cistatic snmp_err_t
124195972f6Sopenharmony_ciinterfaces_Table_get_next_cell_instance(const u32_t *column, struct snmp_obj_id *row_oid, struct snmp_node_instance *cell_instance)
125195972f6Sopenharmony_ci{
126195972f6Sopenharmony_ci  struct netif *netif;
127195972f6Sopenharmony_ci  struct snmp_next_oid_state state;
128195972f6Sopenharmony_ci  u32_t result_temp[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)];
129195972f6Sopenharmony_ci
130195972f6Sopenharmony_ci  LWIP_UNUSED_ARG(column);
131195972f6Sopenharmony_ci
132195972f6Sopenharmony_ci  /* init struct to search next oid */
133195972f6Sopenharmony_ci  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges));
134195972f6Sopenharmony_ci
135195972f6Sopenharmony_ci  /* iterate over all possible OIDs to find the next one */
136195972f6Sopenharmony_ci  NETIF_FOREACH(netif) {
137195972f6Sopenharmony_ci    u32_t test_oid[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)];
138195972f6Sopenharmony_ci    test_oid[0] = netif_to_num(netif);
139195972f6Sopenharmony_ci
140195972f6Sopenharmony_ci    /* check generated OID: is it a candidate for the next one? */
141195972f6Sopenharmony_ci    snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges), netif);
142195972f6Sopenharmony_ci  }
143195972f6Sopenharmony_ci
144195972f6Sopenharmony_ci  /* did we find a next one? */
145195972f6Sopenharmony_ci  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
146195972f6Sopenharmony_ci    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
147195972f6Sopenharmony_ci    /* store netif pointer for subsequent operations (get/test/set) */
148195972f6Sopenharmony_ci    cell_instance->reference.ptr = /* (struct netif*) */state.reference;
149195972f6Sopenharmony_ci    return SNMP_ERR_NOERROR;
150195972f6Sopenharmony_ci  }
151195972f6Sopenharmony_ci
152195972f6Sopenharmony_ci  /* not found */
153195972f6Sopenharmony_ci  return SNMP_ERR_NOSUCHINSTANCE;
154195972f6Sopenharmony_ci}
155195972f6Sopenharmony_ci
156195972f6Sopenharmony_cistatic s16_t
157195972f6Sopenharmony_ciinterfaces_Table_get_value(struct snmp_node_instance *instance, void *value)
158195972f6Sopenharmony_ci{
159195972f6Sopenharmony_ci  struct netif *netif = (struct netif *)instance->reference.ptr;
160195972f6Sopenharmony_ci  u32_t *value_u32 = (u32_t *)value;
161195972f6Sopenharmony_ci  s32_t *value_s32 = (s32_t *)value;
162195972f6Sopenharmony_ci  u16_t value_len;
163195972f6Sopenharmony_ci
164195972f6Sopenharmony_ci  switch (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id)) {
165195972f6Sopenharmony_ci    case 1: /* ifIndex */
166195972f6Sopenharmony_ci      *value_s32 = netif_to_num(netif);
167195972f6Sopenharmony_ci      value_len = sizeof(*value_s32);
168195972f6Sopenharmony_ci      break;
169195972f6Sopenharmony_ci    case 2: /* ifDescr */
170195972f6Sopenharmony_ci      value_len = sizeof(netif->name);
171195972f6Sopenharmony_ci      MEMCPY(value, netif->name, value_len);
172195972f6Sopenharmony_ci      break;
173195972f6Sopenharmony_ci    case 3: /* ifType */
174195972f6Sopenharmony_ci      *value_s32 = netif->link_type;
175195972f6Sopenharmony_ci      value_len = sizeof(*value_s32);
176195972f6Sopenharmony_ci      break;
177195972f6Sopenharmony_ci    case 4: /* ifMtu */
178195972f6Sopenharmony_ci      *value_s32 = netif->mtu;
179195972f6Sopenharmony_ci      value_len = sizeof(*value_s32);
180195972f6Sopenharmony_ci      break;
181195972f6Sopenharmony_ci    case 5: /* ifSpeed */
182195972f6Sopenharmony_ci      *value_u32 = netif->link_speed;
183195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
184195972f6Sopenharmony_ci      break;
185195972f6Sopenharmony_ci    case 6: /* ifPhysAddress */
186195972f6Sopenharmony_ci      value_len = sizeof(netif->hwaddr);
187195972f6Sopenharmony_ci      MEMCPY(value, &netif->hwaddr, value_len);
188195972f6Sopenharmony_ci      break;
189195972f6Sopenharmony_ci    case 7: /* ifAdminStatus */
190195972f6Sopenharmony_ci      if (netif_is_up(netif)) {
191195972f6Sopenharmony_ci        *value_s32 = iftable_ifOperStatus_up;
192195972f6Sopenharmony_ci      } else {
193195972f6Sopenharmony_ci        *value_s32 = iftable_ifOperStatus_down;
194195972f6Sopenharmony_ci      }
195195972f6Sopenharmony_ci      value_len = sizeof(*value_s32);
196195972f6Sopenharmony_ci      break;
197195972f6Sopenharmony_ci    case 8: /* ifOperStatus */
198195972f6Sopenharmony_ci      if (netif_is_up(netif)) {
199195972f6Sopenharmony_ci        if (netif_is_link_up(netif)) {
200195972f6Sopenharmony_ci          *value_s32 = iftable_ifAdminStatus_up;
201195972f6Sopenharmony_ci        } else {
202195972f6Sopenharmony_ci          *value_s32 = iftable_ifAdminStatus_lowerLayerDown;
203195972f6Sopenharmony_ci        }
204195972f6Sopenharmony_ci      } else {
205195972f6Sopenharmony_ci        *value_s32 = iftable_ifAdminStatus_down;
206195972f6Sopenharmony_ci      }
207195972f6Sopenharmony_ci      value_len = sizeof(*value_s32);
208195972f6Sopenharmony_ci      break;
209195972f6Sopenharmony_ci    case 9: /* ifLastChange */
210195972f6Sopenharmony_ci      *value_u32 = netif->ts;
211195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
212195972f6Sopenharmony_ci      break;
213195972f6Sopenharmony_ci    case 10: /* ifInOctets */
214195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifinoctets;
215195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
216195972f6Sopenharmony_ci      break;
217195972f6Sopenharmony_ci    case 11: /* ifInUcastPkts */
218195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifinucastpkts;
219195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
220195972f6Sopenharmony_ci      break;
221195972f6Sopenharmony_ci    case 12: /* ifInNUcastPkts */
222195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifinnucastpkts;
223195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
224195972f6Sopenharmony_ci      break;
225195972f6Sopenharmony_ci    case 13: /* ifInDiscards */
226195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifindiscards;
227195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
228195972f6Sopenharmony_ci      break;
229195972f6Sopenharmony_ci    case 14: /* ifInErrors */
230195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifinerrors;
231195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
232195972f6Sopenharmony_ci      break;
233195972f6Sopenharmony_ci    case 15: /* ifInUnkownProtos */
234195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifinunknownprotos;
235195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
236195972f6Sopenharmony_ci      break;
237195972f6Sopenharmony_ci    case 16: /* ifOutOctets */
238195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifoutoctets;
239195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
240195972f6Sopenharmony_ci      break;
241195972f6Sopenharmony_ci    case 17: /* ifOutUcastPkts */
242195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifoutucastpkts;
243195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
244195972f6Sopenharmony_ci      break;
245195972f6Sopenharmony_ci    case 18: /* ifOutNUcastPkts */
246195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifoutnucastpkts;
247195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
248195972f6Sopenharmony_ci      break;
249195972f6Sopenharmony_ci    case 19: /* ifOutDiscarts */
250195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifoutdiscards;
251195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
252195972f6Sopenharmony_ci      break;
253195972f6Sopenharmony_ci    case 20: /* ifOutErrors */
254195972f6Sopenharmony_ci      *value_u32 = netif->mib2_counters.ifouterrors;
255195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
256195972f6Sopenharmony_ci      break;
257195972f6Sopenharmony_ci    case 21: /* ifOutQLen */
258195972f6Sopenharmony_ci      *value_u32 = iftable_ifOutQLen;
259195972f6Sopenharmony_ci      value_len = sizeof(*value_u32);
260195972f6Sopenharmony_ci      break;
261195972f6Sopenharmony_ci    /** @note returning zeroDotZero (0.0) no media specific MIB support */
262195972f6Sopenharmony_ci    case 22: /* ifSpecific */
263195972f6Sopenharmony_ci      value_len = snmp_zero_dot_zero.len * sizeof(u32_t);
264195972f6Sopenharmony_ci      MEMCPY(value, snmp_zero_dot_zero.id, value_len);
265195972f6Sopenharmony_ci      break;
266195972f6Sopenharmony_ci    default:
267195972f6Sopenharmony_ci      return 0;
268195972f6Sopenharmony_ci  }
269195972f6Sopenharmony_ci
270195972f6Sopenharmony_ci  return value_len;
271195972f6Sopenharmony_ci}
272195972f6Sopenharmony_ci
273195972f6Sopenharmony_ci#if !SNMP_SAFE_REQUESTS
274195972f6Sopenharmony_ci
275195972f6Sopenharmony_cistatic snmp_err_t
276195972f6Sopenharmony_ciinterfaces_Table_set_test(struct snmp_node_instance *instance, u16_t len, void *value)
277195972f6Sopenharmony_ci{
278195972f6Sopenharmony_ci  s32_t *sint_ptr = (s32_t *)value;
279195972f6Sopenharmony_ci
280195972f6Sopenharmony_ci  /* stack should never call this method for another column,
281195972f6Sopenharmony_ci  because all other columns are set to readonly */
282195972f6Sopenharmony_ci  LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7));
283195972f6Sopenharmony_ci  LWIP_UNUSED_ARG(len);
284195972f6Sopenharmony_ci
285195972f6Sopenharmony_ci  if (*sint_ptr == 1 || *sint_ptr == 2) {
286195972f6Sopenharmony_ci    return SNMP_ERR_NOERROR;
287195972f6Sopenharmony_ci  }
288195972f6Sopenharmony_ci
289195972f6Sopenharmony_ci  return SNMP_ERR_WRONGVALUE;
290195972f6Sopenharmony_ci}
291195972f6Sopenharmony_ci
292195972f6Sopenharmony_cistatic snmp_err_t
293195972f6Sopenharmony_ciinterfaces_Table_set_value(struct snmp_node_instance *instance, u16_t len, void *value)
294195972f6Sopenharmony_ci{
295195972f6Sopenharmony_ci  struct netif *netif = (struct netif *)instance->reference.ptr;
296195972f6Sopenharmony_ci  s32_t *sint_ptr = (s32_t *)value;
297195972f6Sopenharmony_ci
298195972f6Sopenharmony_ci  /* stack should never call this method for another column,
299195972f6Sopenharmony_ci  because all other columns are set to readonly */
300195972f6Sopenharmony_ci  LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7));
301195972f6Sopenharmony_ci  LWIP_UNUSED_ARG(len);
302195972f6Sopenharmony_ci
303195972f6Sopenharmony_ci  if (*sint_ptr == 1) {
304195972f6Sopenharmony_ci    netif_set_up(netif);
305195972f6Sopenharmony_ci  } else if (*sint_ptr == 2) {
306195972f6Sopenharmony_ci    netif_set_down(netif);
307195972f6Sopenharmony_ci  }
308195972f6Sopenharmony_ci
309195972f6Sopenharmony_ci  return SNMP_ERR_NOERROR;
310195972f6Sopenharmony_ci}
311195972f6Sopenharmony_ci
312195972f6Sopenharmony_ci#endif /* SNMP_SAFE_REQUESTS */
313195972f6Sopenharmony_ci
314195972f6Sopenharmony_cistatic const struct snmp_scalar_node interfaces_Number = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_INTEGER, interfaces_get_value);
315195972f6Sopenharmony_ci
316195972f6Sopenharmony_cistatic const struct snmp_table_col_def interfaces_Table_columns[] = {
317195972f6Sopenharmony_ci  {  1, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifIndex */
318195972f6Sopenharmony_ci  {  2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifDescr */
319195972f6Sopenharmony_ci  {  3, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifType */
320195972f6Sopenharmony_ci  {  4, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifMtu */
321195972f6Sopenharmony_ci  {  5, SNMP_ASN1_TYPE_GAUGE,        SNMP_NODE_INSTANCE_READ_ONLY }, /* ifSpeed */
322195972f6Sopenharmony_ci  {  6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifPhysAddress */
323195972f6Sopenharmony_ci#if !SNMP_SAFE_REQUESTS
324195972f6Sopenharmony_ci  {  7, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_WRITE }, /* ifAdminStatus */
325195972f6Sopenharmony_ci#else
326195972f6Sopenharmony_ci  {  7, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifAdminStatus */
327195972f6Sopenharmony_ci#endif
328195972f6Sopenharmony_ci  {  8, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOperStatus */
329195972f6Sopenharmony_ci  {  9, SNMP_ASN1_TYPE_TIMETICKS,    SNMP_NODE_INSTANCE_READ_ONLY }, /* ifLastChange */
330195972f6Sopenharmony_ci  { 10, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInOctets */
331195972f6Sopenharmony_ci  { 11, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUcastPkts */
332195972f6Sopenharmony_ci  { 12, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInNUcastPkts */
333195972f6Sopenharmony_ci  { 13, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInDiscarts */
334195972f6Sopenharmony_ci  { 14, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInErrors */
335195972f6Sopenharmony_ci  { 15, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUnkownProtos */
336195972f6Sopenharmony_ci  { 16, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutOctets */
337195972f6Sopenharmony_ci  { 17, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutUcastPkts */
338195972f6Sopenharmony_ci  { 18, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutNUcastPkts */
339195972f6Sopenharmony_ci  { 19, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutDiscarts */
340195972f6Sopenharmony_ci  { 20, SNMP_ASN1_TYPE_COUNTER,      SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutErrors */
341195972f6Sopenharmony_ci  { 21, SNMP_ASN1_TYPE_GAUGE,        SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutQLen */
342195972f6Sopenharmony_ci  { 22, SNMP_ASN1_TYPE_OBJECT_ID,    SNMP_NODE_INSTANCE_READ_ONLY }  /* ifSpecific */
343195972f6Sopenharmony_ci};
344195972f6Sopenharmony_ci
345195972f6Sopenharmony_ci#if !SNMP_SAFE_REQUESTS
346195972f6Sopenharmony_cistatic const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE(
347195972f6Sopenharmony_ci      2, interfaces_Table_columns,
348195972f6Sopenharmony_ci      interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance,
349195972f6Sopenharmony_ci      interfaces_Table_get_value, interfaces_Table_set_test, interfaces_Table_set_value);
350195972f6Sopenharmony_ci#else
351195972f6Sopenharmony_cistatic const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE(
352195972f6Sopenharmony_ci      2, interfaces_Table_columns,
353195972f6Sopenharmony_ci      interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance,
354195972f6Sopenharmony_ci      interfaces_Table_get_value, NULL, NULL);
355195972f6Sopenharmony_ci#endif
356195972f6Sopenharmony_ci
357195972f6Sopenharmony_ci/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
358195972f6Sopenharmony_ciCREATE_LWIP_SYNC_NODE(1, interfaces_Number)
359195972f6Sopenharmony_ciCREATE_LWIP_SYNC_NODE(2, interfaces_Table)
360195972f6Sopenharmony_ci
361195972f6Sopenharmony_cistatic const struct snmp_node *const interface_nodes[] = {
362195972f6Sopenharmony_ci  &SYNC_NODE_NAME(interfaces_Number).node.node,
363195972f6Sopenharmony_ci  &SYNC_NODE_NAME(interfaces_Table).node.node
364195972f6Sopenharmony_ci};
365195972f6Sopenharmony_ci
366195972f6Sopenharmony_ciconst struct snmp_tree_node snmp_mib2_interface_root = SNMP_CREATE_TREE_NODE(2, interface_nodes);
367195972f6Sopenharmony_ci
368195972f6Sopenharmony_ci#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
369