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