BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 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 #if LWIP_HAVE_INT64
95 #define SNMP_ASN1_TYPE_COUNTER64 (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER64)
96 #endif
97  
98 #define SNMP_VARBIND_EXCEPTION_OFFSET 0xF0
99 #define SNMP_VARBIND_EXCEPTION_MASK 0x0F
100  
101 /** error codes predefined by SNMP prot. */
102 typedef enum {
103 SNMP_ERR_NOERROR = 0,
104 /*
105 outdated v1 error codes. do not use anmore!
106 #define SNMP_ERR_NOSUCHNAME 2 use SNMP_ERR_NOSUCHINSTANCE instead
107 #define SNMP_ERR_BADVALUE 3 use SNMP_ERR_WRONGTYPE,SNMP_ERR_WRONGLENGTH,SNMP_ERR_WRONGENCODING or SNMP_ERR_WRONGVALUE instead
108 #define SNMP_ERR_READONLY 4 use SNMP_ERR_NOTWRITABLE instead
109 */
110 SNMP_ERR_GENERROR = 5,
111 SNMP_ERR_NOACCESS = 6,
112 SNMP_ERR_WRONGTYPE = 7,
113 SNMP_ERR_WRONGLENGTH = 8,
114 SNMP_ERR_WRONGENCODING = 9,
115 SNMP_ERR_WRONGVALUE = 10,
116 SNMP_ERR_NOCREATION = 11,
117 SNMP_ERR_INCONSISTENTVALUE = 12,
118 SNMP_ERR_RESOURCEUNAVAILABLE = 13,
119 SNMP_ERR_COMMITFAILED = 14,
120 SNMP_ERR_UNDOFAILED = 15,
121 SNMP_ERR_NOTWRITABLE = 17,
122 SNMP_ERR_INCONSISTENTNAME = 18,
123  
124 SNMP_ERR_NOSUCHINSTANCE = SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE
125 } snmp_err_t;
126  
127 /** internal object identifier representation */
128 struct snmp_obj_id
129 {
130 u8_t len;
131 u32_t id[SNMP_MAX_OBJ_ID_LEN];
132 };
133  
134 struct snmp_obj_id_const_ref
135 {
136 u8_t len;
137 const u32_t* id;
138 };
139  
140 extern const struct snmp_obj_id_const_ref snmp_zero_dot_zero; /* administrative identifier from SNMPv2-SMI */
141  
142 /** SNMP variant value, used as reference in struct snmp_node_instance and table implementation */
143 union snmp_variant_value
144 {
145 void* ptr;
146 const void* const_ptr;
147 u32_t u32;
148 s32_t s32;
149 #if LWIP_HAVE_INT64
150 u64_t u64;
151 #endif
152 };
153  
154  
155 /**
156 SNMP MIB node types
157 tree node is the only node the stack can process in order to walk the tree,
158 all other nodes are assumed to be leaf nodes.
159 This cannot be an enum because users may want to define their own node types.
160 */
161 #define SNMP_NODE_TREE 0x00
162 /* predefined leaf node types */
163 #define SNMP_NODE_SCALAR 0x01
164 #define SNMP_NODE_SCALAR_ARRAY 0x02
165 #define SNMP_NODE_TABLE 0x03
166 #define SNMP_NODE_THREADSYNC 0x04
167  
168 /** node "base class" layout, the mandatory fields for a node */
169 struct snmp_node
170 {
171 /** one out of SNMP_NODE_TREE or any leaf node type (like SNMP_NODE_SCALAR) */
172 u8_t node_type;
173 /** the number assigned to this node which used as part of the full OID */
174 u32_t oid;
175 };
176  
177 /** SNMP node instance access types */
178 typedef enum {
179 SNMP_NODE_INSTANCE_ACCESS_READ = 1,
180 SNMP_NODE_INSTANCE_ACCESS_WRITE = 2,
181 SNMP_NODE_INSTANCE_READ_ONLY = SNMP_NODE_INSTANCE_ACCESS_READ,
182 SNMP_NODE_INSTANCE_READ_WRITE = (SNMP_NODE_INSTANCE_ACCESS_READ | SNMP_NODE_INSTANCE_ACCESS_WRITE),
183 SNMP_NODE_INSTANCE_WRITE_ONLY = SNMP_NODE_INSTANCE_ACCESS_WRITE,
184 SNMP_NODE_INSTANCE_NOT_ACCESSIBLE = 0
185 } snmp_access_t;
186  
187 struct snmp_node_instance;
188  
189 typedef s16_t (*node_instance_get_value_method)(struct snmp_node_instance*, void*);
190 typedef snmp_err_t (*node_instance_set_test_method)(struct snmp_node_instance*, u16_t, void*);
191 typedef snmp_err_t (*node_instance_set_value_method)(struct snmp_node_instance*, u16_t, void*);
192 typedef void (*node_instance_release_method)(struct snmp_node_instance*);
193  
194 #define SNMP_GET_VALUE_RAW_DATA 0x8000
195  
196 /** SNMP node instance */
197 struct snmp_node_instance
198 {
199 /** 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 */
200 const struct snmp_node* node;
201 /** 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 */
202 struct snmp_obj_id instance_oid;
203  
204 /** ASN type for this object (see snmp_asn1.h for definitions) */
205 u8_t asn1_type;
206 /** one out of instance access types defined above (SNMP_NODE_INSTANCE_READ_ONLY,...) */
207 snmp_access_t access;
208  
209 /** returns object value for the given object identifier. Return values <0 to indicate an error */
210 node_instance_get_value_method get_value;
211 /** tests length and/or range BEFORE setting */
212 node_instance_set_test_method set_test;
213 /** sets object value, only called when set_test() was successful */
214 node_instance_set_value_method set_value;
215 /** 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) */
216 node_instance_release_method release_instance;
217  
218 /** reference to pass arbitrary value between calls to get_instance() and get_value/test_value/set_value */
219 union snmp_variant_value reference;
220 /** see reference (if reference is a pointer, the length of underlying data may be stored here or anything else) */
221 u32_t reference_len;
222 };
223  
224  
225 /** SNMP tree node */
226 struct snmp_tree_node
227 {
228 /** inherited "base class" members */
229 struct snmp_node node;
230 u16_t subnode_count;
231 const struct snmp_node* const *subnodes;
232 };
233  
234 #define SNMP_CREATE_TREE_NODE(oid, subnodes) \
235 {{ SNMP_NODE_TREE, (oid) }, \
236 (u16_t)LWIP_ARRAYSIZE(subnodes), (subnodes) }
237  
238 #define SNMP_CREATE_EMPTY_TREE_NODE(oid) \
239 {{ SNMP_NODE_TREE, (oid) }, \
240 0, NULL }
241  
242 /** SNMP leaf node */
243 struct snmp_leaf_node
244 {
245 /** inherited "base class" members */
246 struct snmp_node node;
247 snmp_err_t (*get_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
248 snmp_err_t (*get_next_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
249 };
250  
251 /** represents a single mib with its base oid and root node */
252 struct snmp_mib
253 {
254 const u32_t *base_oid;
255 u8_t base_oid_len;
256 const struct snmp_node *root_node;
257 };
258  
259 #define SNMP_MIB_CREATE(oid_list, root_node) { (oid_list), (u8_t)LWIP_ARRAYSIZE(oid_list), root_node }
260  
261 /** OID range structure */
262 struct snmp_oid_range
263 {
264 u32_t min;
265 u32_t max;
266 };
267  
268 /** checks if incoming OID length and values are in allowed ranges */
269 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);
270  
271 typedef enum {
272 SNMP_NEXT_OID_STATUS_SUCCESS,
273 SNMP_NEXT_OID_STATUS_NO_MATCH,
274 SNMP_NEXT_OID_STATUS_BUF_TO_SMALL
275 } snmp_next_oid_status_t;
276  
277 /** state for next_oid_init / next_oid_check functions */
278 struct snmp_next_oid_state
279 {
280 const u32_t* start_oid;
281 u8_t start_oid_len;
282  
283 u32_t* next_oid;
284 u8_t next_oid_len;
285 u8_t next_oid_max_len;
286  
287 snmp_next_oid_status_t status;
288 void* reference;
289 };
290  
291 void snmp_next_oid_init(struct snmp_next_oid_state *state,
292 const u32_t *start_oid, u8_t start_oid_len,
293 u32_t *next_oid_buf, u8_t next_oid_max_len);
294 u8_t snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, u8_t oid_len);
295 u8_t snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, u8_t oid_len, void* reference);
296  
297 void snmp_oid_assign(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
298 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);
299 void snmp_oid_prefix(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
300 void snmp_oid_append(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
301 u8_t snmp_oid_equal(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
302 s8_t snmp_oid_compare(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
303  
304 #if LWIP_IPV4
305 u8_t snmp_oid_to_ip4(const u32_t *oid, ip4_addr_t *ip);
306 void snmp_ip4_to_oid(const ip4_addr_t *ip, u32_t *oid);
307 #endif /* LWIP_IPV4 */
308 #if LWIP_IPV6
309 u8_t snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip);
310 void snmp_ip6_to_oid(const ip6_addr_t *ip, u32_t *oid);
311 #endif /* LWIP_IPV6 */
312 #if LWIP_IPV4 || LWIP_IPV6
313 u8_t snmp_ip_to_oid(const ip_addr_t *ip, u32_t *oid);
314 u8_t snmp_ip_port_to_oid(const ip_addr_t *ip, u16_t port, u32_t *oid);
315  
316 u8_t snmp_oid_to_ip(const u32_t *oid, u8_t oid_len, ip_addr_t *ip);
317 u8_t snmp_oid_to_ip_port(const u32_t *oid, u8_t oid_len, ip_addr_t *ip, u16_t *port);
318 #endif /* LWIP_IPV4 || LWIP_IPV6 */
319  
320 struct netif;
321 u8_t netif_to_num(const struct netif *netif);
322  
323 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 */
324  
325 err_t snmp_decode_bits(const u8_t *buf, u32_t buf_len, u32_t *bit_value);
326 err_t snmp_decode_truthvalue(const s32_t *asn1_value, u8_t *bool_value);
327 u8_t snmp_encode_bits(u8_t *buf, u32_t buf_len, u32_t bit_value, u8_t bit_count);
328 u8_t snmp_encode_truthvalue(s32_t *asn1_value, u32_t bool_value);
329  
330 struct snmp_statistics
331 {
332 u32_t inpkts;
333 u32_t outpkts;
334 u32_t inbadversions;
335 u32_t inbadcommunitynames;
336 u32_t inbadcommunityuses;
337 u32_t inasnparseerrs;
338 u32_t intoobigs;
339 u32_t innosuchnames;
340 u32_t inbadvalues;
341 u32_t inreadonlys;
342 u32_t ingenerrs;
343 u32_t intotalreqvars;
344 u32_t intotalsetvars;
345 u32_t ingetrequests;
346 u32_t ingetnexts;
347 u32_t insetrequests;
348 u32_t ingetresponses;
349 u32_t intraps;
350 u32_t outtoobigs;
351 u32_t outnosuchnames;
352 u32_t outbadvalues;
353 u32_t outgenerrs;
354 u32_t outgetrequests;
355 u32_t outgetnexts;
356 u32_t outsetrequests;
357 u32_t outgetresponses;
358 u32_t outtraps;
359 #if LWIP_SNMP_V3
360 u32_t unsupportedseclevels;
361 u32_t notintimewindows;
362 u32_t unknownusernames;
363 u32_t unknownengineids;
364 u32_t wrongdigests;
365 u32_t decryptionerrors;
366 #endif
367 };
368  
369 extern struct snmp_statistics snmp_stats;
370  
371 #ifdef __cplusplus
372 }
373 #endif
374  
375 #endif /* LWIP_SNMP */
376  
377 #endif /* LWIP_HDR_APPS_SNMP_CORE_H */