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