1 /* This SNMP Agent test sends a V2 trap with a non null trap list. A successful result is the correction
2 number of messages/packets sent and no internal errors. */
3
4
5 #include "tx_api.h"
6 #include "nx_api.h"
7 #include "nxd_snmp.h"
8 #include "nx_udp.h"
9 #include "small_mib_helper.h"
10
11 extern void test_control_return(UINT);
12
13 #if !defined(NX_DISABLE_IPV4)
14
15 #define DEMO_STACK_SIZE 4096
16
17
18 extern MIB_ENTRY mib2_mib[];
19
20 static UINT v2query_response_complete = NX_FALSE;
21
22 static UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data);
23 static UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data);
24 static UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data);
25 static UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username);
26 static VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr);
27
28 #define QUERY_COUNT 1
29
30 /* Define the ThreadX and NetX object control blocks... */
31
32 static TX_THREAD thread_agent;
33 static TX_THREAD thread_manager;
34 static NX_SNMP_AGENT v2_my_agent;
35 static NX_PACKET_POOL v2_pool_0;
36 static NX_IP agent_ip;
37 static NX_IP manager_ip;
38
39 static NX_UDP_SOCKET snmp_manager_socket;
40
41 #define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1)
42 #define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10)
43
44
45 /* Define the counters used in the demo application... */
46
47 static UINT status;
48 static ULONG error_counter;
49
50
51 /* Define thread prototypes. */
52
53 static void thread_0_entry(ULONG thread_input);
54 static void thread_1_entry(ULONG thread_input);
55 extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req);
56 static void snmp_test_initialize();
57
58
59 /* Send SNMP manager query. */
60 static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number);
61
62 extern char simple_get_query_pkt[82];
63 extern int simple_get_query_size;
64
65 typedef struct SNMP_QUERY_STRUCT
66 {
67 char *snmp_query_pkt_data;
68 int snmp_query_pkt_size;
69 } SNMP_QUERY;
70
71
72 static SNMP_QUERY snmp_query[QUERY_COUNT];
73
74
75 #ifdef CTEST
test_application_define(void * first_unused_memory)76 VOID test_application_define(void *first_unused_memory)
77 #else
78 void netx_snmp_v2_send_trap_test_application_define(void *first_unused_memory)
79 #endif
80 {
81
82 CHAR *pointer;
83
84 /* Setup the working pointer. */
85 pointer = (CHAR *) first_unused_memory;
86
87 /* Create the SNMP agent thread. */
88 tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0,
89 pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
90
91 pointer = pointer + DEMO_STACK_SIZE;
92
93 /* Create the SNMP Manager thread. */
94 tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0,
95 pointer, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
96
97 pointer = pointer + DEMO_STACK_SIZE;
98
99
100 /* Initialize the NetX system. */
101 nx_system_initialize();
102
103 /* Create a packet pool. */
104 status = nx_packet_pool_create(&v2_pool_0, "NetX Main Packet Pool", 1000, pointer, 4096);
105 pointer = pointer + 4096;
106
107 /* Create an IP instance. */
108 status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500,
109 pointer, 2048, 1);
110 pointer = pointer + 2048;
111
112 /* Create another IP instance. */
113 status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500,
114 pointer, 2048, 1);
115 pointer = pointer + 2048;
116
117 /* Check for IP create errors. */
118 if (status)
119 {
120
121 error_counter++;
122 }
123
124 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
125 status = nx_arp_enable(&agent_ip, (void *) pointer, 1024);
126 pointer = pointer + 1024;
127
128 /* Enable ARP and supply ARP cache memory for IP Instance 1. */
129 status += nx_arp_enable(&manager_ip, (void *) pointer, 1024);
130 pointer = pointer + 1024;
131
132 /* Check for ARP enable errors. */
133 if (status)
134 {
135 error_counter++;
136 }
137
138 /* Enable UDP traffic. */
139 status = nx_udp_enable(&agent_ip);
140 status += nx_udp_enable(&manager_ip);
141
142 /* Check for UDP enable errors. */
143 if (status)
144 {
145 error_counter++;
146 }
147
148 /* Create an SNMP agent instance. */
149 status = nx_snmp_agent_create(&v2_my_agent, "SNMP Agent", &agent_ip, pointer, 4096, &v2_pool_0,
150 v2_mib2_username_processing, v2_mib2_get_processing,
151 v2_mib2_getnext_processing, v2_mib2_set_processing);
152
153 if (status)
154 {
155 error_counter++;
156 }
157
158 return;
159 }
160
161
162
163 /* Define the test threads. */
164
thread_0_entry(ULONG thread_input)165 static void thread_0_entry(ULONG thread_input)
166 {
167
168 UINT status;
169 NX_SNMP_TRAP_OBJECT trap_list[7];
170 NX_SNMP_OBJECT_DATA trap_data0;
171 NX_SNMP_OBJECT_DATA trap_data1;
172 NX_SNMP_OBJECT_DATA trap_data2;
173 NX_SNMP_OBJECT_DATA trap_data3;
174 NX_SNMP_OBJECT_DATA trap_data4;
175 NX_SNMP_OBJECT_DATA trap_data5;
176 UINT counter = 133;
177
178
179 printf("NetX Test: SNMP V2 Send Trap Test....................................");
180
181 if (error_counter)
182 {
183 printf("ERROR!\n");
184 test_control_return(1);
185 }
186
187 /* Start the SNMP instance. */
188 status = nx_snmp_agent_start(&v2_my_agent);
189
190 /* Return the test result. */
191 if (status)
192 {
193 error_counter++;
194 }
195
196 /* Wait for the 'manager' to finish querying the Agent. */
197 while (v2query_response_complete == NX_FALSE)
198 {
199 tx_thread_sleep(100);
200 }
201
202
203 /* Now send the traps. */
204 /* Send trap to indicate the link is up. */
205 trap_list[0].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.1.0";
206 trap_list[0].nx_snmp_object_data = &trap_data0;
207 trap_data0.nx_snmp_object_data_type = NX_SNMP_INTEGER;
208 trap_data0.nx_snmp_object_data_msw = counter++;
209
210 trap_list[1].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.7.0";
211 trap_list[1].nx_snmp_object_data = &trap_data1;
212 trap_data1.nx_snmp_object_data_type = NX_SNMP_INTEGER;
213 trap_data1.nx_snmp_object_data_msw = counter++;
214
215 /* Null terminate the list. */
216 trap_list[2].nx_snmp_object_string_ptr = NX_NULL;
217 trap_list[2].nx_snmp_object_data = NX_NULL;
218 #if 1
219 trap_list[2].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.8.0";
220 trap_list[2].nx_snmp_object_data = &trap_data2;
221 trap_data2.nx_snmp_object_data_type = NX_SNMP_INTEGER;
222 trap_data2.nx_snmp_object_data_msw = tx_time_get();
223
224 trap_list[3].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.9.0";
225 trap_list[3].nx_snmp_object_data = &trap_data3;
226 trap_data3.nx_snmp_object_data_type = NX_SNMP_INTEGER;
227 trap_data3.nx_snmp_object_data_msw = counter++;
228
229 trap_list[4].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.10.0.1";
230 trap_list[4].nx_snmp_object_data = &trap_data4;
231 trap_data4.nx_snmp_object_data_type = NX_SNMP_INTEGER;
232 trap_data4.nx_snmp_object_data_msw = tx_time_get();
233
234
235 trap_list[5].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.10.0.2";
236 trap_list[5].nx_snmp_object_data = &trap_data5;
237 trap_data5.nx_snmp_object_data_type = NX_SNMP_INTEGER;
238 trap_data5.nx_snmp_object_data_msw = counter++;
239
240 /* Null terminate the list. */
241 trap_list[6].nx_snmp_object_string_ptr = NX_NULL;
242 trap_list[6].nx_snmp_object_data = NX_NULL;
243 #endif
244
245 status = nx_snmp_agent_trapv2_send(&v2_my_agent, SNMP_MANAGER_ADDRESS, (UCHAR *)"trap", NX_SNMP_TRAP_COLDSTART, tx_time_get(), &trap_list[0]);
246
247 if (status)
248 {
249 error_counter++;
250 }
251
252
253 /* Check for correct internal counters of SNMP processing. */
254 if ((v2_my_agent.nx_snmp_agent_get_requests != 1) ||
255 (v2_my_agent.nx_snmp_agent_total_get_variables != 1) ||
256 (v2_my_agent.nx_snmp_agent_packets_received != 1) ||
257 (v2_my_agent.nx_snmp_agent_packets_sent != 2) ||
258 (v2_my_agent.nx_snmp_agent_getresponse_sent != 1) ||
259 (v2_my_agent.nx_snmp_agent_traps_sent != 1))
260 {
261 error_counter++;
262 }
263
264
265 /* Check for errors processing the request and sending the trap. */
266 if (v2_my_agent.nx_snmp_agent_invalid_packets ||
267 v2_my_agent.nx_snmp_agent_internal_errors ||
268 v2_my_agent.nx_snmp_agent_allocation_errors ||
269 v2_my_agent.nx_snmp_agent_request_errors ||
270 v2_my_agent.nx_snmp_agent_too_big_errors ||
271 v2_my_agent.nx_snmp_agent_username_errors ||
272 v2_my_agent.nx_snmp_agent_unknown_requests)
273 {
274
275 error_counter++;
276 }
277
278 if (error_counter)
279 {
280 printf("ERROR!\n");
281 test_control_return(1);
282 }
283 else
284 {
285 printf("SUCCESS!\n");
286 test_control_return(0);
287 }
288
289 return;
290
291 }
292
293 /* SNMP Manager thread */
thread_1_entry(ULONG thread_input)294 static void thread_1_entry(ULONG thread_input)
295 {
296
297 NX_PACKET *agent_packet;
298 UINT port;
299 UINT i;
300 USHORT request_id = 1;
301
302 /* Let the agent get set up first! */
303 tx_thread_sleep(50);
304
305 /* Create a UDP socket act as the DNS server. */
306 status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
307
308 /* Check status. */
309 if (status)
310 {
311 error_counter++;
312 v2query_response_complete = NX_TRUE;
313 }
314
315 /* Bind the UDP socket to the IP port. */
316 status = nx_udp_socket_bind(&snmp_manager_socket, 161, 200);
317
318
319 /* Check status. */
320 if (status)
321 {
322 error_counter++;
323 v2query_response_complete = NX_TRUE;
324 }
325
326 /* Load the test data up. */
327 snmp_test_initialize();
328
329 /* Send SNMP queries to the agent. */
330 for (i = 0; i < QUERY_COUNT; i++ )
331 {
332
333 /* Send the SNMP manager query packet. */
334 status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i);
335
336 /* Check status. */
337 if (status)
338 {
339
340 error_counter++;
341 v2query_response_complete = NX_TRUE;
342 break;
343 }
344
345 /* Receive the SNMP agent response. */
346 status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 200);
347
348 /* Check status. */
349 if (status)
350 {
351
352 error_counter++;
353 v2query_response_complete = NX_TRUE;
354 break;
355 }
356
357 /* Get the SNMP agent UDP port. */
358 status = nx_udp_packet_info_extract(agent_packet, NX_NULL ,NX_NULL, &port, NX_NULL);
359
360 /* Check status. */
361
362 if (status)
363 {
364
365 error_counter++;
366 v2query_response_complete = NX_TRUE;
367 break;
368 }
369
370 /* Release the packet. */
371 nx_packet_release(agent_packet);
372
373 request_id++;
374 }
375
376 /* Indicate the test is complete. */
377 v2query_response_complete = NX_TRUE;
378
379 /* Unbind the UDP socket. */
380 nx_udp_socket_unbind(&snmp_manager_socket);
381
382 /* Delete the UDP socket. */
383 nx_udp_socket_delete(&snmp_manager_socket);
384
385 return;
386 }
387
388
nx_snmp_query_packet_send(NX_UDP_SOCKET * snmp_manager_socket,UINT snmp_request_id,UINT packet_number)389 static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number)
390 {
391 UINT status;
392 NX_PACKET *response_packet;
393
394
395 /* Allocate a response packet. */
396 status = nx_packet_allocate(&v2_pool_0, &response_packet, NX_UDP_PACKET, 200);
397
398 /* Check status. */
399 if (status)
400 {
401
402 error_counter++;
403 return(1);
404 }
405
406 memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr));
407
408 /* Write the SMTP response messages into the packet payload! */
409 memcpy(response_packet -> nx_packet_prepend_ptr,
410 snmp_query[packet_number].snmp_query_pkt_data,
411 snmp_query[packet_number].snmp_query_pkt_size);
412
413 /* Adjust the write pointer. */
414 response_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size;
415 response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length;
416
417 /* Send the UDP packet with the correct port. */
418 status = nx_udp_socket_send(snmp_manager_socket, response_packet, IP_ADDRESS(10, 0, 0, 10), 161);
419
420 /* Check the status. */
421 if (status)
422 {
423
424 error_counter++;
425 nx_packet_release(response_packet);
426 }
427
428 return status;
429 }
430
431
snmp_test_initialize()432 static void snmp_test_initialize()
433 {
434
435 snmp_query[0].snmp_query_pkt_data = &simple_get_query_pkt[0];
436 snmp_query[0].snmp_query_pkt_size = simple_get_query_size;
437
438 }
439
440
441 /* Define the application's GET processing routine. */
442
v2_mib2_get_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data)443 UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data)
444 {
445
446 UINT i;
447 UINT status;
448
449
450
451 /* Loop through the sample MIB to see if we have information for the supplied variable. */
452 i = 0;
453 status = NX_SNMP_ERROR;
454 while (mib2_mib[i].object_name)
455 {
456
457 /* See if we have found the matching entry. */
458 status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name);
459
460 /* Was it found? */
461 if (status == NX_SUCCESS)
462 {
463
464 /* Yes it was found. */
465 break;
466 }
467
468 /* Move to the next index. */
469 i++;
470 }
471
472 /* Determine if a not found condition is present. */
473 if (status != NX_SUCCESS)
474 {
475
476 /* The object was not found - return an error. */
477 return(NX_SNMP_ERROR_NOSUCHNAME);
478 }
479
480 /* Determine if the entry has a get function. */
481 if (mib2_mib[i].object_get_callback)
482 {
483
484 /* Yes, call the get function. */
485 status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data);
486 }
487 else
488 {
489
490 /* No get function, return no access. */
491 status = NX_SNMP_ERROR_NOACCESS;
492 }
493
494 /* Return the status. */
495 return(status);
496 }
497
498
499 /* Define the application's GETNEXT processing routine. */
500
v2_mib2_getnext_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data)501 UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data)
502 {
503
504 UINT i;
505 UINT status;
506
507
508 /* Loop through the sample MIB to see if we have information for the supplied variable. */
509 i = 0;
510 status = NX_SNMP_ERROR;
511 while (mib2_mib[i].object_name)
512 {
513
514 /* See if we have found the next entry. */
515 status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name);
516
517 /* Is the next entry the mib greater? */
518 if (status == NX_SNMP_NEXT_ENTRY)
519 {
520
521 /* Yes it was found. */
522 break;
523 }
524
525 /* Move to the next index. */
526 i++;
527 }
528
529 /* Determine if a not found condition is present. */
530 if (status != NX_SNMP_NEXT_ENTRY)
531 {
532
533 /* The object was not found - return an error. */
534 return(NX_SNMP_ERROR_NOSUCHNAME);
535 }
536
537
538 /* Copy the new name into the object. */
539 nx_snmp_object_copy(mib2_mib[i].object_name, object_requested);
540
541 /* Determine if the entry has a get function. */
542 if (mib2_mib[i].object_get_callback)
543 {
544
545 /* Yes, call the get function. */
546 status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data);
547
548 /* Determine if the object data indicates an end-of-mib condition. */
549 if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW)
550 {
551
552 /* Copy the name supplied in the mib table. */
553 nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested);
554 }
555 }
556 else
557 {
558
559 /* No get function, return no access. */
560 status = NX_SNMP_ERROR_NOACCESS;
561 }
562
563 /* Return the status. */
564 return(status);
565 }
566
567
568 /* Define the application's SET processing routine. */
569
v2_mib2_set_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data)570 UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data)
571 {
572
573 UINT i;
574 UINT status;
575
576
577 /* Loop through the sample MIB to see if we have information for the supplied variable. */
578 i = 0;
579 status = NX_SNMP_ERROR;
580 while (mib2_mib[i].object_name)
581 {
582
583 /* See if we have found the matching entry. */
584 status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name);
585
586 /* Was it found? */
587 if (status == NX_SUCCESS)
588 {
589
590 /* Yes it was found. */
591 break;
592 }
593
594 /* Move to the next index. */
595 i++;
596 }
597
598 /* Determine if a not found condition is present. */
599 if (status != NX_SUCCESS)
600 {
601
602 /* The object was not found - return an error. */
603 return(NX_SNMP_ERROR_NOSUCHNAME);
604 }
605
606
607 /* Determine if the entry has a set function. */
608 if (mib2_mib[i].object_set_callback)
609 {
610
611 /* Yes, call the set function. */
612 status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data);
613 }
614 else
615 {
616
617 /* No get function, return no access. */
618 status = NX_SNMP_ERROR_NOACCESS;
619 }
620
621
622 /* Return the status. */
623 return(status);
624 }
625
626 /* Create an error code if matching user not found. */
627 #define USER_NOT_FOUND 1
628
629 /* Define the username callback routine routine. Usernames should be
630 associated with permissions (public or private string) and what version
631 of SNMP the user is configured for. The username callback should verify
632 the incoming username MIB access permissions. */
v2_mib2_username_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * username)633 UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username)
634 {
635
636 v2_mib2_variable_update(&agent_ip, &v2_my_agent);
637
638 return NX_SUCCESS;
639
640 }
641
642 extern ULONG sysUpTime;
643 /* Define the application's update routine. */
644
v2_mib2_variable_update(NX_IP * ip_ptr,NX_SNMP_AGENT * agent_ptr)645 VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr)
646 {
647
648 /* Update the snmp parameters. */
649 sysUpTime = tx_time_get();
650 }
651
652 #else
653
654 #ifdef CTEST
test_application_define(void * first_unused_memory)655 VOID test_application_define(void *first_unused_memory)
656 #else
657 void netx_snmp_v2_send_trap_test_application_define(void *first_unused_memory)
658 #endif
659 {
660
661 /* Print out test information banner. */
662 printf("NetX Test: SNMP V2 Send Trap Test....................................N/A\n");
663
664 test_control_return(3);
665 }
666 #endif
667