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