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