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