1195972f6Sopenharmony_ci/**
2195972f6Sopenharmony_ci * @file
3195972f6Sopenharmony_ci * Management Information Base II (RFC1213) UDP 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/udp.h"
43195972f6Sopenharmony_ci#include "lwip/stats.h"
44195972f6Sopenharmony_ci
45195972f6Sopenharmony_ci#include <string.h>
46195972f6Sopenharmony_ci
47195972f6Sopenharmony_ci#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP
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/* --- udp .1.3.6.1.2.1.7 ----------------------------------------------------- */
59195972f6Sopenharmony_ci
60195972f6Sopenharmony_cistatic s16_t
61195972f6Sopenharmony_ciudp_get_value(struct snmp_node_instance *instance, void *value)
62195972f6Sopenharmony_ci{
63195972f6Sopenharmony_ci  u32_t *uint_ptr = (u32_t *)value;
64195972f6Sopenharmony_ci
65195972f6Sopenharmony_ci  switch (instance->node->oid) {
66195972f6Sopenharmony_ci    case 1: /* udpInDatagrams */
67195972f6Sopenharmony_ci      *uint_ptr = STATS_GET(mib2.udpindatagrams);
68195972f6Sopenharmony_ci      return sizeof(*uint_ptr);
69195972f6Sopenharmony_ci    case 2: /* udpNoPorts */
70195972f6Sopenharmony_ci      *uint_ptr = STATS_GET(mib2.udpnoports);
71195972f6Sopenharmony_ci      return sizeof(*uint_ptr);
72195972f6Sopenharmony_ci    case 3: /* udpInErrors */
73195972f6Sopenharmony_ci      *uint_ptr = STATS_GET(mib2.udpinerrors);
74195972f6Sopenharmony_ci      return sizeof(*uint_ptr);
75195972f6Sopenharmony_ci    case 4: /* udpOutDatagrams */
76195972f6Sopenharmony_ci      *uint_ptr = STATS_GET(mib2.udpoutdatagrams);
77195972f6Sopenharmony_ci      return sizeof(*uint_ptr);
78195972f6Sopenharmony_ci#if LWIP_HAVE_INT64
79195972f6Sopenharmony_ci    case 8: { /* udpHCInDatagrams */
80195972f6Sopenharmony_ci      /* use the 32 bit counter for now... */
81195972f6Sopenharmony_ci      u64_t val64 = STATS_GET(mib2.udpindatagrams);
82195972f6Sopenharmony_ci      *((u64_t *)value) = val64;
83195972f6Sopenharmony_ci    }
84195972f6Sopenharmony_ci    return sizeof(u64_t);
85195972f6Sopenharmony_ci    case 9: { /* udpHCOutDatagrams */
86195972f6Sopenharmony_ci      /* use the 32 bit counter for now... */
87195972f6Sopenharmony_ci      u64_t val64 = STATS_GET(mib2.udpoutdatagrams);
88195972f6Sopenharmony_ci      *((u64_t *)value) = val64;
89195972f6Sopenharmony_ci    }
90195972f6Sopenharmony_ci    return sizeof(u64_t);
91195972f6Sopenharmony_ci#endif
92195972f6Sopenharmony_ci    default:
93195972f6Sopenharmony_ci      LWIP_DEBUGF(SNMP_MIB_DEBUG, ("udp_get_value(): unknown id: %"S32_F"\n", instance->node->oid));
94195972f6Sopenharmony_ci      break;
95195972f6Sopenharmony_ci  }
96195972f6Sopenharmony_ci
97195972f6Sopenharmony_ci  return 0;
98195972f6Sopenharmony_ci}
99195972f6Sopenharmony_ci
100195972f6Sopenharmony_ci/* --- udpEndpointTable --- */
101195972f6Sopenharmony_ci
102195972f6Sopenharmony_cistatic snmp_err_t
103195972f6Sopenharmony_ciudp_endpointTable_get_cell_value_core(const u32_t *column, union snmp_variant_value *value)
104195972f6Sopenharmony_ci{
105195972f6Sopenharmony_ci  /* all items except udpEndpointProcess are declared as not-accessible */
106195972f6Sopenharmony_ci  switch (*column) {
107195972f6Sopenharmony_ci    case 8: /* udpEndpointProcess */
108195972f6Sopenharmony_ci      value->u32 = 0; /* not supported */
109195972f6Sopenharmony_ci      break;
110195972f6Sopenharmony_ci    default:
111195972f6Sopenharmony_ci      return SNMP_ERR_NOSUCHINSTANCE;
112195972f6Sopenharmony_ci  }
113195972f6Sopenharmony_ci
114195972f6Sopenharmony_ci  return SNMP_ERR_NOERROR;
115195972f6Sopenharmony_ci}
116195972f6Sopenharmony_ci
117195972f6Sopenharmony_cistatic snmp_err_t
118195972f6Sopenharmony_ciudp_endpointTable_get_cell_value(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, union snmp_variant_value *value, u32_t *value_len)
119195972f6Sopenharmony_ci{
120195972f6Sopenharmony_ci  ip_addr_t local_ip, remote_ip;
121195972f6Sopenharmony_ci  u16_t local_port, remote_port;
122195972f6Sopenharmony_ci  struct udp_pcb *pcb;
123195972f6Sopenharmony_ci  u8_t idx = 0;
124195972f6Sopenharmony_ci
125195972f6Sopenharmony_ci  LWIP_UNUSED_ARG(value_len);
126195972f6Sopenharmony_ci
127195972f6Sopenharmony_ci  /* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */
128195972f6Sopenharmony_ci  idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len - idx, &local_ip, &local_port);
129195972f6Sopenharmony_ci  if (idx == 0) {
130195972f6Sopenharmony_ci    return SNMP_ERR_NOSUCHINSTANCE;
131195972f6Sopenharmony_ci  }
132195972f6Sopenharmony_ci
133195972f6Sopenharmony_ci  /* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */
134195972f6Sopenharmony_ci  idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len - idx, &remote_ip, &remote_port);
135195972f6Sopenharmony_ci  if (idx == 0) {
136195972f6Sopenharmony_ci    return SNMP_ERR_NOSUCHINSTANCE;
137195972f6Sopenharmony_ci  }
138195972f6Sopenharmony_ci
139195972f6Sopenharmony_ci  /* udpEndpointInstance */
140195972f6Sopenharmony_ci  if (row_oid_len < (idx + 1)) {
141195972f6Sopenharmony_ci    return SNMP_ERR_NOSUCHINSTANCE;
142195972f6Sopenharmony_ci  }
143195972f6Sopenharmony_ci  if (row_oid[idx] != 0) {
144195972f6Sopenharmony_ci    return SNMP_ERR_NOSUCHINSTANCE;
145195972f6Sopenharmony_ci  }
146195972f6Sopenharmony_ci
147195972f6Sopenharmony_ci  /* find udp_pcb with requested ip and port*/
148195972f6Sopenharmony_ci  pcb = udp_pcbs;
149195972f6Sopenharmony_ci  while (pcb != NULL) {
150195972f6Sopenharmony_ci    if (ip_addr_cmp(&local_ip, &pcb->local_ip) &&
151195972f6Sopenharmony_ci        (local_port == pcb->local_port) &&
152195972f6Sopenharmony_ci        ip_addr_cmp(&remote_ip, &pcb->remote_ip) &&
153195972f6Sopenharmony_ci        (remote_port == pcb->remote_port)) {
154195972f6Sopenharmony_ci      /* fill in object properties */
155195972f6Sopenharmony_ci      return udp_endpointTable_get_cell_value_core(column, value);
156195972f6Sopenharmony_ci    }
157195972f6Sopenharmony_ci    pcb = pcb->next;
158195972f6Sopenharmony_ci  }
159195972f6Sopenharmony_ci
160195972f6Sopenharmony_ci  /* not found */
161195972f6Sopenharmony_ci  return SNMP_ERR_NOSUCHINSTANCE;
162195972f6Sopenharmony_ci}
163195972f6Sopenharmony_ci
164195972f6Sopenharmony_cistatic snmp_err_t
165195972f6Sopenharmony_ciudp_endpointTable_get_next_cell_instance_and_value(const u32_t *column, struct snmp_obj_id *row_oid, union snmp_variant_value *value, u32_t *value_len)
166195972f6Sopenharmony_ci{
167195972f6Sopenharmony_ci  struct udp_pcb *pcb;
168195972f6Sopenharmony_ci  struct snmp_next_oid_state state;
169195972f6Sopenharmony_ci  /* 1x udpEndpointLocalAddressType  + 1x OID len + 16x udpEndpointLocalAddress  + 1x udpEndpointLocalPort  +
170195972f6Sopenharmony_ci   * 1x udpEndpointRemoteAddressType + 1x OID len + 16x udpEndpointRemoteAddress + 1x udpEndpointRemotePort +
171195972f6Sopenharmony_ci   * 1x udpEndpointInstance = 39
172195972f6Sopenharmony_ci   */
173195972f6Sopenharmony_ci  u32_t  result_temp[39];
174195972f6Sopenharmony_ci
175195972f6Sopenharmony_ci  LWIP_UNUSED_ARG(value_len);
176195972f6Sopenharmony_ci
177195972f6Sopenharmony_ci  /* init struct to search next oid */
178195972f6Sopenharmony_ci  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp));
179195972f6Sopenharmony_ci
180195972f6Sopenharmony_ci  /* iterate over all possible OIDs to find the next one */
181195972f6Sopenharmony_ci  pcb = udp_pcbs;
182195972f6Sopenharmony_ci  while (pcb != NULL) {
183195972f6Sopenharmony_ci    u32_t test_oid[LWIP_ARRAYSIZE(result_temp)];
184195972f6Sopenharmony_ci    u8_t idx = 0;
185195972f6Sopenharmony_ci
186195972f6Sopenharmony_ci    /* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */
187195972f6Sopenharmony_ci    idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]);
188195972f6Sopenharmony_ci
189195972f6Sopenharmony_ci    /* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */
190195972f6Sopenharmony_ci    idx += snmp_ip_port_to_oid(&pcb->remote_ip, pcb->remote_port, &test_oid[idx]);
191195972f6Sopenharmony_ci
192195972f6Sopenharmony_ci    test_oid[idx] = 0; /* udpEndpointInstance */
193195972f6Sopenharmony_ci    idx++;
194195972f6Sopenharmony_ci
195195972f6Sopenharmony_ci    /* check generated OID: is it a candidate for the next one? */
196195972f6Sopenharmony_ci    snmp_next_oid_check(&state, test_oid, idx, NULL);
197195972f6Sopenharmony_ci
198195972f6Sopenharmony_ci    pcb = pcb->next;
199195972f6Sopenharmony_ci  }
200195972f6Sopenharmony_ci
201195972f6Sopenharmony_ci  /* did we find a next one? */
202195972f6Sopenharmony_ci  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
203195972f6Sopenharmony_ci    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
204195972f6Sopenharmony_ci    /* fill in object properties */
205195972f6Sopenharmony_ci    return udp_endpointTable_get_cell_value_core(column, value);
206195972f6Sopenharmony_ci  } else {
207195972f6Sopenharmony_ci    /* not found */
208195972f6Sopenharmony_ci    return SNMP_ERR_NOSUCHINSTANCE;
209195972f6Sopenharmony_ci  }
210195972f6Sopenharmony_ci}
211195972f6Sopenharmony_ci
212195972f6Sopenharmony_ci/* --- udpTable --- */
213195972f6Sopenharmony_ci
214195972f6Sopenharmony_ci#if LWIP_IPV4
215195972f6Sopenharmony_ci
216195972f6Sopenharmony_ci/* list of allowed value ranges for incoming OID */
217195972f6Sopenharmony_cistatic const struct snmp_oid_range udp_Table_oid_ranges[] = {
218195972f6Sopenharmony_ci  { 0, 0xff   }, /* IP A        */
219195972f6Sopenharmony_ci  { 0, 0xff   }, /* IP B        */
220195972f6Sopenharmony_ci  { 0, 0xff   }, /* IP C        */
221195972f6Sopenharmony_ci  { 0, 0xff   }, /* IP D        */
222195972f6Sopenharmony_ci  { 1, 0xffff }  /* Port        */
223195972f6Sopenharmony_ci};
224195972f6Sopenharmony_ci
225195972f6Sopenharmony_cistatic snmp_err_t
226195972f6Sopenharmony_ciudp_Table_get_cell_value_core(struct udp_pcb *pcb, const u32_t *column, union snmp_variant_value *value, u32_t *value_len)
227195972f6Sopenharmony_ci{
228195972f6Sopenharmony_ci  LWIP_UNUSED_ARG(value_len);
229195972f6Sopenharmony_ci
230195972f6Sopenharmony_ci  switch (*column) {
231195972f6Sopenharmony_ci    case 1: /* udpLocalAddress */
232195972f6Sopenharmony_ci      /* set reference to PCB local IP and return a generic node that copies IP4 addresses */
233195972f6Sopenharmony_ci      value->u32 = ip_2_ip4(&pcb->local_ip)->addr;
234195972f6Sopenharmony_ci      break;
235195972f6Sopenharmony_ci    case 2: /* udpLocalPort */
236195972f6Sopenharmony_ci      /* set reference to PCB local port and return a generic node that copies u16_t values */
237195972f6Sopenharmony_ci      value->u32 = pcb->local_port;
238195972f6Sopenharmony_ci      break;
239195972f6Sopenharmony_ci    default:
240195972f6Sopenharmony_ci      return SNMP_ERR_NOSUCHINSTANCE;
241195972f6Sopenharmony_ci  }
242195972f6Sopenharmony_ci
243195972f6Sopenharmony_ci  return SNMP_ERR_NOERROR;
244195972f6Sopenharmony_ci}
245195972f6Sopenharmony_ci
246195972f6Sopenharmony_cistatic snmp_err_t
247195972f6Sopenharmony_ciudp_Table_get_cell_value(const u32_t *column, const u32_t *row_oid, u8_t row_oid_len, union snmp_variant_value *value, u32_t *value_len)
248195972f6Sopenharmony_ci{
249195972f6Sopenharmony_ci  ip4_addr_t ip;
250195972f6Sopenharmony_ci  u16_t port;
251195972f6Sopenharmony_ci  struct udp_pcb *pcb;
252195972f6Sopenharmony_ci
253195972f6Sopenharmony_ci  /* check if incoming OID length and if values are in plausible range */
254195972f6Sopenharmony_ci  if (!snmp_oid_in_range(row_oid, row_oid_len, udp_Table_oid_ranges, LWIP_ARRAYSIZE(udp_Table_oid_ranges))) {
255195972f6Sopenharmony_ci    return SNMP_ERR_NOSUCHINSTANCE;
256195972f6Sopenharmony_ci  }
257195972f6Sopenharmony_ci
258195972f6Sopenharmony_ci  /* get IP and port from incoming OID */
259195972f6Sopenharmony_ci  snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */
260195972f6Sopenharmony_ci  port = (u16_t)row_oid[4];
261195972f6Sopenharmony_ci
262195972f6Sopenharmony_ci  /* find udp_pcb with requested ip and port*/
263195972f6Sopenharmony_ci  pcb = udp_pcbs;
264195972f6Sopenharmony_ci  while (pcb != NULL) {
265195972f6Sopenharmony_ci    if (IP_IS_V4_VAL(pcb->local_ip)) {
266195972f6Sopenharmony_ci      if (ip4_addr_cmp(&ip, ip_2_ip4(&pcb->local_ip)) && (port == pcb->local_port)) {
267195972f6Sopenharmony_ci        /* fill in object properties */
268195972f6Sopenharmony_ci        return udp_Table_get_cell_value_core(pcb, column, value, value_len);
269195972f6Sopenharmony_ci      }
270195972f6Sopenharmony_ci    }
271195972f6Sopenharmony_ci    pcb = pcb->next;
272195972f6Sopenharmony_ci  }
273195972f6Sopenharmony_ci
274195972f6Sopenharmony_ci  /* not found */
275195972f6Sopenharmony_ci  return SNMP_ERR_NOSUCHINSTANCE;
276195972f6Sopenharmony_ci}
277195972f6Sopenharmony_ci
278195972f6Sopenharmony_cistatic snmp_err_t
279195972f6Sopenharmony_ciudp_Table_get_next_cell_instance_and_value(const u32_t *column, struct snmp_obj_id *row_oid, union snmp_variant_value *value, u32_t *value_len)
280195972f6Sopenharmony_ci{
281195972f6Sopenharmony_ci  struct udp_pcb *pcb;
282195972f6Sopenharmony_ci  struct snmp_next_oid_state state;
283195972f6Sopenharmony_ci  u32_t  result_temp[LWIP_ARRAYSIZE(udp_Table_oid_ranges)];
284195972f6Sopenharmony_ci
285195972f6Sopenharmony_ci  /* init struct to search next oid */
286195972f6Sopenharmony_ci  snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(udp_Table_oid_ranges));
287195972f6Sopenharmony_ci
288195972f6Sopenharmony_ci  /* iterate over all possible OIDs to find the next one */
289195972f6Sopenharmony_ci  pcb = udp_pcbs;
290195972f6Sopenharmony_ci  while (pcb != NULL) {
291195972f6Sopenharmony_ci    u32_t test_oid[LWIP_ARRAYSIZE(udp_Table_oid_ranges)];
292195972f6Sopenharmony_ci
293195972f6Sopenharmony_ci    if (IP_IS_V4_VAL(pcb->local_ip)) {
294195972f6Sopenharmony_ci      snmp_ip4_to_oid(ip_2_ip4(&pcb->local_ip), &test_oid[0]);
295195972f6Sopenharmony_ci      test_oid[4] = pcb->local_port;
296195972f6Sopenharmony_ci
297195972f6Sopenharmony_ci      /* check generated OID: is it a candidate for the next one? */
298195972f6Sopenharmony_ci      snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(udp_Table_oid_ranges), pcb);
299195972f6Sopenharmony_ci    }
300195972f6Sopenharmony_ci
301195972f6Sopenharmony_ci    pcb = pcb->next;
302195972f6Sopenharmony_ci  }
303195972f6Sopenharmony_ci
304195972f6Sopenharmony_ci  /* did we find a next one? */
305195972f6Sopenharmony_ci  if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
306195972f6Sopenharmony_ci    snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
307195972f6Sopenharmony_ci    /* fill in object properties */
308195972f6Sopenharmony_ci    return udp_Table_get_cell_value_core((struct udp_pcb *)state.reference, column, value, value_len);
309195972f6Sopenharmony_ci  } else {
310195972f6Sopenharmony_ci    /* not found */
311195972f6Sopenharmony_ci    return SNMP_ERR_NOSUCHINSTANCE;
312195972f6Sopenharmony_ci  }
313195972f6Sopenharmony_ci}
314195972f6Sopenharmony_ci
315195972f6Sopenharmony_ci#endif /* LWIP_IPV4 */
316195972f6Sopenharmony_ci
317195972f6Sopenharmony_cistatic const struct snmp_scalar_node udp_inDatagrams    = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_COUNTER,   udp_get_value);
318195972f6Sopenharmony_cistatic const struct snmp_scalar_node udp_noPorts        = SNMP_SCALAR_CREATE_NODE_READONLY(2, SNMP_ASN1_TYPE_COUNTER,   udp_get_value);
319195972f6Sopenharmony_cistatic const struct snmp_scalar_node udp_inErrors       = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_COUNTER,   udp_get_value);
320195972f6Sopenharmony_cistatic const struct snmp_scalar_node udp_outDatagrams   = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_COUNTER,   udp_get_value);
321195972f6Sopenharmony_ci#if LWIP_HAVE_INT64
322195972f6Sopenharmony_cistatic const struct snmp_scalar_node udp_HCInDatagrams  = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER64, udp_get_value);
323195972f6Sopenharmony_cistatic const struct snmp_scalar_node udp_HCOutDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_COUNTER64, udp_get_value);
324195972f6Sopenharmony_ci#endif
325195972f6Sopenharmony_ci
326195972f6Sopenharmony_ci#if LWIP_IPV4
327195972f6Sopenharmony_cistatic const struct snmp_table_simple_col_def udp_Table_columns[] = {
328195972f6Sopenharmony_ci  { 1, SNMP_ASN1_TYPE_IPADDR,  SNMP_VARIANT_VALUE_TYPE_U32 }, /* udpLocalAddress */
329195972f6Sopenharmony_ci  { 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }  /* udpLocalPort */
330195972f6Sopenharmony_ci};
331195972f6Sopenharmony_cistatic const struct snmp_table_simple_node udp_Table = SNMP_TABLE_CREATE_SIMPLE(5, udp_Table_columns, udp_Table_get_cell_value, udp_Table_get_next_cell_instance_and_value);
332195972f6Sopenharmony_ci#endif /* LWIP_IPV4 */
333195972f6Sopenharmony_ci
334195972f6Sopenharmony_cistatic const struct snmp_table_simple_col_def udp_endpointTable_columns[] = {
335195972f6Sopenharmony_ci  /* all items except udpEndpointProcess are declared as not-accessible */
336195972f6Sopenharmony_ci  { 8, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 }  /* udpEndpointProcess */
337195972f6Sopenharmony_ci};
338195972f6Sopenharmony_ci
339195972f6Sopenharmony_cistatic const struct snmp_table_simple_node udp_endpointTable = SNMP_TABLE_CREATE_SIMPLE(7, udp_endpointTable_columns, udp_endpointTable_get_cell_value, udp_endpointTable_get_next_cell_instance_and_value);
340195972f6Sopenharmony_ci
341195972f6Sopenharmony_ci/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */
342195972f6Sopenharmony_ciCREATE_LWIP_SYNC_NODE(1, udp_inDatagrams)
343195972f6Sopenharmony_ciCREATE_LWIP_SYNC_NODE(2, udp_noPorts)
344195972f6Sopenharmony_ciCREATE_LWIP_SYNC_NODE(3, udp_inErrors)
345195972f6Sopenharmony_ciCREATE_LWIP_SYNC_NODE(4, udp_outDatagrams)
346195972f6Sopenharmony_ci#if LWIP_IPV4
347195972f6Sopenharmony_ciCREATE_LWIP_SYNC_NODE(5, udp_Table)
348195972f6Sopenharmony_ci#endif /* LWIP_IPV4 */
349195972f6Sopenharmony_ciCREATE_LWIP_SYNC_NODE(7, udp_endpointTable)
350195972f6Sopenharmony_ci#if LWIP_HAVE_INT64
351195972f6Sopenharmony_ciCREATE_LWIP_SYNC_NODE(8, udp_HCInDatagrams)
352195972f6Sopenharmony_ciCREATE_LWIP_SYNC_NODE(9, udp_HCOutDatagrams)
353195972f6Sopenharmony_ci#endif
354195972f6Sopenharmony_ci
355195972f6Sopenharmony_cistatic const struct snmp_node *const udp_nodes[] = {
356195972f6Sopenharmony_ci  &SYNC_NODE_NAME(udp_inDatagrams).node.node,
357195972f6Sopenharmony_ci  &SYNC_NODE_NAME(udp_noPorts).node.node,
358195972f6Sopenharmony_ci  &SYNC_NODE_NAME(udp_inErrors).node.node,
359195972f6Sopenharmony_ci  &SYNC_NODE_NAME(udp_outDatagrams).node.node,
360195972f6Sopenharmony_ci#if LWIP_IPV4
361195972f6Sopenharmony_ci  &SYNC_NODE_NAME(udp_Table).node.node,
362195972f6Sopenharmony_ci#endif /* LWIP_IPV4 */
363195972f6Sopenharmony_ci  &SYNC_NODE_NAME(udp_endpointTable).node.node
364195972f6Sopenharmony_ci#if LWIP_HAVE_INT64
365195972f6Sopenharmony_ci  ,
366195972f6Sopenharmony_ci  &SYNC_NODE_NAME(udp_HCInDatagrams).node.node,
367195972f6Sopenharmony_ci  &SYNC_NODE_NAME(udp_HCOutDatagrams).node.node
368195972f6Sopenharmony_ci#endif
369195972f6Sopenharmony_ci};
370195972f6Sopenharmony_ci
371195972f6Sopenharmony_ciconst struct snmp_tree_node snmp_mib2_udp_root = SNMP_CREATE_TREE_NODE(7, udp_nodes);
372195972f6Sopenharmony_ci#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP */
373