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