1.\" 2.\" Copyright (c) 2010 The FreeBSD Foundation 3.\" All rights reserved. 4.\" 5.\" Portions of this documentation were written by Shteryana Sotirova Shopova 6.\" under sponsorship from the FreeBSD Foundation. 7.\" 8.\" Copyright (c) 2004-2005 9.\" Hartmut Brandt. 10.\" All rights reserved. 11.\" Copyright (c) 2001-2003 12.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus). 13.\" All rights reserved. 14.\" 15.\" Author: Harti Brandt <harti@FreeBSD.org> 16.\" 17.\" Redistribution and use in source and binary forms, with or without 18.\" modification, are permitted provided that the following conditions 19.\" are met: 20.\" 1. Redistributions of source code must retain the above copyright 21.\" notice, this list of conditions and the following disclaimer. 22.\" 2. Redistributions in binary form must reproduce the above copyright 23.\" notice, this list of conditions and the following disclaimer in the 24.\" documentation and/or other materials provided with the distribution. 25.\" 26.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 30.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36.\" SUCH DAMAGE. 37.\" 38.\" $Begemot: bsnmp/lib/bsnmplib.3,v 1.9 2005/10/04 08:46:51 brandt_h Exp $ 39.\" 40.Dd December 31, 2016 41.Dt BSNMPLIB 3 42.Os 43.Sh NAME 44.Nm snmp_value_free , 45.Nm snmp_value_parse , 46.Nm snmp_value_copy , 47.Nm snmp_pdu_free , 48.Nm snmp_pdu_decode , 49.Nm snmp_pdu_encode , 50.Nm snmp_pdu_decode_header , 51.Nm snmp_pdu_decode_scoped , 52.Nm snmp_pdu_decode_secmode , 53.Nm snmp_pdu_init_secparams , 54.Nm snmp_pdu_dump , 55.Nm snmp_passwd_to_keys , 56.Nm snmp_get_local_keys , 57.Nm snmp_calc_keychange , 58.Nm TRUTH_MK , 59.Nm TRUTH_GET , 60.Nm TRUTH_OK 61.Nd "SNMP decoding and encoding library" 62.Sh LIBRARY 63Begemot SNMP library 64.Pq libbsnmp, -lbsnmp 65.Sh SYNOPSIS 66.In bsnmp/asn1.h 67.In bsnmp/snmp.h 68.Ft void 69.Fn snmp_value_free "struct snmp_value *value" 70.Ft int 71.Fn snmp_value_parse "const char *buf" "enum snmp_syntax" "union snmp_values *value" 72.Ft int 73.Fn snmp_value_copy "struct snmp_value *to" "const struct snmp_value *from" 74.Ft void 75.Fn snmp_pdu_free "struct snmp_pdu *value" 76.Ft enum snmp_code 77.Fn snmp_pdu_decode "struct asn_buf *buf" "struct snmp_pdu *pdu" "int32_t *ip" 78.Ft enum snmp_code 79.Fn snmp_pdu_encode "struct snmp_pdu *pdu" "struct asn_buf *buf" 80.Ft enum snmp_code 81.Fn snmp_pdu_decode_header "struct snmp_pdu *pdu" "struct asn_buf *buf" 82.Ft enum snmp_code 83.Fn snmp_pdu_decode_scoped "struct asn_buf *buf" "struct snmp_pdu *pdu" "int32_t *ip" 84.Ft enum snmp_code 85.Fn snmp_pdu_decode_secmode "struct asn_buf *buf" "struct snmp_pdu *pdu" 86.Ft void 87.Fn snmp_pdu_init_secparams "struct snmp_pdu *pdu" 88.Ft void 89.Fn snmp_pdu_dump "const struct snmp_pdu *pdu" 90.Ft enum snmp_code 91.Fn snmp_passwd_to_keys "struct snmp_user *user" "char *passwd" 92.Ft enum snmp_code 93.Fn snmp_get_local_keys "struct snmp_user *user" "uint8_t *eid" "uint32_t elen" 94.Ft enum snmp_code 95.Fn snmp_calc_keychange "struct snmp_user *user" "uint8_t *keychange" 96.Ft int 97.Fn TRUTH_MK "F" 98.Ft int 99.Fn TRUTH_GET "T" 100.Ft int 101.Fn TRUTH_OK "T" 102.Sh DESCRIPTION 103The SNMP library contains routines to handle SNMP version 1, 2 and 3 PDUs. 104There are several basic structures used throughout the library: 105.Bd -literal -offset indent 106struct snmp_value { 107 struct asn_oid var; 108 enum snmp_syntax syntax; 109 union snmp_values { 110 int32_t integer;/* also integer32 */ 111 struct { 112 u_int len; 113 u_char *octets; 114 } octetstring; 115 struct asn_oid oid; 116 u_char ipaddress[4]; 117 uint32_t uint32; /* also gauge32, counter32, 118 unsigned32, timeticks */ 119 uint64_t counter64; 120 } v; 121}; 122.Ed 123.Pp 124This structure represents one variable binding from an SNMP PDU. 125The field 126.Fa var 127is the ASN.1 of the variable that is bound. 128.Fa syntax 129contains either the syntax code of the value or an exception code for SNMPv2 130and may be one of: 131.Bd -literal -offset indent 132enum snmp_syntax { 133 SNMP_SYNTAX_NULL = 0, 134 SNMP_SYNTAX_INTEGER, /* == INTEGER32 */ 135 SNMP_SYNTAX_OCTETSTRING, 136 SNMP_SYNTAX_OID, 137 SNMP_SYNTAX_IPADDRESS, 138 SNMP_SYNTAX_COUNTER, 139 SNMP_SYNTAX_GAUGE, /* == UNSIGNED32 */ 140 SNMP_SYNTAX_TIMETICKS, 141 142 /* v2 additions */ 143 SNMP_SYNTAX_COUNTER64, 144 /* exceptions */ 145 SNMP_SYNTAX_NOSUCHOBJECT, 146 SNMP_SYNTAX_NOSUCHINSTANCE, 147 SNMP_SYNTAX_ENDOFMIBVIEW, 148}; 149.Ed 150The field 151.Fa v 152holds the actual value depending on 153.Fa syntax . 154Note, that if 155.Fa syntax 156is 157.Li SNMP_SYNTAX_OCTETSTRING 158and 159.Fa v.octetstring.len 160is not zero, 161.Fa v.octetstring.octets 162points to a string allocated by 163.Xr malloc 3 . 164.Bd -literal -offset indent 165#define SNMP_ENGINE_ID_SIZ 32 166 167struct snmp_engine { 168 uint8_t engine_id[SNMP_ENGINE_ID_SIZ]; 169 uint32_t engine_len; 170 int32_t engine_boots; 171 int32_t engine_time; 172 int32_t max_msg_size; 173}; 174.Ed 175.Pp 176This structure represents an SNMP engine as specified by the SNMP Management 177Architecture described in RFC 3411. 178.Bd -literal -offset indent 179#define SNMP_ADM_STR32_SIZ (32 + 1) 180#define SNMP_AUTH_KEY_SIZ 40 181#define SNMP_PRIV_KEY_SIZ 32 182 183enum snmp_usm_level { 184 SNMP_noAuthNoPriv = 1, 185 SNMP_authNoPriv = 2, 186 SNMP_authPriv = 3 187}; 188 189struct snmp_user { 190 char sec_name[SNMP_ADM_STR32_SIZ]; 191 enum snmp_authentication auth_proto; 192 enum snmp_privacy priv_proto; 193 uint8_t auth_key[SNMP_AUTH_KEY_SIZ]; 194 uint8_t priv_key[SNMP_PRIV_KEY_SIZ]; 195}; 196.Ed 197.Pp 198This structure represents an SNMPv3 user as specified by the User-based 199Security Model (USM) described in RFC 3414. The field 200.Fa sec_name 201is a human readable string containing the security user name. 202.Fa auth_proto 203contains the id of the authentication protocol in use by the user and may be one 204of: 205.Bd -literal -offset indent 206enum snmp_authentication { 207 SNMP_AUTH_NOAUTH = 0, 208 SNMP_AUTH_HMAC_MD5, 209 SNMP_AUTH_HMAC_SHA 210}; 211.Ed 212.Fa priv_proto 213contains the id of the privacy protocol in use by the user and may be one 214of: 215.Bd -literal -offset indent 216enum snmp_privacy { 217 SNMP_PRIV_NOPRIV = 0, 218 SNMP_PRIV_DES = 1, 219 SNMP_PRIV_AES 220}; 221.Ed 222.Fa auth_key 223and 224.Fa priv_key 225contain the authentication and privacy keys for the user. 226.Bd -literal -offset indent 227#define SNMP_COMMUNITY_MAXLEN 128 228#define SNMP_MAX_BINDINGS 100 229#define SNMP_CONTEXT_NAME_SIZ (32 + 1) 230#define SNMP_TIME_WINDOW 150 231 232#define SNMP_USM_AUTH_SIZE 12 233#define SNMP_USM_PRIV_SIZE 8 234 235#define SNMP_MSG_AUTH_FLAG 0x1 236#define SNMP_MSG_PRIV_FLAG 0x2 237#define SNMP_MSG_REPORT_FLAG 0x4 238 239#define SNMP_MPM_SNMP_V1 0 240#define SNMP_MPM_SNMP_V2c 1 241#define SNMP_MPM_SNMP_V3 3 242 243struct snmp_pdu { 244 char community[SNMP_COMMUNITY_MAXLEN + 1]; 245 enum snmp_version version; 246 u_int type; 247 248 /* SNMPv3 PDU header fields */ 249 int32_t identifier; 250 uint8_t flags; 251 int32_t security_model; 252 struct snmp_engine engine; 253 254 /* Associated USM user parameters */ 255 struct snmp_user user; 256 uint8_t msg_digest[SNMP_USM_AUTH_SIZE]; 257 uint8_t msg_salt[SNMP_USM_PRIV_SIZE]; 258 259 /* View-based Access Model */ 260 uint32_t context_engine_len; 261 uint8_t context_engine[SNMP_ENGINE_ID_SIZ]; 262 char context_name[SNMP_CONTEXT_NAME_SIZ]; 263 264 /* trap only */ 265 struct asn_oid enterprise; 266 u_char agent_addr[4]; 267 int32_t generic_trap; 268 int32_t specific_trap; 269 uint32_t time_stamp; 270 271 /* others */ 272 int32_t request_id; 273 int32_t error_status; 274 int32_t error_index; 275 276 /* fixes for encoding */ 277 size_t outer_len; 278 size_t scoped_len; 279 u_char *outer_ptr; 280 u_char *digest_ptr; 281 u_char *encrypted_ptr; 282 u_char *scoped_ptr; 283 u_char *pdu_ptr; 284 u_char *vars_ptr; 285 286 287 struct snmp_value bindings[SNMP_MAX_BINDINGS]; 288 u_int nbindings; 289}; 290.Ed 291This structure contains a decoded SNMP PDU. 292.Fa version 293is one of 294.Bd -literal -offset indent 295enum snmp_version { 296 SNMP_Verr = 0, 297 SNMP_V1 = 1, 298 SNMP_V2c, 299 SNMP_V3 300}; 301.Ed 302and 303.Fa type 304is the type of the PDU. 305.Fa security_model 306is the security model used for SNMPv3 PDUs. The only supported 307value currently is 3 (User-based Security Model). Additional values for any, 308unknown, SNMPv1 and SNMPv2c security models are also enumerated 309.Bd -literal -offset indent 310enum snmp_secmodel { 311 SNMP_SECMODEL_ANY = 0, 312 SNMP_SECMODEL_SNMPv1 = 1, 313 SNMP_SECMODEL_SNMPv2c = 2, 314 SNMP_SECMODEL_USM = 3, 315 SNMP_SECMODEL_UNKNOWN 316}; 317.Ed 318.Pp 319The function 320.Fn snmp_value_free 321is used to free all the dynamic allocated contents of an SNMP value. 322It does not free the structure pointed to by 323.Fa value 324itself. 325.Pp 326The function 327.Fn snmp_value_parse 328parses the ASCII representation of an SNMP value into its binary form. 329This function is mainly used by the configuration file reader of 330.Xr bsnmpd 1 . 331.Pp 332The function 333.Fn snmp_value_copy 334makes a deep copy of the value pointed to by 335.Fa from 336to the structure pointed to by 337.Fa to . 338It assumes that 339.Fa to 340is uninitialized and will overwrite its previous contents. 341It does not itself allocate the structure pointed to by 342.Fa to . 343.Pp 344The function 345.Fn snmp_pdu_free 346frees all the dynamically allocated components of the PDU. 347It does not itself free the structure pointed to by 348.Fa pdu . 349.Pp 350The function 351.Fn snmp_pdu_decode 352decodes the PDU pointed to by 353.Fa buf 354and stores the result into 355.Fa pdu . 356If an error occurs in a variable binding the (1 based) index of this binding 357is stored in the variable pointed to by 358.Fa ip . 359.Pp 360The function 361.Fn snmp_pdu_encode 362encodes the PDU 363.Fa pdu 364into the an octetstring in buffer, and if authentication and privacy are used, 365calculates a message digest and encrypts the PDU data in the buffer 366.Fa buf . 367.Pp 368The function 369.Fn snmp_pdu_decode_header 370decodes the header of the PDU pointed to by 371.Fa buf . 372The uncoded PDU contents remain in the buffer. 373.Pp 374The function 375.Fn snmp_pdu_decode_scoped 376decodes the scoped PDU pointed to by 377.Fa buf . 378.Pp 379The function 380.Fn snmp_pdu_decode_secmode 381verifies the authentication parameter contained in the PDU (if present) and 382if the PDU is encrypted, decrypts the PDU contents pointed to by 383.Fa buf . 384If successful, a plain text scoped PDU is stored in the buffer. 385.Pp 386The function 387.Fn snmp_pdu_init_secparams 388calculates the initialization vector for the privacy protocol in use before 389the PDU pointed to by 390.Fa pdu 391may be encrypted or decrypted. 392.Pp 393The function 394.Fn snmp_pdu_dump 395dumps the PDU in a human readable form by calling 396.Fn snmp_printf . 397.Pp 398The function 399.Fn snmp_passwd_to_keys 400calculates a binary private authentication key corresponding to a plain text human 401readable password string. The calculated key is placed in the 402.Fa auth_key 403field of the 404.Fa user . 405.Pp 406The function 407.Fn snmp_get_local_keys 408calculates a localazied authentication and privacy keys for a specified SNMPv3 409engine. The calculateds keys are placed in the 410.Fa auth_key 411and 412.Fa priv_key 413fields of the 414.Fa user . 415.Pp 416The function 417.Fn snmp_calc_keychange 418calculates a binary key change octet string based on the contents of an old and 419a new binary localized key. The rezult is placed in the buffer pointer to by 420.Fa keychange 421and may be used by an SNMPv3 user who wishes to change his/her password 422or localized key. 423.Pp 424The function 425.Fn TRUTH_MK 426takes a C truth value (zero or non-zero) and makes an SNMP truth value (2 or 1). 427The function 428.Fn TRUTH_GET 429takes an SNMP truth value and makes a C truth value (0 or 1). 430The function 431.Fn TRUTH_OK 432checks, whether its argument is a legal SNMP truth value. 433.Sh DIAGNOSTICS 434When an error occurs in any of the function the function pointed to 435by the global pointer 436.Bd -literal -offset indent 437extern void (*snmp_error)(const char *, ...); 438.Ed 439.Pp 440with a 441.Xr printf 3 442style format string. 443There is a default error handler in the library that prints a message 444starting with 445.Sq SNMP: 446followed by the error message to standard error. 447.Pp 448The function pointed to by 449.Bd -literal -offset indent 450extern void (*snmp_printf)(const char *, ...); 451.Ed 452.Pp 453is called by the 454.Fn snmp_pdu_dump 455function. 456The default handler is 457.Xr printf 3 . 458.Sh ERRORS 459.Fn snmp_pdu_decode 460will return one of the following return codes: 461.Bl -tag -width Er 462.It Bq Er SNMP_CODE_OK 463Success. 464.It Bq Er SNMP_CODE_FAILED 465The ASN.1 coding was wrong. 466.It Bq Er SNMP_CODE_BADLEN 467A variable binding value had a wrong length field. 468.It Bq Er SNMP_CODE_OORANGE 469A variable binding value was out of the allowed range. 470.It Bq Er SNMP_CODE_BADVERS 471The PDU is of an unsupported version. 472.It Bq Er SNMP_CODE_BADENQ 473There was an ASN.1 value with an unsupported tag. 474.It Bq Er SNMP_CODE_BADSECLEVEL 475The requested securityLevel contained in the PDU is not supported. 476.It Bq Er SNMP_CODE_BADDIGEST 477The PDU authentication parameter received in the PDU did not match the 478calculated message digest. 479.It Bq Er SNMP_CODE_EDECRYPT 480Error occurred while trying to decrypt the PDU. 481.El 482.Pp 483.Fn snmp_pdu_encode 484will return one of the following return codes: 485.Bl -tag -width Er 486.It Bq Er SNMP_CODE_OK 487Success. 488.It Bq Er SNMP_CODE_FAILED 489Encoding failed. 490.El 491.Sh SEE ALSO 492.Xr gensnmptree 1 , 493.Xr bsnmpd 1 , 494.Xr bsnmpagent 3 , 495.Xr bsnmpclient 3 , 496.Xr bsnmplib 3 497.Sh CAVEAT 498The SNMPv3 message digests, encryption and decryption, and key routines use 499the cryptographic functions from 500.Xr crypto 3 . 501The library may optionally be built without references to the 502.Xr crypto 3 503library. In such case only plain text SNMPv3 PDUs without message digests 504may be proccessed correctly. 505.Sh STANDARDS 506This implementation conforms to the applicable IETF RFCs and ITU-T 507recommendations. 508.Sh AUTHORS 509The Begemot SNMP library was originally written by 510.An Hartmut Brandt Aq harti@FreeBSD.org 511.Pp 512.An Shteryana Shopova Aq syrinx@FreeBSD.org 513added support for the SNMPv3 message proccessing and User-Based 514Security model message authentication and privacy. 515