1 /* This NetX test is a simple contact between agent and browser with no security.  Note that
2    NX_SNMP_FUNCTION_TESTING must be defined in nxd_snmp.c or else timer tick data (boot time, SysTimerTick, will not match the
3    'pre-recorded' data that the NetX SNMP Agent responses re compared with, and the test will fail.
4    */
5 
6 #include   "tx_api.h"
7 #include   "nx_api.h"
8 #include   "nxd_snmp.h"
9 #include   "nx_udp.h"
10 
11 
12 extern void    test_control_return(UINT);
13 
14 #if !defined(NX_DISABLE_IPV4)
15 
16 #define VERBOSE
17 #define     DEMO_STACK_SIZE         2048
18 
19 UCHAR      *current_object_requested;
20 UINT        aquery_response_complete = NX_FALSE; /* to synchronize when the agent sends the SNMP trap */
21 
22 #define     NX_SNMP_ID_OFFSET       17   /* Size of top snmp header, version, public string */
23                                          /* data header, and request id block; assumes public string is 'public' */
24 #define     QUERY_COUNT             2
25 #define     RESPONSE_COUNT          2
26 
27 
28 UCHAR   asysDescr[] =                "NetX SNMP Agent";              /* sysDescr:OctetString                 RO */
29 UCHAR   asysObjectID[] =             "1.3.6.1.2.1.1";                /* sysObjectID:ObjectID                 RO */
30 LONG    asysUpTime =                  0;                             /* sysUpTime:TimeTicks                  RO */
31 UCHAR   asysContact[128] =           "NetX sysContact Name";         /* sysContact:OctetString               RW */
32 UCHAR   asysName[128] =              "NetX sysName";                 /* sysName:OctetString                  RW */
33 
34 /* This is for SNMPv3 discovery/synchronization. */
35 ULONG   ausmStatsUnknownEngineIDs =        0;                       /* usmStatsUnknownEngineIDs:Counter      RO */
36 ULONG   ausmStatsNotInTimeWindows =        0;                       /* usmStatsNotInTimeWindows:Counter      RO */
37 ULONG   ausmStatsUnsupportedSec   =        01;
38 ULONG   ausmStatsUnknownUsername   =       0;
39 
40 /* Define application MIB data structure. Actual application structures would certainly vary.  */
41 
42 typedef struct NOSEC_MIB_ENTRY_STRUCT
43 {
44 
45     UCHAR       *object_name;
46     void        *object_value_ptr;
47     UINT        (*object_get_callback)(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data);
48     UINT        (*object_set_callback)(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data);
49 } NOSEC_MIB_ENTRY;
50 
51 /* Define the actual MIB-2.  */
52 
53 static NOSEC_MIB_ENTRY   mib2_mib[] = {
54 
55     /*    OBJECT ID                OBJECT VARIABLE                  GET ROUTINE                 SET ROUTINE   */
56 
57     {(UCHAR *) "1.3.6.1.2.1.1.1.0",      asysDescr,                   nx_snmp_object_string_get,      NX_NULL},
58     {(UCHAR *) "1.3.6.1.2.1.1.2.0",      asysObjectID,                nx_snmp_object_id_get,          NX_NULL},
59     {(UCHAR *) "1.3.6.1.2.1.1.3.0",       &asysUpTime,                 nx_snmp_object_timetics_get,    NX_NULL},
60     {(UCHAR *) "1.3.6.1.2.1.1.4.0",       asysContact,                 nx_snmp_object_string_get,      nx_snmp_object_string_set},
61     {(UCHAR *) "1.3.6.1.2.1.1.5.0",       asysName,                    nx_snmp_object_string_get,      nx_snmp_object_string_set},
62 
63     /*  Subset of usm variable bindings for SNMPv3 discovery messages and synchronization: */
64     {(UCHAR *) "1.3.6.1.6.3.15.1.1.1.0",     &ausmStatsUnsupportedSec,          nx_snmp_object_counter_get,     nx_snmp_object_counter_set},
65     {(UCHAR *) "1.3.6.1.6.3.15.1.1.2.0",     &ausmStatsNotInTimeWindows,        nx_snmp_object_counter_get,     nx_snmp_object_counter_set},
66     {(UCHAR *) "1.3.6.1.6.3.15.1.1.3.0",     &ausmStatsUnknownUsername,         nx_snmp_object_counter_get,     nx_snmp_object_counter_set},
67     {(UCHAR *) "1.3.6.1.6.3.15.1.1.4.0",     &ausmStatsUnknownEngineIDs,        nx_snmp_object_counter_get,     nx_snmp_object_counter_set},
68     {(UCHAR *) "1.3.6.1.7",               (UCHAR *) "1.3.6.1.7",               nx_snmp_object_end_of_mib,      NX_NULL},
69     {NX_NULL, NX_NULL, NX_NULL, NX_NULL}
70 };
71 
72 /* To show byte by byte comparison of pre-recorded response with SNMP agent, define this option.
73 #define VERBOSE
74 */
75 
76 
77 /* Define the ThreadX and NetX object control blocks...  */
78 
79 static TX_THREAD               thread_agent;
80 static TX_THREAD               thread_manager;
81 static NX_SNMP_AGENT           my_nosec_agent;
82 static NX_PACKET_POOL          nosec_pool;
83 static NX_IP                   agent_ip;
84 static NX_IP                   manager_ip;
85 static NX_UDP_SOCKET           snmp_manager_socket;
86 
87 #define SNMP_MANAGER_ADDRESS   IP_ADDRESS(10,0,0,1)
88 #define SNMP_AGENT_ADDRESS     IP_ADDRESS(10,0,0,10)
89 
90 
91 
92 UCHAR acontext_engine_id[] = {0x80, 0x00, 0x0d, 0xfe, 0x03, 0x00, 0x77, 0x23, 0x23, 0x46, 0x69};
93 UINT  acontext_engine_size = 11;
94 
95 /* Define the counters used in the demo application...  */
96 
97 static UINT                    status;
98 static ULONG                   error_counter;
99 
100 
101 /* Define thread prototypes.  */
102 
103 static void    thread_0_entry(ULONG thread_input);
104 static void    thread_1_entry(ULONG thread_input);
105 extern void    _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req);
106 static void    snmp_test_initialize();
107 static UINT    check_valid_response(NX_PACKET *agent_packet, UINT packet_number, UINT *valid);
108 
109 
110 static UINT    nosec_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data);
111 static UINT    nosec_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data);
112 static UINT    nosec_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data);
113 static UINT  nosec_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username);
114 static VOID  nosec_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr);
115 
116 /* Send SNMP manager query.  */
117 static UINT    nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number);
118 
119 extern char get_v3_request_packet[101];
120 extern int  v3_request_size;
121 extern char get_v3_next_request_packet[141];
122 extern int  v3_next_request_size;
123 extern char v3_report_packet[147];
124 extern int  v3_report_size;
125 extern char v3_response_packet[154];
126 extern int  v3_response_size;
127 
128 
129 typedef struct SNMP_QUERY_STRUCT
130 {
131     char          *snmp_query_pkt_data;
132     int            snmp_query_pkt_size;
133 } SNMP_QUERY;
134 
135 typedef struct SNMP_RESPONSE_STRUCT
136 {
137     char          *snmp_response_pkt_data;
138     int            snmp_response_pkt_size;
139 } SNMP_RESPONSE;
140 
141 
142 static SNMP_QUERY       snmp_query[QUERY_COUNT];
143 static SNMP_RESPONSE    snmp_response[RESPONSE_COUNT];
144 
145 #define        SNMP_START_OFFSET (14 + 20 + 8) // ethernet, ip and udp headers
146 
147 
148 /* Define what the initial system looks like.  */
149 
150 #ifdef CTEST
test_application_define(void * first_unused_memory)151 VOID test_application_define(void *first_unused_memory)
152 #else
153 void    netx_snmp_security_no_security_application_define(void *first_unused_memory)
154 #endif
155 {
156 
157 CHAR    *pointer;
158 
159     /* Setup the working pointer.  */
160     pointer =  (CHAR *) first_unused_memory;
161 
162     /* Create the SNMP agent thread.  */
163     status = tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0,
164             pointer, DEMO_STACK_SIZE,
165             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
166     pointer =  pointer + DEMO_STACK_SIZE;
167 
168     /* Create the SNMP Manager thread.  */
169     status += tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0,
170             pointer, DEMO_STACK_SIZE,
171             3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
172     pointer =  pointer + DEMO_STACK_SIZE;
173 
174     printf("NetX Test:   SNMP No Security Function Test............................");
175 
176         /* Check for IP create errors.  */
177     /* Check for IP create errors.  */
178     if (status)
179     {
180         printf("ERROR!\n");
181         test_control_return(1);
182     }
183 
184     /* Initialize the NetX system.  */
185     nx_system_initialize();
186 
187     /* Create a packet pool.  */
188     status =  nx_packet_pool_create(&nosec_pool, "NetX Main Packet Pool", 1000, pointer, 4096);
189     pointer = pointer + 4096;
190 
191         /* Check for IP create errors.  */
192     if (status)
193     {
194 
195 #ifdef VERBOSE
196         printf("\npacket create error 0x%x \n",  status);
197 #endif
198         printf("ERROR!\n");
199         test_control_return(1);
200     }
201 
202     /* Create an IP instance.  */
203     status = nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &nosec_pool, _nx_ram_network_driver_1500, pointer , 2048, 1);
204 
205     pointer += 2048;
206 
207     /* Create another IP instance.  */
208     status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &nosec_pool, _nx_ram_network_driver_1500, pointer, 2048, 1);
209 
210     pointer += 2048;
211 
212     /* Check for IP create errors.  */
213     if (status)
214     {
215 
216 #ifdef VERBOSE
217         printf("\nIP create error 0x%x \n",  status);
218 #endif
219         printf("ERROR!\n");
220         test_control_return(1);
221     }
222 
223     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
224     status =  nx_arp_enable(&agent_ip, (void *) pointer, 1024);
225     pointer = pointer + 1024;
226 
227     /* Enable ARP and supply ARP cache memory for IP Instance 1.  */
228     status +=  nx_arp_enable(&manager_ip, (void *) pointer, 1024);
229     pointer = pointer + 1024;
230 
231     /* Check for ARP enable errors.  */
232     if (status)
233     {
234         printf("ERROR!\n");
235         test_control_return(1);
236     }
237 
238     /* Enable UDP traffic.  */
239     status =  nx_udp_enable(&agent_ip);
240     status += nx_udp_enable(&manager_ip);
241 
242     /* Check for UDP enable errors.  */
243     if (status)
244     {
245         printf("ERROR!\n");
246         test_control_return(1);
247     }
248 
249 
250         /* Create an SNMP agent instance.  */
251     status = nx_snmp_agent_create(&my_nosec_agent, "public", &agent_ip, pointer, 4096, &nosec_pool,
252                          nosec_mib2_username_processing, nosec_mib2_get_processing,
253                          nosec_mib2_getnext_processing, nosec_mib2_set_processing);
254     pointer =  pointer + 4096;
255 
256     if (status)
257     {
258 
259 #ifdef VERBOSE
260         printf("\nagent create error 0x%x \n", status);
261 #endif
262         printf("ERROR!\n");
263         test_control_return(1);
264     }
265 
266     if (my_nosec_agent.nx_snmp_agent_v3_enabled == NX_TRUE)
267     {
268         ULONG boot_count;
269 
270         /* Make sure boot time and engine boot ID match the pre-recorded data. */
271         boot_count = 0x1;
272         status = nx_snmp_agent_context_engine_set(&my_nosec_agent, acontext_engine_id, acontext_engine_size);
273         status |= nx_snmp_agent_v3_context_boots_set(&my_nosec_agent, boot_count);
274 
275         if (status)
276         {
277             printf("ERROR!\n");
278             test_control_return(1);
279         }
280     }
281     else
282     {
283 
284 #ifdef VERBOSE
285         printf("\n agent not enabled for V3 \n");
286 #endif
287         printf("ERROR!\n");
288         test_control_return(1);
289     }
290 
291 }
292 
293 /* Define the SNMP Agent thread.  */
294 
thread_0_entry(ULONG thread_input)295 static void    thread_0_entry(ULONG thread_input)
296 {
297 
298 UINT status;
299 
300 
301     tx_thread_sleep(20);
302 
303     /* Start the SNMP instance.  */
304     status = nx_snmp_agent_start(&my_nosec_agent);
305 
306     /* Return the test result.  */
307     if (status)
308     {
309        error_counter++;
310     }
311 
312     while (!aquery_response_complete)
313     {
314         tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
315     }
316 
317    // tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
318 
319     if (error_counter)
320     {
321         printf("ERROR!\n");
322         test_control_return(1);
323     }
324     else
325     {
326         printf("SUCCESS!\n");
327         test_control_return(0);
328     }
329 }
330 
331 /* SNMP Manager thread */
thread_1_entry(ULONG thread_input)332 static void    thread_1_entry(ULONG thread_input)
333 {
334 
335 NX_PACKET   *agent_packet;
336 UINT        port;
337 UINT        i;
338 USHORT      request_id = 1;
339 UINT        valid = NX_TRUE;
340 
341     /* Let the agent get set up first! */
342     tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
343 
344     status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
345 
346     /* Bind the UDP socket to the IP port.  */
347     status |=  nx_udp_socket_bind(&snmp_manager_socket, 0, TX_WAIT_FOREVER);
348 
349     /* Check status.  */
350     if (status)
351     {
352 
353 #ifdef VERBOSE
354         printf("\n UDP socket create error 0x%x \n", status);
355 #endif
356         error_counter++;
357 
358         /* Indicate the query response is complete. */
359         aquery_response_complete = NX_TRUE;
360 
361         return;
362     }
363 
364     /* Load the test data. */
365     snmp_test_initialize();
366 
367     /* Send SNMP queries to the agent..  */
368     for (i = 0; i < QUERY_COUNT; i++ )
369     {
370 
371         /* Send the SNMP manager query packet.  */
372         status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id,  i);
373 
374 #ifdef VERBOSE
375         printf("\n%d query packet send error 0x%x \n",i, status);
376 #endif
377         /* Check status.  */
378         if (status)
379         {
380             error_counter++;
381             break;
382         }
383 
384         /* Receive the SNMP agent response.  */
385         status =  nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, NX_WAIT_FOREVER);
386 
387         /* Check status.  */
388         if (status)
389         {
390 
391 #ifdef VERBOSE
392         printf("\n%d socket receive error 0x%x \n",i, status);
393 #endif
394             error_counter++;
395             break;
396         }
397 
398         /* Get the SNMP agent UDP port.  */
399         status = nx_udp_packet_info_extract(agent_packet, NX_NULL ,NX_NULL, &port, NX_NULL);
400 
401         /* Check status.  */
402         if (status)
403         {
404 
405 #ifdef VERBOSE
406         printf("\n%d packet extract error 0x%x \n",i, status);
407 #endif
408             error_counter++;
409             break;
410         }
411 
412         /* Release the packet.  */
413         nx_packet_release(agent_packet);
414 
415         request_id++;
416     }
417 
418     /* Indicate the query response is complete. */
419     aquery_response_complete = NX_TRUE;
420 
421 }
422 
423 
424 /* Determines if we got a valid response using known SNMP query and response data.  */
check_valid_response(NX_PACKET * agent_packet,UINT packet_number,UINT * valid)425 UINT check_valid_response(NX_PACKET *agent_packet, UINT packet_number, UINT *valid)
426 {
427 
428 UINT  data_size;
429 UCHAR *work_ptr;
430 UINT   j;
431 
432 
433     work_ptr = (UCHAR *)(&snmp_response[packet_number].snmp_response_pkt_data[0] + SNMP_START_OFFSET);
434 
435     data_size = snmp_response[packet_number].snmp_response_pkt_size  - SNMP_START_OFFSET;
436 
437     if (data_size == 0)
438     {
439         return 1; /* Invalid data */
440     }
441 
442     for (j = 0; j < data_size; j++)
443     {
444 
445         /* For each test , initialize outcome as successful test. */
446         *valid = NX_TRUE;
447 
448 #ifdef VERBOSE
449         printf("%d. 0%x  0%x ", j, *(agent_packet -> nx_packet_prepend_ptr + j), work_ptr[j]);
450 #endif
451 
452         /* It is unlikely this logic is needed as long as NX_SNMP_FUNCTION_TESTING is defined,
453            and the sysUpTime is always updated to 1. */
454 
455         if (*(agent_packet -> nx_packet_prepend_ptr + j) != work_ptr[j])
456         {
457 
458             /* There is no way to match certain variables such as 'engine boot time' with system time of the pre-recorded
459                data.  Ignore this data */
460 
461             if (packet_number == 1)
462             {
463 
464                 /* Case 1: the 'work' packet timer tick data is two bytes  */
465                 if (j == 109)
466                 {
467 
468                     /* Determine if the time value is 1 byte or 2 bytes. */
469                     if ((work_ptr[j] == 2) && (*(agent_packet -> nx_packet_prepend_ptr+j) == 1))
470                     {
471                         /* 2 bytes. Skip an extra byte. We do this by bumping the work pointer by one. */
472                         work_ptr = (UCHAR *)(&snmp_response[packet_number].snmp_response_pkt_data[0] + SNMP_START_OFFSET + 1);
473                     }
474 
475                     /* For either cast, skip the time value. */
476                     j++;
477 #ifdef VERBOSE
478                     printf("Packet %d skipping %d'th element for comparison\n", packet_number, j);
479 #endif
480 
481                     continue;
482                 }
483                 /* Case 2:  both have same length of timer tick data, but different value. */
484                 else if (j == 110)
485                 {
486 
487                     /* Just skip over the current index. */
488 #ifdef VERBOSE
489                     printf("Packet %d skipping timer tick data at %d'th index for comparison\n", packet_number, j);
490 #endif
491 
492                     /* Are they both two bytes long? */
493                     if (work_ptr[j-1] == 2)
494                     {
495 
496                         /* Yes. Skip an extra index in addition
497                            to the current one. */
498 #ifdef VERBOSE
499                         printf("Packet %d two byte timer tick: skip one more index to %d'th index\n", packet_number, j);
500 #endif
501 
502                         j++;
503                     }
504 
505                     continue;
506                 }
507                 else
508                 {
509 
510                     /* Else invalid or unexpected data. */
511                     return(1);
512                 }
513             }
514             else
515             {
516 
517                 /* Else invalid or unexpected data. */
518                 return(1);
519             }
520         }
521 #ifdef VERBOSE
522         printf("\n");
523 #endif
524 
525     }
526 
527     return NX_SUCCESS;
528 
529 }
530 
nx_snmp_query_packet_send(NX_UDP_SOCKET * snmp_manager_socket,UINT snmp_request_id,UINT packet_number)531 static UINT   nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number)
532 {
533 UINT        status;
534 NX_PACKET   *query_packet;
535 
536     /* Allocate a response packet.  */
537     status =  nx_packet_allocate(&nosec_pool, &query_packet, NX_UDP_PACKET, TX_WAIT_FOREVER);
538 
539     /* Check status.  */
540     if (status)
541     {
542 
543 #ifdef VERBOSE
544         printf("\n packet allocate error 0x%x \n", status);
545 #endif
546         return status;
547     }
548 
549     /* Write the SNMP query messages into the packet payload!  */
550     snmp_query[packet_number].snmp_query_pkt_data += SNMP_START_OFFSET;
551     memcpy(query_packet -> nx_packet_prepend_ptr, snmp_query[packet_number].snmp_query_pkt_data, snmp_query[packet_number].snmp_query_pkt_size - SNMP_START_OFFSET);
552 
553     /* Adjust the write pointer.  */
554     query_packet -> nx_packet_length =  snmp_query[packet_number].snmp_query_pkt_size - SNMP_START_OFFSET;
555     query_packet -> nx_packet_append_ptr =  query_packet -> nx_packet_prepend_ptr + query_packet -> nx_packet_length;
556 
557 
558     /* Send the UDP packet with the correct port.  */
559     status =  nx_udp_socket_send(snmp_manager_socket, query_packet, IP_ADDRESS(10, 0, 0, 10), 161);
560 
561     /* Check the status.  */
562     if (status)
563     {
564 
565 #ifdef VERBOSE
566         printf("\n socket send error 0x%x \n", status);
567 #endif
568         nx_packet_release(query_packet);
569     }
570     return status;
571 }
572 
573 
snmp_test_initialize()574 static void  snmp_test_initialize()
575 {
576 
577      /* Contact - no security*/
578      snmp_query[0].snmp_query_pkt_data = &get_v3_request_packet[0];
579      snmp_query[0].snmp_query_pkt_size = v3_request_size;
580      snmp_query[1].snmp_query_pkt_data = &get_v3_next_request_packet[0];
581      snmp_query[1].snmp_query_pkt_size = v3_next_request_size;
582 
583      snmp_response[0].snmp_response_pkt_data = &v3_report_packet[0];
584      snmp_response[0].snmp_response_pkt_size = v3_report_size;
585      snmp_response[1].snmp_response_pkt_data = &v3_response_packet[0];
586      snmp_response[1].snmp_response_pkt_size = v3_response_size;
587 
588 }
589 
590 
591 /* Define the application's GET processing routine.  */
nosec_mib2_get_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data)592 UINT    nosec_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data)
593 {
594 
595 UINT    i;
596 UINT    status;
597 
598 
599     /* Loop through the sample MIB to see if we have information for the supplied variable.  */
600     i =  0;
601     status =  NX_SNMP_ERROR;
602     while (mib2_mib[i].object_name)
603     {
604 
605         /* See if we have found the matching entry.  */
606         status =  nx_snmp_object_compare(object_requested, mib2_mib[i].object_name);
607 
608         /* Was it found?  */
609         if (status == NX_SUCCESS)
610         {
611 
612             /* Yes it was found.  */
613             break;
614         }
615 
616         /* Move to the next index.  */
617         i++;
618     }
619 
620     /* Determine if a not found condition is present.  */
621     if (status != NX_SUCCESS)
622     {
623 
624 
625         /* The object was not found - return an error.  */
626         return(NX_SNMP_ERROR_NOSUCHNAME);
627     }
628 
629     /* Determine if the entry has a get function.  */
630     if (mib2_mib[i].object_get_callback)
631     {
632 
633         /* Yes, call the get function.  */
634         status =  (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data);
635     }
636     else
637     {
638 
639 
640         /* No get function, return no access.  */
641         status =  NX_SNMP_ERROR_NOACCESS;
642     }
643 
644 
645     /* Return the status.  */
646     return(status);
647 }
648 
649 
650 /* Define the application's GETNEXT processing routine.  */
651 
nosec_mib2_getnext_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data)652 UINT    nosec_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data)
653 {
654 
655 UINT    i;
656 UINT    status;
657 
658 
659 
660     /* Loop through the sample MIB to see if we have information for the supplied variable.  */
661     i =  0;
662     status =  NX_SNMP_ERROR;
663     while (mib2_mib[i].object_name)
664     {
665 
666         /* See if we have found the next entry.  */
667         status =  nx_snmp_object_compare(object_requested, mib2_mib[i].object_name);
668 
669         /* Is the next entry the mib greater?  */
670         if (status == NX_SNMP_NEXT_ENTRY)
671         {
672 
673             /* Yes it was found.  */
674             break;
675         }
676 
677         /* Move to the next index.  */
678         i++;
679     }
680 
681     /* Determine if a not found condition is present.  */
682     if (status != NX_SNMP_NEXT_ENTRY)
683     {
684 
685         /* The object was not found - return an error.  */
686         return(NX_SNMP_ERROR_NOSUCHNAME);
687     }
688 
689 
690     /* Copy the new name into the object.  */
691     nx_snmp_object_copy(mib2_mib[i].object_name, object_requested);
692 
693     /* Determine if the entry has a get function.  */
694     if (mib2_mib[i].object_get_callback)
695     {
696 
697         /* Yes, call the get function.  */
698         status =  (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data);
699 
700         /* Determine if the object data indicates an end-of-mib condition.  */
701         if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW)
702         {
703 
704             /* Copy the name supplied in the mib table.  */
705             nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested);
706         }
707     }
708     else
709     {
710 
711         /* No get function, return no access.  */
712         status =  NX_SNMP_ERROR_NOACCESS;
713     }
714 
715 
716     /* Return the status.  */
717     return(status);
718 }
719 
720 
721 /* Define the application's SET processing routine.  */
722 
nosec_mib2_set_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data)723 UINT    nosec_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data)
724 {
725 
726 UINT    i;
727 UINT    status;
728 
729 
730 
731     /* Loop through the sample MIB to see if we have information for the supplied variable.  */
732     i =  0;
733     status =  NX_SNMP_ERROR;
734     while (mib2_mib[i].object_name)
735     {
736 
737         /* See if we have found the matching entry.  */
738         status =  nx_snmp_object_compare(object_requested, mib2_mib[i].object_name);
739 
740         /* Was it found?  */
741         if (status == NX_SUCCESS)
742         {
743 
744             /* Yes it was found.  */
745             break;
746         }
747 
748         /* Move to the next index.  */
749         i++;
750     }
751 
752     /* Determine if a not found condition is present.  */
753     if (status != NX_SUCCESS)
754     {
755 
756         /* The object was not found - return an error.  */
757         return(NX_SNMP_ERROR_NOSUCHNAME);
758     }
759 
760 
761     /* Determine if the entry has a set function.  */
762     if (mib2_mib[i].object_set_callback)
763     {
764 
765         /* Yes, call the set function.  */
766         status =  (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data);
767     }
768     else
769     {
770 
771         /* No get function, return no access.  */
772         status =  NX_SNMP_ERROR_NOACCESS;
773     }
774 
775 
776     /* Return the status.  */
777     return(status);
778 }
779 
780 /* Create an error code if matching user not found. */
781 #define USER_NOT_FOUND 1
782 
783 /* Define the username callback routine routine. Usernames should be
784    associated with permissions (public or private string) and what version
785    of SNMP the user is configured for. The username callback should verify
786    the incoming username MIB access permissions.  */
nosec_mib2_username_processing(NX_SNMP_AGENT * agent_ptr,UCHAR * username)787 UINT  nosec_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username)
788 {
789 
790     nosec_mib2_variable_update(&agent_ip, &my_nosec_agent);
791 
792     return NX_SUCCESS;
793 
794 }
795 
796 
797 /* Define the application's update routine.  */
798 
nosec_mib2_variable_update(NX_IP * ip_ptr,NX_SNMP_AGENT * agent_ptr)799 VOID  nosec_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr)
800 {
801 
802 
803     /* Update the snmp parameters.  */
804     asysUpTime =                 1; /* This is necessary to compare pre-recorded data with SNMP agent response! */
805 }
806 #else
807 
808 #ifdef CTEST
test_application_define(void * first_unused_memory)809 VOID test_application_define(void *first_unused_memory)
810 #else
811 void    netx_snmp_security_no_security_application_define(void *first_unused_memory)
812 #endif
813 {
814 
815     /* Print out test information banner.  */
816     printf("NetX Test:   SNMP No Security Function Test............................N/A\n");
817 
818     test_control_return(3);
819 }
820 #endif
821 
822