1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Duo Component                                                    */
16 /**                                                                       */
17 /**   Simple Network Management Protocol (SNMP)                           */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_SNMP_SOURCE_CODE
23 
24 /* Force error checking to be disabled in this module */
25 
26 #ifndef NX_DISABLE_ERROR_CHECKING
27 #define NX_DISABLE_ERROR_CHECKING
28 #endif
29 
30 /* Include necessary system files.  */
31 
32 #include    "nx_api.h"
33 #include    "nxd_snmp.h"
34 
35 #ifndef NX_IPV6_UTIL_INLINE
36 extern void  COPY_NXD_ADDRESS(NXD_ADDRESS *copy_from, NXD_ADDRESS  *copy_to);
37 #endif
38 
39 
40 /* To enable debug output, define this option.
41 #define NX_SNMPV3_PRINT_DEBUG_MESSAGE
42 */
43 
44 #define NX_SNMP_REQUEST_AUTH_SIZE 50
45 
46 #ifndef NX_SNMP_DISABLE_V3
47 /* Define locations in request buffer PDU in the event we need
48    to return the message e.g. error message response. */
49 static UINT   pdu_length;
50 static UCHAR *pdu_buffer_ptr;
51 static UCHAR *pdu_auth_parm_ptr;
52 static UCHAR *pdu_privacy_ptr;
53 #endif
54 
55 /* Enable or disable SNMPv3 debug message printout.  */
56 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
57     #define NX_SNMPV3_DBG_PRINTF printf
58 #endif /* NX_SNMPV3_PRINT_DEBUG_MESSAGE */
59 
60 
61 /* Define global SNMP variables and strings.  */
62 
63 /* If the array size of _nx_snmp_v2_trap_ids is changed, these upper limit MUST by updated! */
64 #define TRAP_ID_MAX  5
65 UCHAR *_nx_snmp_v2_trap_ids[] =  {  (UCHAR *) "1.3.6.1.6.3.1.1.5.1.0" /* (coldStart)                */,
66                                     (UCHAR *) "1.3.6.1.6.3.1.1.5.2.0" /* (warmStart)                */,
67                                     (UCHAR *) "1.3.6.1.6.3.1.1.5.3.0" /* (linkDown)                 */,
68                                     (UCHAR *) "1.3.6.1.6.3.1.1.5.4.0" /* (linkUp)                   */,
69                                     (UCHAR *) "1.3.6.1.6.3.1.1.5.5.0" /* (authenticationFailure)    */,
70                                     (UCHAR *) "1.3.6.1.6.3.1.1.5.6.0" /* (egpNeighborLoss)          */
71                                  };
72 
73 
74 
75 #ifndef NX_SNMP_DISABLE_V3
76 
77 UCHAR *_nx_snmp_v3_trap_ids[] =  {  (UCHAR *) "1.3.6.1.6.3.1.1.5.1.0" /* (coldStart)                */,
78                                     (UCHAR *) "1.3.6.1.6.3.1.1.5.2.0" /* (warmStart)                */,
79                                     (UCHAR *) "1.3.6.1.6.3.1.1.5.3.0" /* (linkDown)                 */,
80                                     (UCHAR *) "1.3.6.1.6.3.1.1.5.4.0" /* (linkUp)                   */,
81                                     (UCHAR *) "1.3.6.1.6.3.1.1.5.5.0" /* (authenticationFailure)    */,
82                                     (UCHAR *) "1.3.6.1.6.3.1.1.5.6.0" /* (egpNeighborLoss)          */
83                                  };
84 
85 /* Define the default context engine information. This will be setup when the SNMP agent is
86    created. Note that this information isn't used for SNMP v1 and v2.  Note the host application
87    should use the nx_snmp_agent_context_engine_set() service to set its own IPv4 (or MAC address
88    depending on format type) when creating the Engine ID. The engine size must match the total engine
89    data including the input context engine data as well. See documentation for more details.
90 
91    Note that this information isn't used for SNMP v1 and v2.  */
92 
93 UCHAR  _nx_snmp_default_context_engine[NX_SNMP_MAX_CONTEXT_STRING] =  {0x80, 0x00, 0x03, 0x10, 0x01, 0xc0, 0xa8, 0x64, 0xaf};
94 UINT   _nx_snmp_default_context_engine_size =  9;
95 
96 CHAR   _nx_snmp_default_initial_user_name[] =  "initial";
97 
98 #endif
99 
100 /* As per RFC 3414 for SNMPv3 the discovery report must include the usmStats variables. */
101 #define     NX_SNMP_DISCOVERY_RESPONSE_UNSUPPORTED_SEC        "1.3.6.1.6.3.15.1.1.1.0"
102 #define     NX_SNMP_DISCOVERY_RESPONSE_UNSUPPORTED_SEC_NUM    1
103 #define     NX_SNMP_DISCOVERY_RESPONSE_MISMATCHED_TIME        "1.3.6.1.6.3.15.1.1.2.0"
104 #define     NX_SNMP_DISCOVERY_RESPONSE_MISMATCHED_TIME_NUM    2
105 #define     NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_USERNAME       "1.3.6.1.6.3.15.1.1.3.0"
106 #define     NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_USERNAME_NUM   3
107 #define     NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_ENGINEID       "1.3.6.1.6.3.15.1.1.4.0"
108 #define     NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_ENGINEID_NUM   4
109 
110 /* Define the maximum difference between local time (in seconds) and browser notion of
111    local time recommended by RFC 3413. */
112 #define     NX_SNMP_TIME_WINDOW                          150
113 
114 
115 /* Bring in externs for caller checking code.  */
116 
117 NX_CALLER_CHECKING_EXTERNS
118 
119 
120 #ifndef NX_SNMP_DISABLE_V3
121 /**************************************************************************/
122 /*                                                                        */
123 /*  FUNCTION                                               RELEASE        */
124 /*                                                                        */
125 /*    _nxe_snmp_agent_authenticate_key_use                PORTABLE C      */
126 /*                                                           6.1          */
127 /*  AUTHOR                                                                */
128 /*                                                                        */
129 /*    Yuxin Zhou, Microsoft Corporation                                   */
130 /*                                                                        */
131 /*  DESCRIPTION                                                           */
132 /*                                                                        */
133 /*    This function checks for errors in the SNMP authentication key      */
134 /*    specification function call.  To disable authentication, set        */
135 /*    the key pointer to null.                                            */
136 /*                                                                        */
137 /*  INPUT                                                                 */
138 /*                                                                        */
139 /*    agent_ptr                             Pointer to SNMP agent         */
140 /*    key                                   Authenticate key              */
141 /*                                                                        */
142 /*  OUTPUT                                                                */
143 /*                                                                        */
144 /*    status                                Completion status             */
145 /*                                                                        */
146 /*  CALLS                                                                 */
147 /*                                                                        */
148 /*    _nx_snmp_agent_authenticate_key_use   Actual authentication key     */
149 /*                                            setup function              */
150 /*                                                                        */
151 /*  CALLED BY                                                             */
152 /*                                                                        */
153 /*    Application Code                                                    */
154 /*                                                                        */
155 /*  RELEASE HISTORY                                                       */
156 /*                                                                        */
157 /*    DATE              NAME                      DESCRIPTION             */
158 /*                                                                        */
159 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
160 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
161 /*                                            resulting in version 6.1    */
162 /*                                                                        */
163 /**************************************************************************/
_nxe_snmp_agent_authenticate_key_use(NX_SNMP_AGENT * agent_ptr,NX_SNMP_SECURITY_KEY * key)164 UINT  _nxe_snmp_agent_authenticate_key_use(NX_SNMP_AGENT *agent_ptr, NX_SNMP_SECURITY_KEY *key)
165 {
166 
167 UINT    status;
168 
169 
170     /* Check for invalid input pointers.  */
171     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID))
172     {
173 
174         return(NX_PTR_ERROR);
175     }
176 
177     if (key != NX_NULL)
178     {
179 
180         /* Check for valid authentication type. */
181         if ((key -> nx_snmp_security_key_type != NX_SNMP_MD5_KEY) && (key -> nx_snmp_security_key_type != NX_SNMP_SHA_KEY))
182         {
183             return NX_SNMP_UNSUPPORTED_AUTHENTICATION;
184         }
185     }
186 
187     /* Call actual service.  */
188     status =  _nx_snmp_agent_authenticate_key_use(agent_ptr, key);
189 
190     /* Return status.  */
191     return(status);
192 }
193 
194 
195 /**************************************************************************/
196 /*                                                                        */
197 /*  FUNCTION                                               RELEASE        */
198 /*                                                                        */
199 /*    _nx_snmp_agent_authenticate_key_use                 PORTABLE C      */
200 /*                                                           6.1          */
201 /*  AUTHOR                                                                */
202 /*                                                                        */
203 /*    Yuxin Zhou, Microsoft Corporation                                   */
204 /*                                                                        */
205 /*  DESCRIPTION                                                           */
206 /*                                                                        */
207 /*    This function sets up the authenticate key to use for checking the  */
208 /*    digest of the request.                                              */
209 /*                                                                        */
210 /*  INPUT                                                                 */
211 /*                                                                        */
212 /*    agent_ptr                             Pointer to SNMP agent         */
213 /*    key                                   Authenticate key              */
214 /*                                                                        */
215 /*  OUTPUT                                                                */
216 /*                                                                        */
217 /*    status                                Completion status             */
218 /*                                                                        */
219 /*  CALLS                                                                 */
220 /*                                                                        */
221 /*    None                                                                */
222 /*                                                                        */
223 /*  CALLED BY                                                             */
224 /*                                                                        */
225 /*    Application Code                                                    */
226 /*                                                                        */
227 /*  RELEASE HISTORY                                                       */
228 /*                                                                        */
229 /*    DATE              NAME                      DESCRIPTION             */
230 /*                                                                        */
231 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
232 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
233 /*                                            resulting in version 6.1    */
234 /*                                                                        */
235 /**************************************************************************/
_nx_snmp_agent_authenticate_key_use(NX_SNMP_AGENT * agent_ptr,NX_SNMP_SECURITY_KEY * key)236 UINT  _nx_snmp_agent_authenticate_key_use(NX_SNMP_AGENT *agent_ptr, NX_SNMP_SECURITY_KEY *key)
237 {
238 
239 #ifdef NX_SNMP_NO_SECURITY
240     return NX_NOT_ENABLED;
241 #else
242 
243     /* Set the authenticate pointer so authentication will use the specified key.  Note this
244        key must have been created prior to calling this routine.  */
245     agent_ptr -> nx_snmp_agent_v3_authentication_key =  key;
246 
247     /* Return success to the caller.  */
248     return(NX_SUCCESS);
249 #endif
250 }
251 
252 
253 /**************************************************************************/
254 /*                                                                        */
255 /*  FUNCTION                                               RELEASE        */
256 /*                                                                        */
257 /*    _nxe_snmp_agent_trap_auth_key_use                   PORTABLE C      */
258 /*                                                           6.1          */
259 /*  AUTHOR                                                                */
260 /*                                                                        */
261 /*    Yuxin Zhou, Microsoft Corporation                                   */
262 /*                                                                        */
263 /*  DESCRIPTION                                                           */
264 /*                                                                        */
265 /*    This function is the error checking service for the setting the trap*/
266 /*    message authentication key. To disable trap key authentication, set */
267 /*    the key pointer to null.                                            */
268 /*                                                                        */
269 /*  INPUT                                                                 */
270 /*                                                                        */
271 /*    agent_ptr                             Pointer to SNMP agent         */
272 /*    key                                   Authenticate key for traps    */
273 /*                                                                        */
274 /*  OUTPUT                                                                */
275 /*                                                                        */
276 /*    status                                Completion status             */
277 /*                                                                        */
278 /*  CALLS                                                                 */
279 /*                                                                        */
280 /*    _nx_snmp_agent_auth_trap_key_use      Actual set trap authentication*/
281 /*                                               key service              */
282 /*                                                                        */
283 /*  CALLED BY                                                             */
284 /*                                                                        */
285 /*    Application Code                                                    */
286 /*                                                                        */
287 /*  RELEASE HISTORY                                                       */
288 /*                                                                        */
289 /*    DATE              NAME                      DESCRIPTION             */
290 /*                                                                        */
291 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
292 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
293 /*                                            resulting in version 6.1    */
294 /*                                                                        */
295 /**************************************************************************/
_nxe_snmp_agent_auth_trap_key_use(NX_SNMP_AGENT * agent_ptr,NX_SNMP_SECURITY_KEY * key)296 UINT  _nxe_snmp_agent_auth_trap_key_use(NX_SNMP_AGENT *agent_ptr, NX_SNMP_SECURITY_KEY *key)
297 {
298 
299 UINT    status;
300 
301 
302     /* Check for invalid input pointers.  */
303     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID))
304     {
305 
306         return(NX_PTR_ERROR);
307     }
308 
309     if (key != NX_NULL)
310     {
311 
312         /* Check for invalid authentication type. */
313         if ((key -> nx_snmp_security_key_type != NX_SNMP_MD5_KEY) && (key -> nx_snmp_security_key_type != NX_SNMP_SHA_KEY))
314         {
315 
316             return NX_SNMP_UNSUPPORTED_AUTHENTICATION;
317         }
318     }
319 
320     /* Call actual service.  */
321     status =  _nx_snmp_agent_auth_trap_key_use(agent_ptr, key);
322 
323     /* Return status.  */
324     return(status);
325 }
326 
327 /**************************************************************************/
328 /*                                                                        */
329 /*  FUNCTION                                               RELEASE        */
330 /*                                                                        */
331 /*    _nx_snmp_agent_auth_trap_key_use                    PORTABLE C      */
332 /*                                                           6.1          */
333 /*  AUTHOR                                                                */
334 /*                                                                        */
335 /*    Yuxin Zhou, Microsoft Corporation                                   */
336 /*                                                                        */
337 /*  DESCRIPTION                                                           */
338 /*                                                                        */
339 /*    This function sets up the authenticate key to use for creating      */
340 /*    authentication parameters in SNMPv3 trap messages.                  */
341 /*                                                                        */
342 /*  INPUT                                                                 */
343 /*                                                                        */
344 /*    agent_ptr                             Pointer to SNMP agent         */
345 /*    key                                   Authenticate key for traps    */
346 /*                                                                        */
347 /*  OUTPUT                                                                */
348 /*                                                                        */
349 /*    status                                Completion status             */
350 /*                                                                        */
351 /*  CALLS                                                                 */
352 /*                                                                        */
353 /*    None                                                                */
354 /*                                                                        */
355 /*  CALLED BY                                                             */
356 /*                                                                        */
357 /*    Application Code                                                    */
358 /*                                                                        */
359 /*  RELEASE HISTORY                                                       */
360 /*                                                                        */
361 /*    DATE              NAME                      DESCRIPTION             */
362 /*                                                                        */
363 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
364 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
365 /*                                            resulting in version 6.1    */
366 /*                                                                        */
367 /**************************************************************************/
_nx_snmp_agent_auth_trap_key_use(NX_SNMP_AGENT * agent_ptr,NX_SNMP_SECURITY_KEY * key)368 UINT    _nx_snmp_agent_auth_trap_key_use(NX_SNMP_AGENT *agent_ptr, NX_SNMP_SECURITY_KEY *key)
369 {
370 
371 #ifdef NX_SNMP_NO_SECURITY
372     return NX_NOT_ENABLED;
373 #else
374 
375 
376     /* Set the authenticate pointer so authentication will use the specified key.  Note this
377        key must have been created prior to calling this routine.  */
378     agent_ptr -> nx_snmp_agent_v3_auth_trap_key =  key;
379 
380     /* Return success to the caller.  */
381     return(NX_SUCCESS);
382 
383 #endif
384 }
385 #endif /* NX_SNMP_DISABLE_V3 */
386 
387 
388 /**************************************************************************/
389 /*                                                                        */
390 /*  FUNCTION                                               RELEASE        */
391 /*                                                                        */
392 /*    _nxe_snmp_agent_community_get                       PORTABLE C      */
393 /*                                                           6.1          */
394 /*  AUTHOR                                                                */
395 /*                                                                        */
396 /*    Yuxin Zhou, Microsoft Corporation                                   */
397 /*                                                                        */
398 /*  DESCRIPTION                                                           */
399 /*                                                                        */
400 /*    This function checks for errors in the SNMP community get           */
401 /*    function call.                                                      */
402 /*                                                                        */
403 /*  INPUT                                                                 */
404 /*                                                                        */
405 /*    agent_ptr                             Pointer to SNMP agent         */
406 /*    community_string_ptr                  Pointer to the community      */
407 /*                                            string destination          */
408 /*                                                                        */
409 /*  OUTPUT                                                                */
410 /*                                                                        */
411 /*    status                                Completion status             */
412 /*                                                                        */
413 /*  CALLS                                                                 */
414 /*                                                                        */
415 /*    _nx_snmp_agent_community_get          Actual community get function */
416 /*                                                                        */
417 /*  CALLED BY                                                             */
418 /*                                                                        */
419 /*    Application Code                                                    */
420 /*                                                                        */
421 /*  RELEASE HISTORY                                                       */
422 /*                                                                        */
423 /*    DATE              NAME                      DESCRIPTION             */
424 /*                                                                        */
425 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
426 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
427 /*                                            resulting in version 6.1    */
428 /*                                                                        */
429 /**************************************************************************/
_nxe_snmp_agent_community_get(NX_SNMP_AGENT * agent_ptr,UCHAR ** community_string_ptr)430 UINT  _nxe_snmp_agent_community_get(NX_SNMP_AGENT *agent_ptr, UCHAR **community_string_ptr)
431 {
432 
433 UINT    status;
434 
435 
436     /* Check for invalid input pointers.  */
437     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) ||
438         (community_string_ptr == NX_NULL))
439         return(NX_PTR_ERROR);
440 
441     /* Call actual service.  */
442     status =  _nx_snmp_agent_community_get(agent_ptr, community_string_ptr);
443 
444     /* Return status.  */
445     return(status);
446 }
447 
448 
449 /**************************************************************************/
450 /*                                                                        */
451 /*  FUNCTION                                               RELEASE        */
452 /*                                                                        */
453 /*    _nx_snmp_agent_community_get                        PORTABLE C      */
454 /*                                                           6.1          */
455 /*  AUTHOR                                                                */
456 /*                                                                        */
457 /*    Yuxin Zhou, Microsoft Corporation                                   */
458 /*                                                                        */
459 /*  DESCRIPTION                                                           */
460 /*                                                                        */
461 /*    This function retrieves the community string.                       */
462 /*                                                                        */
463 /*  INPUT                                                                 */
464 /*                                                                        */
465 /*    agent_ptr                             Pointer to SNMP agent         */
466 /*    community_string_ptr                  Pointer to the community      */
467 /*                                            string destination          */
468 /*                                                                        */
469 /*  OUTPUT                                                                */
470 /*                                                                        */
471 /*    status                                Completion status             */
472 /*                                                                        */
473 /*  CALLS                                                                 */
474 /*                                                                        */
475 /*    None                                                                */
476 /*                                                                        */
477 /*  CALLED BY                                                             */
478 /*                                                                        */
479 /*    Application Code                                                    */
480 /*                                                                        */
481 /*  RELEASE HISTORY                                                       */
482 /*                                                                        */
483 /*    DATE              NAME                      DESCRIPTION             */
484 /*                                                                        */
485 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
486 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
487 /*                                            resulting in version 6.1    */
488 /*                                                                        */
489 /**************************************************************************/
_nx_snmp_agent_community_get(NX_SNMP_AGENT * agent_ptr,UCHAR ** community_string_ptr)490 UINT  _nx_snmp_agent_community_get(NX_SNMP_AGENT *agent_ptr, UCHAR **community_string_ptr)
491 {
492 
493     /* Set a pointer to the community string for the caller.  */
494     *community_string_ptr =  agent_ptr -> nx_snmp_agent_current_community_string;
495 
496     /* Return successful status.  */
497     return(NX_SUCCESS);
498 }
499 
500 
501 #ifndef NX_SNMP_DISABLE_V3
502 /**************************************************************************/
503 /*                                                                        */
504 /*  FUNCTION                                               RELEASE        */
505 /*                                                                        */
506 /*    _nxe_snmp_agent_context_engine_set                  PORTABLE C      */
507 /*                                                           6.1          */
508 /*  AUTHOR                                                                */
509 /*                                                                        */
510 /*    Yuxin Zhou, Microsoft Corporation                                   */
511 /*                                                                        */
512 /*  DESCRIPTION                                                           */
513 /*                                                                        */
514 /*    This function checks for errors in the SNMP context engine set      */
515 /*    function call.                                                      */
516 /*                                                                        */
517 /*  INPUT                                                                 */
518 /*                                                                        */
519 /*    agent_ptr                             Pointer to SNMP agent         */
520 /*    context_engine                        Pointer to context engine     */
521 /*    context_engine_size                   Number of bytes in the        */
522 /*                                            context engine              */
523 /*                                                                        */
524 /*  OUTPUT                                                                */
525 /*                                                                        */
526 /*    status                                Completion status             */
527 /*                                                                        */
528 /*  CALLS                                                                 */
529 /*                                                                        */
530 /*    _nx_snmp_agent_context_engine_set     Actual context engine set     */
531 /*                                            function                    */
532 /*                                                                        */
533 /*  CALLED BY                                                             */
534 /*                                                                        */
535 /*    Application Code                                                    */
536 /*                                                                        */
537 /*  RELEASE HISTORY                                                       */
538 /*                                                                        */
539 /*    DATE              NAME                      DESCRIPTION             */
540 /*                                                                        */
541 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
542 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
543 /*                                            resulting in version 6.1    */
544 /*                                                                        */
545 /**************************************************************************/
_nxe_snmp_agent_context_engine_set(NX_SNMP_AGENT * agent_ptr,UCHAR * context_engine,UINT context_engine_size)546 UINT  _nxe_snmp_agent_context_engine_set(NX_SNMP_AGENT *agent_ptr, UCHAR *context_engine, UINT context_engine_size)
547 {
548 
549 UINT    status;
550 
551 
552     /* Check for invalid input pointers.  */
553     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) ||
554         (context_engine == NX_NULL))
555         return(NX_PTR_ERROR);
556 
557     /* Check for an invalid size.  */
558     if ((context_engine_size == 0) || (context_engine_size >= NX_SNMP_MAX_CONTEXT_STRING))
559         return(NX_SNMP_ERROR);
560 
561     /* Call actual service.  */
562     status =  _nx_snmp_agent_context_engine_set(agent_ptr, context_engine, context_engine_size);
563 
564     /* Return status.  */
565     return(status);
566 }
567 
568 
569 /**************************************************************************/
570 /*                                                                        */
571 /*  FUNCTION                                               RELEASE        */
572 /*                                                                        */
573 /*    _nx_snmp_agent_context_engine_set                   PORTABLE C      */
574 /*                                                           6.1          */
575 /*  AUTHOR                                                                */
576 /*                                                                        */
577 /*    Yuxin Zhou, Microsoft Corporation                                   */
578 /*                                                                        */
579 /*  DESCRIPTION                                                           */
580 /*                                                                        */
581 /*    This function sets the context engine of the specified SNMP agent.  */
582 /*                                                                        */
583 /*  INPUT                                                                 */
584 /*                                                                        */
585 /*    agent_ptr                             Pointer to SNMP agent         */
586 /*    context_engine                        Pointer to context engine     */
587 /*    context_engine_size                   Number of bytes in the        */
588 /*                                            context engine              */
589 /*                                                                        */
590 /*  OUTPUT                                                                */
591 /*                                                                        */
592 /*    status                                Completion status             */
593 /*                                                                        */
594 /*  CALLS                                                                 */
595 /*                                                                        */
596 /*    None                                                                */
597 /*                                                                        */
598 /*  CALLED BY                                                             */
599 /*                                                                        */
600 /*    Application Code                                                    */
601 /*                                                                        */
602 /*  RELEASE HISTORY                                                       */
603 /*                                                                        */
604 /*    DATE              NAME                      DESCRIPTION             */
605 /*                                                                        */
606 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
607 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
608 /*                                            resulting in version 6.1    */
609 /*                                                                        */
610 /**************************************************************************/
_nx_snmp_agent_context_engine_set(NX_SNMP_AGENT * agent_ptr,UCHAR * context_engine,UINT context_engine_size)611 UINT  _nx_snmp_agent_context_engine_set(NX_SNMP_AGENT *agent_ptr, UCHAR *context_engine, UINT context_engine_size)
612 {
613 
614 UINT    i;
615 
616 
617     /* Verify V3 is currently enabled for this agent. */
618     if (agent_ptr -> nx_snmp_agent_v3_enabled == NX_FALSE)
619     {
620         return NX_NOT_ENABLED;
621     }
622 
623     /* Determine if the context engine is the correct size.  */
624     if (context_engine_size > NX_SNMP_MAX_CONTEXT_STRING)
625     {
626 
627         /* Return an error.  */
628         return(NX_SNMP_ERROR);
629     }
630 
631     /* Otherwise, store the context engine.  */
632     for (i = 0; i < context_engine_size; i++)
633     {
634 
635         /* Store a byte of the context engine.  */
636         agent_ptr -> nx_snmp_agent_v3_context_engine[i] =  context_engine[i];
637     }
638 
639     /* Set the context engine length.  */
640     agent_ptr -> nx_snmp_agent_v3_context_engine_size =  context_engine_size;
641 
642     /* Return successful completion.  */
643     return(NX_SUCCESS);
644 }
645 
646 
647 /**************************************************************************/
648 /*                                                                        */
649 /*  FUNCTION                                               RELEASE        */
650 /*                                                                        */
651 /*    _nxe_snmp_agent_context_name_set                    PORTABLE C      */
652 /*                                                           6.1          */
653 /*  AUTHOR                                                                */
654 /*                                                                        */
655 /*    Yuxin Zhou, Microsoft Corporation                                   */
656 /*                                                                        */
657 /*  DESCRIPTION                                                           */
658 /*                                                                        */
659 /*    This function checks for errors in the SNMP context name set        */
660 /*    function call.                                                      */
661 /*                                                                        */
662 /*  INPUT                                                                 */
663 /*                                                                        */
664 /*    agent_ptr                             Pointer to SNMP agent         */
665 /*    context_name                          Pointer to context name       */
666 /*    context_name_size                     Number of bytes in the        */
667 /*                                            context name                */
668 /*                                                                        */
669 /*  OUTPUT                                                                */
670 /*                                                                        */
671 /*    status                                Completion status             */
672 /*                                                                        */
673 /*  CALLS                                                                 */
674 /*                                                                        */
675 /*    _nx_snmp_agent_context_name_set       Actual context name set       */
676 /*                                            function                    */
677 /*                                                                        */
678 /*  CALLED BY                                                             */
679 /*                                                                        */
680 /*    Initialization                                                      */
681 /*                                                                        */
682 /*  RELEASE HISTORY                                                       */
683 /*                                                                        */
684 /*    DATE              NAME                      DESCRIPTION             */
685 /*                                                                        */
686 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
687 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
688 /*                                            resulting in version 6.1    */
689 /*                                                                        */
690 /**************************************************************************/
_nxe_snmp_agent_context_name_set(NX_SNMP_AGENT * agent_ptr,UCHAR * context_name,UINT context_name_size)691 UINT  _nxe_snmp_agent_context_name_set(NX_SNMP_AGENT *agent_ptr, UCHAR *context_name, UINT context_name_size)
692 {
693 
694 UINT    status;
695 
696 
697     /* Check for invalid input pointers.  */
698     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) ||
699         (context_name == NX_NULL))
700         return(NX_PTR_ERROR);
701 
702     /* Check for an invalid size.  */
703     if ((context_name_size == 0) || (context_name_size >= NX_SNMP_MAX_USER_NAME))
704         return(NX_SNMP_ERROR);
705 
706     /* Call actual service.  */
707     status =  _nx_snmp_agent_context_name_set(agent_ptr, context_name, context_name_size);
708 
709     /* Return status.  */
710     return(status);
711 }
712 
713 
714 /**************************************************************************/
715 /*                                                                        */
716 /*  FUNCTION                                               RELEASE        */
717 /*                                                                        */
718 /*    _nx_snmp_agent_context_name_set                     PORTABLE C      */
719 /*                                                           6.1          */
720 /*  AUTHOR                                                                */
721 /*                                                                        */
722 /*    Yuxin Zhou, Microsoft Corporation                                   */
723 /*                                                                        */
724 /*  DESCRIPTION                                                           */
725 /*                                                                        */
726 /*    This function sets the context name of the specified SNMP agent.    */
727 /*                                                                        */
728 /*  INPUT                                                                 */
729 /*                                                                        */
730 /*    agent_ptr                             Pointer to SNMP agent         */
731 /*    context_name                          Pointer to context name       */
732 /*    context_name_size                     Number of bytes in the        */
733 /*                                            context name                */
734 /*                                                                        */
735 /*  OUTPUT                                                                */
736 /*                                                                        */
737 /*    status                                Completion status             */
738 /*                                                                        */
739 /*  CALLS                                                                 */
740 /*                                                                        */
741 /*    None                                                                */
742 /*                                                                        */
743 /*  CALLED BY                                                             */
744 /*                                                                        */
745 /*    Initialization                                                      */
746 /*                                                                        */
747 /*  RELEASE HISTORY                                                       */
748 /*                                                                        */
749 /*    DATE              NAME                      DESCRIPTION             */
750 /*                                                                        */
751 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
752 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
753 /*                                            resulting in version 6.1    */
754 /*                                                                        */
755 /**************************************************************************/
_nx_snmp_agent_context_name_set(NX_SNMP_AGENT * agent_ptr,UCHAR * context_name,UINT context_name_size)756 UINT  _nx_snmp_agent_context_name_set(NX_SNMP_AGENT *agent_ptr, UCHAR *context_name, UINT context_name_size)
757 {
758 
759 UINT    i;
760 
761     /* Determine if the context name is the correct size.  */
762     if (context_name_size > NX_SNMP_MAX_CONTEXT_STRING)
763     {
764 
765         /* Return an error.  */
766         return(NX_SNMP_ERROR);
767     }
768 
769     /* Otherwise, store the context name.  */
770     for (i = 0; i < context_name_size; i++)
771     {
772 
773         /* Store a byte of the context name.  */
774         agent_ptr -> nx_snmp_agent_v3_context_name[i] =  context_name[i];
775     }
776 
777     /* Set the context name length.  */
778     agent_ptr -> nx_snmp_agent_v3_context_name_size =  context_name_size;
779 
780     /* Return successful completion.  */
781     return(NX_SUCCESS);
782 }
783 
784 
785 /**************************************************************************/
786 /*                                                                        */
787 /*  FUNCTION                                               RELEASE        */
788 /*                                                                        */
789 /*    _nxe_snmp_agent_v3_context_boots_set                PORTABLE C      */
790 /*                                                           6.1          */
791 /*  AUTHOR                                                                */
792 /*                                                                        */
793 /*    Yuxin Zhou, Microsoft Corporation                                   */
794 /*                                                                        */
795 /*  DESCRIPTION                                                           */
796 /*                                                                        */
797 /*    This function checks for errors in the SNMP context boots set       */
798 /*    function call.                                                      */
799 /*                                                                        */
800 /*  INPUT                                                                 */
801 /*                                                                        */
802 /*    agent_ptr                             Pointer to SNMP agent         */
803 /*    boots                                 Value to set agent boots to   */
804 /*                                                                        */
805 /*  OUTPUT                                                                */
806 /*                                                                        */
807 /*    NX_PTR_ERROR                          Invalid pointer input         */
808 /*    NX_SNMP_ERROR                         Invalid boot count input      */
809 /*    NX_SUCCESS                            Successful completion status  */
810 /*                                                                        */
811 /*  CALLS                                                                 */
812 /*                                                                        */
813 /*    _nx_snmp_agent_v3_context_boots_set    Actual context boots set      */
814 /*                                            function                    */
815 /*                                                                        */
816 /*  CALLED BY                                                             */
817 /*                                                                        */
818 /*    Initialization                                                      */
819 /*                                                                        */
820 /*  RELEASE HISTORY                                                       */
821 /*                                                                        */
822 /*    DATE              NAME                      DESCRIPTION             */
823 /*                                                                        */
824 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
825 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
826 /*                                            resulting in version 6.1    */
827 /*                                                                        */
828 /**************************************************************************/
_nxe_snmp_agent_v3_context_boots_set(NX_SNMP_AGENT * agent_ptr,UINT boots)829 UINT  _nxe_snmp_agent_v3_context_boots_set(NX_SNMP_AGENT *agent_ptr, UINT boots)
830 {
831 
832 UINT    status;
833 
834 
835     /* Check for invalid input pointer.  */
836     if (agent_ptr == NX_NULL)
837         return(NX_PTR_ERROR);
838 
839     /* Call actual service.  */
840     status =  _nx_snmp_agent_v3_context_boots_set(agent_ptr, boots);
841 
842     /* Return status.  */
843     return(status);
844 }
845 
846 
847 /**************************************************************************/
848 /*                                                                        */
849 /*  FUNCTION                                               RELEASE        */
850 /*                                                                        */
851 /*    _nx_snmp_agent_v3_context_boots_set                 PORTABLE C      */
852 /*                                                           6.1          */
853 /*  AUTHOR                                                                */
854 /*                                                                        */
855 /*    Yuxin Zhou, Microsoft Corporation                                   */
856 /*                                                                        */
857 /*  DESCRIPTION                                                           */
858 /*                                                                        */
859 /*    This function sets the context boot count of the specified SNMP     */
860 /*    agent.                                                              */
861 /*                                                                        */
862 /*  INPUT                                                                 */
863 /*                                                                        */
864 /*    agent_ptr                             Pointer to SNMP agent         */
865 /*    boots                                 Value to set agent boots to   */
866 /*                                                                        */
867 /*  OUTPUT                                                                */
868 /*                                                                        */
869 /*    NX_SUCCESS                            Successful completion status  */
870 /*    NX_SNMP_ERROR                         Invalid boot count input      */
871 /*                                                                        */
872 /*  CALLS                                                                 */
873 /*                                                                        */
874 /*    None                                                                */
875 /*                                                                        */
876 /*  CALLED BY                                                             */
877 /*                                                                        */
878 /*    Initialization                                                      */
879 /*                                                                        */
880 /*  RELEASE HISTORY                                                       */
881 /*                                                                        */
882 /*    DATE              NAME                      DESCRIPTION             */
883 /*                                                                        */
884 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
885 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
886 /*                                            resulting in version 6.1    */
887 /*                                                                        */
888 /**************************************************************************/
_nx_snmp_agent_v3_context_boots_set(NX_SNMP_AGENT * agent_ptr,UINT boots)889 UINT  _nx_snmp_agent_v3_context_boots_set(NX_SNMP_AGENT *agent_ptr, UINT boots)
890 {
891 
892     /* Set the context name length.  */
893     agent_ptr -> nx_snmp_agent_v3_context_engine_boots =  boots;
894 
895     /* Return successful completion.  */
896     return(NX_SUCCESS);
897 }
898 
899 #endif
900 
901 
902 /**************************************************************************/
903 /*                                                                        */
904 /*  FUNCTION                                               RELEASE        */
905 /*                                                                        */
906 /*    _nxe_snmp_agent_create                              PORTABLE C      */
907 /*                                                           6.1          */
908 /*  AUTHOR                                                                */
909 /*                                                                        */
910 /*    Yuxin Zhou, Microsoft Corporation                                   */
911 /*                                                                        */
912 /*  DESCRIPTION                                                           */
913 /*                                                                        */
914 /*    This function checks for errors in the SNMP agent create            */
915 /*    function call.                                                      */
916 /*                                                                        */
917 /*  INPUT                                                                 */
918 /*                                                                        */
919 /*    agent_ptr                             Pointer to SNMP agent         */
920 /*    snmp_agent_name                       Name of SNMP agent            */
921 /*    ip_ptr                                Pointer to IP instance        */
922 /*    stack_ptr                             Pointer to stack for SNMP     */
923 /*                                            thread                      */
924 /*    stack_size                            Size in bytes of thread stack */
925 /*    pool_ptr                              Default packet pool           */
926 /*    snmp_agent_username_process           Username callback routine     */
927 /*    snmp_agent_get_process                Get callback routine          */
928 /*    snmp_agent_getnext_process            Getnext callback routine      */
929 /*    snmp_agent_set_process                Set callback routine          */
930 /*                                                                        */
931 /*  OUTPUT                                                                */
932 /*                                                                        */
933 /*    status                                Completion status             */
934 /*                                                                        */
935 /*  CALLS                                                                 */
936 /*                                                                        */
937 /*    _nx_snmp_agent_create                 Actual agent create function  */
938 /*                                                                        */
939 /*  CALLED BY                                                             */
940 /*                                                                        */
941 /*    Application Code                                                    */
942 /*                                                                        */
943 /*  RELEASE HISTORY                                                       */
944 /*                                                                        */
945 /*    DATE              NAME                      DESCRIPTION             */
946 /*                                                                        */
947 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
948 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
949 /*                                            resulting in version 6.1    */
950 /*                                                                        */
951 /**************************************************************************/
_nxe_snmp_agent_create(NX_SNMP_AGENT * agent_ptr,CHAR * snmp_agent_name,NX_IP * ip_ptr,VOID * stack_ptr,ULONG stack_size,NX_PACKET_POOL * pool_ptr,UINT (* snmp_agent_username_process)(struct NX_SNMP_AGENT_STRUCT * agent_ptr,UCHAR * username),UINT (* snmp_agent_get_process)(struct NX_SNMP_AGENT_STRUCT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data),UINT (* snmp_agent_getnext_process)(struct NX_SNMP_AGENT_STRUCT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data),UINT (* snmp_agent_set_process)(struct NX_SNMP_AGENT_STRUCT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data))952 UINT  _nxe_snmp_agent_create(NX_SNMP_AGENT *agent_ptr, CHAR *snmp_agent_name, NX_IP *ip_ptr, VOID *stack_ptr, ULONG stack_size, NX_PACKET_POOL *pool_ptr,
953                 UINT (*snmp_agent_username_process)(struct NX_SNMP_AGENT_STRUCT *agent_ptr, UCHAR *username),
954                 UINT (*snmp_agent_get_process)(struct NX_SNMP_AGENT_STRUCT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data),
955                 UINT (*snmp_agent_getnext_process)(struct NX_SNMP_AGENT_STRUCT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data),
956                 UINT (*snmp_agent_set_process)(struct NX_SNMP_AGENT_STRUCT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data))
957 {
958 
959 UINT    status;
960 
961 
962     /* Check for invalid input pointers.  */
963     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id == NX_SNMP_ID) || (ip_ptr == NX_NULL) || (stack_ptr == NX_NULL) ||
964         (pool_ptr == NX_NULL) || (!snmp_agent_username_process) || (!snmp_agent_get_process) || (!snmp_agent_getnext_process) || (!snmp_agent_set_process))
965         return(NX_PTR_ERROR);
966 
967     /* Check for an invalid size.  */
968     if (stack_size == 0)
969         return(NX_SNMP_ERROR);
970 
971     /* Call actual service.  */
972     status =  _nx_snmp_agent_create(agent_ptr, snmp_agent_name, ip_ptr, stack_ptr, stack_size, pool_ptr,
973                     snmp_agent_username_process, snmp_agent_get_process, snmp_agent_getnext_process, snmp_agent_set_process);
974 
975     /* Return status.  */
976     return(status);
977 }
978 
979 
980 /**************************************************************************/
981 /*                                                                        */
982 /*  FUNCTION                                               RELEASE        */
983 /*                                                                        */
984 /*    _nx_snmp_agent_create                               PORTABLE C      */
985 /*                                                           6.1          */
986 /*  AUTHOR                                                                */
987 /*                                                                        */
988 /*    Yuxin Zhou, Microsoft Corporation                                   */
989 /*                                                                        */
990 /*  DESCRIPTION                                                           */
991 /*                                                                        */
992 /*    This function creates an SNMP agent.                                */
993 /*                                                                        */
994 /*    Note: The string length of username in snmp_agent_username_process  */
995 /*    callback is limited by NX_SNMP_MAX_USER_NAME.                       */
996 /*    The string length of object_requested in snmp_agent_get_process,    */
997 /*    snmp_agent_getnext_process and snmp_agent_set_process callback is   */
998 /*    limited by NX_SNMP_MAX_OCTET_STRING.                                */
999 /*                                                                        */
1000 /*  INPUT                                                                 */
1001 /*                                                                        */
1002 /*    agent_ptr                             Pointer to SNMP agent         */
1003 /*    snmp_agent_name                       Name of SNMP agent            */
1004 /*    ip_ptr                                Pointer to IP instance        */
1005 /*    stack_ptr                             Pointer to stack for SNMP     */
1006 /*                                            thread                      */
1007 /*    stack_size                            Size in bytes of thread stack */
1008 /*    pool_ptr                              Default packet pool           */
1009 /*    snmp_agent_username_process           Username callback routine     */
1010 /*    snmp_agent_get_process                Get callback routine          */
1011 /*    snmp_agent_getnext_process            Getnext callback routine      */
1012 /*    snmp_agent_set_process                Set callback routine          */
1013 /*                                                                        */
1014 /*  OUTPUT                                                                */
1015 /*                                                                        */
1016 /*    status                                Completion status             */
1017 /*                                                                        */
1018 /*  CALLS                                                                 */
1019 /*                                                                        */
1020 /*    nx_udp_socket_bind                    Bind SNMP agent socket        */
1021 /*    nx_udp_socket_create                  Create SNMP agent socket      */
1022 /*    nx_udp_socket_delete                  Delete SNMP agent socket      */
1023 /*    nx_udp_socket_unbind                  Unbind SNMP agent socket      */
1024 /*    tx_thread_create                      Create SNMP agent thread      */
1025 /*                                                                        */
1026 /*  CALLED BY                                                             */
1027 /*                                                                        */
1028 /*    Application Code                                                    */
1029 /*                                                                        */
1030 /*  RELEASE HISTORY                                                       */
1031 /*                                                                        */
1032 /*    DATE              NAME                      DESCRIPTION             */
1033 /*                                                                        */
1034 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1035 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1036 /*                                            resulting in version 6.1    */
1037 /*                                                                        */
1038 /**************************************************************************/
_nx_snmp_agent_create(NX_SNMP_AGENT * agent_ptr,CHAR * snmp_agent_name,NX_IP * ip_ptr,VOID * stack_ptr,ULONG stack_size,NX_PACKET_POOL * pool_ptr,UINT (* snmp_agent_username_process)(struct NX_SNMP_AGENT_STRUCT * agent_ptr,UCHAR * username),UINT (* snmp_agent_get_process)(struct NX_SNMP_AGENT_STRUCT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data),UINT (* snmp_agent_getnext_process)(struct NX_SNMP_AGENT_STRUCT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data),UINT (* snmp_agent_set_process)(struct NX_SNMP_AGENT_STRUCT * agent_ptr,UCHAR * object_requested,NX_SNMP_OBJECT_DATA * object_data))1039 UINT  _nx_snmp_agent_create(NX_SNMP_AGENT *agent_ptr, CHAR *snmp_agent_name, NX_IP *ip_ptr, VOID *stack_ptr, ULONG stack_size, NX_PACKET_POOL *pool_ptr,
1040                 UINT (*snmp_agent_username_process)(struct NX_SNMP_AGENT_STRUCT *agent_ptr, UCHAR *username),
1041                 UINT (*snmp_agent_get_process)(struct NX_SNMP_AGENT_STRUCT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data),
1042                 UINT (*snmp_agent_getnext_process)(struct NX_SNMP_AGENT_STRUCT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data),
1043                 UINT (*snmp_agent_set_process)(struct NX_SNMP_AGENT_STRUCT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data))
1044 {
1045 
1046 UINT        status;
1047 
1048 #ifndef NX_SNMP_DISABLE_V3
1049 UINT        i;
1050 #endif
1051 
1052 
1053 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
1054     NX_SNMPV3_DBG_PRINTF( "Creating snmp agent of size %d\n\r", stack_size);
1055 #endif
1056 
1057     /* Clear the SNMP agent structure.  */
1058     memset((void *) agent_ptr, 0, sizeof(NX_SNMP_AGENT));
1059 
1060     /* Create the agent's UDP socket.  */
1061      status =  nx_udp_socket_create(ip_ptr, &(agent_ptr -> nx_snmp_agent_socket), snmp_agent_name,
1062                                     NX_SNMP_TYPE_OF_SERVICE,  NX_SNMP_FRAGMENT_OPTION,
1063                                     NX_SNMP_TIME_TO_LIVE, NX_SNMP_QUEUE_DEPTH);
1064 
1065      /* Determine if an error occurred.   */
1066      if (status)
1067      {
1068 
1069          /* Yes, return error code.  */
1070          return(NX_SNMP_ERROR);
1071      }
1072 
1073     /* Now create the SNMP Server thread.  */
1074     status =  tx_thread_create(&(agent_ptr -> nx_snmp_agent_thread), "SNMP Agent Thread", _nx_snmp_agent_thread_entry,
1075             (ULONG) agent_ptr, stack_ptr, stack_size, NX_SNMP_AGENT_PRIORITY, NX_SNMP_AGENT_PRIORITY,
1076             TX_NO_TIME_SLICE, TX_DONT_START);
1077 
1078     /* Determine if an error occurred creating the thread.  */
1079     if (status)
1080     {
1081 
1082          /* Delete the UDP socket.  */
1083          nx_udp_socket_delete(&(agent_ptr -> nx_snmp_agent_socket));
1084 
1085         /* Yes, return error code.  */
1086         return(NX_SNMP_ERROR);
1087     }
1088 
1089     /* Save the Server name.  */
1090     agent_ptr -> nx_snmp_agent_name =  snmp_agent_name;
1091 
1092     /* Save the IP pointer address.  */
1093     agent_ptr -> nx_snmp_agent_ip_ptr =  ip_ptr;
1094 
1095     /* Save the packet pool pointer.  */
1096     agent_ptr -> nx_snmp_agent_packet_pool_ptr =  pool_ptr;
1097 
1098     /* Default the SNMP network interface to the primary interface. */
1099     agent_ptr -> nx_snmp_agent_interface_index = 0;
1100 
1101     /* Initialize the agent as configured for all versions.
1102 
1103        Note that the #define options for disabling version support override dynamic version status.
1104 
1105        For example if  NX_SNMP_DISABLE_V2 is disabled, setting nx_snmp_agent_v2_enabled
1106        to NX_TRUE has no effect. If NX_SNMP_DISABLE_V2 is not disabled, then
1107        nx_snmp_agent_v2_enabled determines at run time if the SNMP is enabled for V2.*/
1108 
1109     agent_ptr -> nx_snmp_agent_v1_enabled = NX_TRUE;
1110     agent_ptr -> nx_snmp_agent_v2_enabled = NX_TRUE;
1111     agent_ptr -> nx_snmp_agent_v3_enabled = NX_TRUE;
1112 
1113 
1114 #ifndef NX_SNMP_DISABLE_V3
1115 
1116     /* Setup the SNMP v3 information.  */
1117 
1118     /* Setup the default context engine.  */
1119     for (i = 0; i < _nx_snmp_default_context_engine_size; i++)
1120     {
1121 
1122         /* Copy byte of default context engine.  */
1123         agent_ptr -> nx_snmp_agent_v3_context_engine[i] =  _nx_snmp_default_context_engine[i];
1124     }
1125 
1126     /* Set the default context engine size.  */
1127     agent_ptr -> nx_snmp_agent_v3_context_engine_size =   _nx_snmp_default_context_engine_size;
1128 
1129     /* Start the time (in ticks) since the previous reboot. */
1130     agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time =  (UINT) (tx_time_get()/NX_IP_PERIODIC_RATE);
1131 
1132 #endif /* NX_SNMP_DISABLE_V3 */
1133 
1134     /* Save the application request processing callback routines.  */
1135     agent_ptr -> nx_snmp_agent_get_process =      snmp_agent_get_process;
1136     agent_ptr -> nx_snmp_agent_getnext_process =  snmp_agent_getnext_process;
1137     agent_ptr -> nx_snmp_agent_set_process =      snmp_agent_set_process;
1138     agent_ptr -> nx_snmp_agent_username_process = snmp_agent_username_process;
1139 
1140     /* Set the agent ID to indicate the SNMP agent thread is ready.  */
1141     agent_ptr -> nx_snmp_agent_id =  NX_SNMP_ID;
1142 
1143     /* Return successful completion.  */
1144     return(NX_SUCCESS);
1145 }
1146 
1147 /**************************************************************************/
1148 /*                                                                        */
1149 /*  FUNCTION                                               RELEASE        */
1150 /*                                                                        */
1151 /*    _nxe_snmp_agent_request_get_type_test               PORTABLE C      */
1152 /*                                                           6.1          */
1153 /*  AUTHOR                                                                */
1154 /*                                                                        */
1155 /*    Yuxin Zhou, Microsoft Corporation                                   */
1156 /*                                                                        */
1157 /*  DESCRIPTION                                                           */
1158 /*                                                                        */
1159 /*    This function checks for errors in the SNMP agent get current       */
1160 /*    request type.                                                       */
1161 /*                                                                        */
1162 /*  INPUT                                                                 */
1163 /*                                                                        */
1164 /*    agent_ptr                             Pointer to SNMP agent         */
1165 /*    is_get_type                           Pointer to request type       */
1166 /*                                                                        */
1167 /*  OUTPUT                                                                */
1168 /*                                                                        */
1169 /*    status                                Completion status             */
1170 /*                                                                        */
1171 /*  CALLS                                                                 */
1172 /*                                                                        */
1173 /*    _nx_snmp_agent_request_get_type_test  Actual request type service   */
1174 /*                                                                        */
1175 /*  CALLED BY                                                             */
1176 /*                                                                        */
1177 /*    Application Code                                                    */
1178 /*                                                                        */
1179 /*  RELEASE HISTORY                                                       */
1180 /*                                                                        */
1181 /*    DATE              NAME                      DESCRIPTION             */
1182 /*                                                                        */
1183 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1184 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1185 /*                                            resulting in version 6.1    */
1186 /*                                                                        */
1187 /**************************************************************************/
_nxe_snmp_agent_request_get_type_test(NX_SNMP_AGENT * agent_ptr,UINT * is_get_type)1188 UINT _nxe_snmp_agent_request_get_type_test(NX_SNMP_AGENT *agent_ptr, UINT *is_get_type)
1189 {
1190 UINT status;
1191 
1192     if ((agent_ptr == NX_NULL) || (is_get_type == NX_NULL))
1193     {
1194         return NX_PTR_ERROR;
1195     }
1196 
1197     status = _nx_snmp_agent_request_get_type_test(agent_ptr, is_get_type);
1198     return status;
1199 }
1200 
1201 
1202 /**************************************************************************/
1203 /*                                                                        */
1204 /*  FUNCTION                                               RELEASE        */
1205 /*                                                                        */
1206 /*    _nx_snmp_agent_request_get_type_test                PORTABLE C      */
1207 /*                                                           6.1          */
1208 /*  AUTHOR                                                                */
1209 /*                                                                        */
1210 /*    Yuxin Zhou, Microsoft Corporation                                   */
1211 /*                                                                        */
1212 /*  DESCRIPTION                                                           */
1213 /*                                                                        */
1214 /*    This function indicates if the current request recieved from the    */
1215 /*    SNMP manager is a Get type (GET, GETNEXT etc) of a SET type. It is  */
1216 /*    intended for use in the username_callback for the host application  */
1217 /*    to process the request for matching community string (private for   */
1218 /*    set requests, public for get requests).                             */
1219 /*                                                                        */
1220 /*  INPUT                                                                 */
1221 /*                                                                        */
1222 /*    agent_ptr                             Pointer to SNMP agent         */
1223 /*    is_get_type                           Pointer to request type       */
1224 /*                                                                        */
1225 /*  OUTPUT                                                                */
1226 /*                                                                        */
1227 /*    status                                Completion status             */
1228 /*                                                                        */
1229 /*  CALLS                                                                 */
1230 /*                                                                        */
1231 /*    None                                                                */
1232 /*                                                                        */
1233 /*  CALLED BY                                                             */
1234 /*                                                                        */
1235 /*    Application Code                                                    */
1236 /*                                                                        */
1237 /*  RELEASE HISTORY                                                       */
1238 /*                                                                        */
1239 /*    DATE              NAME                      DESCRIPTION             */
1240 /*                                                                        */
1241 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1242 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1243 /*                                            resulting in version 6.1    */
1244 /*                                                                        */
1245 /**************************************************************************/
_nx_snmp_agent_request_get_type_test(NX_SNMP_AGENT * agent_ptr,UINT * is_get_type)1246 UINT  _nx_snmp_agent_request_get_type_test(NX_SNMP_AGENT *agent_ptr, UINT *is_get_type)
1247 {
1248 
1249     *is_get_type = agent_ptr -> nx_snmp_agent_request_get_type;
1250 
1251     return NX_SUCCESS;
1252 }
1253 
1254 /**************************************************************************/
1255 /*                                                                        */
1256 /*  FUNCTION                                               RELEASE        */
1257 /*                                                                        */
1258 /*    _nxe_snmp_agent_delete                              PORTABLE C      */
1259 /*                                                           6.1          */
1260 /*  AUTHOR                                                                */
1261 /*                                                                        */
1262 /*    Yuxin Zhou, Microsoft Corporation                                   */
1263 /*                                                                        */
1264 /*  DESCRIPTION                                                           */
1265 /*                                                                        */
1266 /*    This function checks for errors in the SNMP agent delete            */
1267 /*    function call.                                                      */
1268 /*                                                                        */
1269 /*  INPUT                                                                 */
1270 /*                                                                        */
1271 /*    agent_ptr                             Pointer to SNMP agent         */
1272 /*                                                                        */
1273 /*  OUTPUT                                                                */
1274 /*                                                                        */
1275 /*    status                                Completion status             */
1276 /*                                                                        */
1277 /*  CALLS                                                                 */
1278 /*                                                                        */
1279 /*    _nx_snmp_agent_delete                 Actual agent delete function  */
1280 /*                                                                        */
1281 /*  CALLED BY                                                             */
1282 /*                                                                        */
1283 /*    Application Code                                                    */
1284 /*                                                                        */
1285 /*  RELEASE HISTORY                                                       */
1286 /*                                                                        */
1287 /*    DATE              NAME                      DESCRIPTION             */
1288 /*                                                                        */
1289 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1290 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1291 /*                                            resulting in version 6.1    */
1292 /*                                                                        */
1293 /**************************************************************************/
_nxe_snmp_agent_delete(NX_SNMP_AGENT * agent_ptr)1294 UINT  _nxe_snmp_agent_delete(NX_SNMP_AGENT *agent_ptr)
1295 {
1296 
1297 UINT    status;
1298 
1299 
1300     /* Check for invalid input pointers.  */
1301     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID))
1302         return(NX_PTR_ERROR);
1303 
1304     /* Call actual service.  */
1305     status =  _nx_snmp_agent_delete(agent_ptr);
1306 
1307     /* Return status.  */
1308     return(status);
1309 }
1310 
1311 
1312 /**************************************************************************/
1313 /*                                                                        */
1314 /*  FUNCTION                                               RELEASE        */
1315 /*                                                                        */
1316 /*    _nx_snmp_agent_delete                               PORTABLE C      */
1317 /*                                                           6.1          */
1318 /*  AUTHOR                                                                */
1319 /*                                                                        */
1320 /*    Yuxin Zhou, Microsoft Corporation                                   */
1321 /*                                                                        */
1322 /*  DESCRIPTION                                                           */
1323 /*                                                                        */
1324 /*    This function deletes the previously created SNMP agent.            */
1325 /*                                                                        */
1326 /*  INPUT                                                                 */
1327 /*                                                                        */
1328 /*    agent_ptr                             Pointer to SNMP agent         */
1329 /*                                                                        */
1330 /*  OUTPUT                                                                */
1331 /*                                                                        */
1332 /*    status                                Completion status             */
1333 /*                                                                        */
1334 /*  CALLS                                                                 */
1335 /*                                                                        */
1336 /*    nx_udp_socket_delete                  Delete SNMP agent socket      */
1337 /*    nx_udp_socket_unbind                  Unbind SNMP agent socket      */
1338 /*    tx_thread_delete                      Delete SNMP agent thread      */
1339 /*    tx_thread_terminate                   Terminate SNMP agent thread   */
1340 /*                                                                        */
1341 /*  CALLED BY                                                             */
1342 /*                                                                        */
1343 /*    Application Code                                                    */
1344 /*                                                                        */
1345 /*  RELEASE HISTORY                                                       */
1346 /*                                                                        */
1347 /*    DATE              NAME                      DESCRIPTION             */
1348 /*                                                                        */
1349 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1350 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1351 /*                                            resulting in version 6.1    */
1352 /*                                                                        */
1353 /**************************************************************************/
_nx_snmp_agent_delete(NX_SNMP_AGENT * agent_ptr)1354 UINT  _nx_snmp_agent_delete(NX_SNMP_AGENT *agent_ptr)
1355 {
1356 
1357     /* Terminate the SNMP thread.  */
1358     tx_thread_terminate(&(agent_ptr -> nx_snmp_agent_thread));
1359 
1360     /* Delete the SNMP thread.  */
1361     tx_thread_delete(&(agent_ptr -> nx_snmp_agent_thread));
1362 
1363     /* Unbind the UDP socket.  */
1364     nx_udp_socket_unbind(&(agent_ptr -> nx_snmp_agent_socket));
1365 
1366     /* Delete the UDP socket.  */
1367     nx_udp_socket_delete(&(agent_ptr -> nx_snmp_agent_socket));
1368 
1369     /* Clear the agent ID to indicate the SNMP agent is deleted.  */
1370     agent_ptr -> nx_snmp_agent_id =  0;
1371 
1372     /* Return successful completion.  */
1373     return(NX_SUCCESS);
1374 }
1375 
1376 
1377 /**************************************************************************/
1378 /*                                                                        */
1379 /*  FUNCTION                                               RELEASE        */
1380 /*                                                                        */
1381 /*    _nxe_snmp_agent_current_version_get                 PORTABLE C      */
1382 /*                                                           6.1          */
1383 /*  AUTHOR                                                                */
1384 /*                                                                        */
1385 /*    Yuxin Zhou, Microsoft Corporation                                   */
1386 /*                                                                        */
1387 /*  DESCRIPTION                                                           */
1388 /*                                                                        */
1389 /*    This function performs error checking for the get the received      */
1390 /*    packet SNMP version service.                                        */
1391 /*                                                                        */
1392 /*  INPUT                                                                 */
1393 /*                                                                        */
1394 /*    agent_ptr                             Pointer to SNMP agent         */
1395 /*    version                               Pointer to packet SNMP version*/
1396 /*                                                                        */
1397 /*  OUTPUT                                                                */
1398 /*                                                                        */
1399 /*    NX_PTR_ERROR                          Invalid pointer input         */
1400 /*    status                                Completion status             */
1401 /*                                                                        */
1402 /*  CALLS                                                                 */
1403 /*                                                                        */
1404 /*    _nx_snmp_agent_current_version_get    Actual get version service    */
1405 /*                                                                        */
1406 /*  CALLED BY                                                             */
1407 /*                                                                        */
1408 /*    Application Code                                                    */
1409 /*                                                                        */
1410 /*  RELEASE HISTORY                                                       */
1411 /*                                                                        */
1412 /*    DATE              NAME                      DESCRIPTION             */
1413 /*                                                                        */
1414 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1415 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1416 /*                                            resulting in version 6.1    */
1417 /*                                                                        */
1418 /**************************************************************************/
_nxe_snmp_agent_current_version_get(NX_SNMP_AGENT * agent_ptr,UINT * version)1419 UINT _nxe_snmp_agent_current_version_get(NX_SNMP_AGENT *agent_ptr, UINT *version)
1420 {
1421 UINT status;
1422 
1423     if ((agent_ptr == NX_NULL) || (version == NX_NULL))
1424     {
1425         return NX_PTR_ERROR;
1426     }
1427 
1428     status = _nx_snmp_agent_current_version_get(agent_ptr, version);
1429 
1430     return status;
1431 }
1432 
1433 
1434 /**************************************************************************/
1435 /*                                                                        */
1436 /*  FUNCTION                                               RELEASE        */
1437 /*                                                                        */
1438 /*    _nx_snmp_agent_current_version_get                  PORTABLE C      */
1439 /*                                                           6.1          */
1440 /*  AUTHOR                                                                */
1441 /*                                                                        */
1442 /*    Yuxin Zhou, Microsoft Corporation                                   */
1443 /*                                                                        */
1444 /*  DESCRIPTION                                                           */
1445 /*                                                                        */
1446 /*    This function returns the received packet's SNMP version.           */
1447 /*                                                                        */
1448 /*  INPUT                                                                 */
1449 /*                                                                        */
1450 /*    agent_ptr                             Pointer to SNMP agent         */
1451 /*    version                               Pointer to packet SNMP version*/
1452 /*                                                                        */
1453 /*  OUTPUT                                                                */
1454 /*                                                                        */
1455 /*    NX_SUCCESS                            Successful completion         */
1456 /*                                                                        */
1457 /*  CALLS                                                                 */
1458 /*                                                                        */
1459 /*    None                                                                */
1460 /*                                                                        */
1461 /*  CALLED BY                                                             */
1462 /*                                                                        */
1463 /*    Application Code                                                    */
1464 /*                                                                        */
1465 /*  RELEASE HISTORY                                                       */
1466 /*                                                                        */
1467 /*    DATE              NAME                      DESCRIPTION             */
1468 /*                                                                        */
1469 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1470 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1471 /*                                            resulting in version 6.1    */
1472 /*                                                                        */
1473 /**************************************************************************/
_nx_snmp_agent_current_version_get(NX_SNMP_AGENT * agent_ptr,UINT * version)1474 UINT _nx_snmp_agent_current_version_get(NX_SNMP_AGENT *agent_ptr, UINT *version)
1475 {
1476 
1477     *version = agent_ptr -> nx_snmp_agent_current_version;
1478 
1479     return NX_SUCCESS;
1480 }
1481 
1482 
1483 /**************************************************************************/
1484 /*                                                                        */
1485 /*  FUNCTION                                               RELEASE        */
1486 /*                                                                        */
1487 /*    _nxe_snmp_agent_set_version                         PORTABLE C      */
1488 /*                                                           6.1          */
1489 /*  AUTHOR                                                                */
1490 /*                                                                        */
1491 /*    Yuxin Zhou, Microsoft Corporation                                   */
1492 /*                                                                        */
1493 /*  DESCRIPTION                                                           */
1494 /*                                                                        */
1495 /*    This function performs error checking for (dis)enabling the SNMP    */
1496 /*    agent for SNMPV1, SNMPV2 and SNMPV3.                                */
1497 /*                                                                        */
1498 /*  INPUT                                                                 */
1499 /*                                                                        */
1500 /*    agent_ptr                             Pointer to SNMP agent         */
1501 /*    enabled_v1                            V1 enable status              */
1502 /*    enabled_v2                            V2 enable status              */
1503 /*    enabled_v3                            V3 enable status              */
1504 /*                                          Enable = 1 (NX_TRUE)          */
1505 /*                                                                        */
1506 /*  OUTPUT                                                                */
1507 /*                                                                        */
1508 /*    NX_PTR_ERROR                          Invalid pointer input         */
1509 /*    status                                Completion status             */
1510 /*                                                                        */
1511 /*  CALLS                                                                 */
1512 /*                                                                        */
1513 /*    None                                                                */
1514 /*                                                                        */
1515 /*  CALLED BY                                                             */
1516 /*                                                                        */
1517 /*    Application Code                                                    */
1518 /*                                                                        */
1519 /*  RELEASE HISTORY                                                       */
1520 /*                                                                        */
1521 /*    DATE              NAME                      DESCRIPTION             */
1522 /*                                                                        */
1523 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1524 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1525 /*                                            resulting in version 6.1    */
1526 /*                                                                        */
1527 /**************************************************************************/
_nxe_snmp_agent_version_set(NX_SNMP_AGENT * agent_ptr,UINT enabled_v1,UINT enable_v2,UINT enable_v3)1528 UINT _nxe_snmp_agent_version_set(NX_SNMP_AGENT *agent_ptr, UINT enabled_v1, UINT enable_v2, UINT enable_v3)
1529 {
1530 UINT status;
1531 
1532     /* Check for invalid input */
1533     if (agent_ptr == NX_NULL)
1534     {
1535         return NX_PTR_ERROR;
1536     }
1537 
1538     /* Call the actual service. */
1539     status = _nx_snmp_agent_version_set(agent_ptr, enabled_v1, enable_v2, enable_v3);
1540 
1541     return status;
1542 }
1543 
1544 
1545 /**************************************************************************/
1546 /*                                                                        */
1547 /*  FUNCTION                                               RELEASE        */
1548 /*                                                                        */
1549 /*    _nx_snmp_agent_version_set                          PORTABLE C      */
1550 /*                                                           6.1          */
1551 /*  AUTHOR                                                                */
1552 /*                                                                        */
1553 /*    Yuxin Zhou, Microsoft Corporation                                   */
1554 /*                                                                        */
1555 /*  DESCRIPTION                                                           */
1556 /*                                                                        */
1557 /*    This function sets the SNMP agent status for SNMPV1, SNMPV2 and     */
1558 /*    SNMPV3.                                                             */
1559 /*                                                                        */
1560 /*    Note that the #define options for disabling version support override*/
1561 /*    dynamic version status.                                             */
1562 /*                                                                        */
1563 /*    For example if  NX_SNMP_DISABLE_V2 is disabled, setting             */
1564 /*    nx_snmp_agent_v2_enabled to NX_TRUE has no effect. If               */
1565 /*    NX_SNMP_DISABLE_V2 is not disabled, then nx_snmp_agent_v2_enabled   */
1566 /*    determines at run time if the SNMP is enabled for V2.               */
1567 /*                                                                        */
1568 /*  INPUT                                                                 */
1569 /*                                                                        */
1570 /*    agent_ptr                             Pointer to SNMP agent         */
1571 /*    enabled_v1                            V1 enable status              */
1572 /*    enabled_v2                            V2 enable status              */
1573 /*    enabled_v3                            V3 enable status              */
1574 /*                                                                        */
1575 /*  OUTPUT                                                                */
1576 /*                                                                        */
1577 /*    NX_SUCCESS                            Successful completion         */
1578 /*                                                                        */
1579 /*  CALLS                                                                 */
1580 /*                                                                        */
1581 /*    None                                                                */
1582 /*                                                                        */
1583 /*  CALLED BY                                                             */
1584 /*                                                                        */
1585 /*    Application Code                                                    */
1586 /*                                                                        */
1587 /*  RELEASE HISTORY                                                       */
1588 /*                                                                        */
1589 /*    DATE              NAME                      DESCRIPTION             */
1590 /*                                                                        */
1591 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1592 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1593 /*                                            resulting in version 6.1    */
1594 /*                                                                        */
1595 /**************************************************************************/
_nx_snmp_agent_version_set(NX_SNMP_AGENT * agent_ptr,UINT enabled_v1,UINT enable_v2,UINT enable_v3)1596 UINT _nx_snmp_agent_version_set(NX_SNMP_AGENT *agent_ptr, UINT enabled_v1, UINT enable_v2, UINT enable_v3)
1597 {
1598 
1599     /* Set the agent status for each of the SNMP versions. */
1600     agent_ptr -> nx_snmp_agent_v1_enabled = enabled_v1;
1601 
1602     agent_ptr -> nx_snmp_agent_v2_enabled = enable_v2;
1603 
1604     agent_ptr -> nx_snmp_agent_v3_enabled = enable_v3;
1605 
1606     return NX_SUCCESS;
1607 }
1608 
1609 
1610 /**************************************************************************/
1611 /*                                                                        */
1612 /*  FUNCTION                                               RELEASE        */
1613 /*                                                                        */
1614 /*    _nx_snmp_agent_set_interface                        PORTABLE C      */
1615 /*                                                           6.1.6        */
1616 /*  AUTHOR                                                                */
1617 /*                                                                        */
1618 /*    Yuxin Zhou, Microsoft Corporation                                   */
1619 /*                                                                        */
1620 /*  DESCRIPTION                                                           */
1621 /*                                                                        */
1622 /*    This function sets the SNMP network interface for the SNMP agent.   */
1623 /*                                                                        */
1624 /*  INPUT                                                                 */
1625 /*                                                                        */
1626 /*    agent_ptr                             Pointer to SNMP agent         */
1627 /*    if_index                              SNMP network interface index  */
1628 /*                                                                        */
1629 /*  OUTPUT                                                                */
1630 /*                                                                        */
1631 /*    status                                Completion status             */
1632 /*                                                                        */
1633 /*  CALLS                                                                 */
1634 /*                                                                        */
1635 /*    None                                                                */
1636 /*                                                                        */
1637 /*  CALLED BY                                                             */
1638 /*                                                                        */
1639 /*    Application Code                                                    */
1640 /*                                                                        */
1641 /*  RELEASE HISTORY                                                       */
1642 /*                                                                        */
1643 /*    DATE              NAME                      DESCRIPTION             */
1644 /*                                                                        */
1645 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1646 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1647 /*                                            resulting in version 6.1    */
1648 /*  04-02-2021     Yuxin Zhou               Modified comment(s),          */
1649 /*                                            checked the interface index,*/
1650 /*                                            resulting in version 6.1.6  */
1651 /*                                                                        */
1652 /**************************************************************************/
_nxe_snmp_agent_set_interface(NX_SNMP_AGENT * agent_ptr,UINT if_index)1653 UINT _nxe_snmp_agent_set_interface(NX_SNMP_AGENT *agent_ptr, UINT if_index)
1654 {
1655 UINT status;
1656 
1657     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID))
1658     {
1659         return NX_PTR_ERROR;
1660     }
1661 
1662     /* Check for valid interface index.  */
1663     if (if_index >= NX_MAX_PHYSICAL_INTERFACES)
1664     {
1665         return(NX_INVALID_INTERFACE);
1666     }
1667 
1668     status = _nx_snmp_agent_set_interface(agent_ptr, if_index);
1669 
1670     return status;
1671 }
1672 
1673 
1674 /**************************************************************************/
1675 /*                                                                        */
1676 /*  FUNCTION                                               RELEASE        */
1677 /*                                                                        */
1678 /*    _nx_snmp_agent_set_interface                        PORTABLE C      */
1679 /*                                                           6.1          */
1680 /*  AUTHOR                                                                */
1681 /*                                                                        */
1682 /*    Yuxin Zhou, Microsoft Corporation                                   */
1683 /*                                                                        */
1684 /*  DESCRIPTION                                                           */
1685 /*                                                                        */
1686 /*    This function sets the SNMP network interface for the SNMP agent.   */
1687 /*                                                                        */
1688 /*  INPUT                                                                 */
1689 /*                                                                        */
1690 /*    agent_ptr                             Pointer to SNMP agent         */
1691 /*    if_index                              SNMP network interface index  */
1692 /*                                                                        */
1693 /*  OUTPUT                                                                */
1694 /*                                                                        */
1695 /*    status                                Completion status             */
1696 /*                                                                        */
1697 /*  CALLS                                                                 */
1698 /*                                                                        */
1699 /*    None                                                                */
1700 /*                                                                        */
1701 /*  CALLED BY                                                             */
1702 /*                                                                        */
1703 /*    Application Code                                                    */
1704 /*                                                                        */
1705 /*  RELEASE HISTORY                                                       */
1706 /*                                                                        */
1707 /*    DATE              NAME                      DESCRIPTION             */
1708 /*                                                                        */
1709 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1710 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1711 /*                                            resulting in version 6.1    */
1712 /*                                                                        */
1713 /**************************************************************************/
_nx_snmp_agent_set_interface(NX_SNMP_AGENT * agent_ptr,UINT if_index)1714 UINT _nx_snmp_agent_set_interface(NX_SNMP_AGENT *agent_ptr, UINT if_index)
1715 {
1716 
1717     agent_ptr -> nx_snmp_agent_interface_index = if_index;
1718 
1719     return NX_SUCCESS;
1720 }
1721 
1722 
1723 #ifndef NX_SNMP_DISABLE_V3
1724 /**************************************************************************/
1725 /*                                                                        */
1726 /*  FUNCTION                                               RELEASE        */
1727 /*                                                                        */
1728 /*    _nxe_snmp_agent_md5_key_create                      PORTABLE C      */
1729 /*                                                           6.1          */
1730 /*  AUTHOR                                                                */
1731 /*                                                                        */
1732 /*    Yuxin Zhou, Microsoft Corporation                                   */
1733 /*                                                                        */
1734 /*  DESCRIPTION                                                           */
1735 /*                                                                        */
1736 /*    This function checks for errors in the SNMP md5 key create          */
1737 /*    function call.                                                      */
1738 /*                                                                        */
1739 /*  INPUT                                                                 */
1740 /*                                                                        */
1741 /*    agent_ptr                             Pointer to SNMP agent         */
1742 /*    password                              Password for the MD5 key      */
1743 /*    destination_key                       Destination for the MD5 key   */
1744 /*                                                                        */
1745 /*  OUTPUT                                                                */
1746 /*                                                                        */
1747 /*    status                                Completion status             */
1748 /*                                                                        */
1749 /*  CALLS                                                                 */
1750 /*                                                                        */
1751 /*    _nx_snmp_agent_md5_key_create         Actual agent MD5 key create   */
1752 /*                                            function                    */
1753 /*                                                                        */
1754 /*  CALLED BY                                                             */
1755 /*                                                                        */
1756 /*    Application Code                                                    */
1757 /*                                                                        */
1758 /*  RELEASE HISTORY                                                       */
1759 /*                                                                        */
1760 /*    DATE              NAME                      DESCRIPTION             */
1761 /*                                                                        */
1762 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1763 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1764 /*                                            resulting in version 6.1    */
1765 /*                                                                        */
1766 /**************************************************************************/
_nxe_snmp_agent_md5_key_create(NX_SNMP_AGENT * agent_ptr,UCHAR * password,NX_SNMP_SECURITY_KEY * destination_key)1767 UINT  _nxe_snmp_agent_md5_key_create(NX_SNMP_AGENT *agent_ptr, UCHAR *password, NX_SNMP_SECURITY_KEY *destination_key)
1768 {
1769 
1770 UINT    status;
1771 
1772 
1773     /* Check for invalid input pointers.  */
1774     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) ||
1775         (password == NX_NULL) || (destination_key == NX_NULL))
1776         return(NX_PTR_ERROR);
1777 
1778     /* Call actual service.  */
1779     status =  _nx_snmp_agent_md5_key_create(agent_ptr, password, destination_key);
1780 
1781     /* Return status.  */
1782     return(status);
1783 }
1784 
1785 
1786 /**************************************************************************/
1787 /*                                                                        */
1788 /*  FUNCTION                                               RELEASE        */
1789 /*                                                                        */
1790 /*    _nx_snmp_agent_md5_key_create                       PORTABLE C      */
1791 /*                                                           6.1          */
1792 /*  AUTHOR                                                                */
1793 /*                                                                        */
1794 /*    Yuxin Zhou, Microsoft Corporation                                   */
1795 /*                                                                        */
1796 /*  DESCRIPTION                                                           */
1797 /*                                                                        */
1798 /*    This function creates an MD5 key.                                   */
1799 /*                                                                        */
1800 /*    Note: new API nx_snmp_agent_md5_key_create_extended is encouraged   */
1801 /*    to use.                                                             */
1802 /*                                                                        */
1803 /*  INPUT                                                                 */
1804 /*                                                                        */
1805 /*    agent_ptr                             Pointer to SNMP agent         */
1806 /*    password                              Password for the MD5 key      */
1807 /*    destination_key                       Destination for the MD5 key   */
1808 /*                                                                        */
1809 /*  OUTPUT                                                                */
1810 /*                                                                        */
1811 /*    status                                Completion status             */
1812 /*                                                                        */
1813 /*  CALLS                                                                 */
1814 /*                                                                        */
1815 /*    _nx_utility_string_length_check       Check string length           */
1816 /*    _nx_snmp_agent_md5_key_create_extended Agent MD5 key create function*/
1817 /*                                                                        */
1818 /*  CALLED BY                                                             */
1819 /*                                                                        */
1820 /*    Application Code                                                    */
1821 /*                                                                        */
1822 /*  RELEASE HISTORY                                                       */
1823 /*                                                                        */
1824 /*    DATE              NAME                      DESCRIPTION             */
1825 /*                                                                        */
1826 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1827 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1828 /*                                            resulting in version 6.1    */
1829 /*                                                                        */
1830 /**************************************************************************/
_nx_snmp_agent_md5_key_create(NX_SNMP_AGENT * agent_ptr,UCHAR * password,NX_SNMP_SECURITY_KEY * destination_key)1831 UINT  _nx_snmp_agent_md5_key_create(NX_SNMP_AGENT *agent_ptr, UCHAR *password, NX_SNMP_SECURITY_KEY *destination_key)
1832 {
1833 
1834 
1835 /* Verify SNMP security is not disabled for this project. */
1836 #ifdef NX_SNMP_NO_SECURITY
1837     /* Security is not supported, clear the key and return an error.  */
1838     destination_key -> nx_snmp_security_key_type =   0;
1839     destination_key ->  nx_snmp_security_key_size =  0;
1840 
1841     /* Return an error.  */
1842     return(NX_NOT_ENABLED);
1843 #else
1844 
1845 UINT        status;
1846 UINT        password_length;
1847 
1848 
1849     /* Calculate the password length.  */
1850     if (_nx_utility_string_length_check((CHAR *)password, &password_length, NX_MAX_STRING_LENGTH))
1851     {
1852         return(NX_SIZE_ERROR);
1853     }
1854 
1855     /* Check length of password. */
1856     if (password_length == 0)
1857     {
1858         return(NX_SNMP_FAILED);
1859     }
1860 
1861     /* Call actual service.  */
1862     status = _nx_snmp_agent_md5_key_create_extended(agent_ptr, password, password_length, destination_key);
1863 
1864     /* Return status to the caller.  */
1865     return(status);
1866 #endif
1867 }
1868 
1869 
1870 /**************************************************************************/
1871 /*                                                                        */
1872 /*  FUNCTION                                               RELEASE        */
1873 /*                                                                        */
1874 /*    _nxe_snmp_agent_md5_key_create_extended             PORTABLE C      */
1875 /*                                                           6.1          */
1876 /*  AUTHOR                                                                */
1877 /*                                                                        */
1878 /*    Yuxin Zhou, Microsoft Corporation                                   */
1879 /*                                                                        */
1880 /*  DESCRIPTION                                                           */
1881 /*                                                                        */
1882 /*    This function checks for errors in the SNMP md5 key create          */
1883 /*    function call.                                                      */
1884 /*                                                                        */
1885 /*  INPUT                                                                 */
1886 /*                                                                        */
1887 /*    agent_ptr                             Pointer to SNMP agent         */
1888 /*    password                              Password for the MD5 key      */
1889 /*    password_length                       Length of password            */
1890 /*    destination_key                       Destination for the MD5 key   */
1891 /*                                                                        */
1892 /*  OUTPUT                                                                */
1893 /*                                                                        */
1894 /*    status                                Completion status             */
1895 /*                                                                        */
1896 /*  CALLS                                                                 */
1897 /*                                                                        */
1898 /*    _nx_snmp_agent_md5_key_create_extended                              */
1899 /*                                          Actual agent MD5 key create   */
1900 /*                                            function                    */
1901 /*                                                                        */
1902 /*  CALLED BY                                                             */
1903 /*                                                                        */
1904 /*    Application Code                                                    */
1905 /*                                                                        */
1906 /*  RELEASE HISTORY                                                       */
1907 /*                                                                        */
1908 /*    DATE              NAME                      DESCRIPTION             */
1909 /*                                                                        */
1910 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1911 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1912 /*                                            resulting in version 6.1    */
1913 /*                                                                        */
1914 /**************************************************************************/
_nxe_snmp_agent_md5_key_create_extended(NX_SNMP_AGENT * agent_ptr,UCHAR * password,UINT password_length,NX_SNMP_SECURITY_KEY * destination_key)1915 UINT  _nxe_snmp_agent_md5_key_create_extended(NX_SNMP_AGENT *agent_ptr, UCHAR *password, UINT password_length, NX_SNMP_SECURITY_KEY *destination_key)
1916 {
1917 
1918 UINT    status;
1919 
1920 
1921     /* Check for invalid input pointers.  */
1922     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) ||
1923         (password == NX_NULL) || (password_length == 0) || (destination_key == NX_NULL))
1924         return(NX_PTR_ERROR);
1925 
1926     /* Call actual service.  */
1927     status =  _nx_snmp_agent_md5_key_create_extended(agent_ptr, password, password_length, destination_key);
1928 
1929     /* Return status.  */
1930     return(status);
1931 }
1932 
1933 
1934 /**************************************************************************/
1935 /*                                                                        */
1936 /*  FUNCTION                                               RELEASE        */
1937 /*                                                                        */
1938 /*    _nx_snmp_agent_md5_key_create_extended              PORTABLE C      */
1939 /*                                                           6.1          */
1940 /*  AUTHOR                                                                */
1941 /*                                                                        */
1942 /*    Yuxin Zhou, Microsoft Corporation                                   */
1943 /*                                                                        */
1944 /*  DESCRIPTION                                                           */
1945 /*                                                                        */
1946 /*    This function creates an MD5 key.                                   */
1947 /*                                                                        */
1948 /*    Note: The string of password must be NULL-terminated and length     */
1949 /*    of string matches the length specified in the argument list.        */
1950 /*                                                                        */
1951 /*  INPUT                                                                 */
1952 /*                                                                        */
1953 /*    agent_ptr                             Pointer to SNMP agent         */
1954 /*    password                              Password for the MD5 key      */
1955 /*    password_length                       Length of password            */
1956 /*    destination_key                       Destination for the MD5 key   */
1957 /*                                                                        */
1958 /*  OUTPUT                                                                */
1959 /*                                                                        */
1960 /*    status                                Completion status             */
1961 /*                                                                        */
1962 /*  CALLS                                                                 */
1963 /*                                                                        */
1964 /*    _nx_md5_initialize                    Initialize the MD5 algorithm  */
1965 /*    _nx_md5_update                        MD5 algorithm update          */
1966 /*    _nx_md5_digest_calculate              Calculate the MD5 key         */
1967 /*                                                                        */
1968 /*  CALLED BY                                                             */
1969 /*                                                                        */
1970 /*    Application Code                                                    */
1971 /*                                                                        */
1972 /*  RELEASE HISTORY                                                       */
1973 /*                                                                        */
1974 /*    DATE              NAME                      DESCRIPTION             */
1975 /*                                                                        */
1976 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1977 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
1978 /*                                            verified memcpy use cases,  */
1979 /*                                            resulting in version 6.1    */
1980 /*                                                                        */
1981 /**************************************************************************/
_nx_snmp_agent_md5_key_create_extended(NX_SNMP_AGENT * agent_ptr,UCHAR * password,UINT password_length,NX_SNMP_SECURITY_KEY * destination_key)1982 UINT  _nx_snmp_agent_md5_key_create_extended(NX_SNMP_AGENT *agent_ptr, UCHAR *password, UINT password_length, NX_SNMP_SECURITY_KEY *destination_key)
1983 {
1984 
1985 
1986 /* Verify SNMP security is not disabled for this project. */
1987 #ifdef NX_SNMP_NO_SECURITY
1988     /* Security is not supported, clear the key and return an error.  */
1989     destination_key -> nx_snmp_security_key_type =   0;
1990     destination_key ->  nx_snmp_security_key_size =  0;
1991 
1992     /* Return an error.  */
1993     return(NX_NOT_ENABLED);
1994 #else
1995 
1996 NX_MD5      MD;
1997 UCHAR      *cp, password_buf[64];
1998 ULONG       password_index = 0;
1999 ULONG       count = 0, i;
2000 UINT        temp_password_length;
2001 
2002 
2003     /* Get the length of password string.  */
2004     if (_nx_utility_string_length_check((CHAR *)password, &temp_password_length, password_length))
2005         return(NX_SNMP_FAILED);
2006 
2007     /* Check the password string length.  */
2008     if (password_length != temp_password_length)
2009         return(NX_SNMP_FAILED);
2010 
2011     /* Initialize MD5.  */
2012     _nx_md5_initialize(&MD);
2013 
2014     /* Use while loop until we've done 1 Megabyte. */
2015     while (count < 1048576)
2016     {
2017 
2018         cp = password_buf;
2019         for (i = 0; i < 64; i++)
2020         {
2021 
2022             /* Take the next octet of the password, wrapping
2023                to the beginning of the password as necessary.  */
2024             *cp++ = password[password_index++ % password_length];
2025          }
2026          _nx_md5_update(&MD, password_buf, 64);
2027          count += 64;
2028     }
2029     _nx_md5_digest_calculate(&MD, destination_key -> nx_snmp_security_key);          /* tell MD5 we're done */
2030 
2031     /* Now localize the key with the engineID and pass
2032        through MD5 to produce final key
2033        May want to ensure that engineLength <= 32,
2034        otherwise need to use a buffer larger than 64  */
2035     if(agent_ptr -> nx_snmp_agent_v3_context_engine_size > 32)
2036         return(NX_SNMP_FAILED);
2037 
2038     memcpy(password_buf, destination_key -> nx_snmp_security_key, 16); /* Use case of memcpy is verified. */
2039     memcpy(password_buf+16, agent_ptr -> nx_snmp_agent_v3_context_engine, agent_ptr -> nx_snmp_agent_v3_context_engine_size); /* Use case of memcpy is verified. */
2040     memcpy(password_buf+16+agent_ptr -> nx_snmp_agent_v3_context_engine_size, destination_key -> nx_snmp_security_key, 16); /* Use case of memcpy is verified. */
2041 
2042     _nx_md5_initialize(&MD);
2043     _nx_md5_update(&MD, password_buf, 32+agent_ptr -> nx_snmp_agent_v3_context_engine_size);
2044     _nx_md5_digest_calculate(&MD, destination_key -> nx_snmp_security_key);
2045 
2046     /* Setup other information in the key structure.  */
2047     destination_key -> nx_snmp_security_key_type =   NX_SNMP_MD5_KEY;
2048     destination_key ->  nx_snmp_security_key_size =  16;
2049 
2050     /* Return successful completion to the caller.  */
2051     return(NX_SUCCESS);
2052 #endif
2053 }
2054 
2055 
2056 /**************************************************************************/
2057 /*                                                                        */
2058 /*  FUNCTION                                               RELEASE        */
2059 /*                                                                        */
2060 /*    _nxe_snmp_agent_privacy_key_use                     PORTABLE C      */
2061 /*                                                           6.1          */
2062 /*  AUTHOR                                                                */
2063 /*                                                                        */
2064 /*    Yuxin Zhou, Microsoft Corporation                                   */
2065 /*                                                                        */
2066 /*  DESCRIPTION                                                           */
2067 /*                                                                        */
2068 /*    This function checks for errors in the SNMP privacy key             */
2069 /*    specification function call. To disable encryption, set the         */
2070 /*    key pointer to null.                                                */
2071 /*                                                                        */
2072 /*  INPUT                                                                 */
2073 /*                                                                        */
2074 /*    agent_ptr                             Pointer to SNMP agent         */
2075 /*    key                                   Pointer to key to use for     */
2076 /*                                            privacy (encryption)        */
2077 /*                                                                        */
2078 /*  OUTPUT                                                                */
2079 /*                                                                        */
2080 /*    status                                Completion status             */
2081 /*                                                                        */
2082 /*  CALLS                                                                 */
2083 /*                                                                        */
2084 /*    _nx_snmp_agent_privacy_key_use        Actual privacy key setup      */
2085 /*                                            function                    */
2086 /*                                                                        */
2087 /*  CALLED BY                                                             */
2088 /*                                                                        */
2089 /*    Application Code                                                    */
2090 /*                                                                        */
2091 /*  RELEASE HISTORY                                                       */
2092 /*                                                                        */
2093 /*    DATE              NAME                      DESCRIPTION             */
2094 /*                                                                        */
2095 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2096 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2097 /*                                            resulting in version 6.1    */
2098 /*                                                                        */
2099 /**************************************************************************/
_nxe_snmp_agent_privacy_key_use(NX_SNMP_AGENT * agent_ptr,NX_SNMP_SECURITY_KEY * key)2100 UINT  _nxe_snmp_agent_privacy_key_use(NX_SNMP_AGENT *agent_ptr, NX_SNMP_SECURITY_KEY *key)
2101 {
2102 
2103 UINT    status;
2104 
2105 
2106     /* Check for invalid input pointers.  */
2107     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID))
2108         return(NX_PTR_ERROR);
2109 
2110     if (key != NX_NULL)
2111     {
2112 
2113         /* Check for valid privacy key type. */
2114         if ((key -> nx_snmp_security_key_type != NX_SNMP_MD5_KEY) && (key -> nx_snmp_security_key_type != NX_SNMP_SHA_KEY))
2115         {
2116             return NX_SNMP_INVALID_PDU_ENCRYPTION;
2117         }
2118     }
2119 
2120     /* Call actual service.  */
2121     status =  _nx_snmp_agent_privacy_key_use(agent_ptr, key);
2122 
2123     /* Return status.  */
2124     return(status);
2125 }
2126 
2127 
2128 /**************************************************************************/
2129 /*                                                                        */
2130 /*  FUNCTION                                               RELEASE        */
2131 /*                                                                        */
2132 /*    _nx_snmp_agent_privacy_key_use                      PORTABLE C      */
2133 /*                                                           6.1          */
2134 /*  AUTHOR                                                                */
2135 /*                                                                        */
2136 /*    Yuxin Zhou, Microsoft Corporation                                   */
2137 /*                                                                        */
2138 /*  DESCRIPTION                                                           */
2139 /*                                                                        */
2140 /*    This function sets up the specified key to use for privacy. To      */
2141 /*    disable authentication, set the key pointer to null.                */
2142 /*                                                                        */
2143 /*                                                                        */
2144 /*  INPUT                                                                 */
2145 /*                                                                        */
2146 /*    agent_ptr                             Pointer to SNMP agent         */
2147 /*    key                                   Pointer to key to use for     */
2148 /*                                            privacy (encryption)        */
2149 /*                                                                        */
2150 /*  OUTPUT                                                                */
2151 /*                                                                        */
2152 /*    status                                Completion status             */
2153 /*                                                                        */
2154 /*  CALLS                                                                 */
2155 /*                                                                        */
2156 /*    None                                                                */
2157 /*                                                                        */
2158 /*  CALLED BY                                                             */
2159 /*                                                                        */
2160 /*    Application Code                                                    */
2161 /*                                                                        */
2162 /*  RELEASE HISTORY                                                       */
2163 /*                                                                        */
2164 /*    DATE              NAME                      DESCRIPTION             */
2165 /*                                                                        */
2166 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2167 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2168 /*                                            resulting in version 6.1    */
2169 /*                                                                        */
2170 /**************************************************************************/
_nx_snmp_agent_privacy_key_use(NX_SNMP_AGENT * agent_ptr,NX_SNMP_SECURITY_KEY * key)2171 UINT  _nx_snmp_agent_privacy_key_use(NX_SNMP_AGENT *agent_ptr, NX_SNMP_SECURITY_KEY *key)
2172 {
2173 
2174 #ifdef NX_SNMP_NO_SECURITY
2175     return NX_NOT_ENABLED;
2176 #else
2177 
2178 
2179     /* Set the privacy pointer so encryption/decryption will use the specified key.  Note this
2180        key must have been created prior to calling this routine.  */
2181     agent_ptr -> nx_snmp_agent_v3_privacy_key =  key;
2182 
2183     /* Return success to the caller.  */
2184     return(NX_SUCCESS);
2185 #endif
2186 }
2187 
2188 
2189 /**************************************************************************/
2190 /*                                                                        */
2191 /*  FUNCTION                                               RELEASE        */
2192 /*                                                                        */
2193 /*    _nxe_snmp_agent_priv_trap_key_use                   PORTABLE C      */
2194 /*                                                           6.1          */
2195 /*  AUTHOR                                                                */
2196 /*                                                                        */
2197 /*    Yuxin Zhou, Microsoft Corporation                                   */
2198 /*                                                                        */
2199 /*  DESCRIPTION                                                           */
2200 /*                                                                        */
2201 /*    This function performs error checking for setting the privacy key   */
2202 /*    for SNMPv3 trap messages.  To disable trap key encryption, set       */
2203 /*    the key pointer to null.                                            */
2204 /*                                                                        */
2205 /*  INPUT                                                                 */
2206 /*                                                                        */
2207 /*    agent_ptr                             Pointer to SNMP agent         */
2208 /*    key                                   Pointer to key to use for     */
2209 /*                                            privacy (encryption)        */
2210 /*                                                                        */
2211 /*  OUTPUT                                                                */
2212 /*                                                                        */
2213 /*    status                                Completion status             */
2214 /*                                                                        */
2215 /*  CALLS                                                                 */
2216 /*                                                                        */
2217 /*    _nx_snmp_agent_priv_trap_key_use      Actual set privacy key for    */
2218 /*                                           SNMPv3 trap messages service */
2219 /*                                                                        */
2220 /*  CALLED BY                                                             */
2221 /*                                                                        */
2222 /*    Application Code                                                    */
2223 /*                                                                        */
2224 /*  RELEASE HISTORY                                                       */
2225 /*                                                                        */
2226 /*    DATE              NAME                      DESCRIPTION             */
2227 /*                                                                        */
2228 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2229 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2230 /*                                            resulting in version 6.1    */
2231 /*                                                                        */
2232 /**************************************************************************/
_nxe_snmp_agent_priv_trap_key_use(NX_SNMP_AGENT * agent_ptr,NX_SNMP_SECURITY_KEY * key)2233 UINT  _nxe_snmp_agent_priv_trap_key_use(NX_SNMP_AGENT *agent_ptr, NX_SNMP_SECURITY_KEY *key)
2234 {
2235 
2236 UINT    status;
2237 
2238 
2239     /* Check for invalid input pointers.  */
2240     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID))
2241     {
2242         return(NX_PTR_ERROR);
2243     }
2244 
2245     if (key != NX_NULL)
2246     {
2247 
2248         /* Check for valid privacy key type. */
2249         if ((key -> nx_snmp_security_key_type != NX_SNMP_MD5_KEY) && (key -> nx_snmp_security_key_type != NX_SNMP_SHA_KEY))
2250         {
2251             return(NX_SNMP_INVALID_PDU_ENCRYPTION);
2252         }
2253     }
2254 
2255     /* Call actual service.  */
2256     status =  _nx_snmp_agent_priv_trap_key_use(agent_ptr, key);
2257 
2258     /* Return status.  */
2259     return(status);
2260 }
2261 
2262 
2263 /**************************************************************************/
2264 /*                                                                        */
2265 /*  FUNCTION                                               RELEASE        */
2266 /*                                                                        */
2267 /*    _nx_snmp_agent_priv_trap_key_use                    PORTABLE C      */
2268 /*                                                           6.1          */
2269 /*  AUTHOR                                                                */
2270 /*                                                                        */
2271 /*    Yuxin Zhou, Microsoft Corporation                                   */
2272 /*                                                                        */
2273 /*  DESCRIPTION                                                           */
2274 /*                                                                        */
2275 /*    This function sets up the specified key to use for privacy for      */
2276 /*    sending SNMPv3 trap messages.                                       */
2277 /*                                                                        */
2278 /*  INPUT                                                                 */
2279 /*                                                                        */
2280 /*    agent_ptr                             Pointer to SNMP agent         */
2281 /*    key                                   Pointer to key to use for     */
2282 /*                                            privacy (encryption)        */
2283 /*                                                                        */
2284 /*  OUTPUT                                                                */
2285 /*                                                                        */
2286 /*    status                                Completion status             */
2287 /*                                                                        */
2288 /*  CALLS                                                                 */
2289 /*                                                                        */
2290 /*    None                                                                */
2291 /*                                                                        */
2292 /*  CALLED BY                                                             */
2293 /*                                                                        */
2294 /*    Application Code                                                    */
2295 /*                                                                        */
2296 /*  RELEASE HISTORY                                                       */
2297 /*                                                                        */
2298 /*    DATE              NAME                      DESCRIPTION             */
2299 /*                                                                        */
2300 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2301 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2302 /*                                            resulting in version 6.1    */
2303 /*                                                                        */
2304 /**************************************************************************/
_nx_snmp_agent_priv_trap_key_use(NX_SNMP_AGENT * agent_ptr,NX_SNMP_SECURITY_KEY * key)2305 UINT  _nx_snmp_agent_priv_trap_key_use(NX_SNMP_AGENT *agent_ptr, NX_SNMP_SECURITY_KEY *key)
2306 {
2307 
2308 #ifdef NX_SNMP_NO_SECURITY
2309     return NX_NOT_ENABLED;
2310 #else
2311 
2312     /* Set the privacy pointer so encryption/decryption will use the specified key.  Note this
2313        key must have been created prior to calling this routine.  */
2314     agent_ptr -> nx_snmp_agent_v3_priv_trap_key =  key;
2315 
2316     /* Return success to the caller.  */
2317     return(NX_SUCCESS);
2318 #endif
2319 }
2320 
2321 
2322 /**************************************************************************/
2323 /*                                                                        */
2324 /*  FUNCTION                                               RELEASE        */
2325 /*                                                                        */
2326 /*    _nxe_snmp_agent_sha_key_create                      PORTABLE C      */
2327 /*                                                           6.1          */
2328 /*  AUTHOR                                                                */
2329 /*                                                                        */
2330 /*    Yuxin Zhou, Microsoft Corporation                                   */
2331 /*                                                                        */
2332 /*  DESCRIPTION                                                           */
2333 /*                                                                        */
2334 /*    This function checks for errors in the SNMP SHA key create          */
2335 /*    function call.                                                      */
2336 /*                                                                        */
2337 /*  INPUT                                                                 */
2338 /*                                                                        */
2339 /*    agent_ptr                             Pointer to SNMP agent         */
2340 /*    password                              Password for the SHA key      */
2341 /*    destination_key                       Destination for the SHA key   */
2342 /*                                                                        */
2343 /*  OUTPUT                                                                */
2344 /*                                                                        */
2345 /*    status                                Completion status             */
2346 /*                                                                        */
2347 /*  CALLS                                                                 */
2348 /*                                                                        */
2349 /*    _nx_snmp_agent_sha_key_create         Actual agent SHA key create   */
2350 /*                                            function                    */
2351 /*                                                                        */
2352 /*  CALLED BY                                                             */
2353 /*                                                                        */
2354 /*    Application Code                                                    */
2355 /*                                                                        */
2356 /*  RELEASE HISTORY                                                       */
2357 /*                                                                        */
2358 /*    DATE              NAME                      DESCRIPTION             */
2359 /*                                                                        */
2360 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2361 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2362 /*                                            resulting in version 6.1    */
2363 /*                                                                        */
2364 /**************************************************************************/
_nxe_snmp_agent_sha_key_create(NX_SNMP_AGENT * agent_ptr,UCHAR * password,NX_SNMP_SECURITY_KEY * destination_key)2365 UINT  _nxe_snmp_agent_sha_key_create(NX_SNMP_AGENT *agent_ptr, UCHAR *password, NX_SNMP_SECURITY_KEY *destination_key)
2366 {
2367 
2368 UINT    status;
2369 
2370 
2371     /* Check for invalid input pointers.  */
2372     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) ||
2373         (password == NX_NULL) || (destination_key == NX_NULL))
2374         return(NX_PTR_ERROR);
2375 
2376     /* Call actual service.  */
2377     status =  _nx_snmp_agent_sha_key_create(agent_ptr, password, destination_key);
2378 
2379     /* Return status.  */
2380     return(status);
2381 }
2382 
2383 
2384 /**************************************************************************/
2385 /*                                                                        */
2386 /*  FUNCTION                                               RELEASE        */
2387 /*                                                                        */
2388 /*    _nx_snmp_agent_sha_key_create                       PORTABLE C      */
2389 /*                                                           6.1          */
2390 /*  AUTHOR                                                                */
2391 /*                                                                        */
2392 /*    Yuxin Zhou, Microsoft Corporation                                   */
2393 /*                                                                        */
2394 /*  DESCRIPTION                                                           */
2395 /*                                                                        */
2396 /*    This function creates an SHA key.                                   */
2397 /*                                                                        */
2398 /*    Note: new API nx_snmp_agent_sha_key_create_extended is encouraged   */
2399 /*    to use.                                                             */
2400 /*                                                                        */
2401 /*  INPUT                                                                 */
2402 /*                                                                        */
2403 /*    agent_ptr                             Pointer to SNMP agent         */
2404 /*    password                              Password for the SHA key      */
2405 /*    destination_key                       Destination for the SHA key   */
2406 /*                                                                        */
2407 /*  OUTPUT                                                                */
2408 /*                                                                        */
2409 /*    status                                Completion status             */
2410 /*                                                                        */
2411 /*  CALLS                                                                 */
2412 /*                                                                        */
2413 /*    _nx_utility_string_length_check       Check string length           */
2414 /*    _nx_snmp_agent_sha_key_create_extended Actual agent SHA key create  */
2415 /*                                            function                    */
2416 /*                                                                        */
2417 /*  CALLED BY                                                             */
2418 /*                                                                        */
2419 /*    Application Code                                                    */
2420 /*                                                                        */
2421 /*  RELEASE HISTORY                                                       */
2422 /*                                                                        */
2423 /*    DATE              NAME                      DESCRIPTION             */
2424 /*                                                                        */
2425 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2426 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2427 /*                                            resulting in version 6.1    */
2428 /*                                                                        */
2429 /**************************************************************************/
_nx_snmp_agent_sha_key_create(NX_SNMP_AGENT * agent_ptr,UCHAR * password,NX_SNMP_SECURITY_KEY * destination_key)2430 UINT  _nx_snmp_agent_sha_key_create(NX_SNMP_AGENT *agent_ptr, UCHAR *password, NX_SNMP_SECURITY_KEY *destination_key)
2431 {
2432 
2433 /* Verify SNMP security is not disabled for this project. */
2434 #ifdef NX_SNMP_NO_SECURITY
2435 
2436     /* Security is not supported, clear the key and return an error.  */
2437     destination_key -> nx_snmp_security_key_type =   0;
2438     destination_key ->  nx_snmp_security_key_size =  0;
2439 
2440     /* Return an error.  */
2441     return(NX_NOT_ENABLED);
2442 #else
2443 
2444 UINT        status;
2445 UINT        password_length;
2446 
2447 
2448     /* Calculate the password length.  */
2449     if (_nx_utility_string_length_check((CHAR *)password, &password_length, NX_MAX_STRING_LENGTH))
2450     {
2451         return(NX_SIZE_ERROR);
2452     }
2453 
2454     /* Check length of password. */
2455     if (password_length == 0)
2456     {
2457         return(NX_SNMP_FAILED);
2458     }
2459 
2460     /* Call actual service.  */
2461     status = _nx_snmp_agent_sha_key_create_extended(agent_ptr, password, password_length, destination_key);
2462 
2463     /* Return status.  */
2464     return(status);
2465 #endif  /* NX_SNMP_NO_SECURITY */
2466 
2467 }
2468 
2469 
2470 /**************************************************************************/
2471 /*                                                                        */
2472 /*  FUNCTION                                               RELEASE        */
2473 /*                                                                        */
2474 /*    _nxe_snmp_agent_sha_key_create_extended             PORTABLE C      */
2475 /*                                                           6.1          */
2476 /*  AUTHOR                                                                */
2477 /*                                                                        */
2478 /*    Yuxin Zhou, Microsoft Corporation                                   */
2479 /*                                                                        */
2480 /*  DESCRIPTION                                                           */
2481 /*                                                                        */
2482 /*    This function checks for errors in the SNMP SHA key create          */
2483 /*    function call.                                                      */
2484 /*                                                                        */
2485 /*  INPUT                                                                 */
2486 /*                                                                        */
2487 /*    agent_ptr                             Pointer to SNMP agent         */
2488 /*    password                              Password for the SHA key      */
2489 /*    password_length                       Length of password            */
2490 /*    destination_key                       Destination for the SHA key   */
2491 /*                                                                        */
2492 /*  OUTPUT                                                                */
2493 /*                                                                        */
2494 /*    status                                Completion status             */
2495 /*                                                                        */
2496 /*  CALLS                                                                 */
2497 /*                                                                        */
2498 /*    _nx_snmp_agent_sha_key_create_extended Actual agent SHA key create  */
2499 /*                                            function                    */
2500 /*                                                                        */
2501 /*  CALLED BY                                                             */
2502 /*                                                                        */
2503 /*    Application Code                                                    */
2504 /*                                                                        */
2505 /*  RELEASE HISTORY                                                       */
2506 /*                                                                        */
2507 /*    DATE              NAME                      DESCRIPTION             */
2508 /*                                                                        */
2509 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2510 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2511 /*                                            resulting in version 6.1    */
2512 /*                                                                        */
2513 /**************************************************************************/
_nxe_snmp_agent_sha_key_create_extended(NX_SNMP_AGENT * agent_ptr,UCHAR * password,UINT password_length,NX_SNMP_SECURITY_KEY * destination_key)2514 UINT  _nxe_snmp_agent_sha_key_create_extended(NX_SNMP_AGENT *agent_ptr, UCHAR *password, UINT password_length, NX_SNMP_SECURITY_KEY *destination_key)
2515 {
2516 
2517 UINT    status;
2518 
2519 
2520     /* Check for invalid input pointers.  */
2521     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) ||
2522         (password == NX_NULL) || (password_length == 0) || (destination_key == NX_NULL))
2523         return(NX_PTR_ERROR);
2524 
2525     /* Call actual service.  */
2526     status =  _nx_snmp_agent_sha_key_create_extended(agent_ptr, password, password_length, destination_key);
2527 
2528     /* Return status.  */
2529     return(status);
2530 }
2531 
2532 
2533 /**************************************************************************/
2534 /*                                                                        */
2535 /*  FUNCTION                                               RELEASE        */
2536 /*                                                                        */
2537 /*    _nx_snmp_agent_sha_key_create_extended              PORTABLE C      */
2538 /*                                                           6.1          */
2539 /*  AUTHOR                                                                */
2540 /*                                                                        */
2541 /*    Yuxin Zhou, Microsoft Corporation                                   */
2542 /*                                                                        */
2543 /*  DESCRIPTION                                                           */
2544 /*                                                                        */
2545 /*    This function creates an SHA key.                                   */
2546 /*                                                                        */
2547 /*    Note: The string of password must be NULL-terminated and length     */
2548 /*    of string matches the length specified in the argument list.        */
2549 /*                                                                        */
2550 /*  INPUT                                                                 */
2551 /*                                                                        */
2552 /*    agent_ptr                             Pointer to SNMP agent         */
2553 /*    password                              Password for the SHA key      */
2554 /*    password_length                       Length of password            */
2555 /*    destination_key                       Destination for the SHA key   */
2556 /*                                                                        */
2557 /*  OUTPUT                                                                */
2558 /*                                                                        */
2559 /*    status                                Completion status             */
2560 /*                                                                        */
2561 /*  CALLS                                                                 */
2562 /*                                                                        */
2563 /*    _nx_sha1_initialize                   Initialize the SHA algorithm  */
2564 /*    _nx_sha1_update                       SHA algorithm update          */
2565 /*    _nx_sha1_digest_calculate             Calculate the SHA key         */
2566 /*                                                                        */
2567 /*  CALLED BY                                                             */
2568 /*                                                                        */
2569 /*    Application Code                                                    */
2570 /*                                                                        */
2571 /*  RELEASE HISTORY                                                       */
2572 /*                                                                        */
2573 /*    DATE              NAME                      DESCRIPTION             */
2574 /*                                                                        */
2575 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2576 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
2577 /*                                            verified memcpy use cases,  */
2578 /*                                            resulting in version 6.1    */
2579 /*                                                                        */
2580 /**************************************************************************/
_nx_snmp_agent_sha_key_create_extended(NX_SNMP_AGENT * agent_ptr,UCHAR * password,UINT password_length,NX_SNMP_SECURITY_KEY * destination_key)2581 UINT  _nx_snmp_agent_sha_key_create_extended(NX_SNMP_AGENT *agent_ptr, UCHAR *password, UINT password_length, NX_SNMP_SECURITY_KEY *destination_key)
2582 {
2583 
2584 /* Verify SNMP security is not disabled for this project. */
2585 #ifdef NX_SNMP_NO_SECURITY
2586 
2587     /* Security is not supported, clear the key and return an error.  */
2588     destination_key -> nx_snmp_security_key_type =   0;
2589     destination_key ->  nx_snmp_security_key_size =  0;
2590 
2591     /* Return an error.  */
2592     return(NX_NOT_ENABLED);
2593 #else
2594 
2595 NX_SHA1     SH;
2596 UCHAR      *cp, password_buf[72];
2597 ULONG       password_index = 0;
2598 ULONG       count = 0, i;
2599 UINT        temp_password_length;
2600 
2601 
2602     /* Get the length of password string.  */
2603     if (_nx_utility_string_length_check((CHAR *)password, &temp_password_length, password_length))
2604         return(NX_SNMP_FAILED);
2605 
2606     /* Check the password string length.  */
2607     if (password_length != temp_password_length)
2608         return(NX_SNMP_FAILED);
2609 
2610     memset(&SH, 0, sizeof(NX_SHA1));
2611     memset(&password_buf[0], 0, 72);
2612     memset(destination_key, 0, sizeof(NX_SNMP_SECURITY_KEY));
2613 
2614     /* Initialize SHA.  */
2615     _nx_sha1_initialize(&SH);
2616 
2617     /* Use while loop until we've done 1 Megabyte.  */
2618     while (count < 1048576)
2619     {
2620 
2621         cp = password_buf;
2622         for (i = 0; i < 64; i++)
2623         {
2624 
2625             /* Take the next octet of the password, wrapping
2626                to the beginning of the password as necessary.  */
2627              *cp++ = password[password_index++ % password_length];
2628          }
2629          _nx_sha1_update(&SH, password_buf, 64);
2630          count += 64;
2631     }
2632     _nx_sha1_digest_calculate(&SH, destination_key -> nx_snmp_security_key);          /* tell SHA we're done */
2633 
2634     /* Now localize the key with the engineID and pass
2635        through SHA to produce final key
2636        May want to ensure that engineLength <= 32,
2637        otherwise need to use a buffer larger than 72.  */
2638     if(agent_ptr -> nx_snmp_agent_v3_context_engine_size > 32)
2639         return(NX_SNMP_FAILED);
2640 
2641     memcpy(password_buf, destination_key -> nx_snmp_security_key, 20); /* Use case of memcpy is verified. */
2642     memcpy(password_buf+20, agent_ptr -> nx_snmp_agent_v3_context_engine, agent_ptr -> nx_snmp_agent_v3_context_engine_size); /* Use case of memcpy is verified. */
2643     memcpy(password_buf+20+agent_ptr -> nx_snmp_agent_v3_context_engine_size, destination_key -> nx_snmp_security_key, 20); /* Use case of memcpy is verified. */
2644 
2645     _nx_sha1_initialize(&SH);
2646     _nx_sha1_update(&SH, password_buf, 40+agent_ptr -> nx_snmp_agent_v3_context_engine_size);
2647     _nx_sha1_digest_calculate(&SH, destination_key -> nx_snmp_security_key);
2648 
2649     /* Setup other information in the key structure.  */
2650     destination_key -> nx_snmp_security_key_type =   NX_SNMP_SHA_KEY;
2651     destination_key ->  nx_snmp_security_key_size =  20;
2652 
2653     /* Return successful completion to the caller.  */
2654     return(NX_SUCCESS);
2655 #endif  /* NX_SNMP_NO_SECURITY */
2656 
2657 }
2658 #endif /* NX_SNMP_DISABLE_V3 */
2659 
2660 
2661 /**************************************************************************/
2662 /*                                                                        */
2663 /*  FUNCTION                                               RELEASE        */
2664 /*                                                                        */
2665 /*    _nxe_snmp_agent_public_string_test                  PORTABLE C      */
2666 /*                                                           6.1          */
2667 /*  AUTHOR                                                                */
2668 /*                                                                        */
2669 /*    Yuxin Zhou, Microsoft Corporation                                   */
2670 /*                                                                        */
2671 /*  DESCRIPTION                                                           */
2672 /*                                                                        */
2673 /*    This function performs error checking for the check of community    */
2674 /*    string against the agent's public community string.                 */
2675 /*                                                                        */
2676 /*  INPUT                                                                 */
2677 /*                                                                        */
2678 /*    agent_ptr                             Pointer to SNMP agent         */
2679 /*    community_string                      Pointer to public string      */
2680 /*    is_public                             Pointer to outcome            */
2681 /*                                                                        */
2682 /*  OUTPUT                                                                */
2683 /*                                                                        */
2684 /*    NX_SUCCESS                            Successful completion status  */
2685 /*                                                                        */
2686 /*  CALLS                                                                 */
2687 /*                                                                        */
2688 /*    _nx_snmp_agents_public_string_test    Check public string service   */
2689 /*                                                                        */
2690 /*  CALLED BY                                                             */
2691 /*                                                                        */
2692 /*    Application Code                                                    */
2693 /*                                                                        */
2694 /*  RELEASE HISTORY                                                       */
2695 /*                                                                        */
2696 /*    DATE              NAME                      DESCRIPTION             */
2697 /*                                                                        */
2698 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2699 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2700 /*                                            resulting in version 6.1    */
2701 /*                                                                        */
2702 /**************************************************************************/
_nxe_snmp_agent_public_string_test(NX_SNMP_AGENT * agent_ptr,UCHAR * community_string,UINT * is_public)2703 UINT _nxe_snmp_agent_public_string_test(NX_SNMP_AGENT *agent_ptr, UCHAR *community_string, UINT *is_public)
2704 {
2705 
2706 UINT status;
2707 
2708     if ((agent_ptr == NX_NULL) || (community_string == NX_NULL) || (is_public == NX_NULL))
2709     {
2710         return NX_PTR_ERROR;
2711     }
2712 
2713     status = _nx_snmp_agent_public_string_test(agent_ptr, community_string, is_public);
2714 
2715     return status;
2716 }
2717 
2718 
2719 /**************************************************************************/
2720 /*                                                                        */
2721 /*  FUNCTION                                               RELEASE        */
2722 /*                                                                        */
2723 /*    _nx_snmp_agent_public_string_test                   PORTABLE C      */
2724 /*                                                           6.1          */
2725 /*  AUTHOR                                                                */
2726 /*                                                                        */
2727 /*    Yuxin Zhou, Microsoft Corporation                                   */
2728 /*                                                                        */
2729 /*  DESCRIPTION                                                           */
2730 /*                                                                        */
2731 /*    This function performs checks the input community string against the*/
2732 /*    agent's public community string.                                    */
2733 /*                                                                        */
2734 /*    Note: The string length of community_string is limited by           */
2735 /*    NX_SNMP_MAX_USER_NAME.                                              */
2736 /*                                                                        */
2737 /*  INPUT                                                                 */
2738 /*                                                                        */
2739 /*    agent_ptr                             Pointer to SNMP agent         */
2740 /*    community_string                      Pointer to public string      */
2741 /*    is_public                             Pointer to outcome            */
2742 /*                                                                        */
2743 /*  OUTPUT                                                                */
2744 /*                                                                        */
2745 /*    NX_SUCCESS                            Successful completion status  */
2746 /*                                                                        */
2747 /*  CALLS                                                                 */
2748 /*                                                                        */
2749 /*    None                                                                */
2750 /*                                                                        */
2751 /*  CALLED BY                                                             */
2752 /*                                                                        */
2753 /*    Application Code                                                    */
2754 /*                                                                        */
2755 /*  RELEASE HISTORY                                                       */
2756 /*                                                                        */
2757 /*    DATE              NAME                      DESCRIPTION             */
2758 /*                                                                        */
2759 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2760 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2761 /*                                            resulting in version 6.1    */
2762 /*                                                                        */
2763 /**************************************************************************/
_nx_snmp_agent_public_string_test(NX_SNMP_AGENT * agent_ptr,UCHAR * community_string,UINT * is_public)2764 UINT _nx_snmp_agent_public_string_test(NX_SNMP_AGENT *agent_ptr, UCHAR *community_string, UINT *is_public)
2765 {
2766 UINT string_length1, string_length2;
2767 
2768 
2769     if (_nx_utility_string_length_check((CHAR *)community_string, &string_length1, NX_SNMP_MAX_USER_NAME))
2770     {
2771         return(NX_SIZE_ERROR);
2772     }
2773 
2774     if (_nx_utility_string_length_check((CHAR *)agent_ptr -> nx_snmp_agent_public_community_string, &string_length2, NX_SNMP_MAX_USER_NAME))
2775     {
2776         return(NX_SIZE_ERROR);
2777     }
2778 
2779     /* Initialize the outcome */
2780     *is_public = NX_TRUE;
2781 
2782     if (string_length1 != string_length2)
2783     {
2784         /* Input string not the same as agent's public string. */
2785         *is_public = NX_FALSE;
2786         return(NX_SUCCESS);
2787     }
2788 
2789     /* The string lengths match, now match the actual strings. */
2790     if (memcmp(community_string, agent_ptr -> nx_snmp_agent_public_community_string, string_length1))
2791     {
2792 
2793         /* Input string not the same as agent's public string. */
2794         *is_public = NX_FALSE;
2795     }
2796 
2797     return NX_SUCCESS;
2798 }
2799 
2800 
2801 /**************************************************************************/
2802 /*                                                                        */
2803 /*  FUNCTION                                               RELEASE        */
2804 /*                                                                        */
2805 /*    _nxe_snmp_agent_private_string_test                 PORTABLE C      */
2806 /*                                                           6.1          */
2807 /*  AUTHOR                                                                */
2808 /*                                                                        */
2809 /*    Yuxin Zhou, Microsoft Corporation                                   */
2810 /*                                                                        */
2811 /*  DESCRIPTION                                                           */
2812 /*                                                                        */
2813 /*    This function performs error checking for the nx_snmp_agent_receive_*/
2814 /*    _private_string service.                                            */
2815 /*                                                                        */
2816 /*  INPUT                                                                 */
2817 /*                                                                        */
2818 /*    agent_ptr                             Pointer to SNMP agent         */
2819 /*    community_string                      Pointer to received string    */
2820 /*    is_private                            Pointer to outcome            */
2821 /*                                             NX_TRUE if strings match   */
2822 /*                                             NX_FALSE if strings do not */
2823 /*                                                                        */
2824 /*  OUTPUT                                                                */
2825 /*                                                                        */
2826 /*    NX_SUCCESS                            Successful completion status  */
2827 /*                                                                        */
2828 /*  CALLS                                                                 */
2829 /*                                                                        */
2830 /*    _nx_snmp_agent_private_string_test                                  */
2831 /*                                                                        */
2832 /*  CALLED BY                                                             */
2833 /*                                                                        */
2834 /*    Application Code                                                    */
2835 /*                                                                        */
2836 /*  RELEASE HISTORY                                                       */
2837 /*                                                                        */
2838 /*    DATE              NAME                      DESCRIPTION             */
2839 /*                                                                        */
2840 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2841 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2842 /*                                            resulting in version 6.1    */
2843 /*                                                                        */
2844 /**************************************************************************/
_nxe_snmp_agent_private_string_test(NX_SNMP_AGENT * agent_ptr,UCHAR * community_string,UINT * is_private)2845 UINT _nxe_snmp_agent_private_string_test(NX_SNMP_AGENT *agent_ptr, UCHAR *community_string, UINT *is_private)
2846 {
2847 
2848 UINT status;
2849 
2850     if ((agent_ptr == NX_NULL) || (community_string == NX_NULL) || (is_private == NX_NULL))
2851     {
2852         return NX_PTR_ERROR;
2853     }
2854 
2855     status = _nx_snmp_agent_private_string_test(agent_ptr, community_string, is_private);
2856 
2857     return status;
2858 }
2859 
2860 
2861 /**************************************************************************/
2862 /*                                                                        */
2863 /*  FUNCTION                                               RELEASE        */
2864 /*                                                                        */
2865 /*    _nx_snmp_agent_private_string_test                  PORTABLE C      */
2866 /*                                                           6.1          */
2867 /*  AUTHOR                                                                */
2868 /*                                                                        */
2869 /*    Yuxin Zhou, Microsoft Corporation                                   */
2870 /*                                                                        */
2871 /*  DESCRIPTION                                                           */
2872 /*                                                                        */
2873 /*    This function determines if the community string of the received    */
2874 /*    SNMP packet matches the SNMP agent's private community string.      */
2875 /*                                                                        */
2876 /*    Note: The string length of community_string is limited by           */
2877 /*    NX_SNMP_MAX_USER_NAME.                                              */
2878 /*                                                                        */
2879 /*  INPUT                                                                 */
2880 /*                                                                        */
2881 /*    agent_ptr                             Pointer to SNMP agent         */
2882 /*    community_string                      Pointer to received string    */
2883 /*    is_private                            Pointer to outcome            */
2884 /*                                             NX_TRUE if strings match   */
2885 /*                                             NX_FALSE if strings do not */
2886 /*                                                                        */
2887 /*  OUTPUT                                                                */
2888 /*                                                                        */
2889 /*    NX_SUCCESS                            Successful completion status  */
2890 /*                                                                        */
2891 /*  CALLS                                                                 */
2892 /*                                                                        */
2893 /*    None                                                                */
2894 /*                                                                        */
2895 /*  CALLED BY                                                             */
2896 /*                                                                        */
2897 /*    Application Code                                                    */
2898 /*                                                                        */
2899 /*  RELEASE HISTORY                                                       */
2900 /*                                                                        */
2901 /*    DATE              NAME                      DESCRIPTION             */
2902 /*                                                                        */
2903 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2904 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2905 /*                                            resulting in version 6.1    */
2906 /*                                                                        */
2907 /**************************************************************************/
_nx_snmp_agent_private_string_test(NX_SNMP_AGENT * agent_ptr,UCHAR * community_string,UINT * is_private)2908 UINT _nx_snmp_agent_private_string_test(NX_SNMP_AGENT *agent_ptr, UCHAR *community_string, UINT *is_private)
2909 {
2910 UINT string_length1, string_length2;
2911 
2912     if (_nx_utility_string_length_check((CHAR *)community_string, &string_length1, NX_SNMP_MAX_USER_NAME))
2913     {
2914         return(NX_SIZE_ERROR);
2915     }
2916 
2917     if (_nx_utility_string_length_check((CHAR *)agent_ptr -> nx_snmp_agent_private_community_string, &string_length2, NX_SNMP_MAX_USER_NAME))
2918     {
2919         return(NX_SIZE_ERROR);
2920     }
2921 
2922     /* Initialize the outcome */
2923     *is_private = NX_TRUE;
2924 
2925     if (string_length1 != string_length2)
2926     {
2927         /* Input string not the same as agent's private string. */
2928         *is_private = NX_FALSE;
2929         return(NX_SUCCESS);
2930     }
2931 
2932     /* The string lengths match, now match the actual strings. */
2933     if (memcmp(community_string, agent_ptr -> nx_snmp_agent_private_community_string, string_length1))
2934     {
2935 
2936         /* Input string not the same as agent's private string. */
2937         *is_private = NX_FALSE;
2938     }
2939 
2940     return NX_SUCCESS;
2941 }
2942 
2943 
2944 /**************************************************************************/
2945 /*                                                                        */
2946 /*  FUNCTION                                               RELEASE        */
2947 /*                                                                        */
2948 /*    _nxe_snmp_agent_private_string_set                  PORTABLE C      */
2949 /*                                                           6.1          */
2950 /*  AUTHOR                                                                */
2951 /*                                                                        */
2952 /*    Yuxin Zhou, Microsoft Corporation                                   */
2953 /*                                                                        */
2954 /*  DESCRIPTION                                                           */
2955 /*                                                                        */
2956 /*    This function performs error checking for the nx_snmp_agent_set_    */
2957 /*    _private_string service.                                            */
2958 /*                                                                        */
2959 /*  INPUT                                                                 */
2960 /*                                                                        */
2961 /*    agent_ptr                             Pointer to SNMP agent         */
2962 /*    community_string                      Pointer to private string     */
2963 /*                                                                        */
2964 /*  OUTPUT                                                                */
2965 /*                                                                        */
2966 /*    NX_SUCCESS                            Successful completion status  */
2967 /*                                                                        */
2968 /*  CALLS                                                                 */
2969 /*                                                                        */
2970 /*    _nx_snmp_agent_private_string_set     Set private string service    */
2971 /*                                                                        */
2972 /*  CALLED BY                                                             */
2973 /*                                                                        */
2974 /*    Application Code                                                    */
2975 /*                                                                        */
2976 /*  RELEASE HISTORY                                                       */
2977 /*                                                                        */
2978 /*    DATE              NAME                      DESCRIPTION             */
2979 /*                                                                        */
2980 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2981 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2982 /*                                            resulting in version 6.1    */
2983 /*                                                                        */
2984 /**************************************************************************/
_nxe_snmp_agent_private_string_set(NX_SNMP_AGENT * agent_ptr,UCHAR * community_string)2985 UINT _nxe_snmp_agent_private_string_set(NX_SNMP_AGENT *agent_ptr, UCHAR *community_string)
2986 {
2987 
2988 UINT status;
2989 
2990     /* Check for invalid pointer input. */
2991     if ((agent_ptr == NX_NULL) || (community_string == NX_NULL))
2992     {
2993         return NX_PTR_ERROR;
2994     }
2995 
2996     /* Call the actual service. */
2997     status = _nx_snmp_agent_private_string_set(agent_ptr, community_string);
2998 
2999 
3000     return status;
3001 }
3002 
3003 
3004 /**************************************************************************/
3005 /*                                                                        */
3006 /*  FUNCTION                                               RELEASE        */
3007 /*                                                                        */
3008 /*    _nx_snmp_agent_private_string_set                   PORTABLE C      */
3009 /*                                                           6.1          */
3010 /*  AUTHOR                                                                */
3011 /*                                                                        */
3012 /*    Yuxin Zhou, Microsoft Corporation                                   */
3013 /*                                                                        */
3014 /*  DESCRIPTION                                                           */
3015 /*                                                                        */
3016 /*    This function sets the input string and size input as the Agent's   */
3017 /*    private string and private string size.                             */
3018 /*                                                                        */
3019 /*    Note: The string length of community_string is limited by           */
3020 /*    NX_SNMP_MAX_USER_NAME.                                              */
3021 /*                                                                        */
3022 /*  INPUT                                                                 */
3023 /*                                                                        */
3024 /*    agent_ptr                             Pointer to SNMP agent         */
3025 /*    community_string                      Pointer to private string     */
3026 /*                                                                        */
3027 /*  OUTPUT                                                                */
3028 /*                                                                        */
3029 /*    NX_SUCCESS                            Successful completion status  */
3030 /*                                                                        */
3031 /*  CALLS                                                                 */
3032 /*                                                                        */
3033 /*    None                                                                */
3034 /*                                                                        */
3035 /*  CALLED BY                                                             */
3036 /*                                                                        */
3037 /*    Application Code                                                    */
3038 /*                                                                        */
3039 /*  RELEASE HISTORY                                                       */
3040 /*                                                                        */
3041 /*    DATE              NAME                      DESCRIPTION             */
3042 /*                                                                        */
3043 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3044 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3045 /*                                            resulting in version 6.1    */
3046 /*                                                                        */
3047 /**************************************************************************/
_nx_snmp_agent_private_string_set(NX_SNMP_AGENT * agent_ptr,UCHAR * community_string)3048 UINT _nx_snmp_agent_private_string_set(NX_SNMP_AGENT *agent_ptr, UCHAR *community_string)
3049 {
3050 
3051 UINT i;
3052 UINT length;
3053 
3054 
3055     /* Verify the string is not too large, leaving room for the null terminating string. */
3056     if (_nx_utility_string_length_check((CHAR *)community_string, &length, NX_SNMP_MAX_USER_NAME))
3057     {
3058         return NX_SNMP_ERROR_TOOBIG;
3059     }
3060 
3061     /* Copy the string to the SNMP agent private community string. */
3062     for (i = 0; i < length; i++)
3063     {
3064         agent_ptr -> nx_snmp_agent_private_community_string[i] = *community_string;
3065         community_string++;
3066     }
3067 
3068     /* Null terminate the string. */
3069     agent_ptr -> nx_snmp_agent_private_community_string[i] = 0x0;
3070 
3071     return NX_SUCCESS;
3072 }
3073 
3074 
3075 /**************************************************************************/
3076 /*                                                                        */
3077 /*  FUNCTION                                               RELEASE        */
3078 /*                                                                        */
3079 /*    _nxe_snmp_agent_public_string_set                   PORTABLE C      */
3080 /*                                                           6.1          */
3081 /*  AUTHOR                                                                */
3082 /*                                                                        */
3083 /*    Yuxin Zhou, Microsoft Corporation                                   */
3084 /*                                                                        */
3085 /*  DESCRIPTION                                                           */
3086 /*                                                                        */
3087 /*    This function performs error checking for the nx_snmp_agent_set_    */
3088 /*    _public_string service.                                             */
3089 /*                                                                        */
3090 /*  INPUT                                                                 */
3091 /*                                                                        */
3092 /*    agent_ptr                             Pointer to SNMP agent         */
3093 /*    community_string                      Pointer to public string      */
3094 /*                                                                        */
3095 /*  OUTPUT                                                                */
3096 /*                                                                        */
3097 /*    NX_SUCCESS                            Successful completion status  */
3098 /*                                                                        */
3099 /*  CALLS                                                                 */
3100 /*                                                                        */
3101 /*    _nx_snmp_agent_public_string_set      Set public string service     */
3102 /*                                                                        */
3103 /*  CALLED BY                                                             */
3104 /*                                                                        */
3105 /*    Application Code                                                    */
3106 /*                                                                        */
3107 /*  RELEASE HISTORY                                                       */
3108 /*                                                                        */
3109 /*    DATE              NAME                      DESCRIPTION             */
3110 /*                                                                        */
3111 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3112 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3113 /*                                            resulting in version 6.1    */
3114 /*                                                                        */
3115 /**************************************************************************/
_nxe_snmp_agent_public_string_set(NX_SNMP_AGENT * agent_ptr,UCHAR * community_string)3116 UINT _nxe_snmp_agent_public_string_set(NX_SNMP_AGENT *agent_ptr, UCHAR *community_string)
3117 {
3118 
3119 UINT status;
3120 
3121     if ((agent_ptr == NX_NULL) || (community_string == NX_NULL))
3122     {
3123         return NX_PTR_ERROR;
3124     }
3125 
3126     status = _nx_snmp_agent_public_string_set(agent_ptr, community_string);
3127 
3128     return status;
3129 }
3130 
3131 
3132 /**************************************************************************/
3133 /*                                                                        */
3134 /*  FUNCTION                                               RELEASE        */
3135 /*                                                                        */
3136 /*    _nx_snmp_agent_public_string_set                    PORTABLE C      */
3137 /*                                                           6.1          */
3138 /*  AUTHOR                                                                */
3139 /*                                                                        */
3140 /*    Yuxin Zhou, Microsoft Corporation                                   */
3141 /*                                                                        */
3142 /*  DESCRIPTION                                                           */
3143 /*                                                                        */
3144 /*    This function sets the input string and size input as the Agent's   */
3145 /*    public string and public string size.                               */
3146 /*                                                                        */
3147 /*    Note: The string length of community_string is limited by           */
3148 /*    NX_SNMP_MAX_USER_NAME.                                              */
3149 /*                                                                        */
3150 /*  INPUT                                                                 */
3151 /*                                                                        */
3152 /*    agent_ptr                             Pointer to SNMP agent         */
3153 /*    community_string                      Pointer to public  string     */
3154 /*                                                                        */
3155 /*  OUTPUT                                                                */
3156 /*                                                                        */
3157 /*    NX_SUCCESS                            Successful completion status  */
3158 /*                                                                        */
3159 /*  CALLS                                                                 */
3160 /*                                                                        */
3161 /*    None                                                                */
3162 /*                                                                        */
3163 /*  CALLED BY                                                             */
3164 /*                                                                        */
3165 /*    Application Code                                                    */
3166 /*                                                                        */
3167 /*  RELEASE HISTORY                                                       */
3168 /*                                                                        */
3169 /*    DATE              NAME                      DESCRIPTION             */
3170 /*                                                                        */
3171 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3172 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3173 /*                                            resulting in version 6.1    */
3174 /*                                                                        */
3175 /**************************************************************************/
_nx_snmp_agent_public_string_set(NX_SNMP_AGENT * agent_ptr,UCHAR * community_string)3176 UINT _nx_snmp_agent_public_string_set(NX_SNMP_AGENT *agent_ptr, UCHAR *community_string)
3177 {
3178 UINT i;
3179 UINT length;
3180 
3181 
3182     /* Verify the string is not too large, leaving room for the null terminating character. */
3183     if (_nx_utility_string_length_check((CHAR *)community_string, &length, NX_SNMP_MAX_USER_NAME))
3184     {
3185         return NX_SNMP_ERROR_TOOBIG;
3186     }
3187 
3188     /* Copy the string to the SNMP agent public community string. */
3189     for (i = 0; i < length; i++)
3190     {
3191         agent_ptr -> nx_snmp_agent_public_community_string[i] = *community_string;
3192         community_string++;
3193     }
3194 
3195     /* Null terminate the string. */
3196     agent_ptr -> nx_snmp_agent_public_community_string[i] = 0x0;
3197 
3198     return NX_SUCCESS;
3199 }
3200 
3201 
3202 /**************************************************************************/
3203 /*                                                                        */
3204 /*  FUNCTION                                               RELEASE        */
3205 /*                                                                        */
3206 /*    _nxe_snmp_agent_start                               PORTABLE C      */
3207 /*                                                           6.1          */
3208 /*  AUTHOR                                                                */
3209 /*                                                                        */
3210 /*    Yuxin Zhou, Microsoft Corporation                                   */
3211 /*                                                                        */
3212 /*  DESCRIPTION                                                           */
3213 /*                                                                        */
3214 /*    This function checks for errors in the SNMP agent start             */
3215 /*    function call.                                                      */
3216 /*                                                                        */
3217 /*  INPUT                                                                 */
3218 /*                                                                        */
3219 /*    agent_ptr                             Pointer to SNMP agent         */
3220 /*                                                                        */
3221 /*  OUTPUT                                                                */
3222 /*                                                                        */
3223 /*    status                                Completion status             */
3224 /*                                                                        */
3225 /*  CALLS                                                                 */
3226 /*                                                                        */
3227 /*    _nx_snmp_agent_start                  Actual agent start function   */
3228 /*                                                                        */
3229 /*  CALLED BY                                                             */
3230 /*                                                                        */
3231 /*    Application Code                                                    */
3232 /*                                                                        */
3233 /*  RELEASE HISTORY                                                       */
3234 /*                                                                        */
3235 /*    DATE              NAME                      DESCRIPTION             */
3236 /*                                                                        */
3237 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3238 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3239 /*                                            resulting in version 6.1    */
3240 /*                                                                        */
3241 /**************************************************************************/
_nxe_snmp_agent_start(NX_SNMP_AGENT * agent_ptr)3242 UINT  _nxe_snmp_agent_start(NX_SNMP_AGENT *agent_ptr)
3243 {
3244 
3245 UINT    status;
3246 
3247 
3248     /* Check for invalid input pointers.  */
3249     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID))
3250         return(NX_PTR_ERROR);
3251 
3252     /* Call actual service.  */
3253     status =  _nx_snmp_agent_start(agent_ptr);
3254 
3255     /* Return status.  */
3256     return(status);
3257 }
3258 
3259 
3260 /**************************************************************************/
3261 /*                                                                        */
3262 /*  FUNCTION                                               RELEASE        */
3263 /*                                                                        */
3264 /*    _nx_snmp_agent_start                                PORTABLE C      */
3265 /*                                                           6.1          */
3266 /*  AUTHOR                                                                */
3267 /*                                                                        */
3268 /*    Yuxin Zhou, Microsoft Corporation                                   */
3269 /*                                                                        */
3270 /*  DESCRIPTION                                                           */
3271 /*                                                                        */
3272 /*    This function starts the SNMP agent thread.                         */
3273 /*                                                                        */
3274 /*  INPUT                                                                 */
3275 /*                                                                        */
3276 /*    agent_ptr                             Pointer to SNMP agent         */
3277 /*                                                                        */
3278 /*  OUTPUT                                                                */
3279 /*                                                                        */
3280 /*    status                                Completion status             */
3281 /*                                                                        */
3282 /*  CALLS                                                                 */
3283 /*                                                                        */
3284 /*    tx_thread_resume                      Resume SNMP agent thread      */
3285 /*                                                                        */
3286 /*  CALLED BY                                                             */
3287 /*                                                                        */
3288 /*    Application Code                                                    */
3289 /*                                                                        */
3290 /*  RELEASE HISTORY                                                       */
3291 /*                                                                        */
3292 /*    DATE              NAME                      DESCRIPTION             */
3293 /*                                                                        */
3294 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3295 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3296 /*                                            resulting in version 6.1    */
3297 /*                                                                        */
3298 /**************************************************************************/
_nx_snmp_agent_start(NX_SNMP_AGENT * agent_ptr)3299 UINT  _nx_snmp_agent_start(NX_SNMP_AGENT *agent_ptr)
3300 {
3301 
3302 UINT status;
3303 
3304     /* Bind the socket to a the well known SNMP UDP port number.  */
3305     status =  nx_udp_socket_bind(&(agent_ptr -> nx_snmp_agent_socket), NX_SNMP_AGENT_PORT, NX_NO_WAIT);
3306 
3307     /* Determine if an error occurred.  */
3308     if (status)
3309     {
3310 
3311         /* Delete the UDP socket.  */
3312         nx_udp_socket_delete(&(agent_ptr -> nx_snmp_agent_socket));
3313 
3314         /* Yes, return error code.  */
3315         return(NX_SNMP_ERROR);
3316     }
3317 
3318     /* Start the SNMP agent thread.  */
3319     tx_thread_resume(&(agent_ptr -> nx_snmp_agent_thread));
3320 
3321 
3322     /* Return successful status.  */
3323     return(NX_SUCCESS);
3324 }
3325 
3326 
3327 /**************************************************************************/
3328 /*                                                                        */
3329 /*  FUNCTION                                               RELEASE        */
3330 /*                                                                        */
3331 /*    _nxe_snmp_agent_stop                                PORTABLE C      */
3332 /*                                                           6.1          */
3333 /*  AUTHOR                                                                */
3334 /*                                                                        */
3335 /*    Yuxin Zhou, Microsoft Corporation                                   */
3336 /*                                                                        */
3337 /*  DESCRIPTION                                                           */
3338 /*                                                                        */
3339 /*    This function checks for errors in the SNMP agent stop              */
3340 /*    function call.                                                      */
3341 /*                                                                        */
3342 /*  INPUT                                                                 */
3343 /*                                                                        */
3344 /*    agent_ptr                             Pointer to SNMP agent         */
3345 /*                                                                        */
3346 /*  OUTPUT                                                                */
3347 /*                                                                        */
3348 /*    status                                Completion status             */
3349 /*                                                                        */
3350 /*  CALLS                                                                 */
3351 /*                                                                        */
3352 /*    _nx_snmp_agent_stop                   Actual agent stop function    */
3353 /*                                                                        */
3354 /*  CALLED BY                                                             */
3355 /*                                                                        */
3356 /*    Application Code                                                    */
3357 /*                                                                        */
3358 /*  RELEASE HISTORY                                                       */
3359 /*                                                                        */
3360 /*    DATE              NAME                      DESCRIPTION             */
3361 /*                                                                        */
3362 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3363 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3364 /*                                            resulting in version 6.1    */
3365 /*                                                                        */
3366 /**************************************************************************/
_nxe_snmp_agent_stop(NX_SNMP_AGENT * agent_ptr)3367 UINT  _nxe_snmp_agent_stop(NX_SNMP_AGENT *agent_ptr)
3368 {
3369 
3370 UINT    status;
3371 
3372 
3373     /* Check for invalid input pointers.  */
3374     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID))
3375         return(NX_PTR_ERROR);
3376 
3377     /* Call actual service.  */
3378     status =  _nx_snmp_agent_stop(agent_ptr);
3379 
3380     /* Return status.  */
3381     return(status);
3382 }
3383 
3384 
3385 /**************************************************************************/
3386 /*                                                                        */
3387 /*  FUNCTION                                               RELEASE        */
3388 /*                                                                        */
3389 /*    _nx_snmp_agent_stop                                 PORTABLE C      */
3390 /*                                                           6.1          */
3391 /*  AUTHOR                                                                */
3392 /*                                                                        */
3393 /*    Yuxin Zhou, Microsoft Corporation                                   */
3394 /*                                                                        */
3395 /*  DESCRIPTION                                                           */
3396 /*                                                                        */
3397 /*    This function stops the SNMP agent thread.                          */
3398 /*                                                                        */
3399 /*  INPUT                                                                 */
3400 /*                                                                        */
3401 /*    agent_ptr                             Pointer to SNMP agent         */
3402 /*                                                                        */
3403 /*  OUTPUT                                                                */
3404 /*                                                                        */
3405 /*    status                                Completion status             */
3406 /*                                                                        */
3407 /*  CALLS                                                                 */
3408 /*                                                                        */
3409 /*    tx_thread_suspend                     Suspend SNMP agent thread     */
3410 /*                                                                        */
3411 /*  CALLED BY                                                             */
3412 /*                                                                        */
3413 /*    Application Code                                                    */
3414 /*                                                                        */
3415 /*  RELEASE HISTORY                                                       */
3416 /*                                                                        */
3417 /*    DATE              NAME                      DESCRIPTION             */
3418 /*                                                                        */
3419 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3420 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3421 /*                                            resulting in version 6.1    */
3422 /*                                                                        */
3423 /**************************************************************************/
_nx_snmp_agent_stop(NX_SNMP_AGENT * agent_ptr)3424 UINT  _nx_snmp_agent_stop(NX_SNMP_AGENT *agent_ptr)
3425 {
3426 
3427     /* Stop the SNMP agent thread.  */
3428     tx_thread_suspend(&(agent_ptr -> nx_snmp_agent_thread));
3429 
3430     /* Unbind the UDP socket.  */
3431     nx_udp_socket_unbind(&(agent_ptr -> nx_snmp_agent_socket));
3432 
3433     /* Return successful status.  */
3434     return(NX_SUCCESS);
3435 }
3436 
3437 
3438 /**************************************************************************/
3439 /*                                                                        */
3440 /*  FUNCTION                                               RELEASE        */
3441 /*                                                                        */
3442 /*    _nx_snmp_agent_thread_entry                         PORTABLE C      */
3443 /*                                                           6.1          */
3444 /*  AUTHOR                                                                */
3445 /*                                                                        */
3446 /*    Yuxin Zhou, Microsoft Corporation                                   */
3447 /*                                                                        */
3448 /*  DESCRIPTION                                                           */
3449 /*                                                                        */
3450 /*    This function is the entry function of the SNMP agent thread.       */
3451 /*                                                                        */
3452 /*  INPUT                                                                 */
3453 /*                                                                        */
3454 /*    snmp_agent_address                    Pointer to SNMP agent         */
3455 /*                                                                        */
3456 /*  OUTPUT                                                                */
3457 /*                                                                        */
3458 /*    None                                                                */
3459 /*                                                                        */
3460 /*  CALLS                                                                 */
3461 /*                                                                        */
3462 /*    nx_packet_copy                        Copy SNMP packet              */
3463 /*    nx_packet_release                     Release original SNMP packet  */
3464 /*    _nx_snmp_utility_sequence_get         Get sequence number in packet */
3465 /*    _nx_snmp_utility_version_get          Get SNMP version number       */
3466 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
3467 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
3468 /*    nx_udp_socket_receive                 Receive SNMP request          */
3469 /*    nx_udp_source_extract                 Extract source IP and port    */
3470 /*                                            from request                */
3471 /*                                                                        */
3472 /*  CALLED BY                                                             */
3473 /*                                                                        */
3474 /*    ThreadX                                                             */
3475 /*                                                                        */
3476 /*  RELEASE HISTORY                                                       */
3477 /*                                                                        */
3478 /*    DATE              NAME                      DESCRIPTION             */
3479 /*                                                                        */
3480 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3481 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3482 /*                                            resulting in version 6.1    */
3483 /*                                                                        */
3484 /**************************************************************************/
_nx_snmp_agent_thread_entry(ULONG snmp_agent_address)3485 VOID  _nx_snmp_agent_thread_entry(ULONG snmp_agent_address)
3486 {
3487 
3488 NX_SNMP_AGENT           *agent_ptr;
3489 UCHAR                   *buffer_ptr;
3490 NX_PACKET               *packet_ptr;
3491 UINT                    length;
3492 UINT                    version;
3493 UINT                    status;
3494 UINT                    sequence_length;
3495 INT                     buffer_length;
3496 #ifndef NX_DISABLE_PACKET_CHAIN
3497 NX_PACKET               *new_packet_ptr;
3498 #endif
3499 
3500 
3501     /* Setup the agent pointer.  */
3502     agent_ptr =  (NX_SNMP_AGENT *) snmp_agent_address;
3503 
3504     /* Loop to process SNMP Manager requests.  */
3505     while(1)
3506     {
3507 
3508         /* Wait for a SNMP Manager request.  */
3509         status =  nx_udp_socket_receive(&(agent_ptr -> nx_snmp_agent_socket), &packet_ptr, NX_WAIT_FOREVER);
3510 
3511         /* Check for a successful packet reception.  */
3512         if (status)
3513         {
3514 
3515             /* If the error is other than no packet received, update the internal error count. */
3516             if (status != NX_NO_PACKET)
3517             {
3518                 /* Increment the internal error counter.  */
3519                 agent_ptr -> nx_snmp_agent_internal_errors++;
3520             }
3521 
3522             /* Go back and wait for another packet.  */
3523             continue;
3524         }
3525 
3526 
3527         /* Pickup the source information for the packet - do this before the packet copy since the information
3528            prior to the prepend pointer is not copied!  */
3529         nxd_udp_source_extract(packet_ptr, &(agent_ptr -> nx_snmp_agent_current_manager_ip),
3530                                &(agent_ptr -> nx_snmp_agent_current_manager_port));
3531 
3532 #ifndef NX_DISABLE_PACKET_CHAIN
3533         /* Determine if we have to copy the packet into a packet from the SNMP pool.  */
3534         if (packet_ptr -> nx_packet_next)
3535         {
3536 
3537             /* Copy the packet into a packet from the SNMP pool.  */
3538             status =  nx_packet_copy(packet_ptr, &new_packet_ptr, agent_ptr -> nx_snmp_agent_packet_pool_ptr, NX_SNMP_AGENT_TIMEOUT);
3539 
3540             /* Release the original packet.  */
3541             nx_packet_release(packet_ptr);
3542 
3543             /* Determine if the copy was successful.  */
3544             if (status || (new_packet_ptr -> nx_packet_next != NX_NULL))
3545             {
3546 
3547                 /* No, the packet copy was not successful.  */
3548 
3549                 /* Increment the internal error counter.  */
3550                 agent_ptr -> nx_snmp_agent_internal_errors++;
3551 
3552                 /* Go back and wait for another packet.  */
3553                 continue;
3554             }
3555 
3556             /* Otherwise, copy the new packet pointer to the standard packet pointer.  */
3557             packet_ptr =  new_packet_ptr;
3558         }
3559 
3560 #endif /*NX_DISABLE_PACKET_CHAIN */
3561 
3562         buffer_length = (INT)(packet_ptr -> nx_packet_length);
3563 
3564         /* Setup a pointer to the buffer.  */
3565         buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
3566 
3567         /* Pickup the SEQUENCE field.  */
3568         length =  _nx_snmp_utility_sequence_get(buffer_ptr, &sequence_length, buffer_length);
3569 
3570         /* Check for a valid packet.  */
3571         if (length == 0)
3572         {
3573 
3574             /* Increment the unknown command error.  */
3575             agent_ptr -> nx_snmp_agent_unknown_requests++;
3576 
3577             /* Increment the internal error counter.  */
3578             agent_ptr -> nx_snmp_agent_internal_errors++;
3579 
3580             /* Release the packet.  */
3581             nx_packet_release(packet_ptr);
3582 
3583             /* Go back and wait for another packet.  */
3584             continue;
3585         }
3586 
3587         /* Move the buffer pointer up.  */
3588         buffer_ptr =  buffer_ptr + length;
3589 
3590         /* The buffer pointer is moved by the length. Update buffer size */
3591         buffer_length -= (INT)length;
3592 
3593         /* Pickup the SNMP VERSION field.  */
3594         length =  _nx_snmp_utility_version_get(buffer_ptr, &version, buffer_length);
3595 
3596         /* Check for a valid packet.  */
3597         if (length == 0)
3598         {
3599 
3600             /* Increment the unknown command error.  */
3601             agent_ptr -> nx_snmp_agent_unknown_requests++;
3602 
3603             /* Increment the internal error counter.  */
3604             agent_ptr -> nx_snmp_agent_internal_errors++;
3605 
3606             /* Release the packet.  */
3607             nx_packet_release(packet_ptr);
3608 
3609             /* Go back and wait for another packet.  */
3610             continue;
3611         }
3612 
3613         /* Increment the total number of packets received.  */
3614         agent_ptr -> nx_snmp_agent_packets_received++;
3615 
3616         /* We have a valid SNMP version, process relative to the type of SNMP version.  */
3617         if (version == NX_SNMP_VERSION_1)
3618         {
3619 
3620 #ifndef NX_SNMP_DISABLE_V1
3621             /* Verify V1 is currently enabled for this agent. */
3622             if (agent_ptr -> nx_snmp_agent_v1_enabled == NX_FALSE)
3623             {
3624 
3625                 /* It is not. Increment error counter.  */
3626                 agent_ptr -> nx_snmp_agent_invalid_version++;
3627 
3628                 /* Release packet.  */
3629                 nx_packet_release(packet_ptr);
3630             }
3631             else
3632             {
3633 
3634                 /* Update the SNMP agent's version. */
3635                 agent_ptr -> nx_snmp_agent_current_version = version;
3636 
3637                 /* Process SNMP Version 1 request.  */
3638                 _nx_snmp_version_1_and_2_process(agent_ptr, packet_ptr);
3639             }
3640 #else
3641 
3642 
3643             /* Invalid version. Increment error counter.  */
3644             agent_ptr -> nx_snmp_agent_invalid_version++;
3645 
3646             /* Release packet.  */
3647             nx_packet_release(packet_ptr);
3648 #endif
3649         }
3650 #ifdef NX_SNMP_V2C_ONLY
3651         else if (version == NX_SNMP_VERSION_2C)
3652 #else
3653         else if ((version == NX_SNMP_VERSION_2) || (version == NX_SNMP_VERSION_2C))
3654 #endif
3655         {
3656 
3657 #ifndef NX_SNMP_DISABLE_V2
3658 
3659             /* Verify V2 is currently enabled for this agent. */
3660             if (agent_ptr -> nx_snmp_agent_v2_enabled == NX_FALSE)
3661             {
3662                 /* It is not. Increment error counter.  */
3663                 agent_ptr -> nx_snmp_agent_invalid_version++;
3664 
3665                 /* Release packet.  */
3666                 nx_packet_release(packet_ptr);
3667             }
3668             else
3669             {
3670                 /* Update the SNMP agent's version. */
3671                 agent_ptr -> nx_snmp_agent_current_version = version;
3672 
3673 
3674                 /* Process SNMP Version 2 request.  */
3675                 _nx_snmp_version_1_and_2_process(agent_ptr, packet_ptr);
3676             }
3677 #else
3678 
3679             /* Invalid version. Increment error counter.  */
3680             agent_ptr -> nx_snmp_agent_invalid_version++;
3681 
3682             /* Release packet.  */
3683             nx_packet_release(packet_ptr);
3684 #endif
3685         }
3686         else if (version == NX_SNMP_VERSION_3)
3687         {
3688 
3689 #ifndef NX_SNMP_DISABLE_V3
3690 
3691             /* Verify V3 is currently enabled for this agent. */
3692             if (agent_ptr -> nx_snmp_agent_v3_enabled == NX_FALSE)
3693             {
3694 
3695                 /* It is not. Increment error counter.  */
3696                 agent_ptr -> nx_snmp_agent_invalid_version++;
3697 
3698                 /* Release packet.  */
3699                 nx_packet_release(packet_ptr);
3700             }
3701             else
3702             {
3703                 /* Update the SNMP agent's version. */
3704                 agent_ptr -> nx_snmp_agent_current_version = version;
3705 
3706                 /* Process SNMP Version 3 request.  */
3707                 _nx_snmp_version_3_process(agent_ptr, packet_ptr);
3708             }
3709 #else
3710 
3711             /* Invalid version. Increment error counter.  */
3712             agent_ptr -> nx_snmp_agent_invalid_version++;
3713 
3714             /* Release packet.  */
3715             nx_packet_release(packet_ptr);
3716 #endif
3717         }
3718         else
3719         {
3720 
3721             /* Invalid version. Increment error counter.  */
3722             agent_ptr -> nx_snmp_agent_invalid_version++;
3723 
3724             /* Release packet.  */
3725             nx_packet_release(packet_ptr);
3726         }
3727     }
3728 }
3729 
3730 
3731 #ifndef NX_SNMP_DISABLE_V1
3732 /**************************************************************************/
3733 /*                                                                        */
3734 /*  FUNCTION                                               RELEASE        */
3735 /*                                                                        */
3736 /*    _nxe_snmp_agent_trap_send                           PORTABLE C      */
3737 /*                                                           6.1          */
3738 /*  AUTHOR                                                                */
3739 /*                                                                        */
3740 /*    Yuxin Zhou, Microsoft Corporation                                   */
3741 /*                                                                        */
3742 /*  DESCRIPTION                                                           */
3743 /*                                                                        */
3744 /*    This function checks for errors in the SNMPv1 trap send service.    */
3745 /*                                                                        */
3746 /*    Developers are encouraged to use the nxd_snmp_agent_trap_send       */
3747 /*    service which supports IPv4 and IPv6 types.                         */
3748 /*                                                                        */
3749 /*  INPUT                                                                 */
3750 /*                                                                        */
3751 /*    agent_ptr                             Pointer to SNMP agent         */
3752 /*    ip_address                            Destination IPv4 address      */
3753 /*    community                             Community string              */
3754 /*    enterprise                            Identifies the device that is */
3755 /*                                            generating the trap         */
3756 /*    trap_type                             Type of trap                  */
3757 /*    trap_code                             Additional trap information   */
3758 /*    elapsed_time                          Elapsed time from last boot   */
3759 /*                                            of the device (sysUpTime)   */
3760 /*    object_list_ptr                       Variable list of application  */
3761 /*                                            objects to present with the */
3762 /*                                            trap                        */
3763 /*                                                                        */
3764 /*  OUTPUT                                                                */
3765 /*                                                                        */
3766 /*    status                                Completion status             */
3767 /*                                                                        */
3768 /*  CALLS                                                                 */
3769 /*                                                                        */
3770 /*    _nx_snmp_agent_trap_send              Actual agent trap send        */
3771 /*                                            function                    */
3772 /*                                                                        */
3773 /*  CALLED BY                                                             */
3774 /*                                                                        */
3775 /*    Application Code                                                    */
3776 /*                                                                        */
3777 /*  RELEASE HISTORY                                                       */
3778 /*                                                                        */
3779 /*    DATE              NAME                      DESCRIPTION             */
3780 /*                                                                        */
3781 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3782 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3783 /*                                            resulting in version 6.1    */
3784 /*                                                                        */
3785 /**************************************************************************/
_nxe_snmp_agent_trap_send(NX_SNMP_AGENT * agent_ptr,ULONG ip_address,UCHAR * community,UCHAR * enterprise,UINT trap_type,UINT trap_code,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)3786 UINT  _nxe_snmp_agent_trap_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *community, UCHAR *enterprise,
3787                                 UINT trap_type, UINT trap_code, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
3788 {
3789 
3790 #ifndef NX_DISABLE_IPV4
3791 UINT    status;
3792 
3793 
3794     /* Check for invalid input pointers.  */
3795     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) || (community == NX_NULL) || (enterprise == NX_NULL))
3796         return(NX_PTR_ERROR);
3797 
3798     /* Check for invalid IP address.  */
3799     if (ip_address == 0)
3800         return(NX_IP_ADDRESS_ERROR);
3801 
3802     /* Call actual service.  */
3803     status =  _nx_snmp_agent_trap_send(agent_ptr, ip_address, community, enterprise, trap_type, trap_code, elapsed_time, object_list_ptr);
3804 
3805     /* Return status.  */
3806     return(status);
3807 #else
3808     NX_PARAMETER_NOT_USED(agent_ptr);
3809     NX_PARAMETER_NOT_USED(ip_address);
3810     NX_PARAMETER_NOT_USED(community);
3811     NX_PARAMETER_NOT_USED(enterprise);
3812     NX_PARAMETER_NOT_USED(trap_type);
3813     NX_PARAMETER_NOT_USED(trap_code);
3814     NX_PARAMETER_NOT_USED(elapsed_time);
3815     NX_PARAMETER_NOT_USED(object_list_ptr);
3816 
3817     return(NX_NOT_SUPPORTED);
3818 #endif /* NX_DISABLE_IPV4 */
3819 }
3820 
3821 
3822 /**************************************************************************/
3823 /*                                                                        */
3824 /*  FUNCTION                                               RELEASE        */
3825 /*                                                                        */
3826 /*    _nx_snmp_agent_trap_send                            PORTABLE C      */
3827 /*                                                           6.1          */
3828 /*  AUTHOR                                                                */
3829 /*                                                                        */
3830 /*    Yuxin Zhou, Microsoft Corporation                                   */
3831 /*                                                                        */
3832 /*  DESCRIPTION                                                           */
3833 /*                                                                        */
3834 /*    This function stores the input IPv4 destination IP address in a NetX*/
3835 /*    Duo data type that supports IPv4 and IPv6 address formats, and      */
3836 /*    uses the 'dual' trap send service _nxd_snmp_agent_trap_send to build*/
3837 /*    and send the SNMPv1 trap message.                                   */
3838 /*                                                                        */
3839 /*    Developers are encouraged to use nxd_snmp_agent_trap_send.          */
3840 /*                                                                        */
3841 /*  INPUT                                                                 */
3842 /*                                                                        */
3843 /*    agent_ptr                             Pointer to SNMP agent         */
3844 /*    ip_address                            Destination IPv4 address      */
3845 /*    community                             Community string              */
3846 /*    enterprise                            Identifies the device that is */
3847 /*                                            generating the trap         */
3848 /*    trap_type                             Type of trap                  */
3849 /*    trap_code                             Additional trap information   */
3850 /*    elapsed_time                          Elapsed time from last boot   */
3851 /*                                            of the device (sysUpTime)   */
3852 /*    object_list_ptr                       Variable list of application  */
3853 /*                                            objects to present with the */
3854 /*                                            trap                        */
3855 /*                                                                        */
3856 /*  OUTPUT                                                                */
3857 /*                                                                        */
3858 /*    status                                Completion status             */
3859 /*    NX_NOT_ENABLED                        Agent not enabled for V1      */
3860 /*                                                                        */
3861 /*  CALLS                                                                 */
3862 /*                                                                        */
3863 /*    _nxd_snmp_agent_trap_send             Actual agent trap send        */
3864 /*                                            function                    */
3865 /*                                                                        */
3866 /*  CALLED BY                                                             */
3867 /*                                                                        */
3868 /*    Application Code                                                    */
3869 /*                                                                        */
3870 /*  RELEASE HISTORY                                                       */
3871 /*                                                                        */
3872 /*    DATE              NAME                      DESCRIPTION             */
3873 /*                                                                        */
3874 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3875 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3876 /*                                            resulting in version 6.1    */
3877 /*                                                                        */
3878 /**************************************************************************/
3879 
_nx_snmp_agent_trap_send(NX_SNMP_AGENT * agent_ptr,ULONG ip_address,UCHAR * community,UCHAR * enterprise,UINT trap_type,UINT trap_code,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)3880 UINT  _nx_snmp_agent_trap_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *community, UCHAR *enterprise,
3881                                UINT trap_type, UINT trap_code, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
3882 {
3883 
3884 #ifndef NX_DISABLE_IPV4
3885 UINT         status;
3886 NXD_ADDRESS  ip_netxduo_address;
3887 
3888 
3889     ip_netxduo_address.nxd_ip_address.v4 = ip_address;
3890     ip_netxduo_address.nxd_ip_version = NX_IP_VERSION_V4;
3891 
3892     status = _nxd_snmp_agent_trap_send(agent_ptr, &ip_netxduo_address, community, enterprise,
3893                                        trap_type, trap_code, elapsed_time, object_list_ptr);
3894 
3895     return status;
3896 #else
3897     NX_PARAMETER_NOT_USED(agent_ptr);
3898     NX_PARAMETER_NOT_USED(ip_address);
3899     NX_PARAMETER_NOT_USED(community);
3900     NX_PARAMETER_NOT_USED(enterprise);
3901     NX_PARAMETER_NOT_USED(trap_type);
3902     NX_PARAMETER_NOT_USED(trap_code);
3903     NX_PARAMETER_NOT_USED(elapsed_time);
3904     NX_PARAMETER_NOT_USED(object_list_ptr);
3905 
3906     return(NX_NOT_SUPPORTED);
3907 #endif /* NX_DISABLE_IPV4 */
3908 }
3909 
3910 
3911 /**************************************************************************/
3912 /*                                                                        */
3913 /*  FUNCTION                                               RELEASE        */
3914 /*                                                                        */
3915 /*    _nxde_snmp_agent_trap_send                          PORTABLE C      */
3916 /*                                                           6.1          */
3917 /*  AUTHOR                                                                */
3918 /*                                                                        */
3919 /*    Yuxin Zhou, Microsoft Corporation                                   */
3920 /*                                                                        */
3921 /*  DESCRIPTION                                                           */
3922 /*                                                                        */
3923 /*    This function checks for errors in the SNMPv1 trap send service.    */
3924 /*                                                                        */
3925 /*  INPUT                                                                 */
3926 /*                                                                        */
3927 /*    agent_ptr                             Pointer to SNMP agent         */
3928 /*    ip_address                            Destination IP address        */
3929 /*    community                             Community string              */
3930 /*    enterprise                            Identifies the device that is */
3931 /*                                            generating the trap         */
3932 /*    trap_type                             Type of trap                  */
3933 /*    trap_code                             Additional trap information   */
3934 /*    elapsed_time                          Elapsed time from last boot   */
3935 /*                                            of the device (sysUpTime)   */
3936 /*    object_list_ptr                       Variable list of application  */
3937 /*                                            objects to present with the */
3938 /*                                            trap                        */
3939 /*                                                                        */
3940 /*  OUTPUT                                                                */
3941 /*                                                                        */
3942 /*    status                                Completion status             */
3943 /*                                                                        */
3944 /*  CALLS                                                                 */
3945 /*                                                                        */
3946 /*    _nxd_snmp_agent_trap_send            Actual SNMPv1 trap send        */
3947 /*                                            service                     */
3948 /*                                                                        */
3949 /*  CALLED BY                                                             */
3950 /*                                                                        */
3951 /*    Application Code                                                    */
3952 /*                                                                        */
3953 /*  RELEASE HISTORY                                                       */
3954 /*                                                                        */
3955 /*    DATE              NAME                      DESCRIPTION             */
3956 /*                                                                        */
3957 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3958 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3959 /*                                            resulting in version 6.1    */
3960 /*                                                                        */
3961 /**************************************************************************/
_nxde_snmp_agent_trap_send(NX_SNMP_AGENT * agent_ptr,NXD_ADDRESS * ip_address,UCHAR * community,UCHAR * enterprise,UINT trap_type,UINT trap_code,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)3962 UINT  _nxde_snmp_agent_trap_send(NX_SNMP_AGENT *agent_ptr, NXD_ADDRESS *ip_address, UCHAR *community, UCHAR *enterprise,
3963                                 UINT trap_type, UINT trap_code, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
3964 {
3965 
3966 UINT    status;
3967 
3968 
3969     /* Check for invalid input pointers.  */
3970     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) ||
3971         (community == NX_NULL) || (enterprise == NX_NULL) || (ip_address == NX_NULL))
3972         return(NX_PTR_ERROR);
3973 
3974     /* Call actual service.  */
3975     status =  _nxd_snmp_agent_trap_send(agent_ptr, ip_address, community, enterprise, trap_type, trap_code, elapsed_time, object_list_ptr);
3976 
3977     /* Return status.  */
3978     return(status);
3979 }
3980 
3981 
3982 /**************************************************************************/
3983 /*                                                                        */
3984 /*  FUNCTION                                               RELEASE        */
3985 /*                                                                        */
3986 /*    _nxd_snmp_agent_trap_send                           PORTABLE C      */
3987 /*                                                           6.1.6        */
3988 /*  AUTHOR                                                                */
3989 /*                                                                        */
3990 /*    Yuxin Zhou, Microsoft Corporation                                   */
3991 /*                                                                        */
3992 /*  DESCRIPTION                                                           */
3993 /*                                                                        */
3994 /*    This function builds and sends a SNMP v1 trap message to the input  */
3995 /*    destination address.  This service supports both IPv4 and IPv6      */
3996 /*    addresses.                                                          */
3997 /*                                                                        */
3998 /*    Note: The string length of community and enterprise are limited by  */
3999 /*    the packet payload and NX_SNMP_MAX_USER_NAME.                       */
4000 /*                                                                        */
4001 /*  INPUT                                                                 */
4002 /*                                                                        */
4003 /*    agent_ptr                             Pointer to SNMP agent         */
4004 /*    ip_address                            Destination IP address        */
4005 /*    community                             Community string              */
4006 /*    enterprise                            Identifies the device that is */
4007 /*                                            generating the trap         */
4008 /*    trap_type                             Type of trap                  */
4009 /*    trap_code                             Additional trap information   */
4010 /*    elapsed_time                          Elapsed time from last boot   */
4011 /*                                            of the device (sysUpTime)   */
4012 /*    object_list_ptr                       Variable list of application  */
4013 /*                                            objects to present with the */
4014 /*                                            trap                        */
4015 /*                                                                        */
4016 /*  OUTPUT                                                                */
4017 /*                                                                        */
4018 /*    status                                Completion status             */
4019 /*                                                                        */
4020 /*  CALLS                                                                 */
4021 /*                                                                        */
4022 /*    nx_packet_allocate                    Allocate SNMP trap packet     */
4023 /*    nx_packet_release                     Release SNMP packet           */
4024 /*    nx_udp_socket_send                    Send SNMP trap via UDP        */
4025 /*    _nx_snmp_object_copy                  Copy object                   */
4026 /*    _nx_snmp_utility_community_set        Set the community name        */
4027 /*    _nx_snmp_utility_object_data_set      Set the data value            */
4028 /*    _nx_snmp_utility_object_id_set        Set the object ID             */
4029 /*    _nx_snmp_utility_sequence_set         Set the ASN.1 sequence        */
4030 /*    _nx_snmp_utility_request_type_set_multibyte                         */
4031 /*                                          Set trap request type         */
4032 /*    _nx_snmp_utility_version_set          Set the SNMP v1               */
4033 /*                                                                        */
4034 /*  CALLED BY                                                             */
4035 /*                                                                        */
4036 /*    Application Code                                                    */
4037 /*                                                                        */
4038 /*  RELEASE HISTORY                                                       */
4039 /*                                                                        */
4040 /*    DATE              NAME                      DESCRIPTION             */
4041 /*                                                                        */
4042 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4043 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4044 /*                                            resulting in version 6.1    */
4045 /*  04-02-2021     Yuxin Zhou               Modified comment(s),          */
4046 /*                                            checked the interface index,*/
4047 /*                                            resulting in version 6.1.6  */
4048 /*                                                                        */
4049 /**************************************************************************/
_nxd_snmp_agent_trap_send(NX_SNMP_AGENT * agent_ptr,NXD_ADDRESS * ip_address,UCHAR * community,UCHAR * enterprise,UINT trap_type,UINT trap_code,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)4050 UINT  _nxd_snmp_agent_trap_send(NX_SNMP_AGENT *agent_ptr, NXD_ADDRESS *ip_address, UCHAR *community, UCHAR *enterprise,
4051                                UINT trap_type, UINT trap_code, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
4052 {
4053 
4054 UINT                 status;
4055 UINT                 trap_length;
4056 UCHAR                *trap_object_ptr;
4057 NX_SNMP_OBJECT_DATA  *trap_object_data_ptr = NX_NULL;
4058 NX_SNMP_OBJECT_DATA  trap_object_data;
4059 NX_PACKET            *trap_packet_ptr;
4060 UCHAR                *trap_buffer_ptr, *trap_sequence_ptr, *trap_type_ptr, *trap_variable_list_ptr, *trap_variable_ptr;
4061 UINT                 trap_sequence_length, trap_type_length, trap_variable_list_length, trap_variable_length;
4062 UINT                 packet_type;
4063 
4064 
4065     /* Verify V1 is currently enabled for this agent. */
4066     if (agent_ptr -> nx_snmp_agent_v1_enabled == NX_FALSE)
4067     {
4068 
4069         return NX_NOT_ENABLED;
4070     }
4071 
4072     /* Now prepare trap message so we can process the variables one by one.  */
4073 
4074 
4075     /* Determine which packet type we allocate based on the destination address type.  */
4076     if (ip_address -> nxd_ip_version == NX_IP_VERSION_V4)
4077     {
4078         packet_type = NX_IPv4_UDP_PACKET;
4079     }
4080     else if (ip_address -> nxd_ip_version == NX_IP_VERSION_V6)
4081     {
4082 
4083 #ifndef FEATURE_NX_IPV6
4084         return NX_SNMP_INVALID_IP_PROTOCOL_ERROR;
4085 #else
4086         packet_type = NX_IPv6_UDP_PACKET;
4087 #endif  /* FEATURE_NX_IPV6 */
4088     }
4089     else
4090     {
4091         return NX_SNMP_INVALID_IP_PROTOCOL_ERROR;
4092     }
4093 
4094     status =  nx_packet_allocate(agent_ptr -> nx_snmp_agent_packet_pool_ptr, &trap_packet_ptr, packet_type, NX_SNMP_AGENT_TIMEOUT);
4095 
4096     /* Determine if a trap packet was allocated.  */
4097     if (status)
4098     {
4099 
4100         /* Increment the packet allocation error counter.  */
4101         agent_ptr -> nx_snmp_agent_allocation_errors++;
4102 
4103         /* Return to caller.  */
4104         return(NX_SNMP_ERROR);
4105     }
4106 
4107     memset(trap_packet_ptr -> nx_packet_prepend_ptr, 0,
4108            (UINT)(trap_packet_ptr -> nx_packet_data_end - trap_packet_ptr -> nx_packet_prepend_ptr));
4109 
4110     /* Initialize the counters required for the length fields of the trap packet.  */
4111     trap_sequence_length =       0;
4112     trap_type_length =           0;
4113     trap_variable_list_length =  0;
4114 
4115     /* Setup a pointer to the trap packet's buffer area.  */
4116     trap_buffer_ptr =  trap_packet_ptr -> nx_packet_prepend_ptr;
4117 
4118     /* This is also the trap sequence pointer. Remember it since we are going to have to
4119        update it later with the actual length of the trap.  */
4120     trap_sequence_ptr =  trap_buffer_ptr;
4121 
4122     /* First, write the sequence in the trap packet.  A zero is written for now.  This will be
4123        updated later.  */
4124     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
4125 
4126     /* Check for a valid operation.  */
4127     if (trap_length == 0)
4128     {
4129 
4130         /* Increment the internal error counter.  */
4131         agent_ptr -> nx_snmp_agent_internal_errors++;
4132 
4133         /* Release the trap packet too.  */
4134         nx_packet_release(trap_packet_ptr);
4135 
4136         /* Return to caller.  */
4137         return(NX_SNMP_ERROR);
4138     }
4139 
4140     /* Move the trap buffer pointer up.  */
4141     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4142 
4143     /* Now set the Version ID in the trap message.  */
4144     trap_length =  _nx_snmp_utility_version_set(trap_buffer_ptr, NX_SNMP_VERSION_1, trap_packet_ptr -> nx_packet_data_end);
4145 
4146     /* Check for a valid operation.  */
4147     if (trap_length == 0)
4148     {
4149 
4150         /* Increment the internal error counter.  */
4151         agent_ptr -> nx_snmp_agent_internal_errors++;
4152 
4153         /* Release the trap packet.  */
4154         nx_packet_release(trap_packet_ptr);
4155 
4156         /* Return to caller.  */
4157         return(NX_SNMP_ERROR);
4158     }
4159 
4160     /* Move the trap buffer pointer up.  */
4161     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4162 
4163     /* Adjust the trap sequence length.  */
4164     trap_sequence_length =  trap_sequence_length + trap_length;
4165 
4166     /* Now set the community in the trap message.  */
4167     trap_length =  _nx_snmp_utility_community_set(trap_buffer_ptr, community, trap_packet_ptr -> nx_packet_data_end);
4168 
4169     /* Check for a valid operation.  */
4170     if (trap_length == 0)
4171     {
4172 
4173         /* Increment the internal error counter.  */
4174         agent_ptr -> nx_snmp_agent_internal_errors++;
4175 
4176         /* Release the trap packet.  */
4177         nx_packet_release(trap_packet_ptr);
4178 
4179         /* Return to caller.  */
4180         return(NX_SNMP_ERROR);
4181     }
4182 
4183     /* Move the trap buffer pointer up.  */
4184     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4185 
4186     /* Adjust the trap sequence length.  */
4187     trap_sequence_length =  trap_sequence_length + trap_length;
4188 
4189     /* Remember the request type pointer, since it will need to be updated later.  */
4190     trap_type_ptr =  trap_buffer_ptr;
4191 
4192     /* Now set the request type in the trap message.  */
4193     trap_length =  _nx_snmp_utility_request_type_set_multibyte(trap_buffer_ptr, NX_SNMP_ANS1_TRAP_REQUEST, 0, trap_packet_ptr -> nx_packet_data_end);
4194 
4195     /* Check for a valid operation.  */
4196     if (trap_length == 0)
4197     {
4198 
4199         /* Increment the internal error counter.  */
4200         agent_ptr -> nx_snmp_agent_internal_errors++;
4201 
4202         /* Release the trap packet.  */
4203         nx_packet_release(trap_packet_ptr);
4204 
4205         /* Return to caller.  */
4206         return(NX_SNMP_ERROR);
4207     }
4208 
4209     /* Move the trap buffer pointer up.  */
4210     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4211 
4212     /* Adjust the trap sequence length.  */
4213     trap_sequence_length =  trap_sequence_length + trap_length;
4214 
4215     /* Now set the enterprise ID in the trap message.  */
4216     trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, enterprise, trap_packet_ptr -> nx_packet_data_end);
4217 
4218     /* Check for a valid operation.  */
4219     if (trap_length == 0)
4220     {
4221 
4222         /* Increment the internal error counter.  */
4223         agent_ptr -> nx_snmp_agent_internal_errors++;
4224 
4225         /* Release the trap packet too.  */
4226         nx_packet_release(trap_packet_ptr);
4227 
4228         /* Return to caller.  */
4229         return(NX_SNMP_ERROR);
4230     }
4231 
4232     /* Move the trap buffer pointer up.  */
4233     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4234 
4235     /* Adjust the trap sequence length.  */
4236     trap_sequence_length =  trap_sequence_length + trap_length;
4237 
4238     /* Adjust the trap request type length.  */
4239     trap_type_length =  trap_type_length + trap_length;
4240 
4241     /* Set the agent's IP address.  */
4242     trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_IP_ADDRESS;
4243 
4244 
4245 #ifndef NX_DISABLE_IPV4
4246 
4247     /* Check if the interface index is valid.  */
4248     if (agent_ptr -> nx_snmp_agent_interface_index >= NX_MAX_PHYSICAL_INTERFACES)
4249     {
4250 
4251         /* Increment the internal error counter.  */
4252         agent_ptr -> nx_snmp_agent_internal_errors++;
4253 
4254         /* Release the trap packet.  */
4255         nx_packet_release(trap_packet_ptr);
4256 
4257         /* Return to caller.  */
4258         return(NX_SNMP_ERROR);
4259     }
4260 
4261     trap_object_data.nx_snmp_object_data_msw =
4262         (LONG)(agent_ptr -> nx_snmp_agent_ip_ptr) -> nx_ip_interface[agent_ptr -> nx_snmp_agent_interface_index].nx_interface_ip_address;
4263 #else
4264     trap_object_data.nx_snmp_object_data_msw = 0;
4265 #endif /* NX_DISABLE_IPV4 */
4266 
4267     trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
4268 
4269     /* Check for a valid operation.  */
4270     if (trap_length == 0)
4271     {
4272 
4273         /* Increment the internal error counter.  */
4274         agent_ptr -> nx_snmp_agent_internal_errors++;
4275 
4276         /* Release the trap packet.  */
4277         nx_packet_release(trap_packet_ptr);
4278 
4279         /* Return to caller.  */
4280         return(NX_SNMP_ERROR);
4281     }
4282 
4283     /* Move the trap buffer pointer up.  */
4284     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4285 
4286     /* Adjust the trap sequence length.  */
4287     trap_sequence_length =  trap_sequence_length + trap_length;
4288 
4289     /* Adjust the trap request type length.  */
4290     trap_type_length =  trap_type_length + trap_length;
4291 
4292     /* Check that we have a valid trap type requested.  */
4293     if (trap_type > TRAP_ID_MAX)
4294     {
4295 
4296         /* Increment the internal error counter.  */
4297         agent_ptr -> nx_snmp_agent_internal_errors++;
4298 
4299         /* Release the trap packet.  */
4300         nx_packet_release(trap_packet_ptr);
4301 
4302         /* Return to caller.  */
4303         return(NX_SNMP_ERROR);
4304     }
4305 
4306     /* Set the trap type.  */
4307     trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_INTEGER;
4308     trap_object_data.nx_snmp_object_data_msw =   (LONG)trap_type;
4309     trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
4310 
4311     if (trap_length == 0)
4312     {
4313         /* Increment the internal error counter.  */
4314         agent_ptr -> nx_snmp_agent_internal_errors++;
4315 
4316         /* Release the trap packet.  */
4317         nx_packet_release(trap_packet_ptr);
4318 
4319         /* Return to caller.  */
4320         return(NX_SNMP_ERROR);
4321     }
4322 
4323     /* Move the trap buffer pointer up.  */
4324     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4325 
4326     /* Adjust the trap sequence length.  */
4327     trap_sequence_length =  trap_sequence_length + trap_length;
4328 
4329     /* Adjust the trap request type length.  */
4330     trap_type_length =  trap_type_length + trap_length;
4331 
4332     /* Set the specific trap type.  */
4333     trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_INTEGER;
4334     trap_object_data.nx_snmp_object_data_msw =   (LONG)trap_code;
4335     trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
4336 
4337     /* Check for a valid operation.  */
4338     if (trap_length == 0)
4339     {
4340 
4341         /* Increment the internal error counter.  */
4342         agent_ptr -> nx_snmp_agent_internal_errors++;
4343 
4344         /* Release the trap packet.  */
4345         nx_packet_release(trap_packet_ptr);
4346 
4347         /* Return to caller.  */
4348         return(NX_SNMP_ERROR);
4349     }
4350 
4351     /* Move the trap buffer pointer up.  */
4352     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4353 
4354     /* Adjust the trap sequence length.  */
4355     trap_sequence_length =  trap_sequence_length + trap_length;
4356 
4357     /* Adjust the trap request type length.  */
4358     trap_type_length =  trap_type_length + trap_length;
4359 
4360     /* Set the specific time-stamp.  */
4361     trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_TIME_TICS;
4362     trap_object_data.nx_snmp_object_data_msw =   (LONG)elapsed_time;
4363     trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
4364 
4365     /* Check for a valid operation.  */
4366     if (trap_length == 0)
4367     {
4368 
4369         /* Increment the internal error counter.  */
4370         agent_ptr -> nx_snmp_agent_internal_errors++;
4371 
4372         /* Release the trap packet.  */
4373         nx_packet_release(trap_packet_ptr);
4374 
4375         /* Return to caller.  */
4376         return(NX_SNMP_ERROR);
4377     }
4378 
4379     /* Move the trap buffer pointer up.  */
4380     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4381 
4382     /* Adjust the trap sequence length.  */
4383     trap_sequence_length =  trap_sequence_length + trap_length;
4384 
4385     /* Adjust the trap request type length.  */
4386     trap_type_length =  trap_type_length + trap_length;
4387 
4388     /* Remember the start of the trap's variable list field.  */
4389     trap_variable_list_ptr =  trap_buffer_ptr;
4390 
4391     /* Set up the variable list.  For now, the length will be zero.  We
4392        will overwrite this with the actual length later.  */
4393     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
4394 
4395     /* Check for a valid operation.  */
4396     if (trap_length == 0)
4397     {
4398 
4399         /* Increment the internal error counter.  */
4400         agent_ptr -> nx_snmp_agent_internal_errors++;
4401 
4402         /* Release the trap packet too.  */
4403         nx_packet_release(trap_packet_ptr);
4404 
4405         /* Return to caller.  */
4406         return(NX_SNMP_ERROR);
4407     }
4408 
4409     /* Move the trap buffer pointer up.  */
4410     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4411 
4412     /* Adjust the trap sequence length.  */
4413     trap_sequence_length =  trap_sequence_length + trap_length;
4414 
4415     /* Adjust the trap request type length.  */
4416     trap_type_length =  trap_type_length + trap_length;
4417 
4418     /* Default the object pointer to NULL.  */
4419     trap_object_ptr =  NX_NULL;
4420 
4421     /* Determine if an object is specified.  */
4422     if (object_list_ptr)
4423     {
4424 
4425         /* Setup object pointers from the supplied object list.  */
4426         trap_object_ptr =       object_list_ptr -> nx_snmp_object_string_ptr;
4427         trap_object_data_ptr =  object_list_ptr -> nx_snmp_object_data;
4428 
4429         /* Check for a valid operation.  */
4430         if(trap_object_ptr != NX_NULL && trap_object_data_ptr == NX_NULL)
4431         {
4432             /* Release the trap packet.  */
4433             nx_packet_release(trap_packet_ptr);
4434 
4435             /* Done, return to caller.  */
4436             return(NX_SNMP_ERROR);
4437         }
4438     }
4439 
4440     /* Loop to process all the objects in the list.  */
4441     while (trap_object_ptr)
4442     {
4443 
4444         /* Clear the trap variable length.  */
4445         trap_variable_length =  0;
4446 
4447         /* Remember the start of the variable.  */
4448         trap_variable_ptr =  trap_buffer_ptr;
4449 
4450         /* Setup the variable trap sequence.  For now, the length will be zero.  We
4451            will overwrite this with the actual length later.  */
4452         trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
4453 
4454         /* Check for a valid operation.  */
4455         if (trap_length == 0)
4456         {
4457 
4458             /* Increment the internal error counter.  */
4459             agent_ptr -> nx_snmp_agent_internal_errors++;
4460 
4461             /* Release the trap packet too.  */
4462             nx_packet_release(trap_packet_ptr);
4463 
4464             /* Return to caller.  */
4465             return(NX_SNMP_ERROR);
4466         }
4467 
4468         /* Move the trap buffer pointer up.  */
4469         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4470 
4471         /* Adjust the trap sequence length.  */
4472         trap_sequence_length =  trap_sequence_length + trap_length;
4473 
4474         /* Adjust the trap request type length.  */
4475         trap_type_length =  trap_type_length + trap_length;
4476 
4477         /* Adjust the trap variable list size.  */
4478         trap_variable_list_length =  trap_variable_list_length + trap_length;
4479 
4480         /* Place the object into the trap buffer.  */
4481         trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, trap_object_ptr, trap_packet_ptr -> nx_packet_data_end);
4482 
4483         /* Check for a valid operation.  */
4484         if (trap_length == 0)
4485         {
4486 
4487             /* Release the trap packet.  */
4488             nx_packet_release(trap_packet_ptr);
4489 
4490             /* Done, return to caller.  */
4491             return(NX_SNMP_ERROR);
4492         }
4493 
4494         /* Move the trap buffer pointer up.  */
4495         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4496 
4497         /* Adjust the trap sequence length.  */
4498         trap_sequence_length =  trap_sequence_length + trap_length;
4499 
4500         /* Adjust the trap request type length.  */
4501         trap_type_length =  trap_type_length + trap_length;
4502 
4503         /* Adjust the trap variable list size.  */
4504         trap_variable_list_length =  trap_variable_list_length + trap_length;
4505 
4506         /* Adjust the trap variable size.  */
4507         trap_variable_length =  trap_variable_length + trap_length;
4508 
4509         /* Insert the object's data into the trap buffer.  */
4510         trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, trap_object_data_ptr, trap_packet_ptr -> nx_packet_data_end);
4511 
4512         /* Check for a valid operation.  */
4513         if (trap_length == 0)
4514         {
4515 
4516             /* Release the trap packet.  */
4517             nx_packet_release(trap_packet_ptr);
4518 
4519             /* Done, return to caller.  */
4520             return(NX_SNMP_ERROR);
4521         }
4522 
4523         /* Move the trap buffer pointer up.  */
4524         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
4525 
4526         /* Adjust the trap sequence length.  */
4527         trap_sequence_length =  trap_sequence_length + trap_length;
4528 
4529         /* Adjust the trap request type length.  */
4530         trap_type_length =  trap_type_length + trap_length;
4531 
4532         /* Adjust the trap variable list size.  */
4533         trap_variable_list_length =  trap_variable_list_length + trap_length;
4534 
4535         /* Adjust the trap variable size.  */
4536         trap_variable_length =  trap_variable_length + trap_length;
4537 
4538         /* Now update the trap variable sequence with the actual variable length.  */
4539         _nx_snmp_utility_sequence_set(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
4540 
4541         /* Default the object pointer to NULL.  */
4542         trap_object_ptr =  NX_NULL;
4543 
4544         /* Determine if there are more objects to insert into the trap message.  */
4545         if (object_list_ptr)
4546         {
4547 
4548             /* Move to the next object in the list.  */
4549             object_list_ptr++;
4550 
4551             if (object_list_ptr == NX_NULL)
4552             {
4553 
4554                 /* Release the trap packet.  */
4555                 nx_packet_release(trap_packet_ptr);
4556 
4557                 /* Done, return to caller.  */
4558                 return(NX_SNMP_ERROR);
4559             }
4560 
4561             /* Determine if there is another object.  */
4562             if (object_list_ptr -> nx_snmp_object_string_ptr)
4563             {
4564 
4565                 /* Setup the object and object data pointers.  */
4566                 trap_object_ptr =       object_list_ptr -> nx_snmp_object_string_ptr;
4567                 trap_object_data_ptr =  object_list_ptr -> nx_snmp_object_data;
4568 
4569                 /* Check for a valid operation.  */
4570                 if(trap_object_ptr != NX_NULL && trap_object_data_ptr == NX_NULL)
4571                 {
4572                     /* Release the trap packet.  */
4573                     nx_packet_release(trap_packet_ptr);
4574 
4575                     /* Done, return to caller.  */
4576                     return(NX_SNMP_ERROR);
4577                 }
4578             }
4579         }
4580     }
4581 
4582     /* At this point, several trap fields need to be updated with actual lengths.  */
4583     _nx_snmp_utility_sequence_set(trap_sequence_ptr, trap_sequence_length, trap_packet_ptr -> nx_packet_data_end);
4584     _nx_snmp_utility_sequence_set(trap_variable_list_ptr, trap_variable_list_length, trap_packet_ptr -> nx_packet_data_end);
4585     _nx_snmp_utility_request_type_set_multibyte(trap_type_ptr, NX_SNMP_ANS1_TRAP_REQUEST, trap_type_length, trap_packet_ptr -> nx_packet_data_end);
4586 
4587     /* Now the trap packet's pointers must be setup so it can be sent.  */
4588     trap_packet_ptr -> nx_packet_length =  (ULONG)(trap_buffer_ptr - trap_packet_ptr -> nx_packet_prepend_ptr);
4589     trap_packet_ptr -> nx_packet_append_ptr =  trap_buffer_ptr;
4590 
4591     /* Update various statistics.  */
4592     agent_ptr -> nx_snmp_agent_traps_sent++;
4593     agent_ptr -> nx_snmp_agent_packets_sent++;
4594 
4595     /* Send the trap packet back to the requesting SNMP manager.  */
4596     status = nxd_udp_socket_send(&(agent_ptr -> nx_snmp_agent_socket), trap_packet_ptr,
4597                                                 ip_address, NX_SNMP_MANAGER_TRAP_PORT);
4598 
4599     /* Determine if the packet needs to be released. */
4600     if (status)
4601     {
4602 
4603         /* Release packet.  */
4604         nx_packet_release(trap_packet_ptr);
4605     }
4606 
4607     /* Return completion status.  */
4608     return(status);
4609 }
4610 #endif /* NX_SNMP_DISABLE_V1 */
4611 
4612 
4613 #ifndef NX_SNMP_DISABLE_V2
4614 /**************************************************************************/
4615 /*                                                                        */
4616 /*  FUNCTION                                               RELEASE        */
4617 /*                                                                        */
4618 /*    _nxe_snmp_agent_trapv2_send                         PORTABLE C      */
4619 /*                                                           6.1          */
4620 /*  AUTHOR                                                                */
4621 /*                                                                        */
4622 /*    Yuxin Zhou, Microsoft Corporation                                   */
4623 /*                                                                        */
4624 /*  DESCRIPTION                                                           */
4625 /*                                                                        */
4626 /*    This function checks for errors in the SNMPv2 trap send service.    */
4627 /*                                                                        */
4628 /*    Developers are encouraged to use the nxd_snmp_agent_trapv2_send     */
4629 /*    service which supports IPv4 and IPv6 types.                         */
4630 /*                                                                        */
4631 /*  INPUT                                                                 */
4632 /*                                                                        */
4633 /*    agent_ptr                             Pointer to SNMP agent         */
4634 /*    ip_address                            Destination IPv4 address      */
4635 /*    community                             Community name                */
4636 /*    trap_type                             Type of trap                  */
4637 /*    elapsed_time                          Elapsed time from last boot   */
4638 /*                                            of the device (sysUpTime)   */
4639 /*    object_list_ptr                       Variable list of application  */
4640 /*                                            objects to present with the */
4641 /*                                            trap                        */
4642 /*                                                                        */
4643 /*  OUTPUT                                                                */
4644 /*                                                                        */
4645 /*    status                                Completion status             */
4646 /*                                                                        */
4647 /*  CALLS                                                                 */
4648 /*                                                                        */
4649 /*    _nx_snmp_agent_trapv2_send            Actual NetX (IPv4) SNMP trap  */
4650 /*                                            send service                */
4651 /*                                                                        */
4652 /*  CALLED BY                                                             */
4653 /*                                                                        */
4654 /*    Application Code                                                    */
4655 /*                                                                        */
4656 /*  RELEASE HISTORY                                                       */
4657 /*                                                                        */
4658 /*    DATE              NAME                      DESCRIPTION             */
4659 /*                                                                        */
4660 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4661 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4662 /*                                            resulting in version 6.1    */
4663 /*                                                                        */
4664 /**************************************************************************/
_nxe_snmp_agent_trapv2_send(NX_SNMP_AGENT * agent_ptr,ULONG ip_address,UCHAR * community,UINT trap_type,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)4665 UINT  _nxe_snmp_agent_trapv2_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *community, UINT trap_type, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
4666 {
4667 
4668 #ifndef NX_DISABLE_IPV4
4669 UINT    status;
4670 
4671 
4672     /* Check for invalid input pointers.  */
4673     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) ||
4674         (community == NX_NULL) || (ip_address == 0))
4675         return(NX_PTR_ERROR);
4676 
4677     /* Call actual netx service.  */
4678     status =  _nx_snmp_agent_trapv2_send(agent_ptr, ip_address, community, trap_type, elapsed_time, object_list_ptr);
4679 
4680     /* Return status.  */
4681     return(status);
4682 #else
4683     NX_PARAMETER_NOT_USED(agent_ptr);
4684     NX_PARAMETER_NOT_USED(ip_address);
4685     NX_PARAMETER_NOT_USED(community);
4686     NX_PARAMETER_NOT_USED(trap_type);
4687     NX_PARAMETER_NOT_USED(elapsed_time);
4688     NX_PARAMETER_NOT_USED(object_list_ptr);
4689 
4690     return(NX_NOT_SUPPORTED);
4691 #endif /* NX_DISABLE_IPV4 */
4692 }
4693 
4694 
4695 /**************************************************************************/
4696 /*                                                                        */
4697 /*  FUNCTION                                               RELEASE        */
4698 /*                                                                        */
4699 /*    _nx_snmp_agent_trapv2_send                          PORTABLE C      */
4700 /*                                                           6.1          */
4701 /*  AUTHOR                                                                */
4702 /*                                                                        */
4703 /*    Yuxin Zhou, Microsoft Corporation                                   */
4704 /*                                                                        */
4705 /*  DESCRIPTION                                                           */
4706 /*                                                                        */
4707 /*    This function stores the input IPv4 destination IP address in a NetX*/
4708 /*    Duo data type that supports IPv4 and IPv6 address formats, and      */
4709 /*    uses the 'dual' trap send service _nxd_snmp_agent_trap_send to build*/
4710 /*    and send the SNMPv2 trap message.                                   */
4711 /*                                                                        */
4712 /*    Developers are encouraged to use nxd_snmp_agent_trapv2_send.        */
4713 /*                                                                        */
4714 /*  INPUT                                                                 */
4715 /*                                                                        */
4716 /*    agent_ptr                             Pointer to SNMP agent         */
4717 /*    ip_address                            Destination IPv4 address      */
4718 /*    community                             Community name                */
4719 /*    trap_type                             Type of trap                  */
4720 /*    elapsed_time                          Elapsed time from last boot   */
4721 /*                                            of the device (sysUpTime)   */
4722 /*    object_list_ptr                       Variable list of application  */
4723 /*                                            objects to present with the */
4724 /*                                            trap                        */
4725 /*                                                                        */
4726 /*  OUTPUT                                                                */
4727 /*                                                                        */
4728 /*    status                                Completion status             */
4729 /*    NX_NOT_ENABLED                        Agent not enabled for V2      */
4730 /*                                                                        */
4731 /*  CALLS                                                                 */
4732 /*                                                                        */
4733 /*    _nxd_snmp_agent_trapv2_send           Actual NetX Duo SNMP trap     */
4734 /*                                             send service               */
4735 /*                                                                        */
4736 /*  CALLED BY                                                             */
4737 /*                                                                        */
4738 /*    Application Code                                                    */
4739 /*                                                                        */
4740 /*  RELEASE HISTORY                                                       */
4741 /*                                                                        */
4742 /*    DATE              NAME                      DESCRIPTION             */
4743 /*                                                                        */
4744 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4745 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4746 /*                                            resulting in version 6.1    */
4747 /*                                                                        */
4748 /**************************************************************************/
_nx_snmp_agent_trapv2_send(NX_SNMP_AGENT * agent_ptr,ULONG ip_address,UCHAR * community,UINT trap_type,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)4749 UINT  _nx_snmp_agent_trapv2_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *community, UINT trap_type, ULONG elapsed_time,
4750                                  NX_SNMP_TRAP_OBJECT *object_list_ptr)
4751 {
4752 
4753 #ifndef NX_DISABLE_IPV4
4754 UINT        status;
4755 NXD_ADDRESS ip_nxduo_address;
4756 
4757 
4758     ip_nxduo_address.nxd_ip_version = NX_IP_VERSION_V4;
4759     ip_nxduo_address.nxd_ip_address.v4 = ip_address;
4760 
4761     status =  _nxd_snmp_agent_trapv2_send(agent_ptr, &ip_nxduo_address, community, trap_type, elapsed_time, object_list_ptr);
4762 
4763     return status;
4764 #else
4765     NX_PARAMETER_NOT_USED(agent_ptr);
4766     NX_PARAMETER_NOT_USED(ip_address);
4767     NX_PARAMETER_NOT_USED(community);
4768     NX_PARAMETER_NOT_USED(trap_type);
4769     NX_PARAMETER_NOT_USED(elapsed_time);
4770     NX_PARAMETER_NOT_USED(object_list_ptr);
4771 
4772     return(NX_NOT_SUPPORTED);
4773 #endif /* NX_DISABLE_IPV4 */
4774 }
4775 
4776 
4777 /**************************************************************************/
4778 /*                                                                        */
4779 /*  FUNCTION                                               RELEASE        */
4780 /*                                                                        */
4781 /*    _nxde_snmp_agent_trapv2_send                        PORTABLE C      */
4782 /*                                                           6.1          */
4783 /*  AUTHOR                                                                */
4784 /*                                                                        */
4785 /*    Yuxin Zhou, Microsoft Corporation                                   */
4786 /*                                                                        */
4787 /*  DESCRIPTION                                                           */
4788 /*                                                                        */
4789 /*    This function checks for errors in the SNMPv2 trap send service.    */
4790 /*                                                                        */
4791 /*  INPUT                                                                 */
4792 /*                                                                        */
4793 /*    agent_ptr                             Pointer to SNMP agent         */
4794 /*    ip_address                            Destination IP address        */
4795 /*    community                             Community name                */
4796 /*    trap_type                             Type of trap                  */
4797 /*    elapsed_time                          Elapsed time from last boot   */
4798 /*                                            of the device (sysUpTime)   */
4799 /*    object_list_ptr                       Variable list of application  */
4800 /*                                            objects to present with the */
4801 /*                                            trap                        */
4802 /*                                                                        */
4803 /*  OUTPUT                                                                */
4804 /*                                                                        */
4805 /*    status                                Completion status             */
4806 /*                                                                        */
4807 /*  CALLS                                                                 */
4808 /*                                                                        */
4809 /*    _nxd_snmp_agent_trapv2_send           Actual SNMPv2 trap send       */
4810 /*                                            service                     */
4811 /*                                                                        */
4812 /*  CALLED BY                                                             */
4813 /*                                                                        */
4814 /*    Application Code                                                    */
4815 /*                                                                        */
4816 /*  RELEASE HISTORY                                                       */
4817 /*                                                                        */
4818 /*    DATE              NAME                      DESCRIPTION             */
4819 /*                                                                        */
4820 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4821 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4822 /*                                            resulting in version 6.1    */
4823 /*                                                                        */
4824 /**************************************************************************/
_nxde_snmp_agent_trapv2_send(NX_SNMP_AGENT * agent_ptr,NXD_ADDRESS * ip_address,UCHAR * community,UINT trap_type,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)4825 UINT  _nxde_snmp_agent_trapv2_send(NX_SNMP_AGENT *agent_ptr, NXD_ADDRESS *ip_address, UCHAR *community, UINT trap_type, ULONG elapsed_time,
4826                                    NX_SNMP_TRAP_OBJECT *object_list_ptr)
4827 {
4828 
4829 UINT    status;
4830 
4831 
4832     /* Check for invalid input pointers.  */
4833     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) ||
4834         (community == NX_NULL) || (ip_address == NX_NULL))
4835         return(NX_PTR_ERROR);
4836 
4837     /* Call actual service.  */
4838     status =  _nxd_snmp_agent_trapv2_send(agent_ptr, ip_address, community, trap_type, elapsed_time, object_list_ptr);
4839 
4840     /* Return status.  */
4841     return(status);
4842 }
4843 
4844 
4845 /**************************************************************************/
4846 /*                                                                        */
4847 /*  FUNCTION                                               RELEASE        */
4848 /*                                                                        */
4849 /*    _nxd_snmp_agent_trapv2_send                         PORTABLE C      */
4850 /*                                                           6.1          */
4851 /*  AUTHOR                                                                */
4852 /*                                                                        */
4853 /*    Yuxin Zhou, Microsoft Corporation                                   */
4854 /*                                                                        */
4855 /*  DESCRIPTION                                                           */
4856 /*                                                                        */
4857 /*    This function builds and sends a SNMPv2 trap message to the input   */
4858 /*    destination address.  This service supports both IPv4 and IPv6      */
4859 /*    addresses.                                                          */
4860 /*                                                                        */
4861 /*    Note: The string length of community is limited by the packet       */
4862 /*    payload and NX_SNMP_MAX_USER_NAME.                                  */
4863 /*                                                                        */
4864 /*  INPUT                                                                 */
4865 /*                                                                        */
4866 /*    agent_ptr                             Pointer to SNMP agent         */
4867 /*    ip_address                            Destination IP address        */
4868 /*    community                             Community name                */
4869 /*    trap_type                             Type of trap                  */
4870 /*    elapsed_time                          Elapsed time from last boot   */
4871 /*                                            of the device (sysUpTime)   */
4872 /*    object_list_ptr                       Variable list of application  */
4873 /*                                            objects to present with the */
4874 /*                                            trap                        */
4875 /*                                                                        */
4876 /*  OUTPUT                                                                */
4877 /*                                                                        */
4878 /*    status                                Completion status             */
4879 /*                                                                        */
4880 /*  CALLS                                                                 */
4881 /*                                                                        */
4882 /*    nx_packet_allocate                    Allocate SNMP trap packet     */
4883 /*    nx_packet_release                     Release SNMP packet           */
4884 /*    nx_udp_socket_send                    Send SNMP trap via UDP        */
4885 /*    _nx_snmp_object_copy                  Copy object                   */
4886 /*    _nx_snmp_utility_community_set        Set the community name        */
4887 /*    _nx_snmp_utility_error_info_set       Set error information         */
4888 /*    _nx_snmp_utility_object_data_set      Set the data value            */
4889 /*    _nx_snmp_utility_object_id_set        Set the object ID             */
4890 /*    _nx_snmp_utility_sequence_set         Set the ASN.1 sequence        */
4891 /*    _nx_snmp_utility_request_id_set       Set the Trap ID               */
4892 /*    _nx_snmp_utility_request_type_set_multibyte                         */
4893 /*                                          Set trap request type         */
4894 /*    _nx_snmp_utility_version_set          Set the SNMP v1               */
4895 /*                                                                        */
4896 /*  CALLED BY                                                             */
4897 /*                                                                        */
4898 /*    Application Code                                                    */
4899 /*                                                                        */
4900 /*  RELEASE HISTORY                                                       */
4901 /*                                                                        */
4902 /*    DATE              NAME                      DESCRIPTION             */
4903 /*                                                                        */
4904 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4905 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4906 /*                                            resulting in version 6.1    */
4907 /*                                                                        */
4908 /**************************************************************************/
_nxd_snmp_agent_trapv2_send(NX_SNMP_AGENT * agent_ptr,NXD_ADDRESS * ip_address,UCHAR * community,UINT trap_type,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)4909 UINT  _nxd_snmp_agent_trapv2_send(NX_SNMP_AGENT *agent_ptr, NXD_ADDRESS *ip_address, UCHAR *community, UINT trap_type,
4910                                   ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
4911 {
4912 
4913 UINT                 status;
4914 UINT                 trap_length;
4915 UCHAR                *trap_object_ptr;
4916 NX_SNMP_OBJECT_DATA  trap_object_data;
4917 NX_SNMP_OBJECT_DATA  *trap_object_data_ptr = NX_NULL;
4918 NX_PACKET            *trap_packet_ptr;
4919 UCHAR                *trap_buffer_ptr, *trap_sequence_ptr, *trap_type_ptr, *trap_variable_list_ptr, *trap_variable_ptr;
4920 UINT                 trap_sequence_length, trap_type_length, trap_variable_list_length, trap_variable_length;
4921 UINT                 packet_type;
4922 
4923 
4924     /* Verify V2 is currently enabled for this agent. */
4925     if (agent_ptr -> nx_snmp_agent_v2_enabled == NX_FALSE)
4926     {
4927         return NX_NOT_ENABLED;
4928     }
4929 
4930     /* Determine which packet type we allocate based on the destination address type.  */
4931     if (ip_address -> nxd_ip_version == NX_IP_VERSION_V4)
4932     {
4933         packet_type = NX_IPv4_UDP_PACKET;
4934     }
4935     else if (ip_address -> nxd_ip_version == NX_IP_VERSION_V6)
4936     {
4937 #ifndef FEATURE_NX_IPV6
4938         return NX_SNMP_INVALID_IP_PROTOCOL_ERROR;
4939 #else
4940         packet_type = NX_IPv6_UDP_PACKET;
4941 #endif
4942     }
4943     else
4944     {
4945         return NX_SNMP_INVALID_IP_PROTOCOL_ERROR;
4946     }
4947 
4948 
4949     /* Now prepare trap message so we can process the variables one by one.  */
4950 
4951     /* Allocate the packet for the SNMP v2 trap.  */
4952     status =  nx_packet_allocate(agent_ptr -> nx_snmp_agent_packet_pool_ptr, &trap_packet_ptr, packet_type, NX_SNMP_AGENT_TIMEOUT);
4953 
4954     /* Determine if a trap packet was allocated.  */
4955     if (status)
4956     {
4957 
4958         /* Increment the packet allocation error counter.  */
4959         agent_ptr -> nx_snmp_agent_allocation_errors++;
4960 
4961         /* Return to caller.  */
4962         return(NX_SNMP_ERROR);
4963     }
4964 
4965     memset(trap_packet_ptr -> nx_packet_prepend_ptr, 0,
4966            (UINT)(trap_packet_ptr -> nx_packet_data_end - trap_packet_ptr -> nx_packet_prepend_ptr));
4967 
4968     /* Initialize the counters required for the length fields of the trap packet.  */
4969     trap_sequence_length =       0;
4970     trap_type_length =           0;
4971     trap_variable_list_length =  0;
4972     trap_variable_length =       0;
4973 
4974     /* Setup a pointer to the trap packet's buffer area.  */
4975     trap_buffer_ptr =  trap_packet_ptr -> nx_packet_prepend_ptr;
4976 
4977     /* This is also the trap sequence pointer. Remember it since we are going to have to
4978        update it later with the actual length of the trap.  */
4979     trap_sequence_ptr =  trap_buffer_ptr;
4980 
4981     /* First, write the sequence in the trap packet.  A zero is written for now.  This will be
4982        updated later.  */
4983     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
4984 
4985     /* Check for a valid operation.  */
4986     if (trap_length == 0)
4987     {
4988 
4989         /* Increment the internal error counter.  */
4990         agent_ptr -> nx_snmp_agent_internal_errors++;
4991 
4992         /* Release the trap packet too.  */
4993         nx_packet_release(trap_packet_ptr);
4994 
4995         /* Return to caller.  */
4996         return(NX_SNMP_ERROR);
4997     }
4998 
4999     /* Move the trap buffer pointer up.  */
5000     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5001 
5002     /* Now set the Version ID in the trap message.  */
5003     trap_length =  _nx_snmp_utility_version_set(trap_buffer_ptr, NX_SNMP_VERSION_2C, trap_packet_ptr -> nx_packet_data_end);
5004 
5005     /* Check for a valid operation.  */
5006     if (trap_length == 0)
5007     {
5008 
5009         /* Increment the internal error counter.  */
5010         agent_ptr -> nx_snmp_agent_internal_errors++;
5011 
5012         /* Release the trap packet.  */
5013         nx_packet_release(trap_packet_ptr);
5014 
5015         /* Return to caller.  */
5016         return(NX_SNMP_ERROR);
5017     }
5018 
5019     /* Move the trap buffer pointer up.  */
5020     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5021 
5022     /* Adjust the trap sequence length.  */
5023     trap_sequence_length =  trap_sequence_length + trap_length;
5024 
5025     /* Now set the community in the trap message.  */
5026     trap_length =  _nx_snmp_utility_community_set(trap_buffer_ptr, community, trap_packet_ptr -> nx_packet_data_end);
5027 
5028     /* Check for a valid operation.  */
5029     if (trap_length == 0)
5030     {
5031 
5032         /* Increment the internal error counter.  */
5033         agent_ptr -> nx_snmp_agent_internal_errors++;
5034 
5035         /* Release the trap packet.  */
5036         nx_packet_release(trap_packet_ptr);
5037 
5038         /* Return to caller.  */
5039         return(NX_SNMP_ERROR);
5040     }
5041 
5042     /* Move the trap buffer pointer up.  */
5043     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5044 
5045     /* Adjust the trap sequence length.  */
5046     trap_sequence_length =  trap_sequence_length + trap_length;
5047 
5048     /* Remember the request type pointer, since it will need to be updated later.  */
5049     trap_type_ptr =  trap_buffer_ptr;
5050 
5051     /* Now set the request type in the trap message.  */
5052     trap_length =  _nx_snmp_utility_request_type_set_multibyte(trap_buffer_ptr, NX_SNMP_ANS1_TRAP2_REQUEST, 0, trap_packet_ptr -> nx_packet_data_end);
5053 
5054     /* Check for a valid operation.  */
5055     if (trap_length == 0)
5056     {
5057 
5058         /* Increment the internal error counter.  */
5059         agent_ptr -> nx_snmp_agent_internal_errors++;
5060 
5061         /* Release the trap packet.  */
5062         nx_packet_release(trap_packet_ptr);
5063 
5064         /* Return to caller.  */
5065         return(NX_SNMP_ERROR);
5066     }
5067 
5068     /* Move the trap buffer pointer up.  */
5069     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5070 
5071     /* Adjust the trap sequence length.  */
5072     trap_sequence_length =  trap_sequence_length + trap_length;
5073 
5074     /* Now set the trap ID in the trap message.  */
5075     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_traps_sent, trap_packet_ptr -> nx_packet_data_end);
5076 
5077     /* Check for a valid operation.  */
5078     if (trap_length == 0)
5079     {
5080 
5081         /* Increment the internal error counter.  */
5082         agent_ptr -> nx_snmp_agent_internal_errors++;
5083 
5084         /* Release the trap packet too.  */
5085         nx_packet_release(trap_packet_ptr);
5086 
5087         /* Return to caller.  */
5088         return(NX_SNMP_ERROR);
5089     }
5090 
5091     /* Move the trap buffer pointer up.  */
5092     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5093 
5094 
5095     /* Adjust the trap sequence length.  */
5096     trap_sequence_length =  trap_sequence_length + trap_length;
5097 
5098     /* Adjust the trap request type length.  */
5099     trap_type_length =  trap_type_length + trap_length;
5100 
5101     /* Set the trap error information.  */
5102     trap_length =  _nx_snmp_utility_error_info_set(trap_buffer_ptr, 0, 0, trap_packet_ptr -> nx_packet_data_end);
5103 
5104     /* Check for a valid operation.  */
5105     if (trap_length == 0)
5106     {
5107 
5108         /* Increment the internal error counter.  */
5109         agent_ptr -> nx_snmp_agent_internal_errors++;
5110 
5111         /* Release the trap packet.  */
5112         nx_packet_release(trap_packet_ptr);
5113 
5114         /* Return to caller.  */
5115         return(NX_SNMP_ERROR);
5116     }
5117 
5118     /* Move the trap buffer pointer up.  */
5119     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5120 
5121     /* Adjust the trap sequence length.  */
5122     trap_sequence_length =  trap_sequence_length + trap_length;
5123 
5124     /* Adjust the trap request type length.  */
5125     trap_type_length =  trap_type_length + trap_length;
5126 
5127     /* Remember the start of the trap's variable list field.  */
5128     trap_variable_list_ptr =  trap_buffer_ptr;
5129 
5130     /* Setup the variable list.  For now, the length will be zero.  We
5131        will overwrite this with the actual length later.  */
5132     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
5133 
5134     /* Check for a valid operation.  */
5135     if (trap_length == 0)
5136     {
5137 
5138         /* Increment the internal error counter.  */
5139         agent_ptr -> nx_snmp_agent_internal_errors++;
5140 
5141         /* Release the trap packet too.  */
5142         nx_packet_release(trap_packet_ptr);
5143 
5144         /* Return to caller.  */
5145         return(NX_SNMP_ERROR);
5146     }
5147 
5148     /* Move the trap buffer pointer up.  */
5149     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5150 
5151     /* Adjust the trap sequence length.  */
5152     trap_sequence_length =  trap_sequence_length + trap_length;
5153 
5154     /* Adjust the trap request type length.  */
5155     trap_type_length =  trap_type_length + trap_length;
5156 
5157     /* Remember the start of the variable.  */
5158     trap_variable_ptr =  trap_buffer_ptr;
5159 
5160     /* Setup the variable trap sequence.  For now, the length will be zero.  We
5161        will overwrite this with the actual length later.  */
5162     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
5163 
5164     /* Check for a valid operation.  */
5165     if (trap_length == 0)
5166     {
5167 
5168         /* Increment the internal error counter.  */
5169         agent_ptr -> nx_snmp_agent_internal_errors++;
5170 
5171         /* Release the trap packet too.  */
5172         nx_packet_release(trap_packet_ptr);
5173 
5174         /* Return to caller.  */
5175         return(NX_SNMP_ERROR);
5176     }
5177 
5178     /* Move the trap buffer pointer up.  */
5179     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5180 
5181     /* Adjust the trap sequence length.  */
5182     trap_sequence_length =  trap_sequence_length + trap_length;
5183 
5184     /* Adjust the trap request type length.  */
5185     trap_type_length =  trap_type_length + trap_length;
5186 
5187     /* Adjust the trap variable list size.  */
5188     trap_variable_list_length =  trap_variable_list_length + trap_length;
5189 
5190     /* Place the sysUpTime object ID into the trap buffer.  */
5191     trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, (UCHAR *) "1.3.6.1.2.1.1.3.0",
5192                                                   trap_packet_ptr -> nx_packet_data_end);
5193 
5194     /* Check for a valid operation.  */
5195     if (trap_length == 0)
5196     {
5197 
5198         /* Release the trap packet.  */
5199         nx_packet_release(trap_packet_ptr);
5200 
5201         /* Done, return to caller.  */
5202         return(NX_SNMP_ERROR);
5203     }
5204 
5205     /* Move the trap buffer pointer up.  */
5206     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5207 
5208     /* Adjust the trap sequence length.  */
5209     trap_sequence_length =  trap_sequence_length + trap_length;
5210 
5211     /* Adjust the trap request type length.  */
5212     trap_type_length =  trap_type_length + trap_length;
5213 
5214     /* Adjust the trap variable list size.  */
5215     trap_variable_list_length =  trap_variable_list_length + trap_length;
5216 
5217     /* Adjust the trap variable size.  */
5218     trap_variable_length =  trap_variable_length + trap_length;
5219 
5220     /* Insert the SysTimerTicks into the trap buffer as the first item in the variable binding list.  */
5221     trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_TIME_TICS;
5222     trap_object_data.nx_snmp_object_data_msw =   (LONG)elapsed_time;
5223     trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
5224 
5225     /* Check for a valid operation.  */
5226     if (trap_length == 0)
5227     {
5228 
5229         /* Release the trap packet.  */
5230         nx_packet_release(trap_packet_ptr);
5231 
5232         /* Done, return to caller.  */
5233         return(NX_SNMP_ERROR);
5234     }
5235 
5236     /* Move the trap buffer pointer up.  */
5237     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5238 
5239     /* Adjust the trap sequence length.  */
5240     trap_sequence_length =  trap_sequence_length + trap_length;
5241 
5242     /* Adjust the trap request type length.  */
5243     trap_type_length =  trap_type_length + trap_length;
5244 
5245     /* Adjust the trap variable list size.  */
5246     trap_variable_list_length =  trap_variable_list_length + trap_length;
5247 
5248     /* Adjust the trap variable size.  */
5249     trap_variable_length =  trap_variable_length + trap_length;
5250 
5251     /* Now update the trap variable sequence with the actual variable length.  */
5252     _nx_snmp_utility_sequence_set(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
5253 
5254     /* Remember the start of the variable.  */
5255     trap_variable_ptr =  trap_buffer_ptr;
5256 
5257     /* Clear the trap variable size.  */
5258     trap_variable_length =  0;
5259 
5260     /* Check that we have a valid trap type requested.  */
5261     if ((trap_type > TRAP_ID_MAX) && (trap_type != NX_SNMP_TRAP_CUSTOM))
5262     {
5263 
5264         /* Increment the internal error counter.  */
5265         agent_ptr -> nx_snmp_agent_internal_errors++;
5266 
5267         /* Release the trap packet.  */
5268         nx_packet_release(trap_packet_ptr);
5269 
5270         /* Return to caller.  */
5271         return(NX_SNMP_ERROR);
5272     }
5273 
5274     /* Check that we have a trap list if a custom trap is requested.  */
5275     if ((object_list_ptr == NX_NULL) && (trap_type == NX_SNMP_TRAP_CUSTOM))
5276     {
5277 
5278         /* Increment the internal error counter.  */
5279         agent_ptr -> nx_snmp_agent_internal_errors++;
5280 
5281         /* Release the trap packet.  */
5282         nx_packet_release(trap_packet_ptr);
5283 
5284         /* Return to caller.  */
5285         return(NX_SNMP_ERROR);
5286     }
5287 
5288     /* Check if this is an enumerated trap event. */
5289     if (trap_type <= TRAP_ID_MAX)
5290     {
5291 
5292         /* Set up the variable trap sequence.  For now, the length will be zero.  We
5293            will overwrite this with the actual length later.  */
5294         trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
5295 
5296         /* Check for a valid operation.  */
5297         if (trap_length == 0)
5298         {
5299 
5300             /* Increment the internal error counter.  */
5301             agent_ptr -> nx_snmp_agent_internal_errors++;
5302 
5303             /* Release the trap packet too.  */
5304             nx_packet_release(trap_packet_ptr);
5305 
5306             /* Return to caller.  */
5307             return(NX_SNMP_ERROR);
5308         }
5309 
5310         /* Move the trap buffer pointer up.  */
5311         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5312 
5313         /* Adjust the trap sequence length.  */
5314         trap_sequence_length =  trap_sequence_length + trap_length;
5315 
5316         /* Adjust the trap request type length.  */
5317         trap_type_length =  trap_type_length + trap_length;
5318 
5319         /* Adjust the trap variable list size.  */
5320         trap_variable_list_length =  trap_variable_list_length + trap_length;
5321 
5322         /* Place the snmpTrapOID object ID into the trap buffer.  */
5323         trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, (UCHAR *) "1.3.6.1.6.3.1.1.4.1.0",
5324                                                       trap_packet_ptr -> nx_packet_data_end);
5325 
5326         /* Check for a valid operation.  */
5327         if (trap_length == 0)
5328         {
5329 
5330             /* Release the trap packet.  */
5331             nx_packet_release(trap_packet_ptr);
5332 
5333             /* Done, return to caller.  */
5334             return(NX_SNMP_ERROR);
5335         }
5336 
5337         /* Move the trap buffer pointer up.  */
5338         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5339 
5340         /* Adjust the trap sequence length.  */
5341         trap_sequence_length =  trap_sequence_length + trap_length;
5342 
5343         /* Adjust the trap request type length.  */
5344         trap_type_length =  trap_type_length + trap_length;
5345 
5346         /* Adjust the trap variable list size.  */
5347         trap_variable_list_length =  trap_variable_list_length + trap_length;
5348 
5349         /* Adjust the trap variable size.  */
5350         trap_variable_length =  trap_variable_length + trap_length;
5351 
5352         /* Set an Object ID for the data.  */
5353         trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_OBJECT_ID;
5354         trap_object_data.nx_snmp_object_data_msw =   0;
5355 
5356         /* Copy the object specified by the trap_type index. */
5357         _nx_snmp_object_copy(_nx_snmp_v2_trap_ids[trap_type], trap_object_data.nx_snmp_object_octet_string);
5358 
5359         /* Add trap object data to trap buffer. */
5360         trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
5361 
5362         /* Check for a valid operation.  */
5363         if (trap_length == 0)
5364         {
5365 
5366             /* Release the trap packet.  */
5367             nx_packet_release(trap_packet_ptr);
5368 
5369             /* Done, return to caller.  */
5370             return(NX_SNMP_ERROR);
5371         }
5372 
5373         /* Move the trap buffer pointer up.  */
5374         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5375 
5376         /* Adjust the trap sequence length.  */
5377         trap_sequence_length =  trap_sequence_length + trap_length;
5378 
5379         /* Adjust the trap request type length.  */
5380         trap_type_length =  trap_type_length + trap_length;
5381 
5382         /* Adjust the trap variable list size.  */
5383         trap_variable_list_length =  trap_variable_list_length + trap_length;
5384 
5385         /* Adjust the trap variable size.  */
5386         trap_variable_length =  trap_variable_length + trap_length;
5387     }
5388 
5389     /* Now update the trap variable sequence with the actual variable length.  */
5390     _nx_snmp_utility_sequence_set(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
5391 
5392     /* Default the object pointer to NULL.  */
5393     trap_object_ptr =  NX_NULL;
5394 
5395     /* Determine if an object is specified.  */
5396     if (object_list_ptr)
5397     {
5398 
5399         /* Setup object pointers from the supplied object list.  */
5400         trap_object_ptr =       object_list_ptr -> nx_snmp_object_string_ptr;
5401         trap_object_data_ptr =  object_list_ptr -> nx_snmp_object_data;
5402 
5403         /* Check for a valid operation.  */
5404         if(trap_object_ptr != NX_NULL && trap_object_data_ptr == NX_NULL)
5405         {
5406             /* Release the trap packet.  */
5407             nx_packet_release(trap_packet_ptr);
5408 
5409             /* Done, return to caller.  */
5410             return(NX_SNMP_ERROR);
5411         }
5412     }
5413 
5414     /* Loop to process all the objects in the list.  */
5415     while (trap_object_ptr)
5416     {
5417 
5418         /* Clear the trap variable length.  */
5419         trap_variable_length =  0;
5420 
5421         /* Remember the start of the variable.  */
5422         trap_variable_ptr =  trap_buffer_ptr;
5423 
5424         /* Setup the variable trap sequence.  For now, the length will be zero.  We
5425            will overwrite this with the actual length later.  */
5426         trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
5427 
5428         /* Check for a valid operation.  */
5429         if (trap_length == 0)
5430         {
5431 
5432             /* Increment the internal error counter.  */
5433             agent_ptr -> nx_snmp_agent_internal_errors++;
5434 
5435             /* Release the trap packet too.  */
5436             nx_packet_release(trap_packet_ptr);
5437 
5438             /* Return to caller.  */
5439             return(NX_SNMP_ERROR);
5440         }
5441 
5442         /* Move the trap buffer pointer up.  */
5443         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5444 
5445         /* Adjust the trap sequence length.  */
5446         trap_sequence_length =  trap_sequence_length + trap_length;
5447 
5448         /* Adjust the trap request type length.  */
5449         trap_type_length =  trap_type_length + trap_length;
5450 
5451         /* Adjust the trap variable list size.  */
5452         trap_variable_list_length =  trap_variable_list_length + trap_length;
5453 
5454         /* Place the object into the trap buffer.  */
5455         trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, trap_object_ptr, trap_packet_ptr -> nx_packet_data_end);
5456 
5457         /* Check for a valid operation.  */
5458         if (trap_length == 0)
5459         {
5460 
5461             /* Release the trap packet.  */
5462             nx_packet_release(trap_packet_ptr);
5463 
5464             /* Done, return to caller.  */
5465             return(NX_SNMP_ERROR);
5466         }
5467 
5468         /* Move the trap buffer pointer up.  */
5469         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5470 
5471         /* Adjust the trap sequence length.  */
5472         trap_sequence_length =  trap_sequence_length + trap_length;
5473 
5474         /* Adjust the trap request type length.  */
5475         trap_type_length =  trap_type_length + trap_length;
5476 
5477         /* Adjust the trap variable list size.  */
5478         trap_variable_list_length =  trap_variable_list_length + trap_length;
5479 
5480         /* Adjust the trap variable size.  */
5481         trap_variable_length =  trap_variable_length + trap_length;
5482 
5483         /* Insert the object's data into the trap buffer.  */
5484         trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, trap_object_data_ptr, trap_packet_ptr -> nx_packet_data_end);
5485 
5486         /* Check for a valid operation.  */
5487         if (trap_length == 0)
5488         {
5489 
5490             /* Release the trap packet.  */
5491             nx_packet_release(trap_packet_ptr);
5492 
5493             /* Done, return to caller.  */
5494             return(NX_SNMP_ERROR);
5495         }
5496 
5497         /* Move the trap buffer pointer up.  */
5498         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5499 
5500         /* Adjust the trap sequence length.  */
5501         trap_sequence_length =  trap_sequence_length + trap_length;
5502 
5503         /* Adjust the trap request type length.  */
5504         trap_type_length =  trap_type_length + trap_length;
5505 
5506         /* Adjust the trap variable list size.  */
5507         trap_variable_list_length =  trap_variable_list_length + trap_length;
5508 
5509         /* Adjust the trap variable size.  */
5510         trap_variable_length =  trap_variable_length + trap_length;
5511 
5512         /* Now update the trap variable sequence with the actual variable length.  */
5513         _nx_snmp_utility_sequence_set(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
5514 
5515         /* Default the object pointer to NULL.  */
5516         trap_object_ptr =  NX_NULL;
5517 
5518         /* Determine if there are more objects to insert into the trap message.  */
5519         if (object_list_ptr)
5520         {
5521 
5522             /* Move to the next object in the list.  */
5523             object_list_ptr++;
5524 
5525             if (object_list_ptr == NX_NULL)
5526             {
5527                 /* Release the trap packet.  */
5528                 nx_packet_release(trap_packet_ptr);
5529 
5530                 /* Done, return to caller.  */
5531                 return(NX_SNMP_ERROR);
5532             }
5533 
5534             /* Determine if there is another object.  */
5535             if (object_list_ptr -> nx_snmp_object_string_ptr)
5536             {
5537 
5538                 /* Setup the object and object data pointers.  */
5539                 trap_object_ptr =       object_list_ptr -> nx_snmp_object_string_ptr;
5540                 trap_object_data_ptr =  object_list_ptr -> nx_snmp_object_data;
5541 
5542                 /* Check for a valid operation.  */
5543                 if(trap_object_ptr != NX_NULL && trap_object_data_ptr == NX_NULL)
5544                 {
5545                     /* Release the trap packet.  */
5546                     nx_packet_release(trap_packet_ptr);
5547 
5548                     /* Done, return to caller.  */
5549                     return(NX_SNMP_ERROR);
5550                 }
5551             }
5552         }
5553     }
5554 
5555     /* At this point, several trap fields need to be updated with actual lengths.  */
5556 
5557     _nx_snmp_utility_request_type_set_multibyte(trap_type_ptr, NX_SNMP_ANS1_TRAP2_REQUEST, trap_type_length, trap_packet_ptr -> nx_packet_data_end);
5558     _nx_snmp_utility_sequence_set(trap_sequence_ptr, trap_sequence_length, trap_packet_ptr -> nx_packet_data_end);
5559     _nx_snmp_utility_sequence_set(trap_variable_list_ptr, trap_variable_list_length, trap_packet_ptr -> nx_packet_data_end);
5560 
5561     /* Update the trap packet's pointers.  */
5562     trap_packet_ptr -> nx_packet_length =  (ULONG)(trap_buffer_ptr - trap_packet_ptr -> nx_packet_prepend_ptr);
5563     trap_packet_ptr -> nx_packet_append_ptr =  trap_buffer_ptr;
5564 
5565     /* Update various statistics.  */
5566     agent_ptr -> nx_snmp_agent_traps_sent++;
5567     agent_ptr -> nx_snmp_agent_packets_sent++;
5568 
5569     /* Send the trap packet back to the requesting SNMP manager.  */
5570     status = nxd_udp_socket_send(&(agent_ptr -> nx_snmp_agent_socket), trap_packet_ptr,
5571                                    ip_address, NX_SNMP_MANAGER_TRAP_PORT);
5572 
5573     /* Determine if the packet needs to be released. */
5574     if (status)
5575     {
5576 
5577         /* Release packet.  */
5578         nx_packet_release(trap_packet_ptr);
5579 
5580         /* Return an error.  */
5581         return(NX_SNMP_ERROR);
5582     }
5583 
5584     /* Return completion status.  */
5585     return(NX_SUCCESS);
5586 }
5587 
5588 
5589 /**************************************************************************/
5590 /*                                                                        */
5591 /*  FUNCTION                                               RELEASE        */
5592 /*                                                                        */
5593 /*    _nxe_snmp_agent_trapv2_oid_send                     PORTABLE C      */
5594 /*                                                           6.1          */
5595 /*  AUTHOR                                                                */
5596 /*                                                                        */
5597 /*    Yuxin Zhou, Microsoft Corporation                                   */
5598 /*                                                                        */
5599 /*  DESCRIPTION                                                           */
5600 /*                                                                        */
5601 /*    This function checks for errors in the SNMP agent v2 trap send      */
5602 /*    function call.                                                      */
5603 /*                                                                        */
5604 /*  INPUT                                                                 */
5605 /*                                                                        */
5606 /*    agent_ptr                             Pointer to SNMP agent         */
5607 /*    ip_address                            Destination IP address        */
5608 /*    community                             Community name                */
5609 /*    OID                                   OID to send                   */
5610 /*    elapsed_time                          Elapsed time from last boot   */
5611 /*                                            of the device (sysUpTime)   */
5612 /*    object_list_ptr                       Variable list of application  */
5613 /*                                            objects to present with the */
5614 /*                                            trap                        */
5615 /*                                                                        */
5616 /*  OUTPUT                                                                */
5617 /*                                                                        */
5618 /*    status                                Completion status             */
5619 /*                                                                        */
5620 /*  CALLS                                                                 */
5621 /*                                                                        */
5622 /*    _nx_snmp_agent_trapv2_oid_send        Actual agent trap send        */
5623 /*                                            function                    */
5624 /*                                                                        */
5625 /*  CALLED BY                                                             */
5626 /*                                                                        */
5627 /*    Application Code                                                    */
5628 /*                                                                        */
5629 /*  RELEASE HISTORY                                                       */
5630 /*                                                                        */
5631 /*    DATE              NAME                      DESCRIPTION             */
5632 /*                                                                        */
5633 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5634 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5635 /*                                            resulting in version 6.1    */
5636 /*                                                                        */
5637 /**************************************************************************/
_nxe_snmp_agent_trapv2_oid_send(NX_SNMP_AGENT * agent_ptr,ULONG ip_address,UCHAR * community,UCHAR * oid,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)5638 UINT  _nxe_snmp_agent_trapv2_oid_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *community, UCHAR *oid, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
5639 {
5640 
5641 #ifndef NX_DISABLE_IPV4
5642 UINT    status;
5643 
5644 
5645     /* Check for invalid input pointers.  */
5646     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) || (community == NX_NULL))
5647         return(NX_PTR_ERROR);
5648 
5649     /* Check for invalid IP address.  */
5650     if (ip_address == 0)
5651         return(NX_IP_ADDRESS_ERROR);
5652 
5653     /* Call actual service.  */
5654     status =  _nx_snmp_agent_trapv2_oid_send(agent_ptr, ip_address, community, oid, elapsed_time, object_list_ptr);
5655 
5656     /* Return status.  */
5657     return(status);
5658 #else
5659     NX_PARAMETER_NOT_USED(agent_ptr);
5660     NX_PARAMETER_NOT_USED(ip_address);
5661     NX_PARAMETER_NOT_USED(community);
5662     NX_PARAMETER_NOT_USED(oid);
5663     NX_PARAMETER_NOT_USED(elapsed_time);
5664     NX_PARAMETER_NOT_USED(object_list_ptr);
5665 
5666     return(NX_NOT_SUPPORTED);
5667 #endif /* NX_DISABLE_IPV4 */
5668 }
5669 
5670 
5671 /**************************************************************************/
5672 /*                                                                        */
5673 /*  FUNCTION                                               RELEASE        */
5674 /*                                                                        */
5675 /*    _nx_snmp_agent_trapv2__oid_send                     PORTABLE C      */
5676 /*                                                           6.1          */
5677 /*  AUTHOR                                                                */
5678 /*                                                                        */
5679 /*    Yuxin Zhou, Microsoft Corporation                                   */
5680 /*                                                                        */
5681 /*  DESCRIPTION                                                           */
5682 /*                                                                        */
5683 /*    This function builds and sends a SNMP v2 trap message using the OID */
5684 /*    directly from the caller.                                           */
5685 /*                                                                        */
5686 /*  INPUT                                                                 */
5687 /*                                                                        */
5688 /*    agent_ptr                             Pointer to SNMP agent         */
5689 /*    ip_address                            Destination IP address        */
5690 /*    community                             Community name                */
5691 /*    OID                                   OID to send                   */
5692 /*    elapsed_time                          Elapsed time from last boot   */
5693 /*                                            of the device (sysUpTime)   */
5694 /*    object_list_ptr                       Variable list of application  */
5695 /*                                            objects to present with the */
5696 /*                                            trap                        */
5697 /*                                                                        */
5698 /*  OUTPUT                                                                */
5699 /*                                                                        */
5700 /*    status                                Completion status             */
5701 /*                                                                        */
5702 /*  CALLS                                                                 */
5703 /*                                                                        */
5704 /*    _nxd_snmp_agent_trapv2_oid_send       Actual agent trap send        */
5705 /*                                            function                    */
5706 /*                                                                        */
5707 /*  CALLED BY                                                             */
5708 /*                                                                        */
5709 /*    Application Code                                                    */
5710 /*                                                                        */
5711 /*  RELEASE HISTORY                                                       */
5712 /*                                                                        */
5713 /*    DATE              NAME                      DESCRIPTION             */
5714 /*                                                                        */
5715 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5716 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5717 /*                                            resulting in version 6.1    */
5718 /*                                                                        */
5719 /**************************************************************************/
_nx_snmp_agent_trapv2_oid_send(NX_SNMP_AGENT * agent_ptr,ULONG ip_address,UCHAR * community,UCHAR * oid,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)5720 UINT  _nx_snmp_agent_trapv2_oid_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *community, UCHAR *oid, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
5721 {
5722 
5723 #ifndef NX_DISABLE_IPV4
5724 UINT status;
5725 NXD_ADDRESS ipduo_address;
5726 
5727 
5728     ipduo_address.nxd_ip_version = NX_IP_VERSION_V4;
5729     ipduo_address.nxd_ip_address.v4 = ip_address;
5730 
5731     status = _nxd_snmp_agent_trapv2_oid_send(agent_ptr, &ipduo_address, community, oid, elapsed_time, object_list_ptr);
5732 
5733     return status;
5734 #else
5735     NX_PARAMETER_NOT_USED(agent_ptr);
5736     NX_PARAMETER_NOT_USED(ip_address);
5737     NX_PARAMETER_NOT_USED(community);
5738     NX_PARAMETER_NOT_USED(oid);
5739     NX_PARAMETER_NOT_USED(elapsed_time);
5740     NX_PARAMETER_NOT_USED(object_list_ptr);
5741 
5742     return(NX_NOT_SUPPORTED);
5743 #endif /* NX_DISABLE_IPV4 */
5744 }
5745 
5746 /**************************************************************************/
5747 /*                                                                        */
5748 /*  FUNCTION                                               RELEASE        */
5749 /*                                                                        */
5750 /*    _nxde_snmp_agent_trapv2_oid_send                    PORTABLE C      */
5751 /*                                                           6.1          */
5752 /*  AUTHOR                                                                */
5753 /*                                                                        */
5754 /*    Yuxin Zhou, Microsoft Corporation                                   */
5755 /*                                                                        */
5756 /*  DESCRIPTION                                                           */
5757 /*                                                                        */
5758 /*    This function checks for errors in the SNMP agent v2 trap send      */
5759 /*    function call.                                                      */
5760 /*                                                                        */
5761 /*  INPUT                                                                 */
5762 /*                                                                        */
5763 /*    agent_ptr                             Pointer to SNMP agent         */
5764 /*    ip_address                            Destination IP address        */
5765 /*    community                             Community name                */
5766 /*    OID                                   OID to send                   */
5767 /*    elapsed_time                          Elapsed time from last boot   */
5768 /*                                            of the device (sysUpTime)   */
5769 /*    object_list_ptr                       Variable list of application  */
5770 /*                                            objects to present with the */
5771 /*                                            trap                        */
5772 /*                                                                        */
5773 /*  OUTPUT                                                                */
5774 /*                                                                        */
5775 /*    status                                Completion status             */
5776 /*                                                                        */
5777 /*  CALLS                                                                 */
5778 /*                                                                        */
5779 /*    _nxd_snmp_agent_trapv2_oid_send       Actual agent trap send        */
5780 /*                                            function                    */
5781 /*                                                                        */
5782 /*  CALLED BY                                                             */
5783 /*                                                                        */
5784 /*    Application Code                                                    */
5785 /*                                                                        */
5786 /*  RELEASE HISTORY                                                       */
5787 /*                                                                        */
5788 /*    DATE              NAME                      DESCRIPTION             */
5789 /*                                                                        */
5790 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5791 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5792 /*                                            resulting in version 6.1    */
5793 /*                                                                        */
5794 /**************************************************************************/
_nxde_snmp_agent_trapv2_oid_send(NX_SNMP_AGENT * agent_ptr,NXD_ADDRESS * ipduo_address,UCHAR * community,UCHAR * oid,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)5795 UINT  _nxde_snmp_agent_trapv2_oid_send(NX_SNMP_AGENT *agent_ptr, NXD_ADDRESS *ipduo_address, UCHAR *community, UCHAR *oid, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
5796 {
5797 
5798 UINT    status;
5799 
5800 
5801     /* Check for invalid input pointers.  */
5802     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) || (community == NX_NULL) ||
5803         (ipduo_address == NX_NULL))
5804     {
5805 
5806         return(NX_PTR_ERROR);
5807     }
5808 
5809     /* Call actual service.  */
5810     status =  _nxd_snmp_agent_trapv2_oid_send(agent_ptr, ipduo_address, community, oid, elapsed_time, object_list_ptr);
5811 
5812     /* Return status.  */
5813     return(status);
5814 }
5815 
5816 /**************************************************************************/
5817 /*                                                                        */
5818 /*  FUNCTION                                               RELEASE        */
5819 /*                                                                        */
5820 /*    _nxd_snmp_agent_trapv2_oid_send                     PORTABLE C      */
5821 /*                                                           6.1          */
5822 /*  AUTHOR                                                                */
5823 /*                                                                        */
5824 /*    Yuxin Zhou, Microsoft Corporation                                   */
5825 /*                                                                        */
5826 /*  DESCRIPTION                                                           */
5827 /*                                                                        */
5828 /*    This function builds and sends a SNMP v2 trap message using the OID */
5829 /*    directly from the caller. Supports IPv6 and IPv4 connections.       */
5830 /*                                                                        */
5831 /*    Note: The string length of community is limited by the packet       */
5832 /*    payload and NX_SNMP_MAX_USER_NAME. The string length of oid is      */
5833 /*    limited by the packet payload and NX_SNMP_MAX_OCTET_STRING.         */
5834 /*                                                                        */
5835 /*  INPUT                                                                 */
5836 /*                                                                        */
5837 /*    agent_ptr                             Pointer to SNMP agent         */
5838 /*    ip_address                            Destination IP address        */
5839 /*    community                             Community name                */
5840 /*    OID                                   OID to send                   */
5841 /*    elapsed_time                          Elapsed time from last boot   */
5842 /*                                            of the device (sysUpTime)   */
5843 /*    object_list_ptr                       Variable list of application  */
5844 /*                                            objects to present with the */
5845 /*                                            trap                        */
5846 /*                                                                        */
5847 /*  OUTPUT                                                                */
5848 /*                                                                        */
5849 /*    status                                Completion status             */
5850 /*                                                                        */
5851 /*  CALLS                                                                 */
5852 /*                                                                        */
5853 /*    nx_packet_allocate                    Allocate SNMP trap packet     */
5854 /*    nx_packet_release                     Release SNMP packet           */
5855 /*    nx_udp_socket_send                    Send SNMP trap via UDP        */
5856 /*    _nx_snmp_object_copy                  Copy object                   */
5857 /*    _nx_snmp_utility_community_set        Set the community name        */
5858 /*    _nx_snmp_utility_error_info_set       Set error information         */
5859 /*    _nx_snmp_utility_object_data_set      Set the data value            */
5860 /*    _nx_snmp_utility_object_id_set        Set the object ID             */
5861 /*    _nx_snmp_utility_sequence_set         Set the ASN.1 sequence        */
5862 /*    _nx_snmp_utility_request_id_set       Set the Trap ID               */
5863 /*    _nx_snmp_utility_sequence_set_1byte                                 */
5864 /*                                          Set trap sequence             */
5865 /*    _nx_snmp_utility_request_type_set_multibyte                         */
5866 /*                                          Set trap request type         */
5867 /*    _nx_snmp_utility_version_set          Set the SNMP v1               */
5868 /*                                                                        */
5869 /*  CALLED BY                                                             */
5870 /*                                                                        */
5871 /*    Application Code                                                    */
5872 /*                                                                        */
5873 /*  RELEASE HISTORY                                                       */
5874 /*                                                                        */
5875 /*    DATE              NAME                      DESCRIPTION             */
5876 /*                                                                        */
5877 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5878 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5879 /*                                            resulting in version 6.1    */
5880 /*                                                                        */
5881 /**************************************************************************/
_nxd_snmp_agent_trapv2_oid_send(NX_SNMP_AGENT * agent_ptr,NXD_ADDRESS * ipduo_address,UCHAR * community,UCHAR * oid,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)5882 UINT  _nxd_snmp_agent_trapv2_oid_send(NX_SNMP_AGENT *agent_ptr, NXD_ADDRESS *ipduo_address, UCHAR *community, UCHAR *oid, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
5883 {
5884 
5885 UINT                 status;
5886 UINT                 trap_length;
5887 UCHAR                *trap_object_ptr;
5888 NX_SNMP_OBJECT_DATA  trap_object_data;
5889 NX_SNMP_OBJECT_DATA  *trap_object_data_ptr = NX_NULL;
5890 NX_PACKET            *trap_packet_ptr;
5891 UCHAR                *trap_buffer_ptr, *trap_sequence_ptr, *trap_type_ptr, *trap_variable_list_ptr, *trap_variable_ptr;
5892 UINT                 trap_sequence_length, trap_type_length, trap_variable_list_length, trap_variable_length;
5893 UINT                 packet_type = NX_UDP_PACKET;
5894 
5895 
5896     if (ipduo_address -> nxd_ip_version == NX_IP_VERSION_V6)
5897     {
5898         packet_type = NX_IPv6_UDP_PACKET;
5899     }
5900     else
5901     {
5902         packet_type = NX_IPv4_UDP_PACKET;
5903     }
5904 
5905     /* Allocate the packet for the SNMP v2 trap.  */
5906     status =  nx_packet_allocate(agent_ptr -> nx_snmp_agent_packet_pool_ptr, &trap_packet_ptr, packet_type, NX_SNMP_AGENT_TIMEOUT);
5907 
5908     /* Determine if a trap packet was allocated.  */
5909     if (status)
5910     {
5911 
5912         /* Increment the packet allocation error counter.  */
5913         agent_ptr -> nx_snmp_agent_allocation_errors++;
5914 
5915         /* Return to caller.  */
5916         return(NX_SNMP_ERROR);
5917     }
5918 
5919     /* Now prepare trap message so we can process the variables one by one.  */
5920 
5921     /* Initialize the counters required for the length fields of the trap packet.  */
5922     trap_sequence_length =       0;
5923     trap_type_length =           0;
5924     trap_variable_list_length =  0;
5925     trap_variable_length =       0;
5926 
5927     /* Setup a pointer to the trap packet's buffer area.  */
5928     trap_buffer_ptr =  trap_packet_ptr -> nx_packet_prepend_ptr;
5929 
5930     /* This is also the trap sequence pointer. Remember it since we are going to have to
5931        update it later with the actual length of the trap.  */
5932     trap_sequence_ptr =  trap_buffer_ptr;
5933 
5934     /* First, write the sequence in the trap packet.  A zero is written for now.  This will be
5935        updated later.  */
5936     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
5937 
5938     /* Check for a valid operation.  */
5939     if (trap_length == 0)
5940     {
5941 
5942         /* Increment the internal error counter.  */
5943         agent_ptr -> nx_snmp_agent_internal_errors++;
5944 
5945         /* Release the trap packet too.  */
5946         nx_packet_release(trap_packet_ptr);
5947 
5948         /* Return to caller.  */
5949         return(NX_SNMP_ERROR);
5950     }
5951 
5952     /* Move the trap buffer pointer up.  */
5953     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5954 
5955     /* Now set the Version ID in the trap message.  */
5956     trap_length =  _nx_snmp_utility_version_set(trap_buffer_ptr, NX_SNMP_VERSION_2C, trap_packet_ptr -> nx_packet_data_end);
5957 
5958     /* Check for a valid operation.  */
5959     if (trap_length == 0)
5960     {
5961 
5962         /* Increment the internal error counter.  */
5963         agent_ptr -> nx_snmp_agent_internal_errors++;
5964 
5965         /* Release the trap packet.  */
5966         nx_packet_release(trap_packet_ptr);
5967 
5968         /* Return to caller.  */
5969         return(NX_SNMP_ERROR);
5970     }
5971 
5972     /* Move the trap buffer pointer up.  */
5973     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5974 
5975     /* Adjust the trap sequence length.  */
5976     trap_sequence_length =  trap_sequence_length + trap_length;
5977 
5978     /* Now set the community in the trap message.  */
5979     trap_length =  _nx_snmp_utility_community_set(trap_buffer_ptr, community, trap_packet_ptr -> nx_packet_data_end);
5980 
5981     /* Check for a valid operation.  */
5982     if (trap_length == 0)
5983     {
5984 
5985         /* Increment the internal error counter.  */
5986         agent_ptr -> nx_snmp_agent_internal_errors++;
5987 
5988         /* Release the trap packet.  */
5989         nx_packet_release(trap_packet_ptr);
5990 
5991         /* Return to caller.  */
5992         return(NX_SNMP_ERROR);
5993     }
5994 
5995     /* Move the trap buffer pointer up.  */
5996     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
5997 
5998     /* Adjust the trap sequence length.  */
5999     trap_sequence_length =  trap_sequence_length + trap_length;
6000 
6001     /* Remember the request type pointer, since it will need to be updated later.  */
6002     trap_type_ptr =  trap_buffer_ptr;
6003 
6004     /* Now set the request type in the trap message.  */
6005     trap_length =  _nx_snmp_utility_request_type_set_multibyte(trap_buffer_ptr, NX_SNMP_ANS1_TRAP2_REQUEST, 0, trap_packet_ptr -> nx_packet_data_end);
6006 
6007     /* Check for a valid operation.  */
6008     if (trap_length == 0)
6009     {
6010 
6011         /* Increment the internal error counter.  */
6012         agent_ptr -> nx_snmp_agent_internal_errors++;
6013 
6014         /* Release the trap packet.  */
6015         nx_packet_release(trap_packet_ptr);
6016 
6017         /* Return to caller.  */
6018         return(NX_SNMP_ERROR);
6019     }
6020 
6021     /* Move the trap buffer pointer up.  */
6022     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6023 
6024     /* Adjust the trap sequence length.  */
6025     trap_sequence_length =  trap_sequence_length + trap_length;
6026 
6027     /* Now set the trap ID in the trap message.  */
6028     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_traps_sent, trap_packet_ptr -> nx_packet_data_end);
6029 
6030     /* Check for a valid operation.  */
6031     if (trap_length == 0)
6032     {
6033 
6034         /* Increment the internal error counter.  */
6035         agent_ptr -> nx_snmp_agent_internal_errors++;
6036 
6037         /* Release the trap packet too.  */
6038         nx_packet_release(trap_packet_ptr);
6039 
6040         /* Return to caller.  */
6041         return(NX_SNMP_ERROR);
6042     }
6043 
6044     /* Move the trap buffer pointer up.  */
6045     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6046 
6047     /* Adjust the trap sequence length.  */
6048     trap_sequence_length =  trap_sequence_length + trap_length;
6049 
6050     /* Adjust the trap request type length.  */
6051     trap_type_length =  trap_type_length + trap_length;
6052 
6053     /* Set the trap error information.  */
6054     trap_length =  _nx_snmp_utility_error_info_set(trap_buffer_ptr, 0, 0, trap_packet_ptr -> nx_packet_data_end);
6055 
6056     /* Check for a valid operation.  */
6057     if (trap_length == 0)
6058     {
6059 
6060         /* Increment the internal error counter.  */
6061         agent_ptr -> nx_snmp_agent_internal_errors++;
6062 
6063         /* Release the trap packet.  */
6064         nx_packet_release(trap_packet_ptr);
6065 
6066         /* Return to caller.  */
6067         return(NX_SNMP_ERROR);
6068     }
6069 
6070     /* Move the trap buffer pointer up.  */
6071     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6072 
6073     /* Adjust the trap sequence length.  */
6074     trap_sequence_length =  trap_sequence_length + trap_length;
6075 
6076     /* Adjust the trap request type length.  */
6077     trap_type_length =  trap_type_length + trap_length;
6078 
6079     /* Remember the start of the trap's variable list field.  */
6080     trap_variable_list_ptr =  trap_buffer_ptr;
6081 
6082     /* Setup the variable list.  For now, the length will be zero.  We
6083        will overwrite this with the actual length later.  */
6084     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
6085 
6086     /* Check for a valid operation.  */
6087     if (trap_length == 0)
6088     {
6089 
6090         /* Increment the internal error counter.  */
6091         agent_ptr -> nx_snmp_agent_internal_errors++;
6092 
6093         /* Release the trap packet too.  */
6094         nx_packet_release(trap_packet_ptr);
6095 
6096         /* Return to caller.  */
6097         return(NX_SNMP_ERROR);
6098     }
6099 
6100     /* Move the trap buffer pointer up.  */
6101     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6102 
6103     /* Adjust the trap sequence length.  */
6104     trap_sequence_length =  trap_sequence_length + trap_length;
6105 
6106     /* Adjust the trap request type length.  */
6107     trap_type_length =  trap_type_length + trap_length;
6108 
6109     /* Remember the start of the variable.  */
6110     trap_variable_ptr =  trap_buffer_ptr;
6111 
6112     /* Setup the variable trap sequence.  For now, the length will be zero.  We
6113        will overwrite this with the actual length later.  */
6114     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
6115 
6116     /* Check for a valid operation.  */
6117     if (trap_length == 0)
6118     {
6119 
6120         /* Increment the internal error counter.  */
6121         agent_ptr -> nx_snmp_agent_internal_errors++;
6122 
6123         /* Release the trap packet too.  */
6124         nx_packet_release(trap_packet_ptr);
6125 
6126         /* Return to caller.  */
6127         return(NX_SNMP_ERROR);
6128     }
6129 
6130     /* Move the trap buffer pointer up.  */
6131     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6132 
6133     /* Adjust the trap sequence length.  */
6134     trap_sequence_length =  trap_sequence_length + trap_length;
6135 
6136     /* Adjust the trap request type length.  */
6137     trap_type_length =  trap_type_length + trap_length;
6138 
6139     /* Adjust the trap variable list size.  */
6140     trap_variable_list_length =  trap_variable_list_length + trap_length;
6141 
6142     /* Place the sysUpTime object ID into the trap buffer.  */
6143     trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, (UCHAR *) "1.3.6.1.2.1.1.3.0", trap_packet_ptr -> nx_packet_data_end);
6144 
6145     /* Check for a valid operation.  */
6146     if (trap_length == 0)
6147     {
6148 
6149         /* Release the trap packet.  */
6150         nx_packet_release(trap_packet_ptr);
6151 
6152         /* Done, return to caller.  */
6153         return(NX_SNMP_ERROR);
6154     }
6155 
6156     /* Move the trap buffer pointer up.  */
6157     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6158 
6159     /* Adjust the trap sequence length.  */
6160     trap_sequence_length =  trap_sequence_length + trap_length;
6161 
6162     /* Adjust the trap request type length.  */
6163     trap_type_length =  trap_type_length + trap_length;
6164 
6165     /* Adjust the trap variable list size.  */
6166     trap_variable_list_length =  trap_variable_list_length + trap_length;
6167 
6168     /* Adjust the trap variable size.  */
6169     trap_variable_length =  trap_variable_length + trap_length;
6170 
6171     /* Insert the object's data into the trap buffer.  */
6172     trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_TIME_TICS;
6173     trap_object_data.nx_snmp_object_data_msw =   (LONG)elapsed_time;
6174     trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
6175 
6176     /* Check for a valid operation.  */
6177     if (trap_length == 0)
6178     {
6179 
6180         /* Release the trap packet.  */
6181         nx_packet_release(trap_packet_ptr);
6182 
6183         /* Done, return to caller.  */
6184         return(NX_SNMP_ERROR);
6185     }
6186 
6187     /* Move the trap buffer pointer up.  */
6188     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6189 
6190     /* Adjust the trap sequence length.  */
6191     trap_sequence_length =  trap_sequence_length + trap_length;
6192 
6193     /* Adjust the trap request type length.  */
6194     trap_type_length =  trap_type_length + trap_length;
6195 
6196     /* Adjust the trap variable list size.  */
6197     trap_variable_list_length =  trap_variable_list_length + trap_length;
6198 
6199     /* Adjust the trap variable size.  */
6200     trap_variable_length =  trap_variable_length + trap_length;
6201 
6202     /* Now update the trap variable sequence with the actual variable length.  */
6203     _nx_snmp_utility_sequence_set(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
6204 
6205     /* Remember the start of the variable.  */
6206     trap_variable_ptr =  trap_buffer_ptr;
6207 
6208     /* Clear the trap variable size.  */
6209     trap_variable_length =  0;
6210 
6211     /* Setup the variable trap sequence.  For now, the length will be zero.  We
6212        will overwrite this with the actual length later.  */
6213     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
6214 
6215     /* Check for a valid operation.  */
6216     if (trap_length == 0)
6217     {
6218 
6219         /* Increment the internal error counter.  */
6220         agent_ptr -> nx_snmp_agent_internal_errors++;
6221 
6222         /* Release the trap packet too.  */
6223         nx_packet_release(trap_packet_ptr);
6224 
6225         /* Return to caller.  */
6226         return(NX_SNMP_ERROR);
6227     }
6228 
6229     /* Move the trap buffer pointer up.  */
6230     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6231 
6232     /* Adjust the trap sequence length.  */
6233     trap_sequence_length =  trap_sequence_length + trap_length;
6234 
6235     /* Adjust the trap request type length.  */
6236     trap_type_length =  trap_type_length + trap_length;
6237 
6238     /* Adjust the trap variable list size.  */
6239     trap_variable_list_length =  trap_variable_list_length + trap_length;
6240 
6241     /* Place the snmpTrapOID object ID into the trap buffer.  */
6242     trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, (UCHAR *) "1.3.6.1.6.3.1.1.4.1.0", trap_packet_ptr -> nx_packet_data_end);
6243 
6244     /* Check for a valid operation.  */
6245     if (trap_length == 0)
6246     {
6247 
6248         /* Release the trap packet.  */
6249         nx_packet_release(trap_packet_ptr);
6250 
6251         /* Done, return to caller.  */
6252         return(NX_SNMP_ERROR);
6253     }
6254 
6255     /* Move the trap buffer pointer up.  */
6256     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6257 
6258     /* Adjust the trap sequence length.  */
6259     trap_sequence_length =  trap_sequence_length + trap_length;
6260 
6261     /* Adjust the trap request type length.  */
6262     trap_type_length =  trap_type_length + trap_length;
6263 
6264     /* Adjust the trap variable list size.  */
6265     trap_variable_list_length =  trap_variable_list_length + trap_length;
6266 
6267     /* Adjust the trap variable size.  */
6268     trap_variable_length =  trap_variable_length + trap_length;
6269 
6270     /* Set a Object ID for the data.  */
6271     trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_OBJECT_ID;
6272     trap_object_data.nx_snmp_object_data_msw =   0;
6273 
6274     /* Check oid length.  */
6275     if (_nx_utility_string_length_check((CHAR *)oid, NX_NULL, NX_SNMP_MAX_OCTET_STRING))
6276     {
6277 
6278         /* Release the trap packet.  */
6279         nx_packet_release(trap_packet_ptr);
6280 
6281         /* Done, return to caller.  */
6282         return(NX_SNMP_ERROR);
6283     }
6284 
6285     _nx_snmp_object_copy(oid, trap_object_data.nx_snmp_object_octet_string);
6286     trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
6287 
6288     /* Check for a valid operation.  */
6289     if (trap_length == 0)
6290     {
6291 
6292         /* Release the trap packet.  */
6293         nx_packet_release(trap_packet_ptr);
6294 
6295         /* Done, return to caller.  */
6296         return(NX_SNMP_ERROR);
6297     }
6298 
6299     /* Move the trap buffer pointer up.  */
6300     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6301 
6302     /* Adjust the trap sequence length.  */
6303     trap_sequence_length =  trap_sequence_length + trap_length;
6304 
6305     /* Adjust the trap request type length.  */
6306     trap_type_length =  trap_type_length + trap_length;
6307 
6308     /* Adjust the trap variable list size.  */
6309     trap_variable_list_length =  trap_variable_list_length + trap_length;
6310 
6311     /* Adjust the trap variable size.  */
6312     trap_variable_length =  trap_variable_length + trap_length;
6313 
6314     /* Now update the trap variable sequence with the actual variable length.  */
6315     _nx_snmp_utility_sequence_set(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
6316 
6317     /* Default the object pointer to NULL.  */
6318     trap_object_ptr =  NX_NULL;
6319 
6320     /* Determine if an object is specified.  */
6321     if (object_list_ptr)
6322     {
6323 
6324         /* Setup object pointers from the supplied object list.  */
6325         trap_object_ptr =       object_list_ptr -> nx_snmp_object_string_ptr;
6326         trap_object_data_ptr =  object_list_ptr -> nx_snmp_object_data;
6327 
6328         /* Check for a valid operation.  */
6329         if(trap_object_ptr != NX_NULL && trap_object_data_ptr == NX_NULL)
6330         {
6331             /* Release the trap packet.  */
6332             nx_packet_release(trap_packet_ptr);
6333 
6334             /* Done, return to caller.  */
6335             return(NX_SNMP_ERROR);
6336         }
6337     }
6338 
6339     /* Loop to process all the objects in the list.  */
6340     while (trap_object_ptr)
6341     {
6342 
6343         /* Clear the trap variable length.  */
6344         trap_variable_length =  0;
6345 
6346         /* Remember the start of the variable.  */
6347         trap_variable_ptr =  trap_buffer_ptr;
6348 
6349         /* Setup the variable trap sequence.  For now, the length will be zero.  We
6350            will overwrite this with the actual length later.  */
6351         trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
6352 
6353         /* Check for a valid operation.  */
6354         if (trap_length == 0)
6355         {
6356 
6357             /* Increment the internal error counter.  */
6358             agent_ptr -> nx_snmp_agent_internal_errors++;
6359 
6360             /* Release the trap packet too.  */
6361             nx_packet_release(trap_packet_ptr);
6362 
6363             /* Return to caller.  */
6364             return(NX_SNMP_ERROR);
6365         }
6366 
6367         /* Move the trap buffer pointer up.  */
6368         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6369 
6370         /* Adjust the trap sequence length.  */
6371         trap_sequence_length =  trap_sequence_length + trap_length;
6372 
6373         /* Adjust the trap request type length.  */
6374         trap_type_length =  trap_type_length + trap_length;
6375 
6376         /* Adjust the trap variable list size.  */
6377         trap_variable_list_length =  trap_variable_list_length + trap_length;
6378 
6379         /* Place the object into the trap buffer.  */
6380         trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, trap_object_ptr, trap_packet_ptr -> nx_packet_data_end);
6381 
6382         /* Check for a valid operation.  */
6383         if (trap_length == 0)
6384         {
6385 
6386             /* Release the trap packet.  */
6387             nx_packet_release(trap_packet_ptr);
6388 
6389             /* Done, return to caller.  */
6390             return(NX_SNMP_ERROR);
6391         }
6392 
6393         /* Move the trap buffer pointer up.  */
6394         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6395 
6396         /* Adjust the trap sequence length.  */
6397         trap_sequence_length =  trap_sequence_length + trap_length;
6398 
6399         /* Adjust the trap request type length.  */
6400         trap_type_length =  trap_type_length + trap_length;
6401 
6402         /* Adjust the trap variable list size.  */
6403         trap_variable_list_length =  trap_variable_list_length + trap_length;
6404 
6405         /* Adjust the trap variable size.  */
6406         trap_variable_length =  trap_variable_length + trap_length;
6407 
6408         /* Insert the object's data into the trap buffer.  */
6409         trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, trap_object_data_ptr, trap_packet_ptr -> nx_packet_data_end);
6410 
6411         /* Check for a valid operation.  */
6412         if (trap_length == 0)
6413         {
6414 
6415             /* Release the trap packet.  */
6416             nx_packet_release(trap_packet_ptr);
6417 
6418             /* Done, return to caller.  */
6419             return(NX_SNMP_ERROR);
6420         }
6421 
6422         /* Move the trap buffer pointer up.  */
6423         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6424 
6425         /* Adjust the trap sequence length.  */
6426         trap_sequence_length =  trap_sequence_length + trap_length;
6427 
6428         /* Adjust the trap request type length.  */
6429         trap_type_length =  trap_type_length + trap_length;
6430 
6431         /* Adjust the trap variable list size.  */
6432         trap_variable_list_length =  trap_variable_list_length + trap_length;
6433 
6434         /* Adjust the trap variable size.  */
6435         trap_variable_length =  trap_variable_length + trap_length;
6436 
6437         /* Now update the trap variable sequence with the actual variable length.  */
6438         _nx_snmp_utility_sequence_set(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
6439 
6440         /* Default the object pointer to NULL.  */
6441         trap_object_ptr =  NX_NULL;
6442 
6443         /* Determine if there are more objects to insert into the trap message.  */
6444         if (object_list_ptr)
6445         {
6446 
6447             /* Move to the next object in the list.  */
6448             object_list_ptr++;
6449 
6450             if (object_list_ptr == NX_NULL)
6451             {
6452                 /* Release the trap packet.  */
6453                 nx_packet_release(trap_packet_ptr);
6454 
6455                 /* Done, return to caller.  */
6456                 return(NX_SNMP_ERROR);
6457             }
6458 
6459             /* Determine if there is another object.  */
6460             if (object_list_ptr -> nx_snmp_object_string_ptr)
6461             {
6462 
6463                 /* Setup the object and object data pointers.  */
6464                 trap_object_ptr =       object_list_ptr -> nx_snmp_object_string_ptr;
6465                 trap_object_data_ptr =  object_list_ptr -> nx_snmp_object_data;
6466 
6467                 /* Check for a valid operation.  */
6468                 if(trap_object_ptr != NX_NULL && trap_object_data_ptr == NX_NULL)
6469                 {
6470                     /* Release the trap packet.  */
6471                     nx_packet_release(trap_packet_ptr);
6472 
6473                     /* Done, return to caller.  */
6474                     return(NX_SNMP_ERROR);
6475                 }
6476             }
6477         }
6478     }
6479 
6480     /* At this point, several trap fields need to be updated with actual lengths.  */
6481     _nx_snmp_utility_sequence_set(trap_sequence_ptr, trap_sequence_length, trap_packet_ptr -> nx_packet_data_end);
6482     _nx_snmp_utility_sequence_set(trap_variable_list_ptr, trap_variable_list_length, trap_packet_ptr -> nx_packet_data_end);
6483     _nx_snmp_utility_request_type_set_multibyte(trap_type_ptr, NX_SNMP_ANS1_TRAP2_REQUEST, trap_type_length, trap_packet_ptr -> nx_packet_data_end);
6484 
6485     /* Now the trap packet's pointers must be setup so it can be sent.  */
6486     trap_packet_ptr -> nx_packet_length =  (ULONG)(trap_buffer_ptr - trap_packet_ptr -> nx_packet_prepend_ptr);
6487     trap_packet_ptr -> nx_packet_append_ptr =  trap_buffer_ptr;
6488 
6489     /* Update various statistics.  */
6490     agent_ptr -> nx_snmp_agent_traps_sent++;
6491     agent_ptr -> nx_snmp_agent_packets_sent++;
6492 
6493 
6494     /* Send the trap packet back to the requesting SNMP manager. */
6495 
6496     status = nxd_udp_socket_send(&(agent_ptr -> nx_snmp_agent_socket), trap_packet_ptr, ipduo_address, NX_SNMP_MANAGER_TRAP_PORT);
6497 
6498     /* Determine if the packet needs to be released. */
6499     if (status)
6500     {
6501 
6502         /* Release packet.  */
6503         nx_packet_release(trap_packet_ptr);
6504 
6505         /* Return an error.  */
6506         return(NX_SNMP_ERROR);
6507     }
6508 
6509     /* Return completion status.  */
6510     return(NX_SUCCESS);
6511 }
6512 
6513 
6514 #endif /* NX_SNMP_DISABLE_V2 */
6515 
6516 
6517 #ifndef NX_SNMP_DISABLE_V3
6518 /**************************************************************************/
6519 /*                                                                        */
6520 /*  FUNCTION                                               RELEASE        */
6521 /*                                                                        */
6522 /*    _nxe_snmp_agent_trapv3_send                         PORTABLE C      */
6523 /*                                                           6.1          */
6524 /*  AUTHOR                                                                */
6525 /*                                                                        */
6526 /*    Yuxin Zhou, Microsoft Corporation                                   */
6527 /*                                                                        */
6528 /*  DESCRIPTION                                                           */
6529 /*                                                                        */
6530 /*    This function checks for errors in the NetX (IPv4) SNMP agent v3    */
6531 /*    trap send service.                                                  */
6532 /*                                                                        */
6533 /*  INPUT                                                                 */
6534 /*                                                                        */
6535 /*    agent_ptr                             Pointer to SNMP agent         */
6536 /*    ip_address                            Destination IPv4 address      */
6537 /*    username                              Username                      */
6538 /*    trap_type                             Type of trap                  */
6539 /*    elapsed_time                          Elapsed time from last boot   */
6540 /*                                            of the device (sysUpTime)   */
6541 /*    object_list_ptr                       Variable list of application  */
6542 /*                                            objects to present with the */
6543 /*                                            trap                        */
6544 /*                                                                        */
6545 /*  OUTPUT                                                                */
6546 /*                                                                        */
6547 /*    status                                Completion status             */
6548 /*                                                                        */
6549 /*  CALLS                                                                 */
6550 /*                                                                        */
6551 /*    _nx_snmp_agent_trapv3_send            Actual NetX (IPv4) SNMP agent */
6552 /*                                            trap send service           */
6553 /*                                                                        */
6554 /*  CALLED BY                                                             */
6555 /*                                                                        */
6556 /*    Application Code                                                    */
6557 /*                                                                        */
6558 /*  RELEASE HISTORY                                                       */
6559 /*                                                                        */
6560 /*    DATE              NAME                      DESCRIPTION             */
6561 /*                                                                        */
6562 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6563 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6564 /*                                            resulting in version 6.1    */
6565 /*                                                                        */
6566 /**************************************************************************/
_nxe_snmp_agent_trapv3_send(NX_SNMP_AGENT * agent_ptr,ULONG ip_address,UCHAR * username,UINT trap_type,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)6567 UINT  _nxe_snmp_agent_trapv3_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *username, UINT trap_type,
6568                                   ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
6569 {
6570 
6571 #ifndef NX_DISABLE_IPV4
6572 UINT    status;
6573 
6574 
6575     /* Check for invalid input pointers.  */
6576     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID)
6577         || (username == NX_NULL) || (ip_address == NX_NULL))
6578         return(NX_PTR_ERROR);
6579 
6580     /* Call actual service.  */
6581     status =  _nx_snmp_agent_trapv3_send(agent_ptr, ip_address, username, trap_type, elapsed_time, object_list_ptr);
6582 
6583     /* Return status.  */
6584     return(status);
6585 #else
6586     NX_PARAMETER_NOT_USED(agent_ptr);
6587     NX_PARAMETER_NOT_USED(ip_address);
6588     NX_PARAMETER_NOT_USED(username);
6589     NX_PARAMETER_NOT_USED(trap_type);
6590     NX_PARAMETER_NOT_USED(elapsed_time);
6591     NX_PARAMETER_NOT_USED(object_list_ptr);
6592 
6593     return(NX_NOT_SUPPORTED);
6594 #endif /* NX_DISABLE_IPV4 */
6595 }
6596 
6597 
6598 /**************************************************************************/
6599 /*                                                                        */
6600 /*  FUNCTION                                               RELEASE        */
6601 /*                                                                        */
6602 /*    _nx_snmp_agent_trapv3_send                          PORTABLE C      */
6603 /*                                                           6.1          */
6604 /*  AUTHOR                                                                */
6605 /*                                                                        */
6606 /*    Yuxin Zhou, Microsoft Corporation                                   */
6607 /*                                                                        */
6608 /*  DESCRIPTION                                                           */
6609 /*                                                                        */
6610 /*    This function stores the input IPv4 destination IP address in a NetX*/
6611 /*    Duo data type that supports IPv4 and IPv6 address formats, and      */
6612 /*    uses the 'dual' trap send service _nxd_snmp_agent_trap_send to build*/
6613 /*    and send the SNMPv3 trap message.                                   */
6614 /*                                                                        */
6615 /*    Developers are encouraged to use nxd_snmp_agent_trapv3_send.        */
6616 /*                                                                        */
6617 /*  INPUT                                                                 */
6618 /*                                                                        */
6619 /*    agent_ptr                             Pointer to SNMP agent         */
6620 /*    ip_address                            Destination IPv4 address      */
6621 /*    username                              Username                      */
6622 /*    trap_type                             Type of trap                  */
6623 /*    elapsed_time                          Elapsed time from last boot   */
6624 /*                                            of the device (sysUpTime)   */
6625 /*    object_list_ptr                       Variable list of application  */
6626 /*                                            objects to present with the */
6627 /*                                            trap                        */
6628 /*                                                                        */
6629 /*  OUTPUT                                                                */
6630 /*                                                                        */
6631 /*    status                                Completion status             */
6632 /*    NX_NOT_ENABLED                        Agent not enabled for V3      */
6633 /*                                                                        */
6634 /*  CALLS                                                                 */
6635 /*                                                                        */
6636 /*    _nxd_snmp_agent_trapv3_send           Actual SNMPv3  trap send      */
6637 /*                                            service                     */
6638 /*                                                                        */
6639 /*  CALLED BY                                                             */
6640 /*                                                                        */
6641 /*    Application Code                                                    */
6642 /*                                                                        */
6643 /*  RELEASE HISTORY                                                       */
6644 /*                                                                        */
6645 /*    DATE              NAME                      DESCRIPTION             */
6646 /*                                                                        */
6647 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6648 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6649 /*                                            resulting in version 6.1    */
6650 /*                                                                        */
6651 /**************************************************************************/
_nx_snmp_agent_trapv3_send(NX_SNMP_AGENT * agent_ptr,ULONG ip_address,UCHAR * username,UINT trap_type,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)6652 UINT  _nx_snmp_agent_trapv3_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *username, UINT trap_type,
6653                                  ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
6654 {
6655 
6656 #ifndef NX_DISABLE_IPV4
6657 UINT        status;
6658 NXD_ADDRESS ip_nxduo_address;
6659 
6660     ip_nxduo_address.nxd_ip_version = NX_IP_VERSION_V4;
6661     ip_nxduo_address.nxd_ip_address.v4 = ip_address;
6662 
6663     status =  _nxd_snmp_agent_trapv3_send(agent_ptr, &ip_nxduo_address, username, trap_type, elapsed_time, object_list_ptr);
6664     return status;
6665 #else
6666     NX_PARAMETER_NOT_USED(agent_ptr);
6667     NX_PARAMETER_NOT_USED(ip_address);
6668     NX_PARAMETER_NOT_USED(username);
6669     NX_PARAMETER_NOT_USED(trap_type);
6670     NX_PARAMETER_NOT_USED(elapsed_time);
6671     NX_PARAMETER_NOT_USED(object_list_ptr);
6672 
6673     return(NX_NOT_SUPPORTED);
6674 #endif /* NX_DISABLE_IPV4 */
6675 }
6676 
6677 
6678 /**************************************************************************/
6679 /*                                                                        */
6680 /*  FUNCTION                                               RELEASE        */
6681 /*                                                                        */
6682 /*    _nxde_snmp_agent_trapv3_send                        PORTABLE C      */
6683 /*                                                           6.1          */
6684 /*  AUTHOR                                                                */
6685 /*                                                                        */
6686 /*    Yuxin Zhou, Microsoft Corporation                                   */
6687 /*                                                                        */
6688 /*  DESCRIPTION                                                           */
6689 /*                                                                        */
6690 /*    This function checks for errors in the SNMPv3 trap send service.    */
6691 /*                                                                        */
6692 /*    Developers are encouraged to use the nxd_snmp_agent_trapv3_send     */
6693 /*    service which supports IPv4 and IPv6 types.                         */
6694 /*                                                                        */
6695 /*  INPUT                                                                 */
6696 /*                                                                        */
6697 /*    agent_ptr                             Pointer to SNMP agent         */
6698 /*    ip_address                            Destination IP address        */
6699 /*    username                              Username                      */
6700 /*    trap_type                             Type of trap                  */
6701 /*    elapsed_time                          Elapsed time from last boot   */
6702 /*                                            of the device (sysUpTime)   */
6703 /*    object_list_ptr                       Variable list of application  */
6704 /*                                            objects to present with the */
6705 /*                                            trap                        */
6706 /*                                                                        */
6707 /*  OUTPUT                                                                */
6708 /*                                                                        */
6709 /*    status                                Completion status             */
6710 /*                                                                        */
6711 /*  CALLS                                                                 */
6712 /*                                                                        */
6713 /*    _nxd_snmp_agent_trapv3_send           Actual NetX Duo SNMP agent    */
6714 /*                                            trap send service           */
6715 /*                                                                        */
6716 /*  CALLED BY                                                             */
6717 /*                                                                        */
6718 /*    Application Code                                                    */
6719 /*                                                                        */
6720 /*  RELEASE HISTORY                                                       */
6721 /*                                                                        */
6722 /*    DATE              NAME                      DESCRIPTION             */
6723 /*                                                                        */
6724 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6725 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6726 /*                                            resulting in version 6.1    */
6727 /*                                                                        */
6728 /**************************************************************************/
_nxde_snmp_agent_trapv3_send(NX_SNMP_AGENT * agent_ptr,NXD_ADDRESS * ip_address,UCHAR * username,UINT trap_type,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)6729 UINT  _nxde_snmp_agent_trapv3_send(NX_SNMP_AGENT *agent_ptr, NXD_ADDRESS *ip_address, UCHAR *username, UINT trap_type,
6730                                   ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
6731 {
6732 
6733 UINT    status;
6734 
6735 
6736     /* Check for invalid input pointers.  */
6737     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID)
6738         || (username == NX_NULL) || (ip_address == NX_NULL))
6739         return(NX_PTR_ERROR);
6740 
6741     /* Call actual service.  */
6742     status =  _nxd_snmp_agent_trapv3_send(agent_ptr, ip_address, username, trap_type, elapsed_time, object_list_ptr);
6743 
6744     /* Return status.  */
6745     return(status);
6746 }
6747 
6748 
6749 /**************************************************************************/
6750 /*                                                                        */
6751 /*  FUNCTION                                               RELEASE        */
6752 /*                                                                        */
6753 /*    _nxd_snmp_agent_trapv3_send                         PORTABLE C      */
6754 /*                                                           6.1          */
6755 /*  AUTHOR                                                                */
6756 /*                                                                        */
6757 /*    Yuxin Zhou, Microsoft Corporation                                   */
6758 /*                                                                        */
6759 /*  DESCRIPTION                                                           */
6760 /*                                                                        */
6761 /*    This function builds and sends a SNMP v3 trap message to the input  */
6762 /*    destination address.  This service supports both IPv4 and IPv6      */
6763 /*    addresses.                                                          */
6764 /*                                                                        */
6765 /*    Note: The string length of username is limited by the packet        */
6766 /*    payload and NX_SNMP_MAX_OCTET_STRING.                               */
6767 /*                                                                        */
6768 /*  INPUT                                                                 */
6769 /*                                                                        */
6770 /*    agent_ptr                             Pointer to SNMP agent         */
6771 /*    ip_address                            Destination IP address        */
6772 /*    username                              Username                      */
6773 /*    trap_type                             Type of trap                  */
6774 /*    elapsed_time                          Elapsed time from last boot   */
6775 /*                                            of the device (sysUpTime)   */
6776 /*    object_list_ptr                       Variable list of application  */
6777 /*                                            objects to present with the */
6778 /*                                            trap                        */
6779 /*                                                                        */
6780 /*  OUTPUT                                                                */
6781 /*                                                                        */
6782 /*    status                                Completion status             */
6783 /*                                                                        */
6784 /*  CALLS                                                                 */
6785 /*                                                                        */
6786 /*    _nx_des_key_set                       Setup DES encryption          */
6787 /*    _nx_des_encrypt                       Encrypt bytes                 */
6788 /*    _nx_md5_digest_calculate              MD5 algorithm completion      */
6789 /*    _nx_md5_initialize                    MD5 algorithm initialization  */
6790 /*    _nx_md5_update                        MD5 algorithm computation     */
6791 /*    nx_packet_allocate                    Allocate SNMP trap packet     */
6792 /*    nx_packet_release                     Release SNMP packet           */
6793 /*    nx_udp_socket_send                    Send SNMP trap via UDP        */
6794 /*    _nx_snmp_object_copy                  Copy object                   */
6795 /*    _nx_snmp_utility_error_info_set       Set error information         */
6796 /*    _nx_snmp_utility_octet_set            Set octet string              */
6797 /*    _nx_snmp_utility_object_data_set      Set the data value            */
6798 /*    _nx_snmp_utility_object_id_set        Set the object ID             */
6799 /*    _nx_snmp_utility_sequence_set         Set the ASN.1 sequence        */
6800 /*    _nx_snmp_utility_request_id_set       Set the Request ID            */
6801 /*    _nx_snmp_utility_request_type_set_1byte  Set trap request type      */
6802 /*    _nx_snmp_utility_version_set          Set the SNMP v3               */
6803 /*    _nx_sha1_digest_calculate             SHA algorithm completion      */
6804 /*    _nx_sha1_initialize                   SHA algorithm initialization  */
6805 /*    _nx_sha1_update                       SHA algorithm computation     */
6806 /*    tx_time_get                           Get time                      */
6807 /*                                                                        */
6808 /*  CALLED BY                                                             */
6809 /*                                                                        */
6810 /*    Application Code                                                    */
6811 /*                                                                        */
6812 /*  RELEASE HISTORY                                                       */
6813 /*                                                                        */
6814 /*    DATE              NAME                      DESCRIPTION             */
6815 /*                                                                        */
6816 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6817 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6818 /*                                            resulting in version 6.1    */
6819 /*                                                                        */
6820 /**************************************************************************/
_nxd_snmp_agent_trapv3_send(NX_SNMP_AGENT * agent_ptr,NXD_ADDRESS * ip_address,UCHAR * username,UINT trap_type,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)6821 UINT  _nxd_snmp_agent_trapv3_send(NX_SNMP_AGENT *agent_ptr, NXD_ADDRESS *ip_address, UCHAR *username, UINT trap_type, ULONG elapsed_time,
6822                                   NX_SNMP_TRAP_OBJECT *object_list_ptr)
6823 {
6824 
6825 UINT                 status;
6826 UINT                 trap_length;
6827 UCHAR                *trap_object_ptr;
6828 NX_SNMP_OBJECT_DATA  trap_object_data;
6829 NX_SNMP_OBJECT_DATA *trap_object_data_ptr = NX_NULL;
6830 NX_PACKET           *trap_packet_ptr;
6831 UCHAR               *trap_buffer_ptr, *trap_sequence_ptr, *trap_header_ptr, *trap_security_ptr, *trap_pdu_ptr, *trap_type_ptr, *trap_variable_list_ptr, *trap_variable_ptr;
6832 UINT                 trap_sequence_length, trap_header_length, trap_security_length, trap_pdu_length, trap_type_length, trap_variable_list_length, trap_variable_length;
6833 UCHAR                temp_string[NX_SNMP_DIGEST_SIZE];
6834 UINT                 i;
6835 UCHAR               *temp_ptr;
6836 UINT                j, padding;
6837 UCHAR               *trap_encryption_size_ptr = NX_NULL;
6838 UCHAR               *trap_authentication_ptr = NX_NULL, *trap_privacy_ptr = NX_NULL;
6839 UCHAR               key1[NX_SNMP_DIGEST_WORKING_SIZE];
6840 UCHAR               key2[NX_SNMP_DIGEST_WORKING_SIZE];
6841 UINT                packet_type;
6842 UCHAR               message_security_options = 0;
6843 UINT                username_length;
6844 
6845 
6846     /* Verify V3 is currently enabled for this agent. */
6847     if (agent_ptr -> nx_snmp_agent_v3_enabled == NX_FALSE)
6848     {
6849 
6850         return NX_NOT_ENABLED;
6851     }
6852 
6853     /* Determine which packet type we allocate based on the destination address type.  */
6854     if (ip_address -> nxd_ip_version == NX_IP_VERSION_V4)
6855     {
6856         packet_type = NX_IPv4_UDP_PACKET;
6857     }
6858     else if (ip_address -> nxd_ip_version == NX_IP_VERSION_V6)
6859     {
6860 #ifndef FEATURE_NX_IPV6
6861         return NX_SNMP_INVALID_IP_PROTOCOL_ERROR;
6862 #else
6863         packet_type = NX_IPv6_UDP_PACKET;
6864 #endif
6865     }
6866     else
6867     {
6868         return NX_SNMP_INVALID_IP_PROTOCOL_ERROR;
6869     }
6870 
6871     /* Allocate the packet for the SNMP response.  */
6872     status =  nx_packet_allocate(agent_ptr -> nx_snmp_agent_packet_pool_ptr, &trap_packet_ptr, packet_type, NX_SNMP_AGENT_TIMEOUT);
6873 
6874     /* Determine if a trap packet was allocated.  */
6875     if (status)
6876     {
6877 
6878         /* Increment the packet allocation error counter.  */
6879         agent_ptr -> nx_snmp_agent_allocation_errors++;
6880 
6881         /* Return to caller.  */
6882         return(NX_SNMP_ERROR);
6883     }
6884 
6885     memset(trap_packet_ptr -> nx_packet_prepend_ptr, 0,
6886            (UINT)(trap_packet_ptr -> nx_packet_data_end - trap_packet_ptr -> nx_packet_prepend_ptr));
6887 
6888     /* Initialize the counters required for the length fields of the trap packet.  */
6889     trap_sequence_length =       0;
6890     trap_header_length =         0;
6891     trap_security_length =       0;
6892     trap_pdu_length =            0;
6893     trap_type_length =           0;
6894     trap_variable_list_length =  0;
6895     trap_variable_length =       0;
6896 
6897     /* Setup a pointer to the trap packet's buffer area.  */
6898     trap_buffer_ptr =  trap_packet_ptr -> nx_packet_prepend_ptr;
6899 
6900 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
6901     NX_SNMPV3_DBG_PRINTF("Starting trap buffer response at 0x%x\n", trap_buffer_ptr);
6902 #endif
6903     /* This is also the trap sequence pointer. Remember it since we are going to have to
6904        update it later with the actual length of the response.  */
6905     trap_sequence_ptr =  trap_buffer_ptr;
6906 
6907     /* First, write the sequence in the trap packet.  A zero is written for now.  This will be
6908        updated later.  */
6909     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
6910 
6911     /* Check for a valid operation.  */
6912     if (trap_length == 0)
6913     {
6914 
6915         /* Increment the internal error counter.  */
6916         agent_ptr -> nx_snmp_agent_internal_errors++;
6917 
6918         /* Release the trap packet too.  */
6919         nx_packet_release(trap_packet_ptr);
6920 
6921         /* Return to caller.  */
6922         return(NX_SNMP_ERROR);
6923     }
6924 
6925     /* Move the trap buffer pointer up.  */
6926     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6927 
6928 
6929     /* Now set the Version ID in the trap message.  */
6930     trap_length =  _nx_snmp_utility_version_set(trap_buffer_ptr, NX_SNMP_VERSION_3, trap_packet_ptr -> nx_packet_data_end);
6931 
6932     /* Check for a valid operation.  */
6933     if (trap_length == 0)
6934     {
6935 
6936         /* Increment the internal error counter.  */
6937         agent_ptr -> nx_snmp_agent_internal_errors++;
6938 
6939         /* Release the trap packet.  */
6940         nx_packet_release(trap_packet_ptr);
6941 
6942         /* Return to caller.  */
6943         return(NX_SNMP_ERROR);
6944     }
6945 
6946     /* Move the trap buffer pointer up.  */
6947     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6948 
6949     /* Adjust the trap sequence length.  */
6950     trap_sequence_length =  trap_sequence_length + trap_length;
6951 
6952     /* Save the pointer to the global header.  */
6953     trap_header_ptr =  trap_buffer_ptr;
6954 
6955 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
6956     NX_SNMPV3_DBG_PRINTF("Starting trap3 header header at 0x%x\n", trap_header_ptr);
6957 #endif
6958 
6959     /* Write the sequence for the global header in the trap packet.  A zero is written for now.
6960        This will be updated later.  */
6961     trap_length =  _nx_snmp_utility_sequence_set_1byte(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
6962 
6963     /* Check for a valid operation.  */
6964     if (trap_length == 0)
6965     {
6966 
6967         /* Increment the internal error counter.  */
6968         agent_ptr -> nx_snmp_agent_internal_errors++;
6969 
6970         /* Release the trap packet too.  */
6971         nx_packet_release(trap_packet_ptr);
6972 
6973         /* Return to caller.  */
6974         return(NX_SNMP_ERROR);
6975     }
6976 
6977     /* Move the trap buffer pointer up.  */
6978     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
6979 
6980     /* Adjust the trap sequence length.  */
6981     trap_sequence_length =  trap_sequence_length + trap_length;
6982 
6983     /***************8 Now set the request ID.  *********************8*/
6984     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_traps_sent, trap_packet_ptr -> nx_packet_data_end);
6985 
6986     /* Check for a valid operation.  */
6987     if (trap_length == 0)
6988     {
6989 
6990         /* Increment the internal error counter.  */
6991         agent_ptr -> nx_snmp_agent_internal_errors++;
6992 
6993         /* Release the trap packet too.  */
6994         nx_packet_release(trap_packet_ptr);
6995 
6996         /* Return to caller.  */
6997         return(NX_SNMP_ERROR);
6998     }
6999 
7000     /* Move the trap buffer pointer up.  */
7001     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7002 
7003     /* Adjust the trap sequence length.  */
7004     trap_sequence_length =  trap_sequence_length + trap_length;
7005 
7006     /* Adjust the header sequence length.  */
7007     trap_header_length =  trap_header_length + trap_length;
7008 
7009     /********************* Now set the maximum message size.  ***************************8*/
7010     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, (NX_SNMP_PACKET_SIZE - NX_UDP_PACKET), trap_packet_ptr -> nx_packet_data_end);
7011 
7012     /* Check for a valid operation.  */
7013     if (trap_length == 0)
7014     {
7015 
7016         /* Increment the internal error counter.  */
7017         agent_ptr -> nx_snmp_agent_internal_errors++;
7018 
7019         /* Release the trap packet too.  */
7020         nx_packet_release(trap_packet_ptr);
7021 
7022         /* Return to caller.  */
7023         return(NX_SNMP_ERROR);
7024     }
7025 
7026     /* Move the trap buffer pointer up.  */
7027     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7028 
7029     /* Adjust the trap sequence length.  */
7030     trap_sequence_length =  trap_sequence_length + trap_length;
7031 
7032     /* Adjust the header sequence length.  */
7033     trap_header_length =  trap_header_length + trap_length;
7034 
7035     /********************** Now set the security options e.g. Flags.  ****************************/
7036 
7037     /* Determine what the trap message security options are. These are not the same as
7038        the general get/set request PDU options.  */
7039     if (agent_ptr -> nx_snmp_agent_v3_auth_trap_key)
7040     {
7041         message_security_options = NX_SNMP_SECURITY_AUTHORIZE;
7042     }
7043     if (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)
7044     {
7045         message_security_options |= NX_SNMP_SECURITY_PRIVACY;
7046     }
7047 
7048     trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, (UCHAR *)&message_security_options, 1, trap_packet_ptr -> nx_packet_data_end);
7049 
7050     /* Check for a valid operation.  */
7051     if (trap_length == 0)
7052     {
7053 
7054         /* Increment the internal error counter.  */
7055         agent_ptr -> nx_snmp_agent_internal_errors++;
7056 
7057         /* Release the trap packet too.  */
7058         nx_packet_release(trap_packet_ptr);
7059 
7060         /* Return to caller.  */
7061         return(NX_SNMP_ERROR);
7062     }
7063 
7064     /* Move the trap buffer pointer up.  */
7065     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7066 
7067     /* Adjust the trap sequence length.  */
7068     trap_sequence_length =  trap_sequence_length + trap_length;
7069 
7070     /* Adjust the header sequence length.  */
7071     trap_header_length =  trap_header_length + trap_length;
7072 
7073     /******************* Now set the security type (always USM model).  *********************/
7074     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, NX_SNMP_USM_SECURITY_MODEL, trap_packet_ptr -> nx_packet_data_end);
7075 
7076     /* Check for a valid operation.  */
7077     if (trap_length == 0)
7078     {
7079 
7080         /* Increment the internal error counter.  */
7081         agent_ptr -> nx_snmp_agent_internal_errors++;
7082 
7083         /* Release the trap packet too.  */
7084         nx_packet_release(trap_packet_ptr);
7085 
7086         /* Return to caller.  */
7087         return(NX_SNMP_ERROR);
7088     }
7089 
7090     /* Move the trap buffer pointer up.  */
7091     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7092 
7093     /* Adjust the trap sequence length.  */
7094     trap_sequence_length =  trap_sequence_length + trap_length;
7095 
7096     /* Adjust the header sequence length.  */
7097     trap_header_length =  trap_header_length + trap_length;
7098 
7099     /* At this point, we have successfully built the security header.  */
7100 
7101 
7102     /************************** Start the security parameters field. ************************/
7103 
7104     /* First set up the octet string field. For now just put in zeros... we will update when
7105       the actual size is known.  */
7106     trap_buffer_ptr[0] =  NX_SNMP_ANS1_OCTET_STRING;
7107     trap_buffer_ptr[1] =  0;
7108 
7109     /* Move the trap buffer pointer up.  */
7110     trap_buffer_ptr =  trap_buffer_ptr + 2;
7111 
7112     /* Adjust the trap sequence length.  */
7113     trap_sequence_length =  trap_sequence_length + 2;
7114 
7115     /* Remember the security header length pointer.  */
7116     trap_security_ptr =  trap_buffer_ptr;
7117 
7118 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
7119     NX_SNMPV3_DBG_PRINTF("Starting trap3 security header 0x%x\n", trap_security_ptr);
7120 #endif
7121     /* Now set the sequence of the USM security parameters.  */
7122     trap_length =  _nx_snmp_utility_sequence_set_1byte(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
7123 
7124     /* Check for a valid operation.  */
7125     if (trap_length == 0)
7126     {
7127 
7128         /* Increment the internal error counter.  */
7129         agent_ptr -> nx_snmp_agent_internal_errors++;
7130 
7131         /* Release the trap packet too.  */
7132         nx_packet_release(trap_packet_ptr);
7133 
7134         /* Return to caller.  */
7135         return(NX_SNMP_ERROR);
7136     }
7137 
7138     /* Move the trap buffer pointer up.  */
7139     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7140 
7141     /* Adjust the trap sequence length.  */
7142     trap_sequence_length =  trap_sequence_length + trap_length;
7143 
7144     /************************** Now set the context engine.  ***************************/
7145     trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine, agent_ptr -> nx_snmp_agent_v3_context_engine_size, trap_packet_ptr -> nx_packet_data_end);
7146 
7147     /* Check for a valid operation.  */
7148     if (trap_length == 0)
7149     {
7150 
7151         /* Increment the internal error counter.  */
7152         agent_ptr -> nx_snmp_agent_internal_errors++;
7153 
7154         /* Release the trap packet too.  */
7155         nx_packet_release(trap_packet_ptr);
7156 
7157         /* Return to caller.  */
7158         return(NX_SNMP_ERROR);
7159     }
7160 
7161     /* Move the trap buffer pointer up.  */
7162     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7163 
7164     /* Adjust the trap sequence length.  */
7165     trap_sequence_length =  trap_sequence_length + trap_length;
7166 
7167     /* Adjust the security sequence length.  */
7168     trap_security_length =  trap_security_length + trap_length;
7169 
7170     /****************** *****************  **********************/
7171     /*                   Now set BOOT COUNT.                    */
7172     /****************** *****************  **********************/
7173     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine_boots, trap_packet_ptr -> nx_packet_data_end);
7174 
7175     /* Check for a valid operation.  */
7176     if (trap_length == 0)
7177     {
7178 
7179         /* Increment the internal error counter.  */
7180         agent_ptr -> nx_snmp_agent_internal_errors++;
7181 
7182         /* Release the trap packet too.  */
7183         nx_packet_release(trap_packet_ptr);
7184 
7185         /* Return to caller.  */
7186         return(NX_SNMP_ERROR);
7187     }
7188 
7189     /* Move the trap buffer pointer up.  */
7190     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7191 
7192     /* Adjust the trap sequence length.  */
7193     trap_sequence_length =  trap_sequence_length + trap_length;
7194 
7195     /* Adjust the security sequence length.  */
7196     trap_security_length =  trap_security_length + trap_length;
7197 
7198     /****************** *****************  **********************/
7199     /*                   Now set BOOT TIME.                    */
7200     /****************** *****************  **********************/
7201     agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time =  (UINT) (tx_time_get()/NX_IP_PERIODIC_RATE);
7202 
7203     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time, trap_packet_ptr -> nx_packet_data_end);
7204 
7205     /* Check for a valid operation.  */
7206     if (trap_length == 0)
7207     {
7208 
7209         /* Increment the internal error counter.  */
7210         agent_ptr -> nx_snmp_agent_internal_errors++;
7211 
7212         /* Release the trap packet too.  */
7213         nx_packet_release(trap_packet_ptr);
7214 
7215         /* Return to caller.  */
7216         return(NX_SNMP_ERROR);
7217     }
7218 
7219     /* Move the trap buffer pointer up.  */
7220     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7221 
7222     /* Adjust the trap sequence length.  */
7223     trap_sequence_length =  trap_sequence_length + trap_length;
7224 
7225     /* Adjust the security sequence length.  */
7226     trap_security_length =  trap_security_length + trap_length;
7227 
7228     /* Check username length.  */
7229     if (_nx_utility_string_length_check((CHAR *)username, &username_length, NX_SNMP_MAX_OCTET_STRING))
7230     {
7231         return(NX_SIZE_ERROR);
7232     }
7233 
7234     /****************** *****************  **********************/
7235     /*                   Now set USER NAME.                     */
7236     /****************** *****************  **********************/
7237     trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, username, username_length, trap_packet_ptr -> nx_packet_data_end);
7238 
7239     /* Check for a valid operation.  */
7240     if (trap_length == 0)
7241     {
7242 
7243         /* Increment the internal error counter.  */
7244         agent_ptr -> nx_snmp_agent_internal_errors++;
7245 
7246         /* Release the trap packet too.  */
7247         nx_packet_release(trap_packet_ptr);
7248 
7249         /* Return to caller.  */
7250         return(NX_SNMP_ERROR);
7251     }
7252 
7253     /* Move the trap buffer pointer up.  */
7254     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7255 
7256     /* Adjust the trap sequence length.  */
7257     trap_sequence_length =  trap_sequence_length + trap_length;
7258 
7259     /* Adjust the security sequence length.  */
7260     trap_security_length =  trap_security_length + trap_length;
7261 
7262     /* Initialize the temporary string to zero. */
7263     for (i = 0; i < NX_SNMP_DIGEST_SIZE; i++)
7264        temp_string[i] =  0;
7265 
7266     /****************** *****************  **********************/
7267     /*              Now set AUTHENTICATION PARAMETER.           */
7268     /****************** *****************  **********************/
7269     if (agent_ptr -> nx_snmp_agent_v3_auth_trap_key)
7270     {
7271 
7272         /* We have a valid authentication key, so initialize the string to zero. */
7273         trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, temp_string, NX_SNMP_DIGEST_SIZE, trap_packet_ptr -> nx_packet_data_end);
7274 
7275         trap_authentication_ptr =  trap_buffer_ptr + 2;
7276 
7277 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
7278         NX_SNMPV3_DBG_PRINTF("Starting trap3 authentication header 0x%x\n", trap_authentication_ptr);
7279 #endif
7280     }
7281     else
7282     {
7283         /* No security enabled so set this as an empty parameter. */
7284         trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, temp_string,0, trap_packet_ptr -> nx_packet_data_end);
7285     }
7286 
7287     /* Check for a valid operation.  */
7288     if (trap_length == 0)
7289     {
7290 
7291         /* Increment the internal error counter.  */
7292         agent_ptr -> nx_snmp_agent_internal_errors++;
7293 
7294         /* Release the trap packet too.  */
7295         nx_packet_release(trap_packet_ptr);
7296 
7297         /* Return to caller.  */
7298         return(NX_SNMP_ERROR);
7299     }
7300 
7301     /* Move the trap buffer pointer up.  */
7302     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7303 
7304     /* Adjust the trap sequence length.  */
7305     trap_sequence_length =  trap_sequence_length + trap_length;
7306 
7307     /* Adjust the security sequence length.  */
7308     trap_security_length =  trap_security_length + trap_length;
7309 
7310 
7311     /****************** *****************  **********************/
7312     /*              Now set 8 char PRIVACY PARAMETER.           */
7313     /****************** *****************  **********************/
7314     if (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)
7315     {
7316 
7317         /*  We will encrypt the message, so set to all zeros field initially. */
7318         trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, temp_string, 8, trap_packet_ptr -> nx_packet_data_end);
7319 
7320         trap_privacy_ptr =  trap_buffer_ptr + 2;
7321 
7322 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
7323         NX_SNMPV3_DBG_PRINTF("Starting trap_privacy_ptr 0x%x\n", trap_privacy_ptr);
7324 #endif
7325     }
7326     else
7327     {
7328         /* Not encrypting, so set the privacy field as an empty parameter. */
7329         trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, temp_string,0, trap_packet_ptr -> nx_packet_data_end);
7330     }
7331 
7332     /* Check for a valid operation.  */
7333     if (trap_length == 0)
7334     {
7335 
7336         /* Increment the internal error counter.  */
7337         agent_ptr -> nx_snmp_agent_internal_errors++;
7338 
7339         /* Release the trap packet too.  */
7340         nx_packet_release(trap_packet_ptr);
7341 
7342         /* Return to caller.  */
7343         return(NX_SNMP_ERROR);
7344     }
7345 
7346     /* Move the trap buffer pointer up.  */
7347     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7348 
7349     /* Adjust the trap sequence length.  */
7350     trap_sequence_length =  trap_sequence_length + trap_length;
7351 
7352     /* Adjust the security sequence length.  */
7353     trap_security_length =  trap_security_length + trap_length;
7354 
7355     /* If privacy is required, set the response to have an encryption header.  */
7356     if (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)
7357     {
7358 
7359          /* Now setup the trap buffer to encapsulate the encrypted PDU.  Note that
7360             the actual encryption will be done after the complete trap has been
7361             formed.  */
7362          trap_buffer_ptr[0] =  NX_SNMP_ANS1_OCTET_STRING;
7363          trap_buffer_ptr[1] =  0x82;
7364          trap_buffer_ptr[2] =  0x00;
7365          trap_buffer_ptr[3] =  0x00;
7366 
7367          /* Save the trap encryption size pointer.  This will be filled in below
7368             as we build the message.  */
7369          trap_encryption_size_ptr =  trap_buffer_ptr + 2;
7370 
7371          /* Move the trap buffer forward.  */
7372          trap_buffer_ptr =  trap_buffer_ptr + 4;
7373 
7374          /* Increase the length of the total trap message.  */
7375          trap_sequence_length =  trap_sequence_length + 4;
7376     }
7377 
7378     /* Save the trap pdu sequence pointer.  */
7379     trap_pdu_ptr =  trap_buffer_ptr;
7380 
7381 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
7382     NX_SNMPV3_DBG_PRINTF("Starting trap_pdu_ptr: 0x%x\n", trap_pdu_ptr);
7383 #endif
7384 
7385     /****************** *****************  **********************/
7386     /*                  Now start the PDU SEQUENCE.             */
7387     /****************** *****************  **********************/
7388 
7389     /* A zero is written for now.  This will be updated later.  */
7390     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
7391 
7392     /* Check for a valid operation.  */
7393     if (trap_length == 0)
7394     {
7395 
7396         /* Increment the internal error counter.  */
7397         agent_ptr -> nx_snmp_agent_internal_errors++;
7398 
7399         /* Release the trap packet.  */
7400         nx_packet_release(trap_packet_ptr);
7401 
7402         /* Return to caller.  */
7403         return(NX_SNMP_ERROR);
7404     }
7405 
7406     /* Move the trap buffer pointer.  */
7407     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7408 
7409     /* Increment the number of trap sequence bytes.  */
7410     trap_sequence_length =       trap_sequence_length + trap_length;
7411 
7412     /****************************************************/
7413     /*            Set the PDU engine ID                 */
7414     /****************************************************/
7415     trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine, agent_ptr -> nx_snmp_agent_v3_context_engine_size, trap_packet_ptr -> nx_packet_data_end);
7416 
7417     /* Check for a valid packet.  */
7418     if (trap_length == 0)
7419     {
7420 
7421         /* Increment the invalid packet error counter.  */
7422         agent_ptr -> nx_snmp_agent_invalid_packets++;
7423 
7424         /* Release the trap packet.  */
7425         nx_packet_release(trap_packet_ptr);
7426 
7427         /* Return to caller.  */
7428         return(NX_SNMP_ERROR);
7429     }
7430 
7431     /* Move the trap pointer forward.  */
7432     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7433 
7434     /* Increment the sequence length.  */
7435     trap_sequence_length =       trap_sequence_length + trap_length;
7436 
7437     /* Increment the pdu length.  */
7438     trap_pdu_length =            trap_pdu_length + trap_length;
7439 
7440     /****************************************************/
7441     /*            Set the PDU engine name               */
7442     /****************************************************/
7443     trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_name, agent_ptr -> nx_snmp_agent_v3_context_name_size, trap_packet_ptr -> nx_packet_data_end);
7444 
7445     /* Check for a valid packet.  */
7446     if (trap_length == 0)
7447     {
7448 
7449         /* Increment the invalid packet error counter.  */
7450         agent_ptr -> nx_snmp_agent_invalid_packets++;
7451 
7452         /* Release the trap packet.  */
7453         nx_packet_release(trap_packet_ptr);
7454 
7455         /* Return to caller.  */
7456         return(NX_SNMP_ERROR);
7457     }
7458 
7459     /* Move the trap pointer forward.  */
7460     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7461 
7462     /* Save the pointer to the trap type.  */
7463     trap_type_ptr =  trap_buffer_ptr;
7464 
7465 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
7466     NX_SNMPV3_DBG_PRINTF("Starting trap_type_ptr: 0x%x\n", trap_type_ptr);
7467 #endif
7468 
7469     /* Increment the sequence length.  */
7470     trap_sequence_length =       trap_sequence_length + trap_length;
7471 
7472     /* Increment the pdu length.  */
7473     trap_pdu_length =            trap_pdu_length + trap_length;
7474 
7475     /****************************************************/
7476     /*            Set the PDU request type              */
7477     /****************************************************/
7478     trap_length =  _nx_snmp_utility_request_type_set_multibyte(trap_buffer_ptr, NX_SNMP_ANS1_TRAP2_REQUEST, 0, trap_packet_ptr -> nx_packet_data_end);
7479 
7480     /* Check for a valid operation.  */
7481     if (trap_length == 0)
7482     {
7483 
7484         /* Increment the internal error counter.  */
7485         agent_ptr -> nx_snmp_agent_internal_errors++;
7486 
7487         /* Release the trap packet.  */
7488         nx_packet_release(trap_packet_ptr);
7489 
7490         /* Return to caller.  */
7491         return(NX_SNMP_ERROR);
7492     }
7493 
7494     /* Move the trap buffer pointer up.  */
7495     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7496 
7497     /* Adjust the trap sequence length.  */
7498     trap_sequence_length =  trap_sequence_length + trap_length;
7499 
7500     /* Increment the pdu length.  */
7501     trap_pdu_length =  trap_pdu_length + trap_length;
7502 
7503     /****************************************************/
7504     /*            Set the PDU request ID                */
7505     /****************************************************/
7506     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_traps_sent, trap_packet_ptr -> nx_packet_data_end);
7507 
7508     /* Check for a valid operation.  */
7509     if (trap_length == 0)
7510     {
7511 
7512         /* Increment the internal error counter.  */
7513         agent_ptr -> nx_snmp_agent_internal_errors++;
7514 
7515         /* Release the trap packet.  */
7516         nx_packet_release(trap_packet_ptr);
7517 
7518         /* Return to caller.  */
7519         return(NX_SNMP_ERROR);
7520     }
7521 
7522     /* Move the trap buffer pointer up (this assumes two bytes but we may need more) .  */
7523     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7524 
7525     /* Adjust the trap sequence length.  */
7526     trap_sequence_length =  trap_sequence_length + trap_length;
7527 
7528     /* Increment the pdu length.  */
7529     trap_pdu_length =  trap_pdu_length + trap_length;
7530 
7531     /* Adjust the trap request type length.  */
7532     trap_type_length =  trap_type_length + trap_length;
7533 
7534     /****************************************************/
7535     /*            Get the PDU error information         */
7536     /****************************************************/
7537 
7538     /* Assume everything is okay at this point.  */
7539     trap_length =  _nx_snmp_utility_error_info_set(trap_buffer_ptr, 0, 0, trap_packet_ptr -> nx_packet_data_end);
7540 
7541     /* Check for a valid operation.  */
7542     if (trap_length == 0)
7543     {
7544 
7545         /* Increment the internal error counter.  */
7546         agent_ptr -> nx_snmp_agent_internal_errors++;
7547 
7548         /* Release the trap packet.  */
7549         nx_packet_release(trap_packet_ptr);
7550 
7551         /* Return to caller.  */
7552         return(NX_SNMP_ERROR);
7553     }
7554 
7555     /* Move the trap buffer pointer up.  */
7556     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7557 
7558     /* Adjust the trap sequence length.  */
7559     trap_sequence_length =  trap_sequence_length + trap_length;
7560 
7561     /* Increment the pdu length.  */
7562     trap_pdu_length =  trap_pdu_length + trap_length;
7563 
7564     /* Adjust the trap request type length.  */
7565     trap_type_length =  trap_type_length + trap_length;
7566 
7567     /* Remember the start of the response's variable list field.  */
7568     trap_variable_list_ptr =  trap_buffer_ptr;
7569 
7570 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
7571     NX_SNMPV3_DBG_PRINTF("Starting trap_variable_list_ptr: 0x%x\n", trap_variable_list_ptr);
7572 #endif
7573     /* Setup the variable list.  For now, the length will be zero.  We
7574        will overwrite this with the actual length later.  */
7575     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
7576 
7577     /* Check for a valid operation.  */
7578     if (trap_length == 0)
7579     {
7580 
7581         /* Increment the internal error counter.  */
7582         agent_ptr -> nx_snmp_agent_internal_errors++;
7583 
7584         /* Release the trap packet.  */
7585         nx_packet_release(trap_packet_ptr);
7586 
7587         /* Return to caller.  */
7588         return(NX_SNMP_ERROR);
7589     }
7590 
7591     /* Move the trap buffer pointer up.  */
7592     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7593 
7594     /* Adjust the trap sequence length.  */
7595     trap_sequence_length =  trap_sequence_length + trap_length;
7596 
7597     /* Increment the pdu length.  */
7598     trap_pdu_length =  trap_pdu_length + trap_length;
7599 
7600     /* Adjust the trap request type length.  */
7601     trap_type_length =  trap_type_length + trap_length;
7602 
7603     /* Remember the start of the variable.  */
7604     trap_variable_ptr =  trap_buffer_ptr;
7605 
7606 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
7607     NX_SNMPV3_DBG_PRINTF("Starting trap_variable_ptr: 0x%x\n", trap_variable_ptr);
7608 #endif
7609 
7610     /****************************************************/
7611     /*          Start the PDU variable list length      */
7612     /****************************************************/
7613 
7614     /* Initialize the length to zero.  We will update with the actual length later.  */
7615     trap_length =  _nx_snmp_utility_sequence_set_1byte(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
7616 
7617     /* Check for a valid operation.  */
7618     if (trap_length == 0)
7619     {
7620 
7621         /* Increment the internal error counter.  */
7622         agent_ptr -> nx_snmp_agent_internal_errors++;
7623 
7624         /* Release the trap packet.  */
7625         nx_packet_release(trap_packet_ptr);
7626 
7627         /* Return to caller.  */
7628         return(NX_SNMP_ERROR);
7629     }
7630 
7631     /* Move the trap buffer pointer up.  */
7632     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7633 
7634     /* Adjust the trap sequence length.  */
7635     trap_sequence_length =  trap_sequence_length + trap_length;
7636 
7637     /* Increment the pdu length.  */
7638     trap_pdu_length =  trap_pdu_length + trap_length;
7639 
7640     /* Adjust the trap request type length.  */
7641     trap_type_length =  trap_type_length + trap_length;
7642 
7643     /* Adjust the trap variable list size.  */
7644     trap_variable_list_length =  trap_variable_list_length + trap_length;
7645 
7646     /****************************************************/
7647     /*             Set the sysUpTime object ID          */
7648     /****************************************************/
7649 
7650     trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, (UCHAR *) "1.3.6.1.2.1.1.3.0",
7651                                                   trap_packet_ptr -> nx_packet_data_end);
7652 
7653     /* Check for a valid operation.  */
7654     if (trap_length == 0)
7655     {
7656 
7657         /* Release the trap packet.  */
7658         nx_packet_release(trap_packet_ptr);
7659 
7660         /* Done, return to caller.  */
7661         return(NX_SNMP_ERROR);
7662     }
7663 
7664     /* Move the trap buffer pointer up.  */
7665     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7666 
7667     /* Adjust the trap sequence length.  */
7668     trap_sequence_length =  trap_sequence_length + trap_length;
7669 
7670     /* Increment the pdu length.  */
7671     trap_pdu_length =  trap_pdu_length + trap_length;
7672 
7673     /* Adjust the trap request type length.  */
7674     trap_type_length =  trap_type_length + trap_length;
7675 
7676     /* Adjust the trap variable list size.  */
7677     trap_variable_list_length =  trap_variable_list_length + trap_length;
7678 
7679     /* Adjust the trap variable size.  */
7680     trap_variable_length =  trap_variable_length + trap_length;
7681 
7682     /****************************************************/
7683     /*             Set the sysUpTime Timer Ticks        */
7684     /****************************************************/
7685     trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_TIME_TICS;
7686     trap_object_data.nx_snmp_object_data_msw =   (LONG)elapsed_time;
7687     trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
7688 
7689     /* Check for a valid operation.  */
7690     if (trap_length == 0)
7691     {
7692 
7693         /* Release the trap packet.  */
7694         nx_packet_release(trap_packet_ptr);
7695 
7696         /* Done, return to caller.  */
7697         return(NX_SNMP_ERROR);
7698     }
7699 
7700     /* Move the trap buffer pointer up.  */
7701     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7702 
7703     /* Adjust the trap sequence length.  */
7704     trap_sequence_length =  trap_sequence_length + trap_length;
7705 
7706     /* Increment the pdu length.  */
7707     trap_pdu_length =  trap_pdu_length + trap_length;
7708 
7709     /* Adjust the trap request type length.  */
7710     trap_type_length =  trap_type_length + trap_length;
7711 
7712     /* Adjust the trap variable list size.  */
7713     trap_variable_list_length =  trap_variable_list_length + trap_length;
7714 
7715     /* Adjust the trap variable size.  */
7716     trap_variable_length =  trap_variable_length + trap_length;
7717 
7718     /* Now update the trap variable sequence with the actual variable length.  */
7719     _nx_snmp_utility_sequence_set_1byte(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
7720 
7721         /* Check for a valid operation.  */
7722     if (trap_length == 0)
7723     {
7724 
7725         /* Increment the internal error counter.  */
7726         agent_ptr -> nx_snmp_agent_internal_errors++;
7727 
7728         /* Release the trap packet.  */
7729         nx_packet_release(trap_packet_ptr);
7730 
7731         /* Return to caller.  */
7732         return(NX_SNMP_ERROR);
7733     }
7734 
7735     /* Clear the trap variable size.  */
7736     trap_variable_length =  0;
7737 
7738     /* Remember the start of the variable.  */
7739     trap_variable_ptr =  trap_buffer_ptr;
7740 
7741     /* Check for valid trap type. */
7742     if ((trap_type > TRAP_ID_MAX) && (trap_type != NX_SNMP_TRAP_CUSTOM))
7743     {
7744 
7745         /* Increment the internal error counter.  */
7746         agent_ptr -> nx_snmp_agent_internal_errors++;
7747 
7748         /* Release the trap packet.  */
7749         nx_packet_release(trap_packet_ptr);
7750 
7751         /* Return to caller.  */
7752         return(NX_SNMP_ERROR);
7753     }
7754 
7755     /* Check that we have a trap list if a custom trap is requested.  */
7756     if ((object_list_ptr == NX_NULL) && (trap_type == NX_SNMP_TRAP_CUSTOM))
7757     {
7758 
7759         /* Increment the internal error counter.  */
7760         agent_ptr -> nx_snmp_agent_internal_errors++;
7761 
7762         /* Release the trap packet.  */
7763         nx_packet_release(trap_packet_ptr);
7764 
7765         /* Return to caller.  */
7766         return(NX_SNMP_ERROR);
7767     }
7768 
7769     /* Check if this is an enumerated trap type. */
7770     if (trap_type <= TRAP_ID_MAX)
7771     {
7772 
7773         /* Setup the variable trap sequence.  For now, the length will be zero.  We
7774            will overwrite this with the actual length later.  */
7775         trap_length =  _nx_snmp_utility_sequence_set_1byte(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
7776 
7777         /* Check for a valid operation.  */
7778         if (trap_length == 0)
7779         {
7780 
7781             /* Increment the internal error counter.  */
7782             agent_ptr -> nx_snmp_agent_internal_errors++;
7783 
7784             /* Release the trap packet.  */
7785             nx_packet_release(trap_packet_ptr);
7786 
7787             /* Return to caller.  */
7788             return(NX_SNMP_ERROR);
7789         }
7790 
7791         /* Move the trap buffer pointer up.  */
7792         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7793 
7794         /* Adjust the trap sequence length.  */
7795         trap_sequence_length =  trap_sequence_length + trap_length;
7796 
7797         /* Increment the pdu length.  */
7798         trap_pdu_length =  trap_pdu_length + trap_length;
7799 
7800         /* Adjust the trap request type length.  */
7801         trap_type_length =  trap_type_length + trap_length;
7802 
7803         /* Adjust the trap variable list size.  */
7804         trap_variable_list_length =  trap_variable_list_length + trap_length;
7805 
7806         /* Place the snmpTrapOID object ID into the trap buffer.  */
7807         trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, (UCHAR *) "1.3.6.1.6.3.1.1.4.1.0",
7808                                                       trap_packet_ptr -> nx_packet_data_end);
7809 
7810         /* Check for a valid operation.  */
7811         if (trap_length == 0)
7812         {
7813 
7814             /* Release the trap packet.  */
7815             nx_packet_release(trap_packet_ptr);
7816 
7817             /* Done, return to caller.  */
7818             return(NX_SNMP_ERROR);
7819         }
7820 
7821         /* Move the trap buffer pointer up.  */
7822         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7823 
7824         /* Adjust the trap sequence length.  */
7825         trap_sequence_length =  trap_sequence_length + trap_length;
7826 
7827         /* Increment the pdu length.  */
7828         trap_pdu_length =  trap_pdu_length + trap_length;
7829 
7830         /* Adjust the trap request type length.  */
7831         trap_type_length =  trap_type_length + trap_length;
7832 
7833         /* Adjust the trap variable list size.  */
7834         trap_variable_list_length =  trap_variable_list_length + trap_length;
7835 
7836         /* Adjust the trap variable size.  */
7837         trap_variable_length =  trap_variable_length + trap_length;
7838 
7839         /* Set a Object ID for the data.  */
7840         trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_OBJECT_ID;
7841         trap_object_data.nx_snmp_object_data_msw =   0;
7842         _nx_snmp_object_copy(_nx_snmp_v3_trap_ids[trap_type], trap_object_data.nx_snmp_object_octet_string);
7843 
7844         /* Add trap object data to trap buffer. */
7845         trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
7846 
7847         /* Check for a valid operation.  */
7848         if (trap_length == 0)
7849         {
7850 
7851             /* Release the trap packet.  */
7852             nx_packet_release(trap_packet_ptr);
7853 
7854             /* Done, return to caller.  */
7855             return(NX_SNMP_ERROR);
7856         }
7857 
7858         /* Move the trap buffer pointer up.  */
7859         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7860 
7861         /* Adjust the trap sequence length.  */
7862         trap_sequence_length =  trap_sequence_length + trap_length;
7863 
7864         /* Increment the pdu length.  */
7865         trap_pdu_length =  trap_pdu_length + trap_length;
7866 
7867         /* Adjust the trap request type length.  */
7868         trap_type_length =  trap_type_length + trap_length;
7869 
7870         /* Adjust the trap variable list size.  */
7871         trap_variable_list_length =  trap_variable_list_length + trap_length;
7872 
7873         /* Adjust the trap variable size.  */
7874         trap_variable_length =  trap_variable_length + trap_length;
7875 
7876     }
7877 
7878     /* Now update the trap variable sequence with the actual variable length.  */
7879     _nx_snmp_utility_sequence_set_1byte(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
7880 
7881     /* Default the object pointer to NULL.  */
7882     trap_object_ptr =  NX_NULL;
7883 
7884     /* Determine if an object is specified.  */
7885     if (object_list_ptr)
7886     {
7887 
7888         /* Setup object pointers from the supplied object list.  */
7889         trap_object_ptr =       object_list_ptr -> nx_snmp_object_string_ptr;
7890         trap_object_data_ptr =  object_list_ptr -> nx_snmp_object_data;
7891 
7892         /* Check for a valid operation.  */
7893         if(trap_object_ptr != NX_NULL && trap_object_data_ptr == NX_NULL)
7894         {
7895             /* Release the trap packet.  */
7896             nx_packet_release(trap_packet_ptr);
7897 
7898             /* Done, return to caller.  */
7899             return(NX_SNMP_ERROR);
7900         }
7901     }
7902 
7903     /* Loop to process all the objects in the list.  */
7904     while (trap_object_ptr)
7905     {
7906 
7907         /* Clear the trap variable length.  */
7908         trap_variable_length =  0;
7909 
7910         /* Remember the start of the variable.  */
7911         trap_variable_ptr =  trap_buffer_ptr;
7912 
7913         /* Setup the variable trap sequence.  For now, the length will be zero.  We
7914            will overwrite this with the actual length later.  */
7915         trap_length =  _nx_snmp_utility_sequence_set_1byte(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
7916 
7917         /* Check for a valid operation.  */
7918         if (trap_length == 0)
7919         {
7920 
7921             /* Increment the internal error counter.  */
7922             agent_ptr -> nx_snmp_agent_internal_errors++;
7923 
7924             /* Release the trap packet.  */
7925             nx_packet_release(trap_packet_ptr);
7926 
7927             /* Return to caller.  */
7928             return(NX_SNMP_ERROR);
7929         }
7930 
7931         /* Move the trap buffer pointer up.  */
7932         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7933 
7934         /* Adjust the trap sequence length.  */
7935         trap_sequence_length =  trap_sequence_length + trap_length;
7936 
7937         /* Increment the pdu length.  */
7938         trap_pdu_length =  trap_pdu_length + trap_length;
7939 
7940         /* Adjust the trap request type length.  */
7941         trap_type_length =  trap_type_length + trap_length;
7942 
7943         /* Adjust the trap variable list size.  */
7944         trap_variable_list_length =  trap_variable_list_length + trap_length;
7945 
7946         /* Place the object into the trap buffer.  */
7947         trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, trap_object_ptr, trap_packet_ptr -> nx_packet_data_end);
7948 
7949         /* Check for a valid operation.  */
7950         if (trap_length == 0)
7951         {
7952 
7953             /* Release the trap packet.  */
7954             nx_packet_release(trap_packet_ptr);
7955 
7956             /* Done, return to caller.  */
7957             return(NX_SNMP_ERROR);
7958         }
7959 
7960         /* Move the trap buffer pointer up.  */
7961         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7962 
7963         /* Adjust the trap sequence length.  */
7964         trap_sequence_length =  trap_sequence_length + trap_length;
7965 
7966         /* Increment the pdu length.  */
7967         trap_pdu_length =  trap_pdu_length + trap_length;
7968 
7969         /* Adjust the trap request type length.  */
7970         trap_type_length =  trap_type_length + trap_length;
7971 
7972         /* Adjust the trap variable list size.  */
7973         trap_variable_list_length =  trap_variable_list_length + trap_length;
7974 
7975         /* Adjust the trap variable size.  */
7976         trap_variable_length =  trap_variable_length + trap_length;
7977 
7978         /* Insert the object's data into the trap buffer.  */
7979         trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, trap_object_data_ptr, trap_packet_ptr -> nx_packet_data_end);
7980 
7981         /* Check for a valid operation.  */
7982         if (trap_length == 0)
7983         {
7984 
7985             /* Release the trap packet.  */
7986             nx_packet_release(trap_packet_ptr);
7987 
7988             /* Done, return to caller.  */
7989             return(NX_SNMP_ERROR);
7990         }
7991 
7992         /* Move the trap buffer pointer up.  */
7993         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
7994 
7995         /* Adjust the trap sequence length.  */
7996         trap_sequence_length =  trap_sequence_length + trap_length;
7997 
7998         /* Increment the pdu length.  */
7999         trap_pdu_length =  trap_pdu_length + trap_length;
8000 
8001         /* Adjust the trap request type length.  */
8002         trap_type_length =  trap_type_length + trap_length;
8003 
8004         /* Adjust the trap variable list size.  */
8005         trap_variable_list_length =  trap_variable_list_length + trap_length;
8006 
8007         /* Adjust the trap variable size.  */
8008         trap_variable_length =  trap_variable_length + trap_length;
8009 
8010         /* Now update the trap variable sequence with the actual variable length.  */
8011         _nx_snmp_utility_sequence_set_1byte(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
8012 
8013         /* Default the object pointer to NULL.  */
8014         trap_object_ptr =  NX_NULL;
8015 
8016         /* Determine if there are more objects to insert into the trap message.  */
8017         if (object_list_ptr)
8018         {
8019 
8020             /* Move to the next object in the list.  */
8021             object_list_ptr++;
8022 
8023             if (object_list_ptr == NX_NULL)
8024             {
8025                 /* Release the trap packet.  */
8026                 nx_packet_release(trap_packet_ptr);
8027 
8028                 /* Done, return to caller.  */
8029                 return(NX_SNMP_ERROR);
8030             }
8031 
8032             /* Determine if there is another object.  */
8033             if (object_list_ptr -> nx_snmp_object_string_ptr)
8034             {
8035 
8036                 /* Setup the object and object data pointers.  */
8037                 trap_object_ptr =       object_list_ptr -> nx_snmp_object_string_ptr;
8038                 trap_object_data_ptr =  object_list_ptr -> nx_snmp_object_data;
8039 
8040 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
8041                 NX_SNMPV3_DBG_PRINTF("Next trap3 object data at 0x%x\n", trap_object_data_ptr);
8042 #endif
8043                 /* Check for a valid operation.  */
8044                 if(trap_object_ptr != NX_NULL && trap_object_data_ptr == NX_NULL)
8045                 {
8046                     /* Release the trap packet.  */
8047                     nx_packet_release(trap_packet_ptr);
8048 
8049                     /* Done, return to caller.  */
8050                     return(NX_SNMP_ERROR);
8051                 }
8052             }
8053         }
8054     }
8055 
8056 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
8057     NX_SNMPV3_DBG_PRINTF("\nSet trap3 sequence length at 0x%x to 0x%x\n  Set global sequence length at 0x%x  to 0x%x\n  Set trap3 security length at 0x%x  to 0x%x\n Set trap3 pdu length at 0x%x  to 0x%x\n Set trap3 variable list length at 0x%x  to 0x%x\n  Set trap3 type length at 0x%x to 0x%x\n",
8058                           trap_sequence_ptr, trap_sequence_length, trap_header_ptr, trap_header_length,
8059                           trap_security_ptr, trap_security_length, trap_pdu_ptr, trap_pdu_length,
8060                           trap_variable_list_ptr, trap_variable_list_length, trap_type_ptr, trap_type_length);
8061 #endif
8062 
8063     /* At this point, several trap fields need to be updated with actual lengths.  */
8064 
8065     _nx_snmp_utility_request_type_set_multibyte(trap_type_ptr, NX_SNMP_ANS1_TRAP2_REQUEST, trap_type_length, trap_packet_ptr -> nx_packet_data_end);
8066     _nx_snmp_utility_sequence_set(trap_sequence_ptr, trap_sequence_length, trap_packet_ptr -> nx_packet_data_end);
8067     _nx_snmp_utility_sequence_set(trap_variable_list_ptr, trap_variable_list_length, trap_packet_ptr -> nx_packet_data_end);
8068     _nx_snmp_utility_sequence_set(trap_pdu_ptr, trap_pdu_length, trap_packet_ptr -> nx_packet_data_end);
8069     _nx_snmp_utility_sequence_set_1byte(trap_security_ptr, trap_security_length, trap_packet_ptr -> nx_packet_data_end);
8070     _nx_snmp_utility_sequence_set_1byte(trap_header_ptr, trap_header_length, trap_packet_ptr -> nx_packet_data_end);
8071 
8072     /* Setup the security OCTET string length.  */
8073 
8074     /* Backup to the OCTET string for the security size.  */
8075     trap_security_ptr =  trap_security_ptr - 2;
8076 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
8077     NX_SNMPV3_DBG_PRINTF("Move trap3 security pointer by 2 0x%x  (length %u)\n",      trap_security_ptr, trap_security_length);
8078 #endif
8079     /* Account for the 2 byte Security Sequence field.  */
8080     trap_security_length =  trap_security_length + 2;
8081 
8082     /* Store the security size.  */
8083     trap_security_ptr[1] =  (UCHAR) (trap_security_length & 0xFF);
8084 
8085     /* Determine if privacy is required.  If so, encrypt the PDU and setup the response
8086        to have an encryption header.  */
8087     if (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)
8088     {
8089 
8090         /* Determine if any padding needs to be applied - account for the
8091            two bytes of sequence information on the PDU.  */
8092         trap_pdu_length =  trap_pdu_length + 2;
8093         padding =  ((trap_pdu_length+7)/8)*8 - trap_pdu_length;
8094 
8095         /* Add the padding the trap PDU length and the trap sequence length.  */
8096         trap_pdu_length =       trap_pdu_length + padding;
8097         trap_sequence_length =  trap_sequence_length + padding;
8098 
8099         /* Clear the end of the trap message...  just to be nice!  */
8100         for (i = 0; i < padding; i++)
8101         {
8102 
8103             /* Clear byte at the end of the response.  */
8104             *trap_buffer_ptr++ =  0;
8105         }
8106 
8107         /* Setup the size of the encrypted PDU.  */
8108         trap_encryption_size_ptr[0] =  (UCHAR) ((trap_pdu_length >> 8) & 0xFF);
8109         trap_encryption_size_ptr[1] =  (UCHAR) (trap_pdu_length & 0xFF);
8110 
8111         /* Update the total trap sequence length again. */
8112         _nx_snmp_utility_sequence_set(trap_sequence_ptr, trap_sequence_length, trap_packet_ptr -> nx_packet_data_end);
8113 
8114         /* Increment the salt counter.  */
8115         agent_ptr -> nx_snmp_agent_v3_context_salt_counter++;
8116 
8117         /* Build the salt value for the decryption.  */
8118         key1[0] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_engine_boots >> 24) & 0xFF);
8119         key1[1] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_engine_boots >> 16) & 0xFF);
8120         key1[2] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_engine_boots >>  8) & 0xFF);
8121         key1[3] =  (UCHAR) (agent_ptr -> nx_snmp_agent_v3_context_engine_boots & 0xFF);
8122         key1[4] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_salt_counter >> 24) & 0xFF);
8123         key1[5] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_salt_counter >> 16) & 0xFF);
8124         key1[6] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_salt_counter >>  8) & 0xFF);
8125         key1[7] =  (UCHAR) (agent_ptr -> nx_snmp_agent_v3_context_salt_counter & 0xFF);
8126 
8127         /* Loop to store the salt in the privacy field.  */
8128         for (i = 0; i < 8; i++)
8129         {
8130 
8131             /* Store a byte of the salt.  */
8132             trap_privacy_ptr[i] =  key1[i];
8133         }
8134 
8135         /* Setup pointer to the actual PDU.  */
8136         temp_ptr =  trap_encryption_size_ptr + 2;
8137 
8138         /* Make the Initialization Vector (IV).  */
8139         for (i = 0; i < 8; i++)
8140         {
8141 
8142             key2[i] =  (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)->nx_snmp_security_key[8+i] ^ key1[i];
8143         }
8144 
8145         /* Setup the DES.  */
8146         _nx_des_key_set(&(agent_ptr -> nx_snmp_agent_v3_des_data), (agent_ptr -> nx_snmp_agent_v3_priv_trap_key) -> nx_snmp_security_key);
8147 
8148         /* Setup the first input block - use the IV for the first block.  */
8149         for (i = 0; i < 8; i++)
8150         {
8151 
8152             key1[i] =  temp_ptr[i] ^ key2[i];
8153         }
8154 
8155         /* Encrypt the first 8 bytes.  */
8156         _nx_des_encrypt(&(agent_ptr -> nx_snmp_agent_v3_des_data), &key1[0], &temp_ptr[0]);
8157 
8158         /* Loop to encrypt the rest of the PDU.  */
8159         j =  8;
8160         do
8161         {
8162 
8163             /* Setup the next input block.  */
8164             for (i = 0; i < 8; i++)
8165             {
8166 
8167                 key1[i] =  temp_ptr[j+i] ^ temp_ptr[(j-8)+i];
8168             }
8169 
8170             /* Encrypt the next 8 bytes.  */
8171             _nx_des_encrypt(&(agent_ptr -> nx_snmp_agent_v3_des_data), &key1[0], &temp_ptr[j]);
8172 
8173             /* Move the major index forward.  */
8174             j =  j + 8;
8175         } while (j < trap_pdu_length);
8176     }
8177 
8178     /* Now the trap packet's pointers must be setup so it can be sent.  */
8179     trap_packet_ptr -> nx_packet_length =  (ULONG)(trap_buffer_ptr - trap_packet_ptr -> nx_packet_prepend_ptr);
8180     trap_packet_ptr -> nx_packet_append_ptr =  trap_buffer_ptr;
8181 
8182     /* Determine if authentication is required.  */
8183     if (agent_ptr -> nx_snmp_agent_v3_auth_trap_key)
8184     {
8185 
8186         /* Yes, authentication is required.  */
8187 
8188         /* Now determine which authentication is required.  */
8189         if ((agent_ptr -> nx_snmp_agent_v3_auth_trap_key) -> nx_snmp_security_key_type == NX_SNMP_MD5_KEY)
8190         {
8191 
8192             /* Copy the base MD5 key into key1.  */
8193             for (i = 0; i < NX_SNMP_MD5_DIGEST_SIZE; i++)
8194             {
8195 
8196                 /* Copy a byte of the base MD5 key.  */
8197                 key1[i] = (agent_ptr -> nx_snmp_agent_v3_auth_trap_key) -> nx_snmp_security_key[i];
8198             }
8199 
8200             /* Extend key1 to 64 bytes.  */
8201             for (i = NX_SNMP_MD5_DIGEST_SIZE; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
8202             {
8203                 key1[i] =  0;
8204             }
8205 
8206             /* Create key1 and key2.  */
8207             for (i = 0; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
8208             {
8209                 key2[i] = key1[i] ^ 0x5C;
8210                 key1[i] = key1[i] ^ 0x36;
8211             }
8212 
8213             /* Calculate the MAC.  */
8214             _nx_md5_initialize(&(agent_ptr -> nx_snmp_agent_v3_md5_data));
8215 
8216             /* Calculate prepend Key1.  */
8217             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1, NX_SNMP_DIGEST_WORKING_SIZE);
8218 
8219             /* Calculate the message.  */
8220             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), trap_packet_ptr -> nx_packet_prepend_ptr, trap_packet_ptr -> nx_packet_length);
8221 
8222             /* Final calculation of the first pass.   */
8223             _nx_md5_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1);
8224 
8225             /* Prepare to calculate the final MAC.  */
8226             _nx_md5_initialize(&(agent_ptr -> nx_snmp_agent_v3_md5_data));
8227 
8228             /* Prepend Key2 to the result.  */
8229             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key2, NX_SNMP_DIGEST_WORKING_SIZE);
8230 
8231             /* Calculate the previous result.  */
8232             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1, NX_SNMP_MD5_DIGEST_SIZE);
8233 
8234             /* Calculate the final MAC. */
8235             _nx_md5_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key2);
8236         }
8237         else if ((agent_ptr -> nx_snmp_agent_v3_auth_trap_key) -> nx_snmp_security_key_type == NX_SNMP_SHA_KEY)
8238         {
8239 
8240             /* Copy the base SHA key into key1.  */
8241             for (i = 0; i < NX_SNMP_SHA_DIGEST_SIZE; i++)
8242             {
8243 
8244                 /* Copy a byte of the base SHA key.  */
8245                 key1[i] = (agent_ptr -> nx_snmp_agent_v3_auth_trap_key) -> nx_snmp_security_key[i];
8246             }
8247 
8248             /* Extend key1 to 64 bytes.  */
8249             for (i = NX_SNMP_SHA_DIGEST_SIZE; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
8250             {
8251                 key1[i] =  0;
8252             }
8253 
8254             /* Create key1 and key2.  */
8255             for (i = 0; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
8256             {
8257                 key2[i] = key1[i] ^ 0x5C;
8258                 key1[i] = key1[i] ^ 0x36;
8259             }
8260 
8261             /* Calculate the MAC.  */
8262             _nx_sha1_initialize(&(agent_ptr -> nx_snmp_agent_v3_sha_data));
8263 
8264             /* Calculate prepend Key1.  */
8265             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1, NX_SNMP_DIGEST_WORKING_SIZE);
8266 
8267             /* Calculate the message.  */
8268             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), trap_packet_ptr -> nx_packet_prepend_ptr, trap_packet_ptr -> nx_packet_length);
8269 
8270             /* Final calculation of the first pass.   */
8271             _nx_sha1_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1);
8272 
8273             /* Prepare to calculate the final MAC.  */
8274             _nx_sha1_initialize(&(agent_ptr -> nx_snmp_agent_v3_sha_data));
8275 
8276             /* Prepend Key2 to the result.  */
8277             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key2, NX_SNMP_DIGEST_WORKING_SIZE);
8278 
8279             /* Calculate the previous result.  */
8280             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1, NX_SNMP_SHA_DIGEST_SIZE);
8281 
8282             /* Calculate the final MAC. */
8283             _nx_sha1_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key2);
8284         }
8285         else
8286         {
8287 
8288             /* Increment the authentication error counter.  */
8289             agent_ptr -> nx_snmp_agent_authentication_errors++;
8290 
8291             /* Release packet.  */
8292             nx_packet_release(trap_packet_ptr);
8293 
8294             /* Return to caller.  */
8295             return(NX_SNMP_ERROR);
8296         }
8297 
8298         /* At this point, key2 contains the computed digest of the message.  This needs to be
8299            place in the outgoing message.  */
8300 
8301         /* Loop to setup the outgoing digest.  */
8302         for (i = 0; i < NX_SNMP_DIGEST_SIZE; i++)
8303         {
8304 
8305             /* Copy one byte of digest.  */
8306             trap_authentication_ptr[i] =  key2[i];
8307         }
8308     }
8309 
8310     /* Update various statistics.  */
8311     agent_ptr -> nx_snmp_agent_traps_sent++;
8312     agent_ptr -> nx_snmp_agent_packets_sent++;
8313     agent_ptr -> nx_snmp_agent_total_bytes_sent += trap_packet_ptr -> nx_packet_length;
8314 
8315     /* Send the trap packet back to the requesting SNMP manager.  */
8316     status =  nxd_udp_socket_send(&(agent_ptr -> nx_snmp_agent_socket), trap_packet_ptr, ip_address, NX_SNMP_MANAGER_TRAP_PORT);
8317 
8318     /* Determine if the packet needs to be released. */
8319     if (status)
8320     {
8321 
8322         /* Release packet.  */
8323         nx_packet_release(trap_packet_ptr);
8324 
8325         /* Return error. */
8326         return(NX_SNMP_ERROR);
8327     }
8328 
8329     /* Return successful completion.  */
8330     return(NX_SUCCESS);
8331 }
8332 
8333 
8334 /**************************************************************************/
8335 /*                                                                        */
8336 /*  FUNCTION                                               RELEASE        */
8337 /*                                                                        */
8338 /*    _nxe_snmp_agent_trapv3_oid_send                     PORTABLE C      */
8339 /*                                                           6.1          */
8340 /*  AUTHOR                                                                */
8341 /*                                                                        */
8342 /*    Yuxin Zhou, Microsoft Corporation                                   */
8343 /*                                                                        */
8344 /*  DESCRIPTION                                                           */
8345 /*                                                                        */
8346 /*    This function checks for errors in the SNMP agent v3 trap send      */
8347 /*    function call.                                                      */
8348 /*                                                                        */
8349 /*  INPUT                                                                 */
8350 /*                                                                        */
8351 /*    agent_ptr                             Pointer to SNMP agent         */
8352 /*    ip_address                            Destination IP address        */
8353 /*    username                              Username                      */
8354 /*    oid                                   Enterprise ID to send         */
8355 /*    elapsed_time                          Elapsed time from last boot   */
8356 /*                                            of the device (sysUpTime)   */
8357 /*    object_list_ptr                       Variable list of application  */
8358 /*                                            objects to present with the */
8359 /*                                            trap                        */
8360 /*                                                                        */
8361 /*  OUTPUT                                                                */
8362 /*                                                                        */
8363 /*    status                                Completion status             */
8364 /*                                                                        */
8365 /*  CALLS                                                                 */
8366 /*                                                                        */
8367 /*    _nx_snmp_agent_trapv3_send            Actual agent trap send        */
8368 /*                                            function                    */
8369 /*                                                                        */
8370 /*  CALLED BY                                                             */
8371 /*                                                                        */
8372 /*    Application Code                                                    */
8373 /*                                                                        */
8374 /*  RELEASE HISTORY                                                       */
8375 /*                                                                        */
8376 /*    DATE              NAME                      DESCRIPTION             */
8377 /*                                                                        */
8378 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8379 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8380 /*                                            resulting in version 6.1    */
8381 /*                                                                        */
8382 /**************************************************************************/
_nxe_snmp_agent_trapv3_oid_send(NX_SNMP_AGENT * agent_ptr,ULONG ip_address,UCHAR * username,UCHAR * oid,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)8383 UINT  _nxe_snmp_agent_trapv3_oid_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *username, UCHAR *oid, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
8384 {
8385 
8386 #ifndef NX_DISABLE_IPV4
8387 UINT    status;
8388 
8389 
8390     /* Check for invalid input pointers.  */
8391     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) || (username == NX_NULL))
8392         return(NX_PTR_ERROR);
8393 
8394     /* Check for invalid IP address.  */
8395     if (ip_address == 0)
8396         return(NX_IP_ADDRESS_ERROR);
8397 
8398     /* Call actual service.  */
8399     status =  _nx_snmp_agent_trapv3_oid_send(agent_ptr, ip_address, username, oid, elapsed_time, object_list_ptr);
8400 
8401     /* Return status.  */
8402     return(status);
8403 #else
8404     NX_PARAMETER_NOT_USED(agent_ptr);
8405     NX_PARAMETER_NOT_USED(ip_address);
8406     NX_PARAMETER_NOT_USED(username);
8407     NX_PARAMETER_NOT_USED(oid);
8408     NX_PARAMETER_NOT_USED(elapsed_time);
8409     NX_PARAMETER_NOT_USED(object_list_ptr);
8410 
8411     return(NX_NOT_SUPPORTED);
8412 #endif /* NX_DISABLE_IPV4 */
8413 }
8414 
8415 
8416 /**************************************************************************/
8417 /*                                                                        */
8418 /*  FUNCTION                                               RELEASE        */
8419 /*                                                                        */
8420 /*    _nx_snmp_agent_trapv3_oid_send                      PORTABLE C      */
8421 /*                                                           6.1          */
8422 /*  AUTHOR                                                                */
8423 /*                                                                        */
8424 /*    Yuxin Zhou, Microsoft Corporation                                   */
8425 /*                                                                        */
8426 /*  DESCRIPTION                                                           */
8427 /*                                                                        */
8428 /*    This function builds and sends a SNMP v3 trap message.              */
8429 /*                                                                        */
8430 /*  INPUT                                                                 */
8431 /*                                                                        */
8432 /*    agent_ptr                             Pointer to SNMP agent         */
8433 /*    ip_address                            Destination IP address        */
8434 /*    username                              Username                      */
8435 /*    OID                                   Enterprise ID to send         */
8436 /*    elapsed_time                          Elapsed time from last boot   */
8437 /*                                            of the device (sysUpTime)   */
8438 /*    object_list_ptr                       Variable list of application  */
8439 /*                                            objects to present with the */
8440 /*                                            trap                        */
8441 /*                                                                        */
8442 /*  OUTPUT                                                                */
8443 /*                                                                        */
8444 /*    status                                Completion status             */
8445 /*                                                                        */
8446 /*  CALLS                                                                 */
8447 /*                                                                        */
8448 /*    _nxd_snmp_agent_trapv3_oid_send       Actual agent trap send        */
8449 /*                                            function                    */
8450 /*                                                                        */
8451 /*  CALLED BY                                                             */
8452 /*                                                                        */
8453 /*    Application Code                                                    */
8454 /*                                                                        */
8455 /*  RELEASE HISTORY                                                       */
8456 /*                                                                        */
8457 /*    DATE              NAME                      DESCRIPTION             */
8458 /*                                                                        */
8459 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8460 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8461 /*                                            resulting in version 6.1    */
8462 /*                                                                        */
8463 /**************************************************************************/
8464 
_nx_snmp_agent_trapv3_oid_send(NX_SNMP_AGENT * agent_ptr,ULONG ip_address,UCHAR * username,UCHAR * oid,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)8465 UINT  _nx_snmp_agent_trapv3_oid_send(NX_SNMP_AGENT *agent_ptr, ULONG ip_address, UCHAR *username, UCHAR *oid, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
8466 {
8467 
8468 #ifndef NX_DISABLE_IPV4
8469 UINT        status;
8470 NXD_ADDRESS ipduo_address;
8471 
8472 
8473     ipduo_address.nxd_ip_version = NX_IP_VERSION_V4;
8474     ipduo_address.nxd_ip_address.v4 = ip_address;
8475 
8476     status = _nxd_snmp_agent_trapv3_oid_send(agent_ptr, &ipduo_address, username, oid, elapsed_time, object_list_ptr);
8477 
8478     return status;
8479 #else
8480     NX_PARAMETER_NOT_USED(agent_ptr);
8481     NX_PARAMETER_NOT_USED(ip_address);
8482     NX_PARAMETER_NOT_USED(username);
8483     NX_PARAMETER_NOT_USED(oid);
8484     NX_PARAMETER_NOT_USED(elapsed_time);
8485     NX_PARAMETER_NOT_USED(object_list_ptr);
8486 
8487     return(NX_NOT_SUPPORTED);
8488 #endif /* NX_DISABLE_IPV4 */
8489 }
8490 
8491 /**************************************************************************/
8492 /*                                                                        */
8493 /*  FUNCTION                                               RELEASE        */
8494 /*                                                                        */
8495 /*    _nxde_snmp_agent_trapv3_oid_send                    PORTABLE C      */
8496 /*                                                           6.1          */
8497 /*  AUTHOR                                                                */
8498 /*                                                                        */
8499 /*    Yuxin Zhou, Microsoft Corporation                                   */
8500 /*                                                                        */
8501 /*  DESCRIPTION                                                           */
8502 /*                                                                        */
8503 /*    This function checks for errors in the SNMP agent v2 trap send      */
8504 /*    function call.                                                      */
8505 /*                                                                        */
8506 /*  INPUT                                                                 */
8507 /*                                                                        */
8508 /*    agent_ptr                             Pointer to SNMP agent         */
8509 /*    ip_address                            Destination IP address        */
8510 /*    community                             Community name                */
8511 /*    OID                                   OID to send                   */
8512 /*    elapsed_time                          Elapsed time from last boot   */
8513 /*                                            of the device (sysUpTime)   */
8514 /*    object_list_ptr                       Variable list of application  */
8515 /*                                            objects to present with the */
8516 /*                                            trap                        */
8517 /*                                                                        */
8518 /*  OUTPUT                                                                */
8519 /*                                                                        */
8520 /*    status                                Completion status             */
8521 /*                                                                        */
8522 /*  CALLS                                                                 */
8523 /*                                                                        */
8524 /*    _nxd_snmp_agent_trapv3_oid_send       Actual agent trap send        */
8525 /*                                            function                    */
8526 /*                                                                        */
8527 /*  CALLED BY                                                             */
8528 /*                                                                        */
8529 /*    Application Code                                                    */
8530 /*                                                                        */
8531 /*  RELEASE HISTORY                                                       */
8532 /*                                                                        */
8533 /*    DATE              NAME                      DESCRIPTION             */
8534 /*                                                                        */
8535 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8536 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8537 /*                                            resulting in version 6.1    */
8538 /*                                                                        */
8539 /**************************************************************************/
_nxde_snmp_agent_trapv3_oid_send(NX_SNMP_AGENT * agent_ptr,NXD_ADDRESS * ipduo_address,UCHAR * username,UCHAR * oid,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)8540 UINT  _nxde_snmp_agent_trapv3_oid_send(NX_SNMP_AGENT *agent_ptr, NXD_ADDRESS *ipduo_address, UCHAR *username, UCHAR *oid, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
8541 {
8542 
8543 UINT    status;
8544 
8545 
8546     /* Check for invalid input pointers.  */
8547     if ((agent_ptr == NX_NULL) || (agent_ptr -> nx_snmp_agent_id != NX_SNMP_ID) || (username == NX_NULL) ||
8548         (ipduo_address == NX_NULL))
8549     {
8550 
8551         return(NX_PTR_ERROR);
8552     }
8553 
8554     /* Call actual service.  */
8555     status =  _nxd_snmp_agent_trapv3_oid_send(agent_ptr, ipduo_address, username, oid, elapsed_time, object_list_ptr);
8556 
8557     /* Return status.  */
8558     return(status);
8559 }
8560 
8561 /**************************************************************************/
8562 /*                                                                        */
8563 /*  FUNCTION                                               RELEASE        */
8564 /*                                                                        */
8565 /*    _nxd_snmp_agent_trapv3_oid_send                     PORTABLE C      */
8566 /*                                                           6.1          */
8567 /*  AUTHOR                                                                */
8568 /*                                                                        */
8569 /*    Yuxin Zhou, Microsoft Corporation                                   */
8570 /*                                                                        */
8571 /*  DESCRIPTION                                                           */
8572 /*                                                                        */
8573 /*    This function builds and sends a SNMP v3 trap message.              */
8574 /*                                                                        */
8575 /*    Note: The string length of username and oid are limited by the      */
8576 /*    packet payload and NX_SNMP_MAX_OCTET_STRING.                        */
8577 /*                                                                        */
8578 /*  INPUT                                                                 */
8579 /*                                                                        */
8580 /*    agent_ptr                             Pointer to SNMP agent         */
8581 /*    ip_address                            Destination IP address        */
8582 /*    username                              Username                      */
8583 /*    OID                                   Enterprise ID to send         */
8584 /*    elapsed_time                          Elapsed time from last boot   */
8585 /*                                            of the device (sysUpTime)   */
8586 /*    object_list_ptr                       Variable list of application  */
8587 /*                                            objects to present with the */
8588 /*                                            trap                        */
8589 /*                                                                        */
8590 /*  OUTPUT                                                                */
8591 /*                                                                        */
8592 /*    status                                Completion status             */
8593 /*                                                                        */
8594 /*  CALLS                                                                 */
8595 /*                                                                        */
8596 /*    _nx_des_key_set                       Setup DES encryption          */
8597 /*    _nx_des_encrypt                       Encrypt bytes                 */
8598 /*    _nx_md5_digest_calculate              MD5 algorithm completion      */
8599 /*    _nx_md5_initialize                    MD5 algorithm initialization  */
8600 /*    _nx_md5_update                        MD5 algorithm computation     */
8601 /*    nx_packet_allocate                    Allocate SNMP trap packet     */
8602 /*    nx_packet_release                     Release SNMP packet           */
8603 /*    nx_udp_socket_send                    Send SNMP trap via UDP        */
8604 /*    _nx_snmp_object_copy                  Copy object                   */
8605 /*    _nx_snmp_utility_error_info_set       Set error information         */
8606 /*    _nx_snmp_utility_octet_set            Set octet string              */
8607 /*    _nx_snmp_utility_object_data_set      Set the data value            */
8608 /*    _nx_snmp_utility_object_id_set        Set the object ID             */
8609 /*    _nx_snmp_utility_sequence_set         Set the ASN.1 sequence        */
8610 /*    _nx_snmp_utility_request_id_set       Set the Request ID            */
8611 /*    _nx_snmp_utility_request_type_set_multibyte                         */
8612 /*                                          Set trap request type         */
8613 /*    _nx_snmp_utility_version_set          Set the SNMP v3               */
8614 /*    _nx_sha1_digest_calculate             SHA algorithm completion      */
8615 /*    _nx_sha1_initialize                   SHA algorithm initialization  */
8616 /*    _nx_sha1_update                       SHA algorithm computation     */
8617 /*    tx_time_get                           Get time                      */
8618 /*                                                                        */
8619 /*  CALLED BY                                                             */
8620 /*                                                                        */
8621 /*    Application Code                                                    */
8622 /*                                                                        */
8623 /*  RELEASE HISTORY                                                       */
8624 /*                                                                        */
8625 /*    DATE              NAME                      DESCRIPTION             */
8626 /*                                                                        */
8627 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8628 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8629 /*                                            resulting in version 6.1    */
8630 /*                                                                        */
8631 /**************************************************************************/
8632 
_nxd_snmp_agent_trapv3_oid_send(NX_SNMP_AGENT * agent_ptr,NXD_ADDRESS * ipduo_address,UCHAR * username,UCHAR * oid,ULONG elapsed_time,NX_SNMP_TRAP_OBJECT * object_list_ptr)8633 UINT  _nxd_snmp_agent_trapv3_oid_send(NX_SNMP_AGENT *agent_ptr, NXD_ADDRESS *ipduo_address, UCHAR *username, UCHAR *oid, ULONG elapsed_time, NX_SNMP_TRAP_OBJECT *object_list_ptr)
8634 {
8635 
8636 UINT                 status;
8637 UINT                 trap_length;
8638 UCHAR                *trap_object_ptr;
8639 NX_SNMP_OBJECT_DATA  trap_object_data;
8640 NX_SNMP_OBJECT_DATA *trap_object_data_ptr = NX_NULL;
8641 NX_PACKET           *trap_packet_ptr;
8642 UCHAR               *trap_buffer_ptr, *trap_sequence_ptr, *trap_header_ptr, *trap_security_ptr, *trap_pdu_ptr, *trap_type_ptr, *trap_variable_list_ptr, *trap_variable_ptr;
8643 UINT                 trap_sequence_length, trap_header_length, trap_security_length, trap_pdu_length, trap_type_length, trap_variable_list_length, trap_variable_length;
8644 UCHAR                temp_string[NX_SNMP_DIGEST_SIZE];
8645 UINT                i;
8646 #ifndef NX_SNMP_NO_SECURITY
8647 UINT                j, padding;
8648 UCHAR               *temp_ptr;
8649 UCHAR               *trap_encryption_size_ptr = NX_NULL;
8650 UCHAR               *trap_authentication_ptr = NX_NULL, *trap_privacy_ptr = NX_NULL;
8651 UCHAR               key1[NX_SNMP_DIGEST_WORKING_SIZE];
8652 UCHAR               key2[NX_SNMP_DIGEST_WORKING_SIZE];
8653 #endif
8654 UINT                packet_type = NX_UDP_PACKET;
8655 UCHAR               message_security_options;
8656 UINT                username_length;
8657 
8658 
8659     if (ipduo_address -> nxd_ip_version == NX_IP_VERSION_V4)
8660     {
8661         packet_type = NX_IPv4_UDP_PACKET;
8662     }
8663     else
8664     {
8665         packet_type = NX_IPv6_UDP_PACKET;
8666     }
8667 
8668     /* Allocate the packet for the SNMP response.  */
8669     status =  nx_packet_allocate(agent_ptr -> nx_snmp_agent_packet_pool_ptr, &trap_packet_ptr, packet_type, NX_SNMP_AGENT_TIMEOUT);
8670 
8671     /* Determine if a trap packet was allocated.  */
8672     if (status != NX_SUCCESS)
8673     {
8674 
8675         /* Increment the packet allocation error counter.  */
8676         agent_ptr -> nx_snmp_agent_allocation_errors++;
8677 
8678         /* Return to caller.  */
8679         return(NX_SNMP_ERROR);
8680 
8681     }
8682 
8683 
8684     /* Initialize the counters required for the length fields of the trap packet.  */
8685     trap_sequence_length =       0;
8686     trap_header_length =         0;
8687     trap_security_length =       0;
8688     trap_pdu_length =            0;
8689     trap_type_length =           0;
8690     trap_variable_list_length =  0;
8691     trap_variable_length =       0;
8692 
8693     /* Setup a pointer to the trap packet's buffer area.  */
8694     trap_buffer_ptr =  trap_packet_ptr -> nx_packet_prepend_ptr;
8695 
8696     /* This is also the trap sequence pointer. Remember it since we are going to have to
8697        update it later with the actual length of the response.  */
8698     trap_sequence_ptr =  trap_buffer_ptr;
8699 
8700     /* First, write the sequence in the trap packet.  A zero is written for now.  This will be
8701        updated later.  */
8702     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
8703 
8704     /* Check for a valid operation.  */
8705     if (trap_length == 0)
8706     {
8707 
8708         /* Increment the internal error counter.  */
8709         agent_ptr -> nx_snmp_agent_internal_errors++;
8710 
8711         /* Release the trap packet too.  */
8712         nx_packet_release(trap_packet_ptr);
8713 
8714         /* Return to caller.  */
8715         return(NX_SNMP_ERROR);
8716     }
8717 
8718     /* Move the trap buffer pointer up.  */
8719     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
8720 
8721     /* Now set the Version ID in the trap message.  */
8722     trap_length =  _nx_snmp_utility_version_set(trap_buffer_ptr, NX_SNMP_VERSION_3, trap_packet_ptr -> nx_packet_data_end);
8723 
8724     /* Check for a valid operation.  */
8725     if (trap_length == 0)
8726     {
8727 
8728         /* Increment the internal error counter.  */
8729         agent_ptr -> nx_snmp_agent_internal_errors++;
8730 
8731         /* Release the trap packet.  */
8732         nx_packet_release(trap_packet_ptr);
8733 
8734         /* Return to caller.  */
8735         return(NX_SNMP_ERROR);
8736     }
8737 
8738     /* Move the trap buffer pointer up.  */
8739     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
8740 
8741     /* Adjust the trap sequence length.  */
8742     trap_sequence_length =  trap_sequence_length + trap_length;
8743 
8744     /* Save the pointer to the global header.  */
8745     trap_header_ptr =  trap_buffer_ptr;
8746 
8747     /* Write the sequence for the global header in the trap packet.  A zero is written for now.
8748        This will be updated later.  */
8749     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
8750 
8751     /* Check for a valid operation.  */
8752     if (trap_length == 0)
8753     {
8754 
8755         /* Increment the internal error counter.  */
8756         agent_ptr -> nx_snmp_agent_internal_errors++;
8757 
8758         /* Release the trap packet too.  */
8759         nx_packet_release(trap_packet_ptr);
8760 
8761         /* Return to caller.  */
8762         return(NX_SNMP_ERROR);
8763     }
8764 
8765     /* Move the trap buffer pointer up.  */
8766     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
8767 
8768     /* Adjust the trap sequence length.  */
8769     trap_sequence_length =  trap_sequence_length + trap_length;
8770 
8771     /* Now setup the request ID.  */
8772     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_traps_sent, trap_packet_ptr -> nx_packet_data_end);
8773 
8774     /* Check for a valid operation.  */
8775     if (trap_length == 0)
8776     {
8777 
8778         /* Increment the internal error counter.  */
8779         agent_ptr -> nx_snmp_agent_internal_errors++;
8780 
8781         /* Release the trap packet too.  */
8782         nx_packet_release(trap_packet_ptr);
8783 
8784         /* Return to caller.  */
8785         return(NX_SNMP_ERROR);
8786     }
8787 
8788     /* Move the trap buffer pointer up.  */
8789     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
8790 
8791     /* Adjust the trap sequence length.  */
8792     trap_sequence_length =  trap_sequence_length + trap_length;
8793 
8794     /* Adjust the header sequence length.  */
8795     trap_header_length =  trap_header_length + trap_length;
8796 
8797     /* Now setup the maximum message size.  */
8798     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, (NX_SNMP_PACKET_SIZE - NX_UDP_PACKET), trap_packet_ptr -> nx_packet_data_end);
8799 
8800     /* Check for a valid operation.  */
8801     if (trap_length == 0)
8802     {
8803 
8804         /* Increment the internal error counter.  */
8805         agent_ptr -> nx_snmp_agent_internal_errors++;
8806 
8807         /* Release the trap packet too.  */
8808         nx_packet_release(trap_packet_ptr);
8809 
8810         /* Return to caller.  */
8811         return(NX_SNMP_ERROR);
8812     }
8813 
8814     /* Move the trap buffer pointer up.  */
8815     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
8816 
8817     /* Adjust the trap sequence length.  */
8818     trap_sequence_length =  trap_sequence_length + trap_length;
8819 
8820     /* Adjust the header sequence length.  */
8821     trap_header_length =  trap_header_length + trap_length;
8822 
8823     /* Now setup the security options.  */
8824     message_security_options = 0;
8825 
8826     /* Determine what the trap message security options are. These are not the same as
8827        the general get/set request PDU options.  */
8828     if (agent_ptr -> nx_snmp_agent_v3_auth_trap_key)
8829     {
8830         message_security_options = NX_SNMP_SECURITY_AUTHORIZE;
8831     }
8832     if (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)
8833     {
8834         message_security_options |= NX_SNMP_SECURITY_PRIVACY;
8835     }
8836 
8837     trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, (UCHAR *)&message_security_options, 1, trap_packet_ptr -> nx_packet_data_end);
8838 
8839 
8840     /* Check for a valid operation.  */
8841     if (trap_length == 0)
8842     {
8843 
8844         /* Increment the internal error counter.  */
8845         agent_ptr -> nx_snmp_agent_internal_errors++;
8846 
8847         /* Release the trap packet too.  */
8848         nx_packet_release(trap_packet_ptr);
8849 
8850         /* Return to caller.  */
8851         return(NX_SNMP_ERROR);
8852     }
8853 
8854     /* Move the trap buffer pointer up.  */
8855     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
8856 
8857     /* Adjust the trap sequence length.  */
8858     trap_sequence_length =  trap_sequence_length + trap_length;
8859 
8860     /* Adjust the header sequence length.  */
8861     trap_header_length =  trap_header_length + trap_length;
8862 
8863     /* Now setup the security type.  */
8864     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, NX_SNMP_USM_SECURITY_MODEL, trap_packet_ptr -> nx_packet_data_end);
8865 
8866     /* Check for a valid operation.  */
8867     if (trap_length == 0)
8868     {
8869 
8870         /* Increment the internal error counter.  */
8871         agent_ptr -> nx_snmp_agent_internal_errors++;
8872 
8873         /* Release the trap packet too.  */
8874         nx_packet_release(trap_packet_ptr);
8875 
8876         /* Return to caller.  */
8877         return(NX_SNMP_ERROR);
8878     }
8879 
8880     /* Move the trap buffer pointer up.  */
8881     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
8882 
8883     /* Adjust the trap sequence length.  */
8884     trap_sequence_length =  trap_sequence_length + trap_length;
8885 
8886     /* Adjust the header sequence length.  */
8887     trap_header_length =  trap_header_length + trap_length;
8888 
8889     /* At this point, we have successfully built the security header.  Now, we need to build
8890        the security parameters field.  */
8891 
8892     /* First setup the octet string field.  */
8893     trap_buffer_ptr[0] =  NX_SNMP_ANS1_OCTET_STRING;
8894     trap_buffer_ptr[1] =  0x0;
8895 
8896     /* Move the trap buffer pointer up.  */
8897     trap_buffer_ptr =  trap_buffer_ptr + 2;
8898 
8899     /* Adjust the trap sequence length.  */
8900     trap_sequence_length =  trap_sequence_length + 2;
8901 
8902     /* Remember the security header length pointer.  */
8903     trap_security_ptr =  trap_buffer_ptr;
8904 
8905     /* Now set the sequence of the USM security parameters.  */
8906     trap_length =  _nx_snmp_utility_sequence_set_1byte(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
8907 
8908     /* Check for a valid operation.  */
8909     if (trap_length == 0)
8910     {
8911 
8912         /* Increment the internal error counter.  */
8913         agent_ptr -> nx_snmp_agent_internal_errors++;
8914 
8915         /* Release the trap packet too.  */
8916         nx_packet_release(trap_packet_ptr);
8917 
8918         /* Return to caller.  */
8919         return(NX_SNMP_ERROR);
8920     }
8921 
8922     /* Move the trap buffer pointer up.  */
8923     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
8924 
8925     /* Adjust the trap sequence length.  */
8926     trap_sequence_length =  trap_sequence_length + trap_length;
8927 
8928     /* Now setup the context engine.  */
8929     trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine, agent_ptr -> nx_snmp_agent_v3_context_engine_size, trap_packet_ptr -> nx_packet_data_end);
8930 
8931     /* Check for a valid operation.  */
8932     if (trap_length == 0)
8933     {
8934 
8935         /* Increment the internal error counter.  */
8936         agent_ptr -> nx_snmp_agent_internal_errors++;
8937 
8938         /* Release the trap packet too.  */
8939         nx_packet_release(trap_packet_ptr);
8940 
8941         /* Return to caller.  */
8942         return(NX_SNMP_ERROR);
8943     }
8944 
8945     /* Move the trap buffer pointer up.  */
8946     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
8947 
8948     /* Adjust the trap sequence length.  */
8949     trap_sequence_length =  trap_sequence_length + trap_length;
8950 
8951     /* Adjust the security sequence length.  */
8952     trap_security_length =  trap_security_length + trap_length;
8953 
8954     /* Now setup the number of engine boots.  */
8955     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine_boots, trap_packet_ptr -> nx_packet_data_end);
8956 
8957     /* Check for a valid operation.  */
8958     if (trap_length == 0)
8959     {
8960 
8961         /* Increment the internal error counter.  */
8962         agent_ptr -> nx_snmp_agent_internal_errors++;
8963 
8964         /* Release the trap packet too.  */
8965         nx_packet_release(trap_packet_ptr);
8966 
8967         /* Return to caller.  */
8968         return(NX_SNMP_ERROR);
8969     }
8970 
8971     /* Move the trap buffer pointer up.  */
8972     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
8973 
8974     /* Adjust the trap sequence length.  */
8975     trap_sequence_length =  trap_sequence_length + trap_length;
8976 
8977     /* Adjust the security sequence length.  */
8978     trap_security_length =  trap_security_length + trap_length;
8979 
8980     /* Now setup the relative time since the last engine boot.  */
8981     agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time =  (UINT) (tx_time_get()/NX_IP_PERIODIC_RATE);
8982     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time, trap_packet_ptr -> nx_packet_data_end);
8983 
8984     /* Check for a valid operation.  */
8985     if (trap_length == 0)
8986     {
8987 
8988         /* Increment the internal error counter.  */
8989         agent_ptr -> nx_snmp_agent_internal_errors++;
8990 
8991         /* Release the trap packet too.  */
8992         nx_packet_release(trap_packet_ptr);
8993 
8994         /* Return to caller.  */
8995         return(NX_SNMP_ERROR);
8996     }
8997 
8998     /* Move the trap buffer pointer up.  */
8999     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9000 
9001     /* Adjust the trap sequence length.  */
9002     trap_sequence_length =  trap_sequence_length + trap_length;
9003 
9004     /* Adjust the security sequence length.  */
9005     trap_security_length =  trap_security_length + trap_length;
9006 
9007     /* Check username length.  */
9008     if (_nx_utility_string_length_check((CHAR *)username, &username_length, NX_SNMP_MAX_OCTET_STRING))
9009     {
9010         return(NX_SIZE_ERROR);
9011     }
9012 
9013     /* Now setup the user name, as specified by the input parameter.  */
9014     trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, username, username_length, trap_packet_ptr -> nx_packet_data_end);
9015 
9016     /* Check for a valid operation.  */
9017     if (trap_length == 0)
9018     {
9019 
9020         /* Increment the internal error counter.  */
9021         agent_ptr -> nx_snmp_agent_internal_errors++;
9022 
9023         /* Release the trap packet too.  */
9024         nx_packet_release(trap_packet_ptr);
9025 
9026         /* Return to caller.  */
9027         return(NX_SNMP_ERROR);
9028     }
9029 
9030     /* Move the trap buffer pointer up.  */
9031     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9032 
9033     /* Adjust the trap sequence length.  */
9034     trap_sequence_length =  trap_sequence_length + trap_length;
9035 
9036     /* Adjust the security sequence length.  */
9037     trap_security_length =  trap_security_length + trap_length;
9038 
9039     /* Now setup the authentication parameter - it is a 12 character field set to zeros initially.  */
9040     for (i = 0; i < NX_SNMP_DIGEST_SIZE; i++)
9041        temp_string[i] =  0;
9042 
9043     /****************** *****************  **********************/
9044     /*              Now set AUTHENTICATION PARAMETER.           */
9045     /****************** *****************  **********************/
9046     if (agent_ptr -> nx_snmp_agent_v3_auth_trap_key)
9047     {
9048 
9049         /* We have a valid authentication key, so initialize the string to zero. */
9050         trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, temp_string, NX_SNMP_DIGEST_SIZE, trap_packet_ptr -> nx_packet_data_end);
9051 
9052         trap_authentication_ptr =  trap_buffer_ptr + 2;
9053 
9054 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
9055         NX_SNMPV3_DBG_PRINTF("Starting trap3 authentication header 0x%x\n", trap_authentication_ptr);
9056 #endif
9057     }
9058     else
9059     {
9060         /* No security enabled so set this as an empty parameter. */
9061         trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, temp_string,0, trap_packet_ptr -> nx_packet_data_end);
9062     }
9063 
9064         /* Check for a valid operation.  */
9065     if (trap_length == 0)
9066     {
9067 
9068         /* Increment the internal error counter.  */
9069         agent_ptr -> nx_snmp_agent_internal_errors++;
9070 
9071         /* Release the trap packet too.  */
9072         nx_packet_release(trap_packet_ptr);
9073 
9074         /* Return to caller.  */
9075         return(NX_SNMP_ERROR);
9076     }
9077 
9078     /* Move the trap buffer pointer up.  */
9079     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9080 
9081     /* Adjust the trap sequence length.  */
9082     trap_sequence_length =  trap_sequence_length + trap_length;
9083 
9084     /* Adjust the security sequence length.  */
9085     trap_security_length =  trap_security_length + trap_length;
9086 
9087     /****************** *****************  **********************/
9088     /*              Now set 8 char PRIVACY PARAMETER.           */
9089     /****************** *****************  **********************/
9090     if (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)
9091     {
9092 
9093         /*  We will encrypt the message, so set to all zeros field initially. */
9094         trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, temp_string, 8, trap_packet_ptr -> nx_packet_data_end);
9095 
9096         trap_privacy_ptr =  trap_buffer_ptr + 2;
9097 
9098 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
9099         NX_SNMPV3_DBG_PRINTF("Starting trap_privacy_ptr 0x%x\n", trap_privacy_ptr);
9100 #endif
9101     }
9102     else
9103     {
9104         /* Not encrypting, so set the privacy field as an empty parameter. */
9105         trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, temp_string,0, trap_packet_ptr -> nx_packet_data_end);
9106     }
9107 
9108     /* Check for a valid operation.  */
9109     if (trap_length == 0)
9110     {
9111 
9112         /* Increment the internal error counter.  */
9113         agent_ptr -> nx_snmp_agent_internal_errors++;
9114 
9115         /* Release the trap packet too.  */
9116         nx_packet_release(trap_packet_ptr);
9117 
9118         /* Return to caller.  */
9119         return(NX_SNMP_ERROR);
9120     }
9121 
9122     /* Move the trap buffer pointer up.  */
9123     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9124 
9125     /* Adjust the trap sequence length.  */
9126     trap_sequence_length =  trap_sequence_length + trap_length;
9127 
9128     /* Adjust the security sequence length.  */
9129     trap_security_length =  trap_security_length + trap_length;
9130 
9131     /* Determine if privacy is required.  If so, decrypt the source PDU and setup the response
9132        to have an encryption header.  */
9133     if (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)
9134     {
9135 
9136 #ifndef NX_SNMP_NO_SECURITY
9137 
9138         /* Now setup the trap buffer to encapsulate the encrypted PDU.  Note that
9139            the actual encryption will be done after the complete trap has been
9140            formed.  */
9141         trap_buffer_ptr[0] =  NX_SNMP_ANS1_OCTET_STRING;
9142         trap_buffer_ptr[1] =  0x82;
9143         trap_buffer_ptr[2] =  0x00;
9144         trap_buffer_ptr[3] =  0x00;
9145 
9146         /* Save the trap encryption size pointer.  This will be filled in below
9147            as we build the message.  */
9148         trap_encryption_size_ptr =  trap_buffer_ptr + 2;
9149 
9150         /* Move the trap buffer forward.  */
9151         trap_buffer_ptr =  trap_buffer_ptr + 4;
9152 
9153         /* Increase the length of the total trap message.  */
9154         trap_sequence_length =  trap_sequence_length + 4;
9155 
9156 #else
9157         /* Encryption is not supported by this agent but is
9158            specified in the request or by the agent.  Simply
9159            discard the message.  */
9160 
9161         /* Increment the privacy error counter.  */
9162         agent_ptr -> nx_snmp_agent_privacy_errors++;
9163 
9164         /* Release the trap packet.  */
9165         nx_packet_release(trap_packet_ptr);
9166 
9167         /* Return to caller.  */
9168         return(NX_SNMP_ERROR);
9169 #endif
9170     }
9171 
9172     /* Save the trap pdu sequence pointer.  */
9173     trap_pdu_ptr =  trap_buffer_ptr;
9174 
9175     /* First, write the PDU sequence in the trap packet.  A zero is written for now.  This will be
9176        updated later.  */
9177     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
9178 
9179     /* Check for a valid operation.  */
9180     if (trap_length == 0)
9181     {
9182 
9183         /* Increment the internal error counter.  */
9184         agent_ptr -> nx_snmp_agent_internal_errors++;
9185 
9186         /* Release the trap packet.  */
9187         nx_packet_release(trap_packet_ptr);
9188 
9189         /* Return to caller.  */
9190         return(NX_SNMP_ERROR);
9191     }
9192 
9193     /* Move the trap buffer pointer.  */
9194     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9195 
9196     /* Increment the number of trap sequence bytes.  */
9197     trap_sequence_length =       trap_sequence_length + trap_length;
9198 
9199     /* Now store the PDU context engine in the trap packet.  */
9200     trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine, agent_ptr -> nx_snmp_agent_v3_context_engine_size, trap_packet_ptr -> nx_packet_data_end);
9201 
9202     /* Check for a valid packet.  */
9203     if (trap_length == 0)
9204     {
9205 
9206         /* Increment the invalid packet error counter.  */
9207         agent_ptr -> nx_snmp_agent_invalid_packets++;
9208 
9209         /* Release the trap packet.  */
9210         nx_packet_release(trap_packet_ptr);
9211 
9212         /* Return to caller.  */
9213         return(NX_SNMP_ERROR);
9214     }
9215 
9216     /* Move the trap pointer forward.  */
9217     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9218 
9219     /* Increment the sequence length.  */
9220     trap_sequence_length =       trap_sequence_length + trap_length;
9221 
9222     /* Increment the pdu length.  */
9223     trap_pdu_length =            trap_pdu_length + trap_length;
9224 
9225     /* Now store the PDU context name in the trap packet.  */
9226     trap_length =  _nx_snmp_utility_octet_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_name, agent_ptr -> nx_snmp_agent_v3_context_name_size, trap_packet_ptr -> nx_packet_data_end);
9227 
9228     /* Check for a valid packet.  */
9229     if (trap_length == 0)
9230     {
9231 
9232         /* Increment the invalid packet error counter.  */
9233         agent_ptr -> nx_snmp_agent_invalid_packets++;
9234 
9235         /* Release the trap packet.  */
9236         nx_packet_release(trap_packet_ptr);
9237 
9238         /* Return to caller.  */
9239         return(NX_SNMP_ERROR);
9240     }
9241 
9242     /* Move the trap pointer forward.  */
9243     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9244 
9245     /* Save the pointer to the trap type.  */
9246     trap_type_ptr =  trap_buffer_ptr;
9247 
9248     /* Increment the sequence length.  */
9249     trap_sequence_length =       trap_sequence_length + trap_length;
9250 
9251     /* Increment the pdu length.  */
9252     trap_pdu_length =            trap_pdu_length + trap_length;
9253 
9254     /* Setup the trap request type field.  */
9255     trap_length =  _nx_snmp_utility_request_type_set_multibyte(trap_buffer_ptr, NX_SNMP_ANS1_TRAP2_REQUEST, 0, trap_packet_ptr -> nx_packet_data_end);
9256 
9257     /* Check for a valid operation.  */
9258     if (trap_length == 0)
9259     {
9260 
9261         /* Increment the internal error counter.  */
9262         agent_ptr -> nx_snmp_agent_internal_errors++;
9263 
9264         /* Release the trap packet.  */
9265         nx_packet_release(trap_packet_ptr);
9266 
9267         /* Return to caller.  */
9268         return(NX_SNMP_ERROR);
9269     }
9270 
9271     /* Move the trap buffer pointer up.  */
9272     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9273 
9274     /* Adjust the trap sequence length.  */
9275     trap_sequence_length =  trap_sequence_length + trap_length;
9276 
9277     /* Increment the pdu length.  */
9278     trap_pdu_length =  trap_pdu_length + trap_length;
9279 
9280     /* Now set the request ID in the trap message.  */
9281     trap_length =  _nx_snmp_utility_request_id_set(trap_buffer_ptr, agent_ptr -> nx_snmp_agent_traps_sent, trap_packet_ptr -> nx_packet_data_end);
9282 
9283     /* Check for a valid operation.  */
9284     if (trap_length == 0)
9285     {
9286 
9287         /* Increment the internal error counter.  */
9288         agent_ptr -> nx_snmp_agent_internal_errors++;
9289 
9290         /* Release the trap packet.  */
9291         nx_packet_release(trap_packet_ptr);
9292 
9293         /* Return to caller.  */
9294         return(NX_SNMP_ERROR);
9295     }
9296 
9297     /* Move the trap buffer pointer up.  */
9298     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9299 
9300     /* Adjust the trap sequence length.  */
9301     trap_sequence_length =  trap_sequence_length + trap_length;
9302 
9303     /* Increment the pdu length.  */
9304     trap_pdu_length =  trap_pdu_length + trap_length;
9305 
9306     /* Adjust the trap request type length.  */
9307     trap_type_length =  trap_type_length + trap_length;
9308 
9309     /* Set the trap error information.  Assume everything is okay at this point.  */
9310     trap_length =  _nx_snmp_utility_error_info_set(trap_buffer_ptr, 0, 0, trap_packet_ptr -> nx_packet_data_end);
9311 
9312     /* Check for a valid operation.  */
9313     if (trap_length == 0)
9314     {
9315 
9316         /* Increment the internal error counter.  */
9317         agent_ptr -> nx_snmp_agent_internal_errors++;
9318 
9319         /* Release the trap packet.  */
9320         nx_packet_release(trap_packet_ptr);
9321 
9322         /* Return to caller.  */
9323         return(NX_SNMP_ERROR);
9324     }
9325 
9326     /* Move the trap buffer pointer up.  */
9327     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9328 
9329     /* Adjust the trap sequence length.  */
9330     trap_sequence_length =  trap_sequence_length + trap_length;
9331 
9332     /* Increment the pdu length.  */
9333     trap_pdu_length =  trap_pdu_length + trap_length;
9334 
9335     /* Adjust the trap request type length.  */
9336     trap_type_length =  trap_type_length + trap_length;
9337 
9338     /* Remember the start of the response's variable list field.  */
9339     trap_variable_list_ptr =  trap_buffer_ptr;
9340 
9341     /* Setup the variable list.  For now, the length will be zero.  We
9342        will overwrite this with the actual length later.  */
9343     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
9344 
9345     /* Check for a valid operation.  */
9346     if (trap_length == 0)
9347     {
9348 
9349         /* Increment the internal error counter.  */
9350         agent_ptr -> nx_snmp_agent_internal_errors++;
9351 
9352         /* Release the trap packet.  */
9353         nx_packet_release(trap_packet_ptr);
9354 
9355         /* Return to caller.  */
9356         return(NX_SNMP_ERROR);
9357     }
9358 
9359     /* Move the trap buffer pointer up.  */
9360     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9361 
9362     /* Adjust the trap sequence length.  */
9363     trap_sequence_length =  trap_sequence_length + trap_length;
9364 
9365     /* Increment the pdu length.  */
9366     trap_pdu_length =  trap_pdu_length + trap_length;
9367 
9368     /* Adjust the trap request type length.  */
9369     trap_type_length =  trap_type_length + trap_length;
9370 
9371     /* Remember the start of the variable.  */
9372     trap_variable_ptr =  trap_buffer_ptr;
9373 
9374     /* Setup the variable trap sequence.  For now, the length will be zero.  We
9375        will overwrite this with the actual length later.  */
9376     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
9377 
9378     /* Check for a valid operation.  */
9379     if (trap_length == 0)
9380     {
9381 
9382         /* Increment the internal error counter.  */
9383         agent_ptr -> nx_snmp_agent_internal_errors++;
9384 
9385         /* Release the trap packet.  */
9386         nx_packet_release(trap_packet_ptr);
9387 
9388         /* Return to caller.  */
9389         return(NX_SNMP_ERROR);
9390     }
9391 
9392     /* Move the trap buffer pointer up.  */
9393     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9394 
9395     /* Adjust the trap sequence length.  */
9396     trap_sequence_length =  trap_sequence_length + trap_length;
9397 
9398     /* Increment the pdu length.  */
9399     trap_pdu_length =  trap_pdu_length + trap_length;
9400 
9401     /* Adjust the trap request type length.  */
9402     trap_type_length =  trap_type_length + trap_length;
9403 
9404     /* Adjust the trap variable list size.  */
9405     trap_variable_list_length =  trap_variable_list_length + trap_length;
9406 
9407     /* Place the sysUpTime object ID into the trap buffer.  */
9408     trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, (UCHAR *) "1.3.6.1.2.1.1.3.0", trap_packet_ptr -> nx_packet_data_end);
9409 
9410     /* Check for a valid operation.  */
9411     if (trap_length == 0)
9412     {
9413 
9414         /* Release the trap packet.  */
9415         nx_packet_release(trap_packet_ptr);
9416 
9417         /* Done, return to caller.  */
9418         return(NX_SNMP_ERROR);
9419     }
9420 
9421     /* Move the trap buffer pointer up.  */
9422     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9423 
9424     /* Adjust the trap sequence length.  */
9425     trap_sequence_length =  trap_sequence_length + trap_length;
9426 
9427     /* Increment the pdu length.  */
9428     trap_pdu_length =  trap_pdu_length + trap_length;
9429 
9430     /* Adjust the trap request type length.  */
9431     trap_type_length =  trap_type_length + trap_length;
9432 
9433     /* Adjust the trap variable list size.  */
9434     trap_variable_list_length =  trap_variable_list_length + trap_length;
9435 
9436     /* Adjust the trap variable size.  */
9437     trap_variable_length =  trap_variable_length + trap_length;
9438 
9439     /* Insert the object's data into the trap buffer.  */
9440     trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_TIME_TICS;
9441     trap_object_data.nx_snmp_object_data_msw =   (LONG)elapsed_time;
9442     trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
9443 
9444     /* Check for a valid operation.  */
9445     if (trap_length == 0)
9446     {
9447 
9448         /* Release the trap packet.  */
9449         nx_packet_release(trap_packet_ptr);
9450 
9451         /* Done, return to caller.  */
9452         return(NX_SNMP_ERROR);
9453     }
9454 
9455     /* Move the trap buffer pointer up.  */
9456     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9457 
9458     /* Adjust the trap sequence length.  */
9459     trap_sequence_length =  trap_sequence_length + trap_length;
9460 
9461     /* Increment the pdu length.  */
9462     trap_pdu_length =  trap_pdu_length + trap_length;
9463 
9464     /* Adjust the trap request type length.  */
9465     trap_type_length =  trap_type_length + trap_length;
9466 
9467     /* Adjust the trap variable list size.  */
9468     trap_variable_list_length =  trap_variable_list_length + trap_length;
9469 
9470     /* Adjust the trap variable size.  */
9471     trap_variable_length =  trap_variable_length + trap_length;
9472 
9473     /* Now update the trap variable sequence with the actual variable length.  */
9474     _nx_snmp_utility_sequence_set(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
9475 
9476     /* Remember the start of the variable.  */
9477     trap_variable_ptr =  trap_buffer_ptr;
9478 
9479     /* Clear the trap variable size.  */
9480     trap_variable_length =  0;
9481 
9482     /* Setup the variable trap sequence.  For now, the length will be zero.  We
9483        will overwrite this with the actual length later.  */
9484     trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
9485 
9486     /* Check for a valid operation.  */
9487     if (trap_length == 0)
9488     {
9489 
9490         /* Increment the internal error counter.  */
9491         agent_ptr -> nx_snmp_agent_internal_errors++;
9492 
9493         /* Release the trap packet.  */
9494         nx_packet_release(trap_packet_ptr);
9495 
9496         /* Return to caller.  */
9497         return(NX_SNMP_ERROR);
9498     }
9499 
9500     /* Move the trap buffer pointer up.  */
9501     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9502 
9503     /* Adjust the trap sequence length.  */
9504     trap_sequence_length =  trap_sequence_length + trap_length;
9505 
9506     /* Increment the pdu length.  */
9507     trap_pdu_length =  trap_pdu_length + trap_length;
9508 
9509     /* Adjust the trap request type length.  */
9510     trap_type_length =  trap_type_length + trap_length;
9511 
9512     /* Adjust the trap variable list size.  */
9513     trap_variable_list_length =  trap_variable_list_length + trap_length;
9514 
9515     /* Place the snmpTrapOID object ID into the trap buffer.  */
9516     trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, (UCHAR *) "1.3.6.1.6.3.1.1.4.1.0", trap_packet_ptr -> nx_packet_data_end);
9517 
9518     /* Check for a valid operation.  */
9519     if (trap_length == 0)
9520     {
9521 
9522         /* Release the trap packet.  */
9523         nx_packet_release(trap_packet_ptr);
9524 
9525         /* Done, return to caller.  */
9526         return(NX_SNMP_ERROR);
9527     }
9528 
9529     /* Move the trap buffer pointer up.  */
9530     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9531 
9532     /* Adjust the trap sequence length.  */
9533     trap_sequence_length =  trap_sequence_length + trap_length;
9534 
9535     /* Increment the pdu length.  */
9536     trap_pdu_length =  trap_pdu_length + trap_length;
9537 
9538     /* Adjust the trap request type length.  */
9539     trap_type_length =  trap_type_length + trap_length;
9540 
9541     /* Adjust the trap variable list size.  */
9542     trap_variable_list_length =  trap_variable_list_length + trap_length;
9543 
9544     /* Adjust the trap variable size.  */
9545     trap_variable_length =  trap_variable_length + trap_length;
9546 
9547     /* Set a Object ID for the data.  */
9548     trap_object_data.nx_snmp_object_data_type =  NX_SNMP_ANS1_OBJECT_ID;
9549     trap_object_data.nx_snmp_object_data_msw =   0;
9550 
9551     /* Check oid length.  */
9552     if (_nx_utility_string_length_check((CHAR *)oid, NX_NULL, NX_SNMP_MAX_OCTET_STRING))
9553     {
9554 
9555         /* Release the trap packet.  */
9556         nx_packet_release(trap_packet_ptr);
9557 
9558         /* Done, return to caller.  */
9559         return(NX_SNMP_ERROR);
9560     }
9561 
9562     _nx_snmp_object_copy(oid, trap_object_data.nx_snmp_object_octet_string);
9563     trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, &trap_object_data, trap_packet_ptr -> nx_packet_data_end);
9564 
9565     /* Check for a valid operation.  */
9566     if (trap_length == 0)
9567     {
9568 
9569         /* Release the trap packet.  */
9570         nx_packet_release(trap_packet_ptr);
9571 
9572         /* Done, return to caller.  */
9573         return(NX_SNMP_ERROR);
9574     }
9575 
9576     /* Move the trap buffer pointer up.  */
9577     trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9578 
9579     /* Adjust the trap sequence length.  */
9580     trap_sequence_length =  trap_sequence_length + trap_length;
9581 
9582     /* Increment the pdu length.  */
9583     trap_pdu_length =  trap_pdu_length + trap_length;
9584 
9585     /* Adjust the trap request type length.  */
9586     trap_type_length =  trap_type_length + trap_length;
9587 
9588     /* Adjust the trap variable list size.  */
9589     trap_variable_list_length =  trap_variable_list_length + trap_length;
9590 
9591     /* Adjust the trap variable size.  */
9592     trap_variable_length =  trap_variable_length + trap_length;
9593 
9594     /* Now update the trap variable sequence with the actual variable length.  */
9595     _nx_snmp_utility_sequence_set(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
9596 
9597     /* Default the object pointer to NULL.  */
9598     trap_object_ptr =  NX_NULL;
9599 
9600     /* Determine if an object is specified.  */
9601     if (object_list_ptr)
9602     {
9603 
9604         /* Setup object pointers from the supplied object list.  */
9605         trap_object_ptr =       object_list_ptr -> nx_snmp_object_string_ptr;
9606         trap_object_data_ptr =  object_list_ptr -> nx_snmp_object_data;
9607 
9608         /* Check for a valid operation.  */
9609         if(trap_object_ptr != NX_NULL && trap_object_data_ptr == NX_NULL)
9610         {
9611             /* Release the trap packet.  */
9612             nx_packet_release(trap_packet_ptr);
9613 
9614             /* Done, return to caller.  */
9615             return(NX_SNMP_ERROR);
9616         }
9617     }
9618 
9619     /* Loop to process all the objects in the list.  */
9620     while (trap_object_ptr)
9621     {
9622 
9623         /* Clear the trap variable length.  */
9624         trap_variable_length =  0;
9625 
9626         /* Remember the start of the variable.  */
9627         trap_variable_ptr =  trap_buffer_ptr;
9628 
9629         /* Setup the variable trap sequence.  For now, the length will be zero.  We
9630            will overwrite this with the actual length later.  */
9631         trap_length =  _nx_snmp_utility_sequence_set(trap_buffer_ptr, 0, trap_packet_ptr -> nx_packet_data_end);
9632 
9633         /* Check for a valid operation.  */
9634         if (trap_length == 0)
9635         {
9636 
9637             /* Increment the internal error counter.  */
9638             agent_ptr -> nx_snmp_agent_internal_errors++;
9639 
9640             /* Release the trap packet.  */
9641             nx_packet_release(trap_packet_ptr);
9642 
9643             /* Return to caller.  */
9644             return(NX_SNMP_ERROR);
9645         }
9646 
9647         /* Move the trap buffer pointer up.  */
9648         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9649 
9650         /* Adjust the trap sequence length.  */
9651         trap_sequence_length =  trap_sequence_length + trap_length;
9652 
9653         /* Increment the pdu length.  */
9654         trap_pdu_length =  trap_pdu_length + trap_length;
9655 
9656         /* Adjust the trap request type length.  */
9657         trap_type_length =  trap_type_length + trap_length;
9658 
9659         /* Adjust the trap variable list size.  */
9660         trap_variable_list_length =  trap_variable_list_length + trap_length;
9661 
9662         /* Place the object into the trap buffer.  */
9663         trap_length =  _nx_snmp_utility_object_id_set(trap_buffer_ptr, trap_object_ptr, trap_packet_ptr -> nx_packet_data_end);
9664 
9665         /* Check for a valid operation.  */
9666         if (trap_length == 0)
9667         {
9668 
9669             /* Release the trap packet.  */
9670             nx_packet_release(trap_packet_ptr);
9671 
9672             /* Done, return to caller.  */
9673             return(NX_SNMP_ERROR);
9674         }
9675 
9676         /* Move the trap buffer pointer up.  */
9677         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9678 
9679         /* Adjust the trap sequence length.  */
9680         trap_sequence_length =  trap_sequence_length + trap_length;
9681 
9682         /* Increment the pdu length.  */
9683         trap_pdu_length =  trap_pdu_length + trap_length;
9684 
9685         /* Adjust the trap request type length.  */
9686         trap_type_length =  trap_type_length + trap_length;
9687 
9688         /* Adjust the trap variable list size.  */
9689         trap_variable_list_length =  trap_variable_list_length + trap_length;
9690 
9691         /* Adjust the trap variable size.  */
9692         trap_variable_length =  trap_variable_length + trap_length;
9693 
9694         /* Insert the object's data into the trap buffer.  */
9695         trap_length =  _nx_snmp_utility_object_data_set(trap_buffer_ptr, trap_object_data_ptr, trap_packet_ptr -> nx_packet_data_end);
9696 
9697         /* Check for a valid operation.  */
9698         if (trap_length == 0)
9699         {
9700 
9701             /* Release the trap packet.  */
9702             nx_packet_release(trap_packet_ptr);
9703 
9704             /* Done, return to caller.  */
9705             return(NX_SNMP_ERROR);
9706         }
9707 
9708         /* Move the trap buffer pointer up.  */
9709         trap_buffer_ptr =  trap_buffer_ptr + trap_length;
9710 
9711         /* Adjust the trap sequence length.  */
9712         trap_sequence_length =  trap_sequence_length + trap_length;
9713 
9714         /* Increment the pdu length.  */
9715         trap_pdu_length =  trap_pdu_length + trap_length;
9716 
9717         /* Adjust the trap request type length.  */
9718         trap_type_length =  trap_type_length + trap_length;
9719 
9720         /* Adjust the trap variable list size.  */
9721         trap_variable_list_length =  trap_variable_list_length + trap_length;
9722 
9723         /* Adjust the trap variable size.  */
9724         trap_variable_length =  trap_variable_length + trap_length;
9725 
9726         /* Now update the trap variable sequence with the actual variable length.  */
9727         _nx_snmp_utility_sequence_set(trap_variable_ptr, trap_variable_length, trap_packet_ptr -> nx_packet_data_end);
9728 
9729         /* Default the object pointer to NULL.  */
9730         trap_object_ptr =  NX_NULL;
9731 
9732         /* Determine if there are more objects to insert into the trap message.  */
9733         if (object_list_ptr)
9734         {
9735 
9736             /* Move to the next object in the list.  */
9737             object_list_ptr++;
9738 
9739             if (object_list_ptr == NX_NULL)
9740             {
9741                 /* Release the trap packet.  */
9742                 nx_packet_release(trap_packet_ptr);
9743 
9744                 /* Done, return to caller.  */
9745                 return(NX_SNMP_ERROR);
9746             }
9747 
9748             /* Determine if there is another object.  */
9749             if (object_list_ptr -> nx_snmp_object_string_ptr)
9750             {
9751 
9752                 /* Setup the object and object data pointers.  */
9753                 trap_object_ptr =       object_list_ptr -> nx_snmp_object_string_ptr;
9754                 trap_object_data_ptr =  object_list_ptr -> nx_snmp_object_data;
9755 
9756                 /* Check for a valid operation.  */
9757                 if(trap_object_ptr != NX_NULL && trap_object_data_ptr == NX_NULL)
9758                 {
9759                     /* Release the trap packet.  */
9760                     nx_packet_release(trap_packet_ptr);
9761 
9762                     /* Done, return to caller.  */
9763                     return(NX_SNMP_ERROR);
9764                 }
9765             }
9766         }
9767     }
9768 
9769     /* At this point, several trap fields need to be updated with actual lengths.  */
9770     _nx_snmp_utility_sequence_set(trap_sequence_ptr, trap_sequence_length, trap_packet_ptr -> nx_packet_data_end);
9771     _nx_snmp_utility_sequence_set(trap_header_ptr, trap_header_length, trap_packet_ptr -> nx_packet_data_end);
9772     _nx_snmp_utility_sequence_set_1byte(trap_security_ptr, trap_security_length, trap_packet_ptr -> nx_packet_data_end);
9773     _nx_snmp_utility_sequence_set(trap_pdu_ptr, trap_pdu_length, trap_packet_ptr -> nx_packet_data_end);
9774     _nx_snmp_utility_sequence_set(trap_variable_list_ptr, trap_variable_list_length, trap_packet_ptr -> nx_packet_data_end);
9775     _nx_snmp_utility_request_type_set_multibyte(trap_type_ptr, NX_SNMP_ANS1_TRAP2_REQUEST, trap_type_length, trap_packet_ptr -> nx_packet_data_end);
9776 
9777     /* Setup the security OCTET string length.  */
9778 
9779     /* Backup to the OCTET string for the security size.  */
9780     trap_security_ptr =  trap_security_ptr - 2;
9781 
9782     /* Account for the 2 byte Security Sequence field.  */
9783     trap_security_length =  trap_security_length + 2;
9784 
9785     /* Store the security size.  */
9786     trap_security_ptr[1] =  (UCHAR) (trap_security_length & 0xFF);
9787 
9788     /* Determine if privacy is required.  If so, encrypt the PDU and setup the response
9789        to have an encryption header.  */
9790     if (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)
9791     {
9792 
9793 #ifndef NX_SNMP_NO_SECURITY
9794 
9795         /* Determine if any padding needs to be applied - account for the
9796            four bytes of header information on the PDU.  */
9797         trap_pdu_length =  trap_pdu_length + 4;
9798         padding =  ((trap_pdu_length+7)/8)*8 - trap_pdu_length;
9799 
9800         /* Add the padding the trap PDU length and the trap sequence length.  */
9801         trap_pdu_length =       trap_pdu_length + padding;
9802         trap_sequence_length =  trap_sequence_length + padding;
9803 
9804         /* Clear the end of the trap message...  just to be nice!  */
9805         for (i = 0; i < padding; i++)
9806         {
9807 
9808             /* Clear byte at the end of the response.  */
9809             *trap_buffer_ptr++ =  0;
9810         }
9811 
9812         /* Setup the size of the encrypted PDU.  */
9813         trap_encryption_size_ptr[0] =  (UCHAR) ((trap_pdu_length >> 8) & 0xFF);
9814         trap_encryption_size_ptr[1] =  (UCHAR) (trap_pdu_length & 0xFF);
9815 
9816         /* Update the total trap sequence length again. */
9817         _nx_snmp_utility_sequence_set(trap_sequence_ptr, trap_sequence_length, trap_packet_ptr -> nx_packet_data_end);
9818 
9819         /* Increment the salt counter.  */
9820         agent_ptr -> nx_snmp_agent_v3_context_salt_counter++;
9821 
9822         /* Build the salt value for the decryption.  */
9823         key1[0] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_engine_boots >> 24) & 0xFF);
9824         key1[1] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_engine_boots >> 16) & 0xFF);
9825         key1[2] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_engine_boots >>  8) & 0xFF);
9826         key1[3] =  (UCHAR) (agent_ptr -> nx_snmp_agent_v3_context_engine_boots & 0xFF);
9827         key1[4] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_salt_counter >> 24) & 0xFF);
9828         key1[5] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_salt_counter >> 16) & 0xFF);
9829         key1[6] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_salt_counter >>  8) & 0xFF);
9830         key1[7] =  (UCHAR) (agent_ptr -> nx_snmp_agent_v3_context_salt_counter & 0xFF);
9831 
9832         /* Loop to store the salt in the privacy field.  */
9833         for (i = 0; i < 8; i++)
9834         {
9835 
9836             /* Store a byte of the salt.  */
9837             trap_privacy_ptr[i] =  key1[i];
9838         }
9839 
9840         /* Setup pointer to the actual PDU.  */
9841         temp_ptr =  trap_encryption_size_ptr + 2;
9842 
9843         /* Make the Initialization Vector (IV).  */
9844         for (i = 0; i < 8; i++)
9845         {
9846 
9847             key2[i] =  (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)->nx_snmp_security_key[8+i] ^ key1[i];
9848         }
9849 
9850         /* Setup the DES.  */
9851         _nx_des_key_set(&(agent_ptr -> nx_snmp_agent_v3_des_data), (agent_ptr -> nx_snmp_agent_v3_priv_trap_key)->nx_snmp_security_key);
9852 
9853         /* Setup the first input block - use the IV for the first block.  */
9854         for (i = 0; i < 8; i++)
9855         {
9856 
9857             key1[i] =  temp_ptr[i] ^ key2[i];
9858         }
9859 
9860         /* Encrypt the first 8 bytes.  */
9861         _nx_des_encrypt(&(agent_ptr -> nx_snmp_agent_v3_des_data), &key1[0], &temp_ptr[0]);
9862 
9863         /* Loop to encrypt the rest of the PDU.  */
9864         j =  8;
9865         do
9866         {
9867 
9868             /* Setup the next input block.  */
9869             for (i = 0; i < 8; i++)
9870             {
9871 
9872                 key1[i] =  temp_ptr[j+i] ^ temp_ptr[(j-8)+i];
9873             }
9874 
9875             /* Encrypt the next 8 bytes.  */
9876             _nx_des_encrypt(&(agent_ptr -> nx_snmp_agent_v3_des_data), &key1[0], &temp_ptr[j]);
9877 
9878             /* Move the major index forward.  */
9879             j =  j + 8;
9880         } while (j < trap_pdu_length);
9881 
9882 #else
9883 
9884         /* Increment the privacy error counter.  */
9885         agent_ptr -> nx_snmp_agent_privacy_errors++;
9886 
9887         /* Release the trap packet too.  */
9888         nx_packet_release(trap_packet_ptr);
9889 
9890         /* Return to caller.  */
9891         return NX_SNMP_ERROR;
9892 #endif
9893     }
9894 
9895     /* Now the trap packet's pointers must be setup so it can be sent.  */
9896     trap_packet_ptr -> nx_packet_length =  (ULONG)(trap_buffer_ptr - trap_packet_ptr -> nx_packet_prepend_ptr);
9897     trap_packet_ptr -> nx_packet_append_ptr =  trap_buffer_ptr;
9898 
9899 #ifndef NX_SNMP_NO_SECURITY
9900 
9901     /* Determine if authentication is required.  */
9902     if (agent_ptr -> nx_snmp_agent_v3_auth_trap_key)
9903     {
9904 
9905         /* Yes, authentication is required.  */
9906 
9907         /* Now determine which authentication is required.  */
9908         if ((agent_ptr -> nx_snmp_agent_v3_auth_trap_key) -> nx_snmp_security_key_type == NX_SNMP_MD5_KEY)
9909         {
9910 
9911             /* Copy the base MD5 key into key1.  */
9912             for (i = 0; i < NX_SNMP_MD5_DIGEST_SIZE; i++)
9913             {
9914 
9915                 /* Copy a byte of the base MD5 key.  */
9916                 key1[i] = (agent_ptr -> nx_snmp_agent_v3_auth_trap_key) -> nx_snmp_security_key[i];
9917             }
9918 
9919             /* Extend key1 to 64 bytes.  */
9920             for (i = NX_SNMP_MD5_DIGEST_SIZE; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
9921             {
9922                 key1[i] =  0;
9923             }
9924 
9925             /* Create key1 and key2.  */
9926             for (i = 0; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
9927             {
9928                 key2[i] = key1[i] ^ 0x5C;
9929                 key1[i] = key1[i] ^ 0x36;
9930             }
9931 
9932             /* Calculate the MAC.  */
9933             _nx_md5_initialize(&(agent_ptr -> nx_snmp_agent_v3_md5_data));
9934 
9935             /* Calculate prepend Key1.  */
9936             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1, NX_SNMP_DIGEST_WORKING_SIZE);
9937 
9938             /* Calculate the message.  */
9939             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), trap_packet_ptr -> nx_packet_prepend_ptr, trap_packet_ptr -> nx_packet_length);
9940 
9941             /* Final calculation of the first pass.   */
9942             _nx_md5_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1);
9943 
9944             /* Prepare to calculate the final MAC.  */
9945             _nx_md5_initialize(&(agent_ptr -> nx_snmp_agent_v3_md5_data));
9946 
9947             /* Prepend Key2 to the result.  */
9948             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key2, NX_SNMP_DIGEST_WORKING_SIZE);
9949 
9950             /* Calculate the previous result.  */
9951             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1, NX_SNMP_MD5_DIGEST_SIZE);
9952 
9953             /* Calculate the final MAC. */
9954             _nx_md5_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key2);
9955         }
9956         else if ((agent_ptr -> nx_snmp_agent_v3_auth_trap_key) -> nx_snmp_security_key_type == NX_SNMP_SHA_KEY)
9957         {
9958 
9959             /* Copy the base SHA key into key1.  */
9960             for (i = 0; i < NX_SNMP_SHA_DIGEST_SIZE; i++)
9961             {
9962 
9963                 /* Copy a byte of the base SHA key.  */
9964                 key1[i] = (agent_ptr -> nx_snmp_agent_v3_auth_trap_key) -> nx_snmp_security_key[i];
9965             }
9966 
9967             /* Extend key1 to 64 bytes.  */
9968             for (i = NX_SNMP_SHA_DIGEST_SIZE; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
9969             {
9970                 key1[i] =  0;
9971             }
9972 
9973             /* Create key1 and key2.  */
9974             for (i = 0; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
9975             {
9976                 key2[i] = key1[i] ^ 0x5C;
9977                 key1[i] = key1[i] ^ 0x36;
9978             }
9979 
9980             /* Calculate the MAC.  */
9981             _nx_sha1_initialize(&(agent_ptr -> nx_snmp_agent_v3_sha_data));
9982 
9983             /* Calculate prepend Key1.  */
9984             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1, NX_SNMP_DIGEST_WORKING_SIZE);
9985 
9986             /* Calculate the message.  */
9987             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), trap_packet_ptr -> nx_packet_prepend_ptr, trap_packet_ptr -> nx_packet_length);
9988 
9989             /* Final calculation of the first pass.   */
9990             _nx_sha1_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1);
9991 
9992             /* Prepare to calculate the final MAC.  */
9993             _nx_sha1_initialize(&(agent_ptr -> nx_snmp_agent_v3_sha_data));
9994 
9995             /* Prepend Key2 to the result.  */
9996             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key2, NX_SNMP_DIGEST_WORKING_SIZE);
9997 
9998             /* Calculate the previous result.  */
9999             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1, NX_SNMP_SHA_DIGEST_SIZE);
10000 
10001             /* Calculate the final MAC. */
10002             _nx_sha1_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key2);
10003         }
10004         else
10005         {
10006 
10007             /* Increment the authentication error counter.  */
10008             agent_ptr -> nx_snmp_agent_authentication_errors++;
10009 
10010             /* Release packet.  */
10011             nx_packet_release(trap_packet_ptr);
10012 
10013             /* Return to caller.  */
10014             return(NX_SNMP_ERROR);
10015         }
10016 
10017         /* At this point, key2 contains the computed digest of the message.  This needs to be
10018            place in the outgoing message.  */
10019 
10020         /* Loop to setup the outgoing digest.  */
10021         for (i = 0; i < NX_SNMP_DIGEST_SIZE; i++)
10022         {
10023 
10024             /* Copy one byte of digest.  */
10025             trap_authentication_ptr[i] =  key2[i];
10026         }
10027     }
10028 #endif
10029 
10030     /* Update various statistics.  */
10031     agent_ptr -> nx_snmp_agent_traps_sent++;
10032     agent_ptr -> nx_snmp_agent_packets_sent++;
10033     agent_ptr -> nx_snmp_agent_total_bytes_sent += trap_packet_ptr -> nx_packet_length;
10034 
10035     /* Send the trap packet back to the requesting SNMP manager.  */
10036 
10037     status =  nxd_udp_socket_send(&(agent_ptr -> nx_snmp_agent_socket), trap_packet_ptr, ipduo_address, NX_SNMP_MANAGER_TRAP_PORT);
10038 
10039     /* Determine if the packet needs to be released. */
10040     if (status)
10041     {
10042 
10043         /* Release packet.  */
10044         nx_packet_release(trap_packet_ptr);
10045 
10046         /* Return error. */
10047         return(NX_SNMP_ERROR);
10048     }
10049 
10050     /* Return successful completion.  */
10051     return(NX_SUCCESS);
10052 }
10053 
10054 
10055 #endif /* NX_SNMP_DISABLE_V3 */
10056 
10057 
10058 /**************************************************************************/
10059 /*                                                                        */
10060 /*  FUNCTION                                               RELEASE        */
10061 /*                                                                        */
10062 /*    _nxe_snmp_object_compare                            PORTABLE C      */
10063 /*                                                           6.1          */
10064 /*  AUTHOR                                                                */
10065 /*                                                                        */
10066 /*    Yuxin Zhou, Microsoft Corporation                                   */
10067 /*                                                                        */
10068 /*  DESCRIPTION                                                           */
10069 /*                                                                        */
10070 /*    This function checks for errors in the SNMP agent object compare    */
10071 /*    function call.                                                      */
10072 /*                                                                        */
10073 /*  INPUT                                                                 */
10074 /*                                                                        */
10075 /*    requested_object                      Pointer to requested object   */
10076 /*    actual_object                         Pointer to actual object      */
10077 /*                                                                        */
10078 /*  OUTPUT                                                                */
10079 /*                                                                        */
10080 /*    status                                Completion status             */
10081 /*                                                                        */
10082 /*  CALLS                                                                 */
10083 /*                                                                        */
10084 /*    _nx_snmp_object_compare               Actual agent object compare   */
10085 /*                                            function                    */
10086 /*                                                                        */
10087 /*  CALLED BY                                                             */
10088 /*                                                                        */
10089 /*    Application Code                                                    */
10090 /*                                                                        */
10091 /*  RELEASE HISTORY                                                       */
10092 /*                                                                        */
10093 /*    DATE              NAME                      DESCRIPTION             */
10094 /*                                                                        */
10095 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10096 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10097 /*                                            resulting in version 6.1    */
10098 /*                                                                        */
10099 /**************************************************************************/
_nxe_snmp_object_compare(UCHAR * requested_object,UCHAR * actual_object)10100 UINT  _nxe_snmp_object_compare(UCHAR *requested_object, UCHAR *actual_object)
10101 {
10102 
10103 UINT    status;
10104 
10105 
10106     /* Check for invalid input pointers.  */
10107     if ((requested_object == NX_NULL) || (actual_object == NX_NULL))
10108         return(NX_PTR_ERROR);
10109 
10110     /* Call actual service.  */
10111     status =  _nx_snmp_object_compare(requested_object, actual_object);
10112 
10113     /* Return status.  */
10114     return(status);
10115 }
10116 
10117 
10118 /**************************************************************************/
10119 /*                                                                        */
10120 /*  FUNCTION                                               RELEASE        */
10121 /*                                                                        */
10122 /*    _nx_snmp_object_compare                             PORTABLE C      */
10123 /*                                                           6.1          */
10124 /*  AUTHOR                                                                */
10125 /*                                                                        */
10126 /*    Yuxin Zhou, Microsoft Corporation                                   */
10127 /*                                                                        */
10128 /*  DESCRIPTION                                                           */
10129 /*                                                                        */
10130 /*    This function compares two objects.                                 */
10131 /*                                                                        */
10132 /*    Note: new API nx_snmp_object_compare_extended is encouraged to use. */
10133 /*                                                                        */
10134 /*  INPUT                                                                 */
10135 /*                                                                        */
10136 /*    requested_object                      Pointer to requested object   */
10137 /*    actual_object                         Pointer to actual object      */
10138 /*                                                                        */
10139 /*  OUTPUT                                                                */
10140 /*                                                                        */
10141 /*    status                                Completion status             */
10142 /*                                                                        */
10143 /*  CALLS                                                                 */
10144 /*                                                                        */
10145 /*    _nx_snmp_object_compare_extended      Call actual compare service   */
10146 /*                                                                        */
10147 /*  CALLED BY                                                             */
10148 /*                                                                        */
10149 /*    Application Code                                                    */
10150 /*                                                                        */
10151 /*  RELEASE HISTORY                                                       */
10152 /*                                                                        */
10153 /*    DATE              NAME                      DESCRIPTION             */
10154 /*                                                                        */
10155 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10156 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10157 /*                                            resulting in version 6.1    */
10158 /*                                                                        */
10159 /**************************************************************************/
_nx_snmp_object_compare(UCHAR * requested_object,UCHAR * actual_object)10160 UINT  _nx_snmp_object_compare(UCHAR *requested_object, UCHAR *actual_object)
10161 {
10162 
10163 UINT    status;
10164 UINT    requested_object_length;
10165 UINT    actual_object_length;
10166 
10167 
10168     /* Calculate the object length.  */
10169     if ((_nx_utility_string_length_check((CHAR *)requested_object, &requested_object_length, NX_MAX_STRING_LENGTH)) ||
10170         (_nx_utility_string_length_check((CHAR *)actual_object, &actual_object_length, NX_MAX_STRING_LENGTH)))
10171     {
10172         return(NX_SIZE_ERROR);
10173     }
10174 
10175     /* Call actual service.  */
10176     status = _nx_snmp_object_compare_extended(requested_object, requested_object_length, actual_object, actual_object_length);
10177 
10178     /* Return status to the caller.  */
10179     return(status);
10180 }
10181 
10182 
10183 /**************************************************************************/
10184 /*                                                                        */
10185 /*  FUNCTION                                               RELEASE        */
10186 /*                                                                        */
10187 /*    _nxe_snmp_object_compare_extended                   PORTABLE C      */
10188 /*                                                           6.1          */
10189 /*  AUTHOR                                                                */
10190 /*                                                                        */
10191 /*    Yuxin Zhou, Microsoft Corporation                                   */
10192 /*                                                                        */
10193 /*  DESCRIPTION                                                           */
10194 /*                                                                        */
10195 /*    This function checks for errors in the SNMP agent object compare    */
10196 /*    function call.                                                      */
10197 /*                                                                        */
10198 /*  INPUT                                                                 */
10199 /*                                                                        */
10200 /*    requested_object                      Pointer to requested object   */
10201 /*    requested_object_length               Length of object requested    */
10202 /*    actual_object                         Pointer to actual object      */
10203 /*    actual_object_length                  Length of object requested    */
10204 /*                                                                        */
10205 /*  OUTPUT                                                                */
10206 /*                                                                        */
10207 /*    status                                Completion status             */
10208 /*                                                                        */
10209 /*  CALLS                                                                 */
10210 /*                                                                        */
10211 /*    _nx_snmp_object_compare_extended      Actual agent object compare   */
10212 /*                                            extended function           */
10213 /*                                                                        */
10214 /*  CALLED BY                                                             */
10215 /*                                                                        */
10216 /*    Application Code                                                    */
10217 /*                                                                        */
10218 /*  RELEASE HISTORY                                                       */
10219 /*                                                                        */
10220 /*    DATE              NAME                      DESCRIPTION             */
10221 /*                                                                        */
10222 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10223 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10224 /*                                            resulting in version 6.1    */
10225 /*                                                                        */
10226 /**************************************************************************/
_nxe_snmp_object_compare_extended(UCHAR * requested_object,UINT requested_object_length,UCHAR * actual_object,UINT actual_object_length)10227 UINT  _nxe_snmp_object_compare_extended(UCHAR *requested_object, UINT requested_object_length, UCHAR *actual_object, UINT actual_object_length)
10228 {
10229 
10230 
10231     /* Check for invalid input pointers.  */
10232     if ((requested_object == NX_NULL) || (actual_object == NX_NULL))
10233         return(NX_PTR_ERROR);
10234 
10235     /* Call actual service.  */
10236     return(_nx_snmp_object_compare_extended(requested_object, requested_object_length, actual_object, actual_object_length));
10237 }
10238 
10239 
10240 /**************************************************************************/
10241 /*                                                                        */
10242 /*  FUNCTION                                               RELEASE        */
10243 /*                                                                        */
10244 /*    _nx_snmp_object_compare_extended                    PORTABLE C      */
10245 /*                                                           6.1          */
10246 /*  AUTHOR                                                                */
10247 /*                                                                        */
10248 /*    Yuxin Zhou, Microsoft Corporation                                   */
10249 /*                                                                        */
10250 /*  DESCRIPTION                                                           */
10251 /*                                                                        */
10252 /*    This function compares two objects.                                 */
10253 /*                                                                        */
10254 /*    Note: The strings of requested object and actual object must be     */
10255 /*    NULL-terminated and length of each string matches the length        */
10256 /*                                                                        */
10257 /*  INPUT                                                                 */
10258 /*                                                                        */
10259 /*    requested_object                      Pointer to requested object   */
10260 /*    requested_object_length               Length of object requested    */
10261 /*    actual_object                         Pointer to actual object      */
10262 /*    actual_object_length                  Length of object requested    */
10263 /*                                                                        */
10264 /*  OUTPUT                                                                */
10265 /*                                                                        */
10266 /*    status                                Completion status             */
10267 /*                                                                        */
10268 /*  CALLS                                                                 */
10269 /*                                                                        */
10270 /*    None                                                                */
10271 /*                                                                        */
10272 /*  CALLED BY                                                             */
10273 /*                                                                        */
10274 /*    Application Code                                                    */
10275 /*                                                                        */
10276 /*  RELEASE HISTORY                                                       */
10277 /*                                                                        */
10278 /*    DATE              NAME                      DESCRIPTION             */
10279 /*                                                                        */
10280 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10281 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10282 /*                                            resulting in version 6.1    */
10283 /*                                                                        */
10284 /**************************************************************************/
_nx_snmp_object_compare_extended(UCHAR * requested_object,UINT requested_object_length,UCHAR * actual_object,UINT actual_object_length)10285 UINT  _nx_snmp_object_compare_extended(UCHAR *requested_object, UINT requested_object_length, UCHAR *actual_object, UINT actual_object_length)
10286 {
10287 
10288 UINT    i, j;
10289 UINT    request_value;
10290 UINT    actual_value;
10291 UINT    temp_requested_object_length;
10292 UINT    temp_actual_object_lenght;
10293 
10294 
10295     /* Check object string and get the actual string length.  */
10296     if ((_nx_utility_string_length_check((CHAR *)requested_object, &temp_requested_object_length, requested_object_length)) ||
10297         (_nx_utility_string_length_check((CHAR *)actual_object, &temp_actual_object_lenght, actual_object_length)))
10298         return(NX_SNMP_ERROR);
10299 
10300     /* Check the actual string length.  */
10301     if ((requested_object_length != temp_requested_object_length) ||
10302         (actual_object_length != temp_actual_object_lenght))
10303         return(NX_SNMP_ERROR);
10304 
10305     /* Loop to compare the first and second object name.  Stop at the first NULL.  */
10306     i =  0;
10307     request_value =  0;
10308     actual_value =   0;
10309     while ((requested_object[i]) && (actual_object[i]))
10310     {
10311 
10312         /* Update the requested object value.  */
10313         if (requested_object[i] == '.')
10314             request_value =  0;
10315         else
10316             request_value =  (request_value * 10) + (UINT) (requested_object[i] - '0');
10317 
10318         /* Update the actual object value.  */
10319         if (actual_object[i] == '.')
10320             actual_value =  0;
10321         else
10322             actual_value =  (actual_value * 10) + (UINT) (actual_object[i] - '0');
10323 
10324         /* Determine if the names are different.  */
10325         if (requested_object[i] != actual_object[i])
10326         {
10327 
10328             /* Calculate the remainder - if any - of the requested value.  */
10329             j =  i;
10330             while ((requested_object[j]) && (requested_object[j] != '.'))
10331             {
10332 
10333                 /* Update the request value.  */
10334                 request_value =  (request_value * 10) + (UINT) (requested_object[j] - '0');
10335 
10336                 /* Move to next entry.  */
10337                 j++;
10338             }
10339 
10340 
10341             /* Calculate the remainder - if any - of the actual value.  */
10342             j =  i;
10343             while ((actual_object[j]) && (actual_object[j] != '.'))
10344             {
10345 
10346                 /* Update the actual value.  */
10347                 actual_value =  (actual_value * 10) + (UINT) (actual_object[j] - '0');
10348 
10349                 /* Move to next entry.  */
10350                 j++;
10351             }
10352 
10353             /* Determine if the requested object name is less than the actual object name.  */
10354             if (request_value < actual_value)
10355                 return(NX_SNMP_NEXT_ENTRY);
10356             else
10357                 break;
10358         }
10359 
10360         /* Move to next character.  */
10361         i++;
10362     }
10363 
10364     /* Now compare the names to check for a successful match.  */
10365     if ((requested_object[i] == NX_NULL) && (actual_object[i] == NX_NULL))
10366         return(NX_SUCCESS);
10367 
10368     /* If the actual object is NULL, that means that everything else matched exactly.  */
10369     if (actual_object[i] == NX_NULL)
10370         return(NX_SUCCESS);
10371 
10372     /* Determine if the requested object name is NULL.  This case is considered the next entry.  */
10373     if (requested_object[i] == NX_NULL)
10374         return(NX_SNMP_NEXT_ENTRY);
10375 
10376     /* Return an error condition.  */
10377     return(NX_SNMP_ERROR);
10378 }
10379 
10380 
10381 /**************************************************************************/
10382 /*                                                                        */
10383 /*  FUNCTION                                               RELEASE        */
10384 /*                                                                        */
10385 /*    _nxe_snmp_object_copy                               PORTABLE C      */
10386 /*                                                           6.1          */
10387 /*  AUTHOR                                                                */
10388 /*                                                                        */
10389 /*    Yuxin Zhou, Microsoft Corporation                                   */
10390 /*                                                                        */
10391 /*  DESCRIPTION                                                           */
10392 /*                                                                        */
10393 /*    This function checks for errors in the SNMP agent object copy       */
10394 /*    function call.                                                      */
10395 /*                                                                        */
10396 /*  INPUT                                                                 */
10397 /*                                                                        */
10398 /*    source_object_name                    Pointer to source object      */
10399 /*    destination_object_name               Pointer to destination object */
10400 /*                                                                        */
10401 /*  OUTPUT                                                                */
10402 /*                                                                        */
10403 /*    size                                  If error, returns zero, else  */
10404 /*                                            returns number of bytes     */
10405 /*                                            copied                      */
10406 /*  CALLS                                                                 */
10407 /*                                                                        */
10408 /*    _nx_snmp_object_copy                  Actual agent object copy      */
10409 /*                                            function                    */
10410 /*                                                                        */
10411 /*  CALLED BY                                                             */
10412 /*                                                                        */
10413 /*    Application Code                                                    */
10414 /*                                                                        */
10415 /*  RELEASE HISTORY                                                       */
10416 /*                                                                        */
10417 /*    DATE              NAME                      DESCRIPTION             */
10418 /*                                                                        */
10419 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10420 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10421 /*                                            resulting in version 6.1    */
10422 /*                                                                        */
10423 /**************************************************************************/
_nxe_snmp_object_copy(UCHAR * source_object_name,UCHAR * destination_object_name)10424 UINT  _nxe_snmp_object_copy(UCHAR *source_object_name, UCHAR *destination_object_name)
10425 {
10426 
10427 UINT    status;
10428 
10429 
10430     /* Check for invalid input pointers.  */
10431     if ((source_object_name == NX_NULL) || (destination_object_name == NX_NULL))
10432         return(0);
10433 
10434     /* Call actual service.  */
10435     status =  _nx_snmp_object_copy(source_object_name, destination_object_name);
10436 
10437     /* Return status.  */
10438     return(status);
10439 }
10440 
10441 
10442 /**************************************************************************/
10443 /*                                                                        */
10444 /*  FUNCTION                                               RELEASE        */
10445 /*                                                                        */
10446 /*    _nx_snmp_object_copy                                PORTABLE C      */
10447 /*                                                           6.1          */
10448 /*  AUTHOR                                                                */
10449 /*                                                                        */
10450 /*    Yuxin Zhou, Microsoft Corporation                                   */
10451 /*                                                                        */
10452 /*  DESCRIPTION                                                           */
10453 /*                                                                        */
10454 /*    This function copies the source object to the destination object.   */
10455 /*                                                                        */
10456 /*    Note: new API nx_snmp_object_copy_extended is encouraged to use. */
10457 /*                                                                        */
10458 /*  INPUT                                                                 */
10459 /*                                                                        */
10460 /*    source_object_name                    Pointer to source object      */
10461 /*    destination_object_name               Pointer to destination object */
10462 /*                                                                        */
10463 /*  OUTPUT                                                                */
10464 /*                                                                        */
10465 /*    size                                  If error, returns zero, else  */
10466 /*                                            returns number of bytes     */
10467 /*                                            copied                      */
10468 /*                                                                        */
10469 /*  CALLS                                                                 */
10470 /*                                                                        */
10471 /*    None                                                                */
10472 /*                                                                        */
10473 /*  CALLED BY                                                             */
10474 /*                                                                        */
10475 /*    Application Code                                                    */
10476 /*                                                                        */
10477 /*  RELEASE HISTORY                                                       */
10478 /*                                                                        */
10479 /*    DATE              NAME                      DESCRIPTION             */
10480 /*                                                                        */
10481 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10482 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10483 /*                                            resulting in version 6.1    */
10484 /*                                                                        */
10485 /**************************************************************************/
_nx_snmp_object_copy(UCHAR * source_object_name,UCHAR * destination_object_name)10486 UINT  _nx_snmp_object_copy(UCHAR *source_object_name, UCHAR *destination_object_name)
10487 {
10488 
10489 UINT    i;
10490 
10491 
10492     /* Calculate the object length.  */
10493     if (_nx_utility_string_length_check((CHAR *)source_object_name, NX_NULL, NX_MAX_STRING_LENGTH))
10494         return(0);
10495 
10496     /* Loop to copy the name.  */
10497     i =  0;
10498 
10499     while (source_object_name[i])
10500     {
10501 
10502         /* Copy a byte of the name.  */
10503         destination_object_name[i] =  source_object_name[i];
10504 
10505         /* Move to next byte.  */
10506         i++;
10507     }
10508 
10509     /* Ensure name is null terminated.  */
10510     destination_object_name[i] =  NX_NULL;
10511 
10512     /* Return the size of the name.  */
10513     return(i);
10514 }
10515 
10516 
10517 /**************************************************************************/
10518 /*                                                                        */
10519 /*  FUNCTION                                               RELEASE        */
10520 /*                                                                        */
10521 /*    _nxe_snmp_object_copy_extended                      PORTABLE C      */
10522 /*                                                           6.1          */
10523 /*  AUTHOR                                                                */
10524 /*                                                                        */
10525 /*    Yuxin Zhou, Microsoft Corporation                                   */
10526 /*                                                                        */
10527 /*  DESCRIPTION                                                           */
10528 /*                                                                        */
10529 /*    This function checks for errors in the SNMP agent object copy       */
10530 /*    function call.                                                      */
10531 /*                                                                        */
10532 /*  INPUT                                                                 */
10533 /*                                                                        */
10534 /*    source_object_name                    Pointer to source object      */
10535 /*    source_object_name_length             Length of source object       */
10536 /*    destination_object_name_buffer        Pointer to destination object */
10537 /*    destination_object_name_buffer_size   Size of destination object    */
10538 /*                                                                        */
10539 /*  OUTPUT                                                                */
10540 /*                                                                        */
10541 /*    size                                  If error, returns zero, else  */
10542 /*                                            returns number of bytes     */
10543 /*                                            copied                      */
10544 /*  CALLS                                                                 */
10545 /*                                                                        */
10546 /*    _nx_snmp_object_copy_extended         Actual agent object copy      */
10547 /*                                            extended function           */
10548 /*                                                                        */
10549 /*  CALLED BY                                                             */
10550 /*                                                                        */
10551 /*    Application Code                                                    */
10552 /*                                                                        */
10553 /*  RELEASE HISTORY                                                       */
10554 /*                                                                        */
10555 /*    DATE              NAME                      DESCRIPTION             */
10556 /*                                                                        */
10557 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10558 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10559 /*                                            resulting in version 6.1    */
10560 /*                                                                        */
10561 /**************************************************************************/
_nxe_snmp_object_copy_extended(UCHAR * source_object_name,UINT source_object_name_length,UCHAR * destination_object_name_buffer,UINT destination_object_name_buffer_size)10562 UINT  _nxe_snmp_object_copy_extended(UCHAR *source_object_name, UINT source_object_name_length,
10563                                      UCHAR *destination_object_name_buffer, UINT destination_object_name_buffer_size)
10564 {
10565 
10566 
10567     /* Check for invalid input pointers.  */
10568     if ((source_object_name == NX_NULL) || (destination_object_name_buffer == NX_NULL))
10569         return(0);
10570 
10571     /* Call actual service.  */
10572     return(_nx_snmp_object_copy_extended(source_object_name, source_object_name_length, destination_object_name_buffer, destination_object_name_buffer_size));
10573 }
10574 
10575 
10576 /**************************************************************************/
10577 /*                                                                        */
10578 /*  FUNCTION                                               RELEASE        */
10579 /*                                                                        */
10580 /*    _nx_snmp_object_copy_extended                       PORTABLE C      */
10581 /*                                                           6.1          */
10582 /*  AUTHOR                                                                */
10583 /*                                                                        */
10584 /*    Yuxin Zhou, Microsoft Corporation                                   */
10585 /*                                                                        */
10586 /*  DESCRIPTION                                                           */
10587 /*                                                                        */
10588 /*    This function copies the source object to the destination object.   */
10589 /*                                                                        */
10590 /*    Note: the object name must be NULL-terminated, the size of          */
10591 /*    destination object buffer must be larger than source object length. */
10592 /*                                                                        */
10593 /*  INPUT                                                                 */
10594 /*                                                                        */
10595 /*    source_object_name                    Pointer to source object      */
10596 /*    source_object_name_length             Length of source object       */
10597 /*    destination_object_name_buffer        Pointer to destination object */
10598 /*    destination_object_name_buffer_size   Size of destination object    */
10599 /*                                                                        */
10600 /*  OUTPUT                                                                */
10601 /*                                                                        */
10602 /*    size                                  If error, returns zero, else  */
10603 /*                                            returns number of bytes     */
10604 /*                                            copied                      */
10605 /*                                                                        */
10606 /*  CALLS                                                                 */
10607 /*                                                                        */
10608 /*    None                                                                */
10609 /*                                                                        */
10610 /*  CALLED BY                                                             */
10611 /*                                                                        */
10612 /*    Application Code                                                    */
10613 /*                                                                        */
10614 /*  RELEASE HISTORY                                                       */
10615 /*                                                                        */
10616 /*    DATE              NAME                      DESCRIPTION             */
10617 /*                                                                        */
10618 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10619 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
10620 /*                                            verified memcpy use cases,  */
10621 /*                                            resulting in version 6.1    */
10622 /*                                                                        */
10623 /**************************************************************************/
_nx_snmp_object_copy_extended(UCHAR * source_object_name,UINT source_object_name_length,UCHAR * destination_object_name_buffer,UINT destination_object_name_buffer_size)10624 UINT  _nx_snmp_object_copy_extended(UCHAR *source_object_name, UINT source_object_name_length,
10625                                     UCHAR *destination_object_name_buffer, UINT destination_object_name_buffer_size)
10626 {
10627 
10628 UINT    temp_object_name_length;
10629 
10630 
10631     /* Check the string length, the destination oject name buffer size must be larger than source object name length.  */
10632     if ((source_object_name_length == 0) || (destination_object_name_buffer_size <= source_object_name_length))
10633         return(0);
10634 
10635     /* Check name string.  */
10636     if (_nx_utility_string_length_check((CHAR *)source_object_name, &temp_object_name_length, source_object_name_length))
10637         return(0);
10638 
10639     /* Check the actual string length.  */
10640     if (source_object_name_length != temp_object_name_length)
10641         return(0);
10642 
10643     /* Copy the name and null-terminator.  */
10644     memcpy(destination_object_name_buffer, source_object_name, source_object_name_length + 1); /* Use case of memcpy is verified. */
10645 
10646     /* Return the size of the name.  */
10647     return(source_object_name_length);
10648 }
10649 
10650 
10651 /**************************************************************************/
10652 /*                                                                        */
10653 /*  FUNCTION                                               RELEASE        */
10654 /*                                                                        */
10655 /*    _nxe_snmp_object_counter_get                        PORTABLE C      */
10656 /*                                                           6.1          */
10657 /*  AUTHOR                                                                */
10658 /*                                                                        */
10659 /*    Yuxin Zhou, Microsoft Corporation                                   */
10660 /*                                                                        */
10661 /*  DESCRIPTION                                                           */
10662 /*                                                                        */
10663 /*    This function checks for errors in the SNMP agent object counter    */
10664 /*    get function call.                                                  */
10665 /*                                                                        */
10666 /*  INPUT                                                                 */
10667 /*                                                                        */
10668 /*    source_ptr                            Pointer to counter source     */
10669 /*    object_data                           Pointer to object data struct */
10670 /*                                                                        */
10671 /*  OUTPUT                                                                */
10672 /*                                                                        */
10673 /*    status                                Completion status             */
10674 /*                                                                        */
10675 /*  CALLS                                                                 */
10676 /*                                                                        */
10677 /*    _nx_snmp_object_counter_get           Actual agent object counter   */
10678 /*                                            get function                */
10679 /*                                                                        */
10680 /*  CALLED BY                                                             */
10681 /*                                                                        */
10682 /*    Application Code                                                    */
10683 /*                                                                        */
10684 /*  RELEASE HISTORY                                                       */
10685 /*                                                                        */
10686 /*    DATE              NAME                      DESCRIPTION             */
10687 /*                                                                        */
10688 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10689 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10690 /*                                            resulting in version 6.1    */
10691 /*                                                                        */
10692 /**************************************************************************/
_nxe_snmp_object_counter_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)10693 UINT  _nxe_snmp_object_counter_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
10694 {
10695 
10696 UINT    status;
10697 
10698 
10699     /* Check for invalid input pointers.  */
10700     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
10701         return(NX_PTR_ERROR);
10702 
10703     /* Call actual service.  */
10704     status =  _nx_snmp_object_counter_get(source_ptr, object_data);
10705 
10706     /* Return status.  */
10707     return(status);
10708 }
10709 
10710 
10711 /**************************************************************************/
10712 /*                                                                        */
10713 /*  FUNCTION                                               RELEASE        */
10714 /*                                                                        */
10715 /*    _nx_snmp_object_counter_get                         PORTABLE C      */
10716 /*                                                           6.1          */
10717 /*  AUTHOR                                                                */
10718 /*                                                                        */
10719 /*    Yuxin Zhou, Microsoft Corporation                                   */
10720 /*                                                                        */
10721 /*  DESCRIPTION                                                           */
10722 /*                                                                        */
10723 /*    This function retrieves the object counter from the specified       */
10724 /*    source location.                                                    */
10725 /*                                                                        */
10726 /*  INPUT                                                                 */
10727 /*                                                                        */
10728 /*    source_ptr                            Pointer to counter source     */
10729 /*    object_data                           Pointer to object data struct */
10730 /*                                                                        */
10731 /*  OUTPUT                                                                */
10732 /*                                                                        */
10733 /*    status                                Completion status             */
10734 /*                                                                        */
10735 /*  CALLS                                                                 */
10736 /*                                                                        */
10737 /*    None                                                                */
10738 /*                                                                        */
10739 /*  CALLED BY                                                             */
10740 /*                                                                        */
10741 /*    Application Code                                                    */
10742 /*                                                                        */
10743 /*  RELEASE HISTORY                                                       */
10744 /*                                                                        */
10745 /*    DATE              NAME                      DESCRIPTION             */
10746 /*                                                                        */
10747 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10748 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10749 /*                                            resulting in version 6.1    */
10750 /*                                                                        */
10751 /**************************************************************************/
_nx_snmp_object_counter_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)10752 UINT  _nx_snmp_object_counter_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
10753 {
10754 
10755 ULONG   *value_ptr;
10756 
10757 
10758     /* Setup the object data structure.  */
10759     object_data -> nx_snmp_object_data_type =   NX_SNMP_COUNTER;
10760 
10761     /* Setup pointer to the value.  */
10762     value_ptr =  (ULONG *) source_ptr;
10763 
10764     /* Copy the value into the object data structure.  */
10765     object_data -> nx_snmp_object_data_msw =  (LONG)(*value_ptr);
10766 
10767     /* Return success.  */
10768     return(NX_SUCCESS);
10769 }
10770 
10771 
10772 /**************************************************************************/
10773 /*                                                                        */
10774 /*  FUNCTION                                               RELEASE        */
10775 /*                                                                        */
10776 /*    _nxe_snmp_object_counter_set                        PORTABLE C      */
10777 /*                                                           6.1          */
10778 /*  AUTHOR                                                                */
10779 /*                                                                        */
10780 /*    Yuxin Zhou, Microsoft Corporation                                   */
10781 /*                                                                        */
10782 /*  DESCRIPTION                                                           */
10783 /*                                                                        */
10784 /*    This function checks for errors in the SNMP agent object counter    */
10785 /*    set function call.                                                  */
10786 /*                                                                        */
10787 /*  INPUT                                                                 */
10788 /*                                                                        */
10789 /*    destination_ptr                       Pointer to counter destination*/
10790 /*    object_data                           Pointer to object data struct */
10791 /*                                                                        */
10792 /*  OUTPUT                                                                */
10793 /*                                                                        */
10794 /*    status                                Completion status             */
10795 /*                                                                        */
10796 /*  CALLS                                                                 */
10797 /*                                                                        */
10798 /*    _nx_snmp_object_counter_set           Actual agent object counter   */
10799 /*                                            set function                */
10800 /*                                                                        */
10801 /*  CALLED BY                                                             */
10802 /*                                                                        */
10803 /*    Application Code                                                    */
10804 /*                                                                        */
10805 /*  RELEASE HISTORY                                                       */
10806 /*                                                                        */
10807 /*    DATE              NAME                      DESCRIPTION             */
10808 /*                                                                        */
10809 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10810 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10811 /*                                            resulting in version 6.1    */
10812 /*                                                                        */
10813 /**************************************************************************/
_nxe_snmp_object_counter_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)10814 UINT  _nxe_snmp_object_counter_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
10815 {
10816 
10817 UINT    status;
10818 
10819 
10820     /* Check for invalid input pointers.  */
10821     if ((destination_ptr == NX_NULL) || (object_data == NX_NULL))
10822         return(NX_PTR_ERROR);
10823 
10824     /* Call actual service.  */
10825     status =  _nx_snmp_object_counter_set(destination_ptr, object_data);
10826 
10827     /* Return status.  */
10828     return(status);
10829 }
10830 
10831 
10832 /**************************************************************************/
10833 /*                                                                        */
10834 /*  FUNCTION                                               RELEASE        */
10835 /*                                                                        */
10836 /*    _nx_snmp_object_counter_set                         PORTABLE C      */
10837 /*                                                           6.1          */
10838 /*  AUTHOR                                                                */
10839 /*                                                                        */
10840 /*    Yuxin Zhou, Microsoft Corporation                                   */
10841 /*                                                                        */
10842 /*  DESCRIPTION                                                           */
10843 /*                                                                        */
10844 /*    This function retrieves the object counter from the object data     */
10845 /*    structure and places it in the destination.                         */
10846 /*                                                                        */
10847 /*  INPUT                                                                 */
10848 /*                                                                        */
10849 /*    destination_ptr                       Pointer to counter destination*/
10850 /*    object_data                           Pointer to object data struct */
10851 /*                                                                        */
10852 /*  OUTPUT                                                                */
10853 /*                                                                        */
10854 /*    status                                Completion status             */
10855 /*                                                                        */
10856 /*  CALLS                                                                 */
10857 /*                                                                        */
10858 /*    None                                                                */
10859 /*                                                                        */
10860 /*  CALLED BY                                                             */
10861 /*                                                                        */
10862 /*    Application Code                                                    */
10863 /*                                                                        */
10864 /*  RELEASE HISTORY                                                       */
10865 /*                                                                        */
10866 /*    DATE              NAME                      DESCRIPTION             */
10867 /*                                                                        */
10868 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10869 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10870 /*                                            resulting in version 6.1    */
10871 /*                                                                        */
10872 /**************************************************************************/
_nx_snmp_object_counter_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)10873 UINT  _nx_snmp_object_counter_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
10874 {
10875 
10876 ULONG   *value_ptr;
10877 
10878 
10879     /* Determine if the correct type is specified.  */
10880     if (object_data -> nx_snmp_object_data_type != NX_SNMP_COUNTER)
10881     {
10882 
10883         /* Return an invalid type message.  */
10884         return(NX_SNMP_ERROR_WRONGTYPE);
10885     }
10886 
10887     /* Setup pointer to the value.  */
10888     value_ptr =  (ULONG *) destination_ptr;
10889 
10890     /* Copy the value into the object data structure.  */
10891     *value_ptr =  (ULONG)(object_data -> nx_snmp_object_data_msw);
10892 
10893     /* Return success.  */
10894     return(NX_SUCCESS);
10895 }
10896 
10897 
10898 /**************************************************************************/
10899 /*                                                                        */
10900 /*  FUNCTION                                               RELEASE        */
10901 /*                                                                        */
10902 /*    _nxe_snmp_object_counter64_get                      PORTABLE C      */
10903 /*                                                           6.1          */
10904 /*  AUTHOR                                                                */
10905 /*                                                                        */
10906 /*    Yuxin Zhou, Microsoft Corporation                                   */
10907 /*                                                                        */
10908 /*  DESCRIPTION                                                           */
10909 /*                                                                        */
10910 /*    This function checks for errors in the SNMP agent 64-bit object     */
10911 /*    counter get function call.                                          */
10912 /*                                                                        */
10913 /*  INPUT                                                                 */
10914 /*                                                                        */
10915 /*    source_ptr                            Pointer to counter source     */
10916 /*    object_data                           Pointer to object data struct */
10917 /*                                                                        */
10918 /*  OUTPUT                                                                */
10919 /*                                                                        */
10920 /*    status                                Completion status             */
10921 /*                                                                        */
10922 /*  CALLS                                                                 */
10923 /*                                                                        */
10924 /*    _nx_snmp_object_counter64_get         Actual agent object counter   */
10925 /*                                            get function                */
10926 /*                                                                        */
10927 /*  CALLED BY                                                             */
10928 /*                                                                        */
10929 /*    Application Code                                                    */
10930 /*                                                                        */
10931 /*  RELEASE HISTORY                                                       */
10932 /*                                                                        */
10933 /*    DATE              NAME                      DESCRIPTION             */
10934 /*                                                                        */
10935 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10936 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10937 /*                                            resulting in version 6.1    */
10938 /*                                                                        */
10939 /**************************************************************************/
_nxe_snmp_object_counter64_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)10940 UINT  _nxe_snmp_object_counter64_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
10941 {
10942 
10943 UINT    status;
10944 
10945 
10946     /* Check for invalid input pointers.  */
10947     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
10948         return(NX_PTR_ERROR);
10949 
10950     /* Call actual service.  */
10951     status =  _nx_snmp_object_counter64_get(source_ptr, object_data);
10952 
10953     /* Return status.  */
10954     return(status);
10955 }
10956 
10957 
10958 /**************************************************************************/
10959 /*                                                                        */
10960 /*  FUNCTION                                               RELEASE        */
10961 /*                                                                        */
10962 /*    _nx_snmp_object_counter64_get                       PORTABLE C      */
10963 /*                                                           6.1          */
10964 /*  AUTHOR                                                                */
10965 /*                                                                        */
10966 /*    Yuxin Zhou, Microsoft Corporation                                   */
10967 /*                                                                        */
10968 /*  DESCRIPTION                                                           */
10969 /*                                                                        */
10970 /*    This function retrieves the 64-bit object counter from the          */
10971 /*    specified source location.                                          */
10972 /*                                                                        */
10973 /*  INPUT                                                                 */
10974 /*                                                                        */
10975 /*    source_ptr                            Pointer to counter source     */
10976 /*    object_data                           Pointer to object data struct */
10977 /*                                                                        */
10978 /*  OUTPUT                                                                */
10979 /*                                                                        */
10980 /*    status                                Completion status             */
10981 /*                                                                        */
10982 /*  CALLS                                                                 */
10983 /*                                                                        */
10984 /*    None                                                                */
10985 /*                                                                        */
10986 /*  CALLED BY                                                             */
10987 /*                                                                        */
10988 /*    Application Code                                                    */
10989 /*                                                                        */
10990 /*  RELEASE HISTORY                                                       */
10991 /*                                                                        */
10992 /*    DATE              NAME                      DESCRIPTION             */
10993 /*                                                                        */
10994 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10995 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10996 /*                                            resulting in version 6.1    */
10997 /*                                                                        */
10998 /**************************************************************************/
_nx_snmp_object_counter64_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)10999 UINT  _nx_snmp_object_counter64_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
11000 {
11001 
11002 ULONG   *value_ptr;
11003 
11004 
11005     /* Setup the object data structure.  */
11006     object_data -> nx_snmp_object_data_type =   NX_SNMP_COUNTER64;
11007 
11008     /* Setup pointer to the value.  */
11009     value_ptr =  (ULONG *) source_ptr;
11010 
11011     /* Copy the value into the object data structure.  */
11012     object_data -> nx_snmp_object_data_msw =  (LONG)value_ptr[0];
11013     object_data -> nx_snmp_object_data_lsw =  (LONG)value_ptr[1];
11014 
11015     /* Return success.  */
11016     return(NX_SUCCESS);
11017 }
11018 
11019 
11020 /**************************************************************************/
11021 /*                                                                        */
11022 /*  FUNCTION                                               RELEASE        */
11023 /*                                                                        */
11024 /*    _nxe_snmp_object_counter64_set                      PORTABLE C      */
11025 /*                                                           6.1          */
11026 /*  AUTHOR                                                                */
11027 /*                                                                        */
11028 /*    Yuxin Zhou, Microsoft Corporation                                   */
11029 /*                                                                        */
11030 /*  DESCRIPTION                                                           */
11031 /*                                                                        */
11032 /*    This function checks for errors in the SNMP agent 64-bit object     */
11033 /*    counter set function call.                                          */
11034 /*                                                                        */
11035 /*  INPUT                                                                 */
11036 /*                                                                        */
11037 /*    destination_ptr                       Pointer to counter destination*/
11038 /*    object_data                           Pointer to object data struct */
11039 /*                                                                        */
11040 /*  OUTPUT                                                                */
11041 /*                                                                        */
11042 /*    status                                Completion status             */
11043 /*                                                                        */
11044 /*  CALLS                                                                 */
11045 /*                                                                        */
11046 /*    _nx_snmp_object_counter64_set         Actual agent object counter   */
11047 /*                                            set function                */
11048 /*                                                                        */
11049 /*  CALLED BY                                                             */
11050 /*                                                                        */
11051 /*    Application Code                                                    */
11052 /*                                                                        */
11053 /*  RELEASE HISTORY                                                       */
11054 /*                                                                        */
11055 /*    DATE              NAME                      DESCRIPTION             */
11056 /*                                                                        */
11057 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11058 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11059 /*                                            resulting in version 6.1    */
11060 /*                                                                        */
11061 /**************************************************************************/
_nxe_snmp_object_counter64_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)11062 UINT  _nxe_snmp_object_counter64_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
11063 {
11064 
11065 UINT    status;
11066 
11067 
11068     /* Check for invalid input pointers.  */
11069     if ((destination_ptr == NX_NULL) || (object_data == NX_NULL))
11070         return(NX_PTR_ERROR);
11071 
11072     /* Call actual service.  */
11073     status =  _nx_snmp_object_counter64_set(destination_ptr, object_data);
11074 
11075     /* Return status.  */
11076     return(status);
11077 }
11078 
11079 
11080 /**************************************************************************/
11081 /*                                                                        */
11082 /*  FUNCTION                                               RELEASE        */
11083 /*                                                                        */
11084 /*    _nx_snmp_object_counter64_set                       PORTABLE C      */
11085 /*                                                           6.1          */
11086 /*  AUTHOR                                                                */
11087 /*                                                                        */
11088 /*    Yuxin Zhou, Microsoft Corporation                                   */
11089 /*                                                                        */
11090 /*  DESCRIPTION                                                           */
11091 /*                                                                        */
11092 /*    This function retrieves the 64-bit object counter from the object   */
11093 /*    data structure and places it in the destination.                    */
11094 /*                                                                        */
11095 /*  INPUT                                                                 */
11096 /*                                                                        */
11097 /*    destination_ptr                       Pointer to counter destination*/
11098 /*    object_data                           Pointer to object data struct */
11099 /*                                                                        */
11100 /*  OUTPUT                                                                */
11101 /*                                                                        */
11102 /*    status                                Completion status             */
11103 /*                                                                        */
11104 /*  CALLS                                                                 */
11105 /*                                                                        */
11106 /*    None                                                                */
11107 /*                                                                        */
11108 /*  CALLED BY                                                             */
11109 /*                                                                        */
11110 /*    Application Code                                                    */
11111 /*                                                                        */
11112 /*  RELEASE HISTORY                                                       */
11113 /*                                                                        */
11114 /*    DATE              NAME                      DESCRIPTION             */
11115 /*                                                                        */
11116 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11117 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11118 /*                                            resulting in version 6.1    */
11119 /*                                                                        */
11120 /**************************************************************************/
_nx_snmp_object_counter64_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)11121 UINT  _nx_snmp_object_counter64_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
11122 {
11123 
11124 ULONG       *value_ptr;
11125 LONG         temp = 0;
11126 
11127     /* Determine if the correct type is specified.  */
11128     if (object_data -> nx_snmp_object_data_type != NX_SNMP_COUNTER64)
11129     {
11130 
11131         /* Return an invalid type message.  */
11132         return(NX_SNMP_ERROR_WRONGTYPE);
11133     }
11134 
11135     /* Setup pointer to the value.  */
11136     value_ptr =  (ULONG *) destination_ptr;
11137 
11138     if (object_data -> nx_snmp_object_data_lsw  == 0)
11139     {
11140         temp = object_data -> nx_snmp_object_data_msw;
11141         value_ptr[0] = 0;
11142 
11143     }
11144     if ((object_data -> nx_snmp_object_data_lsw & (LONG)0xFFFFFF00) == 0)
11145     {
11146         temp = object_data -> nx_snmp_object_data_msw << 8;
11147         value_ptr[0] = (ULONG)(((ULONG)object_data -> nx_snmp_object_data_msw >> 24) & (0x000000FF));
11148     }
11149     else if ((object_data -> nx_snmp_object_data_lsw & (LONG)0xFFFF0000) == 0)
11150     {
11151 
11152         temp = object_data -> nx_snmp_object_data_msw << 16;
11153         value_ptr[0] = (ULONG)(((ULONG)object_data -> nx_snmp_object_data_msw >> 16) & (0x0000FFFF));
11154     }
11155     else if ((object_data -> nx_snmp_object_data_lsw & (LONG)0xFF000000) == 0)
11156     {
11157 
11158         temp = object_data -> nx_snmp_object_data_msw << 24;
11159         value_ptr[0] = (ULONG)(((ULONG)object_data -> nx_snmp_object_data_msw >> 8) & (0x00FFFFFF));
11160     }
11161     else
11162     {
11163         value_ptr[0] = (ULONG)(object_data -> nx_snmp_object_data_msw);
11164     }
11165 
11166     value_ptr[1] = (ULONG)(object_data -> nx_snmp_object_data_lsw + temp);
11167 
11168     /* Value_ptr udpates the MIB data but we also need to display the data correctly in object. */
11169 
11170     /* Update the object data to make the display correct as well. */
11171     object_data -> nx_snmp_object_data_lsw = (LONG)value_ptr[1];
11172     object_data -> nx_snmp_object_data_msw = (LONG)value_ptr[0];
11173 
11174     /* Return success.  */
11175     return(NX_SUCCESS);
11176 }
11177 
11178 
11179 /**************************************************************************/
11180 /*                                                                        */
11181 /*  FUNCTION                                               RELEASE        */
11182 /*                                                                        */
11183 /*    _nxe_snmp_object_end_of_mib                         PORTABLE C      */
11184 /*                                                           6.1          */
11185 /*  AUTHOR                                                                */
11186 /*                                                                        */
11187 /*    Yuxin Zhou, Microsoft Corporation                                   */
11188 /*                                                                        */
11189 /*  DESCRIPTION                                                           */
11190 /*                                                                        */
11191 /*    This function checks for errors in the SNMP agent end-of-mib object */
11192 /*    set function call.                                                  */
11193 /*                                                                        */
11194 /*  INPUT                                                                 */
11195 /*                                                                        */
11196 /*    not_used_ptr                          Not used                      */
11197 /*    object_data                           Pointer to object data struct */
11198 /*                                                                        */
11199 /*  OUTPUT                                                                */
11200 /*                                                                        */
11201 /*    status                                Completion status             */
11202 /*                                                                        */
11203 /*  CALLS                                                                 */
11204 /*                                                                        */
11205 /*    _nx_snmp_object_end_of_mib            Actual agent object end-of-mib*/
11206 /*                                            set function                */
11207 /*                                                                        */
11208 /*  CALLED BY                                                             */
11209 /*                                                                        */
11210 /*    Application Code                                                    */
11211 /*                                                                        */
11212 /*  RELEASE HISTORY                                                       */
11213 /*                                                                        */
11214 /*    DATE              NAME                      DESCRIPTION             */
11215 /*                                                                        */
11216 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11217 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11218 /*                                            resulting in version 6.1    */
11219 /*                                                                        */
11220 /**************************************************************************/
_nxe_snmp_object_end_of_mib(VOID * not_used_ptr,NX_SNMP_OBJECT_DATA * object_data)11221 UINT  _nxe_snmp_object_end_of_mib(VOID *not_used_ptr, NX_SNMP_OBJECT_DATA *object_data)
11222 {
11223 
11224 UINT    status;
11225 
11226 
11227     /* Check for invalid input pointer.  */
11228     if (object_data == NX_NULL)
11229         return(NX_PTR_ERROR);
11230 
11231     /* Call actual service.  */
11232     status =  _nx_snmp_object_end_of_mib(not_used_ptr, object_data);
11233 
11234     /* Return status.  */
11235     return(status);
11236 }
11237 
11238 
11239 /**************************************************************************/
11240 /*                                                                        */
11241 /*  FUNCTION                                               RELEASE        */
11242 /*                                                                        */
11243 /*    _nx_snmp_object_end_of_mib                          PORTABLE C      */
11244 /*                                                           6.1          */
11245 /*  AUTHOR                                                                */
11246 /*                                                                        */
11247 /*    Yuxin Zhou, Microsoft Corporation                                   */
11248 /*                                                                        */
11249 /*  DESCRIPTION                                                           */
11250 /*                                                                        */
11251 /*    This function places an end-of-mib value in the object data         */
11252 /*    structure.                                                          */
11253 /*                                                                        */
11254 /*  INPUT                                                                 */
11255 /*                                                                        */
11256 /*    not_used_ptr                          Not used                      */
11257 /*    object_data                           Pointer to object data struct */
11258 /*                                                                        */
11259 /*  OUTPUT                                                                */
11260 /*                                                                        */
11261 /*    status                                Completion status             */
11262 /*                                                                        */
11263 /*  CALLS                                                                 */
11264 /*                                                                        */
11265 /*    None                                                                */
11266 /*                                                                        */
11267 /*  CALLED BY                                                             */
11268 /*                                                                        */
11269 /*    Application Code                                                    */
11270 /*                                                                        */
11271 /*  RELEASE HISTORY                                                       */
11272 /*                                                                        */
11273 /*    DATE              NAME                      DESCRIPTION             */
11274 /*                                                                        */
11275 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11276 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11277 /*                                            resulting in version 6.1    */
11278 /*                                                                        */
11279 /**************************************************************************/
_nx_snmp_object_end_of_mib(VOID * not_used_ptr,NX_SNMP_OBJECT_DATA * object_data)11280 UINT  _nx_snmp_object_end_of_mib(VOID *not_used_ptr, NX_SNMP_OBJECT_DATA *object_data)
11281 {
11282 
11283     /* Setup the object data structure.  */
11284     object_data -> nx_snmp_object_data_type =  NX_SNMP_ANS1_END_OF_MIB_VIEW;
11285 
11286     /* Copy the value into the object data structure.  */
11287     object_data -> nx_snmp_object_data_msw =  (LONG) not_used_ptr;
11288 
11289     /* Return success.  */
11290     return(NX_SUCCESS);
11291 }
11292 
11293 
11294 /**************************************************************************/
11295 /*                                                                        */
11296 /*  FUNCTION                                               RELEASE        */
11297 /*                                                                        */
11298 /*    _nxe_snmp_object_gauge_get                          PORTABLE C      */
11299 /*                                                           6.1          */
11300 /*  AUTHOR                                                                */
11301 /*                                                                        */
11302 /*    Yuxin Zhou, Microsoft Corporation                                   */
11303 /*                                                                        */
11304 /*  DESCRIPTION                                                           */
11305 /*                                                                        */
11306 /*    This function checks for errors in the SNMP agent object gauge      */
11307 /*    get function call.                                                  */
11308 /*                                                                        */
11309 /*  INPUT                                                                 */
11310 /*                                                                        */
11311 /*    source_ptr                            Pointer to gauge source       */
11312 /*    object_data                           Pointer to object data struct */
11313 /*                                                                        */
11314 /*  OUTPUT                                                                */
11315 /*                                                                        */
11316 /*    status                                Completion status             */
11317 /*                                                                        */
11318 /*  CALLS                                                                 */
11319 /*                                                                        */
11320 /*    _nx_snmp_object_gauge_get             Actual agent object gauge     */
11321 /*                                            get function                */
11322 /*                                                                        */
11323 /*  CALLED BY                                                             */
11324 /*                                                                        */
11325 /*    Application Code                                                    */
11326 /*                                                                        */
11327 /*  RELEASE HISTORY                                                       */
11328 /*                                                                        */
11329 /*    DATE              NAME                      DESCRIPTION             */
11330 /*                                                                        */
11331 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11332 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11333 /*                                            resulting in version 6.1    */
11334 /*                                                                        */
11335 /**************************************************************************/
_nxe_snmp_object_gauge_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)11336 UINT  _nxe_snmp_object_gauge_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
11337 {
11338 
11339 UINT    status;
11340 
11341 
11342     /* Check for invalid input pointers.  */
11343     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
11344         return(NX_PTR_ERROR);
11345 
11346     /* Call actual service.  */
11347     status =  _nx_snmp_object_gauge_get(source_ptr, object_data);
11348 
11349     /* Return status.  */
11350     return(status);
11351 }
11352 
11353 
11354 /**************************************************************************/
11355 /*                                                                        */
11356 /*  FUNCTION                                               RELEASE        */
11357 /*                                                                        */
11358 /*    _nx_snmp_object_gauge_get                           PORTABLE C      */
11359 /*                                                           6.1          */
11360 /*  AUTHOR                                                                */
11361 /*                                                                        */
11362 /*    Yuxin Zhou, Microsoft Corporation                                   */
11363 /*                                                                        */
11364 /*  DESCRIPTION                                                           */
11365 /*                                                                        */
11366 /*    This function retrieves the object gauge from the specified         */
11367 /*    source location.                                                    */
11368 /*                                                                        */
11369 /*  INPUT                                                                 */
11370 /*                                                                        */
11371 /*    source_ptr                            Pointer to gauge source       */
11372 /*    object_data                           Pointer to object data struct */
11373 /*                                                                        */
11374 /*  OUTPUT                                                                */
11375 /*                                                                        */
11376 /*    status                                Completion status             */
11377 /*                                                                        */
11378 /*  CALLS                                                                 */
11379 /*                                                                        */
11380 /*    None                                                                */
11381 /*                                                                        */
11382 /*  CALLED BY                                                             */
11383 /*                                                                        */
11384 /*    Application Code                                                    */
11385 /*                                                                        */
11386 /*  RELEASE HISTORY                                                       */
11387 /*                                                                        */
11388 /*    DATE              NAME                      DESCRIPTION             */
11389 /*                                                                        */
11390 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11391 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11392 /*                                            resulting in version 6.1    */
11393 /*                                                                        */
11394 /**************************************************************************/
_nx_snmp_object_gauge_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)11395 UINT  _nx_snmp_object_gauge_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
11396 {
11397 
11398 ULONG   *value_ptr;
11399 
11400 
11401     /* Setup the object data structure.  */
11402     object_data -> nx_snmp_object_data_type =   NX_SNMP_GAUGE;
11403 
11404     /* Setup pointer to the value.  */
11405     value_ptr =  (ULONG *) source_ptr;
11406 
11407     /* Copy the value into the object data structure.  */
11408     object_data -> nx_snmp_object_data_msw =  (LONG)(*value_ptr);
11409 
11410     /* Return success.  */
11411     return(NX_SUCCESS);
11412 }
11413 
11414 
11415 /**************************************************************************/
11416 /*                                                                        */
11417 /*  FUNCTION                                               RELEASE        */
11418 /*                                                                        */
11419 /*    _nxe_snmp_object_gauge_set                          PORTABLE C      */
11420 /*                                                           6.1          */
11421 /*  AUTHOR                                                                */
11422 /*                                                                        */
11423 /*    Yuxin Zhou, Microsoft Corporation                                   */
11424 /*                                                                        */
11425 /*  DESCRIPTION                                                           */
11426 /*                                                                        */
11427 /*    This function checks for errors in the SNMP agent object gauge      */
11428 /*    set function call.                                                  */
11429 /*                                                                        */
11430 /*  INPUT                                                                 */
11431 /*                                                                        */
11432 /*    destination_ptr                       Pointer to gauge destination  */
11433 /*    object_data                           Pointer to object data struct */
11434 /*                                                                        */
11435 /*  OUTPUT                                                                */
11436 /*                                                                        */
11437 /*    status                                Completion status             */
11438 /*                                                                        */
11439 /*  CALLS                                                                 */
11440 /*                                                                        */
11441 /*    _nx_snmp_object_gauge_set             Actual agent object gauge     */
11442 /*                                            set function                */
11443 /*                                                                        */
11444 /*  CALLED BY                                                             */
11445 /*                                                                        */
11446 /*    Application Code                                                    */
11447 /*                                                                        */
11448 /*  RELEASE HISTORY                                                       */
11449 /*                                                                        */
11450 /*    DATE              NAME                      DESCRIPTION             */
11451 /*                                                                        */
11452 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11453 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11454 /*                                            resulting in version 6.1    */
11455 /*                                                                        */
11456 /**************************************************************************/
_nxe_snmp_object_gauge_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)11457 UINT  _nxe_snmp_object_gauge_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
11458 {
11459 
11460 UINT    status;
11461 
11462 
11463     /* Check for invalid input pointers.  */
11464     if ((destination_ptr == NX_NULL) || (object_data == NX_NULL))
11465         return(NX_PTR_ERROR);
11466 
11467     /* Call actual service.  */
11468     status =  _nx_snmp_object_gauge_set(destination_ptr, object_data);
11469 
11470     /* Return status.  */
11471     return(status);
11472 }
11473 
11474 
11475 /**************************************************************************/
11476 /*                                                                        */
11477 /*  FUNCTION                                               RELEASE        */
11478 /*                                                                        */
11479 /*    _nx_snmp_object_gauge_set                           PORTABLE C      */
11480 /*                                                           6.1          */
11481 /*  AUTHOR                                                                */
11482 /*                                                                        */
11483 /*    Yuxin Zhou, Microsoft Corporation                                   */
11484 /*                                                                        */
11485 /*  DESCRIPTION                                                           */
11486 /*                                                                        */
11487 /*    This function retrieves the object gauge from the object data       */
11488 /*    structure and places it in the destination.                         */
11489 /*                                                                        */
11490 /*  INPUT                                                                 */
11491 /*                                                                        */
11492 /*    destination_ptr                       Pointer to gauge destination  */
11493 /*    object_data                           Pointer to object data struct */
11494 /*                                                                        */
11495 /*  OUTPUT                                                                */
11496 /*                                                                        */
11497 /*    status                                Completion status             */
11498 /*                                                                        */
11499 /*  CALLS                                                                 */
11500 /*                                                                        */
11501 /*    None                                                                */
11502 /*                                                                        */
11503 /*  CALLED BY                                                             */
11504 /*                                                                        */
11505 /*    Application Code                                                    */
11506 /*                                                                        */
11507 /*  RELEASE HISTORY                                                       */
11508 /*                                                                        */
11509 /*    DATE              NAME                      DESCRIPTION             */
11510 /*                                                                        */
11511 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11512 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11513 /*                                            resulting in version 6.1    */
11514 /*                                                                        */
11515 /**************************************************************************/
_nx_snmp_object_gauge_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)11516 UINT  _nx_snmp_object_gauge_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
11517 {
11518 
11519 ULONG   *value_ptr;
11520 
11521 
11522     /* Determine if the correct type is specified.  */
11523     if (object_data -> nx_snmp_object_data_type != NX_SNMP_GAUGE)
11524     {
11525 
11526         /* Return an invalid type message.  */
11527         return(NX_SNMP_ERROR_WRONGTYPE);
11528     }
11529 
11530     /* Setup pointer to the value.  */
11531     value_ptr =  (ULONG *) destination_ptr;
11532 
11533     /* Copy the value into the object data structure.  */
11534     *value_ptr =  (ULONG)(object_data -> nx_snmp_object_data_msw);
11535 
11536     /* Return success.  */
11537     return(NX_SUCCESS);
11538 }
11539 
11540 
11541 /**************************************************************************/
11542 /*                                                                        */
11543 /*  FUNCTION                                               RELEASE        */
11544 /*                                                                        */
11545 /*    _nxe_snmp_object_id_get                             PORTABLE C      */
11546 /*                                                           6.1          */
11547 /*  AUTHOR                                                                */
11548 /*                                                                        */
11549 /*    Yuxin Zhou, Microsoft Corporation                                   */
11550 /*                                                                        */
11551 /*  DESCRIPTION                                                           */
11552 /*                                                                        */
11553 /*    This function checks for errors in the SNMP agent object ID         */
11554 /*    get function call.                                                  */
11555 /*                                                                        */
11556 /*  INPUT                                                                 */
11557 /*                                                                        */
11558 /*    source_ptr                            Pointer to ID source          */
11559 /*    object_data                           Pointer to object data struct */
11560 /*                                                                        */
11561 /*  OUTPUT                                                                */
11562 /*                                                                        */
11563 /*    status                                Completion status             */
11564 /*                                                                        */
11565 /*  CALLS                                                                 */
11566 /*                                                                        */
11567 /*    _nx_snmp_object_id_get                Actual agent object ID        */
11568 /*                                            get function                */
11569 /*                                                                        */
11570 /*  CALLED BY                                                             */
11571 /*                                                                        */
11572 /*    Application Code                                                    */
11573 /*                                                                        */
11574 /*  RELEASE HISTORY                                                       */
11575 /*                                                                        */
11576 /*    DATE              NAME                      DESCRIPTION             */
11577 /*                                                                        */
11578 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11579 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11580 /*                                            resulting in version 6.1    */
11581 /*                                                                        */
11582 /**************************************************************************/
_nxe_snmp_object_id_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)11583 UINT  _nxe_snmp_object_id_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
11584 {
11585 
11586 UINT    status;
11587 
11588 
11589     /* Check for invalid input pointers.  */
11590     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
11591         return(NX_PTR_ERROR);
11592 
11593     /* Call actual service.  */
11594     status =  _nx_snmp_object_id_get(source_ptr, object_data);
11595 
11596     /* Return status.  */
11597     return(status);
11598 }
11599 
11600 
11601 /**************************************************************************/
11602 /*                                                                        */
11603 /*  FUNCTION                                               RELEASE        */
11604 /*                                                                        */
11605 /*    _nx_snmp_object_id_get                              PORTABLE C      */
11606 /*                                                           6.1          */
11607 /*  AUTHOR                                                                */
11608 /*                                                                        */
11609 /*    Yuxin Zhou, Microsoft Corporation                                   */
11610 /*                                                                        */
11611 /*  DESCRIPTION                                                           */
11612 /*                                                                        */
11613 /*    This function retrieves the object ID from the specified            */
11614 /*    source location.                                                    */
11615 /*                                                                        */
11616 /*  INPUT                                                                 */
11617 /*                                                                        */
11618 /*    source_ptr                            Pointer to object ID source   */
11619 /*    object_data                           Pointer to object data struct */
11620 /*                                                                        */
11621 /*  OUTPUT                                                                */
11622 /*                                                                        */
11623 /*    status                                Completion status             */
11624 /*                                                                        */
11625 /*  CALLS                                                                 */
11626 /*                                                                        */
11627 /*    None                                                                */
11628 /*                                                                        */
11629 /*  CALLED BY                                                             */
11630 /*                                                                        */
11631 /*    Application Code                                                    */
11632 /*                                                                        */
11633 /*  RELEASE HISTORY                                                       */
11634 /*                                                                        */
11635 /*    DATE              NAME                      DESCRIPTION             */
11636 /*                                                                        */
11637 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11638 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
11639 /*                                            verified memcpy use cases,  */
11640 /*                                            resulting in version 6.1    */
11641 /*                                                                        */
11642 /**************************************************************************/
_nx_snmp_object_id_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)11643 UINT  _nx_snmp_object_id_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
11644 {
11645 
11646 UINT    length;
11647 UCHAR   c;
11648 CHAR   *copy_source = (CHAR*)source_ptr;
11649 
11650      c = *((UCHAR *)source_ptr);
11651 
11652      /* Check if this is an empty string. */
11653      if ((c == 0x0) || (c == '0'))
11654      {
11655          copy_source = "0.0.0";
11656      }
11657 
11658      /* Check string length.  */
11659      if (_nx_utility_string_length_check((CHAR *)copy_source, &length, NX_SNMP_MAX_OCTET_STRING))
11660      {
11661          /* Incoming object data is too big to fit in. */
11662          return(NX_SNMP_ERROR);
11663      }
11664 
11665      object_data -> nx_snmp_object_data_type = NX_SNMP_OBJECT_ID;
11666 
11667      memcpy(&object_data -> nx_snmp_object_octet_string[0], copy_source, length); /* Use case of memcpy is verified. */
11668 
11669      /* NULL-terminate the string. */
11670      object_data -> nx_snmp_object_octet_string[length] = 0x0;
11671 
11672      /* Calculate the length.  */
11673      object_data -> nx_snmp_object_octet_string_size =  length;
11674 
11675      /* Return success.  */
11676      return(NX_SUCCESS);
11677 }
11678 
11679 
11680 /**************************************************************************/
11681 /*                                                                        */
11682 /*  FUNCTION                                               RELEASE        */
11683 /*                                                                        */
11684 /*    _nxe_snmp_object_id_set                             PORTABLE C      */
11685 /*                                                           6.1          */
11686 /*  AUTHOR                                                                */
11687 /*                                                                        */
11688 /*    Yuxin Zhou, Microsoft Corporation                                   */
11689 /*                                                                        */
11690 /*  DESCRIPTION                                                           */
11691 /*                                                                        */
11692 /*    This function checks for errors in the SNMP agent object ID         */
11693 /*    set function call.                                                  */
11694 /*                                                                        */
11695 /*  INPUT                                                                 */
11696 /*                                                                        */
11697 /*    destination_ptr                       Pointer to ID destination     */
11698 /*    object_data                           Pointer to object data struct */
11699 /*                                                                        */
11700 /*  OUTPUT                                                                */
11701 /*                                                                        */
11702 /*    status                                Completion status             */
11703 /*                                                                        */
11704 /*  CALLS                                                                 */
11705 /*                                                                        */
11706 /*    _nx_snmp_object_id_set                Actual agent object ID        */
11707 /*                                            set function                */
11708 /*                                                                        */
11709 /*  CALLED BY                                                             */
11710 /*                                                                        */
11711 /*    Application Code                                                    */
11712 /*                                                                        */
11713 /*  RELEASE HISTORY                                                       */
11714 /*                                                                        */
11715 /*    DATE              NAME                      DESCRIPTION             */
11716 /*                                                                        */
11717 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11718 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11719 /*                                            resulting in version 6.1    */
11720 /*                                                                        */
11721 /**************************************************************************/
_nxe_snmp_object_id_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)11722 UINT  _nxe_snmp_object_id_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
11723 {
11724 
11725 UINT    status;
11726 
11727 
11728     /* Check for invalid input pointers.  */
11729     if ((destination_ptr == NX_NULL) || (object_data == NX_NULL))
11730         return(NX_PTR_ERROR);
11731 
11732     /* Call actual service.  */
11733     status =  _nx_snmp_object_id_set(destination_ptr, object_data);
11734 
11735     /* Return status.  */
11736     return(status);
11737 }
11738 
11739 
11740 /**************************************************************************/
11741 /*                                                                        */
11742 /*  FUNCTION                                               RELEASE        */
11743 /*                                                                        */
11744 /*    _nx_snmp_object_id_set                              PORTABLE C      */
11745 /*                                                           6.1          */
11746 /*  AUTHOR                                                                */
11747 /*                                                                        */
11748 /*    Yuxin Zhou, Microsoft Corporation                                   */
11749 /*                                                                        */
11750 /*  DESCRIPTION                                                           */
11751 /*                                                                        */
11752 /*    This function retrieves the object ID from the object data          */
11753 /*    structure and places it in the destination.                         */
11754 /*                                                                        */
11755 /*  INPUT                                                                 */
11756 /*                                                                        */
11757 /*    destination_ptr                       Pointer to ID destination     */
11758 /*    object_data                           Pointer to object data struct */
11759 /*                                                                        */
11760 /*  OUTPUT                                                                */
11761 /*                                                                        */
11762 /*    status                                Completion status             */
11763 /*                                                                        */
11764 /*  CALLS                                                                 */
11765 /*                                                                        */
11766 /*    None                                                                */
11767 /*                                                                        */
11768 /*  CALLED BY                                                             */
11769 /*                                                                        */
11770 /*    Application Code                                                    */
11771 /*                                                                        */
11772 /*  RELEASE HISTORY                                                       */
11773 /*                                                                        */
11774 /*    DATE              NAME                      DESCRIPTION             */
11775 /*                                                                        */
11776 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11777 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11778 /*                                            resulting in version 6.1    */
11779 /*                                                                        */
11780 /**************************************************************************/
_nx_snmp_object_id_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)11781 UINT  _nx_snmp_object_id_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
11782 {
11783 
11784     /* Determine if the correct type is specified.  */
11785     if (object_data -> nx_snmp_object_data_type != NX_SNMP_OBJECT_ID)
11786     {
11787 
11788         /* Return an invalid type message.  */
11789         return(NX_SNMP_ERROR_WRONGTYPE);
11790     }
11791 
11792     /* Copy the object id into the destination string.  */
11793     _nx_snmp_object_copy(object_data -> nx_snmp_object_octet_string, (UCHAR *) destination_ptr);
11794 
11795     /* Return success.  */
11796     return(NX_SUCCESS);
11797 }
11798 
11799 
11800 /**************************************************************************/
11801 /*                                                                        */
11802 /*  FUNCTION                                               RELEASE        */
11803 /*                                                                        */
11804 /*    _nxe_snmp_object_integer_get                        PORTABLE C      */
11805 /*                                                           6.1          */
11806 /*  AUTHOR                                                                */
11807 /*                                                                        */
11808 /*    Yuxin Zhou, Microsoft Corporation                                   */
11809 /*                                                                        */
11810 /*  DESCRIPTION                                                           */
11811 /*                                                                        */
11812 /*    This function checks for errors in the SNMP agent object integer    */
11813 /*    get function call.                                                  */
11814 /*                                                                        */
11815 /*  INPUT                                                                 */
11816 /*                                                                        */
11817 /*    source_ptr                            Pointer to integer source     */
11818 /*    object_data                           Pointer to object data struct */
11819 /*                                                                        */
11820 /*  OUTPUT                                                                */
11821 /*                                                                        */
11822 /*    status                                Completion status             */
11823 /*                                                                        */
11824 /*  CALLS                                                                 */
11825 /*                                                                        */
11826 /*    _nx_snmp_object_integer_get           Actual agent integer          */
11827 /*                                            get function                */
11828 /*                                                                        */
11829 /*  CALLED BY                                                             */
11830 /*                                                                        */
11831 /*    Application Code                                                    */
11832 /*                                                                        */
11833 /*  RELEASE HISTORY                                                       */
11834 /*                                                                        */
11835 /*    DATE              NAME                      DESCRIPTION             */
11836 /*                                                                        */
11837 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11838 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11839 /*                                            resulting in version 6.1    */
11840 /*                                                                        */
11841 /**************************************************************************/
_nxe_snmp_object_integer_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)11842 UINT  _nxe_snmp_object_integer_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
11843 {
11844 
11845 UINT    status;
11846 
11847 
11848     /* Check for invalid input pointers.  */
11849     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
11850         return(NX_PTR_ERROR);
11851 
11852     /* Call actual service.  */
11853     status =  _nx_snmp_object_integer_get(source_ptr, object_data);
11854 
11855     /* Return status.  */
11856     return(status);
11857 }
11858 
11859 
11860 /**************************************************************************/
11861 /*                                                                        */
11862 /*  FUNCTION                                               RELEASE        */
11863 /*                                                                        */
11864 /*    _nx_snmp_object_integer_get                         PORTABLE C      */
11865 /*                                                           6.1          */
11866 /*  AUTHOR                                                                */
11867 /*                                                                        */
11868 /*    Yuxin Zhou, Microsoft Corporation                                   */
11869 /*                                                                        */
11870 /*  DESCRIPTION                                                           */
11871 /*                                                                        */
11872 /*    This function retrieves the object integer from the specified       */
11873 /*    source location.                                                    */
11874 /*                                                                        */
11875 /*  INPUT                                                                 */
11876 /*                                                                        */
11877 /*    source_ptr                            Pointer to integer source     */
11878 /*    object_data                           Pointer to object data struct */
11879 /*                                                                        */
11880 /*  OUTPUT                                                                */
11881 /*                                                                        */
11882 /*    status                                Completion status             */
11883 /*                                                                        */
11884 /*  CALLS                                                                 */
11885 /*                                                                        */
11886 /*    None                                                                */
11887 /*                                                                        */
11888 /*  CALLED BY                                                             */
11889 /*                                                                        */
11890 /*    Application Code                                                    */
11891 /*                                                                        */
11892 /*  RELEASE HISTORY                                                       */
11893 /*                                                                        */
11894 /*    DATE              NAME                      DESCRIPTION             */
11895 /*                                                                        */
11896 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11897 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11898 /*                                            resulting in version 6.1    */
11899 /*                                                                        */
11900 /**************************************************************************/
_nx_snmp_object_integer_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)11901 UINT  _nx_snmp_object_integer_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
11902 {
11903 
11904 LONG   *value_ptr;
11905 
11906 
11907     /* Setup the object data structure.  */
11908     object_data -> nx_snmp_object_data_type =   NX_SNMP_INTEGER;
11909 
11910     /* Setup pointer to the value.  */
11911     value_ptr =  (LONG *) source_ptr;
11912 
11913     /* Copy the value into the object data structure.  */
11914     object_data -> nx_snmp_object_data_msw =  *value_ptr;
11915 
11916     /* Return success.  */
11917     return(NX_SUCCESS);
11918 }
11919 
11920 
11921 /**************************************************************************/
11922 /*                                                                        */
11923 /*  FUNCTION                                               RELEASE        */
11924 /*                                                                        */
11925 /*    _nxe_snmp_object_integer_set                        PORTABLE C      */
11926 /*                                                           6.1          */
11927 /*  AUTHOR                                                                */
11928 /*                                                                        */
11929 /*    Yuxin Zhou, Microsoft Corporation                                   */
11930 /*                                                                        */
11931 /*  DESCRIPTION                                                           */
11932 /*                                                                        */
11933 /*    This function checks for errors in the SNMP agent object integer    */
11934 /*    set function call.                                                  */
11935 /*                                                                        */
11936 /*  INPUT                                                                 */
11937 /*                                                                        */
11938 /*    destination_ptr                       Pointer to integer destination*/
11939 /*    object_data                           Pointer to object data struct */
11940 /*                                                                        */
11941 /*  OUTPUT                                                                */
11942 /*                                                                        */
11943 /*    status                                Completion status             */
11944 /*                                                                        */
11945 /*  CALLS                                                                 */
11946 /*                                                                        */
11947 /*    _nx_snmp_object_integer_set           Actual agent object integer   */
11948 /*                                            set function                */
11949 /*                                                                        */
11950 /*  CALLED BY                                                             */
11951 /*                                                                        */
11952 /*    Application Code                                                    */
11953 /*                                                                        */
11954 /*  RELEASE HISTORY                                                       */
11955 /*                                                                        */
11956 /*    DATE              NAME                      DESCRIPTION             */
11957 /*                                                                        */
11958 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11959 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11960 /*                                            resulting in version 6.1    */
11961 /*                                                                        */
11962 /**************************************************************************/
_nxe_snmp_object_integer_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)11963 UINT  _nxe_snmp_object_integer_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
11964 {
11965 
11966 UINT    status;
11967 
11968 
11969     /* Check for invalid input pointers.  */
11970     if ((destination_ptr == NX_NULL) || (object_data == NX_NULL))
11971         return(NX_PTR_ERROR);
11972 
11973     /* Call actual service.  */
11974     status =  _nx_snmp_object_integer_set(destination_ptr, object_data);
11975 
11976     /* Return status.  */
11977     return(status);
11978 }
11979 
11980 
11981 /**************************************************************************/
11982 /*                                                                        */
11983 /*  FUNCTION                                               RELEASE        */
11984 /*                                                                        */
11985 /*    _nx_snmp_object_integer_set                         PORTABLE C      */
11986 /*                                                           6.1          */
11987 /*  AUTHOR                                                                */
11988 /*                                                                        */
11989 /*    Yuxin Zhou, Microsoft Corporation                                   */
11990 /*                                                                        */
11991 /*  DESCRIPTION                                                           */
11992 /*                                                                        */
11993 /*    This function retrieves the object integer from the object data     */
11994 /*    structure and places it in the destination.                         */
11995 /*                                                                        */
11996 /*  INPUT                                                                 */
11997 /*                                                                        */
11998 /*    destination_ptr                       Pointer to integer destination*/
11999 /*    object_data                           Pointer to object data struct */
12000 /*                                                                        */
12001 /*  OUTPUT                                                                */
12002 /*                                                                        */
12003 /*    status                                Completion status             */
12004 /*                                                                        */
12005 /*  CALLS                                                                 */
12006 /*                                                                        */
12007 /*    None                                                                */
12008 /*                                                                        */
12009 /*  CALLED BY                                                             */
12010 /*                                                                        */
12011 /*    Application Code                                                    */
12012 /*                                                                        */
12013 /*  RELEASE HISTORY                                                       */
12014 /*                                                                        */
12015 /*    DATE              NAME                      DESCRIPTION             */
12016 /*                                                                        */
12017 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12018 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12019 /*                                            resulting in version 6.1    */
12020 /*                                                                        */
12021 /**************************************************************************/
_nx_snmp_object_integer_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)12022 UINT  _nx_snmp_object_integer_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
12023 {
12024 
12025 LONG   *value_ptr;
12026 
12027 
12028     /* Determine if the correct type is specified.  */
12029     if (object_data -> nx_snmp_object_data_type != NX_SNMP_INTEGER)
12030     {
12031 
12032         /* Return an invalid type message.  */
12033         return(NX_SNMP_ERROR_WRONGTYPE);
12034     }
12035 
12036     /* Setup pointer to the value.  */
12037     value_ptr =  (LONG *) destination_ptr;
12038 
12039     /* Copy the value into the object data structure.  */
12040     *value_ptr =  object_data -> nx_snmp_object_data_msw;
12041 
12042     /* Return success.  */
12043     return(NX_SUCCESS);
12044 }
12045 
12046 #ifdef FEATURE_NX_IPV6
12047 
12048 /**************************************************************************/
12049 /*                                                                        */
12050 /*  FUNCTION                                               RELEASE        */
12051 /*                                                                        */
12052 /*    _nxe_snmp_object_ipv6_address_set                   PORTABLE C      */
12053 /*                                                           6.1          */
12054 /*  AUTHOR                                                                */
12055 /*                                                                        */
12056 /*    Yuxin Zhou, Microsoft Corporation                                   */
12057 /*                                                                        */
12058 /*  DESCRIPTION                                                           */
12059 /*                                                                        */
12060 /*    This function performs error checking for the set the IPv6 address  */
12061 /*    service.                                                            */
12062 /*                                                                        */
12063 /*  INPUT                                                                 */
12064 /*                                                                        */
12065 /*    source_ptr                            Pointer to IPv6 address       */
12066 /*    object_data                           Pointer to object data struct */
12067 /*                                                                        */
12068 /*  OUTPUT                                                                */
12069 /*                                                                        */
12070 /*    status                                Completion status             */
12071 /*                                                                        */
12072 /*  CALLS                                                                 */
12073 /*                                                                        */
12074 /*    _nx_snmp_object_ipv6_address_set      Actual set address service    */
12075 /*                                                                        */
12076 /*  CALLED BY                                                             */
12077 /*                                                                        */
12078 /*    Application Code                                                    */
12079 /*                                                                        */
12080 /*  RELEASE HISTORY                                                       */
12081 /*                                                                        */
12082 /*    DATE              NAME                      DESCRIPTION             */
12083 /*                                                                        */
12084 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12085 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12086 /*                                            resulting in version 6.1    */
12087 /*                                                                        */
12088 /**************************************************************************/
_nxe_snmp_object_ipv6_address_set(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)12089 UINT  _nxe_snmp_object_ipv6_address_set(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
12090 {
12091 
12092 UINT status;
12093 
12094     /* Determine if the correct type is specified.  */
12095     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
12096     {
12097 
12098         /* Return an invalid pointer input.  */
12099         return(NX_PTR_ERROR);
12100     }
12101 
12102     status = _nx_snmp_object_ipv6_address_set(source_ptr, object_data);
12103 
12104     return status;
12105 }
12106 
12107 /**************************************************************************/
12108 /*                                                                        */
12109 /*  FUNCTION                                               RELEASE        */
12110 /*                                                                        */
12111 /*    _nx_snmp_object_ipv6_address_set                    PORTABLE C      */
12112 /*                                                           6.1.5        */
12113 /*  AUTHOR                                                                */
12114 /*                                                                        */
12115 /*    Yuxin Zhou, Microsoft Corporation                                   */
12116 /*                                                                        */
12117 /*  DESCRIPTION                                                           */
12118 /*                                                                        */
12119 /*    This function retrieves the object IPv6 address from the object data*/
12120 /*    structure and places it in the destination. Note that 1) the data   */
12121 /*    type is really an octet string of unspecified size and format, and  */
12122 /*    2) the caller must set the nx_snmp_object_string_size before calling*/
12123 /*    this function since it supplies the length of the octet data.       */
12124 /*                                                                        */
12125 /*  INPUT                                                                 */
12126 /*                                                                        */
12127 /*    destination_ptr                       Pointer to IPv6 address       */
12128 /*    object_data                           Pointer to object data struct */
12129 /*                                                                        */
12130 /*  OUTPUT                                                                */
12131 /*                                                                        */
12132 /*    status                                Completion status             */
12133 /*                                                                        */
12134 /*  CALLS                                                                 */
12135 /*                                                                        */
12136 /*    None                                                                */
12137 /*                                                                        */
12138 /*  CALLED BY                                                             */
12139 /*                                                                        */
12140 /*    Application Code                                                    */
12141 /*                                                                        */
12142 /*  RELEASE HISTORY                                                       */
12143 /*                                                                        */
12144 /*    DATE              NAME                      DESCRIPTION             */
12145 /*                                                                        */
12146 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12147 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12148 /*                                            resulting in version 6.1    */
12149 /*  03-02-2021     Yuxin Zhou               Modified comment(s),          */
12150 /*                                            optimized boundary check,   */
12151 /*                                            resulting in version 6.1.5  */
12152 /*                                                                        */
12153 /**************************************************************************/
_nx_snmp_object_ipv6_address_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)12154 UINT  _nx_snmp_object_ipv6_address_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
12155 {
12156 
12157 UINT            i;
12158 UCHAR           *string_ptr;
12159 
12160     /* Determine if the correct type is specified.  */
12161     if (object_data -> nx_snmp_object_data_type != NX_SNMP_ANS1_IPV6_ADDRESS)
12162     {
12163 
12164         /* Return an invalid type message.  */
12165         return(NX_SNMP_ERROR_WRONGTYPE);
12166     }
12167 
12168     /* Determine if the string is too big.  */
12169     if (object_data -> nx_snmp_object_octet_string_size > NX_SNMP_MAX_OCTET_STRING)
12170     {
12171         return NX_SNMP_ERROR_TOOBIG;
12172     }
12173 
12174     /* Setup pointer to the value.  */
12175     string_ptr = destination_ptr;
12176 
12177     /* Copy the object data structure into the destination pointer.  */
12178     /* Copy this string into the destination.  */
12179     for (i = 0; i < object_data -> nx_snmp_object_octet_string_size; i++)
12180     {
12181 
12182         /* Copy character.  */
12183         string_ptr[i] =  object_data -> nx_snmp_object_octet_string[i];
12184     }
12185 
12186     return NX_SUCCESS;
12187 
12188 }
12189 
12190 /**************************************************************************/
12191 /*                                                                        */
12192 /*  FUNCTION                                               RELEASE        */
12193 /*                                                                        */
12194 /*    _nxe_snmp_object_ipv6_address_get                   PORTABLE C      */
12195 /*                                                           6.1          */
12196 /*  AUTHOR                                                                */
12197 /*                                                                        */
12198 /*    Yuxin Zhou, Microsoft Corporation                                   */
12199 /*                                                                        */
12200 /*  DESCRIPTION                                                           */
12201 /*                                                                        */
12202 /*    This function performs error checking for the IPv6 address get      */
12203 /*    service.                                                            */
12204 /*                                                                        */
12205 /*  INPUT                                                                 */
12206 /*                                                                        */
12207 /*    destination_ptr                       Pointer to IPv6 address       */
12208 /*    object_data                           Pointer to object data struct */
12209 /*                                                                        */
12210 /*  OUTPUT                                                                */
12211 /*                                                                        */
12212 /*    status                                Completion status             */
12213 /*                                                                        */
12214 /*  CALLS                                                                 */
12215 /*                                                                        */
12216 /*    _nx_snmp_object_ipv6_address_get     Actual get IPv6 service        */
12217 /*                                                                        */
12218 /*  CALLED BY                                                             */
12219 /*                                                                        */
12220 /*    Application Code                                                    */
12221 /*                                                                        */
12222 /*  RELEASE HISTORY                                                       */
12223 /*                                                                        */
12224 /*    DATE              NAME                      DESCRIPTION             */
12225 /*                                                                        */
12226 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12227 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12228 /*                                            resulting in version 6.1    */
12229 /*                                                                        */
12230 /**************************************************************************/
_nxe_snmp_object_ipv6_address_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)12231 UINT  _nxe_snmp_object_ipv6_address_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
12232 {
12233 
12234 UINT    status;
12235 
12236 
12237     /* Check for invalid input pointers.  */
12238     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
12239         return(NX_PTR_ERROR);
12240 
12241     /* Call actual service.  */
12242     status =  _nx_snmp_object_ipv6_address_get(source_ptr, object_data);
12243 
12244     /* Return status.  */
12245     return(status);
12246 }
12247 
12248 
12249 /**************************************************************************/
12250 /*                                                                        */
12251 /*  FUNCTION                                               RELEASE        */
12252 /*                                                                        */
12253 /*    _nx_snmp_object_ipv6_address_get                    PORTABLE C      */
12254 /*                                                           6.1.5        */
12255 /*  AUTHOR                                                                */
12256 /*                                                                        */
12257 /*    Yuxin Zhou, Microsoft Corporation                                   */
12258 /*                                                                        */
12259 /*  DESCRIPTION                                                           */
12260 /*                                                                        */
12261 /*    This function retrieves the object IPv6 address from the object data*/
12262 /*    structure and places it in the destination.  Note that the caller   */
12263 /*    must set the length of the octet string (object ->                  */
12264 /*    (nx_snmp_octet_string_size) before calling this service.            */
12265 /*                                                                        */
12266 /*  INPUT                                                                 */
12267 /*                                                                        */
12268 /*    destination_ptr                       Pointer to IPv6 address       */
12269 /*    object_data                           Pointer to object data struct */
12270 /*                                                                        */
12271 /*  OUTPUT                                                                */
12272 /*                                                                        */
12273 /*    status                                Completion status             */
12274 /*                                                                        */
12275 /*  CALLS                                                                 */
12276 /*                                                                        */
12277 /*    None                                                                */
12278 /*                                                                        */
12279 /*  CALLED BY                                                             */
12280 /*                                                                        */
12281 /*    Application Code                                                    */
12282 /*                                                                        */
12283 /*  RELEASE HISTORY                                                       */
12284 /*                                                                        */
12285 /*    DATE              NAME                      DESCRIPTION             */
12286 /*                                                                        */
12287 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12288 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12289 /*                                            resulting in version 6.1    */
12290 /*  03-02-2021     Yuxin Zhou               Modified comment(s),          */
12291 /*                                            optimized boundary check,   */
12292 /*                                            resulting in version 6.1.5  */
12293 /*                                                                        */
12294 /**************************************************************************/
_nx_snmp_object_ipv6_address_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)12295 UINT  _nx_snmp_object_ipv6_address_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
12296 {
12297 
12298 UINT    i;
12299 UCHAR   *source_string;
12300 
12301 
12302     /* Determine if the string is too big.  */
12303     if (object_data -> nx_snmp_object_octet_string_size > NX_SNMP_MAX_OCTET_STRING)
12304     {
12305         return NX_SNMP_ERROR_TOOBIG;
12306     }
12307 
12308     /* Setup pointer to source string.  */
12309     source_string =  (UCHAR *) source_ptr;
12310 
12311     /* Setup the object data structure.  */
12312     object_data -> nx_snmp_object_data_type =   NX_SNMP_ANS1_IPV6_ADDRESS;
12313 
12314     /* Copy this string into the destination.  */
12315     for (i = 0; i < object_data->nx_snmp_object_octet_string_size; i++)
12316     {
12317 
12318         /* Copy character.  */
12319         object_data -> nx_snmp_object_octet_string[i] =  source_string[i];
12320     }
12321 
12322     /* Return success.  */
12323     return(NX_SUCCESS);
12324 
12325 }
12326 
12327 #endif /* FEATURE_NX_IPV6 */
12328 
12329 /**************************************************************************/
12330 /*                                                                        */
12331 /*  FUNCTION                                               RELEASE        */
12332 /*                                                                        */
12333 /*    _nxe_snmp_object_ip_address_get                     PORTABLE C      */
12334 /*                                                           6.1          */
12335 /*  AUTHOR                                                                */
12336 /*                                                                        */
12337 /*    Yuxin Zhou, Microsoft Corporation                                   */
12338 /*                                                                        */
12339 /*  DESCRIPTION                                                           */
12340 /*                                                                        */
12341 /*    This function checks for errors in the SNMP agent object IP address */
12342 /*    get function call.                                                  */
12343 /*                                                                        */
12344 /*  INPUT                                                                 */
12345 /*                                                                        */
12346 /*    source_ptr                            Pointer to IP address source  */
12347 /*    object_data                           Pointer to object data struct */
12348 /*                                                                        */
12349 /*  OUTPUT                                                                */
12350 /*                                                                        */
12351 /*    status                                Completion status             */
12352 /*                                                                        */
12353 /*  CALLS                                                                 */
12354 /*                                                                        */
12355 /*    _nx_snmp_object_ip_address_get        Actual agent IP address       */
12356 /*                                            get function                */
12357 /*                                                                        */
12358 /*  CALLED BY                                                             */
12359 /*                                                                        */
12360 /*    Application Code                                                    */
12361 /*                                                                        */
12362 /*  RELEASE HISTORY                                                       */
12363 /*                                                                        */
12364 /*    DATE              NAME                      DESCRIPTION             */
12365 /*                                                                        */
12366 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12367 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12368 /*                                            resulting in version 6.1    */
12369 /*                                                                        */
12370 /**************************************************************************/
_nxe_snmp_object_ip_address_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)12371 UINT  _nxe_snmp_object_ip_address_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
12372 {
12373 
12374 UINT    status;
12375 
12376 
12377     /* Check for invalid input pointers.  */
12378     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
12379         return(NX_PTR_ERROR);
12380 
12381     /* Call actual service.  */
12382     status =  _nx_snmp_object_ip_address_get(source_ptr, object_data);
12383 
12384     /* Return status.  */
12385     return(status);
12386 }
12387 
12388 
12389 /**************************************************************************/
12390 /*                                                                        */
12391 /*  FUNCTION                                               RELEASE        */
12392 /*                                                                        */
12393 /*    _nx_snmp_object_ip_address_get                      PORTABLE C      */
12394 /*                                                           6.1          */
12395 /*  AUTHOR                                                                */
12396 /*                                                                        */
12397 /*    Yuxin Zhou, Microsoft Corporation                                   */
12398 /*                                                                        */
12399 /*  DESCRIPTION                                                           */
12400 /*                                                                        */
12401 /*    This function retrieves the object IP address from the specified    */
12402 /*    source location.                                                    */
12403 /*                                                                        */
12404 /*  INPUT                                                                 */
12405 /*                                                                        */
12406 /*    source_ptr                            Pointer to IP address source  */
12407 /*    object_data                           Pointer to object data struct */
12408 /*                                                                        */
12409 /*  OUTPUT                                                                */
12410 /*                                                                        */
12411 /*    status                                Completion status             */
12412 /*                                                                        */
12413 /*  CALLS                                                                 */
12414 /*                                                                        */
12415 /*    None                                                                */
12416 /*                                                                        */
12417 /*  CALLED BY                                                             */
12418 /*                                                                        */
12419 /*    Application Code                                                    */
12420 /*                                                                        */
12421 /*  RELEASE HISTORY                                                       */
12422 /*                                                                        */
12423 /*    DATE              NAME                      DESCRIPTION             */
12424 /*                                                                        */
12425 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12426 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12427 /*                                            resulting in version 6.1    */
12428 /*                                                                        */
12429 /**************************************************************************/
_nx_snmp_object_ip_address_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)12430 UINT  _nx_snmp_object_ip_address_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
12431 {
12432 
12433 
12434 ULONG   *value_ptr;
12435 
12436     /* Setup the object data structure.  */
12437     object_data -> nx_snmp_object_data_type =   NX_SNMP_ANS1_IP_ADDRESS;
12438 
12439     /* Setup pointer to the value.  */
12440     value_ptr =  (ULONG *) source_ptr;
12441 
12442     /* Copy the value into the object data structure.  */
12443     object_data -> nx_snmp_object_data_msw =  (LONG)(*value_ptr);
12444 
12445     /* Return success.  */
12446     return(NX_SUCCESS);
12447 }
12448 
12449 
12450 /**************************************************************************/
12451 /*                                                                        */
12452 /*  FUNCTION                                               RELEASE        */
12453 /*                                                                        */
12454 /*    _nxe_snmp_object_ip_address_set                     PORTABLE C      */
12455 /*                                                           6.1          */
12456 /*  AUTHOR                                                                */
12457 /*                                                                        */
12458 /*    Yuxin Zhou, Microsoft Corporation                                   */
12459 /*                                                                        */
12460 /*  DESCRIPTION                                                           */
12461 /*                                                                        */
12462 /*    This function checks for errors in the SNMP agent object IP address */
12463 /*    set function call.                                                  */
12464 /*                                                                        */
12465 /*  INPUT                                                                 */
12466 /*                                                                        */
12467 /*    destination_ptr                       Pointer to IP address         */
12468 /*                                            destination                 */
12469 /*    object_data                           Pointer to object data struct */
12470 /*                                                                        */
12471 /*  OUTPUT                                                                */
12472 /*                                                                        */
12473 /*    status                                Completion status             */
12474 /*                                                                        */
12475 /*  CALLS                                                                 */
12476 /*                                                                        */
12477 /*    _nx_snmp_object_ip_address_set        Actual agent object IP address*/
12478 /*                                            set function                */
12479 /*                                                                        */
12480 /*  CALLED BY                                                             */
12481 /*                                                                        */
12482 /*    Application Code                                                    */
12483 /*                                                                        */
12484 /*  RELEASE HISTORY                                                       */
12485 /*                                                                        */
12486 /*    DATE              NAME                      DESCRIPTION             */
12487 /*                                                                        */
12488 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12489 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12490 /*                                            resulting in version 6.1    */
12491 /*                                                                        */
12492 /**************************************************************************/
_nxe_snmp_object_ip_address_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)12493 UINT  _nxe_snmp_object_ip_address_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
12494 {
12495 
12496 UINT    status;
12497 
12498 
12499     /* Check for invalid input pointers.  */
12500     if ((destination_ptr == NX_NULL) || (object_data == NX_NULL))
12501         return(NX_PTR_ERROR);
12502 
12503     /* Call actual service.  */
12504     status =  _nx_snmp_object_ip_address_set(destination_ptr, object_data);
12505 
12506     /* Return status.  */
12507     return(status);
12508 }
12509 
12510 
12511 /**************************************************************************/
12512 /*                                                                        */
12513 /*  FUNCTION                                               RELEASE        */
12514 /*                                                                        */
12515 /*    _nx_snmp_object_ip_address_set                      PORTABLE C      */
12516 /*                                                           6.1          */
12517 /*  AUTHOR                                                                */
12518 /*                                                                        */
12519 /*    Yuxin Zhou, Microsoft Corporation                                   */
12520 /*                                                                        */
12521 /*  DESCRIPTION                                                           */
12522 /*                                                                        */
12523 /*    This function retrieves the object IP address from the object data  */
12524 /*    structure and places it in the destination.                         */
12525 /*                                                                        */
12526 /*  INPUT                                                                 */
12527 /*                                                                        */
12528 /*    destination_ptr                       Pointer to IP address         */
12529 /*                                            destination                 */
12530 /*    object_data                           Pointer to object data struct */
12531 /*                                                                        */
12532 /*  OUTPUT                                                                */
12533 /*                                                                        */
12534 /*    status                                Completion status             */
12535 /*                                                                        */
12536 /*  CALLS                                                                 */
12537 /*                                                                        */
12538 /*    None                                                                */
12539 /*                                                                        */
12540 /*  CALLED BY                                                             */
12541 /*                                                                        */
12542 /*    Application Code                                                    */
12543 /*                                                                        */
12544 /*  RELEASE HISTORY                                                       */
12545 /*                                                                        */
12546 /*    DATE              NAME                      DESCRIPTION             */
12547 /*                                                                        */
12548 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12549 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12550 /*                                            resulting in version 6.1    */
12551 /*                                                                        */
12552 /**************************************************************************/
_nx_snmp_object_ip_address_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)12553 UINT  _nx_snmp_object_ip_address_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
12554 {
12555 
12556 
12557 ULONG   *value_ptr;
12558 
12559     /* Determine if the correct type is specified.  */
12560     if (object_data -> nx_snmp_object_data_type != NX_SNMP_ANS1_IP_ADDRESS)
12561     {
12562 
12563         /* Return an invalid type message.  */
12564         return(NX_SNMP_ERROR_WRONGTYPE);
12565     }
12566 
12567     /* Setup pointer to the value.  */
12568     value_ptr =  (ULONG *) destination_ptr;
12569 
12570     /* Copy the value into the object data structure.  */
12571     *value_ptr =  (ULONG)(object_data -> nx_snmp_object_data_msw);
12572 
12573     /* Return success.  */
12574     return(NX_SUCCESS);
12575 }
12576 
12577 
12578 /**************************************************************************/
12579 /*                                                                        */
12580 /*  FUNCTION                                               RELEASE        */
12581 /*                                                                        */
12582 /*    _nxe_snmp_object_no_instance                        PORTABLE C      */
12583 /*                                                           6.1          */
12584 /*  AUTHOR                                                                */
12585 /*                                                                        */
12586 /*    Yuxin Zhou, Microsoft Corporation                                   */
12587 /*                                                                        */
12588 /*  DESCRIPTION                                                           */
12589 /*                                                                        */
12590 /*    This function checks for errors in the SNMP agent object no-instance*/
12591 /*    set function call.                                                  */
12592 /*                                                                        */
12593 /*  INPUT                                                                 */
12594 /*                                                                        */
12595 /*    not_used_ptr                          Not used pointer              */
12596 /*    object_data                           Pointer to object data struct */
12597 /*                                                                        */
12598 /*  OUTPUT                                                                */
12599 /*                                                                        */
12600 /*    status                                Completion status             */
12601 /*                                                                        */
12602 /*  CALLS                                                                 */
12603 /*                                                                        */
12604 /*    _nx_snmp_object_no_instance           Actual agent object           */
12605 /*                                            no-instance set function    */
12606 /*                                                                        */
12607 /*  CALLED BY                                                             */
12608 /*                                                                        */
12609 /*    Application Code                                                    */
12610 /*                                                                        */
12611 /*  RELEASE HISTORY                                                       */
12612 /*                                                                        */
12613 /*    DATE              NAME                      DESCRIPTION             */
12614 /*                                                                        */
12615 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12616 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12617 /*                                            resulting in version 6.1    */
12618 /*                                                                        */
12619 /**************************************************************************/
_nxe_snmp_object_no_instance(VOID * not_used_ptr,NX_SNMP_OBJECT_DATA * object_data)12620 UINT  _nxe_snmp_object_no_instance(VOID *not_used_ptr, NX_SNMP_OBJECT_DATA *object_data)
12621 {
12622 
12623 UINT    status;
12624 
12625 
12626     /* Check for invalid input pointers.  */
12627     if (object_data == NX_NULL)
12628         return(NX_PTR_ERROR);
12629 
12630     /* Call actual service.  */
12631     status =  _nx_snmp_object_no_instance(not_used_ptr, object_data);
12632 
12633     /* Return status.  */
12634     return(status);
12635 }
12636 
12637 
12638 /**************************************************************************/
12639 /*                                                                        */
12640 /*  FUNCTION                                               RELEASE        */
12641 /*                                                                        */
12642 /*    _nx_snmp_object_no_instance                         PORTABLE C      */
12643 /*                                                           6.1          */
12644 /*  AUTHOR                                                                */
12645 /*                                                                        */
12646 /*    Yuxin Zhou, Microsoft Corporation                                   */
12647 /*                                                                        */
12648 /*  DESCRIPTION                                                           */
12649 /*                                                                        */
12650 /*    This function places a no-instance value in the object data         */
12651 /*    structure.                                                          */
12652 /*                                                                        */
12653 /*  INPUT                                                                 */
12654 /*                                                                        */
12655 /*    not_used_ptr                          Not used                      */
12656 /*    object_data                           Pointer to object data struct */
12657 /*                                                                        */
12658 /*  OUTPUT                                                                */
12659 /*                                                                        */
12660 /*    status                                Completion status             */
12661 /*                                                                        */
12662 /*  CALLS                                                                 */
12663 /*                                                                        */
12664 /*    None                                                                */
12665 /*                                                                        */
12666 /*  CALLED BY                                                             */
12667 /*                                                                        */
12668 /*    Application Code                                                    */
12669 /*                                                                        */
12670 /*  RELEASE HISTORY                                                       */
12671 /*                                                                        */
12672 /*    DATE              NAME                      DESCRIPTION             */
12673 /*                                                                        */
12674 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12675 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12676 /*                                            resulting in version 6.1    */
12677 /*                                                                        */
12678 /**************************************************************************/
_nx_snmp_object_no_instance(VOID * not_used_ptr,NX_SNMP_OBJECT_DATA * object_data)12679 UINT  _nx_snmp_object_no_instance(VOID *not_used_ptr, NX_SNMP_OBJECT_DATA *object_data)
12680 {
12681 
12682     /* Setup the object data structure.  */
12683     object_data -> nx_snmp_object_data_type =  NX_SNMP_ANS1_NO_SUCH_INSTANCE;
12684 
12685     /* Copy the value into the object data structure.  */
12686     object_data -> nx_snmp_object_data_msw =  (LONG) not_used_ptr;
12687 
12688     /* Return success.  */
12689     return(NX_SUCCESS);
12690 }
12691 
12692 
12693 /**************************************************************************/
12694 /*                                                                        */
12695 /*  FUNCTION                                               RELEASE        */
12696 /*                                                                        */
12697 /*    _nxe_snmp_object_not_found                          PORTABLE C      */
12698 /*                                                           6.1          */
12699 /*  AUTHOR                                                                */
12700 /*                                                                        */
12701 /*    Yuxin Zhou, Microsoft Corporation                                   */
12702 /*                                                                        */
12703 /*  DESCRIPTION                                                           */
12704 /*                                                                        */
12705 /*    This function checks for errors in the SNMP agent object not-found  */
12706 /*    set function call.                                                  */
12707 /*                                                                        */
12708 /*  INPUT                                                                 */
12709 /*                                                                        */
12710 /*    not_used_ptr                          Not used pointer              */
12711 /*    object_data                           Pointer to object data struct */
12712 /*                                                                        */
12713 /*  OUTPUT                                                                */
12714 /*                                                                        */
12715 /*    status                                Completion status             */
12716 /*                                                                        */
12717 /*  CALLS                                                                 */
12718 /*                                                                        */
12719 /*    _nx_snmp_object_not_found             Actual agent object           */
12720 /*                                            not-found set function      */
12721 /*                                                                        */
12722 /*  CALLED BY                                                             */
12723 /*                                                                        */
12724 /*    Application Code                                                    */
12725 /*                                                                        */
12726 /*  RELEASE HISTORY                                                       */
12727 /*                                                                        */
12728 /*    DATE              NAME                      DESCRIPTION             */
12729 /*                                                                        */
12730 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12731 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12732 /*                                            resulting in version 6.1    */
12733 /*                                                                        */
12734 /**************************************************************************/
_nxe_snmp_object_not_found(VOID * not_used_ptr,NX_SNMP_OBJECT_DATA * object_data)12735 UINT  _nxe_snmp_object_not_found(VOID *not_used_ptr, NX_SNMP_OBJECT_DATA *object_data)
12736 {
12737 
12738 UINT    status;
12739 
12740 
12741     /* Check for invalid input pointers.  */
12742     if (object_data == NX_NULL)
12743         return(NX_PTR_ERROR);
12744 
12745     /* Call actual service.  */
12746     status =  _nx_snmp_object_not_found(not_used_ptr, object_data);
12747 
12748     /* Return status.  */
12749     return(status);
12750 }
12751 
12752 
12753 /**************************************************************************/
12754 /*                                                                        */
12755 /*  FUNCTION                                               RELEASE        */
12756 /*                                                                        */
12757 /*    _nx_snmp_object_not_found                           PORTABLE C      */
12758 /*                                                           6.1          */
12759 /*  AUTHOR                                                                */
12760 /*                                                                        */
12761 /*    Yuxin Zhou, Microsoft Corporation                                   */
12762 /*                                                                        */
12763 /*  DESCRIPTION                                                           */
12764 /*                                                                        */
12765 /*    This function places an not-found value in the object data          */
12766 /*    structure.                                                          */
12767 /*                                                                        */
12768 /*  INPUT                                                                 */
12769 /*                                                                        */
12770 /*    not_used_ptr                          Not used                      */
12771 /*    object_data                           Pointer to object data struct */
12772 /*                                                                        */
12773 /*  OUTPUT                                                                */
12774 /*                                                                        */
12775 /*    status                                Completion status             */
12776 /*                                                                        */
12777 /*  CALLS                                                                 */
12778 /*                                                                        */
12779 /*    None                                                                */
12780 /*                                                                        */
12781 /*  CALLED BY                                                             */
12782 /*                                                                        */
12783 /*    Application Code                                                    */
12784 /*                                                                        */
12785 /*  RELEASE HISTORY                                                       */
12786 /*                                                                        */
12787 /*    DATE              NAME                      DESCRIPTION             */
12788 /*                                                                        */
12789 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12790 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12791 /*                                            resulting in version 6.1    */
12792 /*                                                                        */
12793 /**************************************************************************/
_nx_snmp_object_not_found(VOID * not_used_ptr,NX_SNMP_OBJECT_DATA * object_data)12794 UINT  _nx_snmp_object_not_found(VOID *not_used_ptr, NX_SNMP_OBJECT_DATA *object_data)
12795 {
12796 
12797     /* Setup the object data structure.  */
12798     object_data -> nx_snmp_object_data_type =  NX_SNMP_ANS1_NO_SUCH_OBJECT;
12799 
12800     /* Copy the value into the object data structure.  */
12801     object_data -> nx_snmp_object_data_msw =  (LONG) not_used_ptr;
12802 
12803     /* Return success.  */
12804     return(NX_SUCCESS);
12805 }
12806 
12807 
12808 /**************************************************************************/
12809 /*                                                                        */
12810 /*  FUNCTION                                               RELEASE        */
12811 /*                                                                        */
12812 /*    _nxe_snmp_object_octet_string_get                   PORTABLE C      */
12813 /*                                                           6.1          */
12814 /*  AUTHOR                                                                */
12815 /*                                                                        */
12816 /*    Yuxin Zhou, Microsoft Corporation                                   */
12817 /*                                                                        */
12818 /*  DESCRIPTION                                                           */
12819 /*                                                                        */
12820 /*    This function checks for errors in the SNMP agent octet string      */
12821 /*    get function call.                                                  */
12822 /*                                                                        */
12823 /*  INPUT                                                                 */
12824 /*                                                                        */
12825 /*    source_ptr                            Pointer to octet string source*/
12826 /*    object_data                           Pointer to object data struct */
12827 /*    length                                Length of octet string        */
12828 /*                                                                        */
12829 /*  OUTPUT                                                                */
12830 /*                                                                        */
12831 /*    status                                Completion status             */
12832 /*                                                                        */
12833 /*  CALLS                                                                 */
12834 /*                                                                        */
12835 /*    _nx_snmp_object_octet_string_get      Actual agent octet string     */
12836 /*                                            get function                */
12837 /*                                                                        */
12838 /*  CALLED BY                                                             */
12839 /*                                                                        */
12840 /*    Application Code                                                    */
12841 /*                                                                        */
12842 /*  RELEASE HISTORY                                                       */
12843 /*                                                                        */
12844 /*    DATE              NAME                      DESCRIPTION             */
12845 /*                                                                        */
12846 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12847 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12848 /*                                            resulting in version 6.1    */
12849 /*                                                                        */
12850 /**************************************************************************/
_nxe_snmp_object_octet_string_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data,UINT length)12851 UINT  _nxe_snmp_object_octet_string_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data, UINT length)
12852 {
12853 
12854 UINT    status;
12855 
12856 
12857     /* Check for invalid input pointers.  */
12858     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
12859         return(NX_PTR_ERROR);
12860 
12861     /* Call actual service.  */
12862     status =  _nx_snmp_object_octet_string_get(source_ptr, object_data, length) ;
12863 
12864     /* Return status.  */
12865     return(status);
12866 }
12867 
12868 
12869 /**************************************************************************/
12870 /*                                                                        */
12871 /*  FUNCTION                                               RELEASE        */
12872 /*                                                                        */
12873 /*    _nx_snmp_object_octet_string_get                    PORTABLE C      */
12874 /*                                                           6.1          */
12875 /*  AUTHOR                                                                */
12876 /*                                                                        */
12877 /*    Yuxin Zhou, Microsoft Corporation                                   */
12878 /*                                                                        */
12879 /*  DESCRIPTION                                                           */
12880 /*                                                                        */
12881 /*    This function retrieves the object octet string from the specified  */
12882 /*    source location. Note that while this does have a length field      */
12883 /*    the caller must set the nx_snmp_object_string_size before calling   */
12884 /*    this function since it supplies the length.                         */
12885 /*                                                                        */
12886 /*    The length field is deprecated. It is only included for legacy code.*/
12887 /*                                                                        */
12888 /*  INPUT                                                                 */
12889 /*                                                                        */
12890 /*    source_ptr                            Pointer to octet string source*/
12891 /*    object_data                           Pointer to object data struct */
12892 /*    length                                Length of octet string        */
12893 /*                                                                        */
12894 /*  OUTPUT                                                                */
12895 /*                                                                        */
12896 /*    status                                Completion status             */
12897 /*                                                                        */
12898 /*  CALLS                                                                 */
12899 /*                                                                        */
12900 /*    None                                                                */
12901 /*                                                                        */
12902 /*  CALLED BY                                                             */
12903 /*                                                                        */
12904 /*    Application Code                                                    */
12905 /*                                                                        */
12906 /*  RELEASE HISTORY                                                       */
12907 /*                                                                        */
12908 /*    DATE              NAME                      DESCRIPTION             */
12909 /*                                                                        */
12910 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12911 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12912 /*                                            resulting in version 6.1    */
12913 /*                                                                        */
12914 /**************************************************************************/
_nx_snmp_object_octet_string_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data,UINT length)12915 UINT  _nx_snmp_object_octet_string_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data, UINT length)
12916 {
12917 
12918 UINT    i;
12919 UCHAR   *source_string;
12920 
12921 
12922     NX_PARAMETER_NOT_USED(length);
12923 
12924     /* Setup pointer to source string.  */
12925     source_string =  (UCHAR *) source_ptr;
12926 
12927     /* Setup the object data structure.  */
12928     object_data -> nx_snmp_object_data_type =   NX_SNMP_OCTET_STRING;
12929 
12930     if (object_data -> nx_snmp_object_octet_string_size > NX_SNMP_MAX_OCTET_STRING)
12931     {
12932         return NX_SNMP_ERROR_TOOBIG;
12933     }
12934 
12935     /* Copy this string into the destination.  */
12936     for (i = 0; i < object_data -> nx_snmp_object_octet_string_size; i++)
12937     {
12938 
12939         /* Copy character.  */
12940         object_data -> nx_snmp_object_octet_string[i] =  source_string[i];
12941     }
12942 
12943     /* The length input is deprecated. The caller sets the length from the MIB table
12944        entry to the object_data instance before calling this function. */
12945 
12946     /* Return success.  */
12947     return(NX_SUCCESS);
12948 }
12949 
12950 
12951 /**************************************************************************/
12952 /*                                                                        */
12953 /*  FUNCTION                                               RELEASE        */
12954 /*                                                                        */
12955 /*    _nxe_snmp_object_octet_string_set                   PORTABLE C      */
12956 /*                                                           6.1          */
12957 /*  AUTHOR                                                                */
12958 /*                                                                        */
12959 /*    Yuxin Zhou, Microsoft Corporation                                   */
12960 /*                                                                        */
12961 /*  DESCRIPTION                                                           */
12962 /*                                                                        */
12963 /*    This function checks for errors in the SNMP agent octet string      */
12964 /*    set function call.                                                  */
12965 /*                                                                        */
12966 /*  INPUT                                                                 */
12967 /*                                                                        */
12968 /*    destination_ptr                       Pointer to octet string       */
12969 /*                                            destination                 */
12970 /*    object_data                           Pointer to object data struct */
12971 /*                                                                        */
12972 /*  OUTPUT                                                                */
12973 /*                                                                        */
12974 /*    status                                Completion status             */
12975 /*                                                                        */
12976 /*  CALLS                                                                 */
12977 /*                                                                        */
12978 /*    _nx_snmp_object_octet_string_set      Actual agent octet string     */
12979 /*                                            set function                */
12980 /*                                                                        */
12981 /*  CALLED BY                                                             */
12982 /*                                                                        */
12983 /*    Application Code                                                    */
12984 /*                                                                        */
12985 /*  RELEASE HISTORY                                                       */
12986 /*                                                                        */
12987 /*    DATE              NAME                      DESCRIPTION             */
12988 /*                                                                        */
12989 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12990 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12991 /*                                            resulting in version 6.1    */
12992 /*                                                                        */
12993 /**************************************************************************/
_nxe_snmp_object_octet_string_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)12994 UINT  _nxe_snmp_object_octet_string_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
12995 {
12996 
12997 UINT    status;
12998 
12999 
13000     /* Check for invalid input pointers.  */
13001     if ((destination_ptr == NX_NULL) || (object_data == NX_NULL))
13002         return(NX_PTR_ERROR);
13003 
13004     /* Call actual service.  */
13005     status =  _nx_snmp_object_octet_string_set(destination_ptr, object_data);
13006 
13007     /* Return status.  */
13008     return(status);
13009 }
13010 
13011 
13012 /**************************************************************************/
13013 /*                                                                        */
13014 /*  FUNCTION                                               RELEASE        */
13015 /*                                                                        */
13016 /*    _nx_snmp_object_octet_string_set                    PORTABLE C      */
13017 /*                                                           6.1.5        */
13018 /*  AUTHOR                                                                */
13019 /*                                                                        */
13020 /*    Yuxin Zhou, Microsoft Corporation                                   */
13021 /*                                                                        */
13022 /*  DESCRIPTION                                                           */
13023 /*                                                                        */
13024 /*    This function retrieves the object octet string from the object     */
13025 /*    data structure and places it in the destination.  Note that the     */
13026 /*    length of the octet string must be set in the object string size.   */
13027 /*                                                                        */
13028 /*  INPUT                                                                 */
13029 /*                                                                        */
13030 /*    destination_ptr                       Pointer to octet string       */
13031 /*                                            destination                 */
13032 /*    object_data                           Pointer to object data struct */
13033 /*                                                                        */
13034 /*  OUTPUT                                                                */
13035 /*                                                                        */
13036 /*    status                                Completion status             */
13037 /*                                                                        */
13038 /*  CALLS                                                                 */
13039 /*                                                                        */
13040 /*    None                                                                */
13041 /*                                                                        */
13042 /*  CALLED BY                                                             */
13043 /*                                                                        */
13044 /*    Application Code                                                    */
13045 /*                                                                        */
13046 /*  RELEASE HISTORY                                                       */
13047 /*                                                                        */
13048 /*    DATE              NAME                      DESCRIPTION             */
13049 /*                                                                        */
13050 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13051 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13052 /*                                            resulting in version 6.1    */
13053 /*  03-02-2021     Yuxin Zhou               Modified comment(s),          */
13054 /*                                            optimized boundary check,   */
13055 /*                                            resulting in version 6.1.5  */
13056 /*                                                                        */
13057 /**************************************************************************/
_nx_snmp_object_octet_string_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)13058 UINT  _nx_snmp_object_octet_string_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
13059 {
13060 
13061 UINT    i;
13062 UCHAR   *string_ptr;
13063 
13064 
13065     /* Check for the proper type.  */
13066     if (object_data -> nx_snmp_object_data_type != NX_SNMP_OCTET_STRING)
13067     {
13068 
13069         /* Return an invalid type message.  */
13070         return(NX_SNMP_ERROR_WRONGTYPE);
13071     }
13072 
13073     if (object_data -> nx_snmp_object_octet_string_size > NX_SNMP_MAX_OCTET_STRING)
13074     {
13075         return NX_SNMP_ERROR_TOOBIG;
13076     }
13077 
13078     /* Setup pointer to the destination string.  */
13079     string_ptr =  (UCHAR *) destination_ptr;
13080 
13081     /* Copy this string into the destination.  */
13082     for (i = 0; i < object_data -> nx_snmp_object_octet_string_size; i++)
13083     {
13084 
13085         /* Copy character.  */
13086         string_ptr[i] =  object_data -> nx_snmp_object_octet_string[i];
13087     }
13088 
13089     /* Return success.  */
13090     return(NX_SUCCESS);
13091 }
13092 
13093 
13094 /**************************************************************************/
13095 /*                                                                        */
13096 /*  FUNCTION                                               RELEASE        */
13097 /*                                                                        */
13098 /*    _nxe_snmp_object_string_get                         PORTABLE C      */
13099 /*                                                           6.1          */
13100 /*  AUTHOR                                                                */
13101 /*                                                                        */
13102 /*    Yuxin Zhou, Microsoft Corporation                                   */
13103 /*                                                                        */
13104 /*  DESCRIPTION                                                           */
13105 /*                                                                        */
13106 /*    This function checks for errors in the SNMP agent string            */
13107 /*    get function call.                                                  */
13108 /*                                                                        */
13109 /*  INPUT                                                                 */
13110 /*                                                                        */
13111 /*    source_ptr                            Pointer to string source      */
13112 /*    object_data                           Pointer to object data struct */
13113 /*                                                                        */
13114 /*  OUTPUT                                                                */
13115 /*                                                                        */
13116 /*    status                                Completion status             */
13117 /*                                                                        */
13118 /*  CALLS                                                                 */
13119 /*                                                                        */
13120 /*    _nx_snmp_object_string_get            Actual agent string           */
13121 /*                                            get function                */
13122 /*                                                                        */
13123 /*  CALLED BY                                                             */
13124 /*                                                                        */
13125 /*    Application Code                                                    */
13126 /*                                                                        */
13127 /*  RELEASE HISTORY                                                       */
13128 /*                                                                        */
13129 /*    DATE              NAME                      DESCRIPTION             */
13130 /*                                                                        */
13131 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13132 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13133 /*                                            resulting in version 6.1    */
13134 /*                                                                        */
13135 /**************************************************************************/
_nxe_snmp_object_string_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)13136 UINT  _nxe_snmp_object_string_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
13137 {
13138 
13139 UINT    status;
13140 
13141 
13142     /* Check for invalid input pointers.  */
13143     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
13144         return(NX_PTR_ERROR);
13145 
13146     /* Call actual service.  */
13147     status =  _nx_snmp_object_string_get(source_ptr, object_data);
13148 
13149     /* Return status.  */
13150     return(status);
13151 }
13152 
13153 
13154 /**************************************************************************/
13155 /*                                                                        */
13156 /*  FUNCTION                                               RELEASE        */
13157 /*                                                                        */
13158 /*    _nx_snmp_object_string_get                          PORTABLE C      */
13159 /*                                                           6.1          */
13160 /*  AUTHOR                                                                */
13161 /*                                                                        */
13162 /*    Yuxin Zhou, Microsoft Corporation                                   */
13163 /*                                                                        */
13164 /*  DESCRIPTION                                                           */
13165 /*                                                                        */
13166 /*    This function retrieves the object ASCII string from the specified  */
13167 /*    source location.                                                    */
13168 /*                                                                        */
13169 /*  INPUT                                                                 */
13170 /*                                                                        */
13171 /*    source_ptr                            Pointer to ASCII string source*/
13172 /*    object_data                           Pointer to object data struct */
13173 /*                                                                        */
13174 /*  OUTPUT                                                                */
13175 /*                                                                        */
13176 /*    status                                Completion status             */
13177 /*                                                                        */
13178 /*  CALLS                                                                 */
13179 /*                                                                        */
13180 /*    None                                                                */
13181 /*                                                                        */
13182 /*  CALLED BY                                                             */
13183 /*                                                                        */
13184 /*    Application Code                                                    */
13185 /*                                                                        */
13186 /*  RELEASE HISTORY                                                       */
13187 /*                                                                        */
13188 /*    DATE              NAME                      DESCRIPTION             */
13189 /*                                                                        */
13190 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13191 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13192 /*                                            resulting in version 6.1    */
13193 /*                                                                        */
13194 /**************************************************************************/
_nx_snmp_object_string_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)13195 UINT  _nx_snmp_object_string_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
13196 {
13197 
13198 UINT    i;
13199 UCHAR   *source_string;
13200 
13201 
13202     /* Setup pointer to source string.  */
13203     source_string =  (UCHAR *) source_ptr;
13204 
13205     /* Setup the object data structure.  */
13206     object_data -> nx_snmp_object_data_type =   NX_SNMP_OCTET_STRING;
13207 
13208     /* Copy this string into the destination.  */
13209     i =  0;
13210     while (source_string[i])
13211     {
13212 
13213         /* Copy character.  */
13214         object_data -> nx_snmp_object_octet_string[i] =  source_string[i];
13215 
13216         /* Move to next character.  */
13217         i++;
13218 
13219         /* Check for size of source string.  */
13220         if (i >= NX_SNMP_MAX_OCTET_STRING)
13221         {
13222 
13223             /* Error, source string is too large.  */
13224             object_data -> nx_snmp_object_octet_string[0] =     NX_NULL;
13225             object_data -> nx_snmp_object_octet_string_size =   0;
13226             return(NX_SNMP_ERROR);
13227         }
13228     }
13229 
13230     /* Store the length of the string in the object data area.  */
13231     object_data -> nx_snmp_object_octet_string_size =   i;
13232 
13233     /* Return success.  */
13234     return(NX_SUCCESS);
13235 }
13236 
13237 
13238 /**************************************************************************/
13239 /*                                                                        */
13240 /*  FUNCTION                                               RELEASE        */
13241 /*                                                                        */
13242 /*    _nxe_snmp_object_string_set                         PORTABLE C      */
13243 /*                                                           6.1          */
13244 /*  AUTHOR                                                                */
13245 /*                                                                        */
13246 /*    Yuxin Zhou, Microsoft Corporation                                   */
13247 /*                                                                        */
13248 /*  DESCRIPTION                                                           */
13249 /*                                                                        */
13250 /*    This function checks for errors in the SNMP agent string            */
13251 /*    set function call.                                                  */
13252 /*                                                                        */
13253 /*  INPUT                                                                 */
13254 /*                                                                        */
13255 /*    destination_ptr                       Pointer to string             */
13256 /*                                            destination                 */
13257 /*    object_data                           Pointer to object data struct */
13258 /*                                                                        */
13259 /*  OUTPUT                                                                */
13260 /*                                                                        */
13261 /*    status                                Completion status             */
13262 /*                                                                        */
13263 /*  CALLS                                                                 */
13264 /*                                                                        */
13265 /*    _nx_snmp_object_string_set             Actual agent string          */
13266 /*                                            set function                */
13267 /*                                                                        */
13268 /*  CALLED BY                                                             */
13269 /*                                                                        */
13270 /*    Application Code                                                    */
13271 /*                                                                        */
13272 /*  RELEASE HISTORY                                                       */
13273 /*                                                                        */
13274 /*    DATE              NAME                      DESCRIPTION             */
13275 /*                                                                        */
13276 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13277 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13278 /*                                            resulting in version 6.1    */
13279 /*                                                                        */
13280 /**************************************************************************/
_nxe_snmp_object_string_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)13281 UINT  _nxe_snmp_object_string_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
13282 {
13283 
13284 UINT    status;
13285 
13286 
13287     /* Check for invalid input pointers.  */
13288     if ((destination_ptr == NX_NULL) || (object_data == NX_NULL))
13289         return(NX_PTR_ERROR);
13290 
13291     /* Call actual service.  */
13292     status =  _nx_snmp_object_string_set(destination_ptr, object_data);
13293 
13294     /* Return status.  */
13295     return(status);
13296 }
13297 
13298 
13299 /**************************************************************************/
13300 /*                                                                        */
13301 /*  FUNCTION                                               RELEASE        */
13302 /*                                                                        */
13303 /*    _nx_snmp_object_string_set                          PORTABLE C      */
13304 /*                                                           6.1.5        */
13305 /*  AUTHOR                                                                */
13306 /*                                                                        */
13307 /*    Yuxin Zhou, Microsoft Corporation                                   */
13308 /*                                                                        */
13309 /*  DESCRIPTION                                                           */
13310 /*                                                                        */
13311 /*    This function retrieves the object ASCII string from the object     */
13312 /*    data structure and places it in the destination.                    */
13313 /*                                                                        */
13314 /*  INPUT                                                                 */
13315 /*                                                                        */
13316 /*    destination_ptr                       Pointer to ASCII string       */
13317 /*                                            destination                 */
13318 /*    object_data                           Pointer to object data struct */
13319 /*                                                                        */
13320 /*  OUTPUT                                                                */
13321 /*                                                                        */
13322 /*    status                                Completion status             */
13323 /*                                                                        */
13324 /*  CALLS                                                                 */
13325 /*                                                                        */
13326 /*    None                                                                */
13327 /*                                                                        */
13328 /*  CALLED BY                                                             */
13329 /*                                                                        */
13330 /*    Application Code                                                    */
13331 /*                                                                        */
13332 /*  RELEASE HISTORY                                                       */
13333 /*                                                                        */
13334 /*    DATE              NAME                      DESCRIPTION             */
13335 /*                                                                        */
13336 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13337 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13338 /*                                            resulting in version 6.1    */
13339 /*  03-02-2021     Yuxin Zhou               Modified comment(s),          */
13340 /*                                            optimized boundary check,   */
13341 /*                                            resulting in version 6.1.5  */
13342 /*                                                                        */
13343 /**************************************************************************/
_nx_snmp_object_string_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)13344 UINT  _nx_snmp_object_string_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
13345 {
13346 
13347 UINT    i;
13348 UCHAR   *string_ptr;
13349 
13350 
13351     /* Check for the proper type.  */
13352     if (object_data -> nx_snmp_object_data_type != NX_SNMP_OCTET_STRING)
13353     {
13354 
13355         /* Return an invalid type message.  */
13356         return(NX_SNMP_ERROR_WRONGTYPE);
13357     }
13358 
13359     /* Determine if the string is too big.  */
13360     if (object_data -> nx_snmp_object_octet_string_size > NX_SNMP_MAX_OCTET_STRING)
13361     {
13362         return NX_SNMP_ERROR_TOOBIG;
13363     }
13364 
13365     /* Setup pointer to the destination string.  */
13366     string_ptr =  (UCHAR *) destination_ptr;
13367 
13368     /* Copy this string into the destination.  */
13369     for (i = 0; i < object_data -> nx_snmp_object_octet_string_size; i++)
13370     {
13371 
13372         /* Copy character.  */
13373         string_ptr[i] =  object_data -> nx_snmp_object_octet_string[i];
13374     }
13375 
13376     /* Null terminate the destination.  */
13377     string_ptr[i] =  NX_NULL;
13378 
13379     /* Return success.  */
13380     return(NX_SUCCESS);
13381 }
13382 
13383 
13384 /**************************************************************************/
13385 /*                                                                        */
13386 /*  FUNCTION                                               RELEASE        */
13387 /*                                                                        */
13388 /*    _nxe_snmp_object_timetics_get                       PORTABLE C      */
13389 /*                                                           6.1          */
13390 /*  AUTHOR                                                                */
13391 /*                                                                        */
13392 /*    Yuxin Zhou, Microsoft Corporation                                   */
13393 /*                                                                        */
13394 /*  DESCRIPTION                                                           */
13395 /*                                                                        */
13396 /*    This function checks for errors in the SNMP agent timetics          */
13397 /*    get function call.                                                  */
13398 /*                                                                        */
13399 /*  INPUT                                                                 */
13400 /*                                                                        */
13401 /*    source_ptr                            Pointer to timetics source    */
13402 /*    object_data                           Pointer to object data struct */
13403 /*                                                                        */
13404 /*  OUTPUT                                                                */
13405 /*                                                                        */
13406 /*    status                                Completion status             */
13407 /*                                                                        */
13408 /*  CALLS                                                                 */
13409 /*                                                                        */
13410 /*    _nx_snmp_object_timetics_get          Actual agent timetics         */
13411 /*                                            get function                */
13412 /*                                                                        */
13413 /*  CALLED BY                                                             */
13414 /*                                                                        */
13415 /*    Application Code                                                    */
13416 /*                                                                        */
13417 /*  RELEASE HISTORY                                                       */
13418 /*                                                                        */
13419 /*    DATE              NAME                      DESCRIPTION             */
13420 /*                                                                        */
13421 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13422 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13423 /*                                            resulting in version 6.1    */
13424 /*                                                                        */
13425 /**************************************************************************/
_nxe_snmp_object_timetics_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)13426 UINT  _nxe_snmp_object_timetics_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
13427 {
13428 
13429 UINT    status;
13430 
13431 
13432     /* Check for invalid input pointers.  */
13433     if ((source_ptr == NX_NULL) || (object_data == NX_NULL))
13434         return(NX_PTR_ERROR);
13435 
13436     /* Call actual service.  */
13437     status =  _nx_snmp_object_timetics_get(source_ptr, object_data);
13438 
13439     /* Return status.  */
13440     return(status);
13441 }
13442 
13443 
13444 /**************************************************************************/
13445 /*                                                                        */
13446 /*  FUNCTION                                               RELEASE        */
13447 /*                                                                        */
13448 /*    _nx_snmp_object_timetics_get                        PORTABLE C      */
13449 /*                                                           6.1          */
13450 /*  AUTHOR                                                                */
13451 /*                                                                        */
13452 /*    Yuxin Zhou, Microsoft Corporation                                   */
13453 /*                                                                        */
13454 /*  DESCRIPTION                                                           */
13455 /*                                                                        */
13456 /*    This function retrieves the object timetics from the specified      */
13457 /*    source location.                                                    */
13458 /*                                                                        */
13459 /*  INPUT                                                                 */
13460 /*                                                                        */
13461 /*    source_ptr                            Pointer to timetics source    */
13462 /*    object_data                           Pointer to object data struct */
13463 /*                                                                        */
13464 /*  OUTPUT                                                                */
13465 /*                                                                        */
13466 /*    status                                Completion status             */
13467 /*                                                                        */
13468 /*  CALLS                                                                 */
13469 /*                                                                        */
13470 /*    None                                                                */
13471 /*                                                                        */
13472 /*  CALLED BY                                                             */
13473 /*                                                                        */
13474 /*    Application Code                                                    */
13475 /*                                                                        */
13476 /*  RELEASE HISTORY                                                       */
13477 /*                                                                        */
13478 /*    DATE              NAME                      DESCRIPTION             */
13479 /*                                                                        */
13480 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13481 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13482 /*                                            resulting in version 6.1    */
13483 /*                                                                        */
13484 /**************************************************************************/
_nx_snmp_object_timetics_get(VOID * source_ptr,NX_SNMP_OBJECT_DATA * object_data)13485 UINT  _nx_snmp_object_timetics_get(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data)
13486 {
13487 
13488 ULONG   *value_ptr;
13489 
13490 
13491     /* Setup the object data structure.  */
13492     object_data -> nx_snmp_object_data_type =   NX_SNMP_TIME_TICS;
13493 
13494     /* Setup pointer to the value.  */
13495     value_ptr =  (ULONG *) source_ptr;
13496 
13497     /* Copy the value into the object data structure.  */
13498     object_data -> nx_snmp_object_data_msw =  (LONG)(*value_ptr);
13499 
13500     /* Return success.  */
13501     return(NX_SUCCESS);
13502 }
13503 
13504 
13505 /**************************************************************************/
13506 /*                                                                        */
13507 /*  FUNCTION                                               RELEASE        */
13508 /*                                                                        */
13509 /*    _nxe_snmp_object_timetics_set                       PORTABLE C      */
13510 /*                                                           6.1          */
13511 /*  AUTHOR                                                                */
13512 /*                                                                        */
13513 /*    Yuxin Zhou, Microsoft Corporation                                   */
13514 /*                                                                        */
13515 /*  DESCRIPTION                                                           */
13516 /*                                                                        */
13517 /*    This function checks for errors in the SNMP agent timetics          */
13518 /*    set function call.                                                  */
13519 /*                                                                        */
13520 /*  INPUT                                                                 */
13521 /*                                                                        */
13522 /*    destination_ptr                       Pointer to timetics           */
13523 /*                                            destination                 */
13524 /*    object_data                           Pointer to object data struct */
13525 /*                                                                        */
13526 /*  OUTPUT                                                                */
13527 /*                                                                        */
13528 /*    status                                Completion status             */
13529 /*                                                                        */
13530 /*  CALLS                                                                 */
13531 /*                                                                        */
13532 /*    _nx_snmp_object_timetics_set          Actual agent timetics         */
13533 /*                                            set function                */
13534 /*                                                                        */
13535 /*  CALLED BY                                                             */
13536 /*                                                                        */
13537 /*    Application Code                                                    */
13538 /*                                                                        */
13539 /*  RELEASE HISTORY                                                       */
13540 /*                                                                        */
13541 /*    DATE              NAME                      DESCRIPTION             */
13542 /*                                                                        */
13543 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13544 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13545 /*                                            resulting in version 6.1    */
13546 /*                                                                        */
13547 /**************************************************************************/
_nxe_snmp_object_timetics_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)13548 UINT  _nxe_snmp_object_timetics_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
13549 {
13550 
13551 UINT    status;
13552 
13553 
13554     /* Check for invalid input pointers.  */
13555     if ((destination_ptr == NX_NULL) || (object_data == NX_NULL))
13556         return(NX_PTR_ERROR);
13557 
13558     /* Call actual service.  */
13559     status =  _nx_snmp_object_timetics_set(destination_ptr, object_data);
13560 
13561     /* Return status.  */
13562     return(status);
13563 }
13564 
13565 
13566 /**************************************************************************/
13567 /*                                                                        */
13568 /*  FUNCTION                                               RELEASE        */
13569 /*                                                                        */
13570 /*    _nx_snmp_object_timetics_set                        PORTABLE C      */
13571 /*                                                           6.1          */
13572 /*  AUTHOR                                                                */
13573 /*                                                                        */
13574 /*    Yuxin Zhou, Microsoft Corporation                                   */
13575 /*                                                                        */
13576 /*  DESCRIPTION                                                           */
13577 /*                                                                        */
13578 /*    This function retrieves the object timetics from the object         */
13579 /*    data structure and places it in the destination.                    */
13580 /*                                                                        */
13581 /*  INPUT                                                                 */
13582 /*                                                                        */
13583 /*    destination_ptr                       Pointer to timetics           */
13584 /*                                            destination                 */
13585 /*    object_data                           Pointer to object data struct */
13586 /*                                                                        */
13587 /*  OUTPUT                                                                */
13588 /*                                                                        */
13589 /*    status                                Completion status             */
13590 /*                                                                        */
13591 /*  CALLS                                                                 */
13592 /*                                                                        */
13593 /*    None                                                                */
13594 /*                                                                        */
13595 /*  CALLED BY                                                             */
13596 /*                                                                        */
13597 /*    Application Code                                                    */
13598 /*                                                                        */
13599 /*  RELEASE HISTORY                                                       */
13600 /*                                                                        */
13601 /*    DATE              NAME                      DESCRIPTION             */
13602 /*                                                                        */
13603 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13604 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13605 /*                                            resulting in version 6.1    */
13606 /*                                                                        */
13607 /**************************************************************************/
_nx_snmp_object_timetics_set(VOID * destination_ptr,NX_SNMP_OBJECT_DATA * object_data)13608 UINT  _nx_snmp_object_timetics_set(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data)
13609 {
13610 
13611 ULONG   *value_ptr;
13612 
13613 
13614     /* Determine if the correct type is specified.  */
13615     if (object_data -> nx_snmp_object_data_type != NX_SNMP_TIME_TICS)
13616     {
13617 
13618         /* Return an invalid type message.  */
13619         return(NX_SNMP_ERROR_WRONGTYPE);
13620     }
13621 
13622     /* Setup pointer to the value.  */
13623     value_ptr =  (ULONG *) destination_ptr;
13624 
13625     /* Copy the value into the object data structure.  */
13626     *value_ptr =  (ULONG)(object_data -> nx_snmp_object_data_msw);
13627 
13628     /* Return success.  */
13629     return(NX_SUCCESS);
13630 }
13631 
13632 
13633 /**************************************************************************/
13634 /*                                                                        */
13635 /*  FUNCTION                                               RELEASE        */
13636 /*                                                                        */
13637 /*    _nx_snmp_utility_community_get                      PORTABLE C      */
13638 /*                                                           6.1          */
13639 /*  AUTHOR                                                                */
13640 /*                                                                        */
13641 /*    Yuxin Zhou, Microsoft Corporation                                   */
13642 /*                                                                        */
13643 /*  DESCRIPTION                                                           */
13644 /*                                                                        */
13645 /*    This function retrieves the community string from the supplied      */
13646 /*    buffer.                                                             */
13647 /*                                                                        */
13648 /*  INPUT                                                                 */
13649 /*                                                                        */
13650 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
13651 /*    community_string                      Pointer to place community    */
13652 /*                                            string                      */
13653 /*    buffer_length                         Size of input buffer          */
13654 /*                                                                        */
13655 /*  OUTPUT                                                                */
13656 /*                                                                        */
13657 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
13658 /*                                            value of zero implies error */
13659 /*                                                                        */
13660 /*  CALLS                                                                 */
13661 /*                                                                        */
13662 /*    None                                                                */
13663 /*                                                                        */
13664 /*  CALLED BY                                                             */
13665 /*                                                                        */
13666 /*    _nx_snmp_version_1_and_2_process      SNMP v1, v2 request processing*/
13667 /*                                                                        */
13668 /*  RELEASE HISTORY                                                       */
13669 /*                                                                        */
13670 /*    DATE              NAME                      DESCRIPTION             */
13671 /*                                                                        */
13672 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13673 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13674 /*                                            resulting in version 6.1    */
13675 /*                                                                        */
13676 /**************************************************************************/
_nx_snmp_utility_community_get(UCHAR * buffer_ptr,UCHAR * community_string,INT buffer_length)13677 UINT  _nx_snmp_utility_community_get(UCHAR *buffer_ptr, UCHAR *community_string, INT buffer_length)
13678 {
13679 
13680 UINT    i;
13681 UINT    length;
13682 UINT    total;
13683 
13684 
13685     /* Buffer size must be at least 2 bytes. */
13686     if (buffer_length < 2)
13687     {
13688         return(0);
13689     }
13690 
13691     /* Set community string to NULL.  */
13692     *community_string =  NX_NULL;
13693 
13694     /* First see if the ANS1 string type is present.  */
13695     if (buffer_ptr[0] != NX_SNMP_ANS1_OCTET_STRING)
13696     {
13697 
13698         /* Return a zero length.  */
13699         return(0);
13700     }
13701 
13702     if (buffer_ptr[1] & NX_SNMP_ANS1_MULTI_BYTES)
13703     {
13704 
13705     /* Get the type of length of the string */
13706     UINT temp = (UINT)(buffer_ptr[1] & 0x7F);
13707 
13708         if (temp == 2)
13709         {
13710 
13711             /* Check the buffer length.  */
13712             if (buffer_length < 4)
13713             {
13714                 return(0);
13715             }
13716 
13717             /* Length is in the next two bytes. Example: 0x04 0x82 0x98 0x01 */
13718             total =  (((UINT) buffer_ptr[2]) << 8) | ((UINT) buffer_ptr[3]);
13719 
13720             /* Move the buffer pointer forward.  */
13721             buffer_ptr =  buffer_ptr + 4;
13722 
13723             /* Initialize the length.  */
13724             length =  4;
13725         }
13726 
13727         else if (temp == 1)
13728         {
13729 
13730             /* Check the buffer length.  */
13731             if (buffer_length < 3)
13732             {
13733                 return(0);
13734             }
13735 
13736             /* Length is in the next byte. Example: 0x04 0x81 0x98 */
13737             total =  (UINT)(buffer_ptr[2]) ;
13738 
13739             /* Move the buffer pointer forward.  */
13740             buffer_ptr =  buffer_ptr + 3;
13741 
13742             /* Initialize the length.  */
13743             length =  3;
13744         }
13745         else
13746         {
13747 
13748             /* String is either null or too big, return a zero length to indicate an error.  */
13749             return(0);
13750         }
13751     }
13752     else
13753     {
13754 
13755         /* Otherwise, assume we have one byte. Example: 0x04 0x98 */
13756 
13757         /*  Pickup the total length of the community character string.  */
13758         total =  (UINT) buffer_ptr[1];
13759 
13760         /* Move the buffer pointer forward.  */
13761         buffer_ptr =  buffer_ptr + 2;
13762 
13763         /* Initialize the length.  */
13764         length =  2;
13765     }
13766 
13767     if ((INT)(length + total) > buffer_length)
13768     {
13769 
13770         /* Buffer is too small. */
13771         return(0);
13772     }
13773 
13774     /* Determine if the length is within the maximum.  */
13775     if (total > (NX_SNMP_MAX_USER_NAME-1))
13776     {
13777 
13778         /* String is too big, return a zero length to indicate an error.  */
13779         return(0);
13780     }
13781 
13782     /* Loop to pickup the remaining characters in the community string.  */
13783     for (i = 0; i < total; i++)
13784     {
13785 
13786         /* Move character from buffer into community string.  */
13787         *community_string++ =  *buffer_ptr++;
13788 
13789         /* Adjust the length.  */
13790         length++;
13791     }
13792 
13793     /* NULL-terminate the community string.  */
13794     *community_string =  NX_NULL;
13795 
13796     /* Return the length of the ANS1 string.  */
13797     return(length);
13798 }
13799 
13800 
13801 /**************************************************************************/
13802 /*                                                                        */
13803 /*  FUNCTION                                               RELEASE        */
13804 /*                                                                        */
13805 /*    _nx_snmp_utility_community_set                      PORTABLE C      */
13806 /*                                                           6.1          */
13807 /*  AUTHOR                                                                */
13808 /*                                                                        */
13809 /*    Yuxin Zhou, Microsoft Corporation                                   */
13810 /*                                                                        */
13811 /*  DESCRIPTION                                                           */
13812 /*                                                                        */
13813 /*    This function places the community string into the supplied         */
13814 /*    buffer.                                                             */
13815 /*                                                                        */
13816 /*  INPUT                                                                 */
13817 /*                                                                        */
13818 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
13819 /*    community_string                      Pointer to source of the      */
13820 /*                                            community string            */
13821 /*    buffer_end                            End of buffer                 */
13822 /*                                                                        */
13823 /*  OUTPUT                                                                */
13824 /*                                                                        */
13825 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
13826 /*                                            value of zero implies error */
13827 /*                                                                        */
13828 /*  CALLS                                                                 */
13829 /*                                                                        */
13830 /*    None                                                                */
13831 /*                                                                        */
13832 /*  CALLED BY                                                             */
13833 /*                                                                        */
13834 /*    _nx_snmp_agent_trap_send              Send SNMP v1 trap             */
13835 /*    _nx_snmp_agent_trapv2_send            Send SNMP v2 trap             */
13836 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
13837 /*                                                                        */
13838 /*  RELEASE HISTORY                                                       */
13839 /*                                                                        */
13840 /*    DATE              NAME                      DESCRIPTION             */
13841 /*                                                                        */
13842 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13843 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13844 /*                                            resulting in version 6.1    */
13845 /*                                                                        */
13846 /**************************************************************************/
_nx_snmp_utility_community_set(UCHAR * buffer_ptr,UCHAR * community_string,UCHAR * buffer_end)13847 UINT  _nx_snmp_utility_community_set(UCHAR *buffer_ptr, UCHAR *community_string, UCHAR *buffer_end)
13848 {
13849 
13850 UINT    i;
13851 UINT    header_size;
13852 UINT    length;
13853 
13854 
13855     /* Check for the end of the buffer.  */
13856     if (buffer_ptr >= buffer_end)
13857         return(0);
13858 
13859     /* First, set the OCTET byte.  */
13860     *buffer_ptr++ =  NX_SNMP_ANS1_OCTET_STRING;
13861 
13862     /* Calculate the length byte.  */
13863     if (_nx_utility_string_length_check((CHAR *)community_string, &length, NX_SNMP_MAX_USER_NAME))
13864     {
13865 
13866         /* Error, community length is too large.  */
13867         return(0);
13868     }
13869 
13870     /* Check for a length greater than 128.  */
13871     if (length >= 128)
13872     {
13873 
13874         /* Check for the end of the buffer.  */
13875         if ((UINT)(buffer_end - buffer_ptr) < (3 + length))
13876             return(0);
13877 
13878         /* Indicate there are two length bytes.  */
13879         *buffer_ptr++ =  (UCHAR) 0x82;
13880 
13881         /* Set the first length byte.  */
13882         *buffer_ptr++ =  (UCHAR) (length >> 8);
13883 
13884         /* Set the second length byte.  */
13885         *buffer_ptr++ =  (UCHAR) (length & 0xFF);
13886 
13887         /* Set the header size.  */
13888         header_size =  4;
13889     }
13890     else
13891     {
13892 
13893         /* Check for the end of the buffer.  */
13894         if ((UINT)(buffer_end - buffer_ptr) < (1 + length))
13895             return(0);
13896 
13897         /* Next set the length byte.  */
13898         *buffer_ptr++ =  (UCHAR) length;
13899 
13900         /* The header is 2 bytes.  */
13901         header_size =  2;
13902     }
13903 
13904     /* Loop to store rest of the community string.  */
13905     for (i = 0; i < length; i++)
13906     {
13907 
13908         /* Store the SNMP community string.  */
13909         *buffer_ptr++ =  (UCHAR) community_string[i];
13910     }
13911 
13912     /* Return the length of the community string.  */
13913     return(length+header_size);
13914 }
13915 
13916 
13917 /**************************************************************************/
13918 /*                                                                        */
13919 /*  FUNCTION                                               RELEASE        */
13920 /*                                                                        */
13921 /*    _nx_snmp_utility_error_info_get                     PORTABLE C      */
13922 /*                                                           6.1          */
13923 /*  AUTHOR                                                                */
13924 /*                                                                        */
13925 /*    Yuxin Zhou, Microsoft Corporation                                   */
13926 /*                                                                        */
13927 /*  DESCRIPTION                                                           */
13928 /*                                                                        */
13929 /*    This function retrieves the error information from the supplied     */
13930 /*    buffer.                                                             */
13931 /*                                                                        */
13932 /*  INPUT                                                                 */
13933 /*                                                                        */
13934 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
13935 /*    error_code                            Pointer to place error code   */
13936 /*    error_index                           Pointer to place error index  */
13937 /*    buffer_length                         Size of input buffer          */
13938 /*                                                                        */
13939 /*  OUTPUT                                                                */
13940 /*                                                                        */
13941 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
13942 /*                                            value of zero implies error */
13943 /*                                                                        */
13944 /*  CALLS                                                                 */
13945 /*                                                                        */
13946 /*    None                                                                */
13947 /*                                                                        */
13948 /*  CALLED BY                                                             */
13949 /*                                                                        */
13950 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
13951 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
13952 /*                                                                        */
13953 /*  RELEASE HISTORY                                                       */
13954 /*                                                                        */
13955 /*    DATE              NAME                      DESCRIPTION             */
13956 /*                                                                        */
13957 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
13958 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
13959 /*                                            resulting in version 6.1    */
13960 /*                                                                        */
13961 /**************************************************************************/
_nx_snmp_utility_error_info_get(UCHAR * buffer_ptr,UINT * error_code,UINT * error_index,INT buffer_length)13962 UINT  _nx_snmp_utility_error_info_get(UCHAR *buffer_ptr, UINT *error_code, UINT *error_index, INT buffer_length)
13963 {
13964 
13965     /* Check for invalid input. */
13966     if (buffer_length < 6)
13967     {
13968         /* Invalid input. */
13969         *error_code =   0;
13970         *error_index =  0;
13971 
13972         /* Return a zero length.  */
13973         return(0);
13974     }
13975 
13976     /* Determine if the error code and error index is correct.  */
13977     if ((buffer_ptr[0] == NX_SNMP_ANS1_INTEGER) &&
13978         (buffer_ptr[1] == 1) &&
13979         (buffer_ptr[3] == NX_SNMP_ANS1_INTEGER) &&
13980         (buffer_ptr[4] == 1))
13981     {
13982 
13983         /* Yes, the SNMP version string is correct.  */
13984 
13985         /* Return the error code and error index.  */
13986         *error_code =  (UINT) buffer_ptr[2];
13987         *error_index = (UINT) buffer_ptr[5];
13988 
13989         /* Return the length of the error code/index string.  */
13990         return(6);
13991     }
13992     else
13993     {
13994 
13995         /* No, the SNMP error code/index is invalid.  */
13996 
13997         /* Clear both.  */
13998         *error_code =   0;
13999         *error_index =  0;
14000 
14001         /* Return a zero length.  */
14002         return(0);
14003     }
14004 }
14005 
14006 
14007 /**************************************************************************/
14008 /*                                                                        */
14009 /*  FUNCTION                                               RELEASE        */
14010 /*                                                                        */
14011 /*    _nx_snmp_utility_error_info_set                     PORTABLE C      */
14012 /*                                                           6.1          */
14013 /*  AUTHOR                                                                */
14014 /*                                                                        */
14015 /*    Yuxin Zhou, Microsoft Corporation                                   */
14016 /*                                                                        */
14017 /*  DESCRIPTION                                                           */
14018 /*                                                                        */
14019 /*    This function places the error information into the supplied        */
14020 /*    buffer.                                                             */
14021 /*                                                                        */
14022 /*  INPUT                                                                 */
14023 /*                                                                        */
14024 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
14025 /*    error_code                            Error code                    */
14026 /*    error_index                           Error index                   */
14027 /*    buffer_end                            End of buffer                 */
14028 /*                                                                        */
14029 /*  OUTPUT                                                                */
14030 /*                                                                        */
14031 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
14032 /*                                            value of zero implies error */
14033 /*                                                                        */
14034 /*  CALLS                                                                 */
14035 /*                                                                        */
14036 /*    None                                                                */
14037 /*                                                                        */
14038 /*  CALLED BY                                                             */
14039 /*                                                                        */
14040 /*    _nx_snmp_agent_trapv2_send            Send SNMP v2 trap             */
14041 /*    _nx_snmp_agent_trapv3_send            Send SNMP v3 trap             */
14042 /*    _nx_snmp_version_error_response       Send error response to Manager*/
14043 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
14044 /*    _nx_snmp_version_3_report_send        Send SNMP v3 report           */
14045 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
14046 /*                                                                        */
14047 /*  RELEASE HISTORY                                                       */
14048 /*                                                                        */
14049 /*    DATE              NAME                      DESCRIPTION             */
14050 /*                                                                        */
14051 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
14052 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
14053 /*                                            resulting in version 6.1    */
14054 /*                                                                        */
14055 /**************************************************************************/
_nx_snmp_utility_error_info_set(UCHAR * buffer_ptr,UINT error_code,UINT error_index,UCHAR * buffer_end)14056 UINT  _nx_snmp_utility_error_info_set(UCHAR *buffer_ptr, UINT error_code, UINT error_index, UCHAR *buffer_end)
14057 {
14058 
14059     /* Check for the end of the buffer.  */
14060     if ((UINT)(buffer_end - buffer_ptr) < 6)
14061         return(0);
14062 
14063     /* First, set the INTEGER byte.  */
14064     *buffer_ptr++ =  NX_SNMP_ANS1_INTEGER;
14065 
14066     /* Next set the length byte.  */
14067     *buffer_ptr++ =  (UCHAR) 1;
14068 
14069     /* Store the error code.  */
14070     *buffer_ptr++ =  (UCHAR) (error_code & 0xFF);
14071 
14072     /* Set the INTEGER byte.  */
14073     *buffer_ptr++ =  NX_SNMP_ANS1_INTEGER;
14074 
14075     /* Next set the length byte.  */
14076     *buffer_ptr++ =  (UCHAR) 1;
14077 
14078     /* Store the error index.  */
14079     *buffer_ptr++ =  (UCHAR) (error_index & 0xFF);
14080 
14081     /* Return the length of the error info.  */
14082     return(6);
14083 }
14084 
14085 
14086 /**************************************************************************/
14087 /*                                                                        */
14088 /*  FUNCTION                                               RELEASE        */
14089 /*                                                                        */
14090 /*    _nx_snmp_utility_object_id_get                      PORTABLE C      */
14091 /*                                                           6.1.10       */
14092 /*  AUTHOR                                                                */
14093 /*                                                                        */
14094 /*    Yuxin Zhou, Microsoft Corporation                                   */
14095 /*                                                                        */
14096 /*  DESCRIPTION                                                           */
14097 /*                                                                        */
14098 /*    This function retrieves the object ID from the supplied buffer      */
14099 /*    and converts the object ID to an ASCII format.                      */
14100 /*                                                                        */
14101 /*  INPUT                                                                 */
14102 /*                                                                        */
14103 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
14104 /*    object_string                         Pointer to place object string*/
14105 /*    buffer_length                         Size of input buffer          */
14106 /*                                                                        */
14107 /*  OUTPUT                                                                */
14108 /*                                                                        */
14109 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
14110 /*                                            value of zero implies error */
14111 /*                                                                        */
14112 /*  CALLS                                                                 */
14113 /*                                                                        */
14114 /*    _nx_utility_uint_to_string            Convert number to ASCII       */
14115 /*                                                                        */
14116 /*  CALLED BY                                                             */
14117 /*                                                                        */
14118 /*    _nx_snmp_utility_object_data_get      Get object data               */
14119 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
14120 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
14121 /*                                                                        */
14122 /*  RELEASE HISTORY                                                       */
14123 /*                                                                        */
14124 /*    DATE              NAME                      DESCRIPTION             */
14125 /*                                                                        */
14126 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
14127 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
14128 /*                                            resulting in version 6.1    */
14129 /*  08-02-2021     Yuxin Zhou               Modified comment(s),          */
14130 /*                                            improved the logic of       */
14131 /*                                            converting number to string,*/
14132 /*                                            resulting in version 6.1.8  */
14133 /*  01-31-2022     Yuxin Zhou               Modified comment(s),          */
14134 /*                                            initialized the sequence    */
14135 /*                                            byte value,                 */
14136 /*                                            resulting in version 6.1.10 */
14137 /*                                                                        */
14138 /**************************************************************************/
_nx_snmp_utility_object_id_get(UCHAR * buffer_ptr,UCHAR * object_string,INT buffer_length)14139 UINT  _nx_snmp_utility_object_id_get(UCHAR *buffer_ptr, UCHAR *object_string, INT buffer_length)
14140 {
14141 
14142 UINT    i;
14143 UINT    length;
14144 ULONG   value;
14145 ULONG   temp;
14146 ULONG   multiply;
14147 UINT    total;
14148 UINT    size;
14149 UCHAR   byte;
14150 UCHAR   saved_byte;
14151 UCHAR  *saved_ptr;
14152 UINT    string_length;
14153 
14154 
14155     /* Buffer size must be at least 4 bytes. */
14156     if (buffer_length < 4)
14157     {
14158         return 0;
14159     }
14160 
14161     /* Set object string to NULL.  */
14162     *object_string =  NX_NULL;
14163 
14164     /* Initialize the string length to 0.  */
14165     string_length = 0;
14166 
14167     /* First see if the ANS1 object type is present.  */
14168     if (buffer_ptr[0] != NX_SNMP_ANS1_OBJECT_ID)
14169     {
14170 
14171         /* Return a zero length.  */
14172         return(0);
14173     }
14174 
14175     if (buffer_ptr[1] & NX_SNMP_ANS1_MULTI_BYTES)
14176     {
14177 
14178         temp = buffer_ptr[1] & 0x7F;
14179 
14180         /* Determine if a two byte length is present.  */
14181         if (temp == 2)
14182         {
14183 
14184             /* Check the buffer length.  */
14185             if (buffer_length < 5)
14186             {
14187                 return(0);
14188             }
14189 
14190             /* Pickup the total length of the object string.  */
14191             total =  (((UINT) buffer_ptr[2]) << 8) | ((UINT) buffer_ptr[3]);
14192 
14193             /* Pickup the first byte.  */
14194             byte =  buffer_ptr[4];
14195 
14196             /* Save the pointer to the first byte.  */
14197             saved_ptr =  &buffer_ptr[4];
14198 
14199             /* Move the buffer pointer forward.  */
14200             buffer_ptr =  buffer_ptr + 4;
14201 
14202             /* Initialize the length.  */
14203             length =  4;
14204         }
14205         else if (temp == 1)
14206         {
14207 
14208             /* Pickup the total length of the object string.  */
14209             total =  buffer_ptr[2];
14210 
14211             /* Pickup the first byte.  */
14212             byte =  buffer_ptr[3];
14213 
14214             /* Save the pointer to the first byte.  */
14215             saved_ptr =  &buffer_ptr[3];
14216 
14217             /* Move the buffer pointer forward.  */
14218             buffer_ptr =  buffer_ptr + 3;
14219 
14220             /* Initialize the length.  */
14221             length =  3;
14222         }
14223         else
14224         {
14225 
14226             /* This is out of range or null. Invalid SNMP sequence. */
14227             return(0);
14228         }
14229     }
14230     else
14231     {
14232 
14233         /* Otherwise, assume one byte. */
14234 
14235         /* Pickup the total length of the object string.  */
14236         total =  (UINT) buffer_ptr[1];
14237 
14238         /* Check for invalid data size */
14239         if ((INT)total > (buffer_length - 1))
14240         {
14241             /* Indicate an invalid request is received. */
14242             return 0;
14243         }
14244 
14245         /* Pickup the first byte.  */
14246         byte =  buffer_ptr[2];
14247 
14248         /* Save the index.  */
14249         saved_ptr =  &buffer_ptr[2];
14250 
14251         /* Move the buffer pointer forward.  */
14252         buffer_ptr =  buffer_ptr + 2;
14253 
14254         /* Initialize the length.  */
14255         length =  2;
14256     }
14257 
14258     /* Save the original byte.  */
14259     saved_byte =  byte;
14260 
14261     /* Calculate the first two characters of object string.  */
14262     if (byte >= 80)
14263     {
14264 
14265         /* This form starts with 2 as the first identifier.  */
14266         *object_string++ =  '2';
14267 
14268         /* Increment the string length.  */
14269         string_length++;
14270 
14271         /* Adjust the byte.  */
14272         byte = (UCHAR)(byte - 80);
14273     }
14274     else if (byte >= 40)
14275     {
14276 
14277         /* This form starts with 1 as the first identifier.  */
14278         *object_string++ =  '1';
14279 
14280         /* Increment the string length.  */
14281         string_length++;
14282 
14283         /* Adjust the byte.  */
14284         byte = (UCHAR)(byte - 40);
14285     }
14286     else
14287     {
14288 
14289         /* This form starts with 0 as the first identifier.  */
14290         *object_string++ =  '0';
14291 
14292         /* Increment the string length.  */
14293         string_length++;
14294     }
14295 
14296     /* Always place a '.'.  */
14297     *object_string++ =  '.';
14298 
14299     /* Increment the string length.  */
14300     string_length++;
14301 
14302     /* Determine if the second identifier is legal.  */
14303     if (byte & NX_SNMP_ANS1_MULTI_BYTES)
14304     {
14305 
14306         /* Second identifier too large, return a zero length.  */
14307         return(0);
14308     }
14309 
14310     /* Write the byte back. */
14311     buffer_ptr[0] =  byte;
14312 
14313     /* Loop to pickup the remaining characters in the object string.  */
14314     while (total)
14315     {
14316 
14317         /* Initialize the sequence byte value to NULL. */
14318         value = 0;
14319 
14320         /* Move the buffer pointer forward.  */
14321         byte =  *buffer_ptr++;
14322 
14323         /* Decrement the total.  */
14324         total--;
14325 
14326         /* Increment the length.  */
14327         length++;
14328 
14329         /* Determine if the next byte has the additional bytes
14330            bit set (BIT 7).  */
14331         if ((byte & NX_SNMP_ANS1_MULTI_BYTES) == 0)
14332         {
14333 
14334             /* The specified sequence value is less than 128 and is actually in this byte!  */
14335             value =  (UINT) byte;
14336         }
14337         else
14338         {
14339 
14340             /* Otherwise, we have a more complicated value that we must loop through
14341                to calculate.  */
14342 
14343             /* Loop to calculate how many bytes there are representing the value.  */
14344             i = 0;
14345             multiply =  128;
14346             while (buffer_ptr[i] & NX_SNMP_ANS1_MULTI_BYTES)
14347             {
14348 
14349                 /* Increment count.  */
14350                 i++;
14351 
14352                 /* Adjust the multiplier. */
14353                 multiply =  multiply * 128;
14354             }
14355 
14356             /* Determine if the count is reasonable.  */
14357             if (i > 3)
14358             {
14359 
14360                 /* Restore the saved byte.  */
14361                 *saved_ptr =  saved_byte;
14362 
14363                 /* Nope, too big!  */
14364                 return(0);
14365             }
14366 
14367             /* Loop to calculate the value.  */
14368             do
14369             {
14370 
14371                 /* Pickup the number of bytes required to represent this value.  */
14372                 temp =  (ULONG) (byte & ~NX_SNMP_ANS1_MULTI_BYTES);
14373 
14374                 /* Calculate the temporary value.  */
14375                 temp =  temp * multiply;
14376 
14377                 /* Calculate total value.  */
14378                 value =  value + temp;
14379 
14380                 /* Adjust the multiply value.  */
14381                 multiply =  multiply/128;
14382 
14383                 /* Pickup next byte.  */
14384                 byte =  *buffer_ptr++;
14385 
14386                 /* Decrement the total.  */
14387                 if (total == 0)
14388                 {
14389 
14390                     /* Restore the saved byte.  */
14391                     *saved_ptr =  saved_byte;
14392 
14393                     return(0);
14394                 }
14395                 else
14396                     total--;
14397 
14398                 /* Increment the length.  */
14399                 length++;
14400 
14401             } while (byte & NX_SNMP_ANS1_MULTI_BYTES);
14402 
14403             /* Add in the remainder.  */
14404             temp =  (ULONG) (byte & ~NX_SNMP_ANS1_MULTI_BYTES);
14405             value =  value + temp;
14406         }
14407 
14408         /* Convert value into ASCII.  */
14409         size = _nx_utility_uint_to_string(value, 10, (CHAR *)object_string, NX_SNMP_MAX_OCTET_STRING + 1 - string_length);
14410 
14411         if (size == 0)
14412         {
14413 
14414             /* String is too long.  */
14415 
14416             /* Null-terminate the string.  */
14417             *object_string =  NX_NULL;
14418 
14419             /* Return the length.  */
14420             return(length);
14421         }
14422 
14423         /* Adjust the object string length.  */
14424         string_length += size;
14425 
14426         /* Adjust the object string.  */
14427         object_string =  object_string + size;
14428 
14429         /* Determine if there are more tokens. */
14430         if (total)
14431         {
14432 
14433             /* Still more nodes, place a dot in the string.  */
14434             *object_string++ =  '.';
14435 
14436             /* Increment the string length.  */
14437             string_length++;
14438 
14439             /* Determine if the length is too long.  */
14440             if (string_length >= NX_SNMP_MAX_OCTET_STRING)
14441             {
14442 
14443                 /* String is too long.  */
14444 
14445                 /* Null-terminate the string.  */
14446                 object_string--;
14447                 *object_string =  NX_NULL;
14448 
14449                 /* Return the length.  */
14450                 return(length);
14451             }
14452         }
14453     }
14454 
14455     /* Restore the saved byte.  */
14456     *saved_ptr =  saved_byte;
14457 
14458     /* NULL-terminate the object string.  */
14459     *object_string =  NX_NULL;
14460 
14461     /* Return the length of the ANS1 string.  */
14462     return(length);
14463 }
14464 
14465 
14466 /**************************************************************************/
14467 /*                                                                        */
14468 /*  FUNCTION                                               RELEASE        */
14469 /*                                                                        */
14470 /*    _nx_snmp_utility_object_id_set                      PORTABLE C      */
14471 /*                                                           6.3.0        */
14472 /*  AUTHOR                                                                */
14473 /*                                                                        */
14474 /*    Yuxin Zhou, Microsoft Corporation                                   */
14475 /*                                                                        */
14476 /*  DESCRIPTION                                                           */
14477 /*                                                                        */
14478 /*    This function converts the ASCII representation of the object into  */
14479 /*    ASN.1 format and then places it in the ASN.1 buffer.                */
14480 /*                                                                        */
14481 /*  INPUT                                                                 */
14482 /*                                                                        */
14483 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
14484 /*    object_string                         Object string in ASCII        */
14485 /*    buffer_end                            End of ASN.1 buffer for error */
14486 /*                                            checking                    */
14487 /*                                                                        */
14488 /*  OUTPUT                                                                */
14489 /*                                                                        */
14490 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
14491 /*                                            value of zero implies error */
14492 /*                                                                        */
14493 /*  CALLS                                                                 */
14494 /*                                                                        */
14495 /*    None                                                                */
14496 /*                                                                        */
14497 /*  CALLED BY                                                             */
14498 /*                                                                        */
14499 /*    _nx_snmp_agent_trap_send              SNMP v1 trap send             */
14500 /*    _nx_snmp_agent_trapv2_send            SNMP v2 trap send             */
14501 /*    _nx_snmp_agent_trapv3_send            SNMP v3 trap send             */
14502 /*    _nx_snmp_utility_object_data_set      Object data set               */
14503 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
14504 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
14505 /*                                                                        */
14506 /*  RELEASE HISTORY                                                       */
14507 /*                                                                        */
14508 /*    DATE              NAME                      DESCRIPTION             */
14509 /*                                                                        */
14510 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
14511 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
14512 /*                                            resulting in version 6.1    */
14513 /*  10-31-2023     Bo Chen                  Modified comment(s), improved */
14514 /*                                            buffer length verification, */
14515 /*                                            resulting in version 6.3.0  */
14516 /*                                                                        */
14517 /**************************************************************************/
_nx_snmp_utility_object_id_set(UCHAR * buffer_ptr,UCHAR * object_string,UCHAR * buffer_end)14518 UINT  _nx_snmp_utility_object_id_set(UCHAR *buffer_ptr, UCHAR *object_string, UCHAR *buffer_end)
14519 {
14520 
14521 UINT    length;
14522 UINT    i;
14523 ULONG   value;
14524 UCHAR   *length_ptr;
14525 UCHAR   encoding_started;
14526 UINT    object_string_length;
14527 
14528 
14529     /* Check for the end of the buffer.  */
14530     if (buffer_ptr >= buffer_end)
14531         return(0);
14532 
14533     /* Check object string length.  */
14534     if (_nx_utility_string_length_check((CHAR*)object_string, &object_string_length, (UINT)(buffer_end - buffer_ptr)))
14535         return(0);
14536 
14537     /* Set the OBJECT byte.  */
14538     *buffer_ptr++ =  NX_SNMP_ANS1_OBJECT_ID;
14539 
14540     /* Remember length pointer.  */
14541     length_ptr =  buffer_ptr;
14542 
14543     /* Check for the end of the buffer.  */
14544     if (buffer_ptr >= buffer_end)
14545         return(0);
14546 
14547     /* Set the length byte to zero for now.  */
14548     *buffer_ptr++ =  0;
14549 
14550     /* Check object string length.  */
14551     if (object_string_length < 2)
14552         return(0);
14553 
14554     /* Determine if the object string is legal.  */
14555     if (((object_string[0] != '0') && (object_string[0] != '1') && (object_string[0] != '2')) ||
14556          (object_string[1] != '.'))
14557     {
14558 
14559         /* Invalid object ID.  */
14560         return(0);
14561     }
14562 
14563     /* Calculate the value of the second identifier.  */
14564     i =  2;
14565     value =  0;
14566 
14567     while ((object_string[i] != '.') && (object_string[i] != NX_NULL))
14568     {
14569 
14570         /* Compute the value.  */
14571         value =  (value * 10) + ((ULONG) (object_string[i] - 0x30));
14572 
14573         /* Move to the next character.  */
14574         i++;
14575     }
14576 
14577     if (object_string[i] == '.')
14578     {
14579         /* Move to the next character.  */
14580         i++;
14581     }
14582 
14583     /* The second identifier must be less that 128.  */
14584     if (value >= 128)
14585     {
14586 
14587         /* Invalid object ID.  */
14588         return(0);
14589     }
14590 
14591     /* Now determine how to set the first byte of the object ID.  */
14592     if (object_string[0] == '1')
14593     {
14594 
14595         /* Increment value by 40 per spec.  */
14596         value = value + 40;
14597     }
14598     else if (object_string[0] == '2')
14599     {
14600 
14601         /* Increment value by 40 per spec.  */
14602         value = value + 80;
14603     }
14604 
14605     /* Check for the end of the buffer.  */
14606     if (buffer_ptr >= buffer_end)
14607         return(0);
14608 
14609     /* Set the first byte, which is the combination of the first two bytes.  */
14610     *buffer_ptr++ =  (UCHAR) value;
14611 
14612     /* Set the length.  */
14613     length =  1;
14614 
14615     /* Process all the characters in the ID.  For now, the limit will be 128 characters in the
14616        ID specification string.  */
14617     while (object_string[i])
14618     {
14619 
14620         UCHAR    *value_ptr;
14621         UCHAR    byte0;
14622         ULONG    mod_value;
14623 
14624         /* Initialize the encoding started flag.  */
14625         encoding_started =  NX_FALSE;
14626 
14627         /* Pickup the next value.  */
14628         value =  0;
14629         while ((object_string[i] != '.') && (object_string[i] != NX_NULL))
14630         {
14631 
14632             /* Compute the value.  */
14633             value =  (value * 10) + ((ULONG) (object_string[i] - 0x30));
14634 
14635             /* Move to the next character.  */
14636             i++;
14637         }
14638 
14639         /* At this point we have a value to store in the ID string.  */
14640 
14641         /* Determine if it is simple encoding.  */
14642         if (value < 128)
14643         {
14644 
14645             /* Check for the end of the buffer.  */
14646             if (buffer_ptr >= buffer_end)
14647                 return(0);
14648 
14649             /* Place the value directly in the buffer.  */
14650             *buffer_ptr++ =  (UCHAR) value;
14651 
14652             /* Increment the length.  */
14653             length++;
14654         }
14655         else
14656         {
14657 
14658             /* Otherwise, we need to encode the numeric value such that it has
14659                more bytes to represent it.  */
14660 
14661             if (value/268435456)
14662             {
14663 
14664                 /* Check for the end of the buffer.  */
14665                 if (buffer_ptr >= buffer_end)
14666                     return(0);
14667 
14668                 /* To avoid compiler warnings of casting an ULONG to a UCHAR (loss of information possible),
14669                 use an intermediate ULONG pointer. */
14670 
14671                 mod_value = value/268435456;  /* (0x10000000) */
14672 
14673                 value_ptr = (UCHAR *)(&mod_value);
14674 
14675                 /* A UCHAR will not hold more than one byte. */
14676                 byte0 = *(value_ptr);
14677 
14678                 *buffer_ptr =  ((UCHAR) (byte0)) | NX_SNMP_ANS1_MULTI_BYTES;
14679 
14680                 buffer_ptr++;
14681 
14682                 /* Update the value.  */
14683                 value =  value % 268435456;
14684 
14685                 /* Increment the length.  */
14686                 length++;
14687 
14688                 /* Set the encoding started flag so that we put 0 bytes below in cases where value is less than the
14689                    next 128 divisor.  */
14690                 encoding_started =  NX_TRUE;
14691             }
14692 
14693             if ((value/2097152) || (encoding_started == NX_TRUE))
14694             {
14695 
14696                 /* Check for the end of the buffer.  */
14697                 if (buffer_ptr >= buffer_end)
14698                     return(0);
14699 
14700                 /* To avoid compiler warnings of casting an ULONG to a UCHAR (loss of information possible),
14701                 use an intermediate ULONG pointer. */
14702 
14703                 mod_value = value/2097152;  /* (0x10000000) */
14704 
14705                 value_ptr = (UCHAR *)(&mod_value);
14706 
14707                 /* A UCHAR will not hold more than one byte. */
14708                 byte0 = *(value_ptr);
14709 
14710                 *buffer_ptr =  ((UCHAR) (byte0)) | NX_SNMP_ANS1_MULTI_BYTES;
14711 
14712                 buffer_ptr++;
14713 
14714                 /* Update the value.  */
14715                 value =  value % 2097152;
14716 
14717                 /* Increment the length.  */
14718                 length++;
14719 
14720                 /* Set the encoding started flag so that we put 0 bytes below in cases where value is less than the
14721                    next 128 divisor.  */
14722                 encoding_started =  NX_TRUE;
14723             }
14724 
14725             if ((value / 16384) || (encoding_started == NX_TRUE))
14726             {
14727 
14728                 /* Check for the end of the buffer.  */
14729                 if (buffer_ptr >= buffer_end)
14730                     return(0);
14731 
14732                 /* To avoid compiler warnings of casting an ULONG to a UCHAR (loss of information possible),
14733                 use an intermediate ULONG pointer. */
14734 
14735                 mod_value = value/16384;  /* (0x10000000) */
14736 
14737                 value_ptr = (UCHAR *)(&mod_value);
14738 
14739                 /* A UCHAR will not hold more than one byte. */
14740                 byte0 = *(value_ptr);
14741 
14742                 *buffer_ptr =  ((UCHAR) (byte0)) | NX_SNMP_ANS1_MULTI_BYTES;
14743 
14744                 buffer_ptr++;
14745 
14746                 /* Update the value.  */
14747                 value =  value % 16384;
14748 
14749                 /* Increment the length.  */
14750                 length++;
14751 
14752 
14753                 /* Set the encoding started flag so that we put 0 bytes below in cases where value is less than the
14754                    next 128 divisor.  */
14755                 encoding_started =  NX_TRUE;
14756             }
14757 
14758             if ((value /128) || (encoding_started == NX_TRUE))
14759             {
14760 
14761                 /* Check for the end of the buffer.  */
14762                 if (buffer_ptr >= buffer_end)
14763                     return(0);
14764 
14765                 /* To avoid compiler warnings of casting an ULONG to a UCHAR (loss of information possible),
14766                 use an intermediate ULONG pointer. */
14767 
14768                 mod_value = value/128;  /* (0x100) */
14769 
14770                 value_ptr = (UCHAR *)(&mod_value);
14771 
14772                 /* A UCHAR will not hold more than one byte. */
14773                 byte0 = *(value_ptr);
14774 
14775                 *buffer_ptr =  ((UCHAR) (byte0)) | NX_SNMP_ANS1_MULTI_BYTES;
14776 
14777                 buffer_ptr++;
14778 
14779                 /* Update the value.  */
14780                 value =  value % 128;
14781 
14782                 /* Increment the length.  */
14783                 length++;
14784             }
14785 
14786             /* Check for the end of the buffer.  */
14787             if (buffer_ptr >= buffer_end)
14788                 return(0);
14789 
14790             /* Place the value directly in the buffer.  */
14791             *buffer_ptr++ =  (UCHAR) value;
14792 
14793             /* Increment the length.  */
14794             length++;
14795         }
14796 
14797         /* Determine if we are sitting on a dot.  */
14798         if (object_string[i] == '.')
14799             i++;
14800     }
14801 
14802     /* Update the length.  */
14803     length_ptr[0] =  (UCHAR) (length & 0xFF);
14804 
14805     /* Return the length plus the header information.  */
14806     return(length + 2);
14807 }
14808 
14809 
14810 /**************************************************************************/
14811 /*                                                                        */
14812 /*  FUNCTION                                               RELEASE        */
14813 /*                                                                        */
14814 /*    _nx_snmp_utility_object_id_set_1byte                PORTABLE C      */
14815 /*                                                           6.1          */
14816 /*  AUTHOR                                                                */
14817 /*                                                                        */
14818 /*    Yuxin Zhou, Microsoft Corporation                                   */
14819 /*                                                                        */
14820 /*  DESCRIPTION                                                           */
14821 /*                                                                        */
14822 /*    This function converts the ASCII representation of the object into  */
14823 /*    ASN.1 format and then places it in the ASN.1 buffer.                */
14824 /*                                                                        */
14825 /*    The difference with _nx_snmp_utility_object_id_set is that          */
14826 /*    this uses only a single byte length field e.g. 0x30 xx instead of   */
14827 /*    0x30 0x82 xx yy where xx(yy) is the sequence length (1 vs 2 bytes). */
14828 /*                                                                        */
14829 /*  INPUT                                                                 */
14830 /*                                                                        */
14831 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
14832 /*    object_string                         Object string in ASCII        */
14833 /*    buffer_end                            End of ASN.1 buffer for error */
14834 /*                                            checking                    */
14835 /*                                                                        */
14836 /*  OUTPUT                                                                */
14837 /*                                                                        */
14838 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
14839 /*                                            value of zero implies error */
14840 /*                                                                        */
14841 /*  CALLS                                                                 */
14842 /*                                                                        */
14843 /*    None                                                                */
14844 /*                                                                        */
14845 /*  CALLED BY                                                             */
14846 /*                                                                        */
14847 /*    _nx_snmp_version_3_report_send        Send SNMP v3 report           */
14848 /*                                                                        */
14849 /*  RELEASE HISTORY                                                       */
14850 /*                                                                        */
14851 /*    DATE              NAME                      DESCRIPTION             */
14852 /*                                                                        */
14853 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
14854 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
14855 /*                                            resulting in version 6.1    */
14856 /*                                                                        */
14857 /**************************************************************************/
_nx_snmp_utility_object_id_set_1byte(UCHAR * buffer_ptr,UCHAR * object_string,UCHAR * buffer_end)14858 UINT  _nx_snmp_utility_object_id_set_1byte(UCHAR *buffer_ptr, UCHAR *object_string, UCHAR *buffer_end)
14859 {
14860 
14861 UINT    length;
14862 UINT    i;
14863 ULONG   value;
14864 UCHAR   *length_ptr;
14865 UCHAR   encoding_started;
14866 
14867 
14868     /* Check for the end of the buffer.  */
14869     if (buffer_ptr >= buffer_end)
14870         return(0);
14871 
14872     /* Set the OBJECT byte.  */
14873     *buffer_ptr++ =  NX_SNMP_ANS1_OBJECT_ID;
14874 
14875     /* Remember length pointer.  */
14876     length_ptr =  buffer_ptr;
14877 
14878     /* Check for the end of the buffer.  */
14879     if (buffer_ptr >= buffer_end)
14880         return(0);
14881 
14882     /* Set the length byte to zero for now.  */
14883     *buffer_ptr++ =  0;
14884 
14885     /* Check for the end of the buffer.  */
14886     if (buffer_ptr >= buffer_end)
14887         return(0);
14888 
14889     /* Determine if the object string is legal.  */
14890     if (((object_string[0] != '0') && (object_string[0] != '1') && (object_string[0] != '2')) ||
14891          (object_string[1] != '.'))
14892     {
14893 
14894         /* Invalid object ID.  */
14895         return(0);
14896     }
14897 
14898     /* Calculate the value of the second identifier.  */
14899     i =  2;
14900     value =  0;
14901 
14902     while ((object_string[i] != '.') && (object_string[i] != NX_NULL))
14903     {
14904 
14905         /* Compute the value.  */
14906         value =  (value * 10) + ((ULONG) (object_string[i] - 0x30));
14907 
14908         /* Move to the next character.  */
14909         i++;
14910     }
14911 
14912     if (object_string[i] == '.')
14913     {
14914         /* Move to the next character.  */
14915         i++;
14916     }
14917 
14918     /* The second identifier must be less that 128.  */
14919     if (value >= 128)
14920     {
14921 
14922         /* Invalid object ID.  */
14923         return(0);
14924     }
14925 
14926     /* Now determine how to set the first byte of the object ID.  */
14927     if (object_string[0] == '1')
14928     {
14929 
14930         /* Increment value by 40 per spec.  */
14931         value = value + 40;
14932     }
14933     else if (object_string[0] == '2')
14934     {
14935 
14936         /* Increment value by 40 per spec.  */
14937         value = value + 80;
14938     }
14939 
14940     /* Set the first byte, which is the combination of the first two bytes.  */
14941     *buffer_ptr++ =  (UCHAR) value;
14942 
14943     /* Set the length.  */
14944     length =  1;
14945 
14946     /* Process all the characters in the ID.  For now, the limit will be 128 characters in the
14947        ID specification string.  */
14948     while (object_string[i])
14949     {
14950 
14951         UCHAR    *value_ptr;
14952         UCHAR    byte0;
14953         ULONG    mod_value;
14954 
14955         /* Initialize the encoding started flag.  */
14956         encoding_started =  NX_FALSE;
14957 
14958         /* Pickup the next value.  */
14959         value =  0;
14960         while ((object_string[i] != '.') && (object_string[i] != NX_NULL))
14961         {
14962 
14963             /* Compute the value.  */
14964             value =  (value * 10) + ((ULONG) (object_string[i] - 0x30));
14965 
14966             /* Move to the next character.  */
14967             i++;
14968         }
14969 
14970         /* At this point we have a value to store in the ID string.  */
14971 
14972         /* Determine if it is simple encoding.  */
14973         if (value < 128)
14974         {
14975 
14976             /* Check for the end of the buffer.  */
14977             if (buffer_ptr >= buffer_end)
14978                 return(0);
14979 
14980             /* Place the value directly in the buffer.  */
14981             *buffer_ptr++ =  (UCHAR) value;
14982 
14983             /* Increment the length.  */
14984             length++;
14985         }
14986         else
14987         {
14988 
14989             /* Otherwise, we need to encode the numeric value such that it has
14990                more bytes to represent it.  */
14991 
14992             if (value/268435456)
14993             {
14994 
14995                 /* Check for the end of the buffer.  */
14996                 if (buffer_ptr >= buffer_end)
14997                     return(0);
14998 
14999                 /* To avoid compiler warnings of casting an ULONG to a UCHAR (loss of information possible),
15000                 use an intermediate ULONG pointer. */
15001 
15002                 mod_value = value/268435456;  /* (0x10000000) */
15003 
15004                 value_ptr = (UCHAR *)(&mod_value);
15005 
15006                 /* A UCHAR will not hold more than one byte. */
15007                 byte0 = *(value_ptr);
15008 
15009                 *buffer_ptr =  ((UCHAR) (byte0)) | NX_SNMP_ANS1_MULTI_BYTES;
15010 
15011                 buffer_ptr++;
15012 
15013 
15014                 /* Update the value.  */
15015                 value =  value % 268435456;
15016 
15017                 /* Increment the length.  */
15018                 length++;
15019 
15020                 /* Set the encoding started flag so that we put 0 bytes below in cases where value is less than the
15021                    next 128 divisor.  */
15022                 encoding_started =  NX_TRUE;
15023             }
15024 
15025             if ((value/2097152) || (encoding_started == NX_TRUE))
15026             {
15027 
15028                 /* Check for the end of the buffer.  */
15029                 if (buffer_ptr >= buffer_end)
15030                     return(0);
15031 
15032                 /* To avoid compiler warnings of casting an ULONG to a UCHAR (loss of information possible),
15033                 use an intermediate ULONG pointer. */
15034 
15035                 mod_value = value/2097152;  /* (0x10000000) */
15036 
15037                 value_ptr = (UCHAR *)(&mod_value);
15038 
15039                 /* A UCHAR will not hold more than one byte. */
15040                 byte0 = *(value_ptr);
15041 
15042                 *buffer_ptr =  ((UCHAR) (byte0)) | NX_SNMP_ANS1_MULTI_BYTES;
15043 
15044                 buffer_ptr++;
15045 
15046                 /* Update the value.  */
15047                 value =  value % 2097152;
15048 
15049                 /* Increment the length.  */
15050                 length++;
15051 
15052                 /* Set the encoding started flag so that we put 0 bytes below in cases where value is less than the
15053                    next 128 divisor.  */
15054                 encoding_started =  NX_TRUE;
15055             }
15056 
15057             if ((value / 16384) || (encoding_started == NX_TRUE))
15058             {
15059 
15060                 /* Check for the end of the buffer.  */
15061                 if (buffer_ptr >= buffer_end)
15062                     return(0);
15063 
15064                 /* To avoid compiler warnings of casting an ULONG to a UCHAR (loss of information possible),
15065                 use an intermediate ULONG pointer. */
15066 
15067                 mod_value = value/16384;  /* (0x10000000) */
15068 
15069                 value_ptr = (UCHAR *)(&mod_value);
15070 
15071                 /* A UCHAR will not hold more than one byte. */
15072                 byte0 = *(value_ptr);
15073 
15074                 *buffer_ptr =  ((UCHAR) (byte0)) | NX_SNMP_ANS1_MULTI_BYTES;
15075 
15076                 buffer_ptr++;
15077 
15078                 /* Update the value.  */
15079                 value =  value % 16384;
15080 
15081                 /* Increment the length.  */
15082                 length++;
15083 
15084 
15085                 /* Set the encoding started flag so that we put 0 bytes below in cases where value is less than the
15086                    next 128 divisor.  */
15087                 encoding_started =  NX_TRUE;
15088             }
15089 
15090             if ((value /128) || (encoding_started == NX_TRUE))
15091             {
15092 
15093                 /* Check for the end of the buffer.  */
15094                 if (buffer_ptr >= buffer_end)
15095                     return(0);
15096 
15097                 /* To avoid compiler warnings of casting an ULONG to a UCHAR (loss of information possible),
15098                 use an intermediate ULONG pointer. */
15099 
15100                 mod_value = value/128;  /* (0x100) */
15101 
15102                 value_ptr = (UCHAR *)(&mod_value);
15103 
15104                 /* A UCHAR will not hold more than one byte. */
15105                 byte0 = *(value_ptr);
15106 
15107                 *buffer_ptr =  ((UCHAR) (byte0)) | NX_SNMP_ANS1_MULTI_BYTES;
15108 
15109                 buffer_ptr++;
15110 
15111                 /* Update the value.  */
15112                 value =  value % 128;
15113 
15114                 /* Increment the length.  */
15115                 length++;
15116             }
15117 
15118             /* Check for the end of the buffer.  */
15119             if (buffer_ptr >= buffer_end)
15120                 return(0);
15121 
15122             /* Place the value directly in the buffer.  */
15123             *buffer_ptr++ =  (UCHAR) value;
15124 
15125             /* Increment the length.  */
15126             length++;
15127         }
15128 
15129         /* Determine if we are sitting on a dot.  */
15130         if (object_string[i] == '.')
15131             i++;
15132     }
15133 
15134     /* Update the length.  */
15135     length_ptr[0] =  (UCHAR) (length & 0xFF);
15136 
15137     /* Return the length plus the header information.  */
15138     return(length + 2);
15139 }
15140 
15141 
15142 /**************************************************************************/
15143 /*                                                                        */
15144 /*  FUNCTION                                               RELEASE        */
15145 /*                                                                        */
15146 /*    _nx_snmp_utility_object_data_get                    PORTABLE C      */
15147 /*                                                           6.2.0        */
15148 /*  AUTHOR                                                                */
15149 /*                                                                        */
15150 /*    Yuxin Zhou, Microsoft Corporation                                   */
15151 /*                                                                        */
15152 /*  DESCRIPTION                                                           */
15153 /*                                                                        */
15154 /*    This function retrieves the object data from the supplied ASN.1     */
15155 /*    buffer.                                                             */
15156 /*                                                                        */
15157 /*  INPUT                                                                 */
15158 /*                                                                        */
15159 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
15160 /*    object_data                           Pointer to place object data  */
15161 /*                                                                        */
15162 /*  OUTPUT                                                                */
15163 /*                                                                        */
15164 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
15165 /*                                            value of zero implies error */
15166 /*                                                                        */
15167 /*  CALLS                                                                 */
15168 /*                                                                        */
15169 /*    _nx_snmp_utility_object_id_get        Get object ID                 */
15170 /*                                                                        */
15171 /*  CALLED BY                                                             */
15172 /*                                                                        */
15173 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
15174 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
15175 /*                                                                        */
15176 /*  RELEASE HISTORY                                                       */
15177 /*                                                                        */
15178 /*    DATE              NAME                      DESCRIPTION             */
15179 /*                                                                        */
15180 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
15181 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
15182 /*                                            resulting in version 6.1    */
15183 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
15184 /*                                            fixed compiler warnings,    */
15185 /*                                            resulting in version 6.2.0  */
15186 /*                                                                        */
15187 /**************************************************************************/
_nx_snmp_utility_object_data_get(UCHAR * buffer_ptr,NX_SNMP_OBJECT_DATA * object_data,INT buffer_length)15188 UINT  _nx_snmp_utility_object_data_get(UCHAR *buffer_ptr, NX_SNMP_OBJECT_DATA *object_data, INT buffer_length)
15189 {
15190 
15191 
15192 UINT    i;
15193 UINT    length = 0;
15194 LONG    data;
15195 UINT    total = 0;
15196 CHAR    byte;
15197 LONG    temp = 0;
15198 USHORT  tlv_type, tlv_tag_class;
15199 UCHAR   *tlv_data;
15200 UCHAR   *work_ptr;
15201 UINT    status;
15202 
15203 
15204     /* Check the buffer length.  */
15205     if (buffer_length < 1)
15206     {
15207         return(0);
15208     }
15209 
15210     work_ptr = buffer_ptr;
15211 
15212     /* First, pickup the request byte.  */
15213     byte =  (CHAR)(*buffer_ptr);
15214 
15215     /* Clear several value words.  */
15216     object_data -> nx_snmp_object_data_msw =   0;
15217     object_data -> nx_snmp_object_data_lsw =   0;
15218 
15219     /* Determine if a NULL is present.  */
15220     if (byte == NX_SNMP_ANS1_NULL)
15221     {
15222 
15223         /* Return NULL values in the input object, and set length to 2 (0x05 00).  */
15224         object_data -> nx_snmp_object_data_type =  NX_SNMP_ANS1_NULL;
15225         object_data -> nx_snmp_object_data_msw =   0;
15226         return(2);
15227     }
15228 
15229     /* Determine if the object is a standard type.  */
15230     else if ((byte == NX_SNMP_ANS1_OCTET_STRING) || (byte == NX_SNMP_ANS1_INTEGER) ||
15231              (byte == NX_SNMP_ANS1_TIME_TICS) || (byte == NX_SNMP_ANS1_GAUGE) ||
15232              (byte == NX_SNMP_ANS1_COUNTER) || (byte == NX_SNMP_ANS1_COUNTER64) ||
15233              (byte == NX_SNMP_IP_ADDRESS) || (byte == NX_SNMP_ANS1_NSAP_ADDRESS))
15234     {
15235 
15236         /* Standard object type.  */
15237 
15238         /* Check the buffer length.  */
15239         if (buffer_length < 3)
15240         {
15241             return(0);
15242         }
15243 
15244         /* If this is an integer, determine if we have a negative number (msb is set). */
15245         if ((*buffer_ptr == NX_SNMP_ANS1_INTEGER) && (*(buffer_ptr + 2) & 0x80))
15246         {
15247 
15248             /* This only applies if short form (size of length =1), not long form (size of length field > 1 byte) */
15249             if (((*(buffer_ptr + 1) & 0x80)== 0))
15250                 temp = -1;
15251 
15252             /* We can only check the sign for long form data after we compute the length of length field below */
15253         }
15254 
15255         /* Update the object with the data type. */
15256         object_data -> nx_snmp_object_data_type = (UINT)byte;
15257 
15258         /* Extract the length of the length field and tag class. This sill update the pointer past the type
15259          * and length fields to the actual data.   */
15260         status = _nx_snmp_utility_tlv_block_parse(work_ptr, buffer_length, &tlv_type, &tlv_tag_class,  (ULONG *)(&total), &tlv_data, (ULONG *)(&length));
15261 
15262         if (status)
15263         {
15264             return 0;
15265         }
15266 
15267         work_ptr = tlv_data;
15268 
15269         /* Initialize working data.  */
15270         data =  temp;
15271         object_data -> nx_snmp_object_octet_string_size =  0;
15272 
15273         i = 0;
15274 
15275         /* handle the special case of a leading zero e.g.  00 DD 2F C9 CE 69 52 74 8D where total is 9 */
15276          if ((total == 9) &&  (object_data -> nx_snmp_object_data_type != NX_SNMP_ANS1_OCTET_STRING))
15277          {
15278              /* Skip the first byte and decrement total */
15279              work_ptr++;
15280              total = total - 1;
15281          }
15282 
15283 
15284          /* Loop through the remaining request length bytes.  */
15285         while (i < total)
15286         {
15287 
15288             /* Pickup next byte.  */
15289             byte =  (CHAR)(*work_ptr++);
15290 
15291             /* Determine the type of the data.  */
15292             if (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_OCTET_STRING)
15293             {
15294 
15295                 /* Check for string size.  */
15296                 if ((i) >= NX_SNMP_MAX_OCTET_STRING)
15297                 {
15298                     return(0);
15299                 }
15300 
15301                 /* Copy byte into the string.  */
15302                 object_data -> nx_snmp_object_octet_string[i] =  (UCHAR)byte;
15303 
15304                 /* Increment the length.  */
15305                 object_data -> nx_snmp_object_octet_string_size++;
15306             }
15307             else
15308             {
15309 
15310                 /* Compute the request id based on the next value.  */
15311                 data =  (data << 8) | ((LONG) (0x000000FF & byte));
15312             }
15313 
15314             /* Increment the length.  */
15315             length++;
15316 
15317              i++;
15318 
15319             /* If we are dealing with a 64 bit number, store the rest (least) significant bytes in lsw. */
15320             if ((i == 4) && (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_COUNTER64))
15321             {
15322                 object_data -> nx_snmp_object_data_msw =  data;
15323 
15324                 data = 0x0;
15325 
15326                 /* Finish the rest of the data into lsw */
15327                 while(i < total)
15328                 {
15329                     /* Pickup next byte.  */
15330                     byte =  (CHAR)(*work_ptr++);
15331 
15332                     /* Compute the request id based on the next value.  */
15333                     data =  (data << 8) | ((LONG) (0x000000FF & byte));
15334 
15335                     i++;
15336                 }
15337 
15338                 object_data -> nx_snmp_object_data_lsw =  data;
15339             }
15340         }
15341 
15342         /* If dealing with a 32 bit data type or less, store the data to msw */
15343         if (object_data -> nx_snmp_object_data_type != NX_SNMP_ANS1_COUNTER64)
15344         {
15345             object_data -> nx_snmp_object_data_msw =  data;
15346         }
15347         else
15348         {
15349             /* Otherwise (e.g. this is a 64 bit data type) store the least significant bytes in the lsw */
15350             object_data -> nx_snmp_object_data_lsw =  data;
15351         }
15352         /* Null terminate the data string.  */
15353         if (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_OCTET_STRING)
15354         {
15355 
15356             /* Null terminate string.  */
15357             if ((i > 0) && (i < NX_SNMP_MAX_OCTET_STRING))
15358             {
15359                 object_data -> nx_snmp_object_octet_string[i] =  NX_NULL;
15360             }
15361         }
15362 
15363         /* Return the length of the request id string.  */
15364         return(length);
15365     }
15366     else if (byte == NX_SNMP_ANS1_OBJECT_ID)
15367     {
15368 
15369         /* Setup the data type.  */
15370         object_data -> nx_snmp_object_data_type =  (UINT)byte;
15371 
15372         /* Convert the object ID to a string.  */
15373         length =  _nx_snmp_utility_object_id_get(buffer_ptr, object_data -> nx_snmp_object_octet_string, buffer_length);
15374 
15375         /* Return length of the object id.  */
15376         return(length);
15377     }
15378 
15379     /* Error; return zero length.  */
15380     return(0);
15381 }
15382 
15383 
15384 /**************************************************************************/
15385 /*                                                                        */
15386 /*  FUNCTION                                               RELEASE        */
15387 /*                                                                        */
15388 /*    _nx_snmp_utility_object_data_set                    PORTABLE C      */
15389 /*                                                           6.1          */
15390 /*  AUTHOR                                                                */
15391 /*                                                                        */
15392 /*    Yuxin Zhou, Microsoft Corporation                                   */
15393 /*                                                                        */
15394 /*  DESCRIPTION                                                           */
15395 /*                                                                        */
15396 /*    This function retrieves the object data and then places it in the   */
15397 /*    ASN.1 buffer.                                                       */
15398 /*                                                                        */
15399 /*  INPUT                                                                 */
15400 /*                                                                        */
15401 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
15402 /*    object_data                           Object data structure         */
15403 /*    buffer_end                            End of ASN.1 buffer for error */
15404 /*                                            checking                    */
15405 /*                                                                        */
15406 /*  OUTPUT                                                                */
15407 /*                                                                        */
15408 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
15409 /*                                            value of zero implies error */
15410 /*                                                                        */
15411 /*  CALLS                                                                 */
15412 /*                                                                        */
15413 /*    _nx_snmp_utility_object_id_set        Set object ID                 */
15414 /*                                                                        */
15415 /*  CALLED BY                                                             */
15416 /*                                                                        */
15417 /*    _nx_snmp_agent_trap_send              Send SNMP v1 Trap             */
15418 /*    _nx_snmp_agent_trapv2_send            Send SNMP v2 Trap             */
15419 /*    _nx_snmp_agent_trapv3_send            Send SNMP v3 Trap             */
15420 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
15421 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
15422 /*                                                                        */
15423 /*  RELEASE HISTORY                                                       */
15424 /*                                                                        */
15425 /*    DATE              NAME                      DESCRIPTION             */
15426 /*                                                                        */
15427 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
15428 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
15429 /*                                            resulting in version 6.1    */
15430 /*                                                                        */
15431 /**************************************************************************/
_nx_snmp_utility_object_data_set(UCHAR * buffer_ptr,NX_SNMP_OBJECT_DATA * object_data,UCHAR * buffer_end)15432 UINT  _nx_snmp_utility_object_data_set(UCHAR *buffer_ptr, NX_SNMP_OBJECT_DATA *object_data, UCHAR *buffer_end)
15433 {
15434 
15435 UINT    i;
15436 UINT    length;
15437 UINT    data_msw;
15438 UINT    data_lsw;
15439 
15440 
15441     /* Process relative to the type of request.  */
15442 
15443     /* See if the request is a NULL.  */
15444     if ((object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_NULL) ||
15445         (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_NO_SUCH_OBJECT) ||
15446         (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_NO_SUCH_INSTANCE) ||
15447         (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_END_OF_MIB_VIEW))
15448     {
15449 
15450         /* Check for the end of the buffer.  */
15451         if ((buffer_ptr + 2) >= buffer_end)
15452             return(0);
15453 
15454         /* Set the NULL type byte.  */
15455         *buffer_ptr++ =  (UCHAR) object_data -> nx_snmp_object_data_type;
15456         *buffer_ptr   =  0;
15457 
15458         /* Set the length. */
15459         length =  2;
15460     }
15461 
15462     /* See if the request is an INTEGER.  */
15463     else if ((object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_INTEGER) ||
15464              (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_UINTEGER32) ||
15465              (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_TIME_TICS) ||
15466              (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_GAUGE) ||
15467              (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_COUNTER) ||
15468              (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_COUNTER64) ||
15469              (object_data -> nx_snmp_object_data_type == NX_SNMP_IP_ADDRESS) ||
15470              (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_NSAP_ADDRESS))
15471     {
15472 
15473 
15474         /* Check for the end of the buffer.  */
15475         if (buffer_ptr >= buffer_end)
15476             return(0);
15477 
15478         /* Set the type byte.  */
15479         *buffer_ptr++ =  (UCHAR)object_data -> nx_snmp_object_data_type;
15480 
15481         /* Pickup the data most significant word.  */
15482         data_msw =  (UINT)(object_data -> nx_snmp_object_data_msw);
15483 
15484         /* Pickup the data least significant word.  */
15485         data_lsw =  (UINT)(object_data -> nx_snmp_object_data_lsw);
15486 
15487         /* Determine the size of the encoding.  */
15488         if (((data_msw & 0xFF000000) || (data_msw & 0x00800000)) && (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_COUNTER64))
15489         {
15490 
15491             /* Check for the end of the buffer.  */
15492             if ((buffer_ptr + 9) >= buffer_end)
15493                 return(0);
15494 
15495             /* Four bytes are required.  */
15496             *buffer_ptr++ =  ((UCHAR) 8);
15497 
15498             /* Set the value in successive bytes.  */
15499             *buffer_ptr++ =  (UCHAR) ((data_msw >> 24) & 0xFF);
15500             *buffer_ptr++ =  (UCHAR) ((data_msw >> 16) & 0xFF);
15501             *buffer_ptr++ =  (UCHAR) ((data_msw >> 8)  & 0xFF);
15502             *buffer_ptr++ =  (UCHAR)  (data_msw & 0xFF);
15503             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 24) & 0xFF);
15504             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 16) & 0xFF);
15505             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 8)  & 0xFF);
15506             *buffer_ptr++ =  (UCHAR)  (data_lsw & 0xFF);
15507 
15508             /* Update the length.  */
15509             length =  10;
15510             return(length);
15511         }
15512         else if (((data_msw & 0x00FF0000) || (data_msw & 0x00008000)) && (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_COUNTER64))
15513         {
15514 
15515             /* Check for the end of the buffer.  */
15516             if ((buffer_ptr + 8) >= buffer_end)
15517                 return(0);
15518 
15519             /* Three bytes are required.  */
15520             *buffer_ptr++ =  ((UCHAR) 7);
15521 
15522             /* Set the value in successive bytes.  */
15523             *buffer_ptr++ =  (UCHAR) ((data_msw >> 16) & 0xFF);
15524             *buffer_ptr++ =  (UCHAR) ((data_msw >> 8)  & 0xFF);
15525             *buffer_ptr++ =  (UCHAR)  (data_msw & 0xFF);
15526             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 24) & 0xFF);
15527             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 16) & 0xFF);
15528             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 8)  & 0xFF);
15529             *buffer_ptr++ =  (UCHAR)  (data_lsw & 0xFF);
15530 
15531             /* Update the length.  */
15532             length =  9;
15533             return(length);
15534         }
15535         else if (((data_msw & 0x0000FF00) || (data_msw & 0x00000080)) && (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_COUNTER64))
15536         {
15537 
15538             /* Check for the end of the buffer.  */
15539             if ((buffer_ptr + 7) >= buffer_end)
15540                 return(0);
15541 
15542             /* Two bytes are required.  */
15543             *buffer_ptr++ =  ((UCHAR) 6);
15544 
15545             /* Set the value in successive bytes.  */
15546             *buffer_ptr++ =  (UCHAR) ((data_msw >> 8)  & 0xFF);
15547             *buffer_ptr++ =  (UCHAR)  (data_msw & 0xFF);
15548             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 24) & 0xFF);
15549             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 16) & 0xFF);
15550             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 8)  & 0xFF);
15551             *buffer_ptr++ =  (UCHAR)  (data_lsw & 0xFF);
15552 
15553             /* Update the length.  */
15554             length =  8;
15555             return(length);
15556         }
15557         else if (((data_msw & 0x000000FF) || (data_lsw & 0x80000000)) && (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_COUNTER64))
15558         {
15559 
15560             /* Check for the end of the buffer.  */
15561             if ((buffer_ptr + 6) >= buffer_end)
15562                 return(0);
15563 
15564             /* One byte is required.  */
15565             *buffer_ptr++ =  ((UCHAR) 5);
15566 
15567             /* Set the value in successive bytes.  */
15568             *buffer_ptr++ =  (UCHAR) (data_msw & 0xFF);
15569             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 24) & 0xFF);
15570             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 16) & 0xFF);
15571             *buffer_ptr++ =  (UCHAR) ((data_lsw >> 8)  & 0xFF);
15572             *buffer_ptr++ =  (UCHAR)  (data_lsw & 0xFF);
15573 
15574             /* Update the length.  */
15575             length =  7;
15576             return(length);
15577         }
15578         else if (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_COUNTER64)
15579         {
15580 
15581             /* Make the least significant word the most significant to use the normal integer processing below.  */
15582             data_msw =  data_lsw;
15583         }
15584 
15585         /* Determine the size of the encoding.  */
15586         if ((data_msw & 0xFF000000) || (data_msw & 0x00800000) || (object_data -> nx_snmp_object_data_type == NX_SNMP_IP_ADDRESS))
15587         {
15588 
15589             /* Check for the end of the buffer.  */
15590             if ((buffer_ptr + 5) >= buffer_end)
15591                 return(0);
15592 
15593             /* Four bytes are required.  */
15594             *buffer_ptr++ =  ((UCHAR) 4);
15595 
15596             /* Set the value in successive bytes.  */
15597             *buffer_ptr++ =  (UCHAR) ((data_msw >> 24) & 0xFF);
15598             *buffer_ptr++ =  (UCHAR) ((data_msw >> 16) & 0xFF);
15599             *buffer_ptr++ =  (UCHAR) ((data_msw >> 8)  & 0xFF);
15600             *buffer_ptr++ =  (UCHAR)  (data_msw & 0xFF);
15601 
15602             /* Update the length.  */
15603             length =  6;
15604         }
15605         else if ((data_msw & 0x00FF0000) || (data_msw & 0x00008000))
15606         {
15607 
15608             /* Check for the end of the buffer.  */
15609             if ((buffer_ptr + 4) >= buffer_end)
15610                 return(0);
15611 
15612             /* Three bytes are required.  */
15613             *buffer_ptr++ =  ((UCHAR) 3);
15614 
15615             /* Set the value in successive bytes.  */
15616             *buffer_ptr++ =  (UCHAR) ((data_msw >> 16) & 0xFF);
15617             *buffer_ptr++ =  (UCHAR) ((data_msw >> 8)  & 0xFF);
15618             *buffer_ptr++ =  (UCHAR)  (data_msw & 0xFF);
15619 
15620             /* Update the length.  */
15621             length =  5;
15622         }
15623         else if ((data_msw & 0x0000FF00) || (data_msw & 0x00000080))
15624         {
15625 
15626             /* Check for the end of the buffer.  */
15627             if ((buffer_ptr + 3) >= buffer_end)
15628                 return(0);
15629 
15630             /* Two bytes are required.  */
15631             *buffer_ptr++ =  ((UCHAR) 2);
15632 
15633             /* Set the value in successive bytes.  */
15634             *buffer_ptr++ =  (UCHAR) ((data_msw >> 8)  & 0xFF);
15635             *buffer_ptr++ =  (UCHAR)  (data_msw & 0xFF);
15636 
15637             /* Update the length.  */
15638             length =  4;
15639         }
15640         else
15641         {
15642 
15643             /* Check for the end of the buffer.  */
15644             if ((buffer_ptr + 2) >= buffer_end)
15645                 return(0);
15646 
15647             /* One byte is required.  */
15648             *buffer_ptr++ =  ((UCHAR) 1);
15649 
15650             /* Set the value in successive bytes.  */
15651             *buffer_ptr++ =  (UCHAR) (data_msw & 0xFF);
15652 
15653             /* Update the length.  */
15654             length =  3;
15655         }
15656     }
15657 
15658     /* See if the request is an octet string. Note that this includes the IPv6 address type.  */
15659     else if (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_OCTET_STRING)
15660     {
15661 
15662         /* Check for the end of the buffer.  */
15663         if (buffer_ptr >= buffer_end)
15664             return(0);
15665 
15666         /* Set the OCTET type byte.  */
15667         *buffer_ptr++ =  NX_SNMP_ANS1_OCTET_STRING;
15668 
15669         /* Check for the end of the buffer.  */
15670         if (buffer_ptr >= buffer_end)
15671             return(0);
15672 
15673         /* Determine if a two byte length is required.  */
15674         if (object_data -> nx_snmp_object_octet_string_size >= 128)
15675         {
15676 
15677             /* A two byte length is required.  */
15678 
15679             /* Set the two byte length.  */
15680             *buffer_ptr++ =  0x82;
15681 
15682             /* Check for the end of the buffer.  */
15683             if (buffer_ptr >= buffer_end)
15684                 return(0);
15685 
15686             /* Set the first byte of the length.  */
15687             *buffer_ptr++ =  (UCHAR) (object_data -> nx_snmp_object_octet_string_size >> 8);
15688 
15689             /* Check for the end of the buffer.  */
15690             if (buffer_ptr >= buffer_end)
15691                 return(0);
15692 
15693             /* Set the second byte of the length.  */
15694             *buffer_ptr++ =  (UCHAR) (object_data -> nx_snmp_object_octet_string_size & 0xFF);
15695 
15696             /* Check for the end of the buffer.  */
15697             if (buffer_ptr >= buffer_end)
15698                 return(0);
15699 
15700             /* Set the length to represent the 4 byte header.  */
15701             length =  4;
15702         }
15703         else
15704         {
15705 
15706             /* Set the length byte.  */
15707             *buffer_ptr++ =  (UCHAR) (object_data -> nx_snmp_object_octet_string_size & 0xFF);
15708 
15709             /* Check for the end of the buffer.  */
15710             if (buffer_ptr >= buffer_end)
15711                 return(0);
15712 
15713             /* Set the length to represent the 2 byte header.  */
15714             length =  2;
15715         }
15716 
15717         /* Loop to process the string.  */
15718         i =  0;
15719         while (i < object_data -> nx_snmp_object_octet_string_size)
15720         {
15721 
15722             /* Check for the end of the buffer.  */
15723             if (buffer_ptr >= buffer_end)
15724                 return(0);
15725 
15726             /* Place octet string into buffer.  */
15727             *buffer_ptr++ =  object_data -> nx_snmp_object_octet_string[i++];
15728         }
15729 
15730         /* Account for the leading bytes in the length.  */
15731         length =  length + i;
15732     }
15733 
15734     else if (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_OBJECT_ID)
15735     {
15736 
15737         /* Call the object set routine.  */
15738         length = _nx_snmp_utility_object_id_set(buffer_ptr, object_data -> nx_snmp_object_octet_string, buffer_end);
15739     }
15740     else
15741     {
15742 
15743         /* Unhandled, return an error by setting length to 0.  */
15744         length =  0;
15745     }
15746 
15747     /* Return the length.  */
15748     return(length);
15749 }
15750 
15751 
15752 /**************************************************************************/
15753 /*                                                                        */
15754 /*  FUNCTION                                               RELEASE        */
15755 /*                                                                        */
15756 /*    _nx_snmp_utility_octet_get                          PORTABLE C      */
15757 /*                                                           6.1          */
15758 /*  AUTHOR                                                                */
15759 /*                                                                        */
15760 /*    Yuxin Zhou, Microsoft Corporation                                   */
15761 /*                                                                        */
15762 /*  DESCRIPTION                                                           */
15763 /*                                                                        */
15764 /*    This function retrieves the octet string from the supplied ASN.1    */
15765 /*    buffer.                                                             */
15766 /*                                                                        */
15767 /*  INPUT                                                                 */
15768 /*                                                                        */
15769 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
15770 /*    octet_string                          Pointer to destination for    */
15771 /*                                            the octet string            */
15772 /*    max_octet_length                      Size of octet string buffer   */
15773 /*    octet_length                          Pointer to length for octet   */
15774 /*                                            string                      */
15775 /*    buffer_length                         Size of input buffer          */
15776 /*                                                                        */
15777 /*  OUTPUT                                                                */
15778 /*                                                                        */
15779 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
15780 /*                                            value of zero implies error */
15781 /*                                                                        */
15782 /*  CALLS                                                                 */
15783 /*                                                                        */
15784 /*    None                                                                */
15785 /*                                                                        */
15786 /*  CALLED BY                                                             */
15787 /*                                                                        */
15788 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
15789 /*                                                                        */
15790 /*  RELEASE HISTORY                                                       */
15791 /*                                                                        */
15792 /*    DATE              NAME                      DESCRIPTION             */
15793 /*                                                                        */
15794 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
15795 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
15796 /*                                            resulting in version 6.1    */
15797 /*                                                                        */
15798 /**************************************************************************/
_nx_snmp_utility_octet_get(UCHAR * buffer_ptr,UCHAR * octet_string,UINT max_octet_length,UINT * octet_length,INT buffer_length)15799 UINT  _nx_snmp_utility_octet_get(UCHAR *buffer_ptr, UCHAR *octet_string, UINT max_octet_length, UINT *octet_length, INT buffer_length)
15800 {
15801 
15802 UINT    i;
15803 UINT    length;
15804 UINT    total;
15805 
15806 
15807     /* Buffer size must be at least 2 bytes. */
15808     if (buffer_length < 2)
15809     {
15810         return(0);
15811     }
15812 
15813     /* Set the octet length to zero.  */
15814     *octet_length =  0;
15815 
15816     /* First see if the ANS1 string type is present.  */
15817     if (buffer_ptr[0] != NX_SNMP_ANS1_OCTET_STRING)
15818     {
15819 
15820         /* Return a zero length.  */
15821         return(0);
15822     }
15823 
15824     /* Determine if a two byte length is present.  */
15825     if (*(buffer_ptr + 1) & NX_SNMP_ANS1_MULTI_BYTES)
15826     {
15827 
15828     UINT temp = *(buffer_ptr + 1) & 0x7F;
15829 
15830         if (temp == 2)
15831         {
15832 
15833             /* A two byte length is present.  */
15834 
15835             /* Check the buffer length.  */
15836             if (buffer_length < 4)
15837             {
15838                 return(0);
15839             }
15840 
15841             /* Pickup the length.  */
15842             total =  (((UINT) buffer_ptr[2]) << 8) | ((UINT) buffer_ptr[3]);
15843 
15844             /* Move the buffer pointer forward.  */
15845             buffer_ptr =  buffer_ptr + 4;
15846 
15847             /* Initialize the length.  */
15848             length =  4;
15849         }
15850         else if (temp == 1)
15851         {
15852 
15853             /* Check the buffer length.  */
15854             if (buffer_length < 3)
15855             {
15856                 return(0);
15857             }
15858 
15859             /* Otherwise, pickup the total length of the octet string.  */
15860             total =  (UINT) buffer_ptr[2];
15861 
15862             /* Move the buffer pointer forward.  */
15863             buffer_ptr =  buffer_ptr + 3;
15864 
15865             /* Initialize the length.  */
15866             length =  3;
15867         }
15868         else
15869         {
15870 
15871             /* Invalid sequence. Too big or null size type. */
15872             return(0);
15873         }
15874     }
15875     else
15876     {
15877 
15878         /* Otherwise, assume 1 byte. Pickup the total length of the octet string.  */
15879         total =  (UINT) buffer_ptr[1];
15880 
15881         /* Move the buffer pointer forward.  */
15882         buffer_ptr =  buffer_ptr + 2;
15883 
15884         /* Initialize the length.  */
15885         length =  2;
15886     }
15887 
15888     /* Check for invalid buffer size. */
15889     if ((INT)(length + total) > buffer_length)
15890     {
15891         /* Indicate an invalid request or packet is received. */
15892         return 0;
15893     }
15894 
15895     /* Determine if the octet string is too large.  */
15896     if (total > max_octet_length)
15897     {
15898 
15899         /* Yes, the octet string is too large. Return an error.  */
15900         return(0);
15901     }
15902 
15903     /* Loop to pickup the remaining characters in the community string.  */
15904     for (i = 0; i < total; i++)
15905     {
15906 
15907         /* Move character from buffer into community string.  */
15908         *octet_string++ =  *buffer_ptr++;
15909 
15910         /* Adjust the length.  */
15911         length++;
15912     }
15913 
15914     /* return the length of the octet string.  */
15915     *octet_length =  total;
15916 
15917     /* Return the length of the ANS1 string.  */
15918     return(length);
15919 }
15920 
15921 
15922 /**************************************************************************/
15923 /*                                                                        */
15924 /*  FUNCTION                                               RELEASE        */
15925 /*                                                                        */
15926 /*    _nx_snmp_utility_octet_set                          PORTABLE C      */
15927 /*                                                           6.1          */
15928 /*  AUTHOR                                                                */
15929 /*                                                                        */
15930 /*    Yuxin Zhou, Microsoft Corporation                                   */
15931 /*                                                                        */
15932 /*  DESCRIPTION                                                           */
15933 /*                                                                        */
15934 /*    This function places the supplied octet string into the ASN.1       */
15935 /*    buffer.                                                             */
15936 /*                                                                        */
15937 /*  INPUT                                                                 */
15938 /*                                                                        */
15939 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
15940 /*    octet_string                          Pointer to octet string       */
15941 /*    octet_length                          Length of the octet string    */
15942 /*    buffer_end                            End of buffer                 */
15943 /*                                                                        */
15944 /*  OUTPUT                                                                */
15945 /*                                                                        */
15946 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
15947 /*                                            value of zero implies error */
15948 /*                                                                        */
15949 /*  CALLS                                                                 */
15950 /*                                                                        */
15951 /*    None                                                                */
15952 /*                                                                        */
15953 /*  CALLED BY                                                             */
15954 /*                                                                        */
15955 /*    _nx_snmp_agent_trapv3_send            Send SNMP v3 trap             */
15956 /*    _nx_snmp_version_3_report_send        Send SNMP v3 report           */
15957 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
15958 /*                                                                        */
15959 /*  RELEASE HISTORY                                                       */
15960 /*                                                                        */
15961 /*    DATE              NAME                      DESCRIPTION             */
15962 /*                                                                        */
15963 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
15964 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
15965 /*                                            resulting in version 6.1    */
15966 /*                                                                        */
15967 /**************************************************************************/
_nx_snmp_utility_octet_set(UCHAR * buffer_ptr,UCHAR * octet_string,UINT octet_length,UCHAR * buffer_end)15968 UINT  _nx_snmp_utility_octet_set(UCHAR *buffer_ptr, UCHAR *octet_string, UINT octet_length, UCHAR *buffer_end)
15969 {
15970 
15971 UINT    i;
15972 UINT    header_size;
15973 
15974 
15975     /* Check for the end of the buffer.  */
15976     if (buffer_ptr >= buffer_end)
15977         return(0);
15978 
15979     /* First, set the OCTET byte.  */
15980     *buffer_ptr++ =  NX_SNMP_ANS1_OCTET_STRING;
15981 
15982     /* Check for a length greater than the maximum.  */
15983     if (octet_length > NX_SNMP_MAX_OCTET_STRING)
15984     {
15985 
15986         /* Error, octet string is too large.  */
15987         return(0);
15988     }
15989 
15990     /* Determine if a two byte length is required.  */
15991     if (octet_length >= 128)
15992     {
15993 
15994         /* Check for the end of the buffer.  */
15995         if ((UINT)(buffer_end - buffer_ptr) < (3 + octet_length))
15996             return(0);
15997 
15998         /* Set the two byte length flag.  */
15999         *buffer_ptr++ =  (UCHAR) 0x82;
16000 
16001         /* Set the first length byte.  */
16002         *buffer_ptr++ =  (UCHAR) (octet_length >> 8);
16003 
16004         /* Set the second length byte.  */
16005         *buffer_ptr++ =  (UCHAR) (octet_length & 0xFF);
16006 
16007         /* Set the header size. */
16008         header_size =  4;
16009     }
16010     else
16011     {
16012 
16013         /* Check for the end of the buffer.  */
16014         if ((UINT)(buffer_end - buffer_ptr) < (1 + octet_length))
16015             return(0);
16016 
16017         /* Next set the length byte.  */
16018         *buffer_ptr++ =  (UCHAR) octet_length;
16019 
16020         /* Set the header size. */
16021         header_size =  2;
16022     }
16023 
16024     /* Loop to store rest of the community string.  */
16025     for (i = 0; i < octet_length; i++)
16026     {
16027 
16028         /* Store the SNMP octet string.  */
16029         *buffer_ptr++ =  (UCHAR) octet_string[i];
16030     }
16031 
16032     /* Return the length of the community string.  */
16033     return(octet_length+header_size);
16034 }
16035 
16036 
16037 /**************************************************************************/
16038 /*                                                                        */
16039 /*  FUNCTION                                               RELEASE        */
16040 /*                                                                        */
16041 /*    _nx_snmp_utility_sequence_get                       PORTABLE C      */
16042 /*                                                           6.1          */
16043 /*  AUTHOR                                                                */
16044 /*                                                                        */
16045 /*    Yuxin Zhou, Microsoft Corporation                                   */
16046 /*                                                                        */
16047 /*  DESCRIPTION                                                           */
16048 /*                                                                        */
16049 /*    This function retrieves the ASN.1 sequence from the supplied ASN.1  */
16050 /*    buffer.                                                             */
16051 /*                                                                        */
16052 /*  INPUT                                                                 */
16053 /*                                                                        */
16054 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
16055 /*    sequence_value                        Pointer to destination for    */
16056 /*                                            the sequence value          */
16057 /*    buffer_length                         Size of buffer data           */
16058 /*                                                                        */
16059 /*  OUTPUT                                                                */
16060 /*                                                                        */
16061 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
16062 /*                                            value of zero implies error */
16063 /*                                                                        */
16064 /*  CALLS                                                                 */
16065 /*                                                                        */
16066 /*    None                                                                */
16067 /*                                                                        */
16068 /*  CALLED BY                                                             */
16069 /*                                                                        */
16070 /*    _nx_snmp_agent_thread_entry           SNMP Agent's thread entry     */
16071 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
16072 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
16073 /*                                                                        */
16074 /*  RELEASE HISTORY                                                       */
16075 /*                                                                        */
16076 /*    DATE              NAME                      DESCRIPTION             */
16077 /*                                                                        */
16078 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
16079 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
16080 /*                                            resulting in version 6.1    */
16081 /*                                                                        */
16082 /**************************************************************************/
_nx_snmp_utility_sequence_get(UCHAR * buffer_ptr,UINT * sequence_value,INT buffer_length)16083 UINT  _nx_snmp_utility_sequence_get(UCHAR *buffer_ptr, UINT *sequence_value, INT buffer_length)
16084 {
16085 
16086 UINT    i;
16087 UINT    length;
16088 UINT    value;
16089 UINT    total;
16090 UCHAR   byte;
16091 
16092 
16093     /* Buffer size must be at least 2 bytes. */
16094     if (buffer_length < 2)
16095     {
16096         return(0);
16097     }
16098 
16099     /* First, pickup the sequence byte.  */
16100     byte =  *buffer_ptr++;
16101 
16102     /* Determine if the byte is a sequence byte (0x30).  */
16103     if (byte != NX_SNMP_ANS1_SEQUENCE)
16104     {
16105 
16106         /* Error, not a sequence byte, return a NULL.  */
16107         *sequence_value =  0;
16108         return(0);
16109     }
16110 
16111     /* Otherwise, we have a valid sequence byte.  */
16112 
16113     /* Pickup next byte.  */
16114     byte =  *buffer_ptr++;
16115 
16116     /* Initialize the length of the sequence field to 2. */
16117     length =  2;
16118 
16119     /* Determine if the next byte has the additional bytes
16120        bit set (BIT 7).  */
16121     if ((byte & NX_SNMP_ANS1_MULTI_BYTES) == 0)
16122     {
16123 
16124         /* The specified sequence value is less than 128 and is actually in this byte!  */
16125         *sequence_value =  (UINT) byte;
16126 
16127         /* Return the actual length of the ANS1 sequence string.  */
16128         return(length);
16129     }
16130 
16131     /* Otherwise, we have a more complicated sequence length that we must loop through
16132        to calculate the actual sequence length.  */
16133 
16134     /* Pickup the number of bytes required to represent the sequence length.  */
16135     total =  (UINT) (byte & ~NX_SNMP_ANS1_MULTI_BYTES);
16136 
16137     /* Check for invalid buffer size. */
16138     if ((INT)(length + total) > buffer_length)
16139     {
16140         /* Indicate an invalid request or packet is received. */
16141         return 0;
16142     }
16143 
16144     value =  0;
16145 
16146     /* Loop through the remaining sequence bytes.  */
16147     for (i = 0; i < total; i++)
16148     {
16149 
16150         /* Pickup next byte.  */
16151         byte =  *buffer_ptr++;
16152 
16153         /* Compute the sequence based on the next value.  */
16154         value =  (value << 8) | ((UINT) byte);
16155 
16156         /* Increment the length.  */
16157         length++;
16158     }
16159 
16160     /* Return the calculated sequence value.  */
16161     *sequence_value =  value;
16162 
16163     /* Return the length of the sequence string.  */
16164     return(length);
16165 }
16166 
16167 
16168 /**************************************************************************/
16169 /*                                                                        */
16170 /*  FUNCTION                                               RELEASE        */
16171 /*                                                                        */
16172 /*    _nx_snmp_utility_sequence_set                       PORTABLE C      */
16173 /*                                                           6.1          */
16174 /*  AUTHOR                                                                */
16175 /*                                                                        */
16176 /*    Yuxin Zhou, Microsoft Corporation                                   */
16177 /*                                                                        */
16178 /*  DESCRIPTION                                                           */
16179 /*                                                                        */
16180 /*    This function places the sequence number into the ASN.1             */
16181 /*    buffer.                                                             */
16182 /*                                                                        */
16183 /*  INPUT                                                                 */
16184 /*                                                                        */
16185 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
16186 /*    sequence_value                        Sequence value                */
16187 /*    buffer_end                            End of buffer                 */
16188 /*                                                                        */
16189 /*  OUTPUT                                                                */
16190 /*                                                                        */
16191 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
16192 /*                                            value of zero implies error */
16193 /*                                                                        */
16194 /*  CALLS                                                                 */
16195 /*                                                                        */
16196 /*    None                                                                */
16197 /*                                                                        */
16198 /*  CALLED BY                                                             */
16199 /*                                                                        */
16200 /*    _nx_snmp_agent_trap_send              Send SNMP v1 trap             */
16201 /*    _nx_snmp_agent_trapv2_send            Send SNMP v2 trap             */
16202 /*    _nx_snmp_agent_trapv3_send            Send SNMP v3 trap             */
16203 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
16204 /*    _nx_snmp_version_3_report_send        Send SNMP v3 report           */
16205 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
16206 /*                                                                        */
16207 /*  RELEASE HISTORY                                                       */
16208 /*                                                                        */
16209 /*    DATE              NAME                      DESCRIPTION             */
16210 /*                                                                        */
16211 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
16212 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
16213 /*                                            resulting in version 6.1    */
16214 /*                                                                        */
16215 /**************************************************************************/
_nx_snmp_utility_sequence_set(UCHAR * buffer_ptr,UINT sequence_value,UCHAR * buffer_end)16216 UINT  _nx_snmp_utility_sequence_set(UCHAR *buffer_ptr, UINT sequence_value, UCHAR *buffer_end)
16217 {
16218 
16219     /* Check for the end of the buffer.  */
16220     if ((UINT)(buffer_end - buffer_ptr) < 4)
16221         return(0);
16222 
16223     /* First, set the sequence byte.  */
16224     *buffer_ptr++ =  NX_SNMP_ANS1_SEQUENCE;
16225 
16226     /* Next set the continue bit to force two additional bytes for length.  */
16227     *buffer_ptr++ =  ((UCHAR) 2) | NX_SNMP_ANS1_MULTI_BYTES;
16228 
16229     /* Store the MSB.  */
16230     *buffer_ptr++ =  (UCHAR) ((sequence_value >> 8) & 0xFF);
16231 
16232     /* Store the LSB.  */
16233     *buffer_ptr =  (UCHAR) (sequence_value & 0xFF);
16234 
16235     /* Return the length of the sequence string.  */
16236     return(4);
16237 }
16238 
16239 
16240 /**************************************************************************/
16241 /*                                                                        */
16242 /*  FUNCTION                                               RELEASE        */
16243 /*                                                                        */
16244 /*    _nx_snmp_utility_sequence_set_1byte                 PORTABLE C      */
16245 /*                                                           6.1          */
16246 /*  AUTHOR                                                                */
16247 /*                                                                        */
16248 /*    Yuxin Zhou, Microsoft Corporation                                   */
16249 /*                                                                        */
16250 /*  DESCRIPTION                                                           */
16251 /*                                                                        */
16252 /*    This function places the sequence number into the ASN.1             */
16253 /*    buffer.  The difference with  _nx_snmp_utility_sequence_set is that */
16254 /*    this uses only a single byte length field e.g. 0x30 xx instead of   */
16255 /*    0x30 0x82 xx yy where xx(yy) is the sequence length (1 vs 2 bytes). */
16256 /*                                                                        */
16257 /*  INPUT                                                                 */
16258 /*                                                                        */
16259 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
16260 /*    sequence_value                        Sequence value                */
16261 /*    buffer_end                            End of buffer                 */
16262 /*                                                                        */
16263 /*  OUTPUT                                                                */
16264 /*                                                                        */
16265 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
16266 /*                                            value of zero implies error */
16267 /*                                                                        */
16268 /*  CALLS                                                                 */
16269 /*                                                                        */
16270 /*    None                                                                */
16271 /*                                                                        */
16272 /*  CALLED BY                                                             */
16273 /*                                                                        */
16274 /*    _nx_snmp_version_3_report_send        Send SNMP v3 report           */
16275 /*                                                                        */
16276 /*  RELEASE HISTORY                                                       */
16277 /*                                                                        */
16278 /*    DATE              NAME                      DESCRIPTION             */
16279 /*                                                                        */
16280 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
16281 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
16282 /*                                            resulting in version 6.1    */
16283 /*                                                                        */
16284 /**************************************************************************/
16285 
_nx_snmp_utility_sequence_set_1byte(UCHAR * buffer_ptr,UINT sequence_value,UCHAR * buffer_end)16286 UINT  _nx_snmp_utility_sequence_set_1byte(UCHAR *buffer_ptr, UINT sequence_value, UCHAR *buffer_end)
16287 {
16288 
16289     /* Check for the end of the buffer.  */
16290     if ((UINT)(buffer_end - buffer_ptr) < 2)
16291         return(0);
16292 
16293     /* First, set the sequence byte.  */
16294     *buffer_ptr++ =  NX_SNMP_ANS1_SEQUENCE;
16295 
16296     /* Store the value.  */
16297     *buffer_ptr =  (UCHAR) (sequence_value & 0xFF);
16298 
16299     /* Return the length of the sequence string.  */
16300     return(2);
16301 }
16302 
16303 
16304 /**************************************************************************/
16305 /*                                                                        */
16306 /*  FUNCTION                                               RELEASE        */
16307 /*                                                                        */
16308 /*    _nx_snmp_utility_request_id_get                     PORTABLE C      */
16309 /*                                                           6.1          */
16310 /*  AUTHOR                                                                */
16311 /*                                                                        */
16312 /*    Yuxin Zhou, Microsoft Corporation                                   */
16313 /*                                                                        */
16314 /*  DESCRIPTION                                                           */
16315 /*                                                                        */
16316 /*    This function retrieves the ASN.1 request ID from the supplied      */
16317 /*    ASN.1 buffer.                                                       */
16318 /*                                                                        */
16319 /*  INPUT                                                                 */
16320 /*                                                                        */
16321 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
16322 /*    request_id                            Pointer to destination for    */
16323 /*                                            the request ID              */
16324 /*    buffer_length                         Size of buffer                */
16325 /*                                                                        */
16326 /*  OUTPUT                                                                */
16327 /*                                                                        */
16328 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
16329 /*                                            value of zero implies error */
16330 /*                                                                        */
16331 /*  CALLS                                                                 */
16332 /*                                                                        */
16333 /*    None                                                                */
16334 /*                                                                        */
16335 /*  CALLED BY                                                             */
16336 /*                                                                        */
16337 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
16338 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
16339 /*                                                                        */
16340 /*  RELEASE HISTORY                                                       */
16341 /*                                                                        */
16342 /*    DATE              NAME                      DESCRIPTION             */
16343 /*                                                                        */
16344 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
16345 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
16346 /*                                            resulting in version 6.1    */
16347 /*                                                                        */
16348 /**************************************************************************/
_nx_snmp_utility_request_id_get(UCHAR * buffer_ptr,ULONG * request_id,INT buffer_length)16349 UINT  _nx_snmp_utility_request_id_get(UCHAR *buffer_ptr, ULONG *request_id, INT buffer_length)
16350 {
16351 
16352 UINT    i;
16353 UINT    length;
16354 ULONG   value;
16355 UINT    total;
16356 UCHAR   byte;
16357 
16358 
16359     /* Buffer size must be at least 2 bytes. */
16360     if (buffer_length < 2)
16361     {
16362         return(0);
16363     }
16364 
16365     /* First, pickup the request byte.  */
16366     byte =  *buffer_ptr++;
16367 
16368     /* Determine if the byte is a valid SNMP request type.  */
16369     if (byte != NX_SNMP_ANS1_INTEGER)
16370     {
16371 
16372         /* Error, not request id, return a NULL.  */
16373         *request_id =    0;
16374         return(0);
16375     }
16376 
16377     /* Otherwise, we have a valid request id.  */
16378 
16379     /* Pickup the ANS1 length byte.  */
16380     total =  (UINT) *buffer_ptr++;
16381 
16382     /* Initialize the length of the request field to 2. */
16383     length =  2;
16384 
16385     /* Check the length specified in the buffer against buffer size. */
16386     if ((INT)(length + total) > buffer_length)
16387     {
16388         *request_id = 0;
16389         return(0);
16390     }
16391 
16392     /* Initialize working request length.  */
16393     value =  0;
16394 
16395     /* Loop through the remaining request length bytes.  */
16396     for (i = 0; i < total; i++)
16397     {
16398 
16399         /* Pickup next byte.  */
16400         byte =  *buffer_ptr++;
16401 
16402         /* Compute the request id based on the next value.  */
16403         value =  (value << 8) | ((ULONG) byte);
16404 
16405         /* Increment the length.  */
16406         length++;
16407     }
16408 
16409     /* Return the calculated request id.  */
16410     *request_id =  value;
16411 
16412     /* Return the length of the request id string.  */
16413     return(length);
16414 }
16415 
16416 
16417 /**************************************************************************/
16418 /*                                                                        */
16419 /*  FUNCTION                                               RELEASE        */
16420 /*                                                                        */
16421 /*    _nx_snmp_utility_request_id_set                     PORTABLE C      */
16422 /*                                                           6.1          */
16423 /*  AUTHOR                                                                */
16424 /*                                                                        */
16425 /*    Yuxin Zhou, Microsoft Corporation                                   */
16426 /*                                                                        */
16427 /*  DESCRIPTION                                                           */
16428 /*                                                                        */
16429 /*    This function places the request ID into the ASN.1 buffer.          */
16430 /*                                                                        */
16431 /*  INPUT                                                                 */
16432 /*                                                                        */
16433 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
16434 /*    request_id                            Request ID                    */
16435 /*    buffer_end                            End of buffer                 */
16436 /*                                                                        */
16437 /*  OUTPUT                                                                */
16438 /*                                                                        */
16439 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
16440 /*                                            value of zero implies error */
16441 /*                                                                        */
16442 /*  CALLS                                                                 */
16443 /*                                                                        */
16444 /*    None                                                                */
16445 /*                                                                        */
16446 /*  CALLED BY                                                             */
16447 /*                                                                        */
16448 /*    _nx_snmp_agent_trapv2_send            Send SNMP v2 trap             */
16449 /*    _nx_snmp_agent_trapv3_send            Send SNMP v3 trap             */
16450 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
16451 /*    _nx_snmp_version_3_report_send        Send SNMP v3 report           */
16452 /*    _nx_snmp_version_3_report_send        Send SNMP v3 report           */
16453 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
16454 /*                                                                        */
16455 /*  RELEASE HISTORY                                                       */
16456 /*                                                                        */
16457 /*    DATE              NAME                      DESCRIPTION             */
16458 /*                                                                        */
16459 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
16460 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
16461 /*                                            resulting in version 6.1    */
16462 /*                                                                        */
16463 /**************************************************************************/
_nx_snmp_utility_request_id_set(UCHAR * buffer_ptr,ULONG request_id,UCHAR * buffer_end)16464 UINT  _nx_snmp_utility_request_id_set(UCHAR *buffer_ptr, ULONG request_id, UCHAR *buffer_end)
16465 {
16466 
16467 UINT    length;
16468 
16469 
16470     /* Check for the end of the buffer.  */
16471     if (buffer_ptr >= buffer_end)
16472         return(0);
16473 
16474     /* First, set the INTEGER byte.  */
16475     *buffer_ptr++ =  NX_SNMP_ANS1_INTEGER;
16476 
16477     /* Determine how big the ID is.  */
16478     if ((request_id & 0xFF000000UL) || (request_id & 0x00800000))
16479     {
16480 
16481         /* Check for the end of the buffer.  */
16482         if ((UINT)(buffer_end - buffer_ptr) < 5)
16483             return(0);
16484 
16485         /* Next set the length byte.  */
16486         *buffer_ptr++ =  (UCHAR) 4;
16487 
16488         /* Set the request ID in successive bytes.  */
16489         *buffer_ptr++ =  (UCHAR) ((request_id >> 24) & 0xFF);
16490         *buffer_ptr++ =  (UCHAR) ((request_id >> 16) & 0xFF);
16491         *buffer_ptr++ =  (UCHAR) ((request_id >> 8)  & 0xFF);
16492         *buffer_ptr++ =  (UCHAR)  (request_id & 0xFF);
16493 
16494         /* Update the length.  */
16495         length =  6;
16496     }
16497     else if ((request_id & 0x00FF0000UL) || (request_id & 0x00008000))
16498     {
16499 
16500         /* Check for the end of the buffer.  */
16501         if ((UINT)(buffer_end - buffer_ptr) < 4)
16502             return(0);
16503 
16504         /* Next set the length byte.  */
16505         *buffer_ptr++ =  (UCHAR) 3;
16506 
16507         /* Set the request ID in successive bytes.  */
16508         *buffer_ptr++ =  (UCHAR) ((request_id >> 16) & 0xFF);
16509         *buffer_ptr++ =  (UCHAR) ((request_id >> 8)  & 0xFF);
16510         *buffer_ptr++ =  (UCHAR)  (request_id & 0xFF);
16511 
16512         /* Update the length.  */
16513         length =  5;
16514     }
16515     else if ((request_id & 0x0000FF00UL) || (request_id & 0x00000080))
16516     {
16517 
16518         /* Check for the end of the buffer.  */
16519         if ((UINT)(buffer_end - buffer_ptr) < 3)
16520             return(0);
16521 
16522         /* Next set the length byte.  */
16523         *buffer_ptr++ =  (UCHAR) 2;
16524 
16525         /* Set the request ID in successive bytes.  */
16526         *buffer_ptr++ =  (UCHAR) ((request_id >> 8)  & 0xFF);
16527         *buffer_ptr++ =  (UCHAR)  (request_id & 0xFF);
16528 
16529         /* Update the length.  */
16530         length =  4;
16531     }
16532     else
16533     {
16534 
16535         /* Check for the end of the buffer.  */
16536         if ((UINT)(buffer_end - buffer_ptr) < 2)
16537             return(0);
16538 
16539         /* Next set the length byte.  */
16540         *buffer_ptr++ =  (UCHAR) 1;
16541 
16542         /* Set the request ID in successive bytes.  */
16543         *buffer_ptr++ =  (UCHAR)  (request_id & 0xFF);
16544 
16545         /* Update the length.  */
16546         length =  3;
16547     }
16548 
16549     /* Return the length of the request ID.  */
16550     return(length);
16551 }
16552 
16553 
16554 /**************************************************************************/
16555 /*                                                                        */
16556 /*  FUNCTION                                               RELEASE        */
16557 /*                                                                        */
16558 /*    _nx_snmp_utility_request_type_get                   PORTABLE C      */
16559 /*                                                           6.1          */
16560 /*  AUTHOR                                                                */
16561 /*                                                                        */
16562 /*    Yuxin Zhou, Microsoft Corporation                                   */
16563 /*                                                                        */
16564 /*  DESCRIPTION                                                           */
16565 /*                                                                        */
16566 /*    This function retrieves the ASN.1 request type from the supplied    */
16567 /*    ASN.1 buffer.                                                       */
16568 /*                                                                        */
16569 /*  INPUT                                                                 */
16570 /*                                                                        */
16571 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
16572 /*    request_type                          Pointer to destination for    */
16573 /*                                            the request type            */
16574 /*    request_length                        Pointer to destination for    */
16575 /*                                            the request length          */
16576 /*    buffer_length                         Size of input buffer          */
16577 /*                                                                        */
16578 /*  OUTPUT                                                                */
16579 /*                                                                        */
16580 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
16581 /*                                            value of zero implies error */
16582 /*                                                                        */
16583 /*  CALLS                                                                 */
16584 /*                                                                        */
16585 /*    None                                                                */
16586 /*                                                                        */
16587 /*  CALLED BY                                                             */
16588 /*                                                                        */
16589 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
16590 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
16591 /*                                                                        */
16592 /*  RELEASE HISTORY                                                       */
16593 /*                                                                        */
16594 /*    DATE              NAME                      DESCRIPTION             */
16595 /*                                                                        */
16596 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
16597 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
16598 /*                                            resulting in version 6.1    */
16599 /*                                                                        */
16600 /**************************************************************************/
_nx_snmp_utility_request_type_get(UCHAR * buffer_ptr,UINT * request_type,UINT * request_length,INT buffer_length)16601 UINT  _nx_snmp_utility_request_type_get(UCHAR *buffer_ptr, UINT *request_type, UINT *request_length, INT buffer_length)
16602 {
16603 
16604 UINT    i;
16605 UINT    length;
16606 UINT    value;
16607 UINT    total;
16608 UCHAR   byte;
16609 
16610 
16611     /* Buffer size must be at least 2 bytes. */
16612     if (buffer_length < 2)
16613     {
16614         return(0);
16615     }
16616 
16617     /* First, pickup the request byte.  */
16618     byte =  *buffer_ptr++;
16619 
16620     /* Determine if the byte is a valid SNMP request type.  */
16621     if ((byte < NX_SNMP_ANS1_SEQUENCE) || (byte > NX_SNMP_ANS1_TRAP2_REQUEST))
16622     {
16623 
16624         /* Error, not request, return a NULL.  */
16625         *request_type =    0;
16626         *request_length =  0;
16627         return(0);
16628     }
16629 
16630     /* Otherwise, we have a valid request.  */
16631 
16632     /* Store the request in the destination.  */
16633     *request_type =  (UINT) byte;
16634 
16635     /* Pickup next byte.  */
16636     byte =  *buffer_ptr++;
16637 
16638     /* Initialize the length of the request field to 2. */
16639     length =  2;
16640 
16641     /* Determine if the next byte has the additional bytes
16642        bit set (BIT 7).  */
16643     if ((byte & NX_SNMP_ANS1_MULTI_BYTES) == 0)
16644     {
16645 
16646         /* The specified request length is less than 128 and is actually in this byte!  */
16647         *request_length =  (UINT) byte;
16648 
16649         /* Return the actual length of the ANS1 request string.  */
16650         return(length);
16651     }
16652 
16653     /* Otherwise, we have a more complicated request length that we must loop through
16654        to calculate the actual length.  */
16655 
16656     /* Pickup the number of bytes required to represent the request length.  */
16657     total =  (UINT) (byte & ~NX_SNMP_ANS1_MULTI_BYTES);
16658 
16659     if ((INT)(length + total) > buffer_length)
16660     {
16661         /* Error, invalid request, return a NULL.  */
16662         *request_type =    0;
16663         *request_length =  0;
16664         return(0);
16665     }
16666 
16667     /* Initialize working request length.  */
16668     value =  0;
16669 
16670     /* Loop through the remaining request length bytes.  */
16671     for (i = 0; i < total; i++)
16672     {
16673 
16674         /* Pickup next byte.  */
16675         byte =  *buffer_ptr++;
16676 
16677         /* Compute the request length based on the next value.  */
16678         value =  (value << 8) | ((UINT) byte);
16679 
16680         /* Increment the length.  */
16681         length++;
16682     }
16683 
16684     /* Return the calculated request length.  */
16685     *request_length =  value;
16686 
16687     /* Return the length of the request string.  */
16688     return(length);
16689 }
16690 
16691 
16692 /**************************************************************************/
16693 /*                                                                        */
16694 /*  FUNCTION                                               RELEASE        */
16695 /*                                                                        */
16696 /*    _nx_snmp_utility_request_type_set_1byte             PORTABLE C      */
16697 /*                                                           6.1          */
16698 /*  AUTHOR                                                                */
16699 /*                                                                        */
16700 /*    Yuxin Zhou, Microsoft Corporation                                   */
16701 /*                                                                        */
16702 /*  DESCRIPTION                                                           */
16703 /*                                                                        */
16704 /*    This function places the request type into the ASN.1 buffer. It is  */
16705 /*    intended for small requests whose size value can fit into one byte. */
16706 /*                                                                        */
16707 /*  INPUT                                                                 */
16708 /*                                                                        */
16709 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
16710 /*    request_type                          Request type                  */
16711 /*    request_length                        Request length                */
16712 /*    buffer_end                            End of buffer                 */
16713 /*                                                                        */
16714 /*  OUTPUT                                                                */
16715 /*                                                                        */
16716 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
16717 /*                                            value of zero implies error */
16718 /*                                                                        */
16719 /*  CALLS                                                                 */
16720 /*                                                                        */
16721 /*    None                                                                */
16722 /*                                                                        */
16723 /*  CALLED BY                                                             */
16724 /*                                                                        */
16725 /*    _nx_snmp_agent_trap_send              Send SNMP v1 trap             */
16726 /*    _nx_snmp_agent_trapv2_send            Send SNMP v2 trap             */
16727 /*    _nx_snmp_agent_trapv3_send            Send SNMP v3 trap             */
16728 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
16729 /*    _nx_snmp_version_3_report_send        Send SNMP v3 report           */
16730 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
16731 /*                                                                        */
16732 /*  RELEASE HISTORY                                                       */
16733 /*                                                                        */
16734 /*    DATE              NAME                      DESCRIPTION             */
16735 /*                                                                        */
16736 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
16737 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
16738 /*                                            resulting in version 6.1    */
16739 /*                                                                        */
16740 /**************************************************************************/
_nx_snmp_utility_request_type_set_1byte(UCHAR * buffer_ptr,UINT request_type,UINT request_length,UCHAR * buffer_end)16741 UINT  _nx_snmp_utility_request_type_set_1byte(UCHAR *buffer_ptr, UINT request_type, UINT request_length, UCHAR *buffer_end)
16742 {
16743 
16744 
16745     /* Check for the end of the buffer.  */
16746     if ((UINT)(buffer_end - buffer_ptr) < 2)
16747         return(0);
16748 
16749     /* First, set the request type byte.  */
16750     *buffer_ptr++ =  (UCHAR) request_type;
16751 
16752     /* Store the request_length.  */
16753     *buffer_ptr =  (UCHAR) (request_length & 0xFF);
16754 
16755     return 2;
16756 
16757 }
16758 
16759 
16760 /**************************************************************************/
16761 /*                                                                        */
16762 /*  FUNCTION                                               RELEASE        */
16763 /*                                                                        */
16764 /*    _nx_snmp_utility_request_type_set_multibyte         PORTABLE C      */
16765 /*                                                           6.1          */
16766 /*  AUTHOR                                                                */
16767 /*                                                                        */
16768 /*    Yuxin Zhou, Microsoft Corporation                                   */
16769 /*                                                                        */
16770 /*  DESCRIPTION                                                           */
16771 /*                                                                        */
16772 /*    This function places the request type into the ASN.1 buffer. It is  */
16773 /*    intended for large requests whose size value requires more than one */
16774 /*    byte, e.g. A2 82 xx yy. For get, getnext requests, and report and   */
16775 /*    trap responses, use _nx_snmp_utility_request_type_set_1byte.        */
16776 /*                                                                        */
16777 /*  INPUT                                                                 */
16778 /*                                                                        */
16779 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
16780 /*    request_type                          Request type                  */
16781 /*    request_length                        Request length                */
16782 /*    buffer_end                            End of buffer                 */
16783 /*                                                                        */
16784 /*  OUTPUT                                                                */
16785 /*                                                                        */
16786 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
16787 /*                                            value of zero implies error */
16788 /*                                                                        */
16789 /*  CALLS                                                                 */
16790 /*                                                                        */
16791 /*    None                                                                */
16792 /*                                                                        */
16793 /*  CALLED BY                                                             */
16794 /*                                                                        */
16795 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
16796 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
16797 /*                                                                        */
16798 /*  RELEASE HISTORY                                                       */
16799 /*                                                                        */
16800 /*    DATE              NAME                      DESCRIPTION             */
16801 /*                                                                        */
16802 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
16803 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
16804 /*                                            resulting in version 6.1    */
16805 /*                                                                        */
16806 /**************************************************************************/
_nx_snmp_utility_request_type_set_multibyte(UCHAR * buffer_ptr,UINT request_type,UINT request_length,UCHAR * buffer_end)16807 UINT  _nx_snmp_utility_request_type_set_multibyte(UCHAR *buffer_ptr, UINT request_type, UINT request_length, UCHAR *buffer_end)
16808 {
16809 
16810     /* Check for the end of the buffer.  */
16811     if ((UINT)(buffer_end - buffer_ptr) < 4)
16812         return(0);
16813 
16814     /* First, set the request type byte.  */
16815     *buffer_ptr++ =  (UCHAR) request_type;
16816 
16817     /* Set the continue bit to force two additional bytes for length.  */
16818     *buffer_ptr++ =  ((UCHAR) 2) | NX_SNMP_ANS1_MULTI_BYTES;
16819 
16820     /* Store the MSB.  */
16821     *buffer_ptr++ =  (UCHAR) ((request_length >> 8) & 0xFF);
16822 
16823     /* Store the LSB.  */
16824     *buffer_ptr =  (UCHAR) (request_length & 0xFF);
16825 
16826     return 4;
16827 }
16828 
16829 
16830 
16831 /**************************************************************************/
16832 /*                                                                        */
16833 /*  FUNCTION                                               RELEASE        */
16834 /*                                                                        */
16835 /*    _nx_snmp_utility_version_get                        PORTABLE C      */
16836 /*                                                           6.1          */
16837 /*  AUTHOR                                                                */
16838 /*                                                                        */
16839 /*    Yuxin Zhou, Microsoft Corporation                                   */
16840 /*                                                                        */
16841 /*  DESCRIPTION                                                           */
16842 /*                                                                        */
16843 /*    This function retrieves the SNMP version from the supplied          */
16844 /*    ASN.1 buffer.                                                       */
16845 /*                                                                        */
16846 /*  INPUT                                                                 */
16847 /*                                                                        */
16848 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
16849 /*    snmp_version                          Pointer to destination for    */
16850 /*                                            the snmp_version            */
16851 /*    buffer_length                         Size of buffer data           */
16852 /*                                                                        */
16853 /*  OUTPUT                                                                */
16854 /*                                                                        */
16855 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
16856 /*                                            value of zero implies error */
16857 /*                                                                        */
16858 /*  CALLS                                                                 */
16859 /*                                                                        */
16860 /*    None                                                                */
16861 /*                                                                        */
16862 /*  CALLED BY                                                             */
16863 /*                                                                        */
16864 /*    _nx_snmp_agent_thread_entry           SNMP Agent's thread entry     */
16865 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
16866 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
16867 /*                                                                        */
16868 /*  RELEASE HISTORY                                                       */
16869 /*                                                                        */
16870 /*    DATE              NAME                      DESCRIPTION             */
16871 /*                                                                        */
16872 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
16873 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
16874 /*                                            resulting in version 6.1    */
16875 /*                                                                        */
16876 /**************************************************************************/
_nx_snmp_utility_version_get(UCHAR * buffer_ptr,UINT * snmp_version,INT buffer_length)16877 UINT  _nx_snmp_utility_version_get(UCHAR *buffer_ptr, UINT *snmp_version, INT buffer_length)
16878 {
16879 
16880     if (buffer_length < 3)
16881     {
16882 
16883         /* Clear the version.  */
16884         *snmp_version =  0;
16885 
16886         /* Return a zero length.  */
16887         return(0);
16888     }
16889 
16890     /* Determine if the version string is correct.  */
16891     if ((buffer_ptr[0] == NX_SNMP_ANS1_INTEGER) &&
16892         (buffer_ptr[1] == 1) &&
16893         ((buffer_ptr[2] == NX_SNMP_VERSION_1) || (buffer_ptr[2] == NX_SNMP_VERSION_2) ||
16894          (buffer_ptr[2] == NX_SNMP_VERSION_2C) || (buffer_ptr[2] == NX_SNMP_VERSION_3)))
16895     {
16896 
16897         /* Yes, the SNMP version string is correct.  */
16898 
16899         /* Return the version.  */
16900         *snmp_version =  (UINT) buffer_ptr[2];
16901 
16902         /* Return the length of the version string.  */
16903         return(3);
16904     }
16905     else
16906     {
16907 
16908         /* No, the SNMP version string is invalid.  */
16909 
16910         /* Clear the version.  */
16911         *snmp_version =  0;
16912 
16913         /* Return a zero length.  */
16914         return(0);
16915     }
16916 }
16917 
16918 
16919 /**************************************************************************/
16920 /*                                                                        */
16921 /*  FUNCTION                                               RELEASE        */
16922 /*                                                                        */
16923 /*    _nx_snmp_utility_version_set                        PORTABLE C      */
16924 /*                                                           6.1          */
16925 /*  AUTHOR                                                                */
16926 /*                                                                        */
16927 /*    Yuxin Zhou, Microsoft Corporation                                   */
16928 /*                                                                        */
16929 /*  DESCRIPTION                                                           */
16930 /*                                                                        */
16931 /*    This function places the SNMP version into the ASN.1 buffer.        */
16932 /*                                                                        */
16933 /*  INPUT                                                                 */
16934 /*                                                                        */
16935 /*    buffer_ptr                            Pointer to ASN.1 buffer       */
16936 /*    snmp_version                          SNMP version number           */
16937 /*    buffer_end                            End of buffer                 */
16938 /*                                                                        */
16939 /*  OUTPUT                                                                */
16940 /*                                                                        */
16941 /*    ASN.1 length                          Length of ASN.1 sequence, a   */
16942 /*                                            value of zero implies error */
16943 /*                                                                        */
16944 /*  CALLS                                                                 */
16945 /*                                                                        */
16946 /*    None                                                                */
16947 /*                                                                        */
16948 /*  CALLED BY                                                             */
16949 /*                                                                        */
16950 /*    _nx_snmp_agent_trap_send              Send SNMP v1 trap             */
16951 /*    _nx_snmp_agent_trapv2_send            Send SNMP v2 trap             */
16952 /*    _nx_snmp_agent_trapv3_send            Send SNMP v3 trap             */
16953 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
16954 /*    _nx_snmp_version_3_report_send        Send SNMP v3 report           */
16955 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
16956 /*                                                                        */
16957 /*  RELEASE HISTORY                                                       */
16958 /*                                                                        */
16959 /*    DATE              NAME                      DESCRIPTION             */
16960 /*                                                                        */
16961 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
16962 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
16963 /*                                            resulting in version 6.1    */
16964 /*                                                                        */
16965 /**************************************************************************/
_nx_snmp_utility_version_set(UCHAR * buffer_ptr,UINT snmp_version,UCHAR * buffer_end)16966 UINT  _nx_snmp_utility_version_set(UCHAR *buffer_ptr, UINT snmp_version, UCHAR *buffer_end)
16967 {
16968 
16969     /* Check for the end of the buffer.  */
16970     if ((UINT)(buffer_end - buffer_ptr) < 3)
16971         return(0);
16972 
16973     /* First, set the INTEGER byte.  */
16974     *buffer_ptr++ =  NX_SNMP_ANS1_INTEGER;
16975 
16976     /* Next set the length byte.  */
16977     *buffer_ptr++ =  (UCHAR) 1;
16978 
16979     /* Store the SNMP version.  */
16980     *buffer_ptr =  (UCHAR) (snmp_version & 0xFF);
16981 
16982     /* Return the length of the sequence string.  */
16983     return(3);
16984 }
16985 
16986 
16987 /**************************************************************************/
16988 /*                                                                        */
16989 /*  FUNCTION                                               RELEASE        */
16990 /*                                                                        */
16991 /*    _nx_snmp_version_error_response                     PORTABLE C      */
16992 /*                                                           6.1.6        */
16993 /*  AUTHOR                                                                */
16994 /*                                                                        */
16995 /*    Yuxin Zhou, Microsoft Corporation                                   */
16996 /*                                                                        */
16997 /*  DESCRIPTION                                                           */
16998 /*                                                                        */
16999 /*    This function places the error information into the SNMP Manager's  */
17000 /*    request packet and returns it to the manager.                       */
17001 /*                                                                        */
17002 /*  INPUT                                                                 */
17003 /*                                                                        */
17004 /*    agent_ptr                             Pointer to SNMP agent         */
17005 /*    packet_ptr                            Pointer to packet containing  */
17006 /*                                            the original SNMP request   */
17007 /*    request_type_ptr                      Pointer to place in ASN.1     */
17008 /*                                            buffer for the request type */
17009 /*    error_string_ptr                      Pointer to place in ASN.1     */
17010 /*                                            buffer to place error info  */
17011 /*    error_code                            Error code                    */
17012 /*    error_index                           Error index                   */
17013 /*                                                                        */
17014 /*  OUTPUT                                                                */
17015 /*                                                                        */
17016 /*    None                                                                */
17017 /*                                                                        */
17018 /*  CALLS                                                                 */
17019 /*                                                                        */
17020 /*    nx_packet_release                     Release the packet            */
17021 /*    nx_udp_socket_send                    Send the UDP packet           */
17022 /*    _nx_snmp_utility_error_info_set       Set the error information     */
17023 /*                                                                        */
17024 /*  CALLED BY                                                             */
17025 /*                                                                        */
17026 /*    _nx_snmp_version_1_and_2_process      Process SNMP v1 and v2 request*/
17027 /*    _nx_snmp_version_3_process            SNMP v3 message processing    */
17028 /*                                                                        */
17029 /*  RELEASE HISTORY                                                       */
17030 /*                                                                        */
17031 /*    DATE              NAME                      DESCRIPTION             */
17032 /*                                                                        */
17033 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
17034 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
17035 /*                                            resulting in version 6.1    */
17036 /*  04-02-2021     Yuxin Zhou               Modified comment(s), improved */
17037 /*                                            verification of encryption, */
17038 /*                                            resulting in version 6.1.6  */
17039 /*                                                                        */
17040 /**************************************************************************/
_nx_snmp_version_error_response(NX_SNMP_AGENT * agent_ptr,NX_PACKET * packet_ptr,UCHAR * request_type_ptr,UCHAR * error_string_ptr,UINT error_code,UINT error_index)17041 VOID  _nx_snmp_version_error_response(NX_SNMP_AGENT *agent_ptr, NX_PACKET *packet_ptr, UCHAR *request_type_ptr,
17042                                       UCHAR *error_string_ptr, UINT error_code, UINT error_index)
17043 {
17044 
17045 UINT    status = NX_SUCCESS;
17046 #ifndef NX_SNMP_DISABLE_V3
17047 ULONG   temp;
17048 #endif
17049 
17050     /* Increment the error counter.  */
17051     agent_ptr -> nx_snmp_agent_request_errors++;
17052 
17053     /* Determine which specific error counter to increment.  */
17054     switch(error_code)
17055     {
17056     case NX_SNMP_ERROR_TOOBIG:
17057         agent_ptr -> nx_snmp_agent_too_big_errors++;
17058         break;
17059     case NX_SNMP_ERROR_BADVALUE:
17060     case NX_SNMP_ERROR_WRONGVALUE:
17061     case NX_SNMP_ERROR_WRONGENCODING:
17062     case NX_SNMP_ERROR_WRONGTYPE:
17063     case NX_SNMP_ERROR_WRONGLENGTH:
17064     case NX_SNMP_ERROR_INCONSISTENTVALUE:
17065         agent_ptr -> nx_snmp_agent_bad_value_errors++;
17066         break;
17067     case NX_SNMP_ERROR_NOSUCHNAME:
17068     case NX_SNMP_ERROR_NOACCESS:
17069     case NX_SNMP_ERROR_NOTWRITABLE:
17070     case NX_SNMP_ERROR_NOCREATION:
17071     case NX_SNMP_ERROR_INCONSISTENTNAME:
17072     case NX_SNMP_ERROR_AUTHORIZATION:
17073         agent_ptr -> nx_snmp_agent_no_such_name_errors++;
17074         break;
17075     case NX_SNMP_ERROR_GENERAL:
17076     case NX_SNMP_ERROR_RESOURCEUNAVAILABLE:
17077     case NX_SNMP_ERROR_COMMITFAILED:
17078     case NX_SNMP_ERROR_UNDOFAILED:
17079         agent_ptr -> nx_snmp_agent_general_errors++;
17080         break;
17081     }
17082 
17083     /* Set the request type to get/response.  */
17084     *request_type_ptr =  (UCHAR) NX_SNMP_ANS1_GET_RESPONSE;
17085 
17086     /* Update the error string with the error code and the object index.  */
17087     _nx_snmp_utility_error_info_set(error_string_ptr, error_code, error_index, packet_ptr -> nx_packet_data_end);
17088 
17089 #ifndef NX_SNMP_DISABLE_V3
17090 
17091     if (agent_ptr -> nx_snmp_agent_current_version == NX_SNMP_VERSION_3)
17092     {
17093 
17094         /* Is the security set to encryption? */
17095         temp = (ULONG)agent_ptr -> nx_snmp_agent_v3_message_security_options;
17096         if (temp & NX_SNMP_SECURITY_PRIVACY)
17097         {
17098 
17099             /* Encrypt the PDU and setup the response to have an encryption header.  This
17100                will also compute our privacy parameter. */
17101             status = _nx_snmp_agent_encrypt_pdu(agent_ptr, NX_NULL, NX_NULL,
17102                                                 NX_NULL, NX_NULL,
17103                                                 NX_NULL, NX_NULL, pdu_privacy_ptr);
17104 
17105             /* Check status.  */
17106             if (status)
17107             {
17108 
17109                 /* Release the packet.  */
17110                 nx_packet_release(packet_ptr);
17111                 return;
17112             }
17113         }
17114 
17115         /* Is the security set to authentication? */
17116         if (temp & NX_SNMP_SECURITY_AUTHORIZE)
17117         {
17118 
17119             /* Compute our authentication parameter.  */
17120             status = _nx_snmp_agent_add_auth_parameter(agent_ptr, packet_ptr, pdu_auth_parm_ptr);
17121 
17122             /* Check status.  */
17123             if (status)
17124             {
17125 
17126                 /* Release the packet.  */
17127                 nx_packet_release(packet_ptr);
17128                 return;
17129             }
17130         }
17131     }
17132 #endif
17133 
17134     /* Increment the sent packet counter.  */
17135     agent_ptr -> nx_snmp_agent_packets_sent++;
17136 
17137     /* Increment the get responses sent counter.  */
17138     agent_ptr -> nx_snmp_agent_getresponse_sent++;
17139 
17140     /* Send the response packet back to the requesting SNMP manager.  */
17141     status =  nxd_udp_socket_send(&(agent_ptr -> nx_snmp_agent_socket), packet_ptr,
17142                                                 &(agent_ptr -> nx_snmp_agent_current_manager_ip),
17143                                                 agent_ptr -> nx_snmp_agent_current_manager_port);
17144 
17145     /* Check for successful call.  */
17146     if (status)
17147     {
17148 
17149         /* Release the packet.  */
17150         nx_packet_release(packet_ptr);
17151     }
17152 
17153     /* Return to caller.  */
17154     return;
17155 }
17156 
17157 #if !defined(NX_SNMP_DISABLE_V1) && !defined(NX_SNMP_DISABLE_V2)
17158 /**************************************************************************/
17159 /*                                                                        */
17160 /*  FUNCTION                                               RELEASE        */
17161 /*                                                                        */
17162 /*    _nx_snmp_version_1_and_2_process                    PORTABLE C      */
17163 /*                                                           6.3.0        */
17164 /*  AUTHOR                                                                */
17165 /*                                                                        */
17166 /*    Yuxin Zhou, Microsoft Corporation                                   */
17167 /*                                                                        */
17168 /*  DESCRIPTION                                                           */
17169 /*                                                                        */
17170 /*    This function processes the SNMP v1 request from the manager.       */
17171 /*                                                                        */
17172 /*  INPUT                                                                 */
17173 /*                                                                        */
17174 /*    agent_ptr                             Pointer to SNMP agent         */
17175 /*    packet_ptr                            Pointer to packet containing  */
17176 /*                                            the SNMP request            */
17177 /*                                                                        */
17178 /*  OUTPUT                                                                */
17179 /*                                                                        */
17180 /*    None                                                                */
17181 /*                                                                        */
17182 /*  CALLS                                                                 */
17183 /*                                                                        */
17184 /*    nx_packet_allocate                    Allocate response packet      */
17185 /*    nx_packet_release                     Release the packet            */
17186 /*    nx_udp_socket_send                    Send the UDP packet           */
17187 /*    _nx_snmp_utility_community_get        Get the community name        */
17188 /*    _nx_snmp_utility_community_set        Set the community name        */
17189 /*    _nx_snmp_utility_error_info_get       Get the error information     */
17190 /*    _nx_snmp_utility_error_info_set       Set the error information     */
17191 /*    _nx_snmp_utility_object_data_get      Get the object data           */
17192 /*    _nx_snmp_utility_object_data_set      Set the object data           */
17193 /*    _nx_snmp_utility_object_id_get        Get the object ID             */
17194 /*    _nx_snmp_utility_object_id_set        Set the object ID             */
17195 /*    _nx_snmp_utility_request_id_get       Get the request ID            */
17196 /*    _nx_snmp_utility_request_id_set       Set the request ID            */
17197 /*    _nx_snmp_utility_request_type_get     Get the request type          */
17198 /*    _nx_snmp_utility_request_type_set_multibyte                         */
17199 /*                                          Set trap request type         */
17200 /*    _nx_snmp_utility_sequence_get         Get the ANS.1 sequence        */
17201 /*    _nx_snmp_utility_sequence_set         Set the ANS.1 sequence        */
17202 /*    _nx_snmp_utility_version_get          Get the SNMP version          */
17203 /*    _nx_snmp_utility_version_set          Set the SNMP version          */
17204 /*    _nx_snmp_version_error_response       Send SNMP Manager error       */
17205 /*                                                                        */
17206 /*  CALLED BY                                                             */
17207 /*                                                                        */
17208 /*    _nx_snmp_agent_thread_entry           SNMP Agent thread             */
17209 /*                                                                        */
17210 /*  RELEASE HISTORY                                                       */
17211 /*                                                                        */
17212 /*    DATE              NAME                      DESCRIPTION             */
17213 /*                                                                        */
17214 /*  10-31-2023     Bo Chen                  Initial Version 6.3.0         */
17215 /*                                                                        */
17216 /**************************************************************************/
_nx_snmp_version_1_and_2_process(NX_SNMP_AGENT * agent_ptr,NX_PACKET * packet_ptr)17217 VOID  _nx_snmp_version_1_and_2_process(NX_SNMP_AGENT *agent_ptr, NX_PACKET *packet_ptr)
17218 {
17219 
17220 UINT        sequence_length, version, request_type, request_length;
17221 UINT        non_repeaters, max_repetitions, next_object;
17222 #ifndef NX_SNMP_DISABLE_V2
17223 UINT        current_repetitions;
17224 #endif /* NX_SNMP_DISABLE_V2 */
17225 UINT        variable_list_length, variable_length;
17226 ULONG       request_id;
17227 UINT        status, length, objects;
17228 UCHAR       *buffer_ptr;
17229 UCHAR       *error_ptr, *request_type_ptr;
17230 UINT        response_length;
17231 UINT        total_variable_length = 0;
17232 NX_PACKET   *response_packet_ptr;
17233 UCHAR       *response_buffer_ptr;
17234 UINT        response_sequence_length, response_type_length;
17235 UINT        response_variable_list_length, response_variable_length;
17236 UCHAR       *response_sequence_ptr, *response_type_ptr;
17237 UCHAR       *response_variable_list_ptr, *response_variable_ptr;
17238 UINT        packet_type;
17239 INT         buffer_length;
17240 
17241 
17242     buffer_length = (INT)(packet_ptr -> nx_packet_length);
17243 
17244     /* Setup a pointer to the buffer.  */
17245     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
17246 
17247     /* Pickup the SEQUENCE field.  */
17248     length =  _nx_snmp_utility_sequence_get(buffer_ptr, &sequence_length, buffer_length);
17249 
17250     /* Check for a valid packet.  */
17251     if (length == 0)
17252     {
17253 
17254         /* Increment the invalid packet error counter.  */
17255         agent_ptr -> nx_snmp_agent_invalid_packets++;
17256 
17257         /* Increment the internal error counter.  */
17258         agent_ptr -> nx_snmp_agent_internal_errors++;
17259 
17260         /* Release the packet.  */
17261         nx_packet_release(packet_ptr);
17262 
17263         /* Return to caller.  */
17264         return;
17265     }
17266 
17267     /* Move the buffer pointer up.  */
17268     buffer_ptr =  buffer_ptr + length;
17269 
17270     /* The buffer pointer is moved by the length. Update buffer size */
17271     buffer_length -= (INT)length;
17272 
17273     /* Pickup the SNMP VERSION field.  */
17274     length =  _nx_snmp_utility_version_get(buffer_ptr, &version, buffer_length);
17275 
17276     /* Check for a valid packet.  */
17277     if (length == 0)
17278     {
17279 
17280         /* Increment the invalid packet error counter.  */
17281         agent_ptr -> nx_snmp_agent_invalid_packets++;
17282 
17283         /* Increment the internal error counter.  */
17284         agent_ptr -> nx_snmp_agent_internal_errors++;
17285 
17286         /* Release the packet.  */
17287         nx_packet_release(packet_ptr);
17288 
17289         /* Return to caller.  */
17290         return;
17291     }
17292 
17293     /* Move the buffer pointer up.  */
17294     buffer_ptr =  buffer_ptr + length;
17295 
17296     /* The buffer pointer is moved by the length. Update buffer size */
17297     buffer_length -= (INT)length;
17298 
17299     /* Pickup the SNMP Community String field.  */
17300     length =  _nx_snmp_utility_community_get(buffer_ptr,
17301                                              agent_ptr -> nx_snmp_agent_current_community_string,
17302                                              buffer_length);
17303 
17304     /* Check for a valid packet.  */
17305     if (length == 0)
17306     {
17307 
17308         /* Increment the invalid packet error counter.  */
17309         agent_ptr -> nx_snmp_agent_invalid_packets++;
17310 
17311         /* Increment the internal error counter.  */
17312         agent_ptr -> nx_snmp_agent_internal_errors++;
17313 
17314         /* Release the packet.  */
17315         nx_packet_release(packet_ptr);
17316 
17317         /* Return to caller.  */
17318         return;
17319     }
17320 
17321     /* Move the buffer pointer up.  */
17322     buffer_ptr =  buffer_ptr + length;
17323 
17324     /* The buffer pointer is moved by the length. Update buffer size */
17325     buffer_length -= (INT)length;
17326 
17327     /* Save the request type pointer.  */
17328     request_type_ptr =  buffer_ptr;
17329 
17330     /* Pickup the SNMP Request type.  */
17331     length =  _nx_snmp_utility_request_type_get(buffer_ptr, &request_type, &request_length, buffer_length);
17332 
17333     /* Check for a valid packet.  */
17334     if (length == 0)
17335     {
17336 
17337         /* Increment the invalid packet error counter.  */
17338         agent_ptr -> nx_snmp_agent_invalid_packets++;
17339 
17340         /* Increment the internal error counter.  */
17341         agent_ptr -> nx_snmp_agent_internal_errors++;
17342 
17343         /* Release the packet.  */
17344         nx_packet_release(packet_ptr);
17345 
17346         /* Return to caller.  */
17347         return;
17348     }
17349 
17350     /* Move the buffer pointer up.  */
17351     buffer_ptr =  buffer_ptr + length;
17352 
17353     /* The buffer pointer is moved by the length. Update buffer size */
17354     buffer_length -= (INT)length;
17355 
17356     agent_ptr -> nx_snmp_agent_request_get_type =  NX_FALSE;
17357     if ((request_type == NX_SNMP_GET_REQUEST) ||
17358         (request_type == NX_SNMP_GET_NEXT_REQUEST) ||
17359         (request_type == NX_SNMP_GET_BULK_REQUEST))
17360     {
17361          agent_ptr -> nx_snmp_agent_request_get_type =  NX_TRUE;
17362     }
17363 
17364     /* Pickup the SNMP Request ID.  */
17365     length =  _nx_snmp_utility_request_id_get(buffer_ptr, &request_id, buffer_length);
17366 
17367     /* Check for a valid packet.  */
17368     if (length == 0)
17369     {
17370 
17371         /* Increment the invalid packet error counter.  */
17372         agent_ptr -> nx_snmp_agent_invalid_packets++;
17373 
17374         /* Increment the internal error counter.  */
17375         agent_ptr -> nx_snmp_agent_internal_errors++;
17376 
17377         /* Release the packet.  */
17378         nx_packet_release(packet_ptr);
17379 
17380         /* Return to caller.  */
17381         return;
17382     }
17383 
17384     /* Move the buffer pointer up.  */
17385     buffer_ptr =  buffer_ptr + length;
17386 
17387     /* The buffer pointer is moved by the length. Update buffer size */
17388     buffer_length -= (INT)length;
17389 
17390     /* Save a pointer to the error string.  */
17391     error_ptr =  buffer_ptr;
17392 
17393     /* Pickup the SNMP Error information.  This is actually used to derive the GETBULK
17394        information in SNMP V2 and above.  */
17395     length =  _nx_snmp_utility_error_info_get(buffer_ptr, &non_repeaters, &max_repetitions, buffer_length);
17396 
17397     /* Check for a valid packet.  */
17398     if (length == 0)
17399     {
17400 
17401         /* Increment the invalid packet error counter.  */
17402         agent_ptr -> nx_snmp_agent_invalid_packets++;
17403 
17404         /* Increment the internal error counter.  */
17405         agent_ptr -> nx_snmp_agent_internal_errors++;
17406 
17407         /* Release the packet.  */
17408         nx_packet_release(packet_ptr);
17409 
17410         /* Return to caller.  */
17411         return;
17412     }
17413 
17414 #ifndef NX_DISABLE_PACKET_CHAIN
17415     /* Determine if the received packet size is too big.  */
17416     if (packet_ptr -> nx_packet_next)
17417     {
17418 
17419         /* Call the error handling response routine.  */
17420         _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_TOOBIG, 0);
17421 
17422         /* Done, return to caller.  */
17423         return;
17424     }
17425 #endif /* NX_DISABLE_PACKET_CHAIN */
17426 
17427     /* Check to see if there is a username processing routine.  */
17428     if (agent_ptr -> nx_snmp_agent_username_process)
17429     {
17430 
17431         /* Yes, there is a callback routine to process the community/username.  */
17432         status = agent_ptr -> nx_snmp_agent_username_process(agent_ptr, agent_ptr -> nx_snmp_agent_current_community_string);
17433 
17434         /* Determine if the callback routine generated an error.  */
17435         if (status != NX_SUCCESS)
17436         {
17437 
17438             /* Increment the number of community/username errors.  */
17439             agent_ptr -> nx_snmp_agent_username_errors++;
17440 
17441             /* Check the version.  */
17442             if (version == NX_SNMP_VERSION_1)
17443             {
17444 
17445 #ifdef NX_SNMP_V1_AUTHORIZATION_ERROR_RESPONSE
17446                 /* Call the error handling response routine.  */
17447                 _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_NOSUCHNAME, 0);
17448 #else
17449                 /* Authorization error response is not supported by version 1. */
17450                 /* Release the packet.  */
17451                 nx_packet_release(packet_ptr);
17452 #endif
17453             }
17454             else
17455             {
17456 
17457                 /* Call the error handling response routine.  */
17458                 _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_AUTHORIZATION, 0);
17459             }
17460 
17461             /* Done, return to caller.  */
17462             return;
17463         }
17464     }
17465 
17466     /* Move the buffer pointer up.  */
17467     buffer_ptr =  buffer_ptr + length;
17468 
17469     /* The buffer pointer is moved by the length. Update buffer size */
17470     buffer_length -= (INT)length;
17471 
17472     /* Pickup the SNMP Variable list length.  */
17473     length =  _nx_snmp_utility_sequence_get(buffer_ptr, &variable_list_length, buffer_length);
17474 
17475     /* Check for a valid packet.  */
17476     if (length == 0)
17477     {
17478 
17479         /* Increment the invalid packet error counter.  */
17480         agent_ptr -> nx_snmp_agent_invalid_packets++;
17481 
17482         /* Increment the internal error counter.  */
17483         agent_ptr -> nx_snmp_agent_internal_errors++;
17484 
17485         /* Release the packet.  */
17486         nx_packet_release(packet_ptr);
17487 
17488         /* Return to caller.  */
17489         return;
17490     }
17491 
17492     /* Move the buffer pointer up.  */
17493     buffer_ptr =  buffer_ptr + length;
17494 
17495     /* The buffer pointer is moved by the length. Update buffer size */
17496     buffer_length -= (INT)length;
17497 
17498     /* At this point we have parsed the incoming SNMP request up to the first
17499        variable.  */
17500 
17501     /* Now prepare response message so we can process the variables one by one.  */
17502 
17503     /* Determine which packet type we allocate based on the destination address type.  */
17504     if (agent_ptr -> nx_snmp_agent_current_manager_ip.nxd_ip_version == NX_IP_VERSION_V4)
17505     {
17506         packet_type = NX_IPv4_UDP_PACKET;
17507     }
17508     else if (agent_ptr -> nx_snmp_agent_current_manager_ip.nxd_ip_version == NX_IP_VERSION_V6)
17509     {
17510 
17511 #ifndef FEATURE_NX_IPV6
17512         /* Release the packet.  */
17513         nx_packet_release(packet_ptr);
17514 
17515         return;
17516 #else
17517         packet_type = NX_IPv6_UDP_PACKET;
17518 #endif  /* FEATURE_NX_IPV6 */
17519     }
17520     else
17521     {
17522 
17523         /* Release the packet.  */
17524         nx_packet_release(packet_ptr);
17525 
17526         return;
17527     }
17528 
17529     /* Allocate the packet for the SNMP response.  */
17530     status =  nx_packet_allocate(agent_ptr -> nx_snmp_agent_packet_pool_ptr, &response_packet_ptr, packet_type, NX_SNMP_AGENT_TIMEOUT);
17531 
17532     /* Determine if a response packet was allocated.  */
17533     if (status)
17534     {
17535 
17536         /* Increment the packet allocation error counter.  */
17537         agent_ptr -> nx_snmp_agent_allocation_errors++;
17538 
17539         /* Release the packet.  */
17540         nx_packet_release(packet_ptr);
17541 
17542         /* Return to caller.  */
17543         return;
17544     }
17545 
17546     memset(response_packet_ptr -> nx_packet_prepend_ptr, 0,
17547            (UINT)(response_packet_ptr -> nx_packet_data_end - response_packet_ptr -> nx_packet_prepend_ptr));
17548 
17549     /* Initialize the counters required for the length fields of the response packet.  */
17550     response_sequence_length =       0;
17551     response_type_length =           0;
17552     response_variable_list_length =  0;
17553 
17554     /* Setup a pointer to the response packet's buffer area.  */
17555     response_buffer_ptr =  response_packet_ptr -> nx_packet_prepend_ptr;
17556 
17557     /* This is also the response sequence pointer. Remember it since we are going to have to
17558        update it later with the actual length of the response.  */
17559     response_sequence_ptr =  response_buffer_ptr;
17560 
17561     /* First, write the sequence in the response packet.  A zero is written for now.  This will be
17562        updated later.  */
17563     response_length =  _nx_snmp_utility_sequence_set(response_buffer_ptr, 0, response_packet_ptr -> nx_packet_data_end);
17564 
17565     /* Check for a valid operation.  */
17566     if (response_length == 0)
17567     {
17568 
17569         /* Increment the internal error counter.  */
17570         agent_ptr -> nx_snmp_agent_internal_errors++;
17571 
17572         /* Release the packet.  */
17573         nx_packet_release(packet_ptr);
17574 
17575         /* Release the response packet too.  */
17576         nx_packet_release(response_packet_ptr);
17577 
17578         /* Return to caller.  */
17579         return;
17580     }
17581 
17582     /* Move the response buffer pointer up.  */
17583     response_buffer_ptr =  response_buffer_ptr + response_length;
17584 
17585     /* Now set the SNMP version in the response.  */
17586     response_length =  _nx_snmp_utility_version_set(response_buffer_ptr, version, response_packet_ptr -> nx_packet_data_end);
17587 
17588     /* Check for a valid operation.  */
17589     if (response_length == 0)
17590     {
17591 
17592         /* Increment the internal error counter.  */
17593         agent_ptr -> nx_snmp_agent_internal_errors++;
17594 
17595         /* Release the packet.  */
17596         nx_packet_release(packet_ptr);
17597 
17598         /* Release the response packet too.  */
17599         nx_packet_release(response_packet_ptr);
17600 
17601         /* Return to caller.  */
17602         return;
17603     }
17604 
17605     /* Move the response buffer pointer up.  */
17606     response_buffer_ptr =  response_buffer_ptr + response_length;
17607 
17608     /* Adjust the response sequence length.  */
17609     response_sequence_length =  response_sequence_length + response_length;
17610 
17611     /* Set the SNMP community in the response message.  */
17612     response_length =  _nx_snmp_utility_community_set(response_buffer_ptr, agent_ptr -> nx_snmp_agent_current_community_string, response_packet_ptr -> nx_packet_data_end);
17613 
17614     /* Check for a valid operation.  */
17615     if (response_length == 0)
17616     {
17617 
17618         /* Increment the internal error counter.  */
17619         agent_ptr -> nx_snmp_agent_internal_errors++;
17620 
17621         /* Release the packet.  */
17622         nx_packet_release(packet_ptr);
17623 
17624         /* Release the response packet too.  */
17625         nx_packet_release(response_packet_ptr);
17626 
17627         /* Return to caller.  */
17628         return;
17629     }
17630 
17631     /* Move the response buffer pointer up.  */
17632     response_buffer_ptr =  response_buffer_ptr + response_length;
17633 
17634     /* Adjust the response sequence length.  */
17635     response_sequence_length =  response_sequence_length + response_length;
17636 
17637     /* Remember the request type pointer, since it will need to be updated later.  */
17638     response_type_ptr =  response_buffer_ptr;
17639 
17640     /* Now set the request type in the response message.  */
17641     response_length =  _nx_snmp_utility_request_type_set_multibyte(response_buffer_ptr, NX_SNMP_ANS1_GET_RESPONSE, 0, response_packet_ptr -> nx_packet_data_end);
17642 
17643     /* Check for a valid operation.  */
17644     if (response_length == 0)
17645     {
17646 
17647         /* Increment the internal error counter.  */
17648         agent_ptr -> nx_snmp_agent_internal_errors++;
17649 
17650         /* Release the packet.  */
17651         nx_packet_release(packet_ptr);
17652 
17653         /* Release the response packet too.  */
17654         nx_packet_release(response_packet_ptr);
17655 
17656         /* Return to caller.  */
17657         return;
17658     }
17659 
17660     /* Move the response buffer pointer up.  */
17661     response_buffer_ptr =  response_buffer_ptr + response_length;
17662 
17663     /* Adjust the response sequence length.  */
17664     response_sequence_length =  response_sequence_length + response_length;
17665 
17666     /* Now set the request ID in the response message.  */
17667     response_length =  _nx_snmp_utility_request_id_set(response_buffer_ptr, request_id, response_packet_ptr -> nx_packet_data_end);
17668 
17669     /* Check for a valid operation.  */
17670     if (response_length == 0)
17671     {
17672 
17673         /* Increment the internal error counter.  */
17674         agent_ptr -> nx_snmp_agent_internal_errors++;
17675 
17676         /* Release the packet.  */
17677         nx_packet_release(packet_ptr);
17678 
17679         /* Release the response packet too.  */
17680         nx_packet_release(response_packet_ptr);
17681 
17682         /* Return to caller.  */
17683         return;
17684     }
17685 
17686     /* Move the response buffer pointer up.  */
17687     response_buffer_ptr =  response_buffer_ptr + response_length;
17688 
17689     /* Adjust the response sequence length.  */
17690     response_sequence_length =  response_sequence_length + response_length;
17691 
17692     /* Adjust the response request type length.  */
17693     response_type_length =  response_type_length + response_length;
17694 
17695     /* Set the response error information.  Assume everything is okay at this point.  */
17696     response_length =  _nx_snmp_utility_error_info_set(response_buffer_ptr, 0, 0, response_packet_ptr -> nx_packet_data_end);
17697 
17698     /* Check for a valid operation.  */
17699     if (response_length == 0)
17700     {
17701 
17702         /* Increment the internal error counter.  */
17703         agent_ptr -> nx_snmp_agent_internal_errors++;
17704 
17705         /* Release the packet.  */
17706         nx_packet_release(packet_ptr);
17707 
17708         /* Release the response packet too.  */
17709         nx_packet_release(response_packet_ptr);
17710 
17711         /* Return to caller.  */
17712         return;
17713     }
17714 
17715     /* Move the response buffer pointer up.  */
17716     response_buffer_ptr =  response_buffer_ptr + response_length;
17717 
17718     /* Adjust the response sequence length.  */
17719     response_sequence_length =  response_sequence_length + response_length;
17720 
17721     /* Adjust the response request type length.  */
17722     response_type_length =  response_type_length + response_length;
17723 
17724     /* Remember the start of the response's variable list field.  */
17725     response_variable_list_ptr =  response_buffer_ptr;
17726 
17727     /* Setup the variable list response.  For now, the length will be zero.  We
17728        will overwrite this with the actual length later.  */
17729     response_length =  _nx_snmp_utility_sequence_set(response_buffer_ptr, 0, response_packet_ptr -> nx_packet_data_end);
17730 
17731     /* Check for a valid operation.  */
17732     if (response_length == 0)
17733     {
17734 
17735         /* Increment the internal error counter.  */
17736         agent_ptr -> nx_snmp_agent_internal_errors++;
17737 
17738         /* Release the packet.  */
17739         nx_packet_release(packet_ptr);
17740 
17741         /* Release the response packet too.  */
17742         nx_packet_release(response_packet_ptr);
17743 
17744         /* Return to caller.  */
17745         return;
17746     }
17747 
17748     /* Move the response buffer pointer up.  */
17749     response_buffer_ptr =  response_buffer_ptr + response_length;
17750 
17751     /* Adjust the response sequence length.  */
17752     response_sequence_length =  response_sequence_length + response_length;
17753 
17754     /* Adjust the response request type length.  */
17755     response_type_length =  response_type_length + response_length;
17756 
17757     /* At this point the response buffer is setup to exactly the same position the
17758        SNMP Manager's input buffer is - right before the first variable.  We can
17759        now walk through the variable list to process each request and place the
17760        result in the response buffer.  */
17761     objects =  0;
17762     next_object = NX_TRUE;
17763 #ifndef NX_SNMP_DISABLE_V2
17764     current_repetitions =  max_repetitions;
17765 #endif /* NX_SNMP_DISABLE_V2 */
17766     do
17767     {
17768 
17769         /* Determine if the next object should be retrieved.  */
17770         if (next_object)
17771         {
17772 
17773             /* Pickup the first SNMP Variable length.  */
17774             length =  _nx_snmp_utility_sequence_get(buffer_ptr, &variable_length, buffer_length);
17775 
17776             /* Calculate the total variable size.  */
17777             total_variable_length =  variable_length + length;
17778 
17779             /* Determine if this variable will fit in the remaining length of the
17780                variable list, buffer length, and if there is integer overflow.  */
17781             if ((length == 0) || (total_variable_length > variable_list_length) ||
17782                 (total_variable_length < variable_length) || (total_variable_length > (UINT)buffer_length))
17783             {
17784 
17785                 /* Increment the invalid packet error counter.  */
17786                 agent_ptr -> nx_snmp_agent_invalid_packets++;
17787 
17788                 /* Release the response packet.  */
17789                 nx_packet_release(response_packet_ptr);
17790 
17791                 /* Call the error handling response routine. This will release the packet  */
17792                 _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_SUCCESS, objects + 1);
17793 
17794                 /* Return to caller.  */
17795                 return;
17796             }
17797 
17798             /* Move the buffer pointer up.  */
17799             buffer_ptr =  buffer_ptr + length;
17800 
17801             /* Update the size of the remaining buffer. */
17802             buffer_length -= (INT)length;
17803 
17804             /* Now pickup the object ID.  */
17805             length =  _nx_snmp_utility_object_id_get(buffer_ptr, agent_ptr -> nx_snmp_agent_current_octet_string, buffer_length);
17806 
17807             /* Determine if the object retrieval was successful.  */
17808             if (length == 0)
17809             {
17810 
17811                 /* Increment the invalid packet error counter.  */
17812                 agent_ptr -> nx_snmp_agent_invalid_packets++;
17813 
17814                 /* Increment the internal error counter.  */
17815                 agent_ptr -> nx_snmp_agent_internal_errors++;
17816 
17817                 /* Release the packet.  */
17818                 nx_packet_release(packet_ptr);
17819 
17820                 /* Release the response packet.  */
17821                 nx_packet_release(response_packet_ptr);
17822 
17823                 /* Return to caller.  */
17824                 return;
17825             }
17826 
17827             /* Move the buffer pointer up.  */
17828             buffer_ptr =  buffer_ptr + length;
17829 
17830             /* Update the size of the remaining buffer. */
17831             buffer_length -= (INT)length;
17832 
17833             /* Default the value to NULL.  */
17834             agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type =  0;
17835 
17836             /* Determine if a value is present.  */
17837             if (length != variable_length)
17838             {
17839 
17840                 /* Pickup the value associated with this variable.  */
17841                 length =  _nx_snmp_utility_object_data_get(buffer_ptr, &(agent_ptr -> nx_snmp_agent_current_object_data), buffer_length);
17842 
17843                 /* Determine if the object value was successful.  */
17844                 if (length == 0)
17845                 {
17846 
17847                     /* Increment the invalid packet error counter.  */
17848                     agent_ptr -> nx_snmp_agent_invalid_packets++;
17849 
17850                     /* Increment the internal error counter.  */
17851                     agent_ptr -> nx_snmp_agent_internal_errors++;
17852 
17853                     /* Send an SNMP version error response. The packet will be released in the function.  */
17854                     _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_BADVALUE, objects + 1);
17855 
17856                     /* Release the response packet.  */
17857                     nx_packet_release(response_packet_ptr);
17858 
17859                     /* Return to caller.  */
17860                     return;
17861                 }
17862                 else
17863                 {
17864 
17865                     /* Move the buffer pointer up.  */
17866                     buffer_ptr =  buffer_ptr + length;
17867 
17868                     /* Update the size of the remaining buffer. */
17869                     buffer_length -= (INT)length;
17870                 }
17871             }
17872         }
17873 
17874         /* At this point, we are ready to call the appropriate application request handling routine.
17875            It is responsible for extracting or placing information in the object data structure.  */
17876         if (request_type == NX_SNMP_ANS1_GET_REQUEST)
17877         {
17878 
17879             /* Increment the total number of get variables.  */
17880             agent_ptr -> nx_snmp_agent_total_get_variables++;
17881 
17882             /* Call the application's GET routine.  */
17883             status =  (agent_ptr -> nx_snmp_agent_get_process)(agent_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
17884                                                                &(agent_ptr -> nx_snmp_agent_current_object_data));
17885         }
17886         else if (request_type == NX_SNMP_ANS1_GET_NEXT_REQUEST)
17887         {
17888 
17889             /* Increment the total number of get variables.  */
17890             agent_ptr -> nx_snmp_agent_total_get_variables++;
17891 
17892             /* Call the application's GETNEXT routine.  */
17893             status =  (agent_ptr -> nx_snmp_agent_getnext_process)(agent_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
17894                                                                    &(agent_ptr -> nx_snmp_agent_current_object_data));
17895         }
17896         else if (request_type == NX_SNMP_ANS1_SET_REQUEST)
17897         {
17898 
17899             /* Increment the total number of set variables.  */
17900             agent_ptr -> nx_snmp_agent_total_set_variables++;
17901 
17902             /* Call the application's SET routine.  */
17903             status =  (agent_ptr -> nx_snmp_agent_set_process)(agent_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
17904                                                                &(agent_ptr -> nx_snmp_agent_current_object_data));
17905         }
17906 
17907 #ifndef NX_SNMP_DISABLE_V2
17908         else if ((request_type == NX_SNMP_ANS1_GET_BULK_REQUEST) && (version != NX_SNMP_VERSION_1))
17909         {
17910 
17911             /* Increment the total number of get variables.  */
17912             agent_ptr -> nx_snmp_agent_total_get_variables++;
17913 
17914             /* Clear the next object flag.  */
17915             next_object =  NX_FALSE;
17916 
17917             /* Call the application's GETNEXT routine.  */
17918             status =  (agent_ptr -> nx_snmp_agent_getnext_process)(agent_ptr, agent_ptr -> nx_snmp_agent_current_octet_string, &(agent_ptr -> nx_snmp_agent_current_object_data));
17919 
17920             /* Decrement the number of non-repeaters.  */
17921             if (non_repeaters)
17922             {
17923 
17924                 /* Decrement the number of non-repeaters.  */
17925                 non_repeaters--;
17926 
17927                 /* Set the next object flag to move to the next entry of the request.  */
17928                 next_object =  NX_TRUE;
17929             }
17930             else
17931             {
17932 
17933                 /* Decrement the repetitions.  */
17934                 if (current_repetitions)
17935                     current_repetitions--;
17936 
17937                 /* Determine if there are more repetitions or if the end of MIB was detected.  */
17938                 if ((current_repetitions == 0) || (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type == NX_SNMP_ANS1_END_OF_MIB_VIEW))
17939                 {
17940 
17941                     /* Reset the current repetition.  */
17942                     current_repetitions =  max_repetitions;
17943 
17944                     /* Set the next object flag to true.  */
17945                     next_object =  NX_TRUE;
17946                 }
17947             }
17948         }
17949 #endif /* NX_SNMP_DISABLE_V2 */
17950         else
17951         {
17952 
17953             /* Release the response packet.  */
17954             nx_packet_release(response_packet_ptr);
17955 
17956             /* Release the packet.  */
17957             nx_packet_release(packet_ptr);
17958 
17959             /* Increment the internal error counter.  */
17960             agent_ptr -> nx_snmp_agent_internal_errors++;
17961 
17962             /* Done, return to caller.  */
17963             return;
17964         }
17965 
17966         /* Check for an error status from the agent's request processing callback routine.  */
17967         if (status)
17968         {
17969 
17970             /* Release the response packet.  */
17971             nx_packet_release(response_packet_ptr);
17972 
17973 #ifndef NX_SNMP_DISABLE_V1
17974             /* Check the version.  */
17975             if (version == NX_SNMP_VERSION_1)
17976             {
17977 
17978                 /* Per RFC2576 4.3 */
17979                 switch(status)
17980                 {
17981                 case NX_SNMP_SUCCESS:
17982                 case NX_SNMP_ERROR_TOOBIG:
17983                     /* Call the error handling response routine.  */
17984                     _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, status, objects + 1);
17985                     break;
17986                 case NX_SNMP_ERROR_BADVALUE:
17987                 case NX_SNMP_ERROR_WRONGVALUE:
17988                 case NX_SNMP_ERROR_WRONGENCODING:
17989                 case NX_SNMP_ERROR_WRONGTYPE:
17990                 case NX_SNMP_ERROR_WRONGLENGTH:
17991                 case NX_SNMP_ERROR_INCONSISTENTVALUE:
17992                     /* Call the error handling response routine.  */
17993                     _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_BADVALUE, objects + 1);
17994                     break;
17995                 case NX_SNMP_ERROR_NOSUCHNAME:
17996                 case NX_SNMP_ERROR_NOACCESS:
17997                 case NX_SNMP_ERROR_NOTWRITABLE:
17998                 case NX_SNMP_ERROR_NOCREATION:
17999                 case NX_SNMP_ERROR_INCONSISTENTNAME:
18000                 case NX_SNMP_ERROR_AUTHORIZATION:
18001                     /* Call the error handling response routine.  */
18002                     _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_NOSUCHNAME, objects + 1);
18003                     break;
18004                 case NX_SNMP_ERROR_GENERAL:
18005                 case NX_SNMP_ERROR_RESOURCEUNAVAILABLE:
18006                 case NX_SNMP_ERROR_COMMITFAILED:
18007                 case NX_SNMP_ERROR_UNDOFAILED:
18008                     /* Call the error handling response routine.  */
18009                     _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_GENERAL, objects + 1);
18010                     break;
18011                 default:
18012                     /* Release the packet.  */
18013                     nx_packet_release(packet_ptr);
18014                 }
18015             }
18016             else
18017 #endif /* NX_SNMP_DISABLE_V1 */
18018             {
18019 
18020                 /* Call the error handling response routine. This will release the packet  */
18021                 _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, status, objects + 1);
18022             }
18023 
18024             /* Done, return to caller.  */
18025             return;
18026         }
18027 
18028         /* Determine if the returning object is valid.  */
18029         if ((agent_ptr -> nx_snmp_agent_current_octet_string[0] != '1') || (agent_ptr -> nx_snmp_agent_current_octet_string[1] != '.') || (agent_ptr -> nx_snmp_agent_current_octet_string[2] != '3') || (agent_ptr -> nx_snmp_agent_current_octet_string[3] != '.'))
18030         {
18031 
18032             /* Release the response packet.  */
18033             nx_packet_release(response_packet_ptr);
18034 
18035             /* Release the packet. */
18036             nx_packet_release(packet_ptr);
18037 
18038             /* Increment the internal error counter.  */
18039             agent_ptr -> nx_snmp_agent_internal_errors++;
18040 
18041             /* Done, return to caller.  */
18042             return;
18043         }
18044 
18045         /* Now ensure the returning object type is valid.  */
18046         if ((agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_INTEGER) &&
18047             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_OCTET_STRING) &&
18048             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NULL) &&
18049             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_TIME_TICS) &&
18050             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_GAUGE) &&
18051             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_COUNTER) &&
18052             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_COUNTER64) &&
18053             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_IP_ADDRESS) &&
18054 #ifdef FEATURE_NX_IPV6
18055             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_IPV6_ADDRESS) &&
18056 #endif
18057             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NSAP_ADDRESS) &&
18058             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_OBJECT_ID)
18059 #ifndef NX_SNMP_DISABLE_V2
18060             &&
18061             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NO_SUCH_OBJECT) &&
18062             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NO_SUCH_INSTANCE) &&
18063             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_END_OF_MIB_VIEW)
18064 #endif /* NX_SNMP_DISABLE_V2 */
18065             )
18066         {
18067 
18068             /* Release the response packet.  */
18069             nx_packet_release(response_packet_ptr);
18070 
18071             /* Call the error handling response routine. This will release the packet  */
18072             _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_NOSUCHNAME, objects + 1);
18073 
18074             /* Increment the internal error counter.  */
18075             agent_ptr -> nx_snmp_agent_internal_errors++;
18076 
18077             /* Done, return to caller.  */
18078             return;
18079         }
18080 
18081         /* Everything is okay, place the object and object data into the response buffer.  */
18082 
18083         /* Remember the start of the variable response sequence.  */
18084         response_variable_ptr =  response_buffer_ptr;
18085 
18086         /* Clear the response variable size.  */
18087         response_variable_length =  0;
18088 
18089         /* Determine if there is enough room in the destination for the variable sequence.  */
18090         if ((response_buffer_ptr + 4) >= response_packet_ptr -> nx_packet_data_end)
18091         {
18092 
18093             /* Release the response packet.  */
18094             nx_packet_release(response_packet_ptr);
18095 
18096             /* Call the error handling response routine. This will release the packet.  */
18097             _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_TOOBIG, objects + 1);
18098 
18099             /* Done, return to caller.  */
18100             return;
18101         }
18102 
18103         /* Setup the variable response sequence.  For now, the length will be zero.  We
18104            will overwrite this with the actual length later.  */
18105         response_length =  _nx_snmp_utility_sequence_set(response_buffer_ptr, 0, response_packet_ptr -> nx_packet_data_end);
18106 
18107         /* Check for a valid operation.  */
18108         if (response_length == 0)
18109         {
18110 
18111             /* Increment the internal error counter.  */
18112             agent_ptr -> nx_snmp_agent_internal_errors++;
18113 
18114             /* Release the packet.  */
18115             nx_packet_release(packet_ptr);
18116 
18117             /* Release the response packet too.  */
18118             nx_packet_release(response_packet_ptr);
18119 
18120             /* Return to caller.  */
18121             return;
18122         }
18123 
18124         /* Move the response buffer pointer up.  */
18125         response_buffer_ptr =  response_buffer_ptr + response_length;
18126 
18127         /* Adjust the response sequence length.  */
18128         response_sequence_length =  response_sequence_length + response_length;
18129 
18130         /* Adjust the response request type length.  */
18131         response_type_length =  response_type_length + response_length;
18132 
18133         /* Adjust the response variable list size.  */
18134         response_variable_list_length =  response_variable_list_length + response_length;
18135 
18136         /* Place the object into the response buffer.  */
18137         response_length =  _nx_snmp_utility_object_id_set(response_buffer_ptr, agent_ptr -> nx_snmp_agent_current_octet_string, response_packet_ptr -> nx_packet_data_end);
18138 
18139         /* Check for a valid operation.  */
18140         if (response_length == 0)
18141         {
18142 
18143             /* Release the response packet.  */
18144             nx_packet_release(response_packet_ptr);
18145 
18146             /* Call the error handling response routine. This will release the packet.  */
18147             _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_TOOBIG, objects + 1);
18148 
18149             /* Done, return to caller.  */
18150             return;
18151         }
18152 
18153         /* Move the response buffer pointer up.  */
18154         response_buffer_ptr =  response_buffer_ptr + response_length;
18155 
18156         /* Adjust the response sequence length.  */
18157         response_sequence_length =  response_sequence_length + response_length;
18158 
18159         /* Adjust the response request type length.  */
18160         response_type_length =  response_type_length + response_length;
18161 
18162         /* Adjust the response variable list size.  */
18163         response_variable_list_length =  response_variable_list_length + response_length;
18164 
18165         /* Adjust the response variable size.  */
18166         response_variable_length =  response_variable_length + response_length;
18167 
18168         /* Insert the object's data into the response buffer.  */
18169         response_length =  _nx_snmp_utility_object_data_set(response_buffer_ptr, &(agent_ptr -> nx_snmp_agent_current_object_data), response_packet_ptr -> nx_packet_data_end);
18170 
18171         /* Check for a valid operation.  */
18172         if (response_length == 0)
18173         {
18174 
18175             /* Release the response packet.  */
18176             nx_packet_release(response_packet_ptr);
18177 
18178             /* Call the error handling response routine. This will release the packet.  */
18179             _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_TOOBIG, objects + 1);
18180 
18181             /* Done, return to caller.  */
18182             return;
18183         }
18184 
18185         /* Move the response buffer pointer up.  */
18186         response_buffer_ptr =  response_buffer_ptr + response_length;
18187 
18188         /* Adjust the response sequence length.  */
18189         response_sequence_length =  response_sequence_length + response_length;
18190 
18191         /* Adjust the response request type length.  */
18192         response_type_length =  response_type_length + response_length;
18193 
18194         /* Adjust the response variable list size.  */
18195         response_variable_list_length =  response_variable_list_length + response_length;
18196 
18197         /* Adjust the response variable size.  */
18198         response_variable_length =  response_variable_length + response_length;
18199 
18200         /* Now update the response variable sequence with the actual variable length.  */
18201         _nx_snmp_utility_sequence_set(response_variable_ptr, response_variable_length, response_packet_ptr -> nx_packet_data_end);
18202 
18203         /* Only update the source object information if the next object flag is set.  */
18204         if (next_object)
18205         {
18206 
18207             /* Decrement the size of the variable list.  */
18208             variable_list_length =  variable_list_length - total_variable_length;
18209 
18210             /* Increment the object counter.  */
18211             objects++;
18212         }
18213     } while ((variable_list_length) || (next_object == NX_FALSE));
18214 
18215     /* At this point, several response fields need to be updated with actual lengths.  */
18216     _nx_snmp_utility_sequence_set(response_sequence_ptr, response_sequence_length, response_packet_ptr -> nx_packet_data_end);
18217     _nx_snmp_utility_sequence_set(response_variable_list_ptr, response_variable_list_length, response_packet_ptr -> nx_packet_data_end);
18218     _nx_snmp_utility_request_type_set_multibyte(response_type_ptr, NX_SNMP_ANS1_GET_RESPONSE, response_type_length, response_packet_ptr -> nx_packet_data_end);
18219 
18220     /* Now the response packet's pointers must be setup so it can be sent.  */
18221     response_packet_ptr -> nx_packet_length =  (ULONG)(response_buffer_ptr - response_packet_ptr -> nx_packet_prepend_ptr);
18222     response_packet_ptr -> nx_packet_append_ptr =  response_buffer_ptr;
18223 
18224     /* Release the original request packet.  */
18225     nx_packet_release(packet_ptr);
18226 
18227     /* Update various statistics.  */
18228     agent_ptr -> nx_snmp_agent_total_bytes_received +=  packet_ptr -> nx_packet_length;
18229     agent_ptr -> nx_snmp_agent_total_bytes_sent +=      response_packet_ptr -> nx_packet_length;
18230     if (request_type == NX_SNMP_ANS1_GET_REQUEST)
18231         agent_ptr -> nx_snmp_agent_get_requests++;
18232     else if (request_type == NX_SNMP_ANS1_GET_NEXT_REQUEST)
18233         agent_ptr -> nx_snmp_agent_getnext_requests++;
18234     else if (request_type == NX_SNMP_ANS1_GET_BULK_REQUEST)
18235         agent_ptr -> nx_snmp_agent_getbulk_requests++;
18236     else if (request_type == NX_SNMP_ANS1_SET_REQUEST)
18237         agent_ptr -> nx_snmp_agent_set_requests++;
18238 
18239     /* Increment the sent packet counter.  */
18240     agent_ptr -> nx_snmp_agent_packets_sent++;
18241 
18242     /* Increment the get responses sent counter.  */
18243     agent_ptr -> nx_snmp_agent_getresponse_sent++;
18244 
18245     /* Send the response packet back to the requesting SNMP manager.  */
18246     status =  nxd_udp_socket_send(&(agent_ptr -> nx_snmp_agent_socket), response_packet_ptr,
18247                                                 &(agent_ptr -> nx_snmp_agent_current_manager_ip),
18248                                                 agent_ptr -> nx_snmp_agent_current_manager_port);
18249 
18250     /* Check for successful call.  */
18251     if (status)
18252     {
18253 
18254         /* Release the packet.  */
18255         nx_packet_release(response_packet_ptr);
18256     }
18257 }
18258 #endif  /* !NX_SNMP_DISABLE_V1 && !NX_SNMP_DISABLE_V2 */
18259 
18260 
18261 #ifndef NX_SNMP_DISABLE_V3
18262 /**************************************************************************/
18263 /*                                                                        */
18264 /*  FUNCTION                                               RELEASE        */
18265 /*                                                                        */
18266 /*    _nx_snmp_version_3_process                          PORTABLE C      */
18267 /*                                                           6.3.0        */
18268 /*  AUTHOR                                                                */
18269 /*                                                                        */
18270 /*    Yuxin Zhou, Microsoft Corporation                                   */
18271 /*                                                                        */
18272 /*  DESCRIPTION                                                           */
18273 /*                                                                        */
18274 /*    This function processes the SNMP v3 request from the manager.       */
18275 /*                                                                        */
18276 /*  INPUT                                                                 */
18277 /*                                                                        */
18278 /*    agent_ptr                             Pointer to SNMP agent         */
18279 /*    packet_ptr                            Pointer to packet containing  */
18280 /*                                            the SNMP request            */
18281 /*                                                                        */
18282 /*  OUTPUT                                                                */
18283 /*                                                                        */
18284 /*    None                                                                */
18285 /*                                                                        */
18286 /*  CALLS                                                                 */
18287 /*                                                                        */
18288 /*    _nx_des_encrypt                       Encrypt bytes                 */
18289 /*    _nx_des_decrypt                       Decrypt bytes                 */
18290 /*    _nx_des_key_set                       Set the DES key               */
18291 /*    _nx_md5_digest_calculate              Finalize MD5 calculation      */
18292 /*    _nx_md5_initialize                    Initialize MD5 calculation    */
18293 /*    _nx_md5_update                        Update MD5 calculation        */
18294 /*    nx_packet_allocate                    Allocate response packet      */
18295 /*    nx_packet_release                     Release the packet            */
18296 /*    nx_udp_socket_send                    Send the UDP packet           */
18297 /*    _nx_snmp_utility_error_info_get       Get the error information     */
18298 /*    _nx_snmp_utility_error_info_set       Set the error information     */
18299 /*    _nx_snmp_utility_object_data_get      Get the object data           */
18300 /*    _nx_snmp_utility_object_data_set      Set the object data           */
18301 /*    _nx_snmp_utility_object_id_get        Get the object ID             */
18302 /*    _nx_snmp_utility_object_id_set        Set the object ID             */
18303 /*    _nx_snmp_utility_octet_get            Get octet string              */
18304 /*    _nx_snmp_utility_octet_set            Set octet string              */
18305 /*    _nx_snmp_utility_request_id_get       Get the request ID            */
18306 /*    _nx_snmp_utility_request_id_set       Set the request ID            */
18307 /*    _nx_snmp_utility_request_type_get     Get the request type          */
18308 /*    _nx_snmp_utility_request_type_set_multibyte                         */
18309 /*                                          Set trap request type         */
18310 /*    _nx_snmp_utility_sequence_get         Get the ANS.1 sequence        */
18311 /*    _nx_snmp_utility_sequence_set         Set the ANS.1 sequence        */
18312 /*    _nx_snmp_utility_version_get          Get the SNMP version          */
18313 /*    _nx_snmp_utility_version_set          Set the SNMP version          */
18314 /*    _nx_snmp_version_error_response       Send SNMP Manager error       */
18315 /*    _nx_snmp_version_3_discovery_respond  Send discovery response       */
18316 /*    _nx_sha1_digest_calculate             Finalize SHA calculation      */
18317 /*    _nx_sha1_initialize                   Initialize SHA calculation    */
18318 /*    _nx_sha1_update                       Update SHA calculation        */
18319 /*                                                                        */
18320 /*  CALLED BY                                                             */
18321 /*                                                                        */
18322 /*    _nx_snmp_agent_thread_entry           SNMP Agent thread             */
18323 /*                                                                        */
18324 /*  RELEASE HISTORY                                                       */
18325 /*                                                                        */
18326 /*    DATE              NAME                      DESCRIPTION             */
18327 /*                                                                        */
18328 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
18329 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
18330 /*                                            verified memcpy use cases,  */
18331 /*                                            resulting in version 6.1    */
18332 /*  04-02-2021     Yuxin Zhou               Modified comment(s), and      */
18333 /*                                            improved boundary check,    */
18334 /*                                            checked NULL pointer,       */
18335 /*                                            resulting in version 6.1.6  */
18336 /*  10-31-2023     Bo Chen                  Modified comment(s), improved */
18337 /*                                            buffer length verification, */
18338 /*                                            fixed packet double release,*/
18339 /*                                            resulting in version 6.3.0  */
18340 /*                                                                        */
18341 /**************************************************************************/
_nx_snmp_version_3_process(NX_SNMP_AGENT * agent_ptr,NX_PACKET * packet_ptr)18342 VOID  _nx_snmp_version_3_process(NX_SNMP_AGENT *agent_ptr, NX_PACKET *packet_ptr)
18343 {
18344 
18345 UINT        i, sequence_length, version, request_type, request_length;
18346 UINT        header_sequence_length, security_sequence_length, pdu_sequence_length;
18347 UINT        non_repeaters, max_repetitions, current_repetitions, next_object;
18348 UINT        variable_list_length, variable_length;
18349 ULONG       request_id;
18350 UINT        status, length, objects;
18351 UCHAR       *buffer_ptr;
18352 UCHAR       *error_ptr, *request_type_ptr, *temp_ptr;
18353 UINT        response_length;
18354 UINT        total_variable_length = 0;
18355 NX_PACKET   *response_packet_ptr;
18356 UINT        context_engine_size, context_name_size;
18357 UCHAR       *response_buffer_ptr;
18358 UINT        response_sequence_length, response_header_length, response_security_length, response_pdu_length, response_type_length;
18359 UINT        response_variable_list_length, response_variable_length;
18360 UCHAR       *response_sequence_ptr, *response_header_ptr, *response_security_ptr, *response_pdu_ptr, *response_type_ptr;
18361 UCHAR       *response_variable_list_ptr, *response_variable_ptr;
18362 UCHAR       temp_string[NX_SNMP_DIGEST_SIZE];
18363 UINT        packet_type;
18364 UCHAR       *response_encryption_size_ptr = NX_NULL;
18365 UCHAR       *response_authentication_ptr = NX_NULL, *response_privacy_ptr = NX_NULL;
18366 UCHAR       *request_authentication_ptr = NX_NULL;
18367 UCHAR       key1[NX_SNMP_DIGEST_WORKING_SIZE];
18368 UCHAR       key2[NX_SNMP_DIGEST_WORKING_SIZE];
18369 UINT        authenticate_message = NX_FALSE;
18370 UINT        encrypt_message = NX_FALSE;
18371 UCHAR       message_sec_level;
18372 UINT        mask;
18373 INT         buffer_length;
18374 
18375 
18376 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18377     NX_SNMPV3_DBG_PRINTF("\nReceived a SNMPv3 request\n\r");
18378 #endif
18379 
18380     buffer_length = (INT)(packet_ptr -> nx_packet_length);
18381 
18382     /* Setup a pointer to the buffer.  */
18383     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
18384 
18385     /* Pickup the SEQUENCE field.  */
18386     length =  _nx_snmp_utility_sequence_get(buffer_ptr, &sequence_length, buffer_length);
18387 
18388     /* Check for a valid packet.  */
18389     if (length == 0)
18390     {
18391 
18392         /* Increment the invalid packet error counter.  */
18393         agent_ptr -> nx_snmp_agent_invalid_packets++;
18394 
18395         /* Increment the internal error counter.  */
18396         agent_ptr -> nx_snmp_agent_internal_errors++;
18397 
18398         /* Release the packet.  */
18399         nx_packet_release(packet_ptr);
18400 
18401         /* Return to caller.  */
18402         return;
18403     }
18404 
18405     /* Move the buffer pointer up.  */
18406     buffer_ptr =  buffer_ptr + length;
18407 
18408     /* The buffer pointer is moved by the length. Update buffer size */
18409     buffer_length -= (INT)length;
18410 
18411     /* Pickup the SNMP VERSION field.  */
18412     length =  _nx_snmp_utility_version_get(buffer_ptr, &version, buffer_length);
18413 
18414     /* Check for a valid packet.  */
18415     if (length == 0)
18416     {
18417 
18418         /* Increment the invalid packet error counter.  */
18419         agent_ptr -> nx_snmp_agent_invalid_packets++;
18420 
18421         /* Increment the internal error counter.  */
18422         agent_ptr -> nx_snmp_agent_internal_errors++;
18423 
18424         /* Release the packet.  */
18425         nx_packet_release(packet_ptr);
18426 
18427         /* Return to caller.  */
18428         return;
18429     }
18430 
18431     /* Move the buffer pointer up.  */
18432     buffer_ptr =  buffer_ptr + length;
18433 
18434     /* The buffer pointer is moved by the length. Update buffer size */
18435     buffer_length -= (INT)length;
18436 
18437     /***** Now we are positioned in front of the global header.  *****/
18438 
18439     /* Pickup the sequence for the header data, which includes the message ID, maximum reply size,
18440        flags, and the security model.  */
18441     length =  _nx_snmp_utility_sequence_get(buffer_ptr, &header_sequence_length, buffer_length);
18442 
18443     /* Check for a valid packet.  */
18444     if (length == 0)
18445     {
18446 
18447         /* Increment the invalid packet error counter.  */
18448         agent_ptr -> nx_snmp_agent_invalid_packets++;
18449 
18450         /* Increment the internal error counter.  */
18451         agent_ptr -> nx_snmp_agent_internal_errors++;
18452 
18453         /* Release the packet.  */
18454         nx_packet_release(packet_ptr);
18455 
18456         /* Return to caller.  */
18457         return;
18458     }
18459 
18460     /* Position to the next field.  */
18461     buffer_ptr =  buffer_ptr + length;
18462 
18463     /* The buffer pointer is moved by the length. Update buffer size */
18464     buffer_length -= (INT)length;
18465 
18466     /********************************************************/
18467     /*                      Get the message ID              */
18468     /********************************************************/
18469     length =  _nx_snmp_utility_request_id_get(buffer_ptr, &(agent_ptr -> nx_snmp_agent_v3_message_id), buffer_length);
18470 
18471     /* Check for a valid packet.  */
18472     if (length == 0)
18473     {
18474 
18475         /* Increment the invalid packet error counter.  */
18476         agent_ptr -> nx_snmp_agent_invalid_packets++;
18477 
18478         /* Increment the internal error counter.  */
18479         agent_ptr -> nx_snmp_agent_internal_errors++;
18480 
18481         /* Release the packet.  */
18482         nx_packet_release(packet_ptr);
18483 
18484         /* Return to caller.  */
18485         return;
18486     }
18487 
18488     /* Position to the next field.  */
18489     buffer_ptr =  buffer_ptr + length;
18490 
18491     /* The buffer pointer is moved by the length. Update buffer size */
18492     buffer_length -= (INT)length;
18493 
18494     /********************************************************/
18495     /*                      Get the message size            */
18496     /********************************************************/
18497     length =  _nx_snmp_utility_request_id_get(buffer_ptr, &(agent_ptr -> nx_snmp_agent_v3_message_size), buffer_length);
18498 
18499     /* Check for a valid packet.  */
18500     if (length == 0)
18501     {
18502 
18503         /* Increment the invalid packet error counter.  */
18504         agent_ptr -> nx_snmp_agent_invalid_packets++;
18505 
18506         /* Increment the internal error counter.  */
18507         agent_ptr -> nx_snmp_agent_internal_errors++;
18508 
18509         /* Release the packet.  */
18510         nx_packet_release(packet_ptr);
18511 
18512         /* Return to caller.  */
18513         return;
18514     }
18515 
18516     /* Position to the next field.  */
18517     buffer_ptr =  buffer_ptr + length;
18518 
18519     /* The buffer pointer is moved by the length. Update buffer size */
18520     buffer_length -= (INT)length;
18521 
18522     /********************************************************/
18523     /*                Get the security options              */
18524     /********************************************************/
18525     length =  _nx_snmp_utility_octet_get(buffer_ptr, &(agent_ptr -> nx_snmp_agent_v3_message_security_options),
18526                                          sizeof(agent_ptr -> nx_snmp_agent_v3_message_security_options), &status, buffer_length);
18527 
18528     /* Check for a valid packet.  */
18529     if (length == 0)
18530     {
18531 
18532         /* Increment the invalid packet error counter.  */
18533         agent_ptr -> nx_snmp_agent_invalid_packets++;
18534 
18535         /* Increment the internal error counter.  */
18536         agent_ptr -> nx_snmp_agent_internal_errors++;
18537 
18538         /* Release the packet.  */
18539         nx_packet_release(packet_ptr);
18540 
18541         /* Return to caller.  */
18542         return;
18543     }
18544 
18545 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18546     NX_SNMPV3_DBG_PRINTF("Extracted security options: 0x%x\n\r", agent_ptr -> nx_snmp_agent_v3_message_security_options);
18547 #endif
18548 
18549     /* Position to the next field.  */
18550     buffer_ptr =  buffer_ptr + length;
18551 
18552     /* The buffer pointer is moved by the length. Update buffer size */
18553     buffer_length -= (INT)length;
18554 
18555     mask = NX_SNMP_SECURITY_AUTHORIZE | NX_SNMP_SECURITY_PRIVACY ;
18556 
18557     /* We want to mask out the reportable bit. */
18558     agent_ptr -> nx_snmp_agent_v3_message_security_options = (UCHAR)(agent_ptr -> nx_snmp_agent_v3_message_security_options & mask);
18559 
18560     /********************************************************/
18561     /*                Get the security type                 */
18562     /********************************************************/
18563     length =  _nx_snmp_utility_request_id_get(buffer_ptr, &(agent_ptr -> nx_snmp_agent_v3_message_security_type), buffer_length);
18564 
18565     /* Check for a valid packet.  */
18566     if ((length == 0) || (agent_ptr -> nx_snmp_agent_v3_message_security_type != NX_SNMP_USM_SECURITY_MODEL))
18567     {
18568 
18569         /* Increment the invalid packet error counter.  */
18570         agent_ptr -> nx_snmp_agent_invalid_packets++;
18571 
18572         /* Increment the internal error counter.  */
18573         agent_ptr -> nx_snmp_agent_internal_errors++;
18574 
18575         /* Release the packet.  */
18576         nx_packet_release(packet_ptr);
18577 
18578         /* Return to caller.  */
18579         return;
18580     }
18581 
18582     /* Position to the next field.  */
18583     buffer_ptr =  buffer_ptr + length;
18584 
18585     /* The buffer pointer is moved by the length. Update buffer size */
18586     buffer_length -= (INT)length;
18587 
18588     /**** Now we are positioned in front of the security parameters field.  ****/
18589 
18590     /* Determine if there are security parameters.  */
18591     if ((buffer_ptr[0] == NX_SNMP_ANS1_OCTET_STRING) && (buffer_ptr[1]))
18592     {
18593 
18594         /* Position the buffer pointer past the octet string.  */
18595         buffer_ptr =  buffer_ptr + 2;
18596 
18597         /* The buffer pointer is moved. Update buffer size */
18598         buffer_length -= 2;
18599 
18600         /* Pickup the sequence for the security data.  */
18601         length =  _nx_snmp_utility_sequence_get(buffer_ptr, &security_sequence_length, buffer_length);
18602 
18603         /* Check for a valid packet.  */
18604         if (length == 0)
18605         {
18606 
18607             /* Increment the invalid packet error counter.  */
18608             agent_ptr -> nx_snmp_agent_invalid_packets++;
18609 
18610             /* Increment the internal error counter.  */
18611             agent_ptr -> nx_snmp_agent_internal_errors++;
18612 
18613             /* Release the packet.  */
18614             nx_packet_release(packet_ptr);
18615 
18616             /* Return to caller.  */
18617             return;
18618         }
18619 
18620         /* Position to the next field.  */
18621         buffer_ptr =  buffer_ptr + length;
18622 
18623         /* The buffer pointer is moved by the length. Update buffer size */
18624         buffer_length -= (INT)length;
18625 
18626         /********************************************************/
18627         /*         Get the authoritative engine ID              */
18628         /********************************************************/
18629         length =  _nx_snmp_utility_octet_get(buffer_ptr, agent_ptr -> nx_snmp_agent_v3_security_context_engine,
18630                                              sizeof(agent_ptr -> nx_snmp_agent_v3_security_context_engine),
18631                                              &(agent_ptr -> nx_snmp_agent_v3_security_context_engine_size), buffer_length);
18632 
18633         /* Check for a valid packet.  */
18634         if (length == 0)
18635         {
18636 
18637             /* Increment the invalid packet error counter.  */
18638             agent_ptr -> nx_snmp_agent_invalid_packets++;
18639 
18640             /* Increment the internal error counter.  */
18641             agent_ptr -> nx_snmp_agent_internal_errors++;
18642 
18643             /* Release the packet.  */
18644             nx_packet_release(packet_ptr);
18645 
18646             /* Return to caller.  */
18647             return;
18648         }
18649 
18650         /* Position to the next field.  */
18651         buffer_ptr =  buffer_ptr + length;
18652 
18653         /* The buffer pointer is moved by the length. Update buffer size */
18654         buffer_length -= (INT)length;
18655 
18656         /********************************************************/
18657         /*         Get the number of engine reboots             */
18658         /********************************************************/
18659         length =  _nx_snmp_utility_request_id_get(buffer_ptr, &(agent_ptr -> nx_snmp_agent_v3_security_engine_boots), buffer_length);
18660 
18661         /* Check for a valid packet.  */
18662         if (length == 0)
18663         {
18664 
18665             /* Increment the invalid packet error counter.  */
18666             agent_ptr -> nx_snmp_agent_invalid_packets++;
18667 
18668             /* Increment the internal error counter.  */
18669             agent_ptr -> nx_snmp_agent_internal_errors++;
18670 
18671             /* Release the packet.  */
18672             nx_packet_release(packet_ptr);
18673 
18674             /* Return to caller.  */
18675             return;
18676         }
18677 
18678         /* Position to the next field.  */
18679         buffer_ptr =  buffer_ptr + length;
18680 
18681         /* The buffer pointer is moved by the length. Update buffer size */
18682         buffer_length -= (INT)length;
18683 
18684         /********************************************************/
18685         /*         Get the engine boot time                     */
18686         /********************************************************/
18687         length =  _nx_snmp_utility_request_id_get(buffer_ptr, &(agent_ptr -> nx_snmp_agent_v3_security_engine_boot_time), buffer_length);
18688 
18689         /* Check for a valid packet.  */
18690         if (length == 0)
18691         {
18692 
18693             /* Increment the invalid packet error counter.  */
18694             agent_ptr -> nx_snmp_agent_invalid_packets++;
18695 
18696             /* Increment the internal error counter.  */
18697             agent_ptr -> nx_snmp_agent_internal_errors++;
18698 
18699             /* Release the packet.  */
18700             nx_packet_release(packet_ptr);
18701 
18702             /* Return to caller.  */
18703             return;
18704         }
18705 
18706         /* Position to the next field.  */
18707         buffer_ptr =  buffer_ptr + length;
18708 
18709         /* The buffer pointer is moved by the length. Update buffer size */
18710         buffer_length -= (INT)length;
18711 
18712         /********************************************************/
18713         /*         Get the security username                    */
18714         /********************************************************/
18715         length =  _nx_snmp_utility_octet_get(buffer_ptr, agent_ptr -> nx_snmp_agent_v3_security_user_name,
18716                                              sizeof(agent_ptr -> nx_snmp_agent_v3_security_user_name), &(agent_ptr -> nx_snmp_agent_v3_security_user_name_size), buffer_length);
18717 
18718 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18719         NX_SNMPV3_DBG_PRINTF("Security name parsed: %s Size: %d\n\r", &agent_ptr -> nx_snmp_agent_v3_security_user_name[0], agent_ptr -> nx_snmp_agent_v3_security_user_name_size);
18720 
18721 #endif
18722         /* Check for a valid packet.  */
18723         if (length == 0)
18724         {
18725 
18726             /* Increment the invalid packet error counter.  */
18727             agent_ptr -> nx_snmp_agent_invalid_packets++;
18728 
18729             /* Increment the internal error counter.  */
18730             agent_ptr -> nx_snmp_agent_internal_errors++;
18731 
18732             /* Release the packet.  */
18733             nx_packet_release(packet_ptr);
18734 
18735             /* Return to caller.  */
18736             return;
18737         }
18738 
18739         /* Null terminate the User Name.  */
18740         agent_ptr -> nx_snmp_agent_v3_security_user_name[agent_ptr -> nx_snmp_agent_v3_security_user_name_size] =  0;
18741 
18742         /* Position to the next field.  */
18743         buffer_ptr =  buffer_ptr + length;
18744 
18745         /* The buffer pointer is moved by the length. Update buffer size */
18746         buffer_length -= (INT)length;
18747 
18748         /********************************************************/
18749         /*         Get the security authentication parameter    */
18750         /********************************************************/
18751         length =  _nx_snmp_utility_octet_get(buffer_ptr, agent_ptr -> nx_snmp_agent_v3_security_authentication,
18752                                              sizeof(agent_ptr -> nx_snmp_agent_v3_security_authentication), &(agent_ptr -> nx_snmp_agent_v3_security_authentication_size), buffer_length);
18753 
18754         /* Check for a valid packet.  */
18755         if (length == 0)
18756         {
18757 
18758             /* Increment the invalid packet error counter.  */
18759             agent_ptr -> nx_snmp_agent_invalid_packets++;
18760 
18761             /* Increment the internal error counter.  */
18762             agent_ptr -> nx_snmp_agent_internal_errors++;
18763 
18764             /* Release the packet.  */
18765             nx_packet_release(packet_ptr);
18766 
18767             /* Return to caller.  */
18768             return;
18769         }
18770 #ifndef NX_SNMP_NO_SECURITY
18771         /* Remember the pointer to the actual NX_SNMP_DIGEST_SIZE byte authorization parameter.  */
18772 
18773         request_authentication_ptr =  buffer_ptr + 2;
18774 #endif
18775 
18776         /* Position to the next field.  */
18777         buffer_ptr =  buffer_ptr + length;
18778 
18779         /* The buffer pointer is moved by the length. Update buffer size */
18780         buffer_length -= (INT)length;
18781 
18782         pdu_privacy_ptr = buffer_ptr + 2;
18783 
18784         /********************************************************/
18785         /*         Get the security privacy parameter           */
18786         /********************************************************/
18787 
18788         /* This is effectively the salt which will be used to unencrypt the PDU. */
18789         length =  _nx_snmp_utility_octet_get(buffer_ptr, agent_ptr -> nx_snmp_agent_v3_security_privacy,
18790                                              sizeof(agent_ptr -> nx_snmp_agent_v3_security_privacy), &(agent_ptr -> nx_snmp_agent_v3_security_privacy_size), buffer_length);
18791 
18792         /* Check for a valid packet.  */
18793         if (length == 0)
18794         {
18795 
18796             /* Increment the invalid packet error counter.  */
18797             agent_ptr -> nx_snmp_agent_invalid_packets++;
18798 
18799             /* Increment the internal error counter.  */
18800             agent_ptr -> nx_snmp_agent_internal_errors++;
18801 
18802             /* Release the packet.  */
18803             nx_packet_release(packet_ptr);
18804 
18805             /* Return to caller.  */
18806             return;
18807         }
18808     }
18809     else
18810     {
18811 
18812         /* Check if security option is set, but the security parameter is empty.*/
18813         if (agent_ptr -> nx_snmp_agent_v3_message_security_options)
18814         {
18815 
18816             /* Increment the invalid packet error counter.  */
18817             agent_ptr -> nx_snmp_agent_invalid_packets++;
18818 
18819             /* Increment the internal error counter.  */
18820             agent_ptr -> nx_snmp_agent_internal_errors++;
18821 
18822             /* Release the packet.  */
18823             nx_packet_release(packet_ptr);
18824 
18825             /* Return to caller.  */
18826             return;
18827         }
18828 
18829         /* Position past the empty security parameter field.  */
18830         length =  2;
18831     }
18832 
18833     /* Move the buffer pointer up.  */
18834     buffer_ptr =  buffer_ptr + length;
18835 
18836     /* The buffer pointer is moved by the length. Update buffer size */
18837     buffer_length -= (INT)length;
18838 
18839     /* Save the location where the request type is located (after context engine ID and name). */
18840     temp_ptr = buffer_ptr;
18841 
18842     /********************************************************/
18843     /*         Determine if we send a report vs response    */
18844     /********************************************************/
18845 
18846     /* Check if Engine ID is missing AND the security user name is blank. */
18847     if ((agent_ptr -> nx_snmp_agent_v3_security_context_engine_size == 0) &&
18848          (agent_ptr -> nx_snmp_agent_v3_security_user_name_size == 0))
18849     {
18850 
18851 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18852         NX_SNMPV3_DBG_PRINTF("No Engine ID, no user name, this is a discovery request. \n\r");
18853 #endif
18854         agent_ptr -> nx_snmp_agent_unknown_engineid_count++;
18855 
18856         _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_ENGINEID_NUM, buffer_length);
18857 
18858         /* We're done ! Release the received SNMP packet.  */
18859         nx_packet_release(packet_ptr);
18860 
18861         return;
18862     }
18863     /* Check for a mismatched Engine ID. */
18864     else if ((memcmp(&agent_ptr -> nx_snmp_agent_v3_context_engine[0],
18865                      &agent_ptr -> nx_snmp_agent_v3_security_context_engine[0],
18866                      agent_ptr -> nx_snmp_agent_v3_security_context_engine_size) != 0))
18867     {
18868 
18869 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18870         NX_SNMPV3_DBG_PRINTF("Detect a mismatched (non null) engine ID\n\r");
18871 #endif
18872          /*  Increment the invalid packet error counter.  */
18873          agent_ptr -> nx_snmp_agent_unknown_engineid_count++;
18874 
18875          _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_ENGINEID_NUM, buffer_length);
18876 
18877          /* Release the packet.  */
18878          nx_packet_release(packet_ptr);
18879 
18880          /*  We will wait for the browser to make a discovery request (blank engine ID). */
18881         return;
18882     }
18883     /* Check for missing username in the securities header. */
18884     else if (agent_ptr -> nx_snmp_agent_v3_security_user_name_size == 0)
18885     {
18886 
18887         /* Missing user name in the securities field. */
18888 
18889 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18890         NX_SNMPV3_DBG_PRINTF("Request is missing a securities username\n\r");
18891 #endif
18892 
18893         /* Update the unknown or missing user name at least. */
18894         agent_ptr -> nx_snmp_agent_unknown_username_count++;
18895 
18896         _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_USERNAME_NUM, buffer_length);
18897 
18898         /* Release the packet.  */
18899         nx_packet_release(packet_ptr);
18900 
18901         return;
18902     }
18903     /* Check for valid username in the security parameters. */
18904     else if (agent_ptr -> nx_snmp_agent_username_process)
18905     {
18906 
18907         status =  (agent_ptr -> nx_snmp_agent_username_process)(agent_ptr, agent_ptr -> nx_snmp_agent_v3_security_user_name);
18908 
18909         if (status != NX_SUCCESS)
18910         {
18911             /* Unknown user name in the securities field. */
18912 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18913             NX_SNMPV3_DBG_PRINTF("Error in username callback: 0x%x\n\r", status);
18914 #endif
18915 
18916             agent_ptr -> nx_snmp_agent_unknown_username_count++;
18917 
18918             _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_USERNAME_NUM, buffer_length);
18919 
18920             /* Release the packet.  */
18921             nx_packet_release(packet_ptr);
18922 
18923             return;
18924         }
18925 
18926          /* Engine ID and username appear acceptable, Not a disco request. Check the boot time. */
18927 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18928          NX_SNMPV3_DBG_PRINTF("Request has a valid Engine ID and user name. Check the boot and boot time\n\r");
18929 #endif
18930 
18931         /* Check if both sides have authentication enabled.    */
18932         if (((agent_ptr -> nx_snmp_agent_v3_message_security_options & NX_SNMP_SECURITY_AUTHORIZE) >= 1) &&
18933             (agent_ptr -> nx_snmp_agent_v3_authentication_key != NX_NULL))
18934         {
18935             /* They do. So now we must check for mismatched boot data. */
18936             if (agent_ptr -> nx_snmp_agent_v3_context_engine_boots != agent_ptr -> nx_snmp_agent_v3_security_engine_boots)
18937             {
18938 
18939                  /* Boot count does not match.  */
18940                 agent_ptr -> nx_snmp_agent_mismatched_time_count++;
18941 
18942 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18943                  NX_SNMPV3_DBG_PRINTF("Detect a %d'th mismatch in the boot count. Agent boot count: %d; Browser boot count %d\n\r",
18944                                       agent_ptr -> nx_snmp_agent_mismatched_time_count,
18945                                       agent_ptr -> nx_snmp_agent_v3_context_engine_boots,
18946                                       agent_ptr -> nx_snmp_agent_v3_security_engine_boots);
18947 #endif
18948 
18949                  _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_MISMATCHED_TIME_NUM, buffer_length);
18950 
18951                  /* Release the packet.  */
18952                  nx_packet_release(packet_ptr);
18953 
18954                  /* Return to caller.  */
18955                  return;
18956             }
18957             /* Determine if the browser boot time exceeds ours by more than the acceptable limit recommended by RFC 3413 of 150 seconds. */
18958             else if  ((agent_ptr -> nx_snmp_agent_v3_security_engine_boot_time > agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time) &&
18959                       ((agent_ptr -> nx_snmp_agent_v3_security_engine_boot_time - agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time) > NX_SNMP_TIME_WINDOW))
18960             {
18961 
18962                  agent_ptr -> nx_snmp_agent_mismatched_time_count++;
18963 
18964                  /* Outside acceptable limits. Do not reply to this request. */
18965 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18966                  NX_SNMPV3_DBG_PRINTF("Detect %d'th invalid boot time; Agent boot time %d is less than Browser boot time %d\n\r",
18967                                       agent_ptr -> nx_snmp_agent_mismatched_time_count,
18968                                       agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time,
18969                                       agent_ptr -> nx_snmp_agent_v3_security_engine_boot_time);
18970 #endif
18971 
18972                  _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_MISMATCHED_TIME_NUM, buffer_length);
18973 
18974                  /* Release the packet.  */
18975                  nx_packet_release(packet_ptr);
18976 
18977                  /* Return to caller.  */
18978                  return;
18979             }
18980             /* Determine if the our boot time exceeds the browser boot time by more than the acceptable limit recommended by RFC 3413 of 150 seconds. */
18981             else if  ((agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time > agent_ptr -> nx_snmp_agent_v3_security_engine_boot_time) &&
18982                       ((agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time - agent_ptr -> nx_snmp_agent_v3_security_engine_boot_time) > NX_SNMP_TIME_WINDOW))
18983             {
18984 
18985                 agent_ptr -> nx_snmp_agent_mismatched_time_count++;
18986 
18987                  /* Outside acceptable limits. Do not reply to this request. */
18988 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
18989                 NX_SNMPV3_DBG_PRINTF("Detect %d'th invalid boot time; Agent boot time %d is greater than Browser boot time %d\n\r",
18990                                      agent_ptr -> nx_snmp_agent_mismatched_time_count,
18991                                      agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time,
18992                                      agent_ptr -> nx_snmp_agent_v3_security_engine_boot_time);
18993 #endif
18994 
18995                 _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_MISMATCHED_TIME_NUM, buffer_length);
18996 
18997                  /* Release the packet.  */
18998                  nx_packet_release(packet_ptr);
18999 
19000                  /* Return to caller.  */
19001                  return;
19002             }
19003         }
19004     }
19005 
19006 
19007     authenticate_message = NX_FALSE;
19008 
19009     /* Check again if the incoming request specifies authentication. */
19010     if ((agent_ptr -> nx_snmp_agent_v3_message_security_options & NX_SNMP_SECURITY_AUTHORIZE) >= 1)
19011     {
19012 
19013         /* Check if our key is not set up or authentication is not enabled (in which
19014            case the authentication key is NULL anyway). */
19015         if (agent_ptr -> nx_snmp_agent_v3_authentication_key == NX_NULL)
19016         {
19017 
19018             /* The request has an unsupported (as in none) authentication level requested. This is an error. */
19019 
19020 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
19021             NX_SNMPV3_DBG_PRINTF("Mismatch of user security levels detected on line %d\n\r", __LINE__);
19022 #endif
19023             agent_ptr -> nx_snmp_agent_unsupported_sec_count++;
19024 
19025             _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_UNSUPPORTED_SEC_NUM, buffer_length);
19026 
19027             /* We're done ! Release the received SNMP packet.  */
19028             nx_packet_release(packet_ptr);
19029 
19030             return;
19031         }
19032         else if (request_authentication_ptr)
19033         {
19034             /* Otherwise Ok to process authentication parameter. */
19035             authenticate_message = NX_TRUE;
19036         }
19037     }
19038     /* Check if the incoming message is not requesting authentication. */
19039     else
19040     {
19041 
19042        if (agent_ptr -> nx_snmp_agent_v3_authentication_key != NX_NULL)
19043        {
19044 
19045            /* The request has an unsupported (as in none) authentication level requested. This
19046               is an error. */
19047 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
19048             NX_SNMPV3_DBG_PRINTF("Mismatch of user security levels detected on line %d\n\r", __LINE__);
19049 #endif
19050             agent_ptr -> nx_snmp_agent_unsupported_sec_count++;
19051 
19052             _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_UNSUPPORTED_SEC_NUM, buffer_length);
19053 
19054             /* We're done ! Release the received SNMP packet.  */
19055             nx_packet_release(packet_ptr);
19056 
19057             return;
19058        }
19059     }
19060 
19061     /********************************************************/
19062     /*               Check Authentication Parameter         */
19063     /********************************************************/
19064 
19065     /* Are we processing the authentication parameter? */
19066     if (authenticate_message == NX_TRUE)
19067     {
19068 
19069         /* Yes, authentication is required.  */
19070 
19071         /* Mark the location in the request buffer. */
19072         pdu_auth_parm_ptr = request_authentication_ptr;
19073 
19074         /* Clear the authentication field in the message.  To calculate the
19075            digest this must be cleared.  Also position past the string and length.  */
19076         for (i = 0; i < agent_ptr -> nx_snmp_agent_v3_security_authentication_size; i++)
19077         {
19078 
19079             /* Clear the byte.  */
19080             *request_authentication_ptr++ =  0;
19081         }
19082         /* Now determine which authentication is required.  */
19083         if (agent_ptr -> nx_snmp_agent_v3_authentication_key -> nx_snmp_security_key_type == NX_SNMP_MD5_KEY)
19084         {
19085 
19086             /* Copy the base MD5 key into key1.  */
19087             for (i = 0; i < NX_SNMP_MD5_DIGEST_SIZE; i++)
19088             {
19089 
19090                 /* Copy a byte of the base MD5 key.  */
19091                 key1[i] = (agent_ptr -> nx_snmp_agent_v3_authentication_key) -> nx_snmp_security_key[i];
19092             }
19093 
19094             /* Extend key1 to 64 bytes.  */
19095             for (i = NX_SNMP_MD5_DIGEST_SIZE; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
19096             {
19097                 key1[i] =  0;
19098             }
19099 
19100             /* Create key1 and key2.  */
19101             for (i = 0; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
19102             {
19103                 key2[i] = key1[i] ^ 0x5C;
19104                 key1[i] = key1[i] ^ 0x36;
19105             }
19106 
19107             /* Calculate the MAC.  */
19108             _nx_md5_initialize(&(agent_ptr -> nx_snmp_agent_v3_md5_data));
19109 
19110             /* Calculate prepend Key1.  */
19111             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1, NX_SNMP_DIGEST_WORKING_SIZE);
19112 
19113             /* Calculate the message.  */
19114             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length);
19115 
19116             /* Final calculation of the first pass.   */
19117             _nx_md5_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1);
19118 
19119             /* Prepare to calculate the final MAC.  */
19120             _nx_md5_initialize(&(agent_ptr -> nx_snmp_agent_v3_md5_data));
19121 
19122             /* Prepend Key2 to the result.  */
19123             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key2, NX_SNMP_DIGEST_WORKING_SIZE);
19124 
19125             /* Calculate the previous result.  */
19126             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1, NX_SNMP_MD5_DIGEST_SIZE);
19127 
19128             /* Calculate the final MAC. */
19129             _nx_md5_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key2);
19130         }
19131         else if (agent_ptr -> nx_snmp_agent_v3_authentication_key -> nx_snmp_security_key_type == NX_SNMP_SHA_KEY)
19132         {
19133 
19134             /* Copy the base SHA key into key1.  */
19135             for (i = 0; i < NX_SNMP_SHA_DIGEST_SIZE; i++)
19136             {
19137 
19138                 /* Copy a byte of the base SHA key.  */
19139                 key1[i] = (agent_ptr -> nx_snmp_agent_v3_authentication_key) -> nx_snmp_security_key[i];
19140             }
19141 
19142             /* Extend key1 to 64 bytes.  */
19143             for (i = NX_SNMP_SHA_DIGEST_SIZE; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
19144             {
19145                 key1[i] =  0;
19146             }
19147 
19148             /* Create key1 and key2.  */
19149             for (i = 0; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
19150             {
19151                 key2[i] = key1[i] ^ 0x5C;
19152                 key1[i] = key1[i] ^ 0x36;
19153             }
19154 
19155             /* Calculate the MAC.  */
19156             _nx_sha1_initialize(&(agent_ptr -> nx_snmp_agent_v3_sha_data));
19157 
19158             /* Calculate prepend Key1.  */
19159             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1, NX_SNMP_DIGEST_WORKING_SIZE);
19160 
19161             /* Calculate the message.  */
19162             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length);
19163 
19164             /* Final calculation of the first pass.   */
19165             _nx_sha1_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1);
19166 
19167              /* Prepare to calculate the final MAC.  */
19168             _nx_sha1_initialize(&(agent_ptr -> nx_snmp_agent_v3_sha_data));
19169 
19170             /* Prepend Key2 to the result.  */
19171             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key2, NX_SNMP_DIGEST_WORKING_SIZE);
19172 
19173             /* Calculate the previous result.  */
19174             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1, NX_SNMP_SHA_DIGEST_SIZE);
19175 
19176             /* Calculate the final MAC. */
19177             _nx_sha1_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key2);
19178         }
19179         else
19180         {
19181 
19182 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
19183             NX_SNMPV3_DBG_PRINTF("Authentication error. Drop the request. Line %d \n\r", __LINE__);
19184 #endif
19185             /* Increment the authentication error counter.  */
19186             agent_ptr -> nx_snmp_agent_authentication_errors++;
19187 
19188             /* Release the original packet.  */
19189             nx_packet_release(packet_ptr);
19190 
19191             /* Return to caller.  */
19192             return;
19193         }
19194 
19195         /* At this point, key2 contains the computed digest of the message.  If this doesn't match,
19196            then the message is invalid.  */
19197         for (i = 0; i < NX_SNMP_DIGEST_SIZE; i++)
19198         {
19199 
19200             /* Check for a mismatch.  */
19201             if (key2[i] != agent_ptr -> nx_snmp_agent_v3_security_authentication[i])
19202             {
19203 
19204 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
19205                 NX_SNMPV3_DBG_PRINTF("Authentication mismatch. Drop the request. Line %d \n\r", __LINE__);
19206 #endif
19207                 /* We are not. Increment the authentication error counter.  */
19208                 agent_ptr -> nx_snmp_agent_authentication_errors++;
19209 
19210                 /* Release the original packet.  */
19211                 nx_packet_release(packet_ptr);
19212 
19213                 /* Return to caller.  */
19214                 return;
19215             }
19216         }
19217     }
19218 
19219     /* Now prepare response message so we can process the variables one by one.  */
19220 
19221     /* Determine which packet type we allocate based on the destination address type.  */
19222     if (agent_ptr -> nx_snmp_agent_current_manager_ip.nxd_ip_version == NX_IP_VERSION_V4)
19223     {
19224         packet_type = NX_IPv4_UDP_PACKET;
19225     }
19226     else if (agent_ptr -> nx_snmp_agent_current_manager_ip.nxd_ip_version == NX_IP_VERSION_V6)
19227     {
19228 
19229 #ifndef FEATURE_NX_IPV6
19230 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
19231         NX_SNMPV3_DBG_PRINTF("Device not enabled for IPv6\n\r");
19232 #endif /* NX_SNMPV3_PRINT_DEBUG_MESSAGE*/
19233 
19234         /* Release the packet.  */
19235         nx_packet_release(packet_ptr);
19236 
19237         return;
19238 #else
19239         packet_type = NX_IPv6_UDP_PACKET;
19240 #endif  /* FEATURE_NX_IPV6 */
19241 
19242     }
19243     else
19244     {
19245 
19246         /* Release the original packet.  */
19247         nx_packet_release(packet_ptr);
19248 
19249         return;
19250     }
19251 
19252     /* Allocate the packet for the SNMP response.  */
19253     status =  nx_packet_allocate(agent_ptr -> nx_snmp_agent_packet_pool_ptr, &response_packet_ptr, packet_type, NX_SNMP_AGENT_TIMEOUT);
19254 
19255     /* Determine if a response packet was allocated.  */
19256     if (status)
19257     {
19258 
19259 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
19260         NX_SNMPV3_DBG_PRINTF("Response packet allocate error. Status: 0x%x\n\r", status);
19261 #endif
19262 
19263         /* Increment the packet allocation error counter.  */
19264         agent_ptr -> nx_snmp_agent_allocation_errors++;
19265 
19266         /* Release the original packet.  */
19267         nx_packet_release(packet_ptr);
19268 
19269         /* Return to caller.  */
19270         return;
19271     }
19272 
19273     memset(response_packet_ptr -> nx_packet_prepend_ptr, 0,
19274            (UINT)(response_packet_ptr -> nx_packet_data_end - response_packet_ptr -> nx_packet_prepend_ptr));
19275 
19276     /* Initialize the counters required for the length fields of the response packet.  */
19277     response_sequence_length =       0;
19278     response_header_length =         0;
19279     response_security_length =       0;
19280     response_pdu_length =            0;
19281     response_type_length =           0;
19282     response_variable_list_length =  0;
19283 
19284     /* Setup a pointer to the response packet's buffer area.  */
19285     response_buffer_ptr =  response_packet_ptr -> nx_packet_prepend_ptr;
19286 
19287     /* This is also the response sequence pointer. Remember it since we are going to have to
19288        update it later with the actual length of the response.  */
19289     response_sequence_ptr =  response_buffer_ptr;
19290 
19291     /* First, write the sequence in the response packet.  A zero is written for now.  This will be
19292        updated later.  */
19293     response_length =  _nx_snmp_utility_sequence_set(response_buffer_ptr, 0, response_packet_ptr -> nx_packet_data_end);
19294 
19295     /* Check for a valid operation.  */
19296     if (response_length == 0)
19297     {
19298 
19299         /* Increment the internal error counter.  */
19300         agent_ptr -> nx_snmp_agent_internal_errors++;
19301 
19302         /* Release the response packet too.  */
19303         nx_packet_release(response_packet_ptr);
19304 
19305         /* Release the original packet.  */
19306         nx_packet_release(packet_ptr);
19307 
19308         /* Return to caller.  */
19309         return;
19310     }
19311 
19312     /* Move the response buffer pointer up.  */
19313     response_buffer_ptr =  response_buffer_ptr + response_length;
19314 
19315     /********************************************************/
19316     /*               Set the Version ID                     */
19317     /********************************************************/
19318     response_length =  _nx_snmp_utility_version_set(response_buffer_ptr, NX_SNMP_VERSION_3, response_packet_ptr -> nx_packet_data_end);
19319 
19320     /* Check for a valid operation.  */
19321     if (response_length == 0)
19322     {
19323 
19324         /* Increment the internal error counter.  */
19325         agent_ptr -> nx_snmp_agent_internal_errors++;
19326 
19327         /* Release the response packet.  */
19328         nx_packet_release(response_packet_ptr);
19329 
19330         /* Release the original packet.  */
19331         nx_packet_release(packet_ptr);
19332 
19333         /* Return to caller.  */
19334         return;
19335     }
19336 
19337     /* Move the response buffer pointer up.  */
19338     response_buffer_ptr =  response_buffer_ptr + response_length;
19339 
19340     /* Adjust the response sequence length.  */
19341     response_sequence_length =  response_sequence_length + response_length;
19342 
19343     /* Save the pointer to the global header.  */
19344     response_header_ptr =  response_buffer_ptr;
19345 
19346     /* Write the sequence for the global header in the response packet.  A zero is written for now.
19347        This will be updated later.  */
19348     response_length =  _nx_snmp_utility_sequence_set(response_buffer_ptr, 0, response_packet_ptr -> nx_packet_data_end);
19349 
19350     /* Check for a valid operation.  */
19351     if (response_length == 0)
19352     {
19353 
19354         /* Increment the internal error counter.  */
19355         agent_ptr -> nx_snmp_agent_internal_errors++;
19356 
19357         /* Release the response packet too.  */
19358         nx_packet_release(response_packet_ptr);
19359 
19360         /* Release the original packet.  */
19361         nx_packet_release(packet_ptr);
19362 
19363         /* Return to caller.  */
19364         return;
19365     }
19366 
19367     /* Move the response buffer pointer up.  */
19368     response_buffer_ptr =  response_buffer_ptr + response_length;
19369 
19370     /* Adjust the response sequence length.  */
19371     response_sequence_length =  response_sequence_length + response_length;
19372 
19373     /********************************************************/
19374     /*               Set the request ID                     */
19375     /********************************************************/
19376     response_length =  _nx_snmp_utility_request_id_set(response_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_message_id, response_packet_ptr -> nx_packet_data_end);
19377 
19378     /* Check for a valid operation.  */
19379     if (response_length == 0)
19380     {
19381 
19382         /* Increment the internal error counter.  */
19383         agent_ptr -> nx_snmp_agent_internal_errors++;
19384 
19385         /* Release the response packet too.  */
19386         nx_packet_release(response_packet_ptr);
19387 
19388         /* Release the original packet.  */
19389         nx_packet_release(packet_ptr);
19390 
19391         /* Return to caller.  */
19392         return;
19393     }
19394 
19395     /* Move the response buffer pointer up.  */
19396     response_buffer_ptr =  response_buffer_ptr + response_length;
19397 
19398     /* Adjust the response sequence length.  */
19399     response_sequence_length =  response_sequence_length + response_length;
19400 
19401     /* Adjust the header sequence length.  */
19402     response_header_length =  response_header_length + response_length;
19403 
19404     /********************************************************/
19405     /*        Set the maximum message size                  */
19406     /********************************************************/
19407     response_length =  _nx_snmp_utility_request_id_set(response_buffer_ptr, (NX_SNMP_PACKET_SIZE - NX_UDP_PACKET), response_packet_ptr -> nx_packet_data_end);
19408 
19409     /* Check for a valid operation.  */
19410     if (response_length == 0)
19411     {
19412 
19413         /* Increment the internal error counter.  */
19414         agent_ptr -> nx_snmp_agent_internal_errors++;
19415 
19416         /* Release the original packet.  */
19417         nx_packet_release(packet_ptr);
19418 
19419         /* Release the response packet too.  */
19420         nx_packet_release(response_packet_ptr);
19421 
19422         /* Return to caller.  */
19423         return;
19424     }
19425 
19426     /* Move the response buffer pointer up.  */
19427     response_buffer_ptr =  response_buffer_ptr + response_length;
19428 
19429     /* Adjust the response sequence length.  */
19430     response_sequence_length =  response_sequence_length + response_length;
19431 
19432     /* Adjust the header sequence length.  */
19433     response_header_length =  response_header_length + response_length;
19434 
19435     /********************************************************/
19436     /*        Set the message security options              */
19437     /********************************************************/
19438     message_sec_level = agent_ptr -> nx_snmp_agent_v3_message_security_options;
19439 
19440     response_length =  _nx_snmp_utility_octet_set(response_buffer_ptr, (UCHAR *)&message_sec_level, 1, response_packet_ptr -> nx_packet_data_end);
19441 
19442     /* Check for a valid operation.  */
19443     if (response_length == 0)
19444     {
19445 
19446         /* Increment the internal error counter.  */
19447         agent_ptr -> nx_snmp_agent_internal_errors++;
19448 
19449         /* Release the original packet.  */
19450         nx_packet_release(packet_ptr);
19451 
19452         /* Release the response packet too.  */
19453         nx_packet_release(response_packet_ptr);
19454 
19455         /* Return to caller.  */
19456         return;
19457     }
19458 
19459     /* Move the response buffer pointer up.  */
19460     response_buffer_ptr =  response_buffer_ptr + response_length;
19461 
19462     /* Adjust the response sequence length.  */
19463     response_sequence_length =  response_sequence_length + response_length;
19464 
19465     /* Adjust the header sequence length.  */
19466     response_header_length =  response_header_length + response_length;
19467 
19468     /****************************************************/
19469     /*             Set the security type                */
19470     /****************************************************/
19471     response_length =  _nx_snmp_utility_request_id_set(response_buffer_ptr, NX_SNMP_USM_SECURITY_MODEL, response_packet_ptr -> nx_packet_data_end);
19472 
19473     /* Check for a valid operation.  */
19474     if (response_length == 0)
19475     {
19476 
19477         /* Increment the internal error counter.  */
19478         agent_ptr -> nx_snmp_agent_internal_errors++;
19479 
19480         /* Release the original packet.  */
19481         nx_packet_release(packet_ptr);
19482 
19483         /* Release the response packet too.  */
19484         nx_packet_release(response_packet_ptr);
19485 
19486         /* Return to caller.  */
19487         return;
19488     }
19489 
19490     /* Move the response buffer pointer up.  */
19491     response_buffer_ptr =  response_buffer_ptr + response_length;
19492 
19493     /* Adjust the response sequence length.  */
19494     response_sequence_length =  response_sequence_length + response_length;
19495 
19496     /* Adjust the header sequence length.  */
19497     response_header_length =  response_header_length + response_length;
19498 
19499     /* At this point, we have successfully built the security header.  Now, we need to build
19500        the security parameters field.  */
19501 
19502     /* First setup the octet string field.  */
19503     response_buffer_ptr[0] =  NX_SNMP_ANS1_OCTET_STRING;
19504     response_buffer_ptr[1] =  0;
19505 
19506     /* Move the response buffer pointer up.  */
19507     response_buffer_ptr =  response_buffer_ptr + 2;
19508 
19509     /* Adjust the response sequence length.  */
19510     response_sequence_length =  response_sequence_length + 2;
19511 
19512     /* Remember the security header length pointer.  */
19513     response_security_ptr =  response_buffer_ptr;
19514 
19515     /* Now set the sequence of the USM security parameters.  */
19516     response_length =  _nx_snmp_utility_sequence_set(response_buffer_ptr, 0, response_packet_ptr -> nx_packet_data_end);
19517 
19518     /* Check for a valid operation.  */
19519     if (response_length == 0)
19520     {
19521 
19522         /* Increment the internal error counter.  */
19523         agent_ptr -> nx_snmp_agent_internal_errors++;
19524 
19525         /* Release the original packet.  */
19526         nx_packet_release(packet_ptr);
19527 
19528         /* Release the response packet too.  */
19529         nx_packet_release(response_packet_ptr);
19530 
19531         /* Return to caller.  */
19532         return;
19533     }
19534 
19535     /* Move the response buffer pointer up.  */
19536     response_buffer_ptr =  response_buffer_ptr + response_length;
19537 
19538     /* Adjust the response sequence length.  */
19539     response_sequence_length =  response_sequence_length + response_length;
19540 
19541     /****************************************************/
19542     /*             Set the Context Engine               */
19543     /****************************************************/
19544     response_length =  _nx_snmp_utility_octet_set(response_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine, agent_ptr -> nx_snmp_agent_v3_context_engine_size, response_packet_ptr -> nx_packet_data_end);
19545 
19546     /* Check for a valid operation.  */
19547     if (response_length == 0)
19548     {
19549 
19550         /* Increment the internal error counter.  */
19551         agent_ptr -> nx_snmp_agent_internal_errors++;
19552 
19553         /* Release the original packet.  */
19554         nx_packet_release(packet_ptr);
19555 
19556         /* Release the response packet too.  */
19557         nx_packet_release(response_packet_ptr);
19558 
19559         /* Return to caller.  */
19560         return;
19561     }
19562 
19563     /* Move the response buffer pointer up.  */
19564     response_buffer_ptr =  response_buffer_ptr + response_length;
19565 
19566     /* Adjust the response sequence length.  */
19567     response_sequence_length =  response_sequence_length + response_length;
19568 
19569     /* Adjust the security sequence length.  */
19570     response_security_length =  response_security_length + response_length;
19571 
19572     /****************************************************/
19573     /*                Set the Boot Count                */
19574     /****************************************************/
19575     if (agent_ptr -> nx_snmp_agent_v3_message_security_options == 0)
19576     {
19577         /* No security, no time synching, so set boot data to zero. */
19578         response_length =  _nx_snmp_utility_request_id_set(response_buffer_ptr, 0, response_packet_ptr -> nx_packet_data_end);
19579     }
19580     else
19581     {
19582         /* Set the actual boot count. */
19583         response_length =  _nx_snmp_utility_request_id_set(response_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine_boots, response_packet_ptr -> nx_packet_data_end);
19584     }
19585 
19586     /* Check for a valid operation.  */
19587     if (response_length == 0)
19588     {
19589 
19590         /* Increment the internal error counter.  */
19591         agent_ptr -> nx_snmp_agent_internal_errors++;
19592 
19593         /* Release the original packet.  */
19594         nx_packet_release(packet_ptr);
19595 
19596         /* Release the response packet too.  */
19597         nx_packet_release(response_packet_ptr);
19598 
19599         /* Return to caller.  */
19600         return;
19601     }
19602 
19603     /* Move the response buffer pointer up.  */
19604     response_buffer_ptr =  response_buffer_ptr + response_length;
19605 
19606     /* Adjust the response sequence length.  */
19607     response_sequence_length =  response_sequence_length + response_length;
19608 
19609     /* Adjust the security sequence length.  */
19610     response_security_length =  response_security_length + response_length;
19611 
19612     /****************************************************/
19613     /*                Set the Boot Time                 */
19614     /****************************************************/
19615 
19616     if (agent_ptr -> nx_snmp_agent_v3_message_security_options == 0)
19617     {
19618         /* No security, no time synching, so set boot data to zero. */
19619         response_length =  _nx_snmp_utility_request_id_set(response_buffer_ptr, 0, response_packet_ptr -> nx_packet_data_end);
19620     }
19621     else
19622     {
19623 
19624         /* Get the tick count since last boot up. */
19625         agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time =  (UINT) (tx_time_get()/NX_IP_PERIODIC_RATE);
19626 
19627         /* Set the actual boot count. */
19628         response_length =  _nx_snmp_utility_request_id_set(response_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time, response_packet_ptr -> nx_packet_data_end);
19629     }
19630 
19631     /* Check for a valid operation.  */
19632     if (response_length == 0)
19633     {
19634 
19635         /* Increment the internal error counter.  */
19636         agent_ptr -> nx_snmp_agent_internal_errors++;
19637 
19638         /* Release the original packet.  */
19639         nx_packet_release(packet_ptr);
19640 
19641         /* Release the response packet too.  */
19642         nx_packet_release(response_packet_ptr);
19643 
19644         /* Return to caller.  */
19645         return;
19646     }
19647 
19648     /* Move the response buffer pointer up.  */
19649     response_buffer_ptr =  response_buffer_ptr + response_length;
19650 
19651     /* Adjust the response sequence length.  */
19652     response_sequence_length =  response_sequence_length + response_length;
19653 
19654     /* Adjust the security sequence length.  */
19655     response_security_length =  response_security_length + response_length;
19656 
19657     /****************************************************/
19658     /*             Set the security user name           */
19659     /****************************************************/
19660 
19661     /* (Use the security name in the request message) */
19662     response_length =  _nx_snmp_utility_octet_set(response_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_security_user_name, agent_ptr -> nx_snmp_agent_v3_security_user_name_size, response_packet_ptr -> nx_packet_data_end);
19663 
19664     /* Check for a valid operation.  */
19665     if (response_length == 0)
19666     {
19667 
19668         /* Increment the internal error counter.  */
19669         agent_ptr -> nx_snmp_agent_internal_errors++;
19670 
19671         /* Release the original packet.  */
19672         nx_packet_release(packet_ptr);
19673 
19674         /* Release the response packet too.  */
19675         nx_packet_release(response_packet_ptr);
19676 
19677         /* Return to caller.  */
19678         return;
19679     }
19680 
19681     /* Move the response buffer pointer up.  */
19682     response_buffer_ptr =  response_buffer_ptr + response_length;
19683 
19684     /* Adjust the response sequence length.  */
19685     response_sequence_length =  response_sequence_length + response_length;
19686 
19687     /* Adjust the security sequence length.  */
19688     response_security_length =  response_security_length + response_length;
19689 
19690     /* Initialize the temporary string to zero. */
19691     for (i = 0; i < NX_SNMP_DIGEST_SIZE; i++)
19692       temp_string[i] =  0;
19693 
19694     /****************************************************/
19695     /*      Set the security Authentication parameter   */
19696     /****************************************************/
19697 
19698     /* Now setup the authentication parameter if authentication is enabled, and only if called for.   */
19699     if (authenticate_message == NX_TRUE)
19700     {
19701 
19702 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
19703         NX_SNMPV3_DBG_PRINTF("Authenticating: initialize auth parameter to zero in response packet. (Line %d) \n\r", __LINE__);
19704 #endif
19705 
19706         /* All set to add an authentication parameter. For now, set to all zeroes. */
19707         response_length =  _nx_snmp_utility_octet_set(response_buffer_ptr, temp_string, NX_SNMP_DIGEST_SIZE, response_packet_ptr -> nx_packet_data_end);
19708 
19709         /* Remember the pointer to the actual NX_SNMP_DIGEST_SIZE byte authorization parameter.  */
19710         response_authentication_ptr =  response_buffer_ptr + 2;
19711     }
19712     else
19713     {
19714 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
19715         NX_SNMPV3_DBG_PRINTF("Not Authenticating: set auth parameter to null in response packet. (Line %d) \n\r", __LINE__);
19716 #endif
19717         /* No security enabled so set this as an empty parameter. */
19718         response_length =  _nx_snmp_utility_octet_set(response_buffer_ptr, temp_string,0, response_packet_ptr -> nx_packet_data_end);
19719 
19720     }
19721 
19722     /* Check for a valid operation.  */
19723     if (response_length == 0)
19724     {
19725 
19726         /* Increment the internal error counter.  */
19727         agent_ptr -> nx_snmp_agent_internal_errors++;
19728 
19729         /* Release the original packet.  */
19730         nx_packet_release(packet_ptr);
19731 
19732         /* Release the response packet too.  */
19733         nx_packet_release(response_packet_ptr);
19734 
19735         /* Return to caller.  */
19736         return;
19737     }
19738 
19739     /* Move the response buffer pointer up.  */
19740     response_buffer_ptr =  response_buffer_ptr + response_length;
19741 
19742     /* Adjust the response sequence length.  */
19743     response_sequence_length =  response_sequence_length + response_length;
19744 
19745     /* Adjust the security sequence length.  */
19746     response_security_length =  response_security_length + response_length;
19747 
19748     encrypt_message = NX_FALSE;
19749 
19750     /* Check if the incoming request specifies authentication. A discovery request should not have
19751        the authentication (or encxryption) flags set. */
19752     if ((agent_ptr -> nx_snmp_agent_v3_message_security_options & NX_SNMP_SECURITY_PRIVACY) >= 2)
19753     {
19754 
19755         /* Check if our key is not set up or privacy is not enabled (in which
19756            case the privacy key is NULL anyway). */
19757         if (agent_ptr -> nx_snmp_agent_v3_privacy_key == NX_NULL)
19758         {
19759 
19760             /* The request has an unsupported (as in none) privacy level requested. This is an error. */
19761 
19762 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
19763             NX_SNMPV3_DBG_PRINTF("Mismatch of user security levels (privacy) detected on line %d\n\r", __LINE__);
19764 #endif
19765             agent_ptr -> nx_snmp_agent_unsupported_sec_count++;
19766 
19767             _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_UNSUPPORTED_SEC_NUM, buffer_length);
19768 
19769             /* Release the response packet too.  */
19770             nx_packet_release(response_packet_ptr);
19771 
19772             /* We're done ! Release the received SNMP packet.  */
19773             nx_packet_release(packet_ptr);
19774 
19775             return;
19776         }
19777         else
19778         {
19779             /* Otherwise Ok to process encrypt/decrypt SNMPv3 data. */
19780             encrypt_message = NX_TRUE;
19781         }
19782     }
19783 
19784     /* Check if the incoming message is not requesting privacy. */
19785     else
19786     {
19787 
19788        if (agent_ptr -> nx_snmp_agent_v3_privacy_key != NX_NULL)
19789        {
19790 
19791            /* The request has an unsupported (as in none) privacy level requested. This
19792               is an error. */
19793 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
19794             NX_SNMPV3_DBG_PRINTF("Mismatch of user security levels (privacy) detected on line %d\n\r", __LINE__);
19795 #endif
19796             agent_ptr -> nx_snmp_agent_unsupported_sec_count++;
19797 
19798             _nx_snmp_version_3_report_send(agent_ptr, buffer_ptr, NX_SNMP_DISCOVERY_RESPONSE_UNSUPPORTED_SEC_NUM, buffer_length);
19799 
19800             /* Release the response packet too.  */
19801             nx_packet_release(response_packet_ptr);
19802 
19803             /* We're done ! Release the received SNMP packet.  */
19804             nx_packet_release(packet_ptr);
19805 
19806             return;
19807        }
19808     }
19809 
19810     /****************************************************/
19811     /*      Set the security Privacy parameter          */
19812     /****************************************************/
19813 
19814     /* Are we applying encryption to our response? */
19815     if (encrypt_message == NX_FALSE)
19816     {
19817 
19818         /* No, so set the privacy field as an empty parameter. */
19819         response_length =  _nx_snmp_utility_octet_set(response_buffer_ptr, temp_string,0, response_packet_ptr -> nx_packet_data_end);
19820     }
19821     else
19822     {
19823 
19824         /* Initialize the 8 character privacy parameter (salt) to all zeros field initially.  */
19825         response_length =  _nx_snmp_utility_octet_set(response_buffer_ptr, temp_string, 8, response_packet_ptr -> nx_packet_data_end);
19826     }
19827 
19828     /* Check for a valid operation.  */
19829     if (response_length == 0)
19830     {
19831 
19832         /* Increment the internal error counter.  */
19833         agent_ptr -> nx_snmp_agent_internal_errors++;
19834 
19835         /* Release the original packet.  */
19836         nx_packet_release(packet_ptr);
19837 
19838         /* Release the response packet too.  */
19839         nx_packet_release(response_packet_ptr);
19840 
19841         /* Return to caller.  */
19842         return;
19843     }
19844 
19845     if (encrypt_message == NX_TRUE)
19846     {
19847 
19848         /* Remember the pointer to the actual 8 byte privacy parameter.  */
19849         response_privacy_ptr =  response_buffer_ptr + 2;
19850     }
19851 
19852     /* Move the response buffer pointer up.  */
19853     response_buffer_ptr =  response_buffer_ptr + response_length;
19854 
19855     /* Adjust the response sequence length.  */
19856     response_sequence_length =  response_sequence_length + response_length;
19857 
19858     /* Adjust the security sequence length.  */
19859     response_security_length =  response_security_length + response_length;
19860 
19861     /****************************************************/
19862     /*         Decrypt the privacy data                 */
19863     /****************************************************/
19864 
19865     /* Check if encryption is required */
19866     if (encrypt_message == NX_TRUE)
19867     {
19868 
19869         response_encryption_size_ptr = 0x0;
19870 
19871         /* Save the location if we need to return an error message. */
19872         pdu_buffer_ptr = buffer_ptr;
19873 
19874         status = _nx_snmp_agent_decrypt_pdu(agent_ptr, &buffer_ptr, response_buffer_ptr,  &response_encryption_size_ptr, &response_length, &buffer_length);
19875 
19876         if (status != NX_SUCCESS)
19877         {
19878 
19879             /* Increment the privacy error counter.  */
19880             agent_ptr -> nx_snmp_agent_privacy_errors++;
19881 
19882             /* Release the packet.  */
19883             nx_packet_release(packet_ptr);
19884 
19885             /* Release the response packet too.  */
19886             nx_packet_release(response_packet_ptr);
19887 
19888             return;
19889         }
19890 
19891         /* Check the packet length.  */
19892         if (buffer_length < 4)
19893         {
19894 
19895             /* Increment the invalid packet error counter.  */
19896             agent_ptr -> nx_snmp_agent_invalid_packets++;
19897 
19898             /* Increment the internal error counter.  */
19899             agent_ptr -> nx_snmp_agent_internal_errors++;
19900 
19901             /* Release the packet.  */
19902             nx_packet_release(packet_ptr);
19903 
19904             /* Release the response packet too.  */
19905             nx_packet_release(response_packet_ptr);
19906 
19907             return;
19908         }
19909 
19910         UINT temp = 0;
19911 
19912         /* This is typically coded as 0x30 0x29 [or whatever length] 0x04 0x82 or [length] without
19913            the multi byte coding. This will also handle 0x81 "multi byte" coding. */
19914         if (buffer_ptr[3] & NX_SNMP_ANS1_MULTI_BYTES)
19915         {
19916 
19917             /* Get the type of length of the string */
19918             temp = (UINT)(buffer_ptr[3] & 0x7F);
19919 
19920             /* Check the packet length.  */
19921             if (((temp != 1) && (temp !=2)) || ((UINT)buffer_length < (4 + temp)))
19922             {
19923 
19924                 /* Increment the invalid packet error counter.  */
19925                 agent_ptr -> nx_snmp_agent_invalid_packets++;
19926 
19927                 /* Increment the internal error counter.  */
19928                 agent_ptr -> nx_snmp_agent_internal_errors++;
19929 
19930                 /* Release the packet.  */
19931                 nx_packet_release(packet_ptr);
19932 
19933                 /* Release the response packet too.  */
19934                 nx_packet_release(response_packet_ptr);
19935 
19936                 return;
19937             }
19938 
19939             if (temp == 2)
19940             {
19941                 pdu_length =  (UINT) (*(buffer_ptr+ 4) << 8) | ((UINT) *(buffer_ptr+5));
19942             }
19943             else
19944             {
19945                 /* temp == 1.  */
19946                 pdu_length = *(buffer_ptr + 4);
19947             }
19948 
19949         }
19950         else  /* Assume one byte */
19951         {
19952             pdu_length = *(buffer_ptr + 3);
19953         }
19954 
19955         /* Check the pdu length.  */
19956         if (pdu_length > (UINT)(buffer_length - 4 - (INT)temp))
19957         {
19958 
19959             /* Increment the invalid packet error counter.  */
19960             agent_ptr -> nx_snmp_agent_invalid_packets++;
19961 
19962             /* Increment the internal error counter.  */
19963             agent_ptr -> nx_snmp_agent_internal_errors++;
19964 
19965             /* Release the packet.  */
19966             nx_packet_release(packet_ptr);
19967 
19968             /* Release the response packet too.  */
19969             nx_packet_release(response_packet_ptr);
19970 
19971             return;
19972         }
19973 
19974         /* Set pdu_buffer_ptr.  */
19975         pdu_buffer_ptr = buffer_ptr;
19976 
19977         response_length = 4;
19978 
19979     }
19980 
19981     /* Now we can process the request type pointer */
19982     while (temp_ptr < packet_ptr -> nx_packet_append_ptr)
19983     {
19984         temp_ptr++;
19985 
19986         /* Check for Get request type. */
19987         if ((*temp_ptr == NX_SNMP_ANS1_GET_REQUEST) || (*temp_ptr == NX_SNMP_ANS1_GET_BULK_REQUEST)||
19988             (*temp_ptr == NX_SNMP_ANS1_GET_NEXT_REQUEST) || (*temp_ptr == NX_SNMP_ANS1_SET_REQUEST))
19989         {
19990             break;
19991         }
19992     }
19993 
19994     /* Check for invalid packet. */
19995     if (temp_ptr == packet_ptr -> nx_packet_append_ptr)
19996     {
19997 
19998         /* Increment the invalid packet error counter.  */
19999         agent_ptr -> nx_snmp_agent_invalid_packets++;
20000 
20001         /* Increment the internal error counter.  */
20002         agent_ptr -> nx_snmp_agent_internal_errors++;
20003 
20004         /* Release the packet.  */
20005         nx_packet_release(packet_ptr);
20006 
20007         /* Release the response packet too.  */
20008         nx_packet_release(response_packet_ptr);
20009 
20010         /* Return to caller.  */
20011         return;
20012     }
20013 
20014     /* Save the request type pointer.  */
20015     request_type_ptr =  temp_ptr;
20016 
20017     /* Save the response pdu sequence pointer.  */
20018     response_pdu_ptr =  response_buffer_ptr;
20019 
20020     /* Move the response buffer pointer.  */
20021     response_buffer_ptr =  response_buffer_ptr + response_length;
20022 
20023     /* Increment the number of response sequence bytes.  */
20024     response_sequence_length = response_sequence_length + response_length;
20025 
20026     /****************************************************/
20027     /*        Get the PDU sequence length               */
20028     /****************************************************/
20029     length =  _nx_snmp_utility_sequence_get(buffer_ptr, &pdu_sequence_length, buffer_length);
20030 
20031     /* Check for a valid packet.  */
20032     if (length == 0)
20033     {
20034 
20035         /* Increment the invalid packet error counter.  */
20036         agent_ptr -> nx_snmp_agent_invalid_packets++;
20037 
20038         /* Increment the internal error counter.  */
20039         agent_ptr -> nx_snmp_agent_internal_errors++;
20040 
20041         /* Release the packet.  */
20042         nx_packet_release(packet_ptr);
20043 
20044         /* Release the response packet too.  */
20045         nx_packet_release(response_packet_ptr);
20046 
20047         /* Return to caller.  */
20048         return;
20049     }
20050 
20051     /* Move the buffer pointer up.  */
20052     buffer_ptr =  buffer_ptr + length;
20053 
20054     /* The buffer pointer is moved by the length. Update buffer size */
20055     buffer_length -= (INT)length;
20056 
20057     /****************************************************/
20058     /*            Get the PDU engine ID                 */
20059     /****************************************************/
20060     length =  _nx_snmp_utility_octet_get(buffer_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
20061                                          sizeof(agent_ptr -> nx_snmp_agent_current_octet_string), &context_engine_size, buffer_length);
20062 
20063     /* Check for a valid packet.  */
20064     if (length == 0)
20065     {
20066 
20067         /* Increment the invalid packet error counter.  */
20068         agent_ptr -> nx_snmp_agent_invalid_packets++;
20069 
20070         /* Increment the internal error counter.  */
20071         agent_ptr -> nx_snmp_agent_internal_errors++;
20072 
20073         /* Release the packet.  */
20074         nx_packet_release(packet_ptr);
20075 
20076         /* Release the response packet too.  */
20077         nx_packet_release(response_packet_ptr);
20078 
20079         /* Return to caller.  */
20080         return;
20081     }
20082 
20083     /* Move the buffer pointer up.  */
20084     buffer_ptr =  buffer_ptr + length;
20085 
20086     /* The buffer pointer is moved by the length. Update buffer size */
20087     buffer_length -= (INT)length;
20088 
20089 
20090     /******************************************************************************/
20091     /*            SET the PDU Sequence Header if the response is encrypted.       */
20092     /******************************************************************************/
20093 
20094     /* If the message is encrypted we have to insert an PDU "inner" sequence header. Because
20095        we will use the multibyte sequence 0x30 82 xx yy format, we have to update the enclosing
20096        sequences (total response length and pdu length and their respective pointers accordingly.
20097     */
20098     if (encrypt_message)
20099     {
20100 
20101         /* Move the response buffer pointer.  */
20102         response_buffer_ptr =  response_buffer_ptr + 4;
20103 
20104         /* Increment the number of response sequence bytes.  */
20105         response_sequence_length = response_sequence_length + 4;
20106 
20107         /* Increment the response pdu sequence pointer.  */
20108         response_pdu_ptr =  response_pdu_ptr + 4;
20109 
20110          /* Increment the pdu length for this sequence header.  */
20111         response_pdu_length =  response_pdu_length + 4;
20112 
20113     }
20114 
20115     /****************************************************/
20116     /*            SET the PDU engine ID                 */
20117     /****************************************************/
20118     response_length =  _nx_snmp_utility_octet_set(response_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine, agent_ptr -> nx_snmp_agent_v3_context_engine_size, response_packet_ptr -> nx_packet_data_end);
20119 
20120     /* Check for a valid packet.  */
20121     if (response_length == 0)
20122     {
20123 
20124         /* Increment the invalid packet error counter.  */
20125         agent_ptr -> nx_snmp_agent_invalid_packets++;
20126 
20127         /* Increment the internal error counter.  */
20128         agent_ptr -> nx_snmp_agent_internal_errors++;
20129 
20130         /* Release the packet.  */
20131         nx_packet_release(packet_ptr);
20132 
20133         /* Release the response packet too.  */
20134         nx_packet_release(response_packet_ptr);
20135 
20136         /* Return to caller.  */
20137         return;
20138     }
20139 
20140     /* Move the response pointer forward.  */
20141     response_buffer_ptr =  response_buffer_ptr + response_length;
20142 
20143     /* Increment the sequence length.  */
20144     response_sequence_length =       response_sequence_length + response_length;
20145 
20146     /* Increment the pdu length.  */
20147     response_pdu_length =            response_pdu_length + response_length;
20148 
20149     /****************************************************/
20150     /*            Get the PDU engine name               */
20151     /****************************************************/
20152     length =  _nx_snmp_utility_octet_get(buffer_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
20153                                          sizeof(agent_ptr -> nx_snmp_agent_current_octet_string), &context_name_size, buffer_length);
20154 
20155     /* Check for a valid packet.  */
20156     if (length == 0)
20157     {
20158 
20159         /* Increment the invalid packet error counter.  */
20160         agent_ptr -> nx_snmp_agent_invalid_packets++;
20161 
20162         /* Increment the internal error counter.  */
20163         agent_ptr -> nx_snmp_agent_internal_errors++;
20164 
20165         /* Release the packet.  */
20166         nx_packet_release(packet_ptr);
20167 
20168         /* Release the response packet too.  */
20169         nx_packet_release(response_packet_ptr);
20170 
20171         /* Return to caller.  */
20172         return;
20173     }
20174 
20175 
20176     /* The browser uses the context name from the SNMP Agent to confirm
20177        the response is coming from the SNMP Agent it sent the request to. They must match.
20178        The request ID only matches the request with response.  A user may have multiple
20179        requests. There may be circumstances where the SNMP Agent only responds with
20180        one context name. Don't know what that would be. */
20181 
20182     /* Check if the SNMP agent has set a PDU engine name yet. */
20183     if (agent_ptr -> nx_snmp_agent_v3_context_name_size == 0)
20184     {
20185 
20186         /* No it has not, so let's set it here. */
20187 
20188         /* First verify that this is a legal length to copy. */
20189         if (context_name_size > NX_SNMP_MAX_CONTEXT_STRING)
20190         {
20191 
20192             /* Invalid length, this will overrun the buffer. */
20193 
20194             /* Release the packet.  */
20195             nx_packet_release(packet_ptr);
20196 
20197             /* Release the response packet too.  */
20198             nx_packet_release(response_packet_ptr);
20199 
20200             /* Return to caller.  */
20201             return;
20202         }
20203 
20204         memcpy(agent_ptr -> nx_snmp_agent_v3_context_name, agent_ptr -> nx_snmp_agent_current_octet_string, context_name_size); /* Use case of memcpy is verified. */
20205 
20206         agent_ptr -> nx_snmp_agent_v3_context_name_size  = context_name_size;
20207     }
20208 
20209     /* Move the buffer pointer up.  */
20210     buffer_ptr =  buffer_ptr + length;
20211 
20212     /* The buffer pointer is moved by the length. Update buffer size */
20213     buffer_length -= (INT)length;
20214 
20215     /****************************************************/
20216     /*            SET the PDU engine name               */
20217     /****************************************************/
20218 
20219     response_length =  _nx_snmp_utility_octet_set(response_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_name, agent_ptr -> nx_snmp_agent_v3_context_name_size, response_packet_ptr -> nx_packet_data_end);
20220 
20221     /* Check for a valid packet.  */
20222     if (response_length == 0)
20223     {
20224 
20225         /* Increment the invalid packet error counter.  */
20226         agent_ptr -> nx_snmp_agent_invalid_packets++;
20227 
20228         /* Increment the internal error counter.  */
20229         agent_ptr -> nx_snmp_agent_internal_errors++;
20230 
20231         /* Release the packet.  */
20232         nx_packet_release(packet_ptr);
20233 
20234         /* Release the response packet too.  */
20235         nx_packet_release(response_packet_ptr);
20236 
20237         /* Return to caller.  */
20238         return;
20239     }
20240 
20241     /* Move the response pointer forward.  */
20242     response_buffer_ptr =  response_buffer_ptr + response_length;
20243 
20244     /* Save the pointer to the response type.  */
20245     response_type_ptr =  response_buffer_ptr;
20246 
20247     /* Increment the sequence length.  */
20248     response_sequence_length =       response_sequence_length + response_length;
20249 
20250     /* Increment the pdu length.  */
20251     response_pdu_length =            response_pdu_length + response_length;
20252 
20253     /****************************************************/
20254     /*            Get the PDU request type              */
20255     /****************************************************/
20256     length =  _nx_snmp_utility_request_type_get(buffer_ptr, &request_type, &request_length, buffer_length);
20257 
20258     /* Check for a valid packet.  */
20259     if (length == 0)
20260     {
20261 
20262         /* Increment the invalid packet error counter.  */
20263         agent_ptr -> nx_snmp_agent_invalid_packets++;
20264 
20265         /* Increment the internal error counter.  */
20266         agent_ptr -> nx_snmp_agent_internal_errors++;
20267 
20268         /* Release the packet.  */
20269         nx_packet_release(packet_ptr);
20270 
20271         /* Release the response packet too.  */
20272         nx_packet_release(response_packet_ptr);
20273 
20274         /* Return to caller.  */
20275         return;
20276     }
20277 
20278     /* Move the buffer pointer up.  */
20279     buffer_ptr =  buffer_ptr + length;
20280 
20281     /* The buffer pointer is moved by the length. Update buffer size */
20282     buffer_length -= (INT)length;
20283 
20284     agent_ptr -> nx_snmp_agent_request_get_type =  NX_FALSE;
20285     if ((request_type == NX_SNMP_GET_REQUEST) ||
20286         (request_type == NX_SNMP_GET_NEXT_REQUEST) ||
20287         (request_type == NX_SNMP_GET_BULK_REQUEST))
20288     {
20289          agent_ptr -> nx_snmp_agent_request_get_type =  NX_TRUE;
20290     }
20291 
20292 
20293     /****************************************************/
20294     /*            SET the PDU request type              */
20295     /****************************************************/
20296     response_length =  _nx_snmp_utility_request_type_set_multibyte(response_buffer_ptr, NX_SNMP_ANS1_GET_RESPONSE, 0, response_packet_ptr -> nx_packet_data_end);
20297 
20298     /* Check for a valid operation.  */
20299     if (response_length == 0)
20300     {
20301 
20302         /* Increment the internal error counter.  */
20303         agent_ptr -> nx_snmp_agent_internal_errors++;
20304 
20305         /* Release the packet.  */
20306         nx_packet_release(packet_ptr);
20307 
20308         /* Release the response packet too.  */
20309         nx_packet_release(response_packet_ptr);
20310 
20311         /* Return to caller.  */
20312         return;
20313     }
20314 
20315     /* Move the response buffer pointer up.  */
20316     response_buffer_ptr =  response_buffer_ptr + response_length;
20317 
20318     /* Adjust the response sequence length.  */
20319     response_sequence_length =  response_sequence_length + response_length;
20320 
20321     /* Increment the pdu length.  */
20322     response_pdu_length =  response_pdu_length + response_length;
20323 
20324     /****************************************************/
20325     /*            Get the PDU request ID                */
20326     /****************************************************/
20327     length =  _nx_snmp_utility_request_id_get(buffer_ptr, &request_id, buffer_length);
20328 
20329     /* Check for a valid packet.  */
20330     if (length == 0)
20331     {
20332 
20333         /* Increment the invalid packet error counter.  */
20334         agent_ptr -> nx_snmp_agent_invalid_packets++;
20335 
20336         /* Increment the internal error counter.  */
20337         agent_ptr -> nx_snmp_agent_internal_errors++;
20338 
20339         /* Release the packet.  */
20340         nx_packet_release(packet_ptr);
20341 
20342         /* Release the response packet too.  */
20343         nx_packet_release(response_packet_ptr);
20344 
20345         /* Return to caller.  */
20346         return;
20347     }
20348 
20349     /* Move the buffer pointer up.  */
20350     buffer_ptr =  buffer_ptr + length;
20351 
20352     /* The buffer pointer is moved by the length. Update buffer size */
20353     buffer_length -= (INT)length;
20354 
20355     /****************************************************/
20356     /*            SET the PDU request ID                */
20357     /****************************************************/
20358     response_length =  _nx_snmp_utility_request_id_set(response_buffer_ptr, request_id, response_packet_ptr -> nx_packet_data_end);
20359 
20360     /* Check for a valid operation.  */
20361     if (response_length == 0)
20362     {
20363 
20364         /* Increment the internal error counter.  */
20365         agent_ptr -> nx_snmp_agent_internal_errors++;
20366 
20367         /* Release the packet.  */
20368         nx_packet_release(packet_ptr);
20369 
20370         /* Release the response packet too.  */
20371         nx_packet_release(response_packet_ptr);
20372 
20373         /* Return to caller.  */
20374         return;
20375     }
20376 
20377     /* Move the response buffer pointer up.  */
20378     response_buffer_ptr =  response_buffer_ptr + response_length;
20379 
20380     /* Adjust the response sequence length.  */
20381     response_sequence_length =  response_sequence_length + response_length;
20382 
20383     /* Increment the pdu length.  */
20384     response_pdu_length =  response_pdu_length + response_length;
20385 
20386     /* Adjust the response request type length.  */
20387     response_type_length =  response_type_length + response_length;
20388 
20389     /* Save a pointer to the error string.  */
20390     error_ptr =  buffer_ptr;
20391 
20392     /****************************************************/
20393     /*            Get the PDU error information         */
20394     /****************************************************/
20395     /* This is actually used to derive the GETBULK information in SNMP V3 and above.  */
20396     length =  _nx_snmp_utility_error_info_get(buffer_ptr, &non_repeaters, &max_repetitions, buffer_length);
20397 
20398     /* Check for a valid packet.  */
20399     if (length == 0)
20400     {
20401 
20402         /* Increment the invalid packet error counter.  */
20403         agent_ptr -> nx_snmp_agent_invalid_packets++;
20404 
20405         /* Increment the internal error counter.  */
20406         agent_ptr -> nx_snmp_agent_internal_errors++;
20407 
20408         /* Release the packet.  */
20409         nx_packet_release(packet_ptr);
20410 
20411         /* Release the response packet too.  */
20412         nx_packet_release(response_packet_ptr);
20413 
20414         /* Return to caller.  */
20415         return;
20416     }
20417 
20418 #ifndef NX_DISABLE_PACKET_CHAIN
20419 
20420     /* Determine if the received packet size is too big.  */
20421     if (packet_ptr -> nx_packet_next)
20422     {
20423 
20424         /* Call the error handling response routine.  */
20425         _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_TOOBIG, 0);
20426 
20427         /* Release the response packet too.  */
20428         nx_packet_release(response_packet_ptr);
20429 
20430         /* Done, return to caller.  */
20431         return;
20432     }
20433 
20434 #endif /* NX_DISABLE_PACKET_CHAIN */
20435 
20436     /* Move the buffer pointer up.  */
20437     buffer_ptr =  buffer_ptr + length;
20438 
20439     /* The buffer pointer is moved by the length. Update buffer size */
20440     buffer_length -= (INT)length;
20441 
20442     /****************************************************/
20443     /*            SET the PDU error information         */
20444     /****************************************************/
20445     response_length =  _nx_snmp_utility_error_info_set(response_buffer_ptr, 0, 0, response_packet_ptr -> nx_packet_data_end);
20446 
20447     /* Check for a valid operation.  */
20448     if (response_length == 0)
20449     {
20450 
20451         /* Increment the internal error counter.  */
20452         agent_ptr -> nx_snmp_agent_internal_errors++;
20453 
20454         /* Release the packet.  */
20455         nx_packet_release(packet_ptr);
20456 
20457         /* Release the response packet too.  */
20458         nx_packet_release(response_packet_ptr);
20459 
20460         /* Return to caller.  */
20461         return;
20462     }
20463 
20464     /* Move the response buffer pointer up.  */
20465     response_buffer_ptr =  response_buffer_ptr + response_length;
20466 
20467     /* Adjust the response sequence length.  */
20468     response_sequence_length =  response_sequence_length + response_length;
20469 
20470     /* Increment the pdu length.  */
20471     response_pdu_length =  response_pdu_length + response_length;
20472 
20473     /* Adjust the response request type length.  */
20474     response_type_length =  response_type_length + response_length;
20475 
20476     /****************************************************/
20477     /*            Get the PDU variable list length      */
20478     /****************************************************/
20479     length =  _nx_snmp_utility_sequence_get(buffer_ptr, &variable_list_length, buffer_length);
20480 
20481     /* Check for a valid packet.  */
20482     if (length == 0)
20483     {
20484 
20485         /* Increment the invalid packet error counter.  */
20486         agent_ptr -> nx_snmp_agent_invalid_packets++;
20487 
20488         /* Increment the internal error counter.  */
20489         agent_ptr -> nx_snmp_agent_internal_errors++;
20490 
20491         /* Release the packet.  */
20492         nx_packet_release(packet_ptr);
20493 
20494         /* Release the response packet too.  */
20495         nx_packet_release(response_packet_ptr);
20496 
20497         /* Return to caller.  */
20498         return;
20499     }
20500 
20501     /* Move the buffer pointer up.  */
20502     buffer_ptr =  buffer_ptr + length;
20503 
20504     /* The buffer pointer is moved by the length. Update buffer size */
20505     buffer_length -= (INT)length;
20506 
20507     /* At this point we have parsed the incoming SNMP request up to the first
20508        variable.  */
20509 
20510     /* Remember the start of the response's variable list field.  */
20511     response_variable_list_ptr =  response_buffer_ptr;
20512 
20513     /* Setup the variable list response.  For now, the length will be zero.  We
20514        will overwrite this with the actual length later.  */
20515     response_length =  _nx_snmp_utility_sequence_set(response_buffer_ptr, 0, response_packet_ptr -> nx_packet_data_end);
20516 
20517     /* Check for a valid operation.  */
20518     if (response_length == 0)
20519     {
20520 
20521         /* Increment the internal error counter.  */
20522         agent_ptr -> nx_snmp_agent_internal_errors++;
20523 
20524         /* Release the packet.  */
20525         nx_packet_release(packet_ptr);
20526 
20527         /* Release the response packet too.  */
20528         nx_packet_release(response_packet_ptr);
20529 
20530         /* Return to caller.  */
20531         return;
20532     }
20533 
20534     /* Move the response buffer pointer up.  */
20535     response_buffer_ptr =  response_buffer_ptr + response_length;
20536 
20537     /* Adjust the response sequence length.  */
20538     response_sequence_length =  response_sequence_length + response_length;
20539 
20540     /* Increment the pdu length.  */
20541     response_pdu_length =  response_pdu_length + response_length;
20542 
20543     /* Adjust the response request type length.  */
20544     response_type_length =  response_type_length + response_length;
20545 
20546 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
20547     NX_SNMPV3_DBG_PRINTF("Process the variable binding list, line %d \n\r", __LINE__);
20548 #endif
20549 
20550     /* At this point the response buffer is setup to exactly the same position the
20551        SNMP Manager's input buffer is - right before the first variable.  We can
20552        now walk through the variable list to process each request and place the
20553        result in the response buffer.  */
20554     objects =              0;
20555     next_object =          NX_TRUE;
20556     current_repetitions =  max_repetitions;
20557     do
20558     {
20559 
20560         /* Determine if the next object should be retrieved.  */
20561         if (next_object)
20562         {
20563 
20564             /* Pickup the first SNMP Variable length.  */
20565             length =  _nx_snmp_utility_sequence_get(buffer_ptr, &variable_length, buffer_length);
20566 
20567             /* Calculate the total variable size.  */
20568             total_variable_length =  variable_length + length;
20569 
20570             if ((length == 0) || (total_variable_length > variable_list_length) ||
20571                 (total_variable_length > (UINT)buffer_length))
20572             {
20573 
20574                 /* Increment the invalid packet error counter.  */
20575                 agent_ptr -> nx_snmp_agent_invalid_packets++;
20576 
20577                 /* Release the packet.  */
20578                 nx_packet_release(packet_ptr);
20579 
20580                 /* Release the response packet.  */
20581                 nx_packet_release(response_packet_ptr);
20582 
20583                 /* Return to caller.  */
20584                 return;
20585             }
20586 
20587             /* Move the buffer pointer up.  */
20588             buffer_ptr =  buffer_ptr + length;
20589 
20590             /* The buffer pointer is moved by the length. Update buffer size */
20591             buffer_length -= (INT)length;
20592 
20593             /* Now pickup the object ID.  */
20594             length =  _nx_snmp_utility_object_id_get(buffer_ptr, agent_ptr -> nx_snmp_agent_current_octet_string, buffer_length);
20595 
20596             /* Determine if the object retrieval was successful.  */
20597             if (length == 0)
20598             {
20599 
20600                 /* Increment the invalid packet error counter.  */
20601                 agent_ptr -> nx_snmp_agent_invalid_packets++;
20602 
20603                 /* Increment the internal error counter.  */
20604                 agent_ptr -> nx_snmp_agent_internal_errors++;
20605 
20606                 /* Release the packet.  */
20607                 nx_packet_release(packet_ptr);
20608 
20609                 /* Release the response packet.  */
20610                 nx_packet_release(response_packet_ptr);
20611 
20612                 /* Return to caller.  */
20613                 return;
20614             }
20615 
20616             /* Move the buffer pointer up.  */
20617             buffer_ptr =  buffer_ptr + length;
20618 
20619             /* The buffer pointer is moved by the length. Update buffer size */
20620             buffer_length -= (INT)length;
20621 
20622             /* Default the value to NULL.  */
20623             agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type =  0;
20624 
20625             /* Determine if a value is present.  */
20626             if (length != variable_length)
20627             {
20628 
20629                 /* Pickup the value associated with this variable.  */
20630                length =  _nx_snmp_utility_object_data_get(buffer_ptr, &(agent_ptr -> nx_snmp_agent_current_object_data), buffer_length);
20631 
20632                 /* Determine if the object value was successful.  */
20633                 if (length == 0)
20634                 {
20635 
20636                     /* Increment the invalid packet error counter.  */
20637                     agent_ptr -> nx_snmp_agent_invalid_packets++;
20638 
20639                     /* Increment the internal error counter.  */
20640                     agent_ptr -> nx_snmp_agent_internal_errors++;
20641 
20642                     /* Send an SNMP version error response. The packet will be released in the function.  */
20643                     _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_BADVALUE, objects+1);
20644 
20645                     /* Release the response packet.  */
20646                     nx_packet_release(response_packet_ptr);
20647 
20648                     /* Return to caller.  */
20649                     return;
20650                 }
20651                 else
20652                 {
20653 
20654                     /* Move the buffer pointer up.  */
20655                     buffer_ptr =  buffer_ptr + length;
20656 
20657                     /* Update the size of the remaining buffer. */
20658                     buffer_length -= (INT)length;
20659                 }
20660             }
20661         }
20662 
20663         /* At this point, we are ready to call the appropriate application request handling routine.
20664            It is responsible for extracting or placing information in the object data structure.  */
20665         if (request_type == NX_SNMP_ANS1_GET_REQUEST)
20666         {
20667 
20668             /* Increment the total number of get variables.  */
20669             agent_ptr -> nx_snmp_agent_total_get_variables++;
20670 
20671             /* Call the application's GET routine.  */
20672             status =  (agent_ptr -> nx_snmp_agent_get_process)(agent_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
20673                                                                &(agent_ptr -> nx_snmp_agent_current_object_data));
20674         }
20675         else if (request_type == NX_SNMP_ANS1_GET_NEXT_REQUEST)
20676         {
20677 
20678             /* Increment the total number of get variables.  */
20679             agent_ptr -> nx_snmp_agent_total_get_variables++;
20680 
20681             /* Call the application's GETNEXT routine.  */
20682             status =  (agent_ptr -> nx_snmp_agent_getnext_process)(agent_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
20683                                                                    &(agent_ptr -> nx_snmp_agent_current_object_data));
20684         }
20685         else if (request_type == NX_SNMP_ANS1_GET_BULK_REQUEST)
20686         {
20687 
20688             /* Increment the total number of get variables.  */
20689             agent_ptr -> nx_snmp_agent_total_get_variables++;
20690 
20691             /* Clear the next object flag.  */
20692             next_object =  NX_FALSE;
20693 
20694             /* Call the application's GETNEXT routine.  */
20695             status =  (agent_ptr -> nx_snmp_agent_getnext_process)(agent_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
20696                                                                    &(agent_ptr -> nx_snmp_agent_current_object_data));
20697 
20698             /* Decrement the number of non-repeaters.  */
20699             if (non_repeaters)
20700             {
20701 
20702                 /* Decrement the number of non-repeaters.  */
20703                 non_repeaters--;
20704 
20705                 /* Set the next object flag to move to the next entry of the request.  */
20706                 next_object =  NX_TRUE;
20707             }
20708             else
20709             {
20710 
20711                 /* Decrement the repetitions.  */
20712                 if (current_repetitions)
20713                     current_repetitions--;
20714 
20715                 /* Determine if there are more repetitions or if the end of MIB was detected.  */
20716                 if ((current_repetitions == 0) || (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type == NX_SNMP_ANS1_END_OF_MIB_VIEW))
20717                 {
20718 
20719                     /* Reset the current repetition.  */
20720                     current_repetitions =  max_repetitions;
20721 
20722                     /* Set the next object flag to true.  */
20723                     next_object =  NX_TRUE;
20724                 }
20725             }
20726         }
20727         else if (request_type == NX_SNMP_ANS1_SET_REQUEST)
20728         {
20729 
20730             /* Increment the total number of set variables.  */
20731             agent_ptr -> nx_snmp_agent_total_set_variables++;
20732 
20733             /* Call the application's SET routine.  */
20734             status =  (agent_ptr -> nx_snmp_agent_set_process)(agent_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
20735                                                                &(agent_ptr -> nx_snmp_agent_current_object_data));
20736         }
20737         else
20738         {
20739 
20740 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
20741             NX_SNMPV3_DBG_PRINTF("Error processing variable binding items (invalid request type %d). Line %d \n\r", request_type, __LINE__);
20742 #endif
20743             /* Release the response packet.  */
20744             nx_packet_release(response_packet_ptr);
20745 
20746             /* Release the packet. */
20747             nx_packet_release(packet_ptr);
20748 
20749             /* Increment the internal error counter.  */
20750             agent_ptr -> nx_snmp_agent_internal_errors++;
20751 
20752             /* Done, return to caller.  */
20753             return;
20754         }
20755 
20756         /* Check for an error status from the agent's request processing callback routine.  */
20757         if (status)
20758         {
20759 
20760 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
20761             NX_SNMPV3_DBG_PRINTF("Error processing variable binding get request callback. Line %d \n\r",  __LINE__);
20762 #endif
20763             /* Release the response packet.  */
20764             nx_packet_release(response_packet_ptr);
20765 
20766             /* Call the error handling response routine.  */
20767             _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, status, objects);
20768 
20769             /* Done, return to caller.  */
20770             return;
20771         }
20772 
20773         /* Determine if the returning object is valid.  */
20774         if ((agent_ptr -> nx_snmp_agent_current_octet_string[0] != '1') || (agent_ptr -> nx_snmp_agent_current_octet_string[1] != '.') ||
20775             (agent_ptr -> nx_snmp_agent_current_octet_string[2] != '3') || (agent_ptr -> nx_snmp_agent_current_octet_string[3] != '.'))
20776         {
20777 
20778 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
20779             NX_SNMPV3_DBG_PRINTF("Error processing variable binding. Invalid object from get request callback. Line %d \n\r",  __LINE__);
20780 #endif
20781             /* Release the response packet.  */
20782             nx_packet_release(response_packet_ptr);
20783 
20784             /* Release the packet. */
20785             nx_packet_release(packet_ptr);
20786 
20787             /* Increment the internal error counter.  */
20788             agent_ptr -> nx_snmp_agent_internal_errors++;
20789 
20790             /* Done, return to caller.  */
20791             return;
20792         }
20793 
20794         /* Now ensure the returning object type is valid.  */
20795         if ((agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_INTEGER) &&
20796             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_OCTET_STRING) &&
20797             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NULL) &&
20798             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_TIME_TICS) &&
20799             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_GAUGE) &&
20800             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_COUNTER) &&
20801             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_COUNTER64) &&
20802             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_IP_ADDRESS) &&
20803 #ifdef FEATURE_NX_IPV6
20804             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_IPV6_ADDRESS) &&
20805 #endif
20806             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NSAP_ADDRESS) &&
20807             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_OBJECT_ID) &&
20808             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NO_SUCH_OBJECT) &&
20809             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NO_SUCH_INSTANCE) &&
20810             (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_END_OF_MIB_VIEW))
20811         {
20812 
20813 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
20814             NX_SNMPV3_DBG_PRINTF("Error processing variable binding (unknown object type). Line %d \n\r",  __LINE__);
20815 #endif
20816             /* Release the response packet.  */
20817             nx_packet_release(response_packet_ptr);
20818 
20819             /* Release the packet. */
20820             nx_packet_release(packet_ptr);
20821 
20822             /* Increment the internal error counter.  */
20823             agent_ptr -> nx_snmp_agent_internal_errors++;
20824 
20825             /* Done, return to caller.  */
20826             return;
20827         }
20828         /* Everything is okay, place the object and object data into the response buffer.  */
20829 
20830         /* Remember the start of the variable response sequence.  */
20831         response_variable_ptr =  response_buffer_ptr;
20832 
20833         /* Clear the response variable size.  */
20834         response_variable_length =  0;
20835 
20836         /* Determine if there is enough room in the destination for the variable sequence.  */
20837         if ((response_buffer_ptr + 4) >= response_packet_ptr -> nx_packet_data_end)
20838         {
20839 
20840             /* Release the response packet.  */
20841             nx_packet_release(response_packet_ptr);
20842 
20843             /* Call the error handling response routine.  */
20844             _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_TOOBIG, objects);
20845 
20846             /* Done, return to caller.  */
20847             return;
20848         }
20849 
20850         /* Setup the variable response sequence.  For now, the length will be zero.  We
20851            will overwrite this with the actual length later.  */
20852         response_length =  _nx_snmp_utility_sequence_set(response_buffer_ptr, 0, response_packet_ptr -> nx_packet_data_end);
20853 
20854         /* Check for a valid operation.  */
20855         if (response_length == 0)
20856         {
20857 
20858             /* Increment the internal error counter.  */
20859             agent_ptr -> nx_snmp_agent_internal_errors++;
20860 
20861             /* Release the packet.  */
20862             nx_packet_release(packet_ptr);
20863 
20864             /* Release the response packet too.  */
20865             nx_packet_release(response_packet_ptr);
20866 
20867             /* Return to caller.  */
20868             return;
20869         }
20870 
20871         /* Move the response buffer pointer up.  */
20872         response_buffer_ptr =  response_buffer_ptr + response_length;
20873 
20874         /* Adjust the response sequence length.  */
20875         response_sequence_length =  response_sequence_length + response_length;
20876 
20877         /* Increment the pdu length.  */
20878         response_pdu_length =  response_pdu_length + response_length;
20879 
20880         /* Adjust the response request type length.  */
20881         response_type_length =  response_type_length + response_length;
20882 
20883         /* Adjust the response variable list size.  */
20884         response_variable_list_length =  response_variable_list_length + response_length;
20885 
20886         /* Place the object into the response buffer.  */
20887         response_length =  _nx_snmp_utility_object_id_set(response_buffer_ptr, agent_ptr -> nx_snmp_agent_current_octet_string, response_packet_ptr -> nx_packet_data_end);
20888 
20889         /* Check for a valid operation.  */
20890         if (response_length == 0)
20891         {
20892 
20893             /* Release the response packet.  */
20894             nx_packet_release(response_packet_ptr);
20895 
20896             /* Call the error handling response routine.  */
20897             _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_TOOBIG, objects);
20898 
20899             /* Done, return to caller.  */
20900             return;
20901         }
20902 
20903         /* Move the response buffer pointer up.  */
20904         response_buffer_ptr =  response_buffer_ptr + response_length;
20905 
20906         /* Adjust the response sequence length.  */
20907         response_sequence_length =  response_sequence_length + response_length;
20908 
20909         /* Increment the pdu length.  */
20910         response_pdu_length =  response_pdu_length + response_length;
20911 
20912         /* Adjust the response request type length.  */
20913         response_type_length =  response_type_length + response_length;
20914 
20915         /* Adjust the response variable list size.  */
20916         response_variable_list_length =  response_variable_list_length + response_length;
20917 
20918         /* Adjust the response variable size.  */
20919         response_variable_length =  response_variable_length + response_length;
20920 
20921         /* Insert the object's data into the response buffer.  */
20922         response_length =  _nx_snmp_utility_object_data_set(response_buffer_ptr, &(agent_ptr -> nx_snmp_agent_current_object_data), response_packet_ptr -> nx_packet_data_end);
20923 
20924         /* Check for a valid operation.  */
20925         if (response_length == 0)
20926         {
20927 
20928             /* Release the response packet.  */
20929             nx_packet_release(response_packet_ptr);
20930 
20931             /* Call the error handling response routine. This will release the packet  */
20932             _nx_snmp_version_error_response(agent_ptr, packet_ptr, request_type_ptr, error_ptr, NX_SNMP_ERROR_TOOBIG, objects);
20933 
20934             /* Done, return to caller.  */
20935             return;
20936         }
20937 
20938         /* Move the response buffer pointer up.  */
20939         response_buffer_ptr =  response_buffer_ptr + response_length;
20940 
20941         /* Adjust the response sequence length.  */
20942         response_sequence_length =  response_sequence_length + response_length;
20943 
20944         /* Increment the pdu length.  */
20945         response_pdu_length =  response_pdu_length + response_length;
20946 
20947         /* Adjust the response request type length.  */
20948         response_type_length =  response_type_length + response_length;
20949 
20950         /* Adjust the response variable list size.  */
20951         response_variable_list_length =  response_variable_list_length + response_length;
20952 
20953         /* Adjust the response variable size.  */
20954         response_variable_length =  response_variable_length + response_length;
20955 
20956         /* Now update the response variable sequence with the actual variable length.  */
20957         _nx_snmp_utility_sequence_set(response_variable_ptr, response_variable_length, response_packet_ptr -> nx_packet_data_end);
20958 
20959         /* Only update the source object information if the next object flag is set.  */
20960         if (next_object)
20961         {
20962 
20963             /* Decrement the size of the variable list.  */
20964             variable_list_length =  variable_list_length - total_variable_length;
20965 
20966             /* Increment the object counter.  */
20967             objects++;
20968         }
20969 
20970     } while ((variable_list_length) || (next_object == NX_FALSE));
20971 
20972 
20973 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
20974     NX_SNMPV3_DBG_PRINTF("Variable binding processing completed\n\r");
20975 #endif
20976 
20977     /* At this point, several response fields need to be updated with actual lengths.  */
20978     _nx_snmp_utility_sequence_set(response_sequence_ptr, response_sequence_length, response_packet_ptr -> nx_packet_data_end);
20979     _nx_snmp_utility_sequence_set(response_header_ptr, response_header_length, response_packet_ptr -> nx_packet_data_end);
20980     _nx_snmp_utility_sequence_set(response_security_ptr, response_security_length, response_packet_ptr -> nx_packet_data_end);
20981     if (encrypt_message == NX_FALSE)
20982     {
20983         _nx_snmp_utility_sequence_set_1byte(response_pdu_ptr, response_pdu_length, response_packet_ptr -> nx_packet_data_end);
20984     }
20985     _nx_snmp_utility_sequence_set(response_variable_list_ptr, response_variable_list_length, response_packet_ptr -> nx_packet_data_end);
20986     _nx_snmp_utility_request_type_set_multibyte(response_type_ptr, NX_SNMP_ANS1_GET_RESPONSE, response_type_length, response_packet_ptr -> nx_packet_data_end);
20987 
20988     /* Setup the security OCTET string length.  */
20989 
20990     /* Backup to the OCTET string for the security size.  */
20991     response_security_ptr =  response_security_ptr - 2;
20992 
20993     /* Account for the 4 byte Security Sequence field.  */
20994     response_security_length =  response_security_length + 4;
20995 
20996     /* Store the security size.  */
20997     response_security_ptr[1] =  (UCHAR) (response_security_length & 0xFF);
20998 
20999     /* Determine if privacy is required.  If so, encrypt the PDU and setup the response
21000        to have an encryption header.  */
21001     if (encrypt_message == NX_TRUE)
21002     {
21003 
21004         _nx_snmp_agent_encrypt_pdu(agent_ptr, &response_pdu_length, &response_sequence_length,
21005                                    response_encryption_size_ptr, &response_sequence_ptr,
21006                                    response_packet_ptr -> nx_packet_data_end,
21007                                    &response_buffer_ptr, response_privacy_ptr);
21008     }
21009 
21010     /* Now the response packet's pointers must be setup so it can be sent.  */
21011     response_packet_ptr -> nx_packet_length =  (ULONG)(response_buffer_ptr - response_packet_ptr -> nx_packet_prepend_ptr);
21012     response_packet_ptr -> nx_packet_append_ptr =  response_buffer_ptr;
21013 
21014     if (authenticate_message == NX_TRUE)
21015     {
21016 
21017         /* Yes, authentication is required.  */
21018         status = _nx_snmp_agent_add_auth_parameter(agent_ptr, response_packet_ptr, response_authentication_ptr);
21019 
21020         if (status != NX_SUCCESS)
21021         {
21022 
21023 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
21024             NX_SNMPV3_DBG_PRINTF("Authentication error creating authentication parameter. Line %d \n\r",  __LINE__);
21025 #endif
21026             /* Increment the authentication error counter.  */
21027             agent_ptr -> nx_snmp_agent_authentication_errors++;
21028 
21029             /* Release the report packet too.  */
21030             nx_packet_release(response_packet_ptr);
21031 
21032             /* Release the original request packet.  */
21033             nx_packet_release(packet_ptr);
21034 
21035             return;
21036         }
21037     }
21038 
21039     /* Release the original request packet.  */
21040     nx_packet_release(packet_ptr);
21041 
21042     /* Update various statistics.  */
21043     agent_ptr -> nx_snmp_agent_total_bytes_received +=  packet_ptr -> nx_packet_length;
21044     agent_ptr -> nx_snmp_agent_total_bytes_sent +=      response_packet_ptr -> nx_packet_length;
21045     if (request_type == NX_SNMP_ANS1_GET_REQUEST)
21046         agent_ptr -> nx_snmp_agent_get_requests++;
21047     else if (request_type == NX_SNMP_ANS1_GET_NEXT_REQUEST)
21048         agent_ptr -> nx_snmp_agent_getnext_requests++;
21049     else if (request_type == NX_SNMP_ANS1_GET_BULK_REQUEST)
21050         agent_ptr -> nx_snmp_agent_getbulk_requests++;
21051     else if (request_type == NX_SNMP_ANS1_SET_REQUEST)
21052         agent_ptr -> nx_snmp_agent_set_requests++;
21053 
21054     /* Increment the sent packet counter.  */
21055     agent_ptr -> nx_snmp_agent_packets_sent++;
21056 
21057     /* Increment the get responses sent counter.  */
21058     agent_ptr -> nx_snmp_agent_getresponse_sent++;
21059 
21060 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
21061     NX_SNMPV3_DBG_PRINTF("Sending the response to SNMPv3 request on line %d.\n\r", __LINE__);
21062 #endif
21063 
21064     /* Send the response packet back to the requesting SNMP manager.  */
21065     status =  nxd_udp_socket_send(&(agent_ptr -> nx_snmp_agent_socket), response_packet_ptr,
21066                                                 &(agent_ptr -> nx_snmp_agent_current_manager_ip),
21067                                                 agent_ptr -> nx_snmp_agent_current_manager_port);
21068 
21069     /* Determine if the packet needs to be released. */
21070     if (status)
21071     {
21072 
21073         /* Release packet.  */
21074         nx_packet_release(response_packet_ptr);
21075     }
21076 }
21077 #endif  /* NX_SNMP_DISABLE_V3 */
21078 
21079 
21080 #ifndef NX_SNMP_DISABLE_V3
21081 /**************************************************************************/
21082 /*                                                                        */
21083 /*  FUNCTION                                               RELEASE        */
21084 /*                                                                        */
21085 /*    _nx_snmp_version_3_report_send                      PORTABLE C      */
21086 /*                                                           6.3.0        */
21087 /*  AUTHOR                                                                */
21088 /*                                                                        */
21089 /*    Yuxin Zhou, Microsoft Corporation                                   */
21090 /*                                                                        */
21091 /*  DESCRIPTION                                                           */
21092 /*                                                                        */
21093 /*    This function sends reports to the SNMP Manager in response to      */
21094 /*    received requests. These are usually discovery requests, but can    */
21095 /*    also be USM violations such as unknown username, unsupported        */
21096 /*    security level or invalid boot data.                                */
21097 /*                                                                        */
21098 /*  INPUT                                                                 */
21099 /*                                                                        */
21100 /*    agent_ptr                             Pointer to SNMP agent         */
21101 /*    discovery_respond                     Reason for report             */
21102 /*    buffer_length                         Size of buffer data           */
21103 /*                                                                        */
21104 /*  OUTPUT                                                                */
21105 /*                                                                        */
21106 /*    None                                                                */
21107 /*                                                                        */
21108 /*  CALLS                                                                 */
21109 /*                                                                        */
21110 /*    nx_packet_allocate                    Allocate response packet      */
21111 /*    nx_packet_release                     Release the packet            */
21112 /*    nx_udp_socket_send                    Send the UDP packet           */
21113 /*    _nx_snmp_utility_error_info_set       Set the error information     */
21114 /*    _nx_snmp_utility_octet_set            Set the octet string          */
21115 /*    _nx_snmp_utility_request_id_set       Set the request ID            */
21116 /*    _nx_snmp_utility_request_type_set_multibyte                         */
21117 /*                                          Set trap request type         */
21118 /*    _nx_snmp_utility_sequence_set         Set the ANS.1 sequence        */
21119 /*    _nx_snmp_utility_version_set          Set the SNMP version          */
21120 /*    tx_time_get                           Get the time                  */
21121 /*                                                                        */
21122 /*  CALLED BY                                                             */
21123 /*                                                                        */
21124 /*    _nx_snmp_version_3_process            Process SNMP v3 request       */
21125 /*                                                                        */
21126 /*  RELEASE HISTORY                                                       */
21127 /*                                                                        */
21128 /*    DATE              NAME                      DESCRIPTION             */
21129 /*                                                                        */
21130 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
21131 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
21132 /*                                            verified memcpy use cases,  */
21133 /*                                            resulting in version 6.1    */
21134 /*  10-31-2023     Bo Chen                  Modified comment(s), improved */
21135 /*                                            buffer length verification, */
21136 /*                                            resulting in version 6.3.0  */
21137 /*                                                                        */
21138 /**************************************************************************/
_nx_snmp_version_3_report_send(NX_SNMP_AGENT * agent_ptr,UCHAR * buffer_ptr,UINT report_respond,INT buffer_length)21139 VOID  _nx_snmp_version_3_report_send(NX_SNMP_AGENT *agent_ptr, UCHAR *buffer_ptr, UINT report_respond, INT buffer_length)
21140 {
21141 
21142 UINT                status;
21143 UINT                report_length;
21144 NX_PACKET           *report_packet_ptr;
21145 UCHAR               *report_buffer_ptr, *report_sequence_ptr, *report_header_ptr, *report_security_ptr;
21146 UCHAR               *report_authentication_ptr = NX_NULL, *report_pdu_ptr, *report_type_ptr;
21147 UINT                report_sequence_length, report_header_length, report_security_length, report_pdu_length, report_type_length;
21148 UCHAR               *report_encryption_size_ptr = NX_NULL;
21149 UCHAR               temp_string[NX_SNMP_DIGEST_SIZE];
21150 UINT                packet_type;
21151 UCHAR               *report_variable_list_ptr = NX_NULL;
21152 UINT                report_variable_length = 0;
21153 UINT                report_variable_list_length = 0;
21154 UCHAR               *report_variable_ptr = NX_NULL;
21155 ULONG               request_id;
21156 UINT                temp, i;
21157 UINT                length;
21158 UINT                request_type;
21159 UINT                request_length;
21160 UINT                authenticate, encryption, send_reply;
21161 UCHAR               report_security_level;
21162 
21163 
21164 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
21165     NX_SNMPV3_DBG_PRINTF("Processing the report...\n\r");
21166 #endif
21167 
21168     /* Now prepare report message so we can process the report.  */
21169 
21170     /* Determine which packet type we allocate based on the destination address type.  */
21171     if (agent_ptr -> nx_snmp_agent_current_manager_ip.nxd_ip_version == NX_IP_VERSION_V4)
21172     {
21173         packet_type = NX_IPv4_UDP_PACKET;
21174     }
21175     else if (agent_ptr -> nx_snmp_agent_current_manager_ip.nxd_ip_version == NX_IP_VERSION_V6)
21176     {
21177 
21178 #ifndef FEATURE_NX_IPV6
21179 
21180 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
21181         NX_SNMPV3_DBG_PRINTF("Report: IPv6 not enabled on this device.\n\r");
21182 #endif  /* NX_SNMPV3_PRINT_DEBUG_MESSAGE */
21183 
21184         return;
21185 #else
21186         packet_type = NX_IPv6_UDP_PACKET;
21187 #endif  /* FEATURE_NX_IPV6 */
21188     }
21189     else
21190     {
21191          return;
21192     }
21193 
21194     /* Allocate the packet for the SNMP report.  */
21195     status =  nx_packet_allocate(agent_ptr -> nx_snmp_agent_packet_pool_ptr, &report_packet_ptr, packet_type, NX_SNMP_AGENT_TIMEOUT);
21196 
21197     /* Determine if a report packet was allocated.  */
21198     if (status)
21199     {
21200 
21201 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
21202         NX_SNMPV3_DBG_PRINTF("Report: error allocating packet 0x%x.\n\r", status);
21203 #endif
21204         /* Increment the packet allocation error counter.  */
21205         agent_ptr -> nx_snmp_agent_allocation_errors++;
21206 
21207         /* Return to caller.  */
21208         return;
21209     }
21210 
21211     memset(report_packet_ptr -> nx_packet_prepend_ptr, 0,
21212            (UINT)(report_packet_ptr -> nx_packet_data_end - report_packet_ptr -> nx_packet_prepend_ptr));
21213 
21214     /* Initialize the counters required for the length fields of the report packet.  */
21215     report_sequence_length =       0;
21216     report_header_length =         0;
21217     report_security_length =       0;
21218     report_pdu_length =            0;
21219     report_type_length =           0;
21220 
21221     /* Setup a pointer to the report packet's buffer area.  */
21222     report_buffer_ptr =  report_packet_ptr -> nx_packet_prepend_ptr;
21223 
21224     _nx_snmp_agent_security_response_status(agent_ptr, &authenticate, &encryption, &send_reply);
21225 
21226     if (send_reply == NX_FALSE)
21227     {
21228 
21229 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
21230         NX_SNMPV3_DBG_PRINTF("Report: received request with encryption set. Encryption not enabled on device; no report sent.\n\r");
21231 #endif
21232         /* Release the report packet too.  */
21233         nx_packet_release(report_packet_ptr);
21234 
21235         return;
21236     }
21237 
21238     /* We need to set our own security level in case the report security settings differ from the incoming request. */
21239     report_security_level = (UCHAR)authenticate;
21240 
21241     /* Find out if we need to decrypt this message. */
21242     if (encryption == NX_TRUE)
21243     {
21244 
21245         /* We do. Decrypt the data. We need to get the PDU data, request id and other data. */
21246         status = _nx_snmp_agent_decrypt_pdu(agent_ptr, &buffer_ptr, NX_NULL, &report_encryption_size_ptr, &report_length, &buffer_length);
21247 
21248         if (status != NX_SUCCESS)
21249         {
21250 
21251             /* Release the report packet.  */
21252             nx_packet_release(report_packet_ptr);
21253 
21254             return;
21255         }
21256     }
21257 
21258     /* Get the PDU sequence location.  */
21259     length =  _nx_snmp_utility_sequence_get(buffer_ptr, &temp, buffer_length);
21260 
21261     if (length == 0)
21262     {
21263 
21264         /* Increment the internal error counter.  */
21265         agent_ptr -> nx_snmp_agent_internal_errors++;
21266 
21267         /* Release the report packet too.  */
21268         nx_packet_release(report_packet_ptr);
21269 
21270         /* Return to caller.  */
21271         return;
21272     }
21273 
21274     buffer_ptr += length;
21275     buffer_length -= (INT)length;
21276 
21277     /* Get the SNMP v3 PDU context engine field location.  */
21278     length =  _nx_snmp_utility_octet_get(buffer_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
21279                                          sizeof(agent_ptr -> nx_snmp_agent_current_octet_string), &temp, buffer_length);
21280 
21281     if (length == 0)
21282     {
21283         /* Increment the internal error counter.  */
21284         agent_ptr -> nx_snmp_agent_internal_errors++;
21285 
21286         /* Release the report packet too.  */
21287         nx_packet_release(report_packet_ptr);
21288 
21289         /* Return to caller.  */
21290         return;
21291     }
21292 
21293     buffer_ptr += length;
21294     buffer_length -= (INT)length;
21295 
21296     /* Get the SNMP v3 PDU context name field location.  */
21297     length =  _nx_snmp_utility_octet_get(buffer_ptr, agent_ptr -> nx_snmp_agent_current_octet_string,
21298                                          sizeof(agent_ptr -> nx_snmp_agent_current_octet_string), &temp, buffer_length);
21299     if (length == 0)
21300     {
21301         /* Increment the internal error counter.  */
21302         agent_ptr -> nx_snmp_agent_internal_errors++;
21303 
21304         /* Release the report packet too.  */
21305         nx_packet_release(report_packet_ptr);
21306 
21307         /* Return to caller.  */
21308         return;
21309     }
21310 
21311     buffer_ptr += length;
21312     buffer_length -= (INT)length;
21313 
21314     /* Pick up the SNMP Request type and location.  */
21315     length =  _nx_snmp_utility_request_type_get(buffer_ptr, &request_type, &request_length, buffer_length);
21316     if (length == 0)
21317     {
21318         /* Increment the internal error counter.  */
21319         agent_ptr -> nx_snmp_agent_internal_errors++;
21320 
21321         /* Release the report packet too.  */
21322         nx_packet_release(report_packet_ptr);
21323 
21324         /* Return to caller.  */
21325         return;
21326     }
21327 
21328     buffer_ptr += length;
21329     buffer_length -= (INT)length;
21330 
21331     /* Get the SNMP Request ID.  We need this for our report. */
21332     length =  _nx_snmp_utility_request_id_get(buffer_ptr, &request_id, buffer_length);
21333     if (length == 0)
21334     {
21335         /* Increment the internal error counter.  */
21336         agent_ptr -> nx_snmp_agent_internal_errors++;
21337 
21338         /* Release the report packet too.  */
21339         nx_packet_release(report_packet_ptr);
21340 
21341         /* Return to caller.  */
21342         return;
21343     }
21344 
21345     /* This is also the report sequence pointer. Remember it since we are going to have to
21346        update it later with the actual length of the report.  */
21347     report_sequence_ptr =  report_buffer_ptr;
21348 
21349     /* First, write the sequence in the report packet.  A zero is written for now.  This will be
21350        updated later.  */
21351     report_length =  _nx_snmp_utility_sequence_set(report_buffer_ptr, 0, report_packet_ptr -> nx_packet_data_end);
21352 
21353     /* Check for a valid operation.  */
21354     if (report_length == 0)
21355     {
21356 
21357         /* Increment the internal error counter.  */
21358         agent_ptr -> nx_snmp_agent_internal_errors++;
21359 
21360         /* Release the report packet too.  */
21361         nx_packet_release(report_packet_ptr);
21362 
21363         /* Return to caller.  */
21364         return;
21365     }
21366 
21367     /* Move the report buffer pointer up.  */
21368     report_buffer_ptr =  report_buffer_ptr + report_length;
21369 
21370     /********************************************************/
21371     /*                      Set the version ID              */
21372     /********************************************************/
21373     report_length =  _nx_snmp_utility_version_set(report_buffer_ptr, NX_SNMP_VERSION_3, report_packet_ptr -> nx_packet_data_end);
21374 
21375     /* Check for a valid operation.  */
21376     if (report_length == 0)
21377     {
21378 
21379         /* Increment the internal error counter.  */
21380         agent_ptr -> nx_snmp_agent_internal_errors++;
21381 
21382         /* Release the report packet.  */
21383         nx_packet_release(report_packet_ptr);
21384 
21385         /* Return to caller.  */
21386         return;
21387     }
21388 
21389     /* Move the report buffer pointer up.  */
21390     report_buffer_ptr =  report_buffer_ptr + report_length;
21391 
21392     /* Adjust the report sequence length.  */
21393     report_sequence_length =  report_sequence_length + report_length;
21394 
21395     /* Save the pointer to the global header.  */
21396     report_header_ptr =  report_buffer_ptr;
21397 
21398     /* Write the sequence for the global header in the report packet.  A zero is written for now.
21399        This will be updated later.  */
21400     report_length =  _nx_snmp_utility_sequence_set(report_buffer_ptr, 0, report_packet_ptr -> nx_packet_data_end);
21401 
21402     /* Check for a valid operation.  */
21403     if (report_length == 0)
21404     {
21405 
21406         /* Increment the internal error counter.  */
21407         agent_ptr -> nx_snmp_agent_internal_errors++;
21408 
21409         /* Release the report packet too.  */
21410         nx_packet_release(report_packet_ptr);
21411 
21412         /* Return to caller.  */
21413         return;
21414     }
21415 
21416     /* Move the report buffer pointer up.  */
21417     report_buffer_ptr =  report_buffer_ptr + report_length;
21418 
21419     /* Adjust the report sequence length.  */
21420     report_sequence_length =  report_sequence_length + report_length;
21421 
21422     /********************************************************/
21423     /*                      Set the request ID              */
21424     /********************************************************/
21425 
21426     /* This must match the request specified by the discovery request.  */
21427     report_length =  _nx_snmp_utility_request_id_set(report_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_message_id, report_packet_ptr -> nx_packet_data_end);
21428 
21429     /* Check for a valid operation.  */
21430     if (report_length == 0)
21431     {
21432 
21433         /* Increment the internal error counter.  */
21434         agent_ptr -> nx_snmp_agent_internal_errors++;
21435 
21436         /* Release the report packet too.  */
21437         nx_packet_release(report_packet_ptr);
21438 
21439         /* Return to caller.  */
21440         return;
21441     }
21442 
21443     /* Move the report buffer pointer up.  */
21444     report_buffer_ptr =  report_buffer_ptr + report_length;
21445 
21446     /* Adjust the report sequence length.  */
21447     report_sequence_length =  report_sequence_length + report_length;
21448 
21449     /* Adjust the header sequence length.  */
21450     report_header_length =  report_header_length + report_length;
21451 
21452     /********************************************************/
21453     /*              Set the maximum message size            */
21454     /********************************************************/
21455     report_length =  _nx_snmp_utility_request_id_set(report_buffer_ptr, (NX_SNMP_PACKET_SIZE - NX_UDP_PACKET), report_packet_ptr -> nx_packet_data_end);
21456 
21457     /* Check for a valid operation.  */
21458     if (report_length == 0)
21459     {
21460 
21461         /* Increment the internal error counter.  */
21462         agent_ptr -> nx_snmp_agent_internal_errors++;
21463 
21464         /* Release the report packet too.  */
21465         nx_packet_release(report_packet_ptr);
21466 
21467         /* Return to caller.  */
21468         return;
21469     }
21470 
21471     /* Move the report buffer pointer up.  */
21472     report_buffer_ptr =  report_buffer_ptr + report_length;
21473 
21474     /* Adjust the report sequence length.  */
21475     report_sequence_length =  report_sequence_length + report_length;
21476 
21477     /* Adjust the header sequence length.  */
21478     report_header_length =  report_header_length + report_length;
21479 
21480     /********************************************************/
21481     /*                  Set the security options            */
21482     /********************************************************/
21483     report_length =  _nx_snmp_utility_octet_set(report_buffer_ptr, (UCHAR *)&(report_security_level), 1, report_packet_ptr -> nx_packet_data_end);
21484 
21485 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
21486     NX_SNMPV3_DBG_PRINTF("Setting report security level to 0x%x\n\r", report_security_level);
21487 #endif
21488 
21489     /* Check for a valid operation.  */
21490     if (report_length == 0)
21491     {
21492 
21493         /* Increment the internal error counter.  */
21494         agent_ptr -> nx_snmp_agent_internal_errors++;
21495 
21496         /* Release the report packet too.  */
21497         nx_packet_release(report_packet_ptr);
21498 
21499         /* Return to caller.  */
21500         return;
21501     }
21502 
21503     /* Move the report buffer pointer up.  */
21504     report_buffer_ptr =  report_buffer_ptr + report_length;
21505 
21506     /* Adjust the report sequence length.  */
21507     report_sequence_length =  report_sequence_length + report_length;
21508 
21509     /* Adjust the header sequence length.  */
21510     report_header_length =  report_header_length + report_length;
21511 
21512     /********************************************************/
21513     /*                  Set the security type               */
21514     /********************************************************/
21515     report_length =  _nx_snmp_utility_request_id_set(report_buffer_ptr, NX_SNMP_USM_SECURITY_MODEL, report_packet_ptr -> nx_packet_data_end);
21516 
21517     /* Check for a valid operation.  */
21518     if (report_length == 0)
21519     {
21520 
21521         /* Increment the internal error counter.  */
21522         agent_ptr -> nx_snmp_agent_internal_errors++;
21523 
21524         /* Release the report packet too.  */
21525         nx_packet_release(report_packet_ptr);
21526 
21527         /* Return to caller.  */
21528         return;
21529     }
21530 
21531     /* Move the report buffer pointer up.  */
21532     report_buffer_ptr =  report_buffer_ptr + report_length;
21533 
21534     /* Adjust the report sequence length.  */
21535     report_sequence_length =  report_sequence_length + report_length;
21536 
21537     /* Adjust the header sequence length.  */
21538     report_header_length =  report_header_length + report_length;
21539 
21540     /* At this point, we have successfully built the security header.  Now, we need to build
21541        the security parameters field.  */
21542 
21543     /* First setup the octet string field.  */
21544     report_buffer_ptr[0] =  NX_SNMP_ANS1_OCTET_STRING;
21545     report_buffer_ptr[1] =  0;
21546 
21547     /* Move the report buffer pointer up.  */
21548     report_buffer_ptr =  report_buffer_ptr + 2;
21549 
21550     /* Adjust the report sequence length.  */
21551     report_sequence_length =  report_sequence_length + 2;
21552 
21553     /* Remember the security header pointer.  */
21554     report_security_ptr =  report_buffer_ptr;
21555 
21556     report_length =  _nx_snmp_utility_sequence_set(report_buffer_ptr, 0, report_packet_ptr -> nx_packet_data_end);
21557 
21558     /* Check for a valid operation.  */
21559     if (report_length == 0)
21560     {
21561 
21562         /* Increment the internal error counter.  */
21563         agent_ptr -> nx_snmp_agent_internal_errors++;
21564 
21565         /* Release the report packet too.  */
21566         nx_packet_release(report_packet_ptr);
21567 
21568         /* Return to caller.  */
21569         return;
21570     }
21571 
21572     /* Move the report buffer pointer up.  */
21573     report_buffer_ptr =  report_buffer_ptr + report_length;
21574 
21575     /* Adjust the report sequence length.  */
21576     report_sequence_length =  report_sequence_length + report_length;
21577 
21578     /********************************************************/
21579     /*                   Set the context engine             */
21580     /********************************************************/
21581     report_length =  _nx_snmp_utility_octet_set(report_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine, agent_ptr -> nx_snmp_agent_v3_context_engine_size, report_packet_ptr -> nx_packet_data_end);
21582 
21583     /* Check for a valid operation.  */
21584     if (report_length == 0)
21585     {
21586 
21587         /* Increment the internal error counter.  */
21588         agent_ptr -> nx_snmp_agent_internal_errors++;
21589 
21590         /* Release the report packet too.  */
21591         nx_packet_release(report_packet_ptr);
21592 
21593         /* Return to caller.  */
21594         return;
21595     }
21596 
21597     /* Move the report buffer pointer up.  */
21598     report_buffer_ptr =  report_buffer_ptr + report_length;
21599 
21600     /* Adjust the report sequence length.  */
21601     report_sequence_length =  report_sequence_length + report_length;
21602 
21603     /* Adjust the security sequence length.  */
21604     report_security_length =  report_security_length + report_length;
21605 
21606     /********************************************************/
21607     /*                  Set the boot count                  */
21608     /********************************************************/
21609     if (report_respond == NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_ENGINEID_NUM)
21610     {
21611 
21612         /* Set boot count to zero for discovery requests. */
21613         report_length =  _nx_snmp_utility_request_id_set(report_buffer_ptr, 0, report_packet_ptr -> nx_packet_data_end);
21614     }
21615     else
21616     {
21617 
21618         /* Use the current SNMP boot count for all others. */
21619         report_length =  _nx_snmp_utility_request_id_set(report_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine_boots, report_packet_ptr -> nx_packet_data_end);
21620     }
21621 
21622     /* Check for a valid operation.  */
21623     if (report_length == 0)
21624     {
21625 
21626         /* Increment the internal error counter.  */
21627         agent_ptr -> nx_snmp_agent_internal_errors++;
21628 
21629         /* Release the report packet too.  */
21630         nx_packet_release(report_packet_ptr);
21631 
21632         /* Return to caller.  */
21633         return;
21634     }
21635 
21636     /* Move the report buffer pointer up.  */
21637     report_buffer_ptr =  report_buffer_ptr + report_length;
21638 
21639     /* Adjust the report sequence length.  */
21640     report_sequence_length =  report_sequence_length + report_length;
21641 
21642     /* Adjust the security sequence length.  */
21643     report_security_length =  report_security_length + report_length;
21644 
21645     /* Start the time (in ticks) since the previous reboot. */
21646     agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time =  (UINT) (tx_time_get()/NX_IP_PERIODIC_RATE);
21647 
21648     /********************************************************/
21649     /*                  Set the boot time                   */
21650     /********************************************************/
21651     if (report_respond == NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_ENGINEID_NUM)
21652     {
21653 
21654         /* Set boot time to zero. */
21655         report_length =  _nx_snmp_utility_request_id_set(report_buffer_ptr, 0, report_packet_ptr -> nx_packet_data_end);
21656     }
21657     else
21658     {
21659 
21660         /* Start the time (in ticks) since the previous reboot. */
21661         agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time =  (UINT) (tx_time_get()/NX_IP_PERIODIC_RATE);
21662         /* Use the current SNMP boot time. */
21663         report_length =  _nx_snmp_utility_request_id_set(report_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine_boot_time, report_packet_ptr -> nx_packet_data_end);
21664     }
21665 
21666     /* Check for a valid operation.  */
21667     if (report_length == 0)
21668     {
21669 
21670         /* Increment the internal error counter.  */
21671         agent_ptr -> nx_snmp_agent_internal_errors++;
21672 
21673         /* Release the report packet too.  */
21674         nx_packet_release(report_packet_ptr);
21675 
21676         /* Return to caller.  */
21677         return;
21678     }
21679 
21680     /* Move the report buffer pointer up.  */
21681     report_buffer_ptr =  report_buffer_ptr + report_length;
21682 
21683     /* Adjust the report sequence length.  */
21684     report_sequence_length =  report_sequence_length + report_length;
21685 
21686     /* Adjust the security sequence length.  */
21687     report_security_length =  report_security_length + report_length;
21688 
21689     /********************************************************/
21690     /*                Set the security user name            */
21691     /********************************************************/
21692 
21693     /* Set the security user name as specified in the request message.  */
21694     report_length =  _nx_snmp_utility_octet_set(report_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_security_user_name, agent_ptr -> nx_snmp_agent_v3_security_user_name_size, report_packet_ptr -> nx_packet_data_end);
21695 
21696 
21697     /* Check for a valid operation.  */
21698     if (report_length == 0)
21699     {
21700 
21701         /* Increment the internal error counter.  */
21702         agent_ptr -> nx_snmp_agent_internal_errors++;
21703 
21704         /* Release the report packet too.  */
21705         nx_packet_release(report_packet_ptr);
21706 
21707         /* Return to caller.  */
21708         return;
21709     }
21710 
21711     /* Move the report buffer pointer up.  */
21712     report_buffer_ptr =  report_buffer_ptr + report_length;
21713 
21714     /* Adjust the report sequence length.  */
21715     report_sequence_length =  report_sequence_length + report_length;
21716 
21717     /* Adjust the security sequence length.  */
21718     report_security_length =  report_security_length + report_length;
21719 
21720     /* Initialize the temporary string to zero. */
21721     for (i = 0; i < NX_SNMP_DIGEST_SIZE; i++)
21722       temp_string[i] =  0;
21723     /********************************************************/
21724     /*     Set the security authentication parameter        */
21725     /********************************************************/
21726 
21727     if (authenticate == NX_TRUE)
21728     {
21729 
21730 
21731 
21732 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
21733         NX_SNMPV3_DBG_PRINTF("Report: set authentication parameter to zero in report. (Line %d) \n\r", __LINE__);
21734 #endif
21735         /* All set to add an authentication parameter. For now, set to all zeros. */
21736         report_length =  _nx_snmp_utility_octet_set(report_buffer_ptr, temp_string, NX_SNMP_DIGEST_SIZE, report_packet_ptr -> nx_packet_data_end);
21737 
21738         /* Remember the pointer to the actual NX_SNMP_DIGEST_SIZE (12) byte authorization parameter.  */
21739         report_authentication_ptr =  report_buffer_ptr + 2;
21740     }
21741     else
21742     {
21743 
21744 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
21745         NX_SNMPV3_DBG_PRINTF("Report: set authentication parameter to empty. \n\r");
21746 #endif
21747         /* No security enabled so set this as an empty parameter. */
21748         report_length =  _nx_snmp_utility_octet_set(report_buffer_ptr, temp_string, 0, report_packet_ptr -> nx_packet_data_end);
21749     }
21750 
21751     /* Check for a valid operation.  */
21752     if (report_length == 0)
21753     {
21754 
21755         /* Increment the internal error counter.  */
21756         agent_ptr -> nx_snmp_agent_internal_errors++;
21757 
21758         /* Release the report packet too.  */
21759         nx_packet_release(report_packet_ptr);
21760 
21761         /* Return to caller.  */
21762         return;
21763     }
21764 
21765     /* Move the report buffer pointer up.  */
21766     report_buffer_ptr =  report_buffer_ptr + report_length;
21767 
21768     /* Adjust the report sequence length.  */
21769     report_sequence_length =  report_sequence_length + report_length;
21770 
21771     /* Adjust the security sequence length.  */
21772     report_security_length =  report_security_length + report_length;
21773 
21774     /* Set the Privacy Parameter field to empty (encryption/privacy not used in reports).  */
21775     report_length =  _nx_snmp_utility_octet_set(report_buffer_ptr, temp_string, 0, report_packet_ptr -> nx_packet_data_end);
21776 
21777     /* Check for a valid operation.  */
21778     if (report_length == 0)
21779     {
21780 
21781         /* Increment the internal error counter.  */
21782         agent_ptr -> nx_snmp_agent_internal_errors++;
21783 
21784         /* Release the report packet too.  */
21785         nx_packet_release(report_packet_ptr);
21786 
21787         /* Return to caller.  */
21788         return;
21789     }
21790 
21791     /* Move the report buffer pointer up.  */
21792     report_buffer_ptr =  report_buffer_ptr + report_length;
21793 
21794     /* Adjust the report sequence length.  */
21795     report_sequence_length =  report_sequence_length + report_length;
21796 
21797     /* Adjust the security sequence length.  */
21798     report_security_length =  report_security_length + report_length;
21799 
21800     /* Remember the PDU sequence pointer.  */
21801     report_pdu_ptr =  report_buffer_ptr;
21802 
21803     /* Now set the sequence of the PDU.  We will replace this sequence type with 'opaque'
21804        if encryption is required later. */
21805     report_length =  _nx_snmp_utility_sequence_set(report_pdu_ptr, 0, report_packet_ptr -> nx_packet_data_end);
21806 
21807     /* Check for a valid operation.  */
21808     if (report_length == 0)
21809     {
21810 
21811         /* Increment the internal error counter.  */
21812         agent_ptr -> nx_snmp_agent_internal_errors++;
21813 
21814         /* Release the report packet too.  */
21815         nx_packet_release(report_packet_ptr);
21816 
21817         /* Return to caller.  */
21818         return;
21819     }
21820 
21821     /* Move the report buffer pointer up.  */
21822     report_buffer_ptr =  report_buffer_ptr + report_length;
21823 
21824     /* Adjust the report sequence length.  */
21825     report_sequence_length =  report_sequence_length + report_length;
21826 
21827     /********************************************************/
21828     /*                  Set the Context Engine ID           */
21829     /********************************************************/
21830 
21831     /* The Context Engine ID should be the same as the msgAuthoritativeEngine ID since there is no proxy. */
21832     report_length =  _nx_snmp_utility_octet_set(report_buffer_ptr, agent_ptr -> nx_snmp_agent_v3_context_engine,
21833                                                 agent_ptr -> nx_snmp_agent_v3_context_engine_size, report_packet_ptr -> nx_packet_data_end);
21834 
21835     /* Check for a valid operation.  */
21836     if (report_length == 0)
21837     {
21838 
21839         /* Increment the internal error counter.  */
21840         agent_ptr -> nx_snmp_agent_internal_errors++;
21841 
21842         /* Release the report packet too.  */
21843         nx_packet_release(report_packet_ptr);
21844 
21845         /* Return to caller.  */
21846         return;
21847     }
21848 
21849     /* Move the report buffer pointer up.  */
21850     report_buffer_ptr =  report_buffer_ptr + report_length;
21851 
21852     /* Adjust the report sequence length.  */
21853     report_sequence_length =  report_sequence_length + report_length;
21854 
21855     /* Adjust the PDU sequence length.  */
21856     report_pdu_length =  report_pdu_length + report_length;
21857 
21858     /* Now setup the PDU context name field - it is a null field in the response.  */
21859     report_length =  _nx_snmp_utility_octet_set(report_buffer_ptr, temp_string, 0, report_packet_ptr -> nx_packet_data_end);
21860 
21861     /* Check for a valid operation.  */
21862     if (report_length == 0)
21863     {
21864 
21865         /* Increment the internal error counter.  */
21866         agent_ptr -> nx_snmp_agent_internal_errors++;
21867 
21868         /* Release the report packet too.  */
21869         nx_packet_release(report_packet_ptr);
21870 
21871         /* Return to caller.  */
21872         return;
21873     }
21874 
21875     /* Move the report buffer pointer up.  */
21876     report_buffer_ptr =  report_buffer_ptr + report_length;
21877 
21878     /* Adjust the report sequence length.  */
21879     report_sequence_length =  report_sequence_length + report_length;
21880 
21881     /* Adjust the PDU sequence length.  */
21882     report_pdu_length =  report_pdu_length + report_length;
21883 
21884     /* Remember the type field's starting address.  */
21885     report_type_ptr =  report_buffer_ptr;
21886 
21887     /* Now setup the message type field.  */
21888     report_length =  _nx_snmp_utility_request_type_set_multibyte(report_buffer_ptr, NX_SNMP_ANS1_REPORT_REQUEST, 0, report_packet_ptr -> nx_packet_data_end);
21889 
21890     /* Check for a valid operation.  */
21891     if (report_length == 0)
21892     {
21893 
21894         /* Increment the internal error counter.  */
21895         agent_ptr -> nx_snmp_agent_internal_errors++;
21896 
21897         /* Release the report packet too.  */
21898         nx_packet_release(report_packet_ptr);
21899 
21900         /* Return to caller.  */
21901         return;
21902     }
21903 
21904     /* Move the report buffer pointer up.  */
21905     report_buffer_ptr =  report_buffer_ptr + report_length;
21906 
21907     /* Adjust the report sequence length.  */
21908     report_sequence_length =  report_sequence_length + report_length;
21909 
21910     /* Adjust the PDU sequence length.  */
21911     report_pdu_length =  report_pdu_length + report_length;
21912 
21913     /********************************************************/
21914     /*                  Set PDU request ID                  */
21915     /********************************************************/
21916     /* Set the PDU request to zero instead of matching the request if the request is encrypted.
21917        Otherwise the request ID must match the request specified by the browser request. */
21918     if (encryption)
21919     {
21920         request_id = 0;
21921     }
21922 
21923     /* Set the PDU request ID.  */
21924     report_length =  _nx_snmp_utility_request_id_set(report_buffer_ptr, request_id, report_packet_ptr -> nx_packet_data_end);
21925 
21926     /* Check for a valid operation.  */
21927     if (report_length == 0)
21928     {
21929 
21930         /* Increment the internal error counter.  */
21931         agent_ptr -> nx_snmp_agent_internal_errors++;
21932 
21933         /* Release the report packet too.  */
21934         nx_packet_release(report_packet_ptr);
21935 
21936         /* Return to caller.  */
21937         return;
21938     }
21939 
21940     /* Move the report buffer pointer up.  */
21941     report_buffer_ptr =  report_buffer_ptr + report_length;
21942 
21943     /* Adjust the report sequence length.  */
21944     report_sequence_length =  report_sequence_length + report_length;
21945 
21946     /* Adjust the PDU sequence length.  */
21947     report_pdu_length =  report_pdu_length + report_length;
21948 
21949     /* Adjust the report type length.  */
21950     report_type_length =  report_type_length + report_length;
21951 
21952     /********************************************************/
21953     /*                  Set the error info                  */
21954     /********************************************************/
21955     report_length =  _nx_snmp_utility_error_info_set(report_buffer_ptr, 0, 0, report_packet_ptr -> nx_packet_data_end);
21956 
21957     /* Check for a valid operation.  */
21958     if (report_length == 0)
21959     {
21960 
21961         /* Increment the internal error counter.  */
21962         agent_ptr -> nx_snmp_agent_internal_errors++;
21963 
21964         /* Release the report packet too.  */
21965         nx_packet_release(report_packet_ptr);
21966 
21967         /* Return to caller.  */
21968         return;
21969     }
21970 
21971     /* Move the report buffer pointer up.  */
21972     report_buffer_ptr =  report_buffer_ptr + report_length;
21973 
21974     /* Adjust the report sequence length.  */
21975     report_sequence_length =  report_sequence_length + report_length;
21976 
21977     /* Adjust the PDU sequence length.  */
21978     report_pdu_length =  report_pdu_length + report_length;
21979 
21980     /* Adjust the report type length.  */
21981     report_type_length =  report_type_length + report_length;
21982 
21983     /* Mark the beginning of the variable list. */
21984     report_variable_list_ptr =  report_buffer_ptr;
21985 
21986     /********************************************************/
21987     /*                  Set up the variable list            */
21988     /********************************************************/
21989 
21990     /* Now setup the sequence for the variable list.  This is set to zero for now.  */
21991     report_length =  _nx_snmp_utility_sequence_set(report_buffer_ptr, 0, report_packet_ptr -> nx_packet_data_end);
21992 
21993     /* Check for a valid operation.  */
21994     if (report_length == 0)
21995     {
21996 
21997         /* Increment the internal error counter.  */
21998         agent_ptr -> nx_snmp_agent_internal_errors++;
21999 
22000         /* Release the report packet too.  */
22001         nx_packet_release(report_packet_ptr);
22002 
22003         /* Return to caller.  */
22004         return;
22005     }
22006 
22007     /* Move the report buffer pointer up.  */
22008     report_buffer_ptr =  report_buffer_ptr + report_length;
22009 
22010     /* Adjust the report sequence length.  */
22011     report_sequence_length =  report_sequence_length + report_length;
22012 
22013     /* Adjust the PDU sequence length.  */
22014     report_pdu_length =  report_pdu_length + report_length;
22015 
22016     /* Adjust the report type length.  */
22017     report_type_length =  report_type_length + report_length;
22018 
22019     /* Remember the start of the variable response sequence.  */
22020     report_variable_ptr =  report_buffer_ptr;
22021 
22022     /* Clear the response variable size.  */
22023     report_variable_length =  0;
22024 
22025     /* Determine if there is enough room in the destination for the variable sequence.  */
22026     if ((report_buffer_ptr + 4) >= report_packet_ptr -> nx_packet_data_end)
22027     {
22028 
22029         /* Release the response packet.  */
22030         nx_packet_release(report_packet_ptr);
22031 
22032         /* Done, return to caller.  */
22033         return;
22034     }
22035 
22036     /********************************************************/
22037     /*    Initialize variable response sequence to zero     */
22038     /********************************************************/
22039 
22040     /*  We will overwrite this with the actual length later.  */
22041     report_length =  _nx_snmp_utility_sequence_set(report_buffer_ptr, 0, report_packet_ptr -> nx_packet_data_end);
22042 
22043     /* Check for a valid operation.  */
22044     if (report_length == 0)
22045     {
22046 
22047         /* Increment the internal error counter.  */
22048         agent_ptr -> nx_snmp_agent_internal_errors++;
22049 
22050         /* Release the response packet too.  */
22051         nx_packet_release(report_packet_ptr);
22052 
22053         /* Return to caller.  */
22054         return;
22055     }
22056 
22057     /* Move the response buffer pointer up.  */
22058     report_buffer_ptr =  report_buffer_ptr + report_length;
22059 
22060     /* Adjust the response sequence length.  */
22061     report_sequence_length =  report_sequence_length + report_length;
22062 
22063     /* Increment the pdu length.  */
22064     report_pdu_length =  report_pdu_length + report_length;
22065 
22066     /* Adjust the response request type length.  */
22067     report_type_length =  report_type_length + report_length;
22068 
22069     /********************************************************/
22070     /*        Adjust the response variable list size.       */
22071     /********************************************************/
22072 
22073     /* Adjust the response variable list size.  */
22074     report_variable_list_length =  report_variable_list_length + report_length;
22075 
22076     /********************************************************/
22077     /*                 Set the report OID object            */
22078     /********************************************************/
22079 
22080     if (report_respond == NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_ENGINEID_NUM)
22081     {
22082         /* This report is responding to a discovery request. */
22083         memcpy(&agent_ptr -> nx_snmp_agent_current_octet_string[0], NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_ENGINEID, /* Use case of memcpy is verified. */
22084                sizeof(NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_ENGINEID));
22085 
22086         status =  _nx_snmp_object_counter_get((VOID *)(&agent_ptr -> nx_snmp_agent_unknown_engineid_count),
22087                                               &agent_ptr -> nx_snmp_agent_current_object_data);
22088 
22089     }
22090     else if (report_respond == NX_SNMP_DISCOVERY_RESPONSE_UNSUPPORTED_SEC_NUM)
22091     {
22092         /* This report is responding to a mismatch ("unsupported") in security level. */
22093         memcpy(&agent_ptr -> nx_snmp_agent_current_octet_string[0], NX_SNMP_DISCOVERY_RESPONSE_UNSUPPORTED_SEC, /* Use case of memcpy is verified. */
22094                sizeof(NX_SNMP_DISCOVERY_RESPONSE_UNSUPPORTED_SEC));
22095 
22096         status =  _nx_snmp_object_counter_get((VOID *)(&agent_ptr -> nx_snmp_agent_unsupported_sec_count),
22097                                               &agent_ptr -> nx_snmp_agent_current_object_data);
22098     }
22099     else if (report_respond == NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_USERNAME_NUM)
22100     {
22101 
22102         /* This report is responding to an unknown user name. */
22103         memcpy(&agent_ptr -> nx_snmp_agent_current_octet_string[0], NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_USERNAME, /* Use case of memcpy is verified. */
22104                sizeof(NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_USERNAME));
22105 
22106         status =  _nx_snmp_object_counter_get((VOID *)(&agent_ptr -> nx_snmp_agent_unknown_username_count),
22107                                               &agent_ptr -> nx_snmp_agent_current_object_data);
22108     }
22109     else if (report_respond == NX_SNMP_DISCOVERY_RESPONSE_MISMATCHED_TIME_NUM)
22110     {
22111 
22112         /* This report is responding to invalid boot time or boot count data received. */
22113         memcpy(&agent_ptr -> nx_snmp_agent_current_octet_string[0], NX_SNMP_DISCOVERY_RESPONSE_MISMATCHED_TIME, /* Use case of memcpy is verified. */
22114                sizeof(NX_SNMP_DISCOVERY_RESPONSE_MISMATCHED_TIME));
22115 
22116         status =  _nx_snmp_object_counter_get((VOID *)(&agent_ptr -> nx_snmp_agent_mismatched_time_count),
22117                                               &agent_ptr -> nx_snmp_agent_current_object_data);
22118     }
22119     else
22120     {
22121 
22122         /* Unknown report type. Abort! */
22123 
22124 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
22125         NX_SNMPV3_DBG_PRINTF("Unknown report parameter %d. Abort report processing. \n\r", report_respond);
22126 #endif
22127         /* Increment the internal error counter.  */
22128         agent_ptr -> nx_snmp_agent_internal_errors++;
22129 
22130         /* Release the report packet too.  */
22131         nx_packet_release(report_packet_ptr);
22132 
22133         return;
22134     }
22135 
22136     /* Check for a valid operation.  */
22137     if (status != NX_SUCCESS)
22138     {
22139 
22140         /* Increment the internal error counter.  */
22141         agent_ptr -> nx_snmp_agent_internal_errors++;
22142 
22143         /* Release the response packet too.  */
22144         nx_packet_release(report_packet_ptr);
22145 
22146         /* Return to caller.  */
22147         return;
22148     }
22149 
22150     /* Increment the total number of get variables.  */
22151     agent_ptr -> nx_snmp_agent_total_get_variables++;
22152 
22153     /* Determine if the returning object is valid.  */
22154     if ((agent_ptr -> nx_snmp_agent_current_octet_string[0] != '1') || (agent_ptr -> nx_snmp_agent_current_octet_string[1] != '.') ||
22155         (agent_ptr -> nx_snmp_agent_current_octet_string[2] != '3') || (agent_ptr -> nx_snmp_agent_current_octet_string[3] != '.'))
22156     {
22157 
22158 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
22159         NX_SNMPV3_DBG_PRINTF("Invalid object from application GET routine on line %d.\n\r", __LINE__);
22160 #endif
22161         /* Release the response packet.  */
22162         nx_packet_release(report_packet_ptr);
22163 
22164         /* Increment the internal error counter.  */
22165         agent_ptr -> nx_snmp_agent_internal_errors++;
22166 
22167         /* Done, return to caller.  */
22168         return;
22169     }
22170 
22171     /* Now ensure the returning object type is valid.  */
22172     if ((agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_INTEGER) &&
22173         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_OCTET_STRING) &&
22174         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NULL) &&
22175         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_TIME_TICS) &&
22176         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_GAUGE) &&
22177         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_COUNTER) &&
22178         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_COUNTER64) &&
22179         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_IP_ADDRESS) &&
22180 #ifdef FEATURE_NX_IPV6
22181         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_IPV6_ADDRESS) &&
22182 #endif
22183         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NSAP_ADDRESS) &&
22184         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_OBJECT_ID) &&
22185         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NO_SUCH_OBJECT) &&
22186         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_NO_SUCH_INSTANCE) &&
22187         (agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type != NX_SNMP_ANS1_END_OF_MIB_VIEW))
22188     {
22189 
22190 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
22191         NX_SNMPV3_DBG_PRINTF("Invalid object type (%d) from application GET routine on line %d.\n\r",
22192                    agent_ptr -> nx_snmp_agent_current_object_data.nx_snmp_object_data_type, __LINE__);
22193 #endif
22194 
22195         /* Release the response packet.  */
22196         nx_packet_release(report_packet_ptr);
22197 
22198         /* Increment the internal error counter.  */
22199         agent_ptr -> nx_snmp_agent_internal_errors++;
22200 
22201         /* Done, return to caller.  */
22202         return;
22203     }
22204 
22205     /* Place the object into the response buffer.  */
22206     report_length =  _nx_snmp_utility_object_id_set_1byte(report_buffer_ptr, agent_ptr -> nx_snmp_agent_current_octet_string, report_packet_ptr -> nx_packet_data_end);
22207 
22208     /* Check for a valid operation.  */
22209     if (report_length == 0)
22210     {
22211 
22212         /* Release the response packet.  */
22213         nx_packet_release(report_packet_ptr);
22214 
22215         /* Done, return to caller.  */
22216         return;
22217     }
22218 
22219     /* Move the response buffer pointer up.  */
22220     report_buffer_ptr =  report_buffer_ptr + report_length;
22221 
22222     /* Adjust the response sequence length.  */
22223     report_sequence_length =  report_sequence_length + report_length;
22224 
22225     /* Increment the pdu length.  */
22226     report_pdu_length =  report_pdu_length + report_length;
22227 
22228     /* Adjust the response request type length.  */
22229     report_type_length =  report_type_length + report_length;
22230 
22231     /* Adjust the response variable list size.  */
22232     report_variable_list_length =  report_variable_list_length + report_length;
22233 
22234     /* Adjust the response variable size.  */
22235     report_variable_length =  report_variable_length + report_length;
22236 
22237     /* Insert the object's data into the response buffer.  */
22238     report_length =  _nx_snmp_utility_object_data_set(report_buffer_ptr, &(agent_ptr -> nx_snmp_agent_current_object_data), report_packet_ptr -> nx_packet_data_end);
22239 
22240     /* Check for a valid operation.  */
22241     if (report_length == 0)
22242     {
22243 
22244         /* Release the response packet.  */
22245         nx_packet_release(report_packet_ptr);
22246 
22247         /* Done, return to caller.  */
22248         return;
22249     }
22250 
22251     /* Move the response buffer pointer up.  */
22252     report_buffer_ptr =  report_buffer_ptr + report_length;
22253 
22254     /* Adjust the response sequence length.  */
22255     report_sequence_length =  report_sequence_length + report_length;
22256 
22257     /* Increment the pdu length.  */
22258     report_pdu_length =  report_pdu_length + report_length;
22259 
22260     /* Adjust the response request type length.  */
22261     report_type_length =  report_type_length + report_length;
22262 
22263     /* Adjust the response variable list size.  */
22264     report_variable_list_length =  report_variable_list_length + report_length;
22265 
22266     /* Adjust the response variable size.  */
22267     report_variable_length =  report_variable_length + report_length;
22268 
22269     /* Now update the response variable sequence with the actual variable length.  */
22270     report_length =  _nx_snmp_utility_sequence_set(report_variable_ptr, report_variable_length, report_packet_ptr -> nx_packet_data_end);
22271 
22272     /* Check for a valid operation.  */
22273     if (report_length == 0)
22274     {
22275 
22276         /* Increment the internal error counter.  */
22277         agent_ptr -> nx_snmp_agent_internal_errors++;
22278 
22279         /* Release the report packet too.  */
22280         nx_packet_release(report_packet_ptr);
22281 
22282         /* Return to caller.  */
22283         return;
22284     }
22285 
22286     /* At this point, several report fields need to be updated with actual lengths.  */
22287     _nx_snmp_utility_sequence_set(report_sequence_ptr, report_sequence_length, report_packet_ptr -> nx_packet_data_end);
22288     _nx_snmp_utility_sequence_set(report_header_ptr, report_header_length, report_packet_ptr -> nx_packet_data_end);
22289     _nx_snmp_utility_sequence_set(report_security_ptr, report_security_length, report_packet_ptr -> nx_packet_data_end);
22290     _nx_snmp_utility_sequence_set(report_pdu_ptr, report_pdu_length, report_packet_ptr -> nx_packet_data_end);
22291     _nx_snmp_utility_sequence_set(report_variable_list_ptr, report_variable_list_length, report_packet_ptr -> nx_packet_data_end);
22292     _nx_snmp_utility_request_type_set_multibyte(report_type_ptr, NX_SNMP_ANS1_REPORT_REQUEST, report_type_length, report_packet_ptr -> nx_packet_data_end);
22293 
22294     /* Now the report packet's pointers must be setup so it can be sent.  */
22295     report_packet_ptr -> nx_packet_length =  (ULONG)(report_buffer_ptr - report_packet_ptr -> nx_packet_prepend_ptr);
22296     report_packet_ptr -> nx_packet_append_ptr =  report_buffer_ptr;
22297 
22298     /********************************************************/
22299     /*           Set the authorization parameter            */
22300     /********************************************************/
22301 
22302     /* Also adjust the length of the security parameters field. */
22303     report_security_ptr =  report_security_ptr - 2;
22304 
22305     /* Adjust the report security length.  */
22306     report_security_length =  report_security_length + 4;
22307 
22308     /* Store the security string size.  */
22309     report_security_ptr[1] =  (UCHAR) (report_security_length & 0xFF);
22310 
22311     /* Update various statistics.  */
22312     agent_ptr -> nx_snmp_agent_reports_sent++;
22313 
22314     /* Increment the sent packet counter.  */
22315     agent_ptr -> nx_snmp_agent_packets_sent++;
22316 
22317     /* Set the authentication parameter if we have determined it needs to be set, and only if we
22318        have a valid user name. (Otherwise there would be no shared key for the other side to check
22319        our authentication.)*/
22320     if ((authenticate == NX_TRUE) && (report_respond != NX_SNMP_DISCOVERY_RESPONSE_UNKNOWN_USERNAME_NUM))
22321     {
22322 
22323         /* Fill in the authentication parameter.  */
22324         status = _nx_snmp_agent_add_auth_parameter(agent_ptr, report_packet_ptr, report_authentication_ptr);
22325 
22326         if (status != NX_SUCCESS)
22327         {
22328 
22329 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
22330             NX_SNMPV3_DBG_PRINTF("Authentication error creating authentication parameter. Line %d \n\r",  __LINE__);
22331 #endif
22332 
22333             /* Increment the authentication error counter.  */
22334             agent_ptr -> nx_snmp_agent_authentication_errors++;
22335 
22336             /* Release the original request packet.  */
22337             nx_packet_release(report_packet_ptr);
22338 
22339             return;
22340         }
22341     }
22342 
22343 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
22344     NX_SNMPV3_DBG_PRINTF("Sending the report on line %d.\n\r", __LINE__);
22345 #endif
22346 
22347     /* Send the report packet back to the requesting SNMP manager.  */
22348     status = nxd_udp_socket_send(&(agent_ptr -> nx_snmp_agent_socket), report_packet_ptr,
22349                                                 &(agent_ptr -> nx_snmp_agent_current_manager_ip),
22350                                                 agent_ptr -> nx_snmp_agent_current_manager_port);
22351 
22352     /* Determine if the packet needs to be released. */
22353     if (status)
22354     {
22355 
22356         /* Release packet.  */
22357         nx_packet_release(report_packet_ptr);
22358     }
22359 
22360 
22361     /* Return to caller.  */
22362     return;
22363 }
22364 
22365 
22366 /**************************************************************************/
22367 /*                                                                        */
22368 /*  FUNCTION                                               RELEASE        */
22369 /*                                                                        */
22370 /*    _nx_snmp_agent_add_auth_parameter                   PORTABLE C      */
22371 /*                                                           6.1.6        */
22372 /*  AUTHOR                                                                */
22373 /*                                                                        */
22374 /*    Yuxin Zhou, Microsoft Corporation                                   */
22375 /*                                                                        */
22376 /*  DESCRIPTION                                                           */
22377 /*                                                                        */
22378 /*   This function updates the specified SNMPv3 response with an          */
22379 /*   authentication parameter.                                            */
22380 /*                                                                        */
22381 /*  INPUT                                                                 */
22382 /*                                                                        */
22383 /*    agent_ptr                             Pointer to SNMP agent         */
22384 /*    response_packet_ptr                   Pointer to reply message data */
22385 /*    response_authentication_ptr           Pointer to authentication     */
22386 /*                                            parameter in the reply      */
22387 /*                                                                        */
22388 /*  OUTPUT                                                                */
22389 /*                                                                        */
22390 /*    NX_SUCCESS                            Successfully added            */
22391 /*                                              authentication parameter  */
22392 /*                                                                        */
22393 /*  CALLS                                                                 */
22394 /*                                                                        */
22395 /*    _nx_md5_update                        Calculate MD5 message digest  */
22396 /*    _nx_md5_digest_calculate              MD5 digest calculated         */
22397 /*    _nx_md5_initialize                    Prepare data for MD5 calc     */
22398 /*    _nx_sha_update                        Calculate SHa message digest  */
22399 /*    _nx_sha__digest_calculate             SHa digest calculated         */
22400 /*    _nx_sha__initialize                   Prepare data for SHa calc     */
22401 /*                                                                        */
22402 /*  CALLED BY                                                             */
22403 /*                                                                        */
22404 /*    _nx_snmp_version_3_process            Process SNMP v3 request reply */
22405 /*    _nx_snmp_version_3_report_send        Process SNMP v3 report        */
22406 /*                                                                        */
22407 /*  RELEASE HISTORY                                                       */
22408 /*                                                                        */
22409 /*    DATE              NAME                      DESCRIPTION             */
22410 /*                                                                        */
22411 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
22412 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
22413 /*                                            resulting in version 6.1    */
22414 /*  04-02-2021     Yuxin Zhou               Modified comment(s),          */
22415 /*                                            checked NULL pointer,       */
22416 /*                                            resulting in version 6.1.6  */
22417 /*                                                                        */
22418 /**************************************************************************/
_nx_snmp_agent_add_auth_parameter(NX_SNMP_AGENT * agent_ptr,NX_PACKET * response_packet_ptr,UCHAR * response_authentication_ptr)22419 UINT _nx_snmp_agent_add_auth_parameter(NX_SNMP_AGENT *agent_ptr, NX_PACKET *response_packet_ptr, UCHAR *response_authentication_ptr)
22420 {
22421 
22422 UINT  i;
22423 UCHAR key1[NX_SNMP_DIGEST_WORKING_SIZE];
22424 UCHAR key2[NX_SNMP_DIGEST_WORKING_SIZE];
22425 
22426         /* Check if the pointer is NULL. */
22427         if (!response_authentication_ptr)
22428         {
22429             return(NX_SNMP_UNSUPPORTED_AUTHENTICATION);
22430         }
22431 
22432         /* Determine which authentication is required.  */
22433         if ((agent_ptr -> nx_snmp_agent_v3_authentication_key) &&
22434             ((agent_ptr -> nx_snmp_agent_v3_authentication_key) -> nx_snmp_security_key_type == NX_SNMP_MD5_KEY))
22435         {
22436 
22437             /* Copy the base MD5 key into key1.  */
22438             for (i = 0; i < NX_SNMP_MD5_DIGEST_SIZE; i++)
22439             {
22440 
22441                 /* Copy a byte of the base MD5 key.  */
22442                 key1[i] = (agent_ptr -> nx_snmp_agent_v3_authentication_key) -> nx_snmp_security_key[i];
22443             }
22444 
22445             /* Extend key1 to 64 bytes.  */
22446             for (i = NX_SNMP_MD5_DIGEST_SIZE; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
22447             {
22448                 key1[i] =  0;
22449             }
22450 
22451             /* Create key1 and key2.  */
22452             for (i = 0; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
22453             {
22454                 key2[i] = key1[i] ^ 0x5C;
22455                 key1[i] = key1[i] ^ 0x36;
22456             }
22457 
22458             /* Calculate the MAC.  */
22459             _nx_md5_initialize(&(agent_ptr -> nx_snmp_agent_v3_md5_data));
22460 
22461             /* Calculate prepend Key1.  */
22462             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1, NX_SNMP_DIGEST_WORKING_SIZE);
22463 
22464             /* Calculate the message.  */
22465             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), response_packet_ptr -> nx_packet_prepend_ptr, response_packet_ptr -> nx_packet_length);
22466 
22467             /* Final calculation of the first pass.   */
22468             _nx_md5_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1);
22469 
22470             /* Prepare to calculate the final MAC.  */
22471             _nx_md5_initialize(&(agent_ptr -> nx_snmp_agent_v3_md5_data));
22472 
22473             /* Prepend Key2 to the result.  */
22474             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key2, NX_SNMP_DIGEST_WORKING_SIZE);
22475 
22476             /* Calculate the previous result.  */
22477             _nx_md5_update(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key1, NX_SNMP_MD5_DIGEST_SIZE);
22478 
22479             /* Calculate the final MAC. */
22480             _nx_md5_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_md5_data), key2);
22481         }
22482         else if ((agent_ptr -> nx_snmp_agent_v3_authentication_key) &&
22483             (agent_ptr -> nx_snmp_agent_v3_authentication_key -> nx_snmp_security_key_type == NX_SNMP_SHA_KEY))
22484         {
22485 
22486             /* Copy the base SHA key into key1.  */
22487             for (i = 0; i < NX_SNMP_SHA_DIGEST_SIZE; i++)
22488             {
22489 
22490                 /* Copy a byte of the base SHA key.  */
22491                 key1[i] = (agent_ptr -> nx_snmp_agent_v3_authentication_key) -> nx_snmp_security_key[i];
22492             }
22493 
22494             /* Extend key1 to 64 bytes.  */
22495             for (i = NX_SNMP_SHA_DIGEST_SIZE; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
22496             {
22497                 key1[i] =  0;
22498             }
22499 
22500             /* Create key1 and key2.  */
22501             for (i = 0; i < NX_SNMP_DIGEST_WORKING_SIZE; i++)
22502             {
22503                 key2[i] = key1[i] ^ 0x5C;
22504                 key1[i] = key1[i] ^ 0x36;
22505             }
22506 
22507             /* Calculate the MAC.  */
22508             _nx_sha1_initialize(&(agent_ptr -> nx_snmp_agent_v3_sha_data));
22509 
22510             /* Calculate prepend Key1.  */
22511             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1, NX_SNMP_DIGEST_WORKING_SIZE);
22512 
22513             /* Calculate the message.  */
22514             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), response_packet_ptr -> nx_packet_prepend_ptr, response_packet_ptr -> nx_packet_length);
22515 
22516             /* Final calculation of the first pass.   */
22517             _nx_sha1_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1);
22518 
22519             /* Prepare to calculate the final MAC.  */
22520             _nx_sha1_initialize(&(agent_ptr -> nx_snmp_agent_v3_sha_data));
22521 
22522             /* Prepend Key2 to the result.  */
22523             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key2, NX_SNMP_DIGEST_WORKING_SIZE);
22524 
22525             /* Calculate the previous result.  */
22526             _nx_sha1_update(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key1, NX_SNMP_SHA_DIGEST_SIZE);
22527 
22528             /* Calculate the final MAC. */
22529             _nx_sha1_digest_calculate(&(agent_ptr -> nx_snmp_agent_v3_sha_data), key2);
22530         }
22531         else
22532         {
22533 
22534             /* Return to caller.  */
22535             return NX_SNMP_UNSUPPORTED_AUTHENTICATION;
22536         }
22537 
22538         /* At this point, key2 contains the computed digest of the message.  This needs to be
22539            placed in the outgoing message.  */
22540 
22541         /* Loop to setup the outgoing digest.  */
22542         for (i = 0; i < NX_SNMP_DIGEST_SIZE; i++)
22543         {
22544 
22545             /* Copy the next byte of digest into the response buffer.  */
22546             response_authentication_ptr[i] =  key2[i];
22547         }
22548 
22549         return NX_SUCCESS;
22550 }
22551 
22552 
22553 /**************************************************************************/
22554 /*                                                                        */
22555 /*  FUNCTION                                               RELEASE        */
22556 /*                                                                        */
22557 /*    _nx_snmp_agent_encrypt_pdu                          PORTABLE C      */
22558 /*                                                           6.3.0        */
22559 /*  AUTHOR                                                                */
22560 /*                                                                        */
22561 /*    Yuxin Zhou, Microsoft Corporation                                   */
22562 /*                                                                        */
22563 /*  DESCRIPTION                                                           */
22564 /*                                                                        */
22565 /*   This function encrypts data pointed to by the response buffer pointer*/
22566 /*   and updates the necessary SNMPv3 header size in the header sequence  */
22567 /*   data.                                                                */
22568 /*                                                                        */
22569 /*  INPUT                                                                 */
22570 /*                                                                        */
22571 /*    agent_ptr                             Pointer to SNMP agent         */
22572 /*    [These pointers pertain to the encrypted data to send:]             */
22573 /*    response_pdu_length                   Size of the PDU data          */
22574 /*    response_sequence_length              Size of the response sequence */
22575 /*    response_encryption_size_ptr          Size of encryption data       */
22576 /*    response_sequence_ptr                 Pointer to the SNMPv3 sequence*/
22577 /*    response_buffer_ptr                   Pointer to the SNMPv3 response*/
22578 /*    response_privacy_ptr                  Pointer to privacy parameter  */
22579 /*    response_length                       Updated size of response      */
22580 /*                                                                        */
22581 /*  OUTPUT                                                                */
22582 /*                                                                        */
22583 /*    NX_SUCCESS                            Data successfully decrypted   */
22584 /*    NX_SNMP_INVALID_PDU_ENCRYPTION        Invalid encrypted data        */
22585 /*    NX_SNMP_INVALID_ENCRYPT_LENGTH        Decryption processing error   */
22586 /*                                                                        */
22587 /*  CALLS                                                                 */
22588 /*                                                                        */
22589 /*    None                                                                */
22590 /*                                                                        */
22591 /*  CALLED BY                                                             */
22592 /*                                                                        */
22593 /*    _nx_snmp_version_3_process            Process SNMP v3 request reply */
22594 /*                                                                        */
22595 /*  RELEASE HISTORY                                                       */
22596 /*                                                                        */
22597 /*    DATE              NAME                      DESCRIPTION             */
22598 /*                                                                        */
22599 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
22600 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
22601 /*                                            resulting in version 6.1    */
22602 /*  04-02-2021     Yuxin Zhou               Modified comment(s), improved */
22603 /*                                            verification of encryption, */
22604 /*                                            resulting in version 6.1.6  */
22605 /*  10-31-2023     Bo Chen                  Modified comment(s), improved */
22606 /*                                            buffer length verification, */
22607 /*                                            resulting in version 6.3.0  */
22608 /*                                                                        */
22609 /**************************************************************************/
22610 
_nx_snmp_agent_encrypt_pdu(NX_SNMP_AGENT * agent_ptr,UINT * response_pdu_length,UINT * response_sequence_length,UCHAR * response_encryption_size_ptr,UCHAR ** response_sequence_ptr,UCHAR * response_sequence_buffer_end,UCHAR ** response_buffer_ptr,UCHAR * response_privacy_ptr)22611 UINT _nx_snmp_agent_encrypt_pdu(NX_SNMP_AGENT *agent_ptr, UINT *response_pdu_length, UINT *response_sequence_length, UCHAR *response_encryption_size_ptr,
22612                                UCHAR **response_sequence_ptr, UCHAR *response_sequence_buffer_end, UCHAR **response_buffer_ptr, UCHAR *response_privacy_ptr)
22613 {
22614 
22615 UINT  i, j;
22616 UINT  padding = 0;
22617 UCHAR *temp_ptr;
22618 UCHAR key1[NX_SNMP_DIGEST_WORKING_SIZE];
22619 UCHAR key2[NX_SNMP_DIGEST_WORKING_SIZE];
22620 UINT  pdu_sequence_length;
22621 UINT  adjusted_pdu_length;
22622 
22623     if (response_pdu_length != NX_NULL)
22624     {
22625 
22626         /* Determine if any padding needs to be applied - account for the
22627            four bytes of header information on the PDU.  */
22628         padding =  ((*response_pdu_length+7)/8)*8 - *response_pdu_length;
22629 
22630         /* Add the padding the response PDU length and the response sequence length.  */
22631         *response_pdu_length =  *response_pdu_length + padding;
22632         *response_sequence_length =  *response_sequence_length + padding;
22633 
22634         /* Check the buffer.  */
22635         if ((UINT)(response_sequence_buffer_end - (*response_buffer_ptr)) < padding)
22636         {
22637             return(NX_SNMP_INVALID_PDU_ENCRYPTION);
22638         }
22639 
22640         /* Use a work pointer to initialize the padding buffer. */
22641         temp_ptr = *response_buffer_ptr;
22642 
22643         /* Clear the end of the response message...  just to be nice!  */
22644         for (i = 0; i < padding; i++)
22645         {
22646 
22647             /* Clear byte at the end of the response.  */
22648             *temp_ptr++ =  0;
22649         }
22650 
22651         adjusted_pdu_length = *response_pdu_length;
22652     }
22653     else
22654     {
22655 
22656         /* Check if the pointer is NULL. */
22657         if (!pdu_buffer_ptr)
22658         {
22659             return(NX_SNMP_INVALID_PDU_ENCRYPTION);
22660         }
22661 
22662         /* Set the temp ptr to where the PDU starts in the request packet. */
22663         temp_ptr = pdu_buffer_ptr;
22664         adjusted_pdu_length = pdu_length;
22665     }
22666 
22667     /* If this is not for our outgoing response e.g. we are re-encrypting the received packet as part
22668        of an error message, use the length from that packet. */
22669     if ((response_encryption_size_ptr == NX_NULL) || (response_pdu_length == NX_NULL))
22670     {
22671 
22672         pdu_sequence_length = pdu_length;
22673     }
22674     else
22675     {
22676 
22677         /* We need to set the PDU "inner" sequence length; it comes just after the main PDU sequence header. */
22678         pdu_sequence_length = *response_pdu_length - 4;
22679 
22680         /* Do not include padding in the inner pdu size! */
22681         pdu_sequence_length = pdu_sequence_length - padding;
22682     }
22683 
22684     if ((response_encryption_size_ptr != NX_NULL) && (response_pdu_length != NX_NULL))
22685     {
22686 
22687         /* Now we set the PDU "inner" sequence header. Use the multibyte sequence 0x30 82 xx yy format.
22688            Note that calling function has already set the pointer for writing encyrpted PDU data past this
22689            inner header.  */
22690         response_encryption_size_ptr[2] =  0x30;
22691         response_encryption_size_ptr[3] =  ((UCHAR) 2) | NX_SNMP_ANS1_MULTI_BYTES;
22692         response_encryption_size_ptr[4] =  (UCHAR) ((pdu_sequence_length >> 8) & 0xFF);
22693         response_encryption_size_ptr[5] =  (UCHAR) (pdu_sequence_length & 0xFF);
22694 
22695         /* Update our response buffer pointer. */
22696         *response_buffer_ptr = temp_ptr;
22697 
22698         response_encryption_size_ptr[0] =  (UCHAR) ((*response_pdu_length >> 8) & 0xFF);
22699         response_encryption_size_ptr[1] =  (UCHAR) (*response_pdu_length & 0xFF);
22700 
22701         /* Update the total response sequence length again. */
22702         _nx_snmp_utility_sequence_set(*response_sequence_ptr, *response_sequence_length, response_sequence_buffer_end);
22703     }
22704 
22705     /* Increment the salt counter.  */
22706     agent_ptr -> nx_snmp_agent_v3_context_salt_counter++;
22707 
22708     /* Build the salt value for the encryption.  */
22709     key1[0] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_engine_boots >> 24) & 0xFF);
22710     key1[1] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_engine_boots >> 16) & 0xFF);
22711     key1[2] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_engine_boots >>  8) & 0xFF);
22712     key1[3] =  (UCHAR) (agent_ptr -> nx_snmp_agent_v3_context_engine_boots & 0xFF);
22713     key1[4] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_salt_counter >> 24) & 0xFF);
22714     key1[5] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_salt_counter >> 16) & 0xFF);
22715     key1[6] =  (UCHAR) ((agent_ptr -> nx_snmp_agent_v3_context_salt_counter >>  8) & 0xFF);
22716     key1[7] =  (UCHAR) (agent_ptr -> nx_snmp_agent_v3_context_salt_counter & 0xFF);
22717 
22718 
22719     if (response_privacy_ptr != NX_NULL)
22720     {
22721 
22722         /* Loop to store the salt in the privacy field.  */
22723         for (i = 0; i < 8; i++)
22724         {
22725 
22726             /* Store a byte of the salt.  */
22727             response_privacy_ptr[i] =  key1[i];
22728         }
22729     }
22730 
22731     /* Setup pointer to the actual PDU.  */
22732     if (response_encryption_size_ptr)
22733     {
22734         temp_ptr =  response_encryption_size_ptr + 2;
22735     }
22736 
22737     /* Make the Initialization Vector (IV).  */
22738     for (i = 0; i < 8; i++)
22739     {
22740 
22741         key2[i] =  (agent_ptr -> nx_snmp_agent_v3_privacy_key)->nx_snmp_security_key[8+i] ^ key1[i];
22742     }
22743 
22744     /* Setup the DES.  */
22745     _nx_des_key_set(&(agent_ptr -> nx_snmp_agent_v3_des_data), (agent_ptr -> nx_snmp_agent_v3_privacy_key)->nx_snmp_security_key);
22746 
22747     /* Set up the first input block - use the IV for the first block.  */
22748     for (i = 0; i < 8; i++)
22749     {
22750 
22751         key1[i] =  temp_ptr[i] ^ key2[i];
22752     }
22753 
22754     /* Encrypt the first 8 bytes.  */
22755     _nx_des_encrypt(&(agent_ptr -> nx_snmp_agent_v3_des_data), &key1[0], &temp_ptr[0]);
22756 
22757     /* Loop to encrypt the rest of the PDU.  */
22758     j =  8;
22759     do
22760     {
22761 
22762         /* Setup the next input block.  */
22763         for (i = 0; i < 8; i++)
22764         {
22765 
22766             key1[i] =  temp_ptr[j+i] ^ temp_ptr[(j-8)+i];
22767         }
22768 
22769         /* Encrypt the next 8 bytes.  */
22770         _nx_des_encrypt(&(agent_ptr -> nx_snmp_agent_v3_des_data), &key1[0], &temp_ptr[j]);
22771 
22772         /* Move the major index forward.  */
22773         j =  j + 8;
22774 
22775     } while (j < adjusted_pdu_length);
22776 
22777     return NX_SUCCESS;
22778 }
22779 
22780 
22781 /**************************************************************************/
22782 /*                                                                        */
22783 /*  FUNCTION                                               RELEASE        */
22784 /*                                                                        */
22785 /*    _nx_snmp_agent_decrypt_pdu                          PORTABLE C      */
22786 /*                                                           6.3.0        */
22787 /*  AUTHOR                                                                */
22788 /*                                                                        */
22789 /*    Yuxin Zhou, Microsoft Corporation                                   */
22790 /*                                                                        */
22791 /*  DESCRIPTION                                                           */
22792 /*                                                                        */
22793 /*   This function decrypts the data pointed to by the buffer pointer     */
22794 /*   input. If the input response buffer pointer is not null, it will set */
22795 /*   up the initial sequence header for the encrypted data around the     */
22796 /*   msgData header                                                       */
22797 /*                                                                        */
22798 /*  INPUT                                                                 */
22799 /*                                                                        */
22800 /*    agent_ptr                             Pointer to SNMP agent         */
22801 /*    buffer_ptr                            Pointer to data to decrypt    */
22802 /*    response_buffer_ptr                   Pointer to response to send   */
22803 /*    [If response_buffer_ptr is null, these have no effect:]             */
22804 /*    response_encryption_size_ptr          Pointer to encrypted data in  */
22805 /*                                             response                   */
22806 /*    response_length                       Size of encrypted data so far */
22807 /*    buffer_length                         Size of buffer data           */
22808 /*                                                                        */
22809 /*  OUTPUT                                                                */
22810 /*                                                                        */
22811 /*    NX_SUCCESS                            Data successfully decrypted   */
22812 /*    NX_SNMP_INVALID_PDU_ENCRYPTION        Invalid encrypted data        */
22813 /*    NX_SNMP_INVALID_ENCRYPT_LENGTH        Decryption processing error   */
22814 /*                                                                        */
22815 /*  CALLS                                                                 */
22816 /*                                                                        */
22817 /*    None                                                                */
22818 /*                                                                        */
22819 /*  CALLED BY                                                             */
22820 /*                                                                        */
22821 /*    _nx_snmp_version_3_process            Process SNMP v3 request reply */
22822 /*    _nx_snmp_version_3_report_send        PRocess SNMP v3 report        */
22823 /*                                                                        */
22824 /*  RELEASE HISTORY                                                       */
22825 /*                                                                        */
22826 /*    DATE              NAME                      DESCRIPTION             */
22827 /*                                                                        */
22828 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
22829 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
22830 /*                                            resulting in version 6.1    */
22831 /*  10-31-2023     Bo Chen                  Modified comment(s), improved */
22832 /*                                            buffer length verification, */
22833 /*                                            resulting in version 6.3.0  */
22834 /*                                                                        */
22835 /**************************************************************************/
22836 
_nx_snmp_agent_decrypt_pdu(NX_SNMP_AGENT * agent_ptr,UCHAR ** buffer_ptr,UCHAR * response_buffer_ptr,UCHAR ** response_encryption_size_ptr,UINT * response_length,INT * buffer_length)22837 UINT _nx_snmp_agent_decrypt_pdu(NX_SNMP_AGENT *agent_ptr, UCHAR **buffer_ptr, UCHAR *response_buffer_ptr,
22838                                 UCHAR **response_encryption_size_ptr, UINT *response_length, INT *buffer_length)
22839 {
22840 
22841 UINT  i, j, encrypted_size;
22842 UCHAR key1[NX_SNMP_DIGEST_WORKING_SIZE];
22843 UCHAR key2[NX_SNMP_DIGEST_WORKING_SIZE];
22844 
22845 
22846     *response_length = 0;
22847 
22848     /* Check the buffer length for tag and length. */
22849     if (*buffer_length < 2)
22850     {
22851         return(NX_SNMP_INVALID_PDU_ENCRYPTION);
22852     }
22853 
22854     /* Decrypt the source PDU and setup the response to have an encryption header.  */
22855     if ((*buffer_ptr)[0] != NX_SNMP_ANS1_OCTET_STRING)
22856     {
22857 
22858 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
22859         NX_SNMPV3_DBG_PRINTF("Encryption error (no privacy key in the request). Line %d \n\r", __LINE__);
22860 #endif
22861         /* Return to caller.  */
22862         return NX_SNMP_INVALID_PDU_ENCRYPTION;
22863     }
22864 
22865     /* Pickup the encrypted PDU size.  */
22866     if ((*buffer_ptr)[1] & NX_SNMP_ANS1_MULTI_BYTES)
22867     {
22868 
22869         UINT temp = (*buffer_ptr)[1] & 0x7F;
22870         if (temp == 2)
22871         {
22872 
22873             /* Check the buffer length. */
22874             if (*buffer_length < 4)
22875             {
22876                 return(NX_SNMP_INVALID_PDU_ENCRYPTION);
22877             }
22878 
22879             /* Two byte octet string.  */
22880             encrypted_size =  (((UINT) (*buffer_ptr)[2]) << 8) | ((UINT) (*buffer_ptr)[3]);
22881 
22882             /* Move the buffer pointer up to the actual encrypted PDU contents.  */
22883             (*buffer_ptr) += 4;
22884             *buffer_length -= 4;
22885         }
22886         else if (temp == 1)
22887         {
22888 
22889             /* Check the buffer length. */
22890             if (*buffer_length < 3)
22891             {
22892                 return(NX_SNMP_INVALID_PDU_ENCRYPTION);
22893             }
22894 
22895             /* One byte octet string e.g. 0x04 0x81 0xXY */
22896             encrypted_size =  (UINT) (*buffer_ptr)[2];
22897 
22898             /* Move the buffer pointer up to the actual encrypted PDU contents.  */
22899             (*buffer_ptr) +=  3;
22900             (*buffer_length) -= 3;
22901 
22902         }
22903         else
22904         {
22905             /* Either null or too big. Invalid size type.*/
22906             return NX_SNMP_ERROR_WRONGENCODING;
22907         }
22908     }
22909     else
22910     {
22911 
22912         /* One byte octet string.  */
22913         encrypted_size =  (UINT) (*buffer_ptr)[1];
22914 
22915         /* Move the buffer pointer up to the actual encrypted PDU contents.  */
22916         (*buffer_ptr) += 2;
22917         (*buffer_length) -= 2;
22918     }
22919 
22920     /* Check for invalid buffer size. */
22921     if ((INT)encrypted_size > *buffer_length)
22922     {
22923 
22924         /* Invalid buffer size. */
22925         return NX_SNMP_INVALID_PDU_ENCRYPTION;
22926     }
22927 
22928     /* Determine if the length is valid.  */
22929     if (encrypted_size % 8)
22930     {
22931 
22932 #ifdef NX_SNMPV3_PRINT_DEBUG_MESSAGE
22933         NX_SNMPV3_DBG_PRINTF("Encryption error (invalid length).Drop the request. Line %d \n\r", __LINE__);
22934 #endif
22935         /* Return to caller.  */
22936         return NX_SNMP_INVALID_ENCRYPT_LENGTH;
22937     }
22938 
22939     /* Create the Initialization Vector (IV).  */
22940     for (i = 0; i < 8; i++)
22941     {
22942 
22943         key2[i] =  (agent_ptr -> nx_snmp_agent_v3_privacy_key) -> nx_snmp_security_key[8+i] ^ agent_ptr -> nx_snmp_agent_v3_security_privacy[i];
22944     }
22945 
22946     /* Initialize the DES component. */
22947     _nx_des_key_set(&(agent_ptr -> nx_snmp_agent_v3_des_data), (agent_ptr -> nx_snmp_agent_v3_privacy_key) -> nx_snmp_security_key);
22948 
22949     /* Decrypt the first 8 bytes.  */
22950     _nx_des_decrypt(&(agent_ptr -> nx_snmp_agent_v3_des_data), (*buffer_ptr), key1);
22951 
22952     /* XOR with the IV.  */
22953     for (i = 0; i < 8; i++)
22954     {
22955 
22956         /* XOR a byte of the IV.  */
22957         key1[i] =  key1[i] ^ key2[i];
22958     }
22959 
22960     /* Loop to decrypt the entire PDU.  */
22961     j = 8;
22962     do
22963     {
22964 
22965         /* Decrypt the next 8-byte block.  */
22966         _nx_des_decrypt(&(agent_ptr -> nx_snmp_agent_v3_des_data), &(*buffer_ptr)[j], key2);
22967 
22968         /* XOR with the previous encrypted 8-byte block.  */
22969         for (i = 0; i < 8; i++)
22970         {
22971 
22972             /* XOR result with previous block.  */
22973             key2[i] =  key2[i] ^ (*buffer_ptr)[(j-8)+i];
22974 
22975             /* Copy a byte of the decrypted block over the source.  */
22976             (*buffer_ptr)[(j-8)+i] =  key1[i];
22977 
22978             /* Save this byte of the new decrypted block.  */
22979             key1[i] =  key2[i];
22980         }
22981 
22982         /* Move j up to the next 8 octet sequence.  */
22983         j = j + 8;
22984     } while (j < encrypted_size);
22985 
22986     /* Flush the last block out to the buffer.  */
22987     for (i = 0; i < 8; i++)
22988     {
22989 
22990         /* Copy a byte of the decrypted block over the source.  */
22991         (*buffer_ptr)[(j-8)+i] =  key1[i];
22992     }
22993 
22994      /* If the caller is going to encrypt its response it will send a non null response buffer pointer. */
22995      if (response_buffer_ptr != NX_NULL)
22996      {
22997 
22998          /* Now setup the response buffer to encapsulate the encrypted PDU.  Note that
22999             the actual encryption will be done after the complete response has been
23000             formed.  */
23001          response_buffer_ptr[0] =  NX_SNMP_ANS1_OCTET_STRING;
23002          response_buffer_ptr[1] =  0x82;
23003          response_buffer_ptr[2] =  0x00;
23004          response_buffer_ptr[3] =  0x00;
23005 
23006          /* Save the response encryption size pointer.  This will be filled in below
23007             as we build the message.  */
23008          *response_encryption_size_ptr =  response_buffer_ptr + 2;
23009 
23010          *response_length = 4 ;
23011      }
23012 
23013      return NX_SUCCESS;
23014 }
23015 
23016 
23017 /**************************************************************************/
23018 /*                                                                        */
23019 /*  FUNCTION                                               RELEASE        */
23020 /*                                                                        */
23021 /*    _nx_snmp_agent_security_response_status             PORTABLE C      */
23022 /*                                                           6.1          */
23023 /*  AUTHOR                                                                */
23024 /*                                                                        */
23025 /*    Yuxin Zhou, Microsoft Corporation                                   */
23026 /*                                                                        */
23027 /*  DESCRIPTION                                                           */
23028 /*                                                                        */
23029 /*   This function determines how to set authentication and privacy       */
23030 /*   parameters in the USM header.                                        */
23031 /*                                                                        */
23032 /*  INPUT                                                                 */
23033 /*                                                                        */
23034 /*    agent_ptr                             Pointer to SNMP agent         */
23035 /*                                                                        */
23036 /*  OUTPUT                                                                */
23037 /*                                                                        */
23038 /*    *authenticate                         If true, authentication       */
23039 /*                                             parameter should be set    */
23040 /*    *encryption                           If true, privacy  parameter   */
23041 /*                                             should be set              */
23042 /*    *send_reply                           If not true, no reply or      */
23043 /*                                             report should be sent      */
23044 /*                                                                        */
23045 /*  CALLS                                                                 */
23046 /*                                                                        */
23047 /*    None                                                                */
23048 /*                                                                        */
23049 /*  CALLED BY                                                             */
23050 /*                                                                        */
23051 /*    _nx_snmp_version_3_report_send        PRocess SNMP v3 report        */
23052 /*                                                                        */
23053 /*  RELEASE HISTORY                                                       */
23054 /*                                                                        */
23055 /*    DATE              NAME                      DESCRIPTION             */
23056 /*                                                                        */
23057 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
23058 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
23059 /*                                            resulting in version 6.1    */
23060 /*                                                                        */
23061 /**************************************************************************/
_nx_snmp_agent_security_response_status(NX_SNMP_AGENT * agent_ptr,UINT * authenticate,UINT * encryption,UINT * send_reply)23062 VOID _nx_snmp_agent_security_response_status(NX_SNMP_AGENT *agent_ptr, UINT *authenticate, UINT *encryption, UINT *send_reply)
23063 {
23064 
23065 
23066     /* Initialize the security parameters to off. */
23067     *encryption = NX_FALSE;
23068     *authenticate = NX_FALSE;
23069 
23070     /* In all but one or two cases we always send a reply. Initialize to true. */
23071     *send_reply = NX_TRUE;
23072 
23073     /* Check if the incoming request specifies encryption (privacy). */
23074     if ((agent_ptr -> nx_snmp_agent_v3_message_security_options & NX_SNMP_SECURITY_PRIVACY ) >= 2)
23075     {
23076 
23077         /* It is. Check if the SNMP agent has created an encryption key. */
23078         if (agent_ptr -> nx_snmp_agent_v3_privacy_key == NX_NULL)
23079         {
23080 
23081             /* We cannot decrypt the incoming message, (need the request ID), so we cannot send a reply. */
23082             *send_reply = NX_FALSE;
23083 
23084             return;
23085         }
23086 
23087         /* Ok to apply privacy security level. */
23088         *encryption = NX_TRUE;
23089     }
23090     else
23091     {
23092 
23093         /* Incoming message does not specify privacy. */
23094 
23095         /* Check if the SNMP agent has created an encryption key. */
23096         if (agent_ptr -> nx_snmp_agent_v3_privacy_key == NX_NULL)
23097         {
23098 
23099             /* It has not.  The SNMP agent is not configured for privacy here. All good. */
23100         }
23101         /* else
23102              Same result, indicate no privacy applied to our response. */
23103 
23104     }
23105 
23106     /* Now if the incoming message security level is set for authentication regardless
23107        of matching privacy levels. */
23108     if ((agent_ptr -> nx_snmp_agent_v3_message_security_options & NX_SNMP_SECURITY_AUTHORIZE) >= 1)
23109     {
23110 
23111         /* It is. Check if the SNMP agent has created an authentication key. */
23112         if (agent_ptr -> nx_snmp_agent_v3_authentication_key != NX_NULL)
23113         {
23114 
23115             /* Ok to authenticate (even if not going apply privacy). */
23116             *authenticate = NX_TRUE;
23117         }
23118         /*else
23119              Cannot authenticate, but we will still send a reply. */
23120     }
23121 
23122     return;
23123 }
23124 
23125 #endif /*NX_SNMP_DISABLE_V3 */
23126 
23127 
23128 /**************************************************************************/
23129 /*                                                                        */
23130 /*  FUNCTION                                               RELEASE        */
23131 /*                                                                        */
23132 /*    _nx_snmp_asn1_tlv_block_parse                       PORTABLE C      */
23133 /*                                                           6.1          */
23134 /*  AUTHOR                                                                */
23135 /*                                                                        */
23136 /*    Yuxin Zhou, Microsoft Corporation                                   */
23137 /*                                                                        */
23138 /*  DESCRIPTION                                                           */
23139 /*                                                                        */
23140 /*    This function parses an ASN.1 type-length-value (TLV) block for use */
23141 /*    by the SNMP Agent parsing data received from the browser.           */
23142 /*                                                                        */
23143 /*  INPUT                                                                 */
23144 /*                                                                        */
23145 /*    buffer                                Pointer to data to be parsed  */
23146 /*    buffer_length                         Size of input buffer          */
23147 /*    tlv_type                              Return block type             */
23148 /*    tlv_tag_class                         Return class of the tag       */
23149 /*    tlv_length                            Return parsed length          */
23150 /*    tlv_data                              Return pointer to block data  */
23151 /*    header_length                         Return length of block itself */
23152 /*                                                                        */
23153 /*  OUTPUT                                                                */
23154 /*                                                                        */
23155 /*    status                                Completion status             */
23156 /*                                                                        */
23157 /*  CALLS                                                                 */
23158 /*                                                                        */
23159 /*    None                                                                */
23160 /*                                                                        */
23161 /*  CALLED BY                                                             */
23162 /*                                                                        */
23163 /*    _nx_snmp_utility_object_get           Extract data from sender      */
23164 /*                                                                        */
23165 /*  RELEASE HISTORY                                                       */
23166 /*                                                                        */
23167 /*    DATE              NAME                      DESCRIPTION             */
23168 /*                                                                        */
23169 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
23170 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
23171 /*                                            buffer length verification, */
23172 /*                                            resulting in version 6.1    */
23173 /*                                                                        */
23174 /**************************************************************************/
_nx_snmp_utility_tlv_block_parse(UCHAR * buffer,INT buffer_length,USHORT * tlv_type,USHORT * tlv_tag_class,ULONG * tlv_length,UCHAR ** tlv_data,ULONG * header_length)23175 UINT _nx_snmp_utility_tlv_block_parse(UCHAR *buffer, INT buffer_length, USHORT *tlv_type,
23176                                       USHORT *tlv_tag_class, ULONG *tlv_length,
23177                                       UCHAR **tlv_data, ULONG *header_length)
23178 {
23179 UINT   current_index = 0;
23180 USHORT current_tag;
23181 ULONG  length;
23182 ULONG  length_bytes;
23183 
23184 
23185     /* Check the buffer length.  */
23186     if ((INT)current_index >= buffer_length)
23187     {
23188         return(NX_SNMP_ERROR_WRONGLENGTH);
23189     }
23190 
23191     current_tag = buffer[current_index];
23192 
23193     /*  Handle multi-byte encoded tags. */
23194     if ((current_tag & NX_SNMP_ASN_TAG_MULTIBYTE_MASK) == NX_SNMP_ASN_TAG_MULTIBYTE_MASK)
23195     {
23196         return(NX_SNMP_MULTIBYTE_TAG_UNSUPPORTED);
23197     }
23198     else
23199     {
23200         *header_length = 1;
23201     }
23202 
23203     /* Get the class of the tag so we can return it. */
23204     *tlv_tag_class = (USHORT)((current_tag & NX_SNMP_ASN_TAG_CLASS_MASK) >> 6);
23205 
23206     /* Make sure we have a valid tag class. */
23207     if (*tlv_tag_class == NX_SNMP_ASN_TAG_CLASS_PRIVATE)
23208     {
23209         /* The tag class is invalid, return error. */
23210         return(NX_SNMP_INVALID_TAG_CLASS);
23211     }
23212 
23213     /* The caller actually handles what happens based on the tag type. */
23214     if (current_tag & NX_SNMP_ASN_TAG_CONSTRUCTED_MASK)
23215     {
23216         current_tag = current_tag & (USHORT)(~NX_SNMP_ASN_TAG_CONSTRUCTED_MASK);
23217     }
23218 
23219     /* Clear out the class and constructed bits before returning the tag value. */
23220     *tlv_type = current_tag & NX_SNMP_ASN_TAG_MASK;
23221     current_index++;
23222 
23223     /* Check the buffer length.  */
23224     if ((INT)current_index >= buffer_length)
23225     {
23226         return(NX_SNMP_ERROR_WRONGLENGTH);
23227     }
23228 
23229     if (current_tag == NX_SNMP_ANS1_NULL)
23230     {
23231         /*  If tag is NULL, there is no length byte, just a value of zero, */
23232         *tlv_length = 1;
23233 
23234         /* Set the data pointer and return. */
23235         *tlv_data = &buffer[current_index];
23236 
23237         return(NX_SUCCESS);
23238     }
23239 
23240     /* Handle the length. */
23241     length = buffer[current_index];
23242     current_index++;
23243     *header_length = *header_length + 1;
23244 
23245     /* Check for multi-byte length by looking at the top bit of the length byte. */
23246     if (length & 0x80)
23247     {
23248         /* Multi-byte length:
23249            > 127, high bit is set, and lower 7 bits becomes the number of following bytes of *length*
23250            so 841 bytes of Value is encoded as 0x82, 0x03, 0x49 (0x82 = 2 bytes of length, 0x0349 = 841).
23251          */
23252 
23253         /*  Mask off top bit to get the number of bytes in length. */
23254         length_bytes = length & 0x7F;
23255         length = 0;
23256 
23257         /*  Check for length too big to handle. */
23258         if (length_bytes > 4)
23259         {
23260 
23261             return(NX_SNMP_ASN1_LENGTH_TOO_LONG);
23262         }
23263 
23264         /* Update header length. */
23265         *header_length = *header_length + length_bytes;
23266 
23267         /* Check the buffer length.  */
23268         if ((current_index + length_bytes) < current_index || (current_index + length_bytes) > (UINT)buffer_length)
23269         {
23270             return(NX_SNMP_ERROR_WRONGLENGTH);
23271         }
23272 
23273         while (length_bytes > 0)
23274         {
23275             /* Shift length one byte up and add in next byte. */
23276             length <<= 8;
23277             length += buffer[current_index];
23278 
23279             /* Advance our index by one byte. */
23280             current_index++;
23281             length_bytes--;
23282         }
23283     }
23284     else
23285     {
23286         /* Single-byte length:
23287            <= 127 (7 bits), length is the number of bytes of Value */
23288         *tlv_length = length;
23289     }
23290 
23291     /* Set the length to return to caller. */
23292     *tlv_length = length;
23293 
23294     /* Check the buffer length.  */
23295     if (current_index >= (UINT)buffer_length || (length + current_index) < current_index ||
23296         (length + current_index) >  (UINT)buffer_length)
23297     {
23298         return(NX_SNMP_ERROR_WRONGLENGTH);
23299     }
23300 
23301     /*  Now, we can set the tld value */
23302     *tlv_data = &buffer[current_index];
23303 
23304     return(NX_SUCCESS);
23305 }
23306 
23307 
23308