1 /* This NetX test concentrates on the basic SNMPv1 operation. The 'manager' sends
2 a request for an unknown item ("oid"). The SNMP agent should not responds, but
3 set an internal error and be able to respond to the next request.
4
5 The MIB database is defined in demo_snmp_helper.h */
6
7
8 #include "tx_api.h"
9 #include "nx_api.h"
10 #include "nxd_snmp.h"
11 #include "nx_udp.h"
12 #include "small_mib_helper.h"
13
14 extern void test_control_return(UINT);
15
16 #if !defined(NX_DISABLE_IPV4)
17
18 #define DEMO_STACK_SIZE 4096
19
20 extern MIB_ENTRY mib2_mib[];
21
22 static UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data);
23 static UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data);
24 static UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data);
25 static UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username);
26 static VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr);
27
28 /* Define the ThreadX and NetX object control blocks... */
29
30 static TX_THREAD thread_agent;
31 static NX_SNMP_AGENT my_agent;
32 static NX_PACKET_POOL pool_0;
33 static NX_IP agent_ip;
34
35 #define SNMP_AGENT_ADDRESS IP_ADDRESS(10, 128, 16, 17)
36
37
38 /* Define the counters used in the demo application... */
39
40 static UINT status;
41 static ULONG error_counter;
42 static ULONG snmp_stack[DEMO_STACK_SIZE / sizeof(ULONG)];
43
44
45 /* Define thread prototypes. */
46
47 static void thread_0_entry(ULONG thread_input);
48 static void thread_1_entry(ULONG thread_input);
49 extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req);
50 static void snmp_test_initialize();
51
52 /* Inject SNMP manager query. */
53 static VOID packet_inject(UCHAR *data_ptr, UINT data_size);
54
55 extern unsigned char v1_double_release_packet[1421];
56 extern int v1_double_release_packet_size;
57
58 #define QUERY_COUNT 1
59
60 typedef struct SNMP_QUERY_STRUCT
61 {
62 char *snmp_query_pkt_data;
63 int snmp_query_pkt_size;
64 } SNMP_QUERY;
65
66
67 static SNMP_QUERY snmp_query[QUERY_COUNT];
68
69
70 #ifdef CTEST
test_application_define(void * first_unused_memory)71 VOID test_application_define(void *first_unused_memory)
72 #else
73 void netx_snmp_v1_packet_double_release_test_application_define(void *first_unused_memory)
74 #endif
75 {
76
77 CHAR *pointer;
78
79 /* Setup the working pointer. */
80 pointer = (CHAR *) first_unused_memory;
81
82 /* Create the SNMP agent thread. */
83 tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0,
84 pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
85
86 pointer = pointer + DEMO_STACK_SIZE;
87
88 /* Initialize the NetX system. */
89 nx_system_initialize();
90
91 /* Create a packet pool. */
92 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, (sizeof(NX_PACKET) + 1536) * 10);
93 pointer = pointer + (sizeof(NX_PACKET) + 1536) * 10;
94
95 /* Create an IP instance. */
96 status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500,
97 pointer, 2048, 1);
98 pointer = pointer + 2048;
99
100 /* Check for IP create errors. */
101 if (status)
102 {
103 error_counter++;
104 }
105
106 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
107 status = nx_arp_enable(&agent_ip, (void *) pointer, 1024);
108 pointer = pointer + 1024;
109
110 /* Check for ARP enable errors. */
111 if (status)
112 {
113 error_counter++;
114 }
115
116 /* Enable UDP traffic. */
117 status = nx_udp_enable(&agent_ip);
118
119 /* Check for UDP enable errors. */
120 if (status)
121 {
122 error_counter++;
123 }
124 }
125
126 /* Define the test threads. */
127
thread_0_entry(ULONG thread_input)128 static void thread_0_entry(ULONG thread_input)
129 {
130
131 UINT status;
132 UINT i;
133 NX_PACKET *packet_ptr;
134
135 printf("NetX Test: SNMP V1 Packet Double Release Test........................");
136
137 if (error_counter)
138 {
139 printf("ERROR!\n");
140 test_control_return(1);
141 }
142
143 /* Create an SNMP agent instance. */
144 status = nx_snmp_agent_create(&my_agent, "SNMP Agent", &agent_ip, snmp_stack, sizeof(snmp_stack), &pool_0,
145 mib2_username_processing, mib2_get_processing,
146 mib2_getnext_processing, mib2_set_processing);
147
148 if (status)
149 {
150 error_counter++;
151 }
152
153 /* Start the SNMP instance. */
154 status = nx_snmp_agent_start(&my_agent);
155
156 /* Return the test result. */
157 if (status)
158 {
159 error_counter++;
160 }
161
162 /* Load the test data up. */
163 snmp_test_initialize();
164
165 /* Send SNMP queries to the agent. */
166 for (i = 0; i < QUERY_COUNT; i++ )
167 {
168
169 /* Inject the SNMP manager query packet. */
170 packet_inject(snmp_query[i].snmp_query_pkt_data, snmp_query[i].snmp_query_pkt_size);
171 }
172
173 /* Wait for processing snmp packet. */
174 tx_thread_sleep(NX_IP_PERIODIC_RATE);
175
176 /* Check if there is invalid packet release. */
177 if (pool_0.nx_packet_pool_invalid_releases)
178 {
179 printf("ERROR!\n");
180 test_control_return(1);
181 }
182
183 if (error_counter)
184 {
185 printf("ERROR!\n");
186 test_control_return(1);
187 }
188 else
189 {
190 printf("SUCCESS!\n");
191 test_control_return(0);
192 }
193
194 }
195
packet_inject(UCHAR * data_ptr,UINT data_size)196 static VOID packet_inject(UCHAR *data_ptr, UINT data_size)
197 {
198 UINT status;
199 NX_PACKET *my_packet;
200
201 status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT);
202
203 /* Check status */
204 if(status)
205 error_counter ++;
206
207 /* Make sure IP header is 4-byte aligned. */
208 my_packet -> nx_packet_prepend_ptr += 2;
209 my_packet -> nx_packet_append_ptr += 2;
210
211 /* Fill in the packet with data. Skip the MAC header. */
212 status = nx_packet_data_append(my_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT);
213
214 /* Check status */
215 if(status)
216 error_counter ++;
217
218 /* Skip the MAC header. */
219 my_packet -> nx_packet_length -= 14;
220 my_packet -> nx_packet_prepend_ptr += 14;
221
222 /* Directly receive the TCP packet. */
223 _nx_ip_packet_deferred_receive(&agent_ip, my_packet);
224 }
225
snmp_test_initialize()226 static void snmp_test_initialize()
227 {
228 snmp_query[0].snmp_query_pkt_data = &v1_double_release_packet[0];
229 snmp_query[0].snmp_query_pkt_size = v1_double_release_packet_size;
230 }
231
232
233 /* Define the application's GET processing routine. */
234
mib2_get_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data)235 UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data)
236 {
237
238 UINT i;
239 UINT status;
240
241
242
243 /* Loop through the sample MIB to see if we have information for the supplied variable. */
244 i = 0;
245 status = NX_SNMP_ERROR;
246 while (mib2_mib[i].object_name)
247 {
248
249 /* See if we have found the matching entry. */
250 status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name);
251
252 /* Was it found? */
253 if (status == NX_SUCCESS)
254 {
255
256 /* Yes it was found. */
257 break;
258 }
259
260 /* Move to the next index. */
261 i++;
262 }
263
264 /* Determine if a not found condition is present. */
265 if (status != NX_SUCCESS)
266 {
267
268 /* The object was not found - return an error. */
269 return(NX_SNMP_ERROR_NOSUCHNAME);
270 }
271
272 /* Determine if the entry has a get function. */
273 if (mib2_mib[i].object_get_callback)
274 {
275
276 /* Yes, call the get function. */
277 status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data);
278 }
279 else
280 {
281
282 /* No get function, return no access. */
283 status = NX_SNMP_ERROR_NOACCESS;
284 }
285
286 /* Return the status. */
287 return(status);
288 }
289
290
291 /* Define the application's GETNEXT processing routine. */
292
mib2_getnext_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data)293 UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data)
294 {
295
296 UINT i;
297 UINT status;
298
299
300 /* Loop through the sample MIB to see if we have information for the supplied variable. */
301 i = 0;
302 status = NX_SNMP_ERROR;
303 while (mib2_mib[i].object_name)
304 {
305
306 /* See if we have found the next entry. */
307 status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name);
308
309 /* Is the next entry the mib greater? */
310 if (status == NX_SNMP_NEXT_ENTRY)
311 {
312
313 /* Yes it was found. */
314 break;
315 }
316
317 /* Move to the next index. */
318 i++;
319 }
320
321 /* Determine if a not found condition is present. */
322 if (status != NX_SNMP_NEXT_ENTRY)
323 {
324
325 /* The object was not found - return an error. */
326 return(NX_SNMP_ERROR_NOSUCHNAME);
327 }
328
329
330 /* Copy the new name into the object. */
331 nx_snmp_object_copy(mib2_mib[i].object_name, object_requested);
332
333 /* Determine if the entry has a get function. */
334 if (mib2_mib[i].object_get_callback)
335 {
336
337 /* Yes, call the get function. */
338 status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data);
339
340 /* Determine if the object data indicates an end-of-mib condition. */
341 if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW)
342 {
343
344 /* Copy the name supplied in the mib table. */
345 nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested);
346 }
347 }
348 else
349 {
350
351 /* No get function, return no access. */
352 status = NX_SNMP_ERROR_NOACCESS;
353 }
354
355 /* Return the status. */
356 return(status);
357 }
358
359
360 /* Define the application's SET processing routine. */
361
mib2_set_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data)362 UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data)
363 {
364
365 UINT i;
366 UINT status;
367
368
369 /* Loop through the sample MIB to see if we have information for the supplied variable. */
370 i = 0;
371 status = NX_SNMP_ERROR;
372 while (mib2_mib[i].object_name)
373 {
374
375 /* See if we have found the matching entry. */
376 status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name);
377
378 /* Was it found? */
379 if (status == NX_SUCCESS)
380 {
381
382 /* Yes it was found. */
383 break;
384 }
385
386 /* Move to the next index. */
387 i++;
388 }
389
390 /* Determine if a not found condition is present. */
391 if (status != NX_SUCCESS)
392 {
393
394 /* The object was not found - return an error. */
395 return(NX_SNMP_ERROR_NOSUCHNAME);
396 }
397
398
399 /* Determine if the entry has a set function. */
400 if (mib2_mib[i].object_set_callback)
401 {
402
403 /* Yes, call the set function. */
404 status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data);
405 }
406 else
407 {
408
409 /* No get function, return no access. */
410 status = NX_SNMP_ERROR_NOACCESS;
411 }
412
413
414 /* Return the status. */
415 return(status);
416 }
417
418 /* Create an error code if matching user not found. */
419 #define USER_NOT_FOUND 1
420
421 /* Define the username callback routine routine. Usernames should be
422 associated with permissions (public or private string) and what version
423 of SNMP the user is configured for. The username callback should verify
424 the incoming username MIB access permissions. */
mib2_username_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * username)425 UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username)
426 {
427
428 mib2_variable_update(&agent_ip, &my_agent);
429
430 return NX_SUCCESS;
431
432 }
433
434 /* Define the application's update routine. */
435
mib2_variable_update(NX_IP * ip_ptr,NX_SNMP_AGENT * agent_ptr)436 VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr)
437 {
438
439 /* Update the snmp parameters. */
440 return;
441 }
442 #else
443
444 #ifdef CTEST
test_application_define(void * first_unused_memory)445 VOID test_application_define(void *first_unused_memory)
446 #else
447 void netx_snmp_v1_packet_double_release_test_application_define(void *first_unused_memory)
448 #endif
449 {
450
451 /* Print out test information banner. */
452 printf("NetX Test: SNMP V1 Packet Double Release Test........................N/A\n");
453
454 test_control_return(3);
455 }
456 #endif
457
458