Prusa MINI Firmware overview
snmp_core.h
Go to the documentation of this file.
1 /**
2  * @file
3  * SNMP core API for implementing MIBs
4  */
5 
6 /*
7  * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without modification,
11  * are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright notice,
14  * this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * 3. The name of the author may not be used to endorse or promote products
19  * derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
24  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30  * OF SUCH DAMAGE.
31  *
32  * Author: Christiaan Simons <christiaan.simons@axon.tv>
33  * Martin Hentschel <info@cl-soft.de>
34  */
35 
36 #ifndef LWIP_HDR_APPS_SNMP_CORE_H
37 #define LWIP_HDR_APPS_SNMP_CORE_H
38 
39 #include "lwip/apps/snmp_opts.h"
40 
41 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
42 
43 #include "lwip/ip_addr.h"
44 #include "lwip/err.h"
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49 
50 /* basic ASN1 defines */
51 #define SNMP_ASN1_CLASS_UNIVERSAL 0x00
52 #define SNMP_ASN1_CLASS_APPLICATION 0x40
53 #define SNMP_ASN1_CLASS_CONTEXT 0x80
54 #define SNMP_ASN1_CLASS_PRIVATE 0xC0
55 
56 #define SNMP_ASN1_CONTENTTYPE_PRIMITIVE 0x00
57 #define SNMP_ASN1_CONTENTTYPE_CONSTRUCTED 0x20
58 
59 /* universal tags (from ASN.1 spec.) */
60 #define SNMP_ASN1_UNIVERSAL_END_OF_CONTENT 0
61 #define SNMP_ASN1_UNIVERSAL_INTEGER 2
62 #define SNMP_ASN1_UNIVERSAL_OCTET_STRING 4
63 #define SNMP_ASN1_UNIVERSAL_NULL 5
64 #define SNMP_ASN1_UNIVERSAL_OBJECT_ID 6
65 #define SNMP_ASN1_UNIVERSAL_SEQUENCE_OF 16
66 
67 /* application specific (SNMP) tags (from SNMPv2-SMI) */
68 #define SNMP_ASN1_APPLICATION_IPADDR 0 /* [APPLICATION 0] IMPLICIT OCTET STRING (SIZE (4)) */
69 #define SNMP_ASN1_APPLICATION_COUNTER 1 /* [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) => u32_t */
70 #define SNMP_ASN1_APPLICATION_GAUGE 2 /* [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) => u32_t */
71 #define SNMP_ASN1_APPLICATION_TIMETICKS 3 /* [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) => u32_t */
72 #define SNMP_ASN1_APPLICATION_OPAQUE 4 /* [APPLICATION 4] IMPLICIT OCTET STRING */
73 #define SNMP_ASN1_APPLICATION_COUNTER64 6 /* [APPLICATION 6] IMPLICIT INTEGER (0..18446744073709551615) */
74 
75 /* context specific (SNMP) tags (from RFC 1905) */
76 #define SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE 1
77 
78 /* full ASN1 type defines */
79 #define SNMP_ASN1_TYPE_END_OF_CONTENT (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_END_OF_CONTENT)
80 #define SNMP_ASN1_TYPE_INTEGER (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_INTEGER)
81 #define SNMP_ASN1_TYPE_OCTET_STRING (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OCTET_STRING)
82 #define SNMP_ASN1_TYPE_NULL (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_NULL)
83 #define SNMP_ASN1_TYPE_OBJECT_ID (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OBJECT_ID)
84 #define SNMP_ASN1_TYPE_SEQUENCE (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_UNIVERSAL_SEQUENCE_OF)
85 #define SNMP_ASN1_TYPE_IPADDR (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_IPADDR)
86 #define SNMP_ASN1_TYPE_IPADDRESS SNMP_ASN1_TYPE_IPADDR
87 #define SNMP_ASN1_TYPE_COUNTER (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER)
88 #define SNMP_ASN1_TYPE_COUNTER32 SNMP_ASN1_TYPE_COUNTER
89 #define SNMP_ASN1_TYPE_GAUGE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_GAUGE)
90 #define SNMP_ASN1_TYPE_GAUGE32 SNMP_ASN1_TYPE_GAUGE
91 #define SNMP_ASN1_TYPE_UNSIGNED32 SNMP_ASN1_TYPE_GAUGE
92 #define SNMP_ASN1_TYPE_TIMETICKS (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_TIMETICKS)
93 #define SNMP_ASN1_TYPE_OPAQUE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_OPAQUE)
94 #define SNMP_ASN1_TYPE_COUNTER64 (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER64)
95 
96 #define SNMP_VARBIND_EXCEPTION_OFFSET 0xF0
97 #define SNMP_VARBIND_EXCEPTION_MASK 0x0F
98 
99 /** error codes predefined by SNMP prot. */
100 typedef enum {
101  SNMP_ERR_NOERROR = 0,
102 /*
103 outdated v1 error codes. do not use anmore!
104 #define SNMP_ERR_NOSUCHNAME 2 use SNMP_ERR_NOSUCHINSTANCE instead
105 #define SNMP_ERR_BADVALUE 3 use SNMP_ERR_WRONGTYPE,SNMP_ERR_WRONGLENGTH,SNMP_ERR_WRONGENCODING or SNMP_ERR_WRONGVALUE instead
106 #define SNMP_ERR_READONLY 4 use SNMP_ERR_NOTWRITABLE instead
107 */
108  SNMP_ERR_GENERROR = 5,
109  SNMP_ERR_NOACCESS = 6,
110  SNMP_ERR_WRONGTYPE = 7,
111  SNMP_ERR_WRONGLENGTH = 8,
112  SNMP_ERR_WRONGENCODING = 9,
113  SNMP_ERR_WRONGVALUE = 10,
114  SNMP_ERR_NOCREATION = 11,
115  SNMP_ERR_INCONSISTENTVALUE = 12,
116  SNMP_ERR_RESOURCEUNAVAILABLE = 13,
117  SNMP_ERR_COMMITFAILED = 14,
118  SNMP_ERR_UNDOFAILED = 15,
119  SNMP_ERR_NOTWRITABLE = 17,
120  SNMP_ERR_INCONSISTENTNAME = 18,
121 
122  SNMP_ERR_NOSUCHINSTANCE = SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE
123 } snmp_err_t;
124 
125 /** internal object identifier representation */
126 struct snmp_obj_id
127 {
128  u8_t len;
130 };
131 
132 struct snmp_obj_id_const_ref
133 {
134  u8_t len;
135  const u32_t* id;
136 };
137 
138 extern const struct snmp_obj_id_const_ref snmp_zero_dot_zero; /* administrative identifier from SNMPv2-SMI */
139 
140 /** SNMP variant value, used as reference in struct snmp_node_instance and table implementation */
141 union snmp_variant_value
142 {
143  void* ptr;
144  const void* const_ptr;
145  u32_t u32;
146  s32_t s32;
147 };
148 
149 
150 /**
151 SNMP MIB node types
152  tree node is the only node the stack can process in order to walk the tree,
153  all other nodes are assumed to be leaf nodes.
154  This cannot be an enum because users may want to define their own node types.
155 */
156 #define SNMP_NODE_TREE 0x00
157 /* predefined leaf node types */
158 #define SNMP_NODE_SCALAR 0x01
159 #define SNMP_NODE_SCALAR_ARRAY 0x02
160 #define SNMP_NODE_TABLE 0x03
161 #define SNMP_NODE_THREADSYNC 0x04
162 
163 /** node "base class" layout, the mandatory fields for a node */
164 struct snmp_node
165 {
166  /** one out of SNMP_NODE_TREE or any leaf node type (like SNMP_NODE_SCALAR) */
167  u8_t node_type;
168  /** the number assigned to this node which used as part of the full OID */
169  u32_t oid;
170 };
171 
172 /** SNMP node instance access types */
173 typedef enum {
174  SNMP_NODE_INSTANCE_ACCESS_READ = 1,
175  SNMP_NODE_INSTANCE_ACCESS_WRITE = 2,
176  SNMP_NODE_INSTANCE_READ_ONLY = SNMP_NODE_INSTANCE_ACCESS_READ,
177  SNMP_NODE_INSTANCE_READ_WRITE = (SNMP_NODE_INSTANCE_ACCESS_READ | SNMP_NODE_INSTANCE_ACCESS_WRITE),
178  SNMP_NODE_INSTANCE_WRITE_ONLY = SNMP_NODE_INSTANCE_ACCESS_WRITE,
179  SNMP_NODE_INSTANCE_NOT_ACCESSIBLE = 0
180 } snmp_access_t;
181 
182 struct snmp_node_instance;
183 
184 typedef s16_t (*node_instance_get_value_method)(struct snmp_node_instance*, void*);
185 typedef snmp_err_t (*node_instance_set_test_method)(struct snmp_node_instance*, u16_t, void*);
186 typedef snmp_err_t (*node_instance_set_value_method)(struct snmp_node_instance*, u16_t, void*);
187 typedef void (*node_instance_release_method)(struct snmp_node_instance*);
188 
189 #define SNMP_GET_VALUE_RAW_DATA 0x8000
190 
191 /** SNMP node instance */
192 struct snmp_node_instance
193 {
194  /** prefilled with the node, get_instance() is called on; may be changed by user to any value to pass an arbitrary node between calls to get_instance() and get_value/test_value/set_value */
195  const struct snmp_node* node;
196  /** prefilled with the instance id requested; for get_instance() this is the exact oid requested; for get_next_instance() this is the relative starting point, stack expects relative oid of next node here */
197  struct snmp_obj_id instance_oid;
198 
199  /** ASN type for this object (see snmp_asn1.h for definitions) */
200  u8_t asn1_type;
201  /** one out of instance access types defined above (SNMP_NODE_INSTANCE_READ_ONLY,...) */
202  snmp_access_t access;
203 
204  /** returns object value for the given object identifier. Return values <0 to indicate an error */
205  node_instance_get_value_method get_value;
206  /** tests length and/or range BEFORE setting */
207  node_instance_set_test_method set_test;
208  /** sets object value, only called when set_test() was successful */
209  node_instance_set_value_method set_value;
210  /** called in any case when the instance is not required anymore by stack (useful for freeing memory allocated in get_instance/get_next_instance methods) */
211  node_instance_release_method release_instance;
212 
213  /** reference to pass arbitrary value between calls to get_instance() and get_value/test_value/set_value */
214  union snmp_variant_value reference;
215  /** see reference (if reference is a pointer, the length of underlying data may be stored here or anything else) */
216  u32_t reference_len;
217 };
218 
219 
220 /** SNMP tree node */
221 struct snmp_tree_node
222 {
223  /** inherited "base class" members */
224  struct snmp_node node;
225  u16_t subnode_count;
226  const struct snmp_node* const *subnodes;
227 };
228 
229 #define SNMP_CREATE_TREE_NODE(oid, subnodes) \
230  {{ SNMP_NODE_TREE, (oid) }, \
231  (u16_t)LWIP_ARRAYSIZE(subnodes), (subnodes) }
232 
233 #define SNMP_CREATE_EMPTY_TREE_NODE(oid) \
234  {{ SNMP_NODE_TREE, (oid) }, \
235  0, NULL }
236 
237 /** SNMP leaf node */
238 struct snmp_leaf_node
239 {
240  /** inherited "base class" members */
241  struct snmp_node node;
242  snmp_err_t (*get_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
243  snmp_err_t (*get_next_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
244 };
245 
246 /** represents a single mib with its base oid and root node */
247 struct snmp_mib
248 {
249  const u32_t *base_oid;
250  u8_t base_oid_len;
251  const struct snmp_node *root_node;
252 };
253 
254 #define SNMP_MIB_CREATE(oid_list, root_node) { (oid_list), (u8_t)LWIP_ARRAYSIZE(oid_list), root_node }
255 
256 /** OID range structure */
257 struct snmp_oid_range
258 {
259  u32_t min;
260  u32_t max;
261 };
262 
263 /** checks if incoming OID length and values are in allowed ranges */
264 u8_t snmp_oid_in_range(const u32_t *oid_in, u8_t oid_len, const struct snmp_oid_range *oid_ranges, u8_t oid_ranges_len);
265 
266 typedef enum {
267  SNMP_NEXT_OID_STATUS_SUCCESS,
268  SNMP_NEXT_OID_STATUS_NO_MATCH,
269  SNMP_NEXT_OID_STATUS_BUF_TO_SMALL
270 } snmp_next_oid_status_t;
271 
272 /** state for next_oid_init / next_oid_check functions */
273 struct snmp_next_oid_state
274 {
275  const u32_t* start_oid;
276  u8_t start_oid_len;
277 
278  u32_t* next_oid;
279  u8_t next_oid_len;
280  u8_t next_oid_max_len;
281 
282  snmp_next_oid_status_t status;
283  void* reference;
284 };
285 
286 void snmp_next_oid_init(struct snmp_next_oid_state *state,
287  const u32_t *start_oid, u8_t start_oid_len,
288  u32_t *next_oid_buf, u8_t next_oid_max_len);
289 u8_t snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len);
290 u8_t snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len, void* reference);
291 
292 void snmp_oid_assign(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
293 void snmp_oid_combine(struct snmp_obj_id* target, const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
294 void snmp_oid_prefix(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
295 void snmp_oid_append(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
296 u8_t snmp_oid_equal(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
297 s8_t snmp_oid_compare(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
298 
299 #if LWIP_IPV4
300 u8_t snmp_oid_to_ip4(const u32_t *oid, ip4_addr_t *ip);
301 void snmp_ip4_to_oid(const ip4_addr_t *ip, u32_t *oid);
302 #endif /* LWIP_IPV4 */
303 #if LWIP_IPV6
304 u8_t snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip);
305 void snmp_ip6_to_oid(const ip6_addr_t *ip, u32_t *oid);
306 #endif /* LWIP_IPV6 */
307 #if LWIP_IPV4 || LWIP_IPV6
308 u8_t snmp_ip_to_oid(const ip_addr_t *ip, u32_t *oid);
309 u8_t snmp_ip_port_to_oid(const ip_addr_t *ip, u16_t port, u32_t *oid);
310 
311 u8_t snmp_oid_to_ip(const u32_t *oid, u8_t oid_len, ip_addr_t *ip);
312 u8_t snmp_oid_to_ip_port(const u32_t *oid, u8_t oid_len, ip_addr_t *ip, u16_t *port);
313 #endif /* LWIP_IPV4 || LWIP_IPV6 */
314 
315 struct netif;
316 u8_t netif_to_num(const struct netif *netif);
317 
318 snmp_err_t snmp_set_test_ok(struct snmp_node_instance* instance, u16_t value_len, void* value); /* generic function which can be used if test is always successful */
319 
320 err_t snmp_decode_bits(const u8_t *buf, u32_t buf_len, u32_t *bit_value);
321 err_t snmp_decode_truthvalue(const s32_t *asn1_value, u8_t *bool_value);
322 u8_t snmp_encode_bits(u8_t *buf, u32_t buf_len, u32_t bit_value, u8_t bit_count);
323 u8_t snmp_encode_truthvalue(s32_t *asn1_value, u32_t bool_value);
324 
325 struct snmp_statistics
326 {
327  u32_t inpkts;
328  u32_t outpkts;
329  u32_t inbadversions;
330  u32_t inbadcommunitynames;
331  u32_t inbadcommunityuses;
332  u32_t inasnparseerrs;
333  u32_t intoobigs;
334  u32_t innosuchnames;
335  u32_t inbadvalues;
336  u32_t inreadonlys;
337  u32_t ingenerrs;
338  u32_t intotalreqvars;
339  u32_t intotalsetvars;
340  u32_t ingetrequests;
341  u32_t ingetnexts;
342  u32_t insetrequests;
343  u32_t ingetresponses;
344  u32_t intraps;
345  u32_t outtoobigs;
346  u32_t outnosuchnames;
347  u32_t outbadvalues;
348  u32_t outgenerrs;
349  u32_t outgetrequests;
350  u32_t outgetnexts;
351  u32_t outsetrequests;
352  u32_t outgetresponses;
353  u32_t outtraps;
354 };
355 
356 extern struct snmp_statistics snmp_stats;
357 
358 #ifdef __cplusplus
359 }
360 #endif
361 
362 #endif /* LWIP_SNMP */
363 
364 #endif /* LWIP_HDR_APPS_SNMP_CORE_H */
s16_t
int16_t s16_t
Definition: arch.h:122
SNMP_MAX_OBJ_ID_LEN
#define SNMP_MAX_OBJ_ID_LEN
Definition: snmp_opts.h:131
u16_t
uint16_t u16_t
Definition: arch.h:121
u32_t
uint32_t u32_t
Definition: arch.h:123
max
#define max(a, b)
Definition: wiring_constants.h:40
state
static volatile fsensor_t state
Definition: filament_sensor.c:23
min
#define min(a, b)
Definition: wiring_constants.h:36
s32_t
int32_t s32_t
Definition: arch.h:124
u8_t
uint8_t u8_t
Definition: arch.h:119
err.h
ip_addr_t
ip6_addr_t ip_addr_t
Definition: ip_addr.h:290
netif
Definition: netif.h:225
void
void
Definition: png.h:1083
snmp_opts.h
s8_t
int8_t s8_t
Definition: arch.h:120
err_t
s8_t err_t
Definition: err.h:57
status
static status_t status
Definition: filament_sensor.c:37
ip_addr.h