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