summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2010-12-09 22:01:15 +0000
committerdim <dim@FreeBSD.org>2010-12-09 22:01:15 +0000
commita3786f65f1e2fa3a4e925fdb4b2b5544b9021bf9 (patch)
tree5f0a24f71baa3176c75a20a51a9e20a22c75426c
parentad01c620333d05c430d583ee40647e396be1ab91 (diff)
parent12dd9eb8e940c48f9fc30dbc137071b4fe5caead (diff)
downloadFreeBSD-src-a3786f65f1e2fa3a4e925fdb4b2b5544b9021bf9.zip
FreeBSD-src-a3786f65f1e2fa3a4e925fdb4b2b5544b9021bf9.tar.gz
Sync: merge r216133 through r216338 from ^/head.
-rw-r--r--ObsoleteFiles.inc21
-rw-r--r--bin/sh/jobs.c197
-rw-r--r--bin/sh/sh.125
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c19
-rw-r--r--contrib/bind9/CHANGES52
-rw-r--r--contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.html225
-rw-r--r--contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.pdfbin0 -> 53051 bytes
-rw-r--r--contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.txt133
-rw-r--r--contrib/bind9/bin/check/check-tool.c31
-rw-r--r--contrib/bind9/bin/check/check-tool.h9
-rw-r--r--contrib/bind9/bin/check/named-checkconf.c12
-rw-r--r--contrib/bind9/bin/check/named-checkzone.c11
-rw-r--r--contrib/bind9/bin/dig/host.c10
-rw-r--r--contrib/bind9/bin/named/client.c8
-rw-r--r--contrib/bind9/bin/named/include/named/query.h6
-rw-r--r--contrib/bind9/bin/named/query.c25
-rw-r--r--contrib/bind9/bin/named/server.c41
-rw-r--r--contrib/bind9/lib/dns/api4
-rw-r--r--contrib/bind9/lib/dns/include/dns/view.h6
-rw-r--r--contrib/bind9/lib/dns/journal.c21
-rw-r--r--contrib/bind9/lib/dns/rbtdb.c65
-rw-r--r--contrib/bind9/lib/dns/validator.c58
-rw-r--r--contrib/bind9/lib/dns/view.c8
-rw-r--r--contrib/bind9/lib/isc/api2
-rw-r--r--contrib/bind9/lib/isc/print.c6
-rw-r--r--contrib/bind9/release-notes.css60
-rw-r--r--contrib/bind9/version4
-rw-r--r--contrib/bsnmp/lib/asn1.c18
-rw-r--r--contrib/bsnmp/lib/asn1.h3
-rw-r--r--contrib/bsnmp/lib/bsnmpclient.391
-rw-r--r--contrib/bsnmp/lib/bsnmplib.3233
-rw-r--r--contrib/bsnmp/lib/snmp.c551
-rw-r--r--contrib/bsnmp/lib/snmp.h145
-rw-r--r--contrib/bsnmp/lib/snmpagent.c58
-rw-r--r--contrib/bsnmp/lib/snmpclient.c131
-rw-r--r--contrib/bsnmp/lib/snmpclient.h52
-rw-r--r--contrib/bsnmp/lib/snmpcrypto.c404
-rw-r--r--contrib/bsnmp/lib/snmppriv.h12
-rwxr-xr-xcontrib/bsnmp/snmp_usm/snmp_usm.3132
-rwxr-xr-xcontrib/bsnmp/snmp_usm/usm_snmp.c614
-rwxr-xr-xcontrib/bsnmp/snmp_usm/usm_tree.def109
-rwxr-xr-xcontrib/bsnmp/snmp_vacm/snmp_vacm.394
-rwxr-xr-xcontrib/bsnmp/snmp_vacm/vacm_snmp.c1026
-rwxr-xr-xcontrib/bsnmp/snmp_vacm/vacm_tree.def104
-rw-r--r--contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt3
-rw-r--r--contrib/bsnmp/snmpd/action.c175
-rw-r--r--contrib/bsnmp/snmpd/bsnmpd.116
-rw-r--r--contrib/bsnmp/snmpd/config.c22
-rw-r--r--contrib/bsnmp/snmpd/export.c1
-rw-r--r--contrib/bsnmp/snmpd/main.c923
-rw-r--r--contrib/bsnmp/snmpd/snmpd.h15
-rw-r--r--contrib/bsnmp/snmpd/snmpmod.3102
-rw-r--r--contrib/bsnmp/snmpd/snmpmod.h128
-rw-r--r--contrib/bsnmp/snmpd/trans_lsock.c1
-rw-r--r--contrib/bsnmp/snmpd/trans_udp.c1
-rw-r--r--contrib/bsnmp/snmpd/trap.c1
-rw-r--r--contrib/bsnmp/snmpd/tree.def10
-rw-r--r--contrib/traceroute/as.c3
-rw-r--r--contrib/traceroute/as.h2
-rw-r--r--contrib/traceroute/ifaddrlist.c8
-rw-r--r--contrib/traceroute/traceroute.c13
-rw-r--r--crypto/openssl/ACKNOWLEDGMENTS25
-rw-r--r--crypto/openssl/CHANGES12
-rw-r--r--crypto/openssl/FAQ53
-rw-r--r--crypto/openssl/Makefile2
-rw-r--r--crypto/openssl/NEWS5
-rw-r--r--crypto/openssl/README2
-rw-r--r--crypto/openssl/crypto/evp/p_sign.c2
-rw-r--r--crypto/openssl/crypto/evp/p_verify.c2
-rw-r--r--crypto/openssl/crypto/jpake/jpake.c36
-rw-r--r--crypto/openssl/crypto/jpake/jpake.h2
-rw-r--r--crypto/openssl/crypto/jpake/jpake_err.c4
-rw-r--r--crypto/openssl/crypto/opensslv.h6
-rw-r--r--crypto/openssl/crypto/stack/safestack.h2
-rw-r--r--crypto/openssl/doc/ssl/SSL_CTX_set_options.pod13
-rw-r--r--crypto/openssl/openssl.spec2
-rw-r--r--crypto/openssl/ssl/s3_clnt.c3
-rw-r--r--crypto/openssl/ssl/s3_srvr.c5
-rw-r--r--etc/snmpd.config136
-rw-r--r--games/bcd/bcd.66
-rw-r--r--games/caesar/caesar.66
-rw-r--r--games/caesar/rot13.sh8
-rw-r--r--games/factor/factor.66
-rw-r--r--games/morse/morse.66
-rw-r--r--games/number/number.66
-rw-r--r--games/pom/pom.66
-rw-r--r--games/random/random.66
-rw-r--r--lib/csu/amd64/crt1.c5
-rw-r--r--lib/csu/amd64/crti.S6
-rw-r--r--lib/csu/amd64/crtn.S6
-rw-r--r--lib/csu/arm/crt1.c6
-rw-r--r--lib/csu/arm/crtn.S1
-rw-r--r--lib/csu/i386-elf/crt1_c.c3
-rw-r--r--lib/csu/i386-elf/crt1_s.S4
-rw-r--r--lib/csu/i386-elf/crti.S6
-rw-r--r--lib/csu/i386-elf/crtn.S6
-rw-r--r--lib/csu/ia64/crt1.S3
-rw-r--r--lib/csu/ia64/crti.S3
-rw-r--r--lib/csu/ia64/crtn.S3
-rw-r--r--lib/csu/powerpc/crt1.c5
-rw-r--r--lib/csu/powerpc/crti.S9
-rw-r--r--lib/csu/powerpc/crtn.S7
-rw-r--r--lib/csu/powerpc64/crt1.c5
-rw-r--r--lib/csu/powerpc64/crti.S8
-rw-r--r--lib/csu/powerpc64/crtn.S7
-rw-r--r--lib/csu/sparc64/crt1.c5
-rw-r--r--lib/csu/sparc64/crti.S7
-rw-r--r--lib/csu/sparc64/crtn.S6
-rw-r--r--lib/libarchive/archive_read_extract.c3
-rw-r--r--lib/libarchive/test/Makefile17
-rw-r--r--lib/libarchive/test/test_acl_freebsd.c5
-rw-r--r--lib/libbsnmp/libbsnmp/Makefile11
-rw-r--r--lib/libc/stdio/freopen.c21
-rw-r--r--lib/libgeom/libgeom.34
-rw-r--r--lib/msun/Makefile11
-rw-r--r--lib/msun/Symbol.map2
-rw-r--r--lib/msun/man/log.318
-rw-r--r--lib/msun/man/math.321
-rw-r--r--lib/msun/src/e_log2.c60
-rw-r--r--lib/msun/src/e_log2f.c58
-rw-r--r--lib/msun/src/k_log.h116
-rw-r--r--lib/msun/src/k_logf.h55
-rw-r--r--lib/msun/src/math.h2
-rw-r--r--lib/msun/src/math_private.h2
-rw-r--r--libexec/bootpd/rtmsg.c6
-rw-r--r--libexec/mknetid/parse_group.c2
-rw-r--r--sbin/fsck_ffs/SMM.doc/Makefile8
-rw-r--r--sbin/geom/class/eli/geli.88
-rw-r--r--sbin/ifconfig/ifconfig.c4
-rw-r--r--sbin/route/route.c60
-rw-r--r--secure/lib/libcrypto/Makefile.inc4
-rw-r--r--secure/lib/libcrypto/man/ASN1_OBJECT_new.32
-rw-r--r--secure/lib/libcrypto/man/ASN1_STRING_length.32
-rw-r--r--secure/lib/libcrypto/man/ASN1_STRING_new.32
-rw-r--r--secure/lib/libcrypto/man/ASN1_STRING_print_ex.32
-rw-r--r--secure/lib/libcrypto/man/ASN1_generate_nconf.32
-rw-r--r--secure/lib/libcrypto/man/BIO_ctrl.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_base64.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_buffer.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_cipher.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_md.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_null.32
-rw-r--r--secure/lib/libcrypto/man/BIO_f_ssl.32
-rw-r--r--secure/lib/libcrypto/man/BIO_find_type.32
-rw-r--r--secure/lib/libcrypto/man/BIO_new.32
-rw-r--r--secure/lib/libcrypto/man/BIO_push.32
-rw-r--r--secure/lib/libcrypto/man/BIO_read.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_accept.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_bio.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_connect.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_fd.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_file.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_mem.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_null.32
-rw-r--r--secure/lib/libcrypto/man/BIO_s_socket.32
-rw-r--r--secure/lib/libcrypto/man/BIO_set_callback.32
-rw-r--r--secure/lib/libcrypto/man/BIO_should_retry.32
-rw-r--r--secure/lib/libcrypto/man/BN_BLINDING_new.32
-rw-r--r--secure/lib/libcrypto/man/BN_CTX_new.32
-rw-r--r--secure/lib/libcrypto/man/BN_CTX_start.32
-rw-r--r--secure/lib/libcrypto/man/BN_add.32
-rw-r--r--secure/lib/libcrypto/man/BN_add_word.32
-rw-r--r--secure/lib/libcrypto/man/BN_bn2bin.32
-rw-r--r--secure/lib/libcrypto/man/BN_cmp.32
-rw-r--r--secure/lib/libcrypto/man/BN_copy.32
-rw-r--r--secure/lib/libcrypto/man/BN_generate_prime.32
-rw-r--r--secure/lib/libcrypto/man/BN_mod_inverse.32
-rw-r--r--secure/lib/libcrypto/man/BN_mod_mul_montgomery.32
-rw-r--r--secure/lib/libcrypto/man/BN_mod_mul_reciprocal.32
-rw-r--r--secure/lib/libcrypto/man/BN_new.32
-rw-r--r--secure/lib/libcrypto/man/BN_num_bytes.32
-rw-r--r--secure/lib/libcrypto/man/BN_rand.32
-rw-r--r--secure/lib/libcrypto/man/BN_set_bit.32
-rw-r--r--secure/lib/libcrypto/man/BN_swap.32
-rw-r--r--secure/lib/libcrypto/man/BN_zero.32
-rw-r--r--secure/lib/libcrypto/man/CONF_modules_free.32
-rw-r--r--secure/lib/libcrypto/man/CONF_modules_load_file.32
-rw-r--r--secure/lib/libcrypto/man/CRYPTO_set_ex_data.32
-rw-r--r--secure/lib/libcrypto/man/DH_generate_key.32
-rw-r--r--secure/lib/libcrypto/man/DH_generate_parameters.32
-rw-r--r--secure/lib/libcrypto/man/DH_get_ex_new_index.32
-rw-r--r--secure/lib/libcrypto/man/DH_new.32
-rw-r--r--secure/lib/libcrypto/man/DH_set_method.32
-rw-r--r--secure/lib/libcrypto/man/DH_size.32
-rw-r--r--secure/lib/libcrypto/man/DSA_SIG_new.32
-rw-r--r--secure/lib/libcrypto/man/DSA_do_sign.32
-rw-r--r--secure/lib/libcrypto/man/DSA_dup_DH.32
-rw-r--r--secure/lib/libcrypto/man/DSA_generate_key.32
-rw-r--r--secure/lib/libcrypto/man/DSA_generate_parameters.32
-rw-r--r--secure/lib/libcrypto/man/DSA_get_ex_new_index.32
-rw-r--r--secure/lib/libcrypto/man/DSA_new.32
-rw-r--r--secure/lib/libcrypto/man/DSA_set_method.32
-rw-r--r--secure/lib/libcrypto/man/DSA_sign.32
-rw-r--r--secure/lib/libcrypto/man/DSA_size.32
-rw-r--r--secure/lib/libcrypto/man/ERR_GET_LIB.32
-rw-r--r--secure/lib/libcrypto/man/ERR_clear_error.32
-rw-r--r--secure/lib/libcrypto/man/ERR_error_string.32
-rw-r--r--secure/lib/libcrypto/man/ERR_get_error.32
-rw-r--r--secure/lib/libcrypto/man/ERR_load_crypto_strings.32
-rw-r--r--secure/lib/libcrypto/man/ERR_load_strings.32
-rw-r--r--secure/lib/libcrypto/man/ERR_print_errors.32
-rw-r--r--secure/lib/libcrypto/man/ERR_put_error.32
-rw-r--r--secure/lib/libcrypto/man/ERR_remove_state.32
-rw-r--r--secure/lib/libcrypto/man/ERR_set_mark.32
-rw-r--r--secure/lib/libcrypto/man/EVP_BytesToKey.32
-rw-r--r--secure/lib/libcrypto/man/EVP_DigestInit.32
-rw-r--r--secure/lib/libcrypto/man/EVP_EncryptInit.32
-rw-r--r--secure/lib/libcrypto/man/EVP_OpenInit.32
-rw-r--r--secure/lib/libcrypto/man/EVP_PKEY_new.32
-rw-r--r--secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.32
-rw-r--r--secure/lib/libcrypto/man/EVP_SealInit.32
-rw-r--r--secure/lib/libcrypto/man/EVP_SignInit.32
-rw-r--r--secure/lib/libcrypto/man/EVP_VerifyInit.32
-rw-r--r--secure/lib/libcrypto/man/OBJ_nid2obj.32
-rw-r--r--secure/lib/libcrypto/man/OPENSSL_Applink.32
-rw-r--r--secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.32
-rw-r--r--secure/lib/libcrypto/man/OPENSSL_config.32
-rw-r--r--secure/lib/libcrypto/man/OPENSSL_ia32cap.32
-rw-r--r--secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.32
-rw-r--r--secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.32
-rw-r--r--secure/lib/libcrypto/man/PKCS12_create.32
-rw-r--r--secure/lib/libcrypto/man/PKCS12_parse.32
-rw-r--r--secure/lib/libcrypto/man/PKCS7_decrypt.32
-rw-r--r--secure/lib/libcrypto/man/PKCS7_encrypt.32
-rw-r--r--secure/lib/libcrypto/man/PKCS7_sign.32
-rw-r--r--secure/lib/libcrypto/man/PKCS7_verify.32
-rw-r--r--secure/lib/libcrypto/man/RAND_add.32
-rw-r--r--secure/lib/libcrypto/man/RAND_bytes.32
-rw-r--r--secure/lib/libcrypto/man/RAND_cleanup.32
-rw-r--r--secure/lib/libcrypto/man/RAND_egd.32
-rw-r--r--secure/lib/libcrypto/man/RAND_load_file.32
-rw-r--r--secure/lib/libcrypto/man/RAND_set_rand_method.32
-rw-r--r--secure/lib/libcrypto/man/RSA_blinding_on.32
-rw-r--r--secure/lib/libcrypto/man/RSA_check_key.32
-rw-r--r--secure/lib/libcrypto/man/RSA_generate_key.32
-rw-r--r--secure/lib/libcrypto/man/RSA_get_ex_new_index.32
-rw-r--r--secure/lib/libcrypto/man/RSA_new.32
-rw-r--r--secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.32
-rw-r--r--secure/lib/libcrypto/man/RSA_print.32
-rw-r--r--secure/lib/libcrypto/man/RSA_private_encrypt.32
-rw-r--r--secure/lib/libcrypto/man/RSA_public_encrypt.32
-rw-r--r--secure/lib/libcrypto/man/RSA_set_method.32
-rw-r--r--secure/lib/libcrypto/man/RSA_sign.32
-rw-r--r--secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.32
-rw-r--r--secure/lib/libcrypto/man/RSA_size.32
-rw-r--r--secure/lib/libcrypto/man/SMIME_read_PKCS7.32
-rw-r--r--secure/lib/libcrypto/man/SMIME_write_PKCS7.32
-rw-r--r--secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.32
-rw-r--r--secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.32
-rw-r--r--secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.32
-rw-r--r--secure/lib/libcrypto/man/X509_NAME_print_ex.32
-rw-r--r--secure/lib/libcrypto/man/X509_new.32
-rw-r--r--secure/lib/libcrypto/man/bio.32
-rw-r--r--secure/lib/libcrypto/man/blowfish.32
-rw-r--r--secure/lib/libcrypto/man/bn.32
-rw-r--r--secure/lib/libcrypto/man/bn_internal.32
-rw-r--r--secure/lib/libcrypto/man/buffer.32
-rw-r--r--secure/lib/libcrypto/man/crypto.32
-rw-r--r--secure/lib/libcrypto/man/d2i_ASN1_OBJECT.32
-rw-r--r--secure/lib/libcrypto/man/d2i_DHparams.32
-rw-r--r--secure/lib/libcrypto/man/d2i_DSAPublicKey.32
-rw-r--r--secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.32
-rw-r--r--secure/lib/libcrypto/man/d2i_RSAPublicKey.32
-rw-r--r--secure/lib/libcrypto/man/d2i_X509.32
-rw-r--r--secure/lib/libcrypto/man/d2i_X509_ALGOR.32
-rw-r--r--secure/lib/libcrypto/man/d2i_X509_CRL.32
-rw-r--r--secure/lib/libcrypto/man/d2i_X509_NAME.32
-rw-r--r--secure/lib/libcrypto/man/d2i_X509_REQ.32
-rw-r--r--secure/lib/libcrypto/man/d2i_X509_SIG.32
-rw-r--r--secure/lib/libcrypto/man/des.32
-rw-r--r--secure/lib/libcrypto/man/dh.32
-rw-r--r--secure/lib/libcrypto/man/dsa.32
-rw-r--r--secure/lib/libcrypto/man/ecdsa.32
-rw-r--r--secure/lib/libcrypto/man/engine.32
-rw-r--r--secure/lib/libcrypto/man/err.32
-rw-r--r--secure/lib/libcrypto/man/evp.32
-rw-r--r--secure/lib/libcrypto/man/hmac.32
-rw-r--r--secure/lib/libcrypto/man/lh_stats.32
-rw-r--r--secure/lib/libcrypto/man/lhash.32
-rw-r--r--secure/lib/libcrypto/man/md5.32
-rw-r--r--secure/lib/libcrypto/man/mdc2.32
-rw-r--r--secure/lib/libcrypto/man/pem.32
-rw-r--r--secure/lib/libcrypto/man/rand.32
-rw-r--r--secure/lib/libcrypto/man/rc4.32
-rw-r--r--secure/lib/libcrypto/man/ripemd.32
-rw-r--r--secure/lib/libcrypto/man/rsa.32
-rw-r--r--secure/lib/libcrypto/man/sha.32
-rw-r--r--secure/lib/libcrypto/man/threads.32
-rw-r--r--secure/lib/libcrypto/man/ui.32
-rw-r--r--secure/lib/libcrypto/man/ui_compat.32
-rw-r--r--secure/lib/libcrypto/man/x509.32
-rw-r--r--secure/lib/libssl/man/SSL_CIPHER_get_name.32
-rw-r--r--secure/lib/libssl/man/SSL_COMP_add_compression_method.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_add_session.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_ctrl.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_flush_sessions.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_free.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_get_ex_new_index.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_get_verify_mode.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_load_verify_locations.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_new.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_sess_number.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_sessions.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_cert_store.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_cipher_list.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_client_CA_list.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_generate_session_id.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_info_callback.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_max_cert_list.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_mode.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_msg_callback.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_options.315
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_session_id_context.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_ssl_version.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_timeout.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_set_verify.32
-rw-r--r--secure/lib/libssl/man/SSL_CTX_use_certificate.32
-rw-r--r--secure/lib/libssl/man/SSL_SESSION_free.32
-rw-r--r--secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.32
-rw-r--r--secure/lib/libssl/man/SSL_SESSION_get_time.32
-rw-r--r--secure/lib/libssl/man/SSL_accept.32
-rw-r--r--secure/lib/libssl/man/SSL_alert_type_string.32
-rw-r--r--secure/lib/libssl/man/SSL_clear.32
-rw-r--r--secure/lib/libssl/man/SSL_connect.32
-rw-r--r--secure/lib/libssl/man/SSL_do_handshake.32
-rw-r--r--secure/lib/libssl/man/SSL_free.32
-rw-r--r--secure/lib/libssl/man/SSL_get_SSL_CTX.32
-rw-r--r--secure/lib/libssl/man/SSL_get_ciphers.32
-rw-r--r--secure/lib/libssl/man/SSL_get_client_CA_list.32
-rw-r--r--secure/lib/libssl/man/SSL_get_current_cipher.32
-rw-r--r--secure/lib/libssl/man/SSL_get_default_timeout.32
-rw-r--r--secure/lib/libssl/man/SSL_get_error.32
-rw-r--r--secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.32
-rw-r--r--secure/lib/libssl/man/SSL_get_ex_new_index.32
-rw-r--r--secure/lib/libssl/man/SSL_get_fd.32
-rw-r--r--secure/lib/libssl/man/SSL_get_peer_cert_chain.32
-rw-r--r--secure/lib/libssl/man/SSL_get_peer_certificate.32
-rw-r--r--secure/lib/libssl/man/SSL_get_rbio.32
-rw-r--r--secure/lib/libssl/man/SSL_get_session.32
-rw-r--r--secure/lib/libssl/man/SSL_get_verify_result.32
-rw-r--r--secure/lib/libssl/man/SSL_get_version.32
-rw-r--r--secure/lib/libssl/man/SSL_library_init.32
-rw-r--r--secure/lib/libssl/man/SSL_load_client_CA_file.32
-rw-r--r--secure/lib/libssl/man/SSL_new.32
-rw-r--r--secure/lib/libssl/man/SSL_pending.32
-rw-r--r--secure/lib/libssl/man/SSL_read.32
-rw-r--r--secure/lib/libssl/man/SSL_rstate_string.32
-rw-r--r--secure/lib/libssl/man/SSL_session_reused.32
-rw-r--r--secure/lib/libssl/man/SSL_set_bio.32
-rw-r--r--secure/lib/libssl/man/SSL_set_connect_state.32
-rw-r--r--secure/lib/libssl/man/SSL_set_fd.32
-rw-r--r--secure/lib/libssl/man/SSL_set_session.32
-rw-r--r--secure/lib/libssl/man/SSL_set_shutdown.32
-rw-r--r--secure/lib/libssl/man/SSL_set_verify_result.32
-rw-r--r--secure/lib/libssl/man/SSL_shutdown.32
-rw-r--r--secure/lib/libssl/man/SSL_state_string.32
-rw-r--r--secure/lib/libssl/man/SSL_want.32
-rw-r--r--secure/lib/libssl/man/SSL_write.32
-rw-r--r--secure/lib/libssl/man/d2i_SSL_SESSION.32
-rw-r--r--secure/lib/libssl/man/ssl.32
-rw-r--r--secure/usr.bin/openssl/man/CA.pl.12
-rw-r--r--secure/usr.bin/openssl/man/asn1parse.12
-rw-r--r--secure/usr.bin/openssl/man/ca.12
-rw-r--r--secure/usr.bin/openssl/man/ciphers.12
-rw-r--r--secure/usr.bin/openssl/man/crl.12
-rw-r--r--secure/usr.bin/openssl/man/crl2pkcs7.12
-rw-r--r--secure/usr.bin/openssl/man/dgst.12
-rw-r--r--secure/usr.bin/openssl/man/dhparam.12
-rw-r--r--secure/usr.bin/openssl/man/dsa.12
-rw-r--r--secure/usr.bin/openssl/man/dsaparam.12
-rw-r--r--secure/usr.bin/openssl/man/ec.12
-rw-r--r--secure/usr.bin/openssl/man/ecparam.12
-rw-r--r--secure/usr.bin/openssl/man/enc.12
-rw-r--r--secure/usr.bin/openssl/man/errstr.12
-rw-r--r--secure/usr.bin/openssl/man/gendsa.12
-rw-r--r--secure/usr.bin/openssl/man/genrsa.12
-rw-r--r--secure/usr.bin/openssl/man/nseq.12
-rw-r--r--secure/usr.bin/openssl/man/ocsp.12
-rw-r--r--secure/usr.bin/openssl/man/openssl.12
-rw-r--r--secure/usr.bin/openssl/man/passwd.12
-rw-r--r--secure/usr.bin/openssl/man/pkcs12.12
-rw-r--r--secure/usr.bin/openssl/man/pkcs7.12
-rw-r--r--secure/usr.bin/openssl/man/pkcs8.12
-rw-r--r--secure/usr.bin/openssl/man/rand.12
-rw-r--r--secure/usr.bin/openssl/man/req.12
-rw-r--r--secure/usr.bin/openssl/man/rsa.12
-rw-r--r--secure/usr.bin/openssl/man/rsautl.12
-rw-r--r--secure/usr.bin/openssl/man/s_client.12
-rw-r--r--secure/usr.bin/openssl/man/s_server.12
-rw-r--r--secure/usr.bin/openssl/man/s_time.12
-rw-r--r--secure/usr.bin/openssl/man/sess_id.12
-rw-r--r--secure/usr.bin/openssl/man/smime.12
-rw-r--r--secure/usr.bin/openssl/man/speed.12
-rw-r--r--secure/usr.bin/openssl/man/spkac.12
-rw-r--r--secure/usr.bin/openssl/man/verify.12
-rw-r--r--secure/usr.bin/openssl/man/version.12
-rw-r--r--secure/usr.bin/openssl/man/x509.12
-rw-r--r--secure/usr.bin/openssl/man/x509v3_config.12
-rw-r--r--share/doc/psd/12.make/Makefile1
-rw-r--r--share/doc/psd/12.make/stubs (renamed from usr.bin/make/PSD.doc/stubs)0
-rw-r--r--share/doc/psd/12.make/tutorial.ms (renamed from usr.bin/make/PSD.doc/tutorial.ms)0
-rw-r--r--share/doc/psd/18.gprof/Makefile1
-rw-r--r--share/doc/psd/18.gprof/abstract.me (renamed from usr.bin/gprof/PSD.doc/abstract.me)0
-rw-r--r--share/doc/psd/18.gprof/gathering.me (renamed from usr.bin/gprof/PSD.doc/gathering.me)0
-rw-r--r--share/doc/psd/18.gprof/header.me (renamed from usr.bin/gprof/PSD.doc/header.me)0
-rw-r--r--share/doc/psd/18.gprof/intro.me (renamed from usr.bin/gprof/PSD.doc/intro.me)0
-rw-r--r--share/doc/psd/18.gprof/postp.me (renamed from usr.bin/gprof/PSD.doc/postp.me)0
-rw-r--r--share/doc/psd/18.gprof/postp1.pic (renamed from usr.bin/gprof/PSD.doc/postp1.pic)0
-rw-r--r--share/doc/psd/18.gprof/postp2.pic (renamed from usr.bin/gprof/PSD.doc/postp2.pic)0
-rw-r--r--share/doc/psd/18.gprof/postp3.pic (renamed from usr.bin/gprof/PSD.doc/postp3.pic)0
-rw-r--r--share/doc/psd/18.gprof/pres1.pic (renamed from usr.bin/gprof/PSD.doc/pres1.pic)0
-rw-r--r--share/doc/psd/18.gprof/pres2.pic (renamed from usr.bin/gprof/PSD.doc/pres2.pic)0
-rw-r--r--share/doc/psd/18.gprof/present.me (renamed from usr.bin/gprof/PSD.doc/present.me)0
-rw-r--r--share/doc/psd/18.gprof/profiling.me (renamed from usr.bin/gprof/PSD.doc/profiling.me)0
-rw-r--r--share/doc/psd/18.gprof/refs.me (renamed from usr.bin/gprof/PSD.doc/refs.me)0
-rw-r--r--share/doc/psd/22.rpcgen/Makefile1
-rw-r--r--share/doc/psd/22.rpcgen/rpcgen.ms (renamed from lib/libc/rpc/PSD.doc/rpcgen.ms)0
-rw-r--r--share/doc/psd/22.rpcgen/stubs (renamed from lib/libc/rpc/PSD.doc/stubs)0
-rw-r--r--share/doc/psd/23.rpc/Makefile1
-rw-r--r--share/doc/psd/23.rpc/rpc.prog.ms (renamed from lib/libc/rpc/PSD.doc/rpc.prog.ms)0
-rw-r--r--share/doc/psd/23.rpc/stubs3
-rw-r--r--share/doc/psd/24.xdr/Makefile1
-rw-r--r--share/doc/psd/24.xdr/stubs3
-rw-r--r--share/doc/psd/24.xdr/xdr.nts.ms (renamed from lib/libc/rpc/PSD.doc/xdr.nts.ms)0
-rw-r--r--share/doc/psd/25.xdrrfc/Makefile1
-rw-r--r--share/doc/psd/25.xdrrfc/stubs3
-rw-r--r--share/doc/psd/25.xdrrfc/xdr.rfc.ms (renamed from lib/libc/rpc/PSD.doc/xdr.rfc.ms)0
-rw-r--r--share/doc/psd/26.rpcrfc/Makefile1
-rw-r--r--share/doc/psd/26.rpcrfc/rpc.rfc.ms (renamed from lib/libc/rpc/PSD.doc/rpc.rfc.ms)0
-rw-r--r--share/doc/psd/26.rpcrfc/stubs3
-rw-r--r--share/doc/psd/27.nfsrpc/Makefile1
-rw-r--r--share/doc/psd/27.nfsrpc/nfs.rfc.ms (renamed from lib/libc/rpc/PSD.doc/nfs.rfc.ms)0
-rw-r--r--share/doc/psd/27.nfsrpc/stubs3
-rw-r--r--share/doc/smm/02.config/0.t (renamed from usr.sbin/config/SMM.doc/0.t)0
-rw-r--r--share/doc/smm/02.config/1.t (renamed from usr.sbin/config/SMM.doc/1.t)0
-rw-r--r--share/doc/smm/02.config/2.t (renamed from usr.sbin/config/SMM.doc/2.t)0
-rw-r--r--share/doc/smm/02.config/3.t (renamed from usr.sbin/config/SMM.doc/3.t)0
-rw-r--r--share/doc/smm/02.config/4.t (renamed from usr.sbin/config/SMM.doc/4.t)0
-rw-r--r--share/doc/smm/02.config/5.t (renamed from usr.sbin/config/SMM.doc/5.t)0
-rw-r--r--share/doc/smm/02.config/6.t (renamed from usr.sbin/config/SMM.doc/6.t)0
-rw-r--r--share/doc/smm/02.config/Makefile1
-rw-r--r--share/doc/smm/02.config/a.t (renamed from usr.sbin/config/SMM.doc/a.t)0
-rw-r--r--share/doc/smm/02.config/b.t (renamed from usr.sbin/config/SMM.doc/b.t)0
-rw-r--r--share/doc/smm/02.config/c.t (renamed from usr.sbin/config/SMM.doc/c.t)0
-rw-r--r--share/doc/smm/02.config/d.t (renamed from usr.sbin/config/SMM.doc/d.t)0
-rw-r--r--share/doc/smm/02.config/e.t (renamed from usr.sbin/config/SMM.doc/e.t)0
-rw-r--r--share/doc/smm/02.config/spell.ok (renamed from usr.sbin/config/SMM.doc/spell.ok)0
-rw-r--r--share/doc/smm/03.fsck/0.t (renamed from sbin/fsck_ffs/SMM.doc/0.t)0
-rw-r--r--share/doc/smm/03.fsck/1.t (renamed from sbin/fsck_ffs/SMM.doc/1.t)0
-rw-r--r--share/doc/smm/03.fsck/2.t (renamed from sbin/fsck_ffs/SMM.doc/2.t)0
-rw-r--r--share/doc/smm/03.fsck/3.t (renamed from sbin/fsck_ffs/SMM.doc/3.t)0
-rw-r--r--share/doc/smm/03.fsck/4.t (renamed from sbin/fsck_ffs/SMM.doc/4.t)0
-rw-r--r--share/doc/smm/03.fsck/Makefile1
-rw-r--r--share/doc/smm/07.lpr/0.t (renamed from usr.sbin/lpr/SMM.doc/0.t)0
-rw-r--r--share/doc/smm/07.lpr/1.t (renamed from usr.sbin/lpr/SMM.doc/1.t)0
-rw-r--r--share/doc/smm/07.lpr/2.t (renamed from usr.sbin/lpr/SMM.doc/2.t)0
-rw-r--r--share/doc/smm/07.lpr/3.t (renamed from usr.sbin/lpr/SMM.doc/3.t)0
-rw-r--r--share/doc/smm/07.lpr/4.t (renamed from usr.sbin/lpr/SMM.doc/4.t)0
-rw-r--r--share/doc/smm/07.lpr/5.t (renamed from usr.sbin/lpr/SMM.doc/5.t)0
-rw-r--r--share/doc/smm/07.lpr/6.t (renamed from usr.sbin/lpr/SMM.doc/6.t)0
-rw-r--r--share/doc/smm/07.lpr/7.t (renamed from usr.sbin/lpr/SMM.doc/7.t)0
-rw-r--r--share/doc/smm/07.lpr/Makefile (renamed from usr.sbin/lpr/SMM.doc/Makefile)3
-rw-r--r--share/doc/smm/07.lpr/spell.ok (renamed from usr.sbin/lpr/SMM.doc/spell.ok)0
-rw-r--r--share/doc/smm/11.timedop/Makefile1
-rw-r--r--share/doc/smm/11.timedop/timed.ms (renamed from usr.sbin/timed/SMM.doc/timedop/timed.ms)0
-rw-r--r--share/doc/smm/12.timed/Makefile1
-rw-r--r--share/doc/smm/12.timed/date (renamed from usr.sbin/timed/SMM.doc/timed/date)0
-rw-r--r--share/doc/smm/12.timed/loop (renamed from usr.sbin/timed/SMM.doc/timed/loop)0
-rw-r--r--share/doc/smm/12.timed/spell.ok (renamed from usr.sbin/timed/SMM.doc/timed/spell.ok)0
-rw-r--r--share/doc/smm/12.timed/time (renamed from usr.sbin/timed/SMM.doc/timed/time)0
-rw-r--r--share/doc/smm/12.timed/timed.ms (renamed from usr.sbin/timed/SMM.doc/timed/timed.ms)0
-rw-r--r--share/doc/smm/12.timed/unused (renamed from usr.sbin/timed/SMM.doc/timed/unused)0
-rw-r--r--share/doc/usd/04.csh/Makefile1
-rw-r--r--share/doc/usd/04.csh/csh.1 (renamed from bin/csh/USD.doc/csh.1)0
-rw-r--r--share/doc/usd/04.csh/csh.2 (renamed from bin/csh/USD.doc/csh.2)0
-rw-r--r--share/doc/usd/04.csh/csh.3 (renamed from bin/csh/USD.doc/csh.3)0
-rw-r--r--share/doc/usd/04.csh/csh.4 (renamed from bin/csh/USD.doc/csh.4)0
-rw-r--r--share/doc/usd/04.csh/csh.a (renamed from bin/csh/USD.doc/csh.a)0
-rw-r--r--share/doc/usd/04.csh/csh.g (renamed from bin/csh/USD.doc/csh.g)0
-rw-r--r--share/doc/usd/04.csh/tabs (renamed from bin/csh/USD.doc/tabs)0
-rw-r--r--share/doc/usd/05.dc/Makefile1
-rw-r--r--share/doc/usd/05.dc/dc (renamed from usr.bin/dc/USD.doc/dc)0
-rw-r--r--share/doc/usd/06.bc/Makefile1
-rw-r--r--share/doc/usd/06.bc/bc (renamed from usr.bin/bc/USD.doc/bc)0
-rw-r--r--share/doc/usd/07.mail/Makefile1
-rw-r--r--share/doc/usd/07.mail/mail0.nr (renamed from usr.bin/mail/USD.doc/mail0.nr)0
-rw-r--r--share/doc/usd/07.mail/mail1.nr (renamed from usr.bin/mail/USD.doc/mail1.nr)0
-rw-r--r--share/doc/usd/07.mail/mail2.nr (renamed from usr.bin/mail/USD.doc/mail2.nr)0
-rw-r--r--share/doc/usd/07.mail/mail3.nr (renamed from usr.bin/mail/USD.doc/mail3.nr)0
-rw-r--r--share/doc/usd/07.mail/mail4.nr (renamed from usr.bin/mail/USD.doc/mail4.nr)0
-rw-r--r--share/doc/usd/07.mail/mail5.nr (renamed from usr.bin/mail/USD.doc/mail5.nr)0
-rw-r--r--share/doc/usd/07.mail/mail6.nr (renamed from usr.bin/mail/USD.doc/mail6.nr)0
-rw-r--r--share/doc/usd/07.mail/mail7.nr (renamed from usr.bin/mail/USD.doc/mail7.nr)0
-rw-r--r--share/doc/usd/07.mail/mail8.nr (renamed from usr.bin/mail/USD.doc/mail8.nr)0
-rw-r--r--share/doc/usd/07.mail/mail9.nr (renamed from usr.bin/mail/USD.doc/mail9.nr)0
-rw-r--r--share/doc/usd/07.mail/maila.nr (renamed from usr.bin/mail/USD.doc/maila.nr)0
-rw-r--r--share/man/man3/fpgetround.36
-rw-r--r--share/man/man5/rc.conf.52
-rw-r--r--share/man/man9/Makefile2
-rw-r--r--share/man/man9/SYSINIT.9163
-rw-r--r--share/man/man9/bus_space.93
-rw-r--r--share/misc/committers-ports.dot3
-rw-r--r--sys/amd64/amd64/busdma_machdep.c1205
-rw-r--r--sys/amd64/amd64/exception.S1
-rw-r--r--sys/amd64/amd64/genassym.c1
-rw-r--r--sys/amd64/amd64/identcpu.c48
-rw-r--r--sys/amd64/amd64/machdep.c13
-rw-r--r--sys/amd64/amd64/tsc.c231
-rw-r--r--sys/amd64/amd64/vm_machdep.c6
-rw-r--r--sys/amd64/ia32/ia32_signal.c3
-rw-r--r--sys/amd64/include/cpu.h1
-rw-r--r--sys/amd64/include/pcb.h1
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c6
-rw-r--r--sys/arm/at91/at91_pmc.c2
-rw-r--r--sys/cddl/compat/opensolaris/sys/cyclic_impl.h9
-rw-r--r--sys/cddl/dev/cyclic/cyclic.c339
-rw-r--r--sys/cddl/dev/cyclic/i386/cyclic_machdep.c12
-rw-r--r--sys/cddl/dev/dtrace/amd64/dtrace_subr.c28
-rw-r--r--sys/cddl/dev/dtrace/i386/dtrace_subr.c28
-rw-r--r--sys/compat/ndis/kern_ndis.c13
-rw-r--r--sys/compat/ndis/ndis_var.h1
-rw-r--r--sys/compat/ndis/ntoskrnl_var.h1
-rw-r--r--sys/compat/ndis/subr_ndis.c13
-rw-r--r--sys/compat/ndis/subr_ntoskrnl.c12
-rw-r--r--sys/conf/files.amd644
-rw-r--r--sys/conf/files.i3864
-rw-r--r--sys/conf/files.mips1
-rw-r--r--sys/conf/files.pc984
-rw-r--r--sys/conf/files.powerpc3
-rw-r--r--sys/dev/aac/aac_cam.c3
-rw-r--r--sys/dev/acpica/acpi_hpet.c20
-rw-r--r--sys/dev/ahci/ahci.c4
-rw-r--r--sys/dev/bwn/if_bwn.c4
-rw-r--r--sys/dev/e1000/if_em.c69
-rw-r--r--sys/dev/e1000/if_igb.c2
-rw-r--r--sys/dev/ichwd/ichwd.c28
-rw-r--r--sys/dev/ichwd/ichwd.h11
-rw-r--r--sys/dev/iwn/if_iwn.c44
-rw-r--r--sys/dev/iwn/if_iwnvar.h1
-rw-r--r--sys/dev/ixgbe/ixgbe.c6
-rw-r--r--sys/dev/mfi/mfi_cam.c8
-rw-r--r--sys/dev/mps/mps.c2
-rw-r--r--sys/dev/siba/siba_bwn.c2
-rw-r--r--sys/dev/sis/if_sisreg.h2
-rw-r--r--sys/dev/usb/net/if_axe.c73
-rw-r--r--sys/dev/usb/usb_pf.c1
-rw-r--r--sys/dev/usb/usb_request.c4
-rw-r--r--sys/dev/wpi/if_wpi.c21
-rw-r--r--sys/dev/xen/blkfront/blkfront.c2
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c18
-rw-r--r--sys/geom/part/g_part_mbr.c6
-rw-r--r--sys/i386/i386/identcpu.c48
-rw-r--r--sys/i386/i386/machdep.c10
-rw-r--r--sys/i386/i386/pmap.c101
-rw-r--r--sys/i386/include/cpu.h2
-rw-r--r--sys/kern/init_main.c1
-rw-r--r--sys/kern/kern_fork.c119
-rw-r--r--sys/kern/kern_thread.c46
-rw-r--r--sys/kern/kern_umtx.c16
-rw-r--r--sys/kern/sched_4bsd.c23
-rw-r--r--sys/kern/sched_ule.c21
-rw-r--r--sys/kern/uipc_usrreq.c81
-rw-r--r--sys/mips/adm5120/adm5120_machdep.c3
-rw-r--r--sys/mips/alchemy/alchemy_machdep.c3
-rw-r--r--sys/mips/atheros/ar71xx_machdep.c3
-rw-r--r--sys/mips/cavium/octeon_machdep.c8
-rw-r--r--sys/mips/idt/idt_machdep.c3
-rw-r--r--sys/mips/include/md_var.h6
-rw-r--r--sys/mips/include/pmap.h3
-rw-r--r--sys/mips/include/vmparam.h8
-rw-r--r--sys/mips/malta/malta_machdep.c3
-rw-r--r--sys/mips/mips/minidump_machdep.c4
-rw-r--r--sys/mips/mips/mp_machdep.c2
-rw-r--r--sys/mips/mips/pmap.c47
-rw-r--r--sys/mips/mips/uma_machdep.c87
-rw-r--r--sys/mips/mips/vm_machdep.c3
-rw-r--r--sys/mips/rmi/dev/nlge/if_nlge.c1
-rw-r--r--sys/mips/rmi/xlr_machdep.c7
-rw-r--r--sys/mips/rmi/xlr_pci.c7
-rw-r--r--sys/mips/sentry5/s5_machdep.c5
-rw-r--r--sys/mips/sibyte/sb_machdep.c5
-rw-r--r--sys/net/if.h4
-rw-r--r--sys/netinet/ip_fastfwd.c2
-rw-r--r--sys/netinet/sctp_indata.c69
-rw-r--r--sys/netinet/sctp_input.c2
-rw-r--r--sys/netinet/sctp_structs.h1
-rw-r--r--sys/netinet6/nd6.c37
-rw-r--r--sys/pc98/pc98/machdep.c10
-rw-r--r--sys/powerpc/aim/mmu_oea.c18
-rw-r--r--sys/powerpc/aim/mmu_oea64.c780
-rw-r--r--sys/powerpc/aim/mmu_oea64.h77
-rw-r--r--sys/powerpc/aim/moea64_if.m115
-rw-r--r--sys/powerpc/aim/moea64_native.c637
-rw-r--r--sys/powerpc/include/bus_dma.h4
-rw-r--r--sys/powerpc/include/pmap.h19
-rw-r--r--sys/powerpc/include/pte.h4
-rw-r--r--sys/powerpc/powerpc/busdma_machdep.c198
-rw-r--r--sys/powerpc/powerpc/iommu_if.m54
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/proc.h3
-rw-r--r--sys/sys/queue.h6
-rw-r--r--sys/teken/teken_subr.h3
-rw-r--r--sys/vm/vm_map.c42
-rw-r--r--sys/vm/vm_map.h5
-rw-r--r--sys/vm/vm_mmap.c16
-rw-r--r--sys/vm/vm_page.c9
-rw-r--r--sys/x86/x86/busdma_machdep.c (renamed from sys/i386/i386/busdma_machdep.c)40
-rw-r--r--sys/x86/x86/tsc.c (renamed from sys/i386/i386/tsc.c)46
-rw-r--r--sys/xen/evtchn/evtchn.c53
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc1
-rw-r--r--tools/regression/lib/msun/Makefile4
-rw-r--r--tools/regression/lib/msun/test-exponential.c2
-rw-r--r--tools/regression/lib/msun/test-fma.c3
-rw-r--r--tools/regression/lib/msun/test-fmaxmin.c9
-rw-r--r--tools/regression/lib/msun/test-invtrig.c2
-rw-r--r--tools/regression/lib/msun/test-logarithm.c158
-rw-r--r--tools/regression/lib/msun/test-logarithm.t10
-rw-r--r--tools/regression/lib/msun/test-lrint.c7
-rw-r--r--tools/regression/lib/msun/test-nearbyint.c100
-rw-r--r--tools/regression/lib/msun/test-nearbyint.t10
-rw-r--r--tools/regression/lib/msun/test-trig.c2
-rw-r--r--tools/regression/sockets/unix_gc/unix_gc.c63
-rw-r--r--tools/regression/usr.bin/printf/regress.m5.out1
-rw-r--r--tools/regression/usr.bin/printf/regress.sh3
-rw-r--r--tools/tools/nanobsd/nanobsd.sh8
-rw-r--r--usr.bin/calendar/calendars/calendar.freebsd1
-rwxr-xr-xusr.bin/man/man.sh104
-rw-r--r--usr.bin/printf/printf.c10
-rw-r--r--usr.bin/stat/Makefile1
-rw-r--r--usr.bin/stat/stat.1104
-rw-r--r--usr.bin/stat/stat.c118
-rw-r--r--usr.bin/truss/syscalls.c2
-rw-r--r--usr.sbin/Makefile.amd643
-rw-r--r--usr.sbin/ac/ac.c2
-rw-r--r--usr.sbin/boot0cfg/boot0cfg.c2
-rw-r--r--usr.sbin/bsnmpd/Makefile3
-rw-r--r--usr.sbin/bsnmpd/bsnmpd/Makefile8
-rw-r--r--usr.sbin/bsnmpd/modules/Makefile2
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c1
-rwxr-xr-xusr.sbin/bsnmpd/modules/snmp_usm/Makefile22
-rwxr-xr-xusr.sbin/bsnmpd/modules/snmp_vacm/Makefile20
-rw-r--r--usr.sbin/bsnmpd/tools/Makefile7
-rw-r--r--usr.sbin/bsnmpd/tools/Makefile.inc13
-rw-r--r--usr.sbin/bsnmpd/tools/bsnmptools/Makefile28
-rw-r--r--usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1401
-rw-r--r--usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c1275
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/Makefile14
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpimport.c971
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c1018
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.c1287
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.h95
-rwxr-xr-xusr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c2121
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h331
-rw-r--r--usr.sbin/cxgbtool/cxgbtool.c3
-rw-r--r--usr.sbin/extattrctl/extattrctl.c6
-rw-r--r--usr.sbin/fifolog/lib/fifolog_write.h6
-rw-r--r--usr.sbin/fifolog/lib/fifolog_write_poll.c290
-rw-r--r--usr.sbin/fwcontrol/fwcontrol.c1
-rw-r--r--usr.sbin/lpr/Makefile2
-rw-r--r--usr.sbin/rarpd/rarpd.c4
-rw-r--r--usr.sbin/sysinstall/dist.c5
-rw-r--r--usr.sbin/sysinstall/install.c2
-rw-r--r--usr.sbin/timed/SMM.doc/timed/Makefile12
-rw-r--r--usr.sbin/timed/SMM.doc/timedop/Makefile8
-rw-r--r--usr.sbin/traceroute/Makefile2
-rw-r--r--usr.sbin/traceroute6/Makefile2
-rw-r--r--usr.sbin/traceroute6/traceroute6.c27
-rw-r--r--usr.sbin/usbdevs/Makefile7
-rw-r--r--usr.sbin/usbdevs/usbdevs.870
-rw-r--r--usr.sbin/usbdevs/usbdevs.c233
-rw-r--r--usr.sbin/usbdump/usbdump.c2
681 files changed, 17733 insertions, 4560 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 0756547..5828a52 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -22,16 +22,33 @@
# grep '+=' /usr/src/tools/build/mk/OptionalObsoleteFiles.inc | sort -u) | \
# sort | uniq -d
#
+# To find regular duplicates not dependant on optional components, you can
+# also use something that will not give you false positives, e.g.:
+# for t in `make -V TARGETS universe`; do
+# __MAKE_CONF=/dev/null make -f Makefile.inc1 TARGET=$t \
+# -V OLD_FILES -V OLD_LIBS -V OLD_DIRS check-old | \
+# xargs -n1 | sort | uniq -d;
+# done
+#
+# For optional components, you can use the following to see if some entries
+# in OptionalObsoleteFiles.inc have been obsoleted by ObsoleteFiles.inc
+# for o in tools/build/options/WITH*; do
+# __MAKE_CONF=/dev/null make -f Makefile.inc1 -D${o##*/} \
+# -V OLD_FILES -V OLD_LIBS -V OLD_DIRS check-old | \
+# xargs -n1 | sort | uniq -d;
+# done
+# 20101114: Remove long-obsolete MAKEDEV.8
+OLD_FILES+=usr/share/man/man8/MAKEDEV.8.gz
# 20101112: vgonel(9) has gone to private API a while ago
OLD_FILES+=usr/share/man/man9/vgonel.9.gz
# 20101112: removed gasp.info
OLD_FILES+=usr/share/info/gasp.info.gz
-# 20101109: headers moved to machine/ to x86/
+# 20101109: headers moved from machine/ to x86/
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386"
OLD_FILES+=usr/include/machine/mptable.h
.endif
-# 20101101: headers moved to machine/ to x86/
+# 20101101: headers moved from machine/ to x86/
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386"
OLD_FILES+=usr/include/machine/apicreg.h
OLD_FILES+=usr/include/machine/mca.h
diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c
index 8722f67..de813c2 100644
--- a/bin/sh/jobs.c
+++ b/bin/sh/jobs.c
@@ -100,7 +100,8 @@ static void setcurjob(struct job *);
static void deljob(struct job *);
static struct job *getcurjob(struct job *);
#endif
-static void showjob(struct job *, pid_t, int);
+static void printjobcmd(struct job *);
+static void showjob(struct job *, int);
/*
@@ -205,8 +206,7 @@ fgcmd(int argc __unused, char **argv)
jp = getjob(argv[1]);
if (jp->jobctl == 0)
error("job not created under job control");
- out1str(jp->ps[0].cmd);
- out1c('\n');
+ printjobcmd(jp);
flushout(&output);
pgrp = jp->ps[0].pid;
tcsetpgrp(ttyfd, pgrp);
@@ -235,8 +235,7 @@ bgcmd(int argc, char **argv)
jp->foreground = 0;
fmtstr(s, 64, "[%td] ", jp - jobtab + 1);
out1str(s);
- out1str(jp->ps[0].cmd);
- out1c('\n');
+ printjobcmd(jp);
} while (--argc > 1);
return 0;
}
@@ -296,19 +295,33 @@ jobscmd(int argc, char *argv[])
showjobs(0, mode);
else
while ((id = *argv++) != NULL)
- showjob(getjob(id), 0, mode);
+ showjob(getjob(id), mode);
return (0);
}
static void
-showjob(struct job *jp, pid_t pid, int mode)
+printjobcmd(struct job *jp)
+{
+ struct procstat *ps;
+ int i;
+
+ for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
+ out1str(ps->cmd);
+ if (i > 0)
+ out1str(" | ");
+ }
+ out1c('\n');
+}
+
+static void
+showjob(struct job *jp, int mode)
{
char s[64];
+ char statestr[64];
struct procstat *ps;
struct job *j;
int col, curr, i, jobno, prev, procno;
- pid_t ppid;
char c;
procno = (mode == SHOWJOBS_PGIDS) ? 1 : jp->nprocs;
@@ -321,16 +334,44 @@ showjob(struct job *jp, pid_t pid, int mode)
prev = j - jobtab + 1;
}
#endif
+ ps = jp->ps + jp->nprocs - 1;
+ if (jp->state == 0) {
+ strcpy(statestr, "Running");
+#if JOBS
+ } else if (jp->state == JOBSTOPPED) {
+ while (!WIFSTOPPED(ps->status) && ps > jp->ps)
+ ps--;
+ if (WIFSTOPPED(ps->status))
+ i = WSTOPSIG(ps->status);
+ else
+ i = -1;
+ if (i > 0 && i < sys_nsig && sys_siglist[i])
+ strcpy(statestr, sys_siglist[i]);
+ else
+ strcpy(statestr, "Suspended");
+#endif
+ } else if (WIFEXITED(ps->status)) {
+ if (WEXITSTATUS(ps->status) == 0)
+ strcpy(statestr, "Done");
+ else
+ fmtstr(statestr, 64, "Done(%d)",
+ WEXITSTATUS(ps->status));
+ } else {
+ i = WTERMSIG(ps->status);
+ if (i > 0 && i < sys_nsig && sys_siglist[i])
+ strcpy(statestr, sys_siglist[i]);
+ else
+ fmtstr(statestr, 64, "Signal %d", i);
+ if (WCOREDUMP(ps->status))
+ strcat(statestr, " (core dumped)");
+ }
+
for (ps = jp->ps ; ; ps++) { /* for each process */
if (mode == SHOWJOBS_PIDS || mode == SHOWJOBS_PGIDS) {
- ppid = (mode == SHOWJOBS_PIDS) ? ps->pid :
- getpgid(ps->pid);
- out1fmt("%d\n", (int)ppid);
+ out1fmt("%d\n", (int)ps->pid);
goto skip;
}
- if (mode != SHOWJOBS_VERBOSE && ps != jp->ps && pid == 0)
- goto skip;
- if (pid != 0 && pid != ps->pid)
+ if (mode != SHOWJOBS_VERBOSE && ps != jp->ps)
goto skip;
if (jobno == curr && ps == jp->ps)
c = '+';
@@ -349,39 +390,19 @@ showjob(struct job *jp, pid_t pid, int mode)
out1str(s);
col += strlen(s);
}
- s[0] = '\0';
- if (ps != jp->ps) {
- *s = '\0';
- } else if (ps->status == -1) {
- strcpy(s, "Running");
- } else if (WIFEXITED(ps->status)) {
- if (WEXITSTATUS(ps->status) == 0)
- strcpy(s, "Done");
- else
- fmtstr(s, 64, "Done (%d)",
- WEXITSTATUS(ps->status));
- } else {
-#if JOBS
- if (WIFSTOPPED(ps->status))
- i = WSTOPSIG(ps->status);
- else
-#endif
- i = WTERMSIG(ps->status);
- if ((i & 0x7F) < sys_nsig && sys_siglist[i & 0x7F])
- scopy(sys_siglist[i & 0x7F], s);
- else
- fmtstr(s, 64, "Signal %d", i & 0x7F);
- if (WCOREDUMP(ps->status))
- strcat(s, " (core dumped)");
+ if (ps == jp->ps) {
+ out1str(statestr);
+ col += strlen(statestr);
}
- out1str(s);
- col += strlen(s);
do {
out1c(' ');
col++;
} while (col < 30);
- out1str(ps->cmd);
- out1c('\n');
+ if (mode == SHOWJOBS_VERBOSE) {
+ out1str(ps->cmd);
+ out1c('\n');
+ } else
+ printjobcmd(jp);
skip: if (--procno <= 0)
break;
}
@@ -413,7 +434,7 @@ showjobs(int change, int mode)
}
if (change && ! jp->changed)
continue;
- showjob(jp, 0, mode);
+ showjob(jp, mode);
jp->changed = 0;
/* Hack: discard jobs for which $! has not been referenced
* in interactive mode when they terminate.
@@ -769,7 +790,7 @@ forkshell(struct job *jp, union node *n, int mode)
TRACE(("forkshell(%%%td, %p, %d) called\n", jp - jobtab, (void *)n,
mode));
INTOFF;
- if (mode == FORK_BG)
+ if (mode == FORK_BG && (jp == NULL || jp->nprocs == 0))
checkzombies();
flushall();
pid = fork();
@@ -961,7 +982,7 @@ dowait(int block, struct job *job)
int done;
int stopped;
int sig;
- int i;
+ int coredump;
in_dowait++;
TRACE(("dowait(%d) called\n", block));
@@ -983,7 +1004,7 @@ dowait(int block, struct job *job)
INTOFF;
thisjob = NULL;
for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
- if (jp->used) {
+ if (jp->used && jp->nprocs > 0) {
done = 1;
stopped = 1;
for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
@@ -1020,36 +1041,29 @@ dowait(int block, struct job *job)
}
}
INTON;
- if (! rootshell || ! iflag || (job && thisjob == job)) {
-#if JOBS
- if (WIFSTOPPED(status))
- sig = WSTOPSIG(status);
- else
-#endif
- {
- if (WIFEXITED(status))
- sig = 0;
+ if (!thisjob || thisjob->state == 0)
+ ;
+ else if ((!rootshell || !iflag || thisjob == job) &&
+ thisjob->foreground && thisjob->state != JOBSTOPPED) {
+ sig = 0;
+ coredump = 0;
+ for (sp = thisjob->ps; sp < thisjob->ps + thisjob->nprocs; sp++)
+ if (WIFSIGNALED(sp->status)) {
+ sig = WTERMSIG(sp->status);
+ coredump = WCOREDUMP(sp->status);
+ }
+ if (sig > 0 && sig != SIGINT && sig != SIGPIPE) {
+ if (sig < sys_nsig && sys_siglist[sig])
+ out1str(sys_siglist[sig]);
else
- sig = WTERMSIG(status);
- }
- if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
- if (!mflag ||
- (thisjob->foreground && !WIFSTOPPED(status))) {
- i = WTERMSIG(status);
- if ((i & 0x7F) < sys_nsig && sys_siglist[i & 0x7F])
- out1str(sys_siglist[i & 0x7F]);
- else
- out1fmt("Signal %d", i & 0x7F);
- if (WCOREDUMP(status))
- out1str(" (core dumped)");
- out1c('\n');
- } else
- showjob(thisjob, pid, SHOWJOBS_DEFAULT);
+ out1fmt("Signal %d", sig);
+ if (coredump)
+ out1str(" (core dumped)");
+ out1c('\n');
}
} else {
TRACE(("Not printing status, rootshell=%d, job=%p\n", rootshell, job));
- if (thisjob)
- thisjob->changed = 1;
+ thisjob->changed = 1;
}
return pid;
}
@@ -1300,13 +1314,46 @@ cmdputs(const char *s)
if (--cmdnleft > 0)
*q++ = '{';
subtype = *p++;
+ if ((subtype & VSTYPE) == VSLENGTH && --cmdnleft > 0)
+ *q++ = '#';
} else if (c == '=' && subtype != 0) {
- *q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL];
+ *q = "}-+?=##%%\0X"[(subtype & VSTYPE) - VSNORMAL];
+ if (*q)
+ q++;
+ else
+ cmdnleft++;
+ if (((subtype & VSTYPE) == VSTRIMLEFTMAX ||
+ (subtype & VSTYPE) == VSTRIMRIGHTMAX) &&
+ --cmdnleft > 0)
+ *q = q[-1], q++;
subtype = 0;
} else if (c == CTLENDVAR) {
*q++ = '}';
- } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE)
- cmdnleft++; /* ignore it */
+ } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE) {
+ cmdnleft -= 5;
+ if (cmdnleft > 0) {
+ *q++ = '$';
+ *q++ = '(';
+ *q++ = '.';
+ *q++ = '.';
+ *q++ = '.';
+ *q++ = ')';
+ }
+ } else if (c == CTLARI) {
+ cmdnleft -= 2;
+ if (cmdnleft > 0) {
+ *q++ = '$';
+ *q++ = '(';
+ *q++ = '(';
+ }
+ p++;
+ } else if (c == CTLENDARI) {
+ if (--cmdnleft > 0) {
+ *q++ = ')';
+ *q++ = ')';
+ }
+ } else if (c == CTLQUOTEMARK || c == CTLQUOTEEND)
+ cmdnleft++; /* ignore */
else
*q++ = c;
if (--cmdnleft <= 0) {
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 16f431e..a6fd7be 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
-.Dd December 1, 2010
+.Dd December 3, 2010
.Dt SH 1
.Os
.Sh NAME
@@ -1593,12 +1593,7 @@ To include a
.Ql - ,
make it the first or last character listed.
.Ss Built-in Commands
-This section lists the commands which
-are built-in because they need to perform some operation
-that cannot be performed by a separate process.
-In addition to
-these, built-in versions of essential utilities
-are provided for efficiency.
+This section lists the built-in commands.
.Bl -tag -width indent
.It Ic \&:
A null command that returns a 0 (true) exit value.
@@ -1649,15 +1644,19 @@ subsection.
Continue the specified jobs
(or the current job if no jobs are given)
in the background.
+.It Ic bind Oo Fl aeklrsv Oc Oo Ar key Oo Ar command Oc Oc
+List or alter key bindings for the line editor.
+This command is documented in
+.Xr editrc 5 .
+.It Ic break Op Ar num
+See the
+.Sx Flow-Control Constructs
+subsection.
.It Ic builtin Ar cmd Op Ar arg ...
Execute the specified built-in command,
.Ar cmd .
This is useful when the user wishes to override a shell function
with the same name as a built-in command.
-.It Ic bind Oo Fl aeklrsv Oc Oo Ar key Oo Ar command Oc Oc
-List or alter key bindings for the line editor.
-This command is documented in
-.Xr editrc 5 .
.It Ic cd Oo Fl L | P Oc Op Ar directory
Switch to the specified
.Ar directory ,
@@ -1759,6 +1758,10 @@ a shell keyword
or
an alias for
.Ar value .
+.It Ic continue Op Ar num
+See the
+.Sx Flow-Control Constructs
+subsection.
.It Ic echo Oo Fl e | n Oc Op Ar string ...
Print a space-separated list of the arguments to the standard output
and append a newline character.
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
index d734f2c..c7edd2e 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
@@ -48,11 +48,13 @@
static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
+#ifdef sun
#if defined(__i386) || defined(__amd64)
#define BOOTCMD "installgrub(1M)"
#else
#define BOOTCMD "installboot(1M)"
#endif
+#endif /* sun */
/*
* ====================================================================
@@ -1889,14 +1891,15 @@ zpool_vdev_attach(zpool_handle_t *zhp,
if (ret == 0) {
if (rootpool) {
- /*
- * XXX - This should be removed once we can
- * automatically install the bootblocks on the
- * newly attached disk.
- */
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Please "
- "be sure to invoke %s to make '%s' bootable.\n"),
- BOOTCMD, new_disk);
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "If "
+ "you boot from pool '%s', you may need to update\n"
+ "boot code on newly attached disk '%s'.\n\n"
+ "Assuming you use GPT partitioning and 'da0' is "
+ "your new boot disk\n"
+ "you may use the following command:\n\n"
+ "\tgpart bootcode -b /boot/pmbr -p "
+ "/boot/gptzfsboot -i 1 da0\n\n"),
+ zhp->zpool_name, new_disk);
}
return (0);
}
diff --git a/contrib/bind9/CHANGES b/contrib/bind9/CHANGES
index cb2581a..a44c804 100644
--- a/contrib/bind9/CHANGES
+++ b/contrib/bind9/CHANGES
@@ -1,3 +1,55 @@
+
+ --- 9.6-ESV-R3 released ---
+
+2972. [bug] win32: address windows socket errors. [RT #21906]
+
+2971. [bug] Fixed a bug that caused journal files not to be
+ compacted on Windows systems as a result of
+ non-POSIX-compliant rename() semantics. [RT #22434]
+
+2970. [security] Adding a NO DATA negative cache entry failed to clear
+ any matching RRSIG records. A subsequent lookup of
+ of NO DATA cache entry could trigger a INSIST when the
+ unexpected RRSIG was also returned with the NO DATA
+ cache entry.
+
+ CVE-2010-3613, VU#706148. [RT #22288]
+
+2969. [security] Fix acl type processing so that allow-query works
+ in options and view statements. Also add a new
+ set of tests to verify proper functioning.
+
+ CVE-2010-3615, VU#510208. [RT #22418]
+
+2968. [security] Named could fail to prove a data set was insecure
+ before marking it as insecure. One set of conditions
+ that can trigger this occurs naturally when rolling
+ DNSKEY algorithms.
+
+ CVE-2010-3614, VU#837744. [RT #22309]
+
+2967. [bug] 'host -D' now turns on debugging messages earlier.
+ [RT #22361]
+
+2966. [bug] isc_print_vsnprintf() failed to check if there was
+ space available in the buffer when adding a left
+ justified character with a non zero width,
+ (e.g. "%-1c"). [RT #22270]
+
+2964. [bug] view->queryacl was being overloaded. Seperate the
+ usage into view->queryacl, view->cacheacl and
+ view->queryonacl. [RT #22114]
+
+2962. [port] win32: add more dependencies to BINDBuild.dsw.
+ [RT #22062]
+
+2952. [port] win32: named-checkzone and named-checkconf failed
+ to initialise winsock. [RT #21932]
+
+2951. [bug] named failed to generate a correct signed response
+ in a optout, delegation only zone with no secure
+ delegations. [RT #22007]
+
--- 9.6-ESV-R2 released ---
2939. [func] Check that named successfully skips NSEC3 records
diff --git a/contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.html b/contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.html
new file mode 100644
index 0000000..946330d
--- /dev/null
+++ b/contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.html
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ - Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: RELEASE-NOTES-BIND-9.6-ESV.html,v 1.1.2.2 2010/11/29 01:16:39 tbox Exp $ -->
+
+<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title></title><link rel="stylesheet" type="text/css" href="release-notes.css" /><meta name="generator" content="DocBook XSL Stylesheets V1.76.1" /></head><body><div class="article"><div class="titlepage"><hr /></div>
+
+ <div class="section" title="Introduction"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36111950"></a>Introduction</h2></div></div></div>
+
+ <p>
+ BIND 9.6-ESV-R3 is a maintenance release for BIND 9.6-ESV.
+ </p>
+ <p>
+ This document summarizes changes from BIND 9.6-ESV-R1 to BIND 9.6-ESV-R3.
+ Please see the CHANGES file in the source code release for a
+ complete list of all changes.
+ </p>
+ </div>
+
+ <div class="section" title="Download"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112014"></a>Download</h2></div></div></div>
+
+ <p>
+ The latest release of BIND 9 software can always be found
+ on our web site at
+ <a class="ulink" href="http://www.isc.org/software/bind" target="_top">http://www.isc.org/software/bind</a>.
+ There you will find additional information about each release,
+ source code, and some pre-compiled versions for certain operating
+ systems.
+ </p>
+ </div>
+
+ <div class="section" title="Support"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112037"></a>Support</h2></div></div></div>
+
+ <p>Product support information is available on
+ <a class="ulink" href="http://www.isc.org/services/support" target="_top">http://www.isc.org/services/support</a>
+ for paid support options. Free support is provided by our user
+ community via a mailing list. Information on all public email
+ lists is available at
+ <a class="ulink" href="https://lists.isc.org/mailman/listinfo" target="_top">https://lists.isc.org/mailman/listinfo</a>.
+ </p>
+ </div>
+
+ <div class="section" title="New Features"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36111986"></a>New Features</h2></div></div></div>
+
+ <div class="section" title="9.6-ESV-R2"><div class="titlepage"><div><div><h3 class="title"><a id="id36112025"></a>9.6-ESV-R2</h3></div></div></div>
+
+ <p>None.</p>
+ </div>
+ <div class="section" title="9.6-ESV-R3"><div class="titlepage"><div><div><h3 class="title"><a id="id36112098"></a>9.6-ESV-R3</h3></div></div></div>
+
+ <p>None.</p>
+ </div>
+ </div>
+
+ <div class="section" title="Feature Changes"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112120"></a>Feature Changes</h2></div></div></div>
+
+ <div class="section" title="9.6-ESV-R2"><div class="titlepage"><div><div><h3 class="title"><a id="id36112125"></a>9.6-ESV-R2</h3></div></div></div>
+
+ <p>None.</p>
+ </div>
+ <div class="section" title="9.6-ESV-R3"><div class="titlepage"><div><div><h3 class="title"><a id="id36112135"></a>9.6-ESV-R3</h3></div></div></div>
+
+ <p>None.</p>
+ </div>
+ </div>
+
+ <div class="section" title="Security Fixes"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112146"></a>Security Fixes</h2></div></div></div>
+
+ <div class="section" title="9.6-ESV-R2"><div class="titlepage"><div><div><h3 class="title"><a id="id36112151"></a>9.6-ESV-R2</h3></div></div></div>
+
+ <p>None.</p>
+ </div>
+ <div class="section" title="9.6-ESV-R3"><div class="titlepage"><div><div><h3 class="title"><a id="id36112160"></a>9.6-ESV-R3</h3></div></div></div>
+
+ <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
+ Adding a NO DATA signed negative response to cache failed to clear
+ any matching RRSIG records already in cache. A subsequent lookup
+ of the cached NO DATA entry could crash named (INSIST) when the
+ unexpected RRSIG was also returned with the NO DATA cache entry.
+ [RT #22288] [CVE-2010-3613] [VU#706148]
+ </li><li class="listitem">
+ BIND, acting as a DNSSEC validator, was determining if the NS RRset
+ is insecure based on a value that could mean either that the RRset
+ is actually insecure or that there wasn't a matching key for the RRSIG
+ in the DNSKEY RRset when resuming from validating the DNSKEY RRset.
+ This can happen when in the middle of a DNSKEY algorithm rollover,
+ when two different algorithms were used to sign a zone but only the
+ new set of keys are in the zone DNSKEY RRset.
+ [RT #22309] [CVE-2010-3614] [VU#837744]
+ </li></ul></div>
+ </div>
+ </div>
+
+ <div class="section" title="Bug Fixes"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112186"></a>Bug Fixes</h2></div></div></div>
+
+ <div class="section" title="9.6-ESV-R2"><div class="titlepage"><div><div><h3 class="title"><a id="id36112191"></a>9.6-ESV-R2</h3></div></div></div>
+
+ <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
+ Check that named successfully skips NSEC3 records
+ that fail to match the NSEC3PARAM record currently
+ in use.
+ [RT #21868]
+ </li><li class="listitem">
+ Worked around a race condition in the cache database memory
+ handling. Without this fix a DNS cache DB or ADB could
+ incorrectly stay in an over memory state, effectively refusing
+ further caching, which subsequently made a BIND 9 caching
+ server unworkable.
+ [RT #21818]
+ </li><li class="listitem">
+ BIND did not properly handle non-cacheable negative responses
+ from insecure zones. This caused several non-protocol-compliant
+ zones to become unresolvable. BIND is now more accepting of
+ responses it receives from less strict servers.
+ [RT #21555]
+ </li><li class="listitem">
+ The resolver could attempt to destroy a fetch context too
+ soon, resulting in a crash.
+ [RT #19878]
+ </li><li class="listitem">
+ The placeholder negative caching element was not
+ properly constructed triggering a crash (INSIST) in
+ dns_ncache_towire().
+ [RT #21346]
+ </li><li class="listitem">
+ Handle the introduction of new trusted-keys and
+ DS, DLV RRsets better.
+ [RT #21097]
+ </li><li class="listitem">
+ Fix arguments to dns_keytable_findnextkeynode() call.
+ [RT #20877]
+ </li></ul></div>
+ </div>
+ <div class="section" title="9.6-ESV-R3"><div class="titlepage"><div><div><h3 class="title"><a id="id36112232"></a>9.6-ESV-R3</h3></div></div></div>
+
+ <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
+ Microsoft changed the behavior of sockets between NT/XP based
+ stacks vs Vista/windows7 stacks. Server 2003/2008 have the older
+ behavior, 2008r2 has the new behavior. With the change, different
+ error results are possible, so ISC adapted BIND to handle the new
+ error results.
+ This resolves an issue where sockets would shut down on
+ Windows servers causing named to stop responding to queries.
+ [RT #21906]
+ </li><li class="listitem">
+ Windows has non-POSIX compliant behavior in its rename() and unlink()
+ calls. This caused journal compaction to fail on Windows BIND servers
+ with the log error: "dns_journal_compact failed: failure".
+ [RT #22434]
+ </li><li class="listitem">
+ 'host -D' now turns on debugging messages earlier.
+ [RT #22361]
+ </li><li class="listitem">
+ isc_print_vsnprintf() failed to check if there was
+ space available in the buffer when adding a left
+ justified character with a non zero width,
+ (e.g. "%-1c").
+ [RT #22270]
+ </li><li class="listitem">
+ view-&gt;queryacl was being overloaded. Seperate the
+ usage into view-&gt;queryacl, view-&gt;cacheacl and
+ view-&gt;queryonacl.
+ [RT #22114]
+ </li><li class="listitem">
+ win32: add more dependencies to BINDBuild.dsw.
+ [RT #22062]
+ </li><li class="listitem">
+ win32: named-checkzone and named-checkconf failed
+ to initialise winsock.
+ [RT #21932]
+ </li><li class="listitem">
+ named failed to generate a correct signed response
+ in a optout, delegation only zone with no secure
+ delegations.
+ [RT #22007]
+ </li></ul></div>
+ </div>
+ </div>
+
+ <div class="section" title="Known issues in this release"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112280"></a>Known issues in this release</h2></div></div></div>
+
+ <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
+ <p>
+ "make test" will fail on OSX and possibly other operating systems.
+ The failure occurs in a new test to check for allow-query ACLs.
+ The failure is caused because the source address is not specified on
+ the dig commands issued in the test.
+ </p>
+ <p>
+ If running "make test" is part of your usual acceptance process,
+ please edit the file <code class="code">bin/tests/system/allow_query/test.sh</code>
+ and add
+ </p><p>
+ <code class="code">-b 10.53.0.2</code>
+ </p><p>
+ to the <code class="code">DIGOPTS</code> line.
+ </p>
+ </li></ul></div>
+ </div>
+
+ <div class="section" title="Thank You"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112315"></a>Thank You</h2></div></div></div>
+
+ <p>
+ Thank you to everyone who assisted us in making this release possible.
+ If you would like to contribute to ISC to assist us in continuing to make
+ quality open source software, please visit our donations page at
+ <a class="ulink" href="http://www.isc.org/supportisc" target="_top">http://www.isc.org/supportisc</a>.
+ </p>
+ </div>
+</div></body></html>
diff --git a/contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.pdf b/contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.pdf
new file mode 100644
index 0000000..60fa9fa
--- /dev/null
+++ b/contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.pdf
Binary files differ
diff --git a/contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.txt b/contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.txt
new file mode 100644
index 0000000..028c16d
--- /dev/null
+++ b/contrib/bind9/RELEASE-NOTES-BIND-9.6-ESV.txt
@@ -0,0 +1,133 @@
+ __________________________________________________________________
+
+Introduction
+
+ BIND 9.6-ESV-R3 is a maintenance release for BIND 9.6-ESV.
+
+ This document summarizes changes from BIND 9.6-ESV-R1 to BIND
+ 9.6-ESV-R3. Please see the CHANGES file in the source code release for
+ a complete list of all changes.
+
+Download
+
+ The latest release of BIND 9 software can always be found on our web
+ site at http://www.isc.org/software/bind. There you will find
+ additional information about each release, source code, and some
+ pre-compiled versions for certain operating systems.
+
+Support
+
+ Product support information is available on
+ http://www.isc.org/services/support for paid support options. Free
+ support is provided by our user community via a mailing list.
+ Information on all public email lists is available at
+ https://lists.isc.org/mailman/listinfo.
+
+New Features
+
+9.6-ESV-R2
+
+ None.
+
+9.6-ESV-R3
+
+ None.
+
+Feature Changes
+
+9.6-ESV-R2
+
+ None.
+
+9.6-ESV-R3
+
+ None.
+
+Security Fixes
+
+9.6-ESV-R2
+
+ None.
+
+9.6-ESV-R3
+
+ * Adding a NO DATA signed negative response to cache failed to clear
+ any matching RRSIG records already in cache. A subsequent lookup of
+ the cached NO DATA entry could crash named (INSIST) when the
+ unexpected RRSIG was also returned with the NO DATA cache entry.
+ [RT #22288] [CVE-2010-3613] [VU#706148]
+ * BIND, acting as a DNSSEC validator, was determining if the NS RRset
+ is insecure based on a value that could mean either that the RRset
+ is actually insecure or that there wasn't a matching key for the
+ RRSIG in the DNSKEY RRset when resuming from validating the DNSKEY
+ RRset. This can happen when in the middle of a DNSKEY algorithm
+ rollover, when two different algorithms were used to sign a zone
+ but only the new set of keys are in the zone DNSKEY RRset. [RT
+ #22309] [CVE-2010-3614] [VU#837744]
+
+Bug Fixes
+
+9.6-ESV-R2
+
+ * Check that named successfully skips NSEC3 records that fail to
+ match the NSEC3PARAM record currently in use. [RT #21868]
+ * Worked around a race condition in the cache database memory
+ handling. Without this fix a DNS cache DB or ADB could incorrectly
+ stay in an over memory state, effectively refusing further caching,
+ which subsequently made a BIND 9 caching server unworkable. [RT
+ #21818]
+ * BIND did not properly handle non-cacheable negative responses from
+ insecure zones. This caused several non-protocol-compliant zones to
+ become unresolvable. BIND is now more accepting of responses it
+ receives from less strict servers. [RT #21555]
+ * The resolver could attempt to destroy a fetch context too soon,
+ resulting in a crash. [RT #19878]
+ * The placeholder negative caching element was not properly
+ constructed triggering a crash (INSIST) in dns_ncache_towire(). [RT
+ #21346]
+ * Handle the introduction of new trusted-keys and DS, DLV RRsets
+ better. [RT #21097]
+ * Fix arguments to dns_keytable_findnextkeynode() call. [RT #20877]
+
+9.6-ESV-R3
+
+ * Microsoft changed the behavior of sockets between NT/XP based
+ stacks vs Vista/windows7 stacks. Server 2003/2008 have the older
+ behavior, 2008r2 has the new behavior. With the change, different
+ error results are possible, so ISC adapted BIND to handle the new
+ error results. This resolves an issue where sockets would shut down
+ on Windows servers causing named to stop responding to queries. [RT
+ #21906]
+ * Windows has non-POSIX compliant behavior in its rename() and
+ unlink() calls. This caused journal compaction to fail on Windows
+ BIND servers with the log error: "dns_journal_compact failed:
+ failure". [RT #22434]
+ * 'host -D' now turns on debugging messages earlier. [RT #22361]
+ * isc_print_vsnprintf() failed to check if there was space available
+ in the buffer when adding a left justified character with a non
+ zero width, (e.g. "%-1c"). [RT #22270]
+ * view->queryacl was being overloaded. Seperate the usage into
+ view->queryacl, view->cacheacl and view->queryonacl. [RT #22114]
+ * win32: add more dependencies to BINDBuild.dsw. [RT #22062]
+ * win32: named-checkzone and named-checkconf failed to initialise
+ winsock. [RT #21932]
+ * named failed to generate a correct signed response in a optout,
+ delegation only zone with no secure delegations. [RT #22007]
+
+Known issues in this release
+
+ * "make test" will fail on OSX and possibly other operating systems.
+ The failure occurs in a new test to check for allow-query ACLs. The
+ failure is caused because the source address is not specified on
+ the dig commands issued in the test.
+ If running "make test" is part of your usual acceptance process,
+ please edit the file bin/tests/system/allow_query/test.sh and add
+ -b 10.53.0.2
+ to the DIGOPTS line.
+
+Thank You
+
+ Thank you to everyone who assisted us in making this release possible.
+ If you would like to contribute to ISC to assist us in continuing to
+ make quality open source software, please visit our donations page at
+ http://www.isc.org/supportisc.
diff --git a/contrib/bind9/bin/check/check-tool.c b/contrib/bind9/bin/check/check-tool.c
index e0a7208..396f105 100644
--- a/contrib/bind9/bin/check/check-tool.c
+++ b/contrib/bind9/bin/check/check-tool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check-tool.c,v 1.35.36.3 2009/01/20 02:03:18 marka Exp $ */
+/* $Id: check-tool.c,v 1.35.36.3.24.2 2010/09/07 23:46:25 tbox Exp $ */
/*! \file */
@@ -23,6 +23,10 @@
#include <stdio.h>
+#ifdef _WIN32
+#include <Winsock2.h>
+#endif
+
#include "check-tool.h"
#include <isc/buffer.h>
#include <isc/log.h>
@@ -662,3 +666,26 @@ dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
return (result);
}
+
+#ifdef _WIN32
+void
+InitSockets(void) {
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int err;
+
+ wVersionRequested = MAKEWORD(2, 0);
+
+ err = WSAStartup( wVersionRequested, &wsaData );
+ if (err != 0) {
+ fprintf(stderr, "WSAStartup() failed: %d\n", err);
+ exit(1);
+ }
+}
+
+void
+DestroySockets(void) {
+ WSACleanup();
+}
+#endif
+
diff --git a/contrib/bind9/bin/check/check-tool.h b/contrib/bind9/bin/check/check-tool.h
index b0ba7e0..0128926 100644
--- a/contrib/bind9/bin/check/check-tool.h
+++ b/contrib/bind9/bin/check/check-tool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check-tool.h,v 1.14 2007/06/18 23:47:17 tbox Exp $ */
+/* $Id: check-tool.h,v 1.14.628.2 2010/09/07 23:46:26 tbox Exp $ */
#ifndef CHECK_TOOL_H
#define CHECK_TOOL_H
@@ -43,6 +43,11 @@ isc_result_t
dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
dns_masterformat_t fileformat, const dns_master_style_t *style);
+#ifdef _WIN32
+void InitSockets(void);
+void DestroySockets(void);
+#endif
+
extern int debug;
extern isc_boolean_t nomerge;
extern isc_boolean_t docheckmx;
diff --git a/contrib/bind9/bin/check/named-checkconf.c b/contrib/bind9/bin/check/named-checkconf.c
index eba0d93..7ed1043 100644
--- a/contrib/bind9/bin/check/named-checkconf.c
+++ b/contrib/bind9/bin/check/named-checkconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: named-checkconf.c,v 1.46.222.2 2009/02/16 23:47:15 tbox Exp $ */
+/* $Id: named-checkconf.c,v 1.46.222.2.24.2 2010/09/07 23:46:26 tbox Exp $ */
/*! \file */
@@ -453,6 +453,10 @@ main(int argc, char **argv) {
if (conffile == NULL || conffile[0] == '\0')
conffile = NAMED_CONFFILE;
+#ifdef _WIN32
+ InitSockets();
+#endif
+
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
RUNTIME_CHECK(setup_logging(mctx, stdout, &logc) == ISC_R_SUCCESS);
@@ -494,5 +498,9 @@ main(int argc, char **argv) {
isc_mem_destroy(&mctx);
+#ifdef _WIN32
+ DestroySockets();
+#endif
+
return (exit_status);
}
diff --git a/contrib/bind9/bin/check/named-checkzone.c b/contrib/bind9/bin/check/named-checkzone.c
index 0b49b51..1fa015a 100644
--- a/contrib/bind9/bin/check/named-checkzone.c
+++ b/contrib/bind9/bin/check/named-checkzone.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: named-checkzone.c,v 1.51.34.4 2009/11/10 20:01:41 each Exp $ */
+/* $Id: named-checkzone.c,v 1.51.34.4.10.2 2010/09/07 23:46:26 tbox Exp $ */
/*! \file */
@@ -419,6 +419,10 @@ main(int argc, char **argv) {
if (isc_commandline_index + 2 != argc)
usage();
+#ifdef _WIN32
+ InitSockets();
+#endif
+
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
if (!quiet)
RUNTIME_CHECK(setup_logging(mctx, errout, &lctx)
@@ -453,5 +457,8 @@ main(int argc, char **argv) {
isc_hash_destroy();
isc_entropy_detach(&ectx);
isc_mem_destroy(&mctx);
+#ifdef _WIN32
+ DestroySockets();
+#endif
return ((result == ISC_R_SUCCESS) ? 0 : 1);
}
diff --git a/contrib/bind9/bin/dig/host.c b/contrib/bind9/bin/dig/host.c
index 8cd5b3d..1a7d174 100644
--- a/contrib/bind9/bin/dig/host.c
+++ b/contrib/bind9/bin/dig/host.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: host.c,v 1.116.216.3 2009/09/08 23:28:20 marka Exp $ */
+/* $Id: host.c,v 1.116.216.3.10.2 2010/10/19 23:46:25 tbox Exp $ */
/*! \file */
@@ -625,7 +625,9 @@ pre_parse_args(int argc, char **argv) {
case 'v': break;
case 'w': break;
case 'C': break;
- case 'D': break;
+ case 'D':
+ debugging = ISC_TRUE;
+ break;
case 'N': break;
case 'R': break;
case 'T': break;
@@ -792,7 +794,7 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) {
ndots = atoi(isc_commandline_argument);
break;
case 'D':
- debugging = ISC_TRUE;
+ /* Handled by pre_parse_args(). */
break;
case '4':
if (have_ipv4) {
diff --git a/contrib/bind9/bin/named/client.c b/contrib/bind9/bin/named/client.c
index ae5386c..a0e034a 100644
--- a/contrib/bind9/bin/named/client.c
+++ b/contrib/bind9/bin/named/client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: client.c,v 1.259.12.3 2009/01/29 22:40:33 jinmei Exp $ */
+/* $Id: client.c,v 1.259.12.3.24.2 2010/09/29 23:46:31 tbox Exp $ */
#include <config.h>
@@ -1859,13 +1859,13 @@ client_request(isc_task_t *task, isc_event_t *event) {
client->view->recursionacl,
ISC_TRUE) == ISC_R_SUCCESS &&
ns_client_checkaclsilent(client, NULL,
- client->view->queryacl,
+ client->view->cacheacl,
ISC_TRUE) == ISC_R_SUCCESS &&
ns_client_checkaclsilent(client, &client->interface->addr,
client->view->recursiononacl,
ISC_TRUE) == ISC_R_SUCCESS &&
ns_client_checkaclsilent(client, &client->interface->addr,
- client->view->queryonacl,
+ client->view->cacheonacl,
ISC_TRUE) == ISC_R_SUCCESS)
ra = ISC_TRUE;
diff --git a/contrib/bind9/bin/named/include/named/query.h b/contrib/bind9/bin/named/include/named/query.h
index 500b577..3f019a3 100644
--- a/contrib/bind9/bin/named/include/named/query.h
+++ b/contrib/bind9/bin/named/include/named/query.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.h,v 1.40 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: query.h,v 1.40.626.2 2010/09/29 23:46:31 tbox Exp $ */
#ifndef NAMED_QUERY_H
#define NAMED_QUERY_H 1
@@ -71,6 +71,8 @@ struct ns_query {
#define NS_QUERYATTR_SECURE 0x0200
#define NS_QUERYATTR_NOAUTHORITY 0x0400
#define NS_QUERYATTR_NOADDITIONAL 0x0800
+#define NS_QUERYATTR_CACHEACLOKVALID 0x1000
+#define NS_QUERYATTR_CACHEACLOK 0x2000
isc_result_t
ns_query_init(ns_client_t *client);
diff --git a/contrib/bind9/bin/named/query.c b/contrib/bind9/bin/named/query.c
index 73ed1a6..0ba708b 100644
--- a/contrib/bind9/bin/named/query.c
+++ b/contrib/bind9/bin/named/query.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.c,v 1.313.20.16.10.2 2010/06/26 23:46:14 tbox Exp $ */
+/* $Id: query.c,v 1.313.20.16.10.3 2010/09/29 00:03:32 marka Exp $ */
/*! \file */
@@ -820,17 +820,15 @@ query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
return (DNS_R_REFUSED);
dns_db_attach(client->view->cachedb, &db);
- if ((client->query.attributes &
- NS_QUERYATTR_QUERYOKVALID) != 0) {
+ if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) != 0) {
/*
- * We've evaluated the view's queryacl already. If
- * NS_QUERYATTR_QUERYOK is set, then the client is
+ * We've evaluated the view's cacheacl already. If
+ * NS_QUERYATTR_CACHEACLOK is set, then the client is
* allowed to make queries, otherwise the query should
* be refused.
*/
check_acl = ISC_FALSE;
- if ((client->query.attributes &
- NS_QUERYATTR_QUERYOK) == 0)
+ if ((client->query.attributes & NS_QUERYATTR_CACHEACLOK) == 0)
goto refuse;
} else {
/*
@@ -844,16 +842,15 @@ query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")];
result = ns_client_checkaclsilent(client, NULL,
- client->view->queryacl,
+ client->view->cacheacl,
ISC_TRUE);
if (result == ISC_R_SUCCESS) {
/*
- * We were allowed by the default
- * "allow-query" ACL. Remember this so we
- * don't have to check again.
+ * We were allowed by the "allow-query-cache" ACL.
+ * Remember this so we don't have to check again.
*/
client->query.attributes |=
- NS_QUERYATTR_QUERYOK;
+ NS_QUERYATTR_CACHEACLOK;
if (log && isc_log_wouldlog(ns_g_lctx,
ISC_LOG_DEBUG(3)))
{
@@ -876,9 +873,9 @@ query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
}
/*
* We've now evaluated the view's query ACL, and
- * the NS_QUERYATTR_QUERYOK attribute is now valid.
+ * the NS_QUERYATTR_CACHEACLOKVALID attribute is now valid.
*/
- client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
+ client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID;
if (result != ISC_R_SUCCESS)
goto refuse;
diff --git a/contrib/bind9/bin/named/server.c b/contrib/bind9/bin/named/server.c
index 8f67786..5fbe043 100644
--- a/contrib/bind9/bin/named/server.c
+++ b/contrib/bind9/bin/named/server.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.c,v 1.520.12.11.10.1 2010/03/03 22:06:36 marka Exp $ */
+/* $Id: server.c,v 1.520.12.11.10.4 2010/11/16 22:42:03 marka Exp $ */
/*! \file */
@@ -1132,6 +1132,14 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_acache_setcachesize(view->acache, max_acache_size);
}
+ CHECK(configure_view_acl(vconfig, config, "allow-query", actx,
+ ns_g_mctx, &view->queryacl));
+
+ if (view->queryacl == NULL) {
+ CHECK(configure_view_acl(NULL, ns_g_config, "allow-query", actx,
+ ns_g_mctx, &view->queryacl));
+ }
+
/*
* Configure the zones.
*/
@@ -1606,13 +1614,13 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* configured in named.conf.
*/
CHECK(configure_view_acl(vconfig, config, "allow-query-cache",
- actx, ns_g_mctx, &view->queryacl));
+ actx, ns_g_mctx, &view->cacheacl));
CHECK(configure_view_acl(vconfig, config, "allow-query-cache-on",
- actx, ns_g_mctx, &view->queryonacl));
- if (view->queryonacl == NULL)
+ actx, ns_g_mctx, &view->cacheonacl));
+ if (view->cacheonacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
"allow-query-cache-on", actx,
- ns_g_mctx, &view->queryonacl));
+ ns_g_mctx, &view->cacheonacl));
if (strcmp(view->name, "_bind") != 0) {
CHECK(configure_view_acl(vconfig, config, "allow-recursion",
actx, ns_g_mctx,
@@ -1628,14 +1636,14 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* "allow-recursion" inherits from "allow-query-cache" if set,
* otherwise from "allow-query" if set.
*/
- if (view->queryacl == NULL && view->recursionacl != NULL)
- dns_acl_attach(view->recursionacl, &view->queryacl);
- if (view->queryacl == NULL && view->recursion)
+ if (view->cacheacl == NULL && view->recursionacl != NULL)
+ dns_acl_attach(view->recursionacl, &view->cacheacl);
+ if (view->cacheacl == NULL && view->recursion)
CHECK(configure_view_acl(vconfig, config, "allow-query",
- actx, ns_g_mctx, &view->queryacl));
+ actx, ns_g_mctx, &view->cacheacl));
if (view->recursion &&
- view->recursionacl == NULL && view->queryacl != NULL)
- dns_acl_attach(view->queryacl, &view->recursionacl);
+ view->recursionacl == NULL && view->cacheacl != NULL)
+ dns_acl_attach(view->cacheacl, &view->recursionacl);
/*
* Set default "allow-recursion", "allow-recursion-on" and
@@ -1651,16 +1659,13 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
"allow-recursion-on",
actx, ns_g_mctx,
&view->recursiononacl));
- if (view->queryacl == NULL) {
+ if (view->cacheacl == NULL) {
if (view->recursion)
CHECK(configure_view_acl(NULL, ns_g_config,
"allow-query-cache", actx,
- ns_g_mctx, &view->queryacl));
- else {
- if (view->queryacl != NULL)
- dns_acl_detach(&view->queryacl);
- CHECK(dns_acl_none(ns_g_mctx, &view->queryacl));
- }
+ ns_g_mctx, &view->cacheacl));
+ else
+ CHECK(dns_acl_none(ns_g_mctx, &view->cacheacl));
}
/*
diff --git a/contrib/bind9/lib/dns/api b/contrib/bind9/lib/dns/api
index b1adf784..82e6786 100644
--- a/contrib/bind9/lib/dns/api
+++ b/contrib/bind9/lib/dns/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 57
+LIBINTERFACE = 58
LIBREVISION = 0
-LIBAGE = 2
+LIBAGE = 0
diff --git a/contrib/bind9/lib/dns/include/dns/view.h b/contrib/bind9/lib/dns/include/dns/view.h
index 5b53c16..0b4dedc 100644
--- a/contrib/bind9/lib/dns/include/dns/view.h
+++ b/contrib/bind9/lib/dns/include/dns/view.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.h,v 1.111.88.4 2009/01/29 22:40:35 jinmei Exp $ */
+/* $Id: view.h,v 1.111.88.4.24.2 2010/09/29 23:46:31 tbox Exp $ */
#ifndef DNS_VIEW_H
#define DNS_VIEW_H 1
@@ -118,6 +118,8 @@ struct dns_view {
isc_boolean_t enablevalidation;
isc_boolean_t acceptexpired;
dns_transfer_format_t transfer_format;
+ dns_acl_t * cacheacl;
+ dns_acl_t * cacheonacl;
dns_acl_t * queryacl;
dns_acl_t * queryonacl;
dns_acl_t * recursionacl;
diff --git a/contrib/bind9/lib/dns/journal.c b/contrib/bind9/lib/dns/journal.c
index 638e647..933576f 100644
--- a/contrib/bind9/lib/dns/journal.c
+++ b/contrib/bind9/lib/dns/journal.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: journal.c,v 1.103.48.6 2009/11/04 23:47:25 tbox Exp $ */
+/* $Id: journal.c,v 1.103.48.6.10.2 2010/11/17 23:46:16 tbox Exp $ */
#include <config.h>
@@ -2173,6 +2173,12 @@ dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
indexend = new->header.end.offset;
}
+
+ /*
+ * Close both journals before trying to rename files (this is
+ * necessary on WIN32).
+ */
+ dns_journal_destroy(&j);
dns_journal_destroy(&new);
/*
@@ -2180,12 +2186,14 @@ dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
* Any IXFR outs will just continue and the old journal will be
* removed on final close.
*
- * With MSDOS / NTFS we need to do a two stage rename triggered
- * bu EEXISTS. Hopefully all IXFR's that were active at the last
- * rename are now complete.
+ * With MSDOS / NTFS we need to do a two stage rename, triggered
+ * by EEXIST. (If any IXFR's are running in other threads, however,
+ * this will fail, and the journal will not be compacted. But
+ * if so, hopefully they'll be finished by the next time we
+ * compact.)
*/
if (rename(newname, filename) == -1) {
- if (errno == EACCES && !is_backup) {
+ if (errno == EEXIST && !is_backup) {
result = isc_file_remove(backup);
if (result != ISC_R_SUCCESS &&
result != ISC_R_FILENOTFOUND)
@@ -2202,7 +2210,6 @@ dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
}
}
- dns_journal_destroy(&j);
result = ISC_R_SUCCESS;
failure:
diff --git a/contrib/bind9/lib/dns/rbtdb.c b/contrib/bind9/lib/dns/rbtdb.c
index 538c228..f61b83b 100644
--- a/contrib/bind9/lib/dns/rbtdb.c
+++ b/contrib/bind9/lib/dns/rbtdb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.270.12.16.10.3 2010/08/13 07:25:21 marka Exp $ */
+/* $Id: rbtdb.c,v 1.270.12.16.10.6 2010/11/16 07:46:23 marka Exp $ */
/*! \file */
@@ -5421,14 +5421,14 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
dns_rdataset_t *addedrdataset, isc_stdtime_t now)
{
rbtdb_changed_t *changed = NULL;
- rdatasetheader_t *topheader, *topheader_prev, *header;
+ rdatasetheader_t *topheader, *topheader_prev, *header, *sigheader;
unsigned char *merged;
isc_result_t result;
isc_boolean_t header_nx;
isc_boolean_t newheader_nx;
isc_boolean_t merge;
dns_rdatatype_t rdtype, covers;
- rbtdb_rdatatype_t negtype;
+ rbtdb_rdatatype_t negtype, sigtype;
dns_trust_t trust;
int idx;
@@ -5466,7 +5466,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
newheader_nx = NONEXISTENT(newheader) ? ISC_TRUE : ISC_FALSE;
topheader_prev = NULL;
-
+ sigheader = NULL;
negtype = 0;
if (rbtversion == NULL && !newheader_nx) {
rdtype = RBTDB_RDATATYPE_BASE(newheader->type);
@@ -5475,26 +5475,34 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
* We're adding a negative cache entry.
*/
covers = RBTDB_RDATATYPE_EXT(newheader->type);
- if (covers == dns_rdatatype_any) {
+ sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig,
+ covers);
+ for (topheader = rbtnode->data;
+ topheader != NULL;
+ topheader = topheader->next) {
/*
- * We're adding an negative cache entry
+ * If we're adding an negative cache entry
* which covers all types (NXDOMAIN,
* NODATA(QTYPE=ANY)).
*
* We make all other data stale so that the
* only rdataset that can be found at this
* node is the negative cache entry.
+ *
+ * Otherwise look for any RRSIGs of the
+ * given type so they can be marked stale
+ * later.
*/
- for (topheader = rbtnode->data;
- topheader != NULL;
- topheader = topheader->next) {
+ if (covers == dns_rdatatype_any) {
set_ttl(rbtdb, topheader, 0);
topheader->attributes |=
RDATASET_ATTR_STALE;
- }
- rbtnode->dirty = 1;
- goto find_header;
+ rbtnode->dirty = 1;
+ } else if (topheader->type == sigtype)
+ sigheader = topheader;
}
+ if (covers == dns_rdatatype_any)
+ goto find_header;
negtype = RBTDB_RDATATYPE_VALUE(covers, 0);
} else {
/*
@@ -5732,6 +5740,11 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
if (rbtversion == NULL) {
set_ttl(rbtdb, header, 0);
header->attributes |= RDATASET_ATTR_STALE;
+ if (sigheader != NULL) {
+ set_ttl(rbtdb, sigheader, 0);
+ sigheader->attributes |=
+ RDATASET_ATTR_STALE;
+ }
}
idx = newheader->node->locknum;
if (IS_CACHE(rbtdb)) {
@@ -7071,6 +7084,8 @@ dns_rbtdb_create
* change.
*/
if (!IS_CACHE(rbtdb)) {
+ dns_rbtnode_t *nsec3node;
+
rbtdb->origin_node = NULL;
result = dns_rbt_addnode(rbtdb->tree, &rbtdb->common.origin,
&rbtdb->origin_node);
@@ -7094,6 +7109,32 @@ dns_rbtdb_create
dns_name_hash(&name, ISC_TRUE) %
rbtdb->node_lock_count;
#endif
+ /*
+ * Add an apex node to the NSEC3 tree so that NSEC3 searches
+ * return partial matches when there is only a single NSEC3
+ * record in the tree.
+ */
+ nsec3node = NULL;
+ result = dns_rbt_addnode(rbtdb->nsec3, &rbtdb->common.origin,
+ &nsec3node);
+ if (result != ISC_R_SUCCESS) {
+ INSIST(result != ISC_R_EXISTS);
+ free_rbtdb(rbtdb, ISC_FALSE, NULL);
+ return (result);
+ }
+ nsec3node->nsec3 = 1;
+ /*
+ * We need to give the nsec3 origin node the right locknum.
+ */
+ dns_name_init(&name, NULL);
+ dns_rbt_namefromnode(nsec3node, &name);
+#ifdef DNS_RBT_USEHASH
+ nsec3node->locknum = nsec3node->hashval %
+ rbtdb->node_lock_count;
+#else
+ nsec3node->locknum = dns_name_hash(&name, ISC_TRUE) %
+ rbtdb->node_lock_count;
+#endif
}
/*
diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c
index 90c18bc..fc6f454 100644
--- a/contrib/bind9/lib/dns/validator.c
+++ b/contrib/bind9/lib/dns/validator.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.164.12.11.10.6 2010/09/03 02:55:18 marka Exp $ */
+/* $Id: validator.c,v 1.164.12.11.10.7 2010/11/16 01:48:32 marka Exp $ */
#include <config.h>
@@ -393,6 +393,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
+ isc_result_t saved_result;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
@@ -429,6 +430,17 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
val->keyset = &val->frdataset;
}
result = validate(val, ISC_TRUE);
+ if (result == DNS_R_NOVALIDSIG &&
+ (val->attributes & VALATTR_TRIEDVERIFY) == 0)
+ {
+ saved_result = result;
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "falling back to insecurity proof");
+ val->attributes |= VALATTR_INSECURITY;
+ result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
+ if (result == DNS_R_NOTINSECURE)
+ result = saved_result;
+ }
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
@@ -619,6 +631,7 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
+ isc_result_t saved_result;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
@@ -645,6 +658,17 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
if (val->frdataset.trust >= dns_trust_secure)
(void) get_dst_key(val, val->siginfo, &val->frdataset);
result = validate(val, ISC_TRUE);
+ if (result == DNS_R_NOVALIDSIG &&
+ (val->attributes & VALATTR_TRIEDVERIFY) == 0)
+ {
+ saved_result = result;
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "falling back to insecurity proof");
+ val->attributes |= VALATTR_INSECURITY;
+ result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
+ if (result == DNS_R_NOTINSECURE)
+ result = saved_result;
+ }
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
@@ -1875,9 +1899,11 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
* was known and "sufficiently good".
*/
if (!dns_resolver_algorithm_supported(val->view->resolver,
- event->name,
- val->siginfo->algorithm))
+ event->name,
+ val->siginfo->algorithm)) {
+ resume = ISC_FALSE;
continue;
+ }
if (!resume) {
result = get_key(val, val->siginfo);
@@ -1888,16 +1914,12 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
}
/*
- * The key is insecure, so mark the data as insecure also.
+ * There isn't a secure DNSKEY for this signature so move
+ * onto the next RRSIG.
*/
if (val->key == NULL) {
- if (val->mustbesecure) {
- validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
- return (DNS_R_MUSTBESECURE);
- }
- markanswer(val, "validate");
- return (ISC_R_SUCCESS);
+ resume = ISC_FALSE;
+ continue;
}
do {
@@ -3703,6 +3725,20 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
*/
result = DNS_R_NOVALIDNSEC;
goto out;
+ } else if (DNS_TRUST_PENDING(val->frdataset.trust) ||
+ DNS_TRUST_ANSWER(val->frdataset.trust)) {
+ /*
+ * If we have "trust == answer" then this namespace
+ * has switched from insecure to should be secure.
+ */
+ result = create_validator(val, tname,
+ dns_rdatatype_ds,
+ &val->frdataset,
+ NULL, dsvalidated,
+ "proveunsecure");
+ if (result != ISC_R_SUCCESS)
+ goto out;
+ return (DNS_R_WAIT);
} else if (val->frdataset.trust < dns_trust_secure) {
/*
* This shouldn't happen, since the negative
diff --git a/contrib/bind9/lib/dns/view.c b/contrib/bind9/lib/dns/view.c
index 3726eef..54f0d26 100644
--- a/contrib/bind9/lib/dns/view.c
+++ b/contrib/bind9/lib/dns/view.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.c,v 1.150.84.3.10.1 2010/03/03 22:06:39 marka Exp $ */
+/* $Id: view.c,v 1.150.84.3.10.2 2010/09/29 00:03:32 marka Exp $ */
/*! \file */
@@ -168,6 +168,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->acceptexpired = ISC_FALSE;
view->minimalresponses = ISC_FALSE;
view->transfer_format = dns_one_answer;
+ view->cacheacl = NULL;
+ view->cacheonacl = NULL;
view->queryacl = NULL;
view->queryonacl = NULL;
view->recursionacl = NULL;
@@ -294,6 +296,10 @@ destroy(dns_view_t *view) {
dns_acl_detach(&view->matchclients);
if (view->matchdestinations != NULL)
dns_acl_detach(&view->matchdestinations);
+ if (view->cacheacl != NULL)
+ dns_acl_detach(&view->cacheacl);
+ if (view->cacheonacl != NULL)
+ dns_acl_detach(&view->cacheonacl);
if (view->queryacl != NULL)
dns_acl_detach(&view->queryacl);
if (view->queryonacl != NULL)
diff --git a/contrib/bind9/lib/isc/api b/contrib/bind9/lib/isc/api
index 823f692..b765f45 100644
--- a/contrib/bind9/lib/isc/api
+++ b/contrib/bind9/lib/isc/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 53
-LIBREVISION = 0
+LIBREVISION = 1
LIBAGE = 3
diff --git a/contrib/bind9/lib/isc/print.c b/contrib/bind9/lib/isc/print.c
index b892e3a..6b98195 100644
--- a/contrib/bind9/lib/isc/print.c
+++ b/contrib/bind9/lib/isc/print.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: print.c,v 1.35 2008/02/18 23:46:59 tbox Exp $ */
+/* $Id: print.c,v 1.35.418.2 2010/10/18 23:46:34 tbox Exp $ */
/*! \file */
@@ -468,7 +468,7 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
if (width > 0) {
count += width;
width--;
- if (left) {
+ if (left && size > 1) {
*str++ = c;
size--;
}
diff --git a/contrib/bind9/release-notes.css b/contrib/bind9/release-notes.css
new file mode 100644
index 0000000..411eb8b
--- /dev/null
+++ b/contrib/bind9/release-notes.css
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: release-notes.css,v 1.1.4.3 2010/11/29 01:16:39 tbox Exp $ */
+
+body {
+ background-color: #ffffff;
+ color: #333333;
+ font-family: "Helvetica Neue", "ArialMT", "Verdana", "Arial", "Helvetica", sans-serif;
+ font-size: 14px;
+ line-height: 18px;
+ margin: 2em auto;
+ width: 700px;
+}
+
+.command {
+ font-family: "Courier New", "Courier", monospace;
+ font-weight: normal;
+}
+
+.note {
+ background-color: #ddeedd;
+ border: 1px solid #aaccaa;
+ margin: 1em 0 1em 0;
+ padding: 0.5em 1em 0.5em 1em;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+}
+
+.screen {
+ background-color: #ffffee;
+ border: 1px solid #ddddaa;
+ padding: 0.25em 1em 0.25em 1em;
+ margin: 1em 0 1em 0;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+}
+
+.section.title {
+ font-size: 150%;
+ font-weight: bold;
+}
+
+.section.section.title {
+ font-size: 130%;
+ font-weight: bold;
+}
diff --git a/contrib/bind9/version b/contrib/bind9/version
index a16a96f..d736ecf 100644
--- a/contrib/bind9/version
+++ b/contrib/bind9/version
@@ -1,4 +1,4 @@
-# $Id: version,v 1.43.12.8.4.3 2010/09/03 02:57:11 marka Exp $
+# $Id: version,v 1.43.12.8.4.4 2010/11/18 23:37:13 marka Exp $
#
# This file must follow /bin/sh rules. It is imported directly via
# configure.
@@ -7,4 +7,4 @@ MAJORVER=9
MINORVER=6
PATCHVER=
RELEASETYPE=-ESV
-RELEASEVER=-R2
+RELEASEVER=-R3
diff --git a/contrib/bsnmp/lib/asn1.c b/contrib/bsnmp/lib/asn1.c
index 16b523d..4d9704f 100644
--- a/contrib/bsnmp/lib/asn1.c
+++ b/contrib/bsnmp/lib/asn1.c
@@ -196,7 +196,7 @@ asn_put_temp_header(struct asn_buf *b, u_char type, u_char **ptr)
return (ret);
}
enum asn_err
-asn_commit_header(struct asn_buf *b, u_char *ptr)
+asn_commit_header(struct asn_buf *b, u_char *ptr, size_t *moved)
{
asn_len_t len;
u_int lenlen, shift;
@@ -215,6 +215,8 @@ asn_commit_header(struct asn_buf *b, u_char *ptr)
memmove(ptr + 1 + lenlen, ptr + TEMP_LEN, len);
b->asn_ptr -= shift;
b->asn_len += shift;
+ if (moved != NULL)
+ *moved = shift;
}
return (ASN_ERR_OK);
}
@@ -913,6 +915,20 @@ asn_skip(struct asn_buf *b, asn_len_t len)
}
/*
+ * Add a padding
+ */
+enum asn_err
+asn_pad(struct asn_buf *b, asn_len_t len)
+{
+ if (b->asn_len < len)
+ return (ASN_ERR_EOBUF);
+ b->asn_ptr += len;
+ b->asn_len -= len;
+
+ return (ASN_ERR_OK);
+}
+
+/*
* Compare two OIDs.
*
* o1 < o2 : -1
diff --git a/contrib/bsnmp/lib/asn1.h b/contrib/bsnmp/lib/asn1.h
index 5748b14..cf9a727 100644
--- a/contrib/bsnmp/lib/asn1.h
+++ b/contrib/bsnmp/lib/asn1.h
@@ -93,7 +93,7 @@ enum asn_err asn_get_header(struct asn_buf *, u_char *, asn_len_t *);
enum asn_err asn_put_header(struct asn_buf *, u_char, asn_len_t);
enum asn_err asn_put_temp_header(struct asn_buf *, u_char, u_char **);
-enum asn_err asn_commit_header(struct asn_buf *, u_char *);
+enum asn_err asn_commit_header(struct asn_buf *, u_char *, size_t *);
enum asn_err asn_get_integer_raw(struct asn_buf *, asn_len_t, int32_t *);
enum asn_err asn_get_integer(struct asn_buf *, int32_t *);
@@ -129,6 +129,7 @@ enum asn_err asn_get_timeticks(struct asn_buf *, uint32_t *);
enum asn_err asn_put_timeticks(struct asn_buf *, uint32_t);
enum asn_err asn_skip(struct asn_buf *, asn_len_t);
+enum asn_err asn_pad(struct asn_buf *, asn_len_t);
/*
* Utility functions for OIDs
diff --git a/contrib/bsnmp/lib/bsnmpclient.3 b/contrib/bsnmp/lib/bsnmpclient.3
index 870f546..5fe9a9a 100644
--- a/contrib/bsnmp/lib/bsnmpclient.3
+++ b/contrib/bsnmp/lib/bsnmpclient.3
@@ -31,7 +31,7 @@
.\"
.\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.12 2005/10/04 08:46:50 brandt_h Exp $
.\"
-.Dd October 4, 2005
+.Dd September 9, 2010
.Dt BSNMPCLIENT 3
.Os
.Sh NAME
@@ -52,7 +52,8 @@
.Nm snmp_table_cb_f ,
.Nm snmp_table_fetch ,
.Nm snmp_table_fetch_async ,
-.Nm snmp_dialog
+.Nm snmp_dialog ,
+.Nm snmp_discover_engine
.Nd "SNMP client library"
.Sh LIBRARY
Begemot SNMP library
@@ -102,44 +103,56 @@ Begemot SNMP library
.Fn snmp_table_fetch_async "const struct snmp_table *descr" "void *list" "snmp_table_cb_f callback" "void *uarg"
.Ft int
.Fn snmp_dialog "struct snmp_pdu *req" "struct snmp_pdu *resp"
+.Ft int
+.Fn snmp_discover_engine "void"
.Sh DESCRIPTION
The SNMP library contains routines to easily build SNMP client applications
-that use SNMP versions 1 or 2.
+that use SNMP versions 1, 2 or 3.
Most of the routines use a
.Vt struct snmp_client :
.Bd -literal -offset indent
struct snmp_client {
- enum snmp_version version;
- int trans; /* transport type to use */
+ enum snmp_version version;
+ int trans; /* which transport to use */
/* these two are read-only for the application */
- char *cport; /* port number as string */
- char *chost; /* host name or IP address as string */
+ char *cport; /* port number as string */
+ char *chost; /* host name or IP address as string */
+
+ char read_community[SNMP_COMMUNITY_MAXLEN + 1];
+ char write_community[SNMP_COMMUNITY_MAXLEN + 1];
+
+ /* SNMPv3 specific fields */
+ int32_t identifier;
+ int32_t security_model;
+ struct snmp_engine engine;
+ struct snmp_user user;
- char read_community[SNMP_COMMUNITY_MAXLEN + 1];
- char write_community[SNMP_COMMUNITY_MAXLEN + 1];
+ /* SNMPv3 Access control - VACM*/
+ uint32_t clen;
+ uint8_t cengine[SNMP_ENGINE_ID_SIZ];
+ char cname[SNMP_CONTEXT_NAME_SIZ];
- struct timeval timeout;
- u_int retries;
+ struct timeval timeout;
+ u_int retries;
- int dump_pdus;
+ int dump_pdus;
- size_t txbuflen;
- size_t rxbuflen;
+ size_t txbuflen;
+ size_t rxbuflen;
- int fd;
+ int fd;
- int32_t next_reqid;
- int32_t max_reqid;
- int32_t min_reqid;
+ int32_t next_reqid;
+ int32_t max_reqid;
+ int32_t min_reqid;
- char error[SNMP_STRERROR_LEN];
+ char error[SNMP_STRERROR_LEN];
- snmp_timeout_start_f timeout_start;
- snmp_timeout_stop_f timeout_stop;
+ snmp_timeout_start_f timeout_start;
+ snmp_timeout_stop_f timeout_stop;
- /* private */
- char local_path[sizeof(SNMP_LOCAL_PATH)];
+ char local_path[sizeof(SNMP_LOCAL_PATH)];
};
.Ed
.Pp
@@ -194,6 +207,23 @@ The default is
The community name to be used for SET requests.
The default is
.Sq private .
+.It Va identifier
+The message indentifier value to be used with SNMPv3 PDUs. Incremented with
+each transmitted PDU.
+.It Va security_model
+The security model to be used with SNMPv3 PDUs. Currently only User-Based
+Security model specified by RFC 3414 (value 3) is supported.
+.It Va engine
+The authorative SNMP engine parameters to be used with SNMPv3 PDUs.
+.It Va user
+The USM SNMP user credentials to be used with SNMPv3 PDUs.
+.It Va clen
+The length of the context engine id to be used with SNMPv3 PDUs.
+.It Va cengine
+The context engine id to be used with SNMPv3 PDUs. Default is empty.
+.It Va cname
+The context name to be used with SNMPv3 PDUs. Default is
+.Sq "" .
.It Va timeout
The maximum time to wait for responses to requests.
If the time elapses, the request is resent up to
@@ -617,6 +647,21 @@ returns -1.
If a response was received 0 is returned.
.Pp
The function
+.Fn snmp_discover_engine
+is used to discover the authorative snmpEngineId of a remote SNMPv3 agent.
+A request PDU with empty USM user name is sent and the client's engine
+parameters are set according to the snmpEngine parameters received in the
+response PDU.
+If the client is configured to use authentication and/or privacy and the
+snmpEngineBoots and/or snmpEngineTime in the response had zero values, an
+additional request (possibly encrypted) with the appropriate user credentials
+is sent to fetch the missing values.
+Note, that the function blocks until the discovery proccess is completed.
+If no response could be received after all timeouts and retries, or the
+response contained errors the function returns -1.
+If the discovery proccess was completed 0 is returned.
+.Pp
+The function
.Fn snmp_parse_server
is used to parse an SNMP server specification string and fill in the
fields of a
diff --git a/contrib/bsnmp/lib/bsnmplib.3 b/contrib/bsnmp/lib/bsnmplib.3
index dfbffc4..af36879 100644
--- a/contrib/bsnmp/lib/bsnmplib.3
+++ b/contrib/bsnmp/lib/bsnmplib.3
@@ -1,4 +1,10 @@
.\"
+.\" Copyright (c) 2010 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" Portions of this documentation were written by Shteryana Sotirova Shopova
+.\" under sponsorship from the FreeBSD Foundation.
+.\"
.\" Copyright (c) 2004-2005
.\" Hartmut Brandt.
.\" All rights reserved.
@@ -31,7 +37,7 @@
.\"
.\" $Begemot: bsnmp/lib/bsnmplib.3,v 1.9 2005/10/04 08:46:51 brandt_h Exp $
.\"
-.Dd October 4, 2005
+.Dd September 9, 2010
.Dt BSNMPLIB 3
.Os
.Sh NAME
@@ -39,9 +45,15 @@
.Nm snmp_value_parse ,
.Nm snmp_value_copy ,
.Nm snmp_pdu_free ,
-.Nm snmp_code snmp_pdu_decode ,
-.Nm snmp_code snmp_pdu_encode ,
+.Nm snmp_pdu_decode ,
+.Nm snmp_pdu_encode ,
+.Nm snmp_pdu_decode_header ,
+.Nm snmp_pdu_decode_scoped ,
+.Nm snmp_pdu_decode_secmode ,
.Nm snmp_pdu_dump ,
+.Nm snmp_passwd_to_keys ,
+.Nm snmp_get_local_keys ,
+.Nm snmp_calc_keychange ,
.Nm TRUTH_MK ,
.Nm TRUTH_GET ,
.Nm TRUTH_OK
@@ -64,8 +76,20 @@ Begemot SNMP library
.Fn snmp_pdu_decode "struct asn_buf *buf" "struct snmp_pdu *pdu" "int32_t *ip"
.Ft enum snmp_code
.Fn snmp_pdu_encode "struct snmp_pdu *pdu" "struct asn_buf *buf"
+.Ft enum snmp_code
+.Fn snmp_pdu_decode_header "struct snmp_pdu *pdu" "struct asn_buf *buf"
+.Ft enum snmp_code
+.Fn snmp_pdu_decode_scoped "struct asn_buf *buf" "struct snmp_pdu *pdu" "int32_t *ip"
+.Ft enum snmp_code
+.Fn snmp_pdu_decode_secmode "struct asn_buf *buf" "struct snmp_pdu *pdu"
.Ft void
.Fn snmp_pdu_dump "const struct snmp_pdu *pdu"
+.Ft enum snmp_code
+.Fn snmp_passwd_to_keys "struct snmp_user *user" "char *passwd"
+.Ft enum snmp_code
+.Fn snmp_get_local_keys "struct snmp_user *user" "uint8_t *eid" "uint32_t elen"
+.Ft enum snmp_code
+.Fn snmp_calc_keychange "struct snmp_user *user" "uint8_t *keychange"
.Ft int
.Fn TRUTH_MK "F"
.Ft int
@@ -73,8 +97,8 @@ Begemot SNMP library
.Ft int
.Fn TRUTH_OK "T"
.Sh DESCRIPTION
-The SNMP library contains routines to handle SNMP version 1 and 2 PDUs.
-There are two basic structures used throughout the library:
+The SNMP library contains routines to handle SNMP version 1, 2 and 3 PDUs.
+There are several basic structures used throughout the library:
.Bd -literal -offset indent
struct snmp_value {
struct asn_oid var;
@@ -134,34 +158,126 @@ is not zero,
.Fa v.octetstring.octets
points to a string allocated by
.Xr malloc 3 .
+.Pp
+.Bd -literal -offset indent
+#define SNMP_ENGINE_ID_SIZ 32
+
+struct snmp_engine {
+ uint8_t engine_id[SNMP_ENGINE_ID_SIZ];
+ uint32_t engine_len;
+ int32_t engine_boots;
+ int32_t engine_time;
+ int32_t max_msg_size;
+};
+.Ed
+.Pp
+This structure represents an SNMP engine as specified by the SNMP Management
+Architecture described in RFC 3411.
+.Pp
+.Bd -literal -offset indent
+#define SNMP_USM_NAME_SIZ (32 + 1)
+#define SNMP_AUTH_KEY_SIZ 40
+#define SNMP_PRIV_KEY_SIZ 32
+
+struct snmp_user {
+ char sec_name[SNMP_USM_NAME_SIZ];
+ enum snmp_authentication auth_proto;
+ enum snmp_privacy priv_proto;
+ uint8_t auth_key[SNMP_AUTH_KEY_SIZ];
+ uint8_t priv_key[SNMP_PRIV_KEY_SIZ];
+};
+.Ed
+.Pp
+This structure represents an SNMPv3 user as specified by the User-based
+Security Model (USM) described in RFC 3414. The field
+.Fa sec_name
+is a human readable string containing the security user name.
+.Fa auth_proto
+contains the id of the authentication protocol in use by the user and may be one
+of:
+.Bd -literal -offset indent
+enum snmp_authentication {
+ SNMP_AUTH_NOAUTH = 0,
+ SNMP_AUTH_HMAC_MD5,
+ SNMP_AUTH_HMAC_SHA
+};
+.Ed
+.Fa priv_proto
+contains the id of the privacy protocol in use by the user and may be one
+of:
+.Bd -literal -offset indent
+enum snmp_privacy {
+ SNMP_PRIV_NOPRIV = 0,
+ SNMP_PRIV_DES = 1,
+ SNMP_PRIV_AES
+};
+.Ed
+.Fa auth_key
+and
+.Fa priv_key
+contain the authentication and privacy keys for the user.
+.Pp
.Bd -literal -offset indent
-#define SNMP_COMMUNITY_MAXLEN 128
-#define SNMP_MAX_BINDINGS 100
+#define SNMP_COMMUNITY_MAXLEN 128
+#define SNMP_MAX_BINDINGS 100
+#define SNMP_CONTEXT_NAME_SIZ (32 + 1)
+#define SNMP_TIME_WINDOW 150
+
+#define SNMP_USM_AUTH_SIZE 12
+#define SNMP_USM_PRIV_SIZE 8
+
+#define SNMP_MSG_AUTH_FLAG 0x1
+#define SNMP_MSG_PRIV_FLAG 0x2
+#define SNMP_MSG_REPORT_FLAG 0x4
+
+#define SNMP_SECMODEL_USM 3
struct snmp_pdu {
- char community[SNMP_COMMUNITY_MAXLEN + 1];
- enum snmp_version version;
- u_int type;
+ char community[SNMP_COMMUNITY_MAXLEN + 1];
+ enum snmp_version version;
+ u_int type;
+
+ /* SNMPv3 PDU header fields */
+ int32_t identifier;
+ uint8_t flags;
+ int32_t security_model;
+ struct snmp_engine engine;
+
+ /* Associated USM user parameters */
+ struct snmp_user user;
+ uint8_t msg_digest[SNMP_USM_AUTH_SIZE];
+ uint8_t msg_salt[SNMP_USM_PRIV_SIZE];
+
+ /* View-based Access Model */
+ uint32_t context_engine_len;
+ uint8_t context_engine[SNMP_ENGINE_ID_SIZ];
+ char context_name[SNMP_CONTEXT_NAME_SIZ];
/* trap only */
- struct asn_oid enterprise;
- u_char agent_addr[4];
- int32_t generic_trap;
- int32_t specific_trap;
- u_int32_t time_stamp;
+ struct asn_oid enterprise;
+ u_char agent_addr[4];
+ int32_t generic_trap;
+ int32_t specific_trap;
+ uint32_t time_stamp;
/* others */
- int32_t request_id;
- int32_t error_status;
- int32_t error_index;
+ int32_t request_id;
+ int32_t error_status;
+ int32_t error_index;
/* fixes for encoding */
- u_char *outer_ptr;
- u_char *pdu_ptr;
- u_char *vars_ptr;
+ size_t outer_len;
+ size_t scoped_len;
+ u_char *outer_ptr;
+ u_char *digest_ptr;
+ u_char *encrypted_ptr;
+ u_char *scoped_ptr;
+ u_char *pdu_ptr;
+ u_char *vars_ptr;
+
- struct snmp_value bindings[SNMP_MAX_BINDINGS];
- u_int nbindings;
+ struct snmp_value bindings[SNMP_MAX_BINDINGS];
+ u_int nbindings;
};
.Ed
This structure contains a decoded SNMP PDU.
@@ -172,11 +288,15 @@ enum snmp_version {
SNMP_Verr = 0,
SNMP_V1 = 1,
SNMP_V2c,
+ SNMP_V3
};
.Ed
and
.Fa type
is the type of the PDU.
+.Fa security_model
+is the security model used for SNMPv3 PDUs. The only supported
+value currently is 3 (User-based Security Model).
.Pp
The function
.Fn snmp_value_free
@@ -223,15 +343,60 @@ The function
.Fn snmp_pdu_encode
encodes the PDU
.Fa pdu
-into the an octetstring in buffer
+into the an octetstring in buffer, and if authentication and privacy are used,
+calculates a message digest and encrypts the PDU data in the buffer
+.Fa buf .
+.Pp
+The function
+.Fn snmp_pdu_decode_header
+decodes the header of the PDU pointed to by
+.Fa buf .
+The uncoded PDU contents remain in the buffer.
+.Pp
+The function
+.Fn snmp_pdu_decode_scoped
+decodes the scoped PDU pointed to by
.Fa buf .
.Pp
The function
+.Fn snmp_pdu_decode_secmode
+verifies the authentication parameter contained in the PDU (if present) and
+if the PDU is encrypted, decrypts the PDU contents pointed to by
+.Fa buf .
+If successfull, a plain text scoped PDU is stored in the buffer.
+.Pp
+The function
.Fn snmp_pdu_dump
dumps the PDU in a human readable form by calling
.Fn snmp_printf .
.Pp
The function
+.Fn snmp_passwd_to_keys
+calculates a binary private authentication key corresponding to a plain text human
+readable password string. The calculated key is placed in the
+.Fa auth_key
+field of the
+.Fa user .
+.Pp
+The function
+.Fn snmp_get_local_keys
+calculates a localazied authentication and privacy keys for a specified SNMPv3
+engine. The calculateds keys are placed in the
+.Fa auth_key
+and
+.Fa priv_key
+fields of the
+.Fa user .
+.Pp
+The function
+.Fn snmp_calc_keychange
+calculates a binary key change octet string based on the contents of an old and
+a new binary localized key. The rezult is placed in the buffer pointer to by
+.Fa keychange
+and may be used by an SNMPv3 user who wishes to change his/her password
+or localized key.
+.Pp
+The function
.Fn TRUTH_MK
takes a C truth value (zero or non-zero) and makes an SNMP truth value (2 or 1).
The function
@@ -281,6 +446,13 @@ A variable binding value was out of the allowed range.
The PDU is of an unsupported version.
.It Bq Er SNMP_CODE_BADENQ
There was an ASN.1 value with an unsupported tag.
+.It Bq Er SNMP_CODE_BADSECLEVEL
+The requested securityLevel contained in the PDU is not supported.
+.It Bq Er SNMP_CODE_BADDIGEST
+The PDU authentication parameter received in the PDU did not match the
+calculated message digest.
+.It Bq Er SNMP_CODE_EDECRYPT
+Error occured while trying to decrypt the PDU.
.El
.Pp
.Fn snmp_pdu_encode
@@ -297,8 +469,21 @@ Encoding failed.
.Xr bsnmpagent 3 ,
.Xr bsnmpclient 3 ,
.Xr bsnmplib 3
+.Sh CAVEAT
+The SNMPv3 message digests, encryption and decryption, and key routines use
+the cryptographic functions from
+.Xr crypto 3 .
+The library may optionally be built without references to the
+.Xr crypto 3
+library. In such case only plain text SNMPv3 PDUs without message digests
+may be proccessed correctly.
.Sh STANDARDS
This implementation conforms to the applicable IETF RFCs and ITU-T
recommendations.
.Sh AUTHORS
+The Begemot SNMP library was originally written by
.An Hartmut Brandt Aq harti@FreeBSD.org
+.Pp
+.An Shteryana Shopova Aq syrinx@FreeBSD.org
+added support for the SNMPv3 message proccessing and User-Based
+Security model message authentication and privacy.
diff --git a/contrib/bsnmp/lib/snmp.c b/contrib/bsnmp/lib/snmp.c
index b2700b1..322ac9f 100644
--- a/contrib/bsnmp/lib/snmp.c
+++ b/contrib/bsnmp/lib/snmp.c
@@ -5,6 +5,12 @@
*
* Author: Harti Brandt <harti@freebsd.org>
*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Shteryana Sotirova Shopova
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -271,47 +277,310 @@ parse_pdus(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
return (err);
}
+
+static enum asn_err
+parse_secparams(struct asn_buf *b, struct snmp_pdu *pdu)
+{
+ asn_len_t octs_len;
+ u_char buf[256]; /* XXX: calc max possible size here */
+ struct asn_buf tb;
+
+ memset(buf, 0, 256);
+ tb.asn_ptr = buf;
+ tb.asn_len = 256;
+
+ if (asn_get_octetstring(b, buf, &tb.asn_len) != ASN_ERR_OK) {
+ snmp_error("cannot parse usm header");
+ return (ASN_ERR_FAILED);
+ }
+
+ if (asn_get_sequence(&tb, &octs_len) != ASN_ERR_OK) {
+ snmp_error("cannot decode usm header");
+ return (ASN_ERR_FAILED);
+ }
+
+ octs_len = SNMP_ENGINE_ID_SIZ;
+ if (asn_get_octetstring(&tb, (u_char *)&pdu->engine.engine_id,
+ &octs_len) != ASN_ERR_OK) {
+ snmp_error("cannot decode msg engine id");
+ return (ASN_ERR_FAILED);
+ }
+ pdu->engine.engine_len = octs_len;
+
+ if (asn_get_integer(&tb, &pdu->engine.engine_boots) != ASN_ERR_OK) {
+ snmp_error("cannot decode msg engine boots");
+ return (ASN_ERR_FAILED);
+ }
+
+ if (asn_get_integer(&tb, &pdu->engine.engine_time) != ASN_ERR_OK) {
+ snmp_error("cannot decode msg engine time");
+ return (ASN_ERR_FAILED);
+ }
+
+ octs_len = SNMP_ADM_STR32_SIZ - 1;
+ if (asn_get_octetstring(&tb, (u_char *)&pdu->user.sec_name, &octs_len)
+ != ASN_ERR_OK) {
+ snmp_error("cannot decode msg user name");
+ return (ASN_ERR_FAILED);
+ }
+ pdu->user.sec_name[octs_len] = '\0';
+
+ octs_len = sizeof(pdu->msg_digest);
+ if (asn_get_octetstring(&tb, (u_char *)&pdu->msg_digest, &octs_len) !=
+ ASN_ERR_OK || ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0 &&
+ octs_len != sizeof(pdu->msg_digest))) {
+ snmp_error("cannot decode msg authentication param");
+ return (ASN_ERR_FAILED);
+ }
+
+ octs_len = sizeof(pdu->msg_salt);
+ if (asn_get_octetstring(&tb, (u_char *)&pdu->msg_salt, &octs_len) !=
+ ASN_ERR_OK ||((pdu->flags & SNMP_MSG_PRIV_FLAG) != 0 &&
+ octs_len != sizeof(pdu->msg_salt))) {
+ snmp_error("cannot decode msg authentication param");
+ return (ASN_ERR_FAILED);
+ }
+
+ if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0) {
+ pdu->digest_ptr = b->asn_ptr - SNMP_USM_AUTH_SIZE;
+ pdu->digest_ptr -= octs_len + ASN_MAXLENLEN;
+ }
+
+ return (ASN_ERR_OK);
+}
+
+static enum snmp_code
+pdu_encode_secparams(struct asn_buf *b, struct snmp_pdu *pdu)
+{
+ u_char buf[256], *sptr;
+ struct asn_buf tb;
+ size_t auth_off, moved = 0;
+
+ auth_off = 0;
+ memset(buf, 0, 256);
+ tb.asn_ptr = buf;
+ tb.asn_len = 256;
+
+ if (asn_put_temp_header(&tb, (ASN_TYPE_SEQUENCE|ASN_TYPE_CONSTRUCTED),
+ &sptr) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (asn_put_octetstring(&tb, (u_char *)pdu->engine.engine_id,
+ pdu->engine.engine_len) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (asn_put_integer(&tb, pdu->engine.engine_boots) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (asn_put_integer(&tb, pdu->engine.engine_time) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (asn_put_octetstring(&tb, (u_char *)pdu->user.sec_name,
+ strlen(pdu->user.sec_name)) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0) {
+ auth_off = sizeof(buf) - tb.asn_len + ASN_MAXLENLEN;
+ if (asn_put_octetstring(&tb, (u_char *)pdu->msg_digest,
+ sizeof(pdu->msg_digest)) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+ } else {
+ if (asn_put_octetstring(&tb, (u_char *)pdu->msg_digest, 0)
+ != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+ }
+
+ if ((pdu->flags & SNMP_MSG_PRIV_FLAG) != 0) {
+ if (asn_put_octetstring(&tb, (u_char *)pdu->msg_salt,
+ sizeof(pdu->msg_salt)) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+ } else {
+ if (asn_put_octetstring(&tb, (u_char *)pdu->msg_salt, 0)
+ != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+ }
+
+ if (asn_commit_header(&tb, sptr, &moved) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0)
+ pdu->digest_ptr = b->asn_ptr + auth_off - moved;
+
+ if (asn_put_octetstring(b, buf, sizeof(buf) - tb.asn_len) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+ pdu->digest_ptr += ASN_MAXLENLEN;
+
+ if ((pdu->flags & SNMP_MSG_PRIV_FLAG) != 0 && asn_put_temp_header(b,
+ ASN_TYPE_OCTETSTRING, &pdu->encrypted_ptr) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ return (SNMP_CODE_OK);
+}
+
/*
- * Parse the outer SEQUENCE value. ASN_ERR_TAG means 'bad version'.
+ * Decode the PDU except for the variable bindings itself.
+ * If decoding fails because of a bad binding, but the rest can be
+ * decoded, ip points to the index of the failed variable (errors
+ * OORANGE, BADLEN or BADVERS).
*/
-enum asn_err
-snmp_parse_message_hdr(struct asn_buf *b, struct snmp_pdu *pdu, asn_len_t *lenp)
+enum snmp_code
+snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
+{
+ enum snmp_code code;
+
+ if ((code = snmp_pdu_decode_header(b, pdu)) != SNMP_CODE_OK)
+ return (code);
+
+ if (pdu->version == SNMP_V3) {
+ if (pdu->security_model != SNMP_SECMODEL_USM)
+ return (SNMP_CODE_FAILED);
+ if ((code = snmp_pdu_decode_secmode(b, pdu)) != SNMP_CODE_OK)
+ return (code);
+ }
+
+ code = snmp_pdu_decode_scoped(b, pdu, ip);
+
+ switch (code) {
+ case SNMP_CODE_FAILED:
+ snmp_pdu_free(pdu);
+ break;
+
+ case SNMP_CODE_BADENC:
+ if (pdu->version == SNMP_Verr)
+ return (SNMP_CODE_BADVERS);
+
+ default:
+ break;
+ }
+
+ return (code);
+}
+
+enum snmp_code
+snmp_pdu_decode_header(struct asn_buf *b, struct snmp_pdu *pdu)
{
int32_t version;
- u_char type;
- u_int comm_len;
+ u_int octs_len;
+ asn_len_t len;
+
+ pdu->outer_ptr = b->asn_ptr;
+ pdu->outer_len = b->asn_len;
+
+ if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
+ snmp_error("cannot decode pdu header");
+ return (SNMP_CODE_FAILED);
+ }
+ if (b->asn_len < len) {
+ snmp_error("outer sequence value too short");
+ return (SNMP_CODE_FAILED);
+ }
+ if (b->asn_len != len) {
+ snmp_error("ignoring trailing junk in message");
+ b->asn_len = len;
+ }
if (asn_get_integer(b, &version) != ASN_ERR_OK) {
snmp_error("cannot decode version");
- return (ASN_ERR_FAILED);
+ return (SNMP_CODE_FAILED);
}
- if (version == 0) {
+ if (version == 0)
pdu->version = SNMP_V1;
- } else if (version == 1) {
+ else if (version == 1)
pdu->version = SNMP_V2c;
- } else {
+ else if (version == 3)
+ pdu->version = SNMP_V3;
+ else {
pdu->version = SNMP_Verr;
snmp_error("unsupported SNMP version");
- return (ASN_ERR_TAG);
+ return (SNMP_CODE_BADENC);
}
- comm_len = SNMP_COMMUNITY_MAXLEN;
- if (asn_get_octetstring(b, (u_char *)pdu->community,
- &comm_len) != ASN_ERR_OK) {
- snmp_error("cannot decode community");
- return (ASN_ERR_FAILED);
+ if (pdu->version == SNMP_V3) {
+ if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
+ snmp_error("cannot decode pdu global data header");
+ return (SNMP_CODE_FAILED);
+ }
+
+ if (asn_get_integer(b, &pdu->identifier) != ASN_ERR_OK) {
+ snmp_error("cannot decode msg indetifier");
+ return (SNMP_CODE_FAILED);
+ }
+
+ if (asn_get_integer(b, &pdu->engine.max_msg_size)
+ != ASN_ERR_OK) {
+ snmp_error("cannot decode msg size");
+ return (SNMP_CODE_FAILED);
+ }
+
+ octs_len = 1;
+ if (asn_get_octetstring(b, (u_char *)&pdu->flags,
+ &octs_len) != ASN_ERR_OK) {
+ snmp_error("cannot decode msg flags");
+ return (SNMP_CODE_FAILED);
+ }
+
+ if (asn_get_integer(b, &pdu->security_model) != ASN_ERR_OK) {
+ snmp_error("cannot decode msg size");
+ return (SNMP_CODE_FAILED);
+ }
+
+ if (pdu->security_model != SNMP_SECMODEL_USM)
+ return (SNMP_CODE_FAILED);
+
+ if (parse_secparams(b, pdu) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+ } else {
+ octs_len = SNMP_COMMUNITY_MAXLEN;
+ if (asn_get_octetstring(b, (u_char *)pdu->community,
+ &octs_len) != ASN_ERR_OK) {
+ snmp_error("cannot decode community");
+ return (SNMP_CODE_FAILED);
+ }
+ pdu->community[octs_len] = '\0';
+ }
+
+ return (SNMP_CODE_OK);
+}
+
+enum snmp_code
+snmp_pdu_decode_scoped(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
+{
+ u_char type;
+ asn_len_t len, trailer;
+ enum asn_err err;
+
+ if (pdu->version == SNMP_V3) {
+ if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
+ snmp_error("cannot decode scoped pdu header");
+ return (SNMP_CODE_FAILED);
+ }
+
+ len = SNMP_ENGINE_ID_SIZ;
+ if (asn_get_octetstring(b, (u_char *)&pdu->context_engine,
+ &len) != ASN_ERR_OK) {
+ snmp_error("cannot decode msg context engine");
+ return (SNMP_CODE_FAILED);
+ }
+ pdu->context_engine_len = len;
+
+ len = SNMP_CONTEXT_NAME_SIZ;
+ if (asn_get_octetstring(b, (u_char *)&pdu->context_name,
+ &len) != ASN_ERR_OK) {
+ snmp_error("cannot decode msg context name");
+ return (SNMP_CODE_FAILED);
+ }
+ pdu->context_name[len] = '\0';
}
- pdu->community[comm_len] = '\0';
- if (asn_get_header(b, &type, lenp) != ASN_ERR_OK) {
+ if (asn_get_header(b, &type, &len) != ASN_ERR_OK) {
snmp_error("cannot get pdu header");
- return (ASN_ERR_FAILED);
+ return (SNMP_CODE_FAILED);
}
if ((type & ~ASN_TYPE_MASK) !=
(ASN_TYPE_CONSTRUCTED | ASN_CLASS_CONTEXT)) {
snmp_error("bad pdu header tag");
- return (ASN_ERR_FAILED);
+ return (SNMP_CODE_FAILED);
}
pdu->type = type & ASN_TYPE_MASK;
@@ -326,7 +595,7 @@ snmp_parse_message_hdr(struct asn_buf *b, struct snmp_pdu *pdu, asn_len_t *lenp)
case SNMP_PDU_TRAP:
if (pdu->version != SNMP_V1) {
snmp_error("bad pdu type %u", pdu->type);
- return (ASN_ERR_FAILED);
+ return (SNMP_CODE_FAILED);
}
break;
@@ -336,99 +605,64 @@ snmp_parse_message_hdr(struct asn_buf *b, struct snmp_pdu *pdu, asn_len_t *lenp)
case SNMP_PDU_REPORT:
if (pdu->version == SNMP_V1) {
snmp_error("bad pdu type %u", pdu->type);
- return (ASN_ERR_FAILED);
+ return (SNMP_CODE_FAILED);
}
break;
default:
snmp_error("bad pdu type %u", pdu->type);
- return (ASN_ERR_FAILED);
- }
-
-
- if (*lenp > b->asn_len) {
- snmp_error("pdu length too long");
- return (ASN_ERR_FAILED);
+ return (SNMP_CODE_FAILED);
}
- return (ASN_ERR_OK);
-}
-
-static enum asn_err
-parse_message(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
-{
- enum asn_err err;
- asn_len_t len, trailer;
-
- err = snmp_parse_message_hdr(b, pdu, &len);
- if (ASN_ERR_STOPPED(err))
- return (err);
-
trailer = b->asn_len - len;
b->asn_len = len;
err = parse_pdus(b, pdu, ip);
if (ASN_ERR_STOPPED(err))
- return (ASN_ERR_FAILED);
+ return (SNMP_CODE_FAILED);
if (b->asn_len != 0)
snmp_error("ignoring trailing junk after pdu");
b->asn_len = trailer;
- return (err);
+ return (SNMP_CODE_OK);
}
-/*
- * Decode the PDU except for the variable bindings itself.
- * If decoding fails because of a bad binding, but the rest can be
- * decoded, ip points to the index of the failed variable (errors
- * OORANGE, BADLEN or BADVERS).
- */
enum snmp_code
-snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
+snmp_pdu_decode_secmode(struct asn_buf *b, struct snmp_pdu *pdu)
{
- asn_len_t len;
+ u_char type;
+ enum snmp_code code;
+ uint8_t digest[SNMP_USM_AUTH_SIZE];
- memset(pdu, 0, sizeof(*pdu));
+ if (pdu->user.auth_proto != SNMP_AUTH_NOAUTH &&
+ (pdu->flags & SNMP_MSG_AUTH_FLAG) == 0)
+ return (SNMP_CODE_BADSECLEVEL);
- if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
- snmp_error("cannot decode pdu header");
- return (SNMP_CODE_FAILED);
- }
- if (b->asn_len < len) {
- snmp_error("outer sequence value too short");
+ if ((code = snmp_pdu_calc_digest(b, pdu, digest)) !=
+ SNMP_CODE_OK)
return (SNMP_CODE_FAILED);
- }
- if (b->asn_len != len) {
- snmp_error("ignoring trailing junk in message");
- b->asn_len = len;
- }
-
- switch (parse_message(b, pdu, ip)) {
- case ASN_ERR_OK:
- return (SNMP_CODE_OK);
+ if (pdu->user.auth_proto != SNMP_AUTH_NOAUTH &&
+ memcmp(digest, pdu->msg_digest, sizeof(pdu->msg_digest)) != 0)
+ return (SNMP_CODE_BADDIGEST);
- case ASN_ERR_FAILED:
- case ASN_ERR_EOBUF:
- snmp_pdu_free(pdu);
+ if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV && (asn_get_header(b, &type,
+ &pdu->scoped_len) != ASN_ERR_OK || type != ASN_TYPE_OCTETSTRING)) {
+ snmp_error("cannot decode encrypted pdu");
return (SNMP_CODE_FAILED);
+ }
+ pdu->scoped_ptr = b->asn_ptr;
- case ASN_ERR_BADLEN:
- return (SNMP_CODE_BADLEN);
-
- case ASN_ERR_RANGE:
- return (SNMP_CODE_OORANGE);
+ if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV &&
+ (pdu->flags & SNMP_MSG_PRIV_FLAG) == 0)
+ return (SNMP_CODE_BADSECLEVEL);
- case ASN_ERR_TAG:
- if (pdu->version == SNMP_Verr)
- return (SNMP_CODE_BADVERS);
- else
- return (SNMP_CODE_BADENC);
- }
+ if ((code = snmp_pdu_decrypt(b, pdu)) != SNMP_CODE_OK)
+ return (SNMP_CODE_FAILED);
- return (SNMP_CODE_OK);
+ return (code);
}
/*
@@ -500,6 +734,7 @@ enum snmp_code
snmp_pdu_encode_header(struct asn_buf *b, struct snmp_pdu *pdu)
{
enum asn_err err;
+ u_char *v3_hdr_ptr;
if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE|ASN_TYPE_CONSTRUCTED),
&pdu->outer_ptr) != ASN_ERR_OK)
@@ -509,14 +744,62 @@ snmp_pdu_encode_header(struct asn_buf *b, struct snmp_pdu *pdu)
err = asn_put_integer(b, 0);
else if (pdu->version == SNMP_V2c)
err = asn_put_integer(b, 1);
+ else if (pdu->version == SNMP_V3)
+ err = asn_put_integer(b, 3);
else
return (SNMP_CODE_BADVERS);
if (err != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
- if (asn_put_octetstring(b, (u_char *)pdu->community,
- strlen(pdu->community)) != ASN_ERR_OK)
- return (SNMP_CODE_FAILED);
+ if (pdu->version == SNMP_V3) {
+ if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE |
+ ASN_TYPE_CONSTRUCTED), &v3_hdr_ptr) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (asn_put_integer(b, pdu->identifier) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (asn_put_integer(b, pdu->engine.max_msg_size) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (pdu->type != SNMP_PDU_RESPONSE &&
+ pdu->type != SNMP_PDU_TRAP &&
+ pdu->type != SNMP_PDU_REPORT)
+ pdu->flags |= SNMP_MSG_REPORT_FLAG;
+
+ if (asn_put_octetstring(b, (u_char *)&pdu->flags, 1)
+ != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (asn_put_integer(b, pdu->security_model) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (asn_commit_header(b, v3_hdr_ptr, NULL) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (pdu->security_model != SNMP_SECMODEL_USM)
+ return (SNMP_CODE_FAILED);
+
+ if (pdu_encode_secparams(b, pdu) != SNMP_CODE_OK)
+ return (SNMP_CODE_FAILED);
+
+ /* View-based Access Conntrol information */
+ if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE |
+ ASN_TYPE_CONSTRUCTED), &pdu->scoped_ptr) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (asn_put_octetstring(b, (u_char *)pdu->context_engine,
+ pdu->context_engine_len) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (asn_put_octetstring(b, (u_char *)pdu->context_name,
+ strlen(pdu->context_name)) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+ } else {
+ if (asn_put_octetstring(b, (u_char *)pdu->community,
+ strlen(pdu->community)) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+ }
if (asn_put_temp_header(b, (ASN_TYPE_CONSTRUCTED | ASN_CLASS_CONTEXT |
pdu->type), &pdu->pdu_ptr) != ASN_ERR_OK)
@@ -550,13 +833,66 @@ snmp_pdu_encode_header(struct asn_buf *b, struct snmp_pdu *pdu)
return (SNMP_CODE_OK);
}
+static enum asn_err
+snmp_pdu_fix_padd(struct asn_buf *b, struct snmp_pdu *pdu)
+{
+ asn_len_t padlen;
+
+ if (pdu->user.priv_proto == SNMP_PRIV_DES && pdu->scoped_len % 8 != 0) {
+ padlen = 8 - (pdu->scoped_len % 8);
+ if (asn_pad(b, padlen) != ASN_ERR_OK)
+ return (ASN_ERR_FAILED);
+ pdu->scoped_len += padlen;
+ }
+
+ return (ASN_ERR_OK);
+}
+
enum snmp_code
-snmp_fix_encoding(struct asn_buf *b, const struct snmp_pdu *pdu)
+snmp_fix_encoding(struct asn_buf *b, struct snmp_pdu *pdu)
{
- if (asn_commit_header(b, pdu->vars_ptr) != ASN_ERR_OK ||
- asn_commit_header(b, pdu->pdu_ptr) != ASN_ERR_OK ||
- asn_commit_header(b, pdu->outer_ptr) != ASN_ERR_OK)
+ size_t moved = 0;
+ enum snmp_code code;
+
+ if (asn_commit_header(b, pdu->vars_ptr, NULL) != ASN_ERR_OK ||
+ asn_commit_header(b, pdu->pdu_ptr, NULL) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
+
+ if (pdu->version == SNMP_V3) {
+ if (asn_commit_header(b, pdu->scoped_ptr, NULL) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ pdu->scoped_len = b->asn_ptr - pdu->scoped_ptr;
+ if ((code = snmp_pdu_fix_padd(b, pdu))!= ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (pdu->security_model != SNMP_SECMODEL_USM)
+ return (SNMP_CODE_FAILED);
+
+ if (snmp_pdu_encrypt(b, pdu) != SNMP_CODE_OK)
+ return (SNMP_CODE_FAILED);
+
+ if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV &&
+ asn_commit_header(b, pdu->encrypted_ptr, NULL) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+ }
+
+ if (asn_commit_header(b, pdu->outer_ptr, &moved) != ASN_ERR_OK)
+ return (SNMP_CODE_FAILED);
+
+ pdu->outer_len = b->asn_ptr - pdu->outer_ptr;
+ pdu->digest_ptr -= moved;
+
+ if (pdu->version == SNMP_V3) {
+ if ((code = snmp_pdu_calc_digest(b, pdu, pdu->msg_digest)) !=
+ SNMP_CODE_OK)
+ return (SNMP_CODE_FAILED);
+
+ if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0)
+ memcpy(pdu->digest_ptr, pdu->msg_digest,
+ sizeof(pdu->msg_digest));
+ }
+
return (SNMP_CODE_OK);
}
@@ -639,7 +975,7 @@ snmp_binding_encode(struct asn_buf *b, const struct snmp_value *binding)
return (err);
}
- err = asn_commit_header(b, ptr);
+ err = asn_commit_header(b, ptr, NULL);
if (err != ASN_ERR_OK) {
*b = save;
return (err);
@@ -775,6 +1111,8 @@ snmp_pdu_dump(const struct snmp_pdu *pdu)
vers = "SNMPv1";
else if (pdu->version == SNMP_V2c)
vers = "SNMPv2c";
+ else if (pdu->version == SNMP_V3)
+ vers = "SNMPv3";
else
vers = "v?";
@@ -838,6 +1176,39 @@ snmp_value_copy(struct snmp_value *to, const struct snmp_value *from)
}
void
+snmp_pdu_init_secparams(struct snmp_pdu *pdu, struct snmp_engine *eng,
+ struct snmp_user *user)
+{
+ int32_t rval;
+
+ memcpy(&pdu->engine, eng, sizeof(pdu->engine));
+ memcpy(&pdu->user, user, sizeof(pdu->user));
+
+ if (user->auth_proto != SNMP_AUTH_NOAUTH)
+ pdu->flags |= SNMP_MSG_AUTH_FLAG;
+
+ switch (user->priv_proto) {
+ case SNMP_PRIV_DES:
+ memcpy(pdu->msg_salt, &eng->engine_boots,
+ sizeof(eng->engine_boots));
+ rval = random();
+ memcpy(pdu->msg_salt + sizeof(eng->engine_boots), &rval,
+ sizeof(int32_t));
+ pdu->flags |= SNMP_MSG_PRIV_FLAG;
+ break;
+ case SNMP_PRIV_AES:
+ rval = random();
+ memcpy(pdu->msg_salt, &rval, sizeof(int32_t));
+ rval = random();
+ memcpy(pdu->msg_salt + sizeof(int32_t), &rval, sizeof(int32_t));
+ pdu->flags |= SNMP_MSG_PRIV_FLAG;
+ break;
+ default:
+ break;
+ }
+}
+
+void
snmp_pdu_free(struct snmp_pdu *pdu)
{
u_int i;
diff --git a/contrib/bsnmp/lib/snmp.h b/contrib/bsnmp/lib/snmp.h
index 43af22e..3a6cec7 100644
--- a/contrib/bsnmp/lib/snmp.h
+++ b/contrib/bsnmp/lib/snmp.h
@@ -5,6 +5,13 @@
*
* Author: Harti Brandt <harti@freebsd.org>
*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Shteryana Sotirova Shopova
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -35,8 +42,11 @@
#include <sys/types.h>
-#define SNMP_COMMUNITY_MAXLEN 128
-#define SNMP_MAX_BINDINGS 100
+#define SNMP_COMMUNITY_MAXLEN 128
+#define SNMP_MAX_BINDINGS 100
+#define SNMP_CONTEXT_NAME_SIZ (32 + 1)
+#define SNMP_ENGINE_ID_SIZ 32
+#define SNMP_TIME_WINDOW 150
enum snmp_syntax {
SNMP_SYNTAX_NULL = 0,
@@ -75,33 +85,110 @@ struct snmp_value {
enum snmp_version {
SNMP_Verr = 0,
SNMP_V1 = 1,
- SNMP_V2c,
+ SNMP_V2c = 2,
+ SNMP_V3,
+};
+
+#define SNMP_ADM_STR32_SIZ (32 + 1)
+#define SNMP_AUTH_KEY_SIZ 40
+#define SNMP_PRIV_KEY_SIZ 32
+#define SNMP_USM_AUTH_SIZE 12
+#define SNMP_USM_PRIV_SIZE 8
+#define SNMP_AUTH_HMACMD5_KEY_SIZ 16
+#define SNMP_AUTH_HMACSHA_KEY_SIZ 20
+#define SNMP_PRIV_AES_KEY_SIZ 16
+#define SNMP_PRIV_DES_KEY_SIZ 8
+
+
+enum snmp_secmodel {
+ SNMP_SECMODEL_ANY = 0,
+ SNMP_SECMODEL_SNMPv1 = 1,
+ SNMP_SECMODEL_SNMPv2c = 2,
+ SNMP_SECMODEL_USM = 3,
+ SNMP_SECMODEL_UNKNOWN
+};
+
+enum snmp_usm_level {
+ SNMP_noAuthNoPriv = 1,
+ SNMP_authNoPriv = 2,
+ SNMP_authPriv = 3
+};
+
+enum snmp_authentication {
+ SNMP_AUTH_NOAUTH = 0,
+ SNMP_AUTH_HMAC_MD5,
+ SNMP_AUTH_HMAC_SHA
+};
+
+enum snmp_privacy {
+ SNMP_PRIV_NOPRIV = 0,
+ SNMP_PRIV_DES = 1,
+ SNMP_PRIV_AES
+};
+
+struct snmp_engine {
+ uint8_t engine_id[SNMP_ENGINE_ID_SIZ];
+ uint32_t engine_len;
+ int32_t engine_boots;
+ int32_t engine_time;
+ int32_t max_msg_size;
+};
+
+struct snmp_user {
+ char sec_name[SNMP_ADM_STR32_SIZ];
+ enum snmp_authentication auth_proto;
+ enum snmp_privacy priv_proto;
+ uint8_t auth_key[SNMP_AUTH_KEY_SIZ];
+ uint8_t priv_key[SNMP_PRIV_KEY_SIZ];
};
struct snmp_pdu {
- char community[SNMP_COMMUNITY_MAXLEN + 1];
- enum snmp_version version;
- u_int type;
+ char community[SNMP_COMMUNITY_MAXLEN + 1];
+ enum snmp_version version;
+ u_int type;
+
+ /* SNMPv3 PDU header fields */
+ int32_t identifier;
+ uint8_t flags;
+ int32_t security_model;
+ struct snmp_engine engine;
+
+ /* Associated USM user parameters */
+ struct snmp_user user;
+ uint8_t msg_digest[SNMP_USM_AUTH_SIZE];
+ uint8_t msg_salt[SNMP_USM_PRIV_SIZE];
+
+ /* View-based Access Model */
+ /* XXX: put in separate structure - conflicts with struct snmp_context */
+ uint32_t context_engine_len;
+ uint8_t context_engine[SNMP_ENGINE_ID_SIZ];
+ char context_name[SNMP_CONTEXT_NAME_SIZ];
/* trap only */
- struct asn_oid enterprise;
- u_char agent_addr[4];
- int32_t generic_trap;
- int32_t specific_trap;
- uint32_t time_stamp;
+ struct asn_oid enterprise;
+ u_char agent_addr[4];
+ int32_t generic_trap;
+ int32_t specific_trap;
+ uint32_t time_stamp;
/* others */
- int32_t request_id;
- int32_t error_status;
- int32_t error_index;
+ int32_t request_id;
+ int32_t error_status;
+ int32_t error_index;
/* fixes for encoding */
- u_char *outer_ptr;
- u_char *pdu_ptr;
- u_char *vars_ptr;
+ size_t outer_len;
+ size_t scoped_len;
+ u_char *outer_ptr;
+ u_char *digest_ptr;
+ u_char *encrypted_ptr;
+ u_char *scoped_ptr;
+ u_char *pdu_ptr;
+ u_char *vars_ptr;
+
- struct snmp_value bindings[SNMP_MAX_BINDINGS];
- u_int nbindings;
+ struct snmp_value bindings[SNMP_MAX_BINDINGS];
+ u_int nbindings;
};
#define snmp_v1_pdu snmp_pdu
@@ -150,20 +237,38 @@ enum snmp_code {
SNMP_CODE_BADLEN,
SNMP_CODE_BADENC,
SNMP_CODE_OORANGE,
+ SNMP_CODE_BADSECLEVEL,
+ SNMP_CODE_NOTINTIME,
+ SNMP_CODE_BADUSER,
+ SNMP_CODE_BADENGINE,
+ SNMP_CODE_BADDIGEST,
+ SNMP_CODE_EDECRYPT
};
+#define SNMP_MSG_AUTH_FLAG 0x1
+#define SNMP_MSG_PRIV_FLAG 0x2
+#define SNMP_MSG_REPORT_FLAG 0x4
+#define SNMP_MSG_AUTODISCOVER 0x80
+
void snmp_value_free(struct snmp_value *);
int snmp_value_parse(const char *, enum snmp_syntax, union snmp_values *);
int snmp_value_copy(struct snmp_value *, const struct snmp_value *);
void snmp_pdu_free(struct snmp_pdu *);
enum snmp_code snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *);
-enum snmp_code snmp_pdu_encode(struct snmp_pdu *pdu, struct asn_buf *resp_b);
+enum snmp_code snmp_pdu_decode_header(struct asn_buf *, struct snmp_pdu *);
+enum snmp_code snmp_pdu_decode_scoped(struct asn_buf *, struct snmp_pdu *, int32_t *);
+enum snmp_code snmp_pdu_encode(struct snmp_pdu *, struct asn_buf *);
+enum snmp_code snmp_pdu_decode_secmode(struct asn_buf *, struct snmp_pdu *);
int snmp_pdu_snoop(const struct asn_buf *);
void snmp_pdu_dump(const struct snmp_pdu *pdu);
+enum snmp_code snmp_passwd_to_keys(struct snmp_user *, char *);
+enum snmp_code snmp_get_local_keys(struct snmp_user *, uint8_t *, uint32_t);
+enum snmp_code snmp_calc_keychange(struct snmp_user *, uint8_t *);
+
extern void (*snmp_error)(const char *, ...);
extern void (*snmp_printf)(const char *, ...);
diff --git a/contrib/bsnmp/lib/snmpagent.c b/contrib/bsnmp/lib/snmpagent.c
index ca9ccbd..9cd9676 100644
--- a/contrib/bsnmp/lib/snmpagent.c
+++ b/contrib/bsnmp/lib/snmpagent.c
@@ -165,6 +165,29 @@ find_subnode(const struct snmp_value *value)
return (NULL);
}
+static void
+snmp_pdu_create_response(struct snmp_pdu *pdu, struct snmp_pdu *resp)
+{
+ memset(resp, 0, sizeof(*resp));
+ strcpy(resp->community, pdu->community);
+ resp->version = pdu->version;
+ resp->type = SNMP_PDU_RESPONSE;
+ resp->request_id = pdu->request_id;
+ resp->version = pdu->version;
+
+ if (resp->version != SNMP_V3)
+ return;
+
+ snmp_pdu_init_secparams(resp, &pdu->engine, &pdu->user);
+ resp->identifier = pdu->identifier;
+ resp->security_model = pdu->security_model;
+ resp->context_engine_len = pdu->context_engine_len;
+ memcpy(resp->context_engine, pdu->context_engine,
+ resp->context_engine_len);
+ strlcpy(resp->context_name, pdu->context_name,
+ sizeof(resp->context_name));
+}
+
/*
* Execute a GET operation. The tree is rooted at the global 'root'.
* Build the response PDU on the fly. If the return code is SNMP_RET_ERR
@@ -184,12 +207,7 @@ snmp_get(struct snmp_pdu *pdu, struct asn_buf *resp_b,
memset(&context, 0, sizeof(context));
context.ctx.data = data;
- memset(resp, 0, sizeof(*resp));
- strcpy(resp->community, pdu->community);
- resp->version = pdu->version;
- resp->type = SNMP_PDU_RESPONSE;
- resp->request_id = pdu->request_id;
- resp->version = pdu->version;
+ snmp_pdu_create_response(pdu, resp);
if (snmp_pdu_encode_header(resp_b, resp) != SNMP_CODE_OK)
/* cannot even encode header - very bad */
@@ -384,11 +402,7 @@ snmp_getnext(struct snmp_pdu *pdu, struct asn_buf *resp_b,
memset(&context, 0, sizeof(context));
context.ctx.data = data;
- memset(resp, 0, sizeof(*resp));
- strcpy(resp->community, pdu->community);
- resp->type = SNMP_PDU_RESPONSE;
- resp->request_id = pdu->request_id;
- resp->version = pdu->version;
+ snmp_pdu_create_response(pdu, resp);
if (snmp_pdu_encode_header(resp_b, resp))
return (SNMP_RET_IGN);
@@ -440,12 +454,7 @@ snmp_getbulk(struct snmp_pdu *pdu, struct asn_buf *resp_b,
memset(&context, 0, sizeof(context));
context.ctx.data = data;
- memset(resp, 0, sizeof(*resp));
- strcpy(resp->community, pdu->community);
- resp->version = pdu->version;
- resp->type = SNMP_PDU_RESPONSE;
- resp->request_id = pdu->request_id;
- resp->version = pdu->version;
+ snmp_pdu_create_response(pdu, resp);
if (snmp_pdu_encode_header(resp_b, resp) != SNMP_CODE_OK)
/* cannot even encode header - very bad */
@@ -652,11 +661,7 @@ snmp_set(struct snmp_pdu *pdu, struct asn_buf *resp_b,
TAILQ_INIT(&context.dlist);
context.ctx.data = data;
- memset(resp, 0, sizeof(*resp));
- strcpy(resp->community, pdu->community);
- resp->type = SNMP_PDU_RESPONSE;
- resp->request_id = pdu->request_id;
- resp->version = pdu->version;
+ snmp_pdu_create_response(pdu, resp);
if (snmp_pdu_encode_header(resp_b, resp))
return (SNMP_RET_IGN);
@@ -951,16 +956,9 @@ snmp_make_errresp(const struct snmp_pdu *pdu, struct asn_buf *pdu_b,
enum snmp_code code;
memset(&resp, 0, sizeof(resp));
-
- /* Message sequence */
- if (asn_get_sequence(pdu_b, &len) != ASN_ERR_OK)
- return (SNMP_RET_IGN);
- if (pdu_b->asn_len < len)
+ if ((code = snmp_pdu_decode_header(pdu_b, &resp)) != SNMP_CODE_OK)
return (SNMP_RET_IGN);
- err = snmp_parse_message_hdr(pdu_b, &resp, &len);
- if (ASN_ERR_STOPPED(err))
- return (SNMP_RET_IGN);
if (pdu_b->asn_len < len)
return (SNMP_RET_IGN);
pdu_b->asn_len = len;
diff --git a/contrib/bsnmp/lib/snmpclient.c b/contrib/bsnmp/lib/snmpclient.c
index b77543a..103ea69 100644
--- a/contrib/bsnmp/lib/snmpclient.c
+++ b/contrib/bsnmp/lib/snmpclient.c
@@ -852,6 +852,9 @@ snmp_client_init(struct snmp_client *c)
strcpy(c->read_community, "public");
strcpy(c->write_community, "private");
+
+ c->security_model = SNMP_SECMODEL_USM;
+ strcpy(c->cname, "");
c->timeout.tv_sec = 3;
c->timeout.tv_usec = 0;
@@ -864,6 +867,8 @@ snmp_client_init(struct snmp_client *c)
c->max_reqid = INT32_MAX;
c->min_reqid = 0;
c->next_reqid = 0;
+
+ c->engine.max_msg_size = 1500; /* XXX */
}
@@ -1132,7 +1137,8 @@ snmp_close(void)
void
snmp_pdu_create(struct snmp_pdu *pdu, u_int op)
{
- memset(pdu,0,sizeof(struct snmp_pdu));
+ memset(pdu, 0, sizeof(struct snmp_pdu));
+
if (op == SNMP_PDU_SET)
strlcpy(pdu->community, snmp_client.write_community,
sizeof(pdu->community));
@@ -1145,6 +1151,33 @@ snmp_pdu_create(struct snmp_pdu *pdu, u_int op)
pdu->error_status = 0;
pdu->error_index = 0;
pdu->nbindings = 0;
+
+ if (snmp_client.version != SNMP_V3)
+ return;
+
+ pdu->identifier = ++snmp_client.identifier;
+ pdu->engine.max_msg_size = snmp_client.engine.max_msg_size;
+ pdu->flags = 0;
+ pdu->security_model = snmp_client.security_model;
+
+ if (snmp_client.security_model == SNMP_SECMODEL_USM)
+ snmp_pdu_init_secparams(pdu, &snmp_client.engine,
+ &snmp_client.user);
+ else
+ seterr(&snmp_client, "unknown security model");
+
+ if (snmp_client.clen > 0) {
+ memcpy(pdu->context_engine, snmp_client.cengine,
+ snmp_client.clen);
+ pdu->context_engine_len = snmp_client.clen;
+ } else {
+ memcpy(pdu->context_engine, snmp_client.engine.engine_id,
+ snmp_client.engine.engine_len);
+ pdu->context_engine_len = snmp_client.engine.engine_len;
+ }
+
+ strlcpy(pdu->context_name, snmp_client.cname,
+ sizeof(pdu->context_name));
}
/* add pairs of (struct asn_oid, enum snmp_syntax) to an existing pdu */
@@ -1406,15 +1439,24 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
abuf.asn_ptr = buf;
abuf.asn_len = ret;
+ memset(pdu, 0, sizeof(*pdu));
+ if (snmp_client.security_model == SNMP_SECMODEL_USM)
+ snmp_pdu_init_secparams(pdu, &snmp_client.engine,
+ &snmp_client.user);
+
if (SNMP_CODE_OK != (ret = snmp_pdu_decode(&abuf, pdu, &ip))) {
seterr(&snmp_client, "snmp_decode_pdu: failed %d", ret);
free(buf);
return (-1);
}
+
free(buf);
if (snmp_client.dump_pdus)
snmp_pdu_dump(pdu);
+ snmp_client.engine.engine_time = pdu->engine.engine_time;
+ snmp_client.engine.engine_boots = pdu->engine.engine_boots;
+
return (+1);
}
@@ -1685,6 +1727,93 @@ snmp_dialog(struct snmp_v1_pdu *req, struct snmp_v1_pdu *resp)
}
int
+snmp_discover_engine(char *passwd)
+{
+ char cname[SNMP_ADM_STR32_SIZ];
+ enum snmp_authentication cap;
+ enum snmp_privacy cpp;
+ struct snmp_pdu req, resp;
+
+ if (snmp_client.version != SNMP_V3)
+ seterr(&snmp_client, "wrong version");
+
+ strlcpy(cname, snmp_client.user.sec_name, sizeof(cname));
+ cap = snmp_client.user.auth_proto;
+ cpp = snmp_client.user.priv_proto;
+
+ snmp_client.engine.engine_len = 0;
+ snmp_client.engine.engine_boots = 0;
+ snmp_client.engine.engine_time = 0;
+ snmp_client.user.auth_proto = SNMP_AUTH_NOAUTH;
+ snmp_client.user.priv_proto = SNMP_PRIV_NOPRIV;
+ memset(snmp_client.user.sec_name, 0, sizeof(snmp_client.user.sec_name));
+
+ snmp_pdu_create(&req, SNMP_PDU_GET);
+
+ if (snmp_dialog(&req, &resp) == -1)
+ return (-1);
+
+ if (resp.version != req.version) {
+ seterr(&snmp_client, "wrong version");
+ return (-1);
+ }
+
+ if (resp.error_status != SNMP_ERR_NOERROR) {
+ seterr(&snmp_client, "Error %d in responce", resp.error_status);
+ return (-1);
+ }
+
+ snmp_client.engine.engine_len = resp.engine.engine_len;
+ snmp_client.engine.max_msg_size = resp.engine.max_msg_size;
+ memcpy(snmp_client.engine.engine_id, resp.engine.engine_id,
+ resp.engine.engine_len);
+
+ strlcpy(snmp_client.user.sec_name, cname,
+ sizeof(snmp_client.user.sec_name));
+ snmp_client.user.auth_proto = cap;
+ snmp_client.user.priv_proto = cpp;
+
+ if (snmp_client.user.auth_proto == SNMP_AUTH_NOAUTH)
+ return (0);
+
+ if (passwd == NULL ||
+ snmp_passwd_to_keys(&snmp_client.user, passwd) != SNMP_CODE_OK ||
+ snmp_get_local_keys(&snmp_client.user, snmp_client.engine.engine_id,
+ snmp_client.engine.engine_len) != SNMP_CODE_OK)
+ return (-1);
+
+ if (resp.engine.engine_boots != 0)
+ snmp_client.engine.engine_boots = resp.engine.engine_boots;
+
+ if (resp.engine.engine_time != 0) {
+ snmp_client.engine.engine_time = resp.engine.engine_time;
+ return (0);
+ }
+
+ snmp_pdu_create(&req, SNMP_PDU_GET);
+ req.engine.engine_boots = 0;
+ req.engine.engine_time = 0;
+
+ if (snmp_dialog(&req, &resp) == -1)
+ return (-1);
+
+ if (resp.version != req.version) {
+ seterr(&snmp_client, "wrong version");
+ return (-1);
+ }
+
+ if (resp.error_status != SNMP_ERR_NOERROR) {
+ seterr(&snmp_client, "Error %d in responce", resp.error_status);
+ return (-1);
+ }
+
+ snmp_client.engine.engine_boots = resp.engine.engine_boots;
+ snmp_client.engine.engine_time = resp.engine.engine_time;
+
+ return (0);
+}
+
+int
snmp_client_set_host(struct snmp_client *cl, const char *h)
{
char *np;
diff --git a/contrib/bsnmp/lib/snmpclient.h b/contrib/bsnmp/lib/snmpclient.h
index e137b4c..619f726 100644
--- a/contrib/bsnmp/lib/snmpclient.h
+++ b/contrib/bsnmp/lib/snmpclient.h
@@ -69,36 +69,47 @@ typedef void (*snmp_timeout_stop_f)(void *timeout_id);
* Client context.
*/
struct snmp_client {
- enum snmp_version version;
- int trans; /* which transport to use */
+ enum snmp_version version;
+ int trans; /* which transport to use */
/* these two are read-only for the application */
- char *cport; /* port number as string */
- char *chost; /* host name or IP address as string */
+ char *cport; /* port number as string */
+ char *chost; /* host name or IP address as string */
- char read_community[SNMP_COMMUNITY_MAXLEN + 1];
- char write_community[SNMP_COMMUNITY_MAXLEN + 1];
+ char read_community[SNMP_COMMUNITY_MAXLEN + 1];
+ char write_community[SNMP_COMMUNITY_MAXLEN + 1];
- struct timeval timeout;
- u_int retries;
+ /* SNMPv3 specific fields */
+ int32_t identifier;
+ int32_t security_model;
+ struct snmp_engine engine;
+ struct snmp_user user;
- int dump_pdus;
+ /* SNMPv3 Access control - VACM*/
+ uint32_t clen;
+ uint8_t cengine[SNMP_ENGINE_ID_SIZ];
+ char cname[SNMP_CONTEXT_NAME_SIZ];
- size_t txbuflen;
- size_t rxbuflen;
+ struct timeval timeout;
+ u_int retries;
- int fd;
+ int dump_pdus;
- int32_t next_reqid;
- int32_t max_reqid;
- int32_t min_reqid;
+ size_t txbuflen;
+ size_t rxbuflen;
- char error[SNMP_STRERROR_LEN];
+ int fd;
- snmp_timeout_start_f timeout_start;
- snmp_timeout_stop_f timeout_stop;
+ int32_t next_reqid;
+ int32_t max_reqid;
+ int32_t min_reqid;
- char local_path[sizeof(SNMP_LOCAL_PATH)];
+ char error[SNMP_STRERROR_LEN];
+
+ snmp_timeout_start_f timeout_start;
+ snmp_timeout_stop_f timeout_stop;
+
+ char local_path[sizeof(SNMP_LOCAL_PATH)];
};
/* the global context */
@@ -181,6 +192,9 @@ int snmp_table_fetch_async(const struct snmp_table *, void *,
/* send a request and wait for the response */
int snmp_dialog(struct snmp_pdu *_req, struct snmp_pdu *_resp);
+/* discover an authorative snmpEngineId */
+int snmp_discover_engine(char *);
+
/* parse a server specification */
int snmp_parse_server(struct snmp_client *, const char *);
diff --git a/contrib/bsnmp/lib/snmpcrypto.c b/contrib/bsnmp/lib/snmpcrypto.c
new file mode 100644
index 0000000..81d8eac
--- /dev/null
+++ b/contrib/bsnmp/lib/snmpcrypto.c
@@ -0,0 +1,404 @@
+/*-
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Shteryana Sotirova Shopova under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#elif defined(HAVE_INTTYPES_H)
+#include <inttypes.h>
+#endif
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netinet/in.h>
+
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/evp.h>
+#endif
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmppriv.h"
+
+#define SNMP_PRIV_AES_IV_SIZ 16
+#define SNMP_EXTENDED_KEY_SIZ 64
+#define SNMP_AUTH_KEY_LOOPCNT 1048576
+#define SNMP_AUTH_BUF_SIZE 72
+
+static const uint8_t ipad = 0x36;
+static const uint8_t opad = 0x5c;
+
+#ifdef HAVE_LIBCRYPTO
+
+static int32_t
+snmp_digest_init(const struct snmp_user *user, EVP_MD_CTX *ctx,
+ const EVP_MD **dtype, uint32_t *keylen)
+{
+ if (user->auth_proto == SNMP_AUTH_HMAC_MD5) {
+ *dtype = EVP_md5();
+ *keylen = SNMP_AUTH_HMACMD5_KEY_SIZ;
+ } else if (user->auth_proto == SNMP_AUTH_HMAC_SHA) {
+ *dtype = EVP_sha1();
+ *keylen = SNMP_AUTH_HMACSHA_KEY_SIZ;
+ } else if (user->auth_proto == SNMP_AUTH_NOAUTH)
+ return (0);
+ else {
+ snmp_error("unknown authentication option - %d",
+ user->auth_proto);
+ return (-1);
+ }
+
+ if (EVP_DigestInit(ctx, *dtype) != 1)
+ return (-1);
+
+ return (1);
+}
+
+enum snmp_code
+snmp_pdu_calc_digest(struct asn_buf *b, const struct snmp_pdu *pdu,
+ uint8_t *digest)
+{
+ uint8_t md[EVP_MAX_MD_SIZE], extkey[SNMP_EXTENDED_KEY_SIZ];
+ uint8_t key1[SNMP_EXTENDED_KEY_SIZ], key2[SNMP_EXTENDED_KEY_SIZ];
+ uint32_t i, keylen, olen;
+ int32_t err;
+ const EVP_MD *dtype;
+ EVP_MD_CTX ctx;
+
+ err = snmp_digest_init(&pdu->user, &ctx, &dtype, &keylen);
+ if (err < 0)
+ return (SNMP_CODE_BADDIGEST);
+ else if (err == 0)
+ return (SNMP_CODE_OK);
+
+ memset(pdu->digest_ptr, 0, sizeof(pdu->msg_digest));
+ memcpy(extkey, pdu->user.auth_key, keylen);
+ memset(extkey + keylen, 0, sizeof(extkey) - keylen);
+
+ for (i = 0; i < SNMP_EXTENDED_KEY_SIZ; i++) {
+ key1[i] = extkey[i] ^ ipad;
+ key2[i] = extkey[i] ^ opad;
+ }
+
+ if (EVP_DigestUpdate(&ctx, key1, SNMP_EXTENDED_KEY_SIZ) != 1 ||
+ EVP_DigestUpdate(&ctx, pdu->outer_ptr, pdu->outer_len) != 1 ||
+ EVP_DigestFinal(&ctx, md, &olen) != 1)
+ goto failed;
+
+ if (EVP_DigestInit(&ctx, dtype) != 1 ||
+ EVP_DigestUpdate(&ctx, key2, SNMP_EXTENDED_KEY_SIZ) != 1 ||
+ EVP_DigestUpdate(&ctx, md, olen) != 1 ||
+ EVP_DigestFinal(&ctx, md, &olen) != 1)
+ goto failed;
+
+ if (olen < SNMP_USM_AUTH_SIZE) {
+ snmp_error("bad digest size - %d", olen);
+ EVP_MD_CTX_cleanup(&ctx);
+ return (SNMP_CODE_BADDIGEST);
+ }
+
+ memcpy(digest, md, SNMP_USM_AUTH_SIZE);
+ EVP_MD_CTX_cleanup(&ctx);
+ return (SNMP_CODE_OK);
+
+failed:
+ EVP_MD_CTX_cleanup(&ctx);
+ return (SNMP_CODE_BADDIGEST);
+}
+
+static int32_t
+snmp_pdu_cipher_init(const struct snmp_pdu *pdu, int32_t len,
+ EVP_CIPHER_CTX *ctx, const EVP_CIPHER **ctype, uint8_t *piv)
+{
+ int i;
+ uint32_t netint;
+
+ if (pdu->user.priv_proto == SNMP_PRIV_DES) {
+ if (len % 8 != 0)
+ return (-1);
+ *ctype = EVP_des_cbc();
+ memcpy(piv, pdu->msg_salt, sizeof(pdu->msg_salt));
+ for (i = 0; i < 8; i++)
+ piv[i] = piv[i] ^ pdu->user.priv_key[8 + i];
+ } else if (pdu->user.priv_proto == SNMP_PRIV_AES) {
+ *ctype = EVP_aes_128_cfb128();
+ netint = htonl(pdu->engine.engine_boots);
+ memcpy(piv, &netint, sizeof(netint));
+ piv += sizeof(netint);
+ netint = htonl(pdu->engine.engine_time);
+ memcpy(piv, &netint, sizeof(netint));
+ piv += sizeof(netint);
+ memcpy(piv, pdu->msg_salt, sizeof(pdu->msg_salt));
+ } else if (pdu->user.priv_proto == SNMP_PRIV_NOPRIV)
+ return (0);
+ else {
+ snmp_error("unknown privacy option - %d", pdu->user.priv_proto);
+ return (-1);
+ }
+
+ return (1);
+}
+
+enum snmp_code
+snmp_pdu_encrypt(struct asn_buf *b, const struct snmp_pdu *pdu)
+{
+ int32_t err, olen;
+ uint8_t iv[SNMP_PRIV_AES_IV_SIZ];
+ const EVP_CIPHER *ctype;
+ EVP_CIPHER_CTX ctx;
+
+ err = snmp_pdu_cipher_init(pdu, pdu->scoped_len, &ctx, &ctype, iv);
+ if (err < 0)
+ return (SNMP_CODE_EDECRYPT);
+ else if (err == 0)
+ return (SNMP_CODE_OK);
+
+ if (EVP_EncryptInit(&ctx, ctype, pdu->user.priv_key, iv) != 1)
+ return (SNMP_CODE_FAILED);
+
+ if (EVP_EncryptUpdate(&ctx, pdu->scoped_ptr, &olen, pdu->scoped_ptr,
+ pdu->scoped_len) != 1 ||
+ EVP_EncryptFinal(&ctx, pdu->scoped_ptr + olen, &olen) != 1) {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return (SNMP_CODE_FAILED);
+ }
+
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return (SNMP_CODE_OK);
+}
+
+enum snmp_code
+snmp_pdu_decrypt(struct asn_buf *b, const struct snmp_pdu *pdu)
+{
+ int32_t err, olen;
+ uint8_t iv[SNMP_PRIV_AES_IV_SIZ];
+ const EVP_CIPHER *ctype;
+ EVP_CIPHER_CTX ctx;
+
+ err = snmp_pdu_cipher_init(pdu, pdu->scoped_len, &ctx, &ctype, iv);
+ if (err < 0)
+ return (SNMP_CODE_EDECRYPT);
+ else if (err == 0)
+ return (SNMP_CODE_OK);
+
+ if (EVP_DecryptInit(&ctx, ctype, pdu->user.priv_key, iv) != 1 ||
+ EVP_CIPHER_CTX_set_padding(&ctx, 0) != 1)
+ return (SNMP_CODE_EDECRYPT);
+
+ if (EVP_DecryptUpdate(&ctx, pdu->scoped_ptr, &olen, pdu->scoped_ptr,
+ pdu->scoped_len) != 1 ||
+ EVP_DecryptFinal(&ctx, pdu->scoped_ptr + olen, &olen) != 1) {
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return (SNMP_CODE_EDECRYPT);
+ }
+
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return (SNMP_CODE_OK);
+}
+
+/* [RFC 3414] - A.2. Password to Key Algorithm */
+enum snmp_code
+snmp_passwd_to_keys(struct snmp_user *user, char *passwd)
+{
+ int err, loop, i, pwdlen;
+ uint32_t keylen, olen;
+ const EVP_MD *dtype;
+ EVP_MD_CTX ctx;
+ uint8_t authbuf[SNMP_AUTH_BUF_SIZE];
+
+ if (passwd == NULL || user == NULL)
+ return (SNMP_CODE_FAILED);
+
+ err = snmp_digest_init(user, &ctx, &dtype, &keylen);
+ if (err < 0)
+ return (SNMP_CODE_BADDIGEST);
+ else if (err == 0)
+ return (SNMP_CODE_OK);
+
+ memset(user->auth_key, 0, sizeof(user->auth_key));
+ pwdlen = strlen(passwd);
+
+ for (loop = 0; loop < SNMP_AUTH_KEY_LOOPCNT; loop += i) {
+ for (i = 0; i < SNMP_EXTENDED_KEY_SIZ; i++)
+ authbuf[i] = passwd[(loop + i) % pwdlen];
+ if (EVP_DigestUpdate(&ctx, authbuf, SNMP_EXTENDED_KEY_SIZ) != 1)
+ goto failed;
+ }
+
+ if (EVP_DigestFinal(&ctx, user->auth_key, &olen) != 1)
+ goto failed;
+
+ EVP_MD_CTX_cleanup(&ctx);
+ return (SNMP_CODE_OK);
+
+failed:
+ EVP_MD_CTX_cleanup(&ctx);
+ return (SNMP_CODE_BADDIGEST);
+}
+
+/* [RFC 3414] - 2.6. Key Localization Algorithm */
+enum snmp_code
+snmp_get_local_keys(struct snmp_user *user, uint8_t *eid, uint32_t elen)
+{
+ int err;
+ uint32_t keylen, olen;
+ const EVP_MD *dtype;
+ EVP_MD_CTX ctx;
+ uint8_t authbuf[SNMP_AUTH_BUF_SIZE];
+
+ if (user == NULL || eid == NULL || elen > SNMP_ENGINE_ID_SIZ)
+ return (SNMP_CODE_FAILED);
+
+ memset(user->priv_key, 0, sizeof(user->priv_key));
+ memset(authbuf, 0, sizeof(authbuf));
+
+ err = snmp_digest_init(user, &ctx, &dtype, &keylen);
+ if (err < 0)
+ return (SNMP_CODE_BADDIGEST);
+ else if (err == 0)
+ return (SNMP_CODE_OK);
+
+ memcpy(authbuf, user->auth_key, keylen);
+ memcpy(authbuf + keylen, eid, elen);
+ memcpy(authbuf + keylen + elen, user->auth_key, keylen);
+
+ if (EVP_DigestUpdate(&ctx, authbuf, 2 * keylen + elen) != 1 ||
+ EVP_DigestFinal(&ctx, user->auth_key, &olen) != 1) {
+ EVP_MD_CTX_cleanup(&ctx);
+ return (SNMP_CODE_BADDIGEST);
+ }
+ EVP_MD_CTX_cleanup(&ctx);
+
+ if (user->priv_proto != SNMP_PRIV_NOPRIV)
+ memcpy(user->priv_key, user->auth_key, sizeof(user->priv_key));
+
+ return (SNMP_CODE_OK);
+}
+
+enum snmp_code
+snmp_calc_keychange(struct snmp_user *user, uint8_t *keychange)
+{
+ int32_t i, err, rvalue[SNMP_AUTH_HMACSHA_KEY_SIZ / 4];
+ uint32_t keylen, olen;
+ const EVP_MD *dtype;
+ EVP_MD_CTX ctx;
+
+ err = snmp_digest_init(user, &ctx, &dtype, &keylen);
+ if (err < 0)
+ return (SNMP_CODE_BADDIGEST);
+ else if (err == 0)
+ return (SNMP_CODE_OK);
+
+ for (i = 0; i < keylen / 4; i++)
+ rvalue[i] = random();
+
+ memcpy(keychange, user->auth_key, keylen);
+ memcpy(keychange + keylen, rvalue, keylen);
+
+ if (EVP_DigestUpdate(&ctx, keychange, 2 * keylen) != 1 ||
+ EVP_DigestFinal(&ctx, keychange, &olen) != 1) {
+ EVP_MD_CTX_cleanup(&ctx);
+ return (SNMP_CODE_BADDIGEST);
+ }
+
+ EVP_MD_CTX_cleanup(&ctx);
+ return (SNMP_CODE_OK);
+}
+
+#else /* !HAVE_LIBCRYPTO */
+
+enum snmp_code
+snmp_pdu_calc_digest(struct asn_buf *b __unused, const struct snmp_pdu *pdu,
+ uint8_t *digest __unused)
+{
+ if (pdu->user.auth_proto != SNMP_AUTH_NOAUTH)
+ return (SNMP_CODE_BADSECLEVEL);
+
+
+ return (SNMP_CODE_OK);
+}
+
+enum snmp_code
+snmp_pdu_encrypt(struct asn_buf *b __unused, const struct snmp_pdu *pdu)
+{
+ if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV)
+ return (SNMP_CODE_BADSECLEVEL);
+
+ return (SNMP_CODE_OK);
+}
+
+enum snmp_code
+snmp_pdu_decrypt(struct asn_buf *b __unused, const struct snmp_pdu *pdu)
+{
+ if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV)
+ return (SNMP_CODE_BADSECLEVEL);
+
+ return (SNMP_CODE_OK);
+}
+
+int
+snmp_passwd_to_keys(struct snmp_user *user, char *passwd __unused)
+{
+ if (user->auth_proto == SNMP_AUTH_NOAUTH &&
+ user->priv_proto == SNMP_PRIV_NOPRIV)
+ return (SNMP_CODE_OK);
+
+ errno = EPROTONOSUPPORT;
+
+ return (SNMP_CODE_FAILED);
+}
+
+int
+snmp_get_local_keys(struct snmp_user *user, uint8_t *eid __unused,
+ uint32_t elen __unused)
+{
+ if (user->auth_proto == SNMP_AUTH_NOAUTH &&
+ user->priv_proto == SNMP_PRIV_NOPRIV)
+ return (SNMP_CODE_OK);
+
+ errno = EPROTONOSUPPORT;
+
+ return (SNMP_CODE_FAILED);
+}
+
+enum snmp_code
+snmp_calc_keychange(struct snmp_user *user __unused,
+ uint8_t *keychange __unused)
+{
+ errno = EPROTONOSUPPORT;
+ return (SNMP_CODE_FAILED);
+}
+
+#endif /* HAVE_LIBCRYPTO */
diff --git a/contrib/bsnmp/lib/snmppriv.h b/contrib/bsnmp/lib/snmppriv.h
index 535e0e9..98ac7e0 100644
--- a/contrib/bsnmp/lib/snmppriv.h
+++ b/contrib/bsnmp/lib/snmppriv.h
@@ -34,12 +34,18 @@
enum asn_err snmp_binding_encode(struct asn_buf *, const struct snmp_value *);
enum snmp_code snmp_pdu_encode_header(struct asn_buf *, struct snmp_pdu *);
-enum snmp_code snmp_fix_encoding(struct asn_buf *, const struct snmp_pdu *);
-enum asn_err snmp_parse_message_hdr(struct asn_buf *b, struct snmp_pdu *pdu,
- asn_len_t *lenp);
+enum snmp_code snmp_fix_encoding(struct asn_buf *, struct snmp_pdu *);
enum asn_err snmp_parse_pdus_hdr(struct asn_buf *b, struct snmp_pdu *pdu,
asn_len_t *lenp);
+void snmp_pdu_init_secparams(struct snmp_pdu *, struct snmp_engine *,
+ struct snmp_user *);
+
+enum snmp_code snmp_pdu_calc_digest(struct asn_buf *, const struct snmp_pdu *,
+ uint8_t *);
+enum snmp_code snmp_pdu_encrypt(struct asn_buf *, const struct snmp_pdu *);
+enum snmp_code snmp_pdu_decrypt(struct asn_buf *, const struct snmp_pdu *);
+
#define DEFAULT_HOST "localhost"
#define DEFAULT_PORT "snmp"
#define DEFAULT_LOCAL "/var/run/snmp.sock"
diff --git a/contrib/bsnmp/snmp_usm/snmp_usm.3 b/contrib/bsnmp/snmp_usm/snmp_usm.3
new file mode 100755
index 0000000..7fd0817
--- /dev/null
+++ b/contrib/bsnmp/snmp_usm/snmp_usm.3
@@ -0,0 +1,132 @@
+.\"-
+.\" Copyright (C) 2010 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This documentation was written by Shteryana Sotirova Shopova under
+.\" sponsorship from the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 9, 2010
+.Dt SNMP_USM 3
+.Os
+.Sh NAME
+.Nm snmp_usm
+.Nd "user-based security module for
+.Xr bsnmpd 1
+.Sh LIBRARY
+.Pq begemotSnmpdModulePath."usm" = "/usr/lib/snmp_usm.so"
+.Sh DESCRIPTION
+The
+.Nm snmp_usm
+module implements SNMPv3 User-Based Security Model MIB as defined in RFC 3414.
+The module is used to manage the internal list of SNMPv3 USM active users in
+.Nm bsnmpd .
+The module must be loaded for
+.Nm bsnmpd
+to receive and process SNMPv3 USM PDUs correctly.
+.Sh IMPLEMENTATION NOTES
+A short description of the objects in the MIB follows.
+.Bl -tag -width "XXXXXXXXX"
+.It Va usmStats
+The subtree contains statistics for the User-based Security Model PDU processing.
+The statistics are reset each time the module is loaded.
+.It Va usmUserSpinLock
+An advisory lock used to coordinate several Command Generator Applications when
+altering the SNMP USM users.
+.It Va usmUserTable
+The table contains all SNMP USM users configured in
+.Nm bsnmpd.
+The table contains the following objects
+.Bl -tag -width ".It Va usmUserEngineID"
+.It Va usmUserEngineID
+An SNMP engine's administratively-unique identifier. Must be set to the same
+Engine ID as
+.Nm bsnmpd
+so that the user will actually be allowed to communicate with the daemon.
+The column is used as entry key and is not accessible for GET or SET operations.
+.It Va usmUserName
+The USM user name. The second entry key, again not accessible for GET or SET
+operations.
+.It Va usmUserSecurityName
+The column has the exact same value as the
+.Va usmUserName
+column, however is accessible for GET operations.
+.It Va usmUserCloneFrom
+A GET on this column will return an empty OID. SET operations are currently not
+supported.
+.It Va usmUserAuthProtocol
+The value of this column contains the OID corresponding to the authentication
+protocol used by the USM user. The following protocols and their OIDs are known to
+.Nm
+module
+.Bl -tag -width ".It Va NoAuthProtocol"
+.It NoAuthProtocol 1.3.6.1.6.3.10.1.1.1
+.It HMACMD5AuthProtocol 1.3.6.1.6.3.10.1.1.2
+.It HMACSHAAuthProtocol 1.3.6.1.6.3.10.1.1.3
+.El
+.It Va usmUserAuthKeyChange , Va usmUserOwnAuthKeyChange
+These columns may be used to change the user's authentication key.
+.It Va usmUserPrivProtocol
+The value of this column contains the OID corresponding to the privacy
+protocol used by the USM user. The following protocols and their OIDs are known to
+.Nm
+module
+.Bl -tag -width ".It Va NoPrivProtocol"
+.It NoPrivProtocol 1.3.6.1.6.3.10.1.2.1
+.It DESPrivProtoco 1.3.6.1.6.3.10.1.2.2
+.It AesCfb128Protocol 1.3.6.1.6.3.10.1.2.4
+.El
+.It Va usmUserPrivKeyChange , Va usmUserOwnPrivKeyChange
+These columns may be used to change the user's privacy key.
+.It Va usmUserPublic
+An arbitrary octet string that may be modified to confirm a SET operation on any
+of the columns was successfull.
+.It Va usmUserStorageType
+This column always has either of two values. Entries created via
+.Nm bsnmpd's
+configuration file always have this column set to readOnly (5) and
+it is not possible to modify those entries. Entries created by Command Generator
+Applications always have this column set to volatile(2) and such entries are
+lost when the module is restarted. A SET operation on this column is not
+allowed.
+.It Va usmUserStatus
+This column is used to create new USM user entries or delete exsiting ones from
+the table.
+.El
+.EL
+.Sh FILES
+.Bl -tag -width "XXXXXXXXX"
+.It Pa /usr/share/snmp/defs/usm_tree.def
+The description of the MIB tree implemented by
+.Nm .
+.El
+.Sh SEE ALSO
+.Xr bsnmpd 1 ,
+.Xr gensnmptree 1 ,
+.Xr snmpmod 3
+.Sh STANDARDS
+IETF RFC 3414
+.Sh AUTHORS
+.An Shteryana Shopova Aq syrinx@FreeBSD.org
diff --git a/contrib/bsnmp/snmp_usm/usm_snmp.c b/contrib/bsnmp/snmp_usm/usm_snmp.c
new file mode 100755
index 0000000..d5350bc
--- /dev/null
+++ b/contrib/bsnmp/snmp_usm/usm_snmp.c
@@ -0,0 +1,614 @@
+/*-
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Shteryana Sotirova Shopova under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/queue.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmpmod.h"
+
+#include "usm_tree.h"
+#include "usm_oid.h"
+
+static struct lmodule *usm_module;
+/* For the registration. */
+static const struct asn_oid oid_usm = OIDX_snmpUsmMIB;
+
+static const struct asn_oid oid_usmNoAuthProtocol = OIDX_usmNoAuthProtocol;
+static const struct asn_oid oid_usmHMACMD5AuthProtocol = \
+ OIDX_usmHMACMD5AuthProtocol;
+static const struct asn_oid oid_usmHMACSHAAuthProtocol = \
+ OIDX_usmHMACSHAAuthProtocol;
+
+static const struct asn_oid oid_usmNoPrivProtocol = OIDX_usmNoPrivProtocol;
+static const struct asn_oid oid_usmDESPrivProtocol = OIDX_usmDESPrivProtocol;
+static const struct asn_oid oid_usmAesCfb128Protocol = OIDX_usmAesCfb128Protocol;
+
+static const struct asn_oid oid_usmUserSecurityName = OIDX_usmUserSecurityName;
+
+/* The registration. */
+static uint reg_usm;
+
+static int32_t usm_lock;
+
+static struct usm_user * usm_get_user(const struct asn_oid *, uint);
+static struct usm_user * usm_get_next_user(const struct asn_oid *, uint);
+static void usm_append_userindex(struct asn_oid *, uint,
+ const struct usm_user *);
+static int usm_user_index_decode(const struct asn_oid *, uint, uint8_t *,
+ uint32_t *, char *);
+
+int
+op_usm_stats(struct snmp_context *ctx __unused, struct snmp_value *val,
+ uint32_t sub __unused, uint32_t iidx __unused, enum snmp_op op)
+{
+ struct snmpd_usmstat *usmstats;
+
+ if (op == SNMP_OP_SET)
+ return (SNMP_ERR_NOT_WRITEABLE);
+
+ if ((usmstats = bsnmpd_get_usm_stats()) == NULL)
+ return (SNMP_ERR_GENERR);
+
+ if (op == SNMP_OP_GET) {
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_usmStatsUnsupportedSecLevels:
+ val->v.uint32 = usmstats->unsupported_seclevels;
+ break;
+ case LEAF_usmStatsNotInTimeWindows:
+ val->v.uint32 = usmstats->not_in_time_windows;
+ break;
+ case LEAF_usmStatsUnknownUserNames:
+ val->v.uint32 = usmstats->unknown_users;
+ break;
+ case LEAF_usmStatsUnknownEngineIDs:
+ val->v.uint32 = usmstats->unknown_engine_ids;
+ break;
+ case LEAF_usmStatsWrongDigests:
+ val->v.uint32 = usmstats->wrong_digests;
+ break;
+ case LEAF_usmStatsDecryptionErrors:
+ val->v.uint32 = usmstats->decrypt_errors;
+ break;
+ default:
+ return (SNMP_ERR_NOSUCHNAME);
+ }
+ return (SNMP_ERR_NOERROR);
+ }
+ abort();
+}
+
+int
+op_usm_lock(struct snmp_context *ctx __unused, struct snmp_value *val,
+ uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
+{
+ if (val->var.subs[sub - 1] != LEAF_usmUserSpinLock)
+ return (SNMP_ERR_NOSUCHNAME);
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if (++usm_lock == INT32_MAX)
+ usm_lock = 0;
+ val->v.integer = usm_lock;
+ break;
+ case SNMP_OP_GETNEXT:
+ abort();
+ case SNMP_OP_SET:
+ if (val->v.integer != usm_lock)
+ return (SNMP_ERR_INCONS_VALUE);
+ break;
+ case SNMP_OP_ROLLBACK:
+ /* FALLTHROUGH */
+ case SNMP_OP_COMMIT:
+ break;
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+int
+op_usm_users(struct snmp_context *ctx, struct snmp_value *val,
+ uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
+{
+ uint32_t elen;
+ struct usm_user *uuser, *clone;
+ char uname[SNMP_ADM_STR32_SIZ];
+ uint8_t eid[SNMP_ENGINE_ID_SIZ];
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if ((uuser = usm_get_user(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_GETNEXT:
+ if ((uuser = usm_get_next_user(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ usm_append_userindex(&val->var, sub, uuser);
+ break;
+
+ case SNMP_OP_SET:
+ if ((uuser = usm_get_user(&val->var, sub)) == NULL &&
+ val->var.subs[sub - 1] != LEAF_usmUserStatus &&
+ val->var.subs[sub - 1] != LEAF_usmUserCloneFrom)
+ return (SNMP_ERR_NOSUCHNAME);
+
+ if (community != COMM_INITIALIZE &&
+ uuser->type == StorageType_readOnly)
+ return (SNMP_ERR_NOT_WRITEABLE);
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_usmUserSecurityName:
+ return (SNMP_ERR_NOT_WRITEABLE);
+
+ case LEAF_usmUserCloneFrom:
+ if (uuser != NULL || usm_user_index_decode(&val->var,
+ sub, eid, &elen, uname) < 0 ||
+ !(asn_is_suboid(&oid_usmUserSecurityName, &val->v.oid)))
+ return (SNMP_ERR_WRONG_VALUE);
+ if ((clone = usm_get_user(&val->v.oid, sub)) == NULL)
+ return (SNMP_ERR_INCONS_VALUE);
+ if ((uuser = usm_new_user(eid, elen, uname)) == NULL)
+ return (SNMP_ERR_GENERR);
+ uuser->status = RowStatus_notReady;
+ if (community != COMM_INITIALIZE)
+ uuser->type = StorageType_volatile;
+ else
+ uuser->type = StorageType_readOnly;
+
+ uuser->suser.auth_proto = clone->suser.auth_proto;
+ uuser->suser.priv_proto = clone->suser.priv_proto;
+ memcpy(uuser->suser.auth_key, clone->suser.auth_key,
+ sizeof(uuser->suser.auth_key));
+ memcpy(uuser->suser.priv_key, clone->suser.priv_key,
+ sizeof(uuser->suser.priv_key));
+ ctx->scratch->int1 = RowStatus_createAndWait;
+ break;
+
+ case LEAF_usmUserAuthProtocol:
+ ctx->scratch->int1 = uuser->suser.auth_proto;
+ if (asn_compare_oid(&oid_usmNoAuthProtocol,
+ &val->v.oid) == 0)
+ uuser->suser.auth_proto = SNMP_AUTH_NOAUTH;
+ else if (asn_compare_oid(&oid_usmHMACMD5AuthProtocol,
+ &val->v.oid) == 0)
+ uuser->suser.auth_proto = SNMP_AUTH_HMAC_MD5;
+ else if (asn_compare_oid(&oid_usmHMACSHAAuthProtocol,
+ &val->v.oid) == 0)
+ uuser->suser.auth_proto = SNMP_AUTH_HMAC_SHA;
+ else
+ return (SNMP_ERR_WRONG_VALUE);
+ break;
+
+ case LEAF_usmUserAuthKeyChange:
+ case LEAF_usmUserOwnAuthKeyChange:
+ if (val->var.subs[sub - 1] ==
+ LEAF_usmUserOwnAuthKeyChange &&
+ (usm_user == NULL || strcmp(uuser->suser.sec_name,
+ usm_user->suser.sec_name) != 0))
+ return (SNMP_ERR_NO_ACCESS);
+ if (val->v.octetstring.len > SNMP_AUTH_KEY_SIZ)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->ptr1 = malloc(SNMP_AUTH_KEY_SIZ);
+ if (ctx->scratch->ptr1 == NULL)
+ return (SNMP_ERR_GENERR);
+ memcpy(ctx->scratch->ptr1, uuser->suser.auth_key,
+ SNMP_AUTH_KEY_SIZ);
+ memcpy(uuser->suser.auth_key, val->v.octetstring.octets,
+ val->v.octetstring.len);
+ break;
+
+ case LEAF_usmUserPrivProtocol:
+ ctx->scratch->int1 = uuser->suser.priv_proto;
+ if (asn_compare_oid(&oid_usmNoPrivProtocol,
+ &val->v.oid) == 0)
+ uuser->suser.priv_proto = SNMP_PRIV_NOPRIV;
+ else if (asn_compare_oid(&oid_usmDESPrivProtocol,
+ &val->v.oid) == 0)
+ uuser->suser.priv_proto = SNMP_PRIV_DES;
+ else if (asn_compare_oid(&oid_usmAesCfb128Protocol,
+ &val->v.oid) == 0)
+ uuser->suser.priv_proto = SNMP_PRIV_AES;
+ else
+ return (SNMP_ERR_WRONG_VALUE);
+ break;
+
+ case LEAF_usmUserPrivKeyChange:
+ case LEAF_usmUserOwnPrivKeyChange:
+ if (val->var.subs[sub - 1] ==
+ LEAF_usmUserOwnPrivKeyChange &&
+ (usm_user == NULL || strcmp(uuser->suser.sec_name,
+ usm_user->suser.sec_name) != 0))
+ return (SNMP_ERR_NO_ACCESS);
+ if (val->v.octetstring.len > SNMP_PRIV_KEY_SIZ)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->ptr1 = malloc(SNMP_PRIV_KEY_SIZ);
+ if (ctx->scratch->ptr1 == NULL)
+ return (SNMP_ERR_GENERR);
+ memcpy(ctx->scratch->ptr1, uuser->suser.priv_key,
+ SNMP_PRIV_KEY_SIZ);
+ memcpy(uuser->suser.priv_key, val->v.octetstring.octets,
+ val->v.octetstring.len);
+ break;
+
+ case LEAF_usmUserPublic:
+ if (val->v.octetstring.len > SNMP_ADM_STR32_SIZ)
+ return (SNMP_ERR_INCONS_VALUE);
+ if (uuser->user_public_len > 0) {
+ ctx->scratch->ptr2 =
+ malloc(uuser->user_public_len);
+ if (ctx->scratch->ptr2 == NULL)
+ return (SNMP_ERR_GENERR);
+ memcpy(ctx->scratch->ptr2, uuser->user_public,
+ uuser->user_public_len);
+ ctx->scratch->int2 = uuser->user_public_len;
+ }
+ if (val->v.octetstring.len > 0) {
+ memcpy(uuser->user_public,
+ val->v.octetstring.octets,
+ val->v.octetstring.len);
+ uuser->user_public_len = val->v.octetstring.len;
+ } else {
+ memset(uuser->user_public, 0,
+ SNMP_ADM_STR32_SIZ);
+ uuser->user_public_len = 0;
+ }
+ break;
+
+ case LEAF_usmUserStorageType:
+ return (SNMP_ERR_INCONS_VALUE);
+
+ case LEAF_usmUserStatus:
+ if (uuser == NULL) {
+ if (val->v.integer != RowStatus_createAndWait ||
+ usm_user_index_decode(&val->var, sub, eid,
+ &elen, uname) < 0)
+ return (SNMP_ERR_INCONS_VALUE);
+ uuser = usm_new_user(eid, elen, uname);
+ if (uuser == NULL)
+ return (SNMP_ERR_GENERR);
+ uuser->status = RowStatus_notReady;
+ if (community != COMM_INITIALIZE)
+ uuser->type = StorageType_volatile;
+ else
+ uuser->type = StorageType_readOnly;
+ } else if (val->v.integer != RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+
+ uuser->status = val->v.integer;
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_usmUserAuthKeyChange:
+ case LEAF_usmUserOwnAuthKeyChange:
+ case LEAF_usmUserPrivKeyChange:
+ case LEAF_usmUserOwnPrivKeyChange:
+ free(ctx->scratch->ptr1);
+ break;
+ case LEAF_usmUserPublic:
+ if (ctx->scratch->ptr2 != NULL)
+ free(ctx->scratch->ptr2);
+ break;
+ case LEAF_usmUserStatus:
+ if (val->v.integer != RowStatus_destroy)
+ break;
+ if ((uuser = usm_get_user(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+ usm_delete_user(uuser);
+ break;
+ default:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_ROLLBACK:
+ if ((uuser = usm_get_user(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_usmUserAuthProtocol:
+ uuser->suser.auth_proto = ctx->scratch->int1;
+ break;
+ case LEAF_usmUserAuthKeyChange:
+ case LEAF_usmUserOwnAuthKeyChange:
+ memcpy(uuser->suser.auth_key, ctx->scratch->ptr1,
+ SNMP_AUTH_KEY_SIZ);
+ free(ctx->scratch->ptr1);
+ break;
+ case LEAF_usmUserPrivProtocol:
+ uuser->suser.priv_proto = ctx->scratch->int1;
+ break;
+ case LEAF_usmUserPrivKeyChange:
+ case LEAF_usmUserOwnPrivKeyChange:
+ memcpy(uuser->suser.priv_key, ctx->scratch->ptr1,
+ SNMP_AUTH_KEY_SIZ);
+ free(ctx->scratch->ptr1);
+ break;
+ case LEAF_usmUserPublic:
+ if (ctx->scratch->ptr2 != NULL) {
+ memcpy(uuser->user_public, ctx->scratch->ptr2,
+ ctx->scratch->int2);
+ uuser->user_public_len = ctx->scratch->int2;
+ free(ctx->scratch->ptr2);
+ } else {
+ memset(uuser->user_public, 0,
+ SNMP_ADM_STR32_SIZ);
+ uuser->user_public_len = 0;
+ }
+ break;
+ case LEAF_usmUserCloneFrom:
+ case LEAF_usmUserStatus:
+ if (ctx->scratch->int1 == RowStatus_createAndWait)
+ usm_delete_user(uuser);
+ break;
+ default:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ default:
+ abort();
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_usmUserSecurityName:
+ return (string_get(val, uuser->suser.sec_name, -1));
+ case LEAF_usmUserCloneFrom:
+ memcpy(&val->v.oid, &oid_zeroDotZero, sizeof(oid_zeroDotZero));
+ break;
+ case LEAF_usmUserAuthProtocol:
+ switch (uuser->suser.auth_proto) {
+ case SNMP_AUTH_HMAC_MD5:
+ memcpy(&val->v.oid, &oid_usmHMACMD5AuthProtocol,
+ sizeof(oid_usmHMACMD5AuthProtocol));
+ break;
+ case SNMP_AUTH_HMAC_SHA:
+ memcpy(&val->v.oid, &oid_usmHMACSHAAuthProtocol,
+ sizeof(oid_usmHMACSHAAuthProtocol));
+ break;
+ default:
+ memcpy(&val->v.oid, &oid_usmNoAuthProtocol,
+ sizeof(oid_usmNoAuthProtocol));
+ break;
+ }
+ break;
+ case LEAF_usmUserAuthKeyChange:
+ case LEAF_usmUserOwnAuthKeyChange:
+ return (string_get(val, (char *)uuser->suser.auth_key, 0));
+ case LEAF_usmUserPrivProtocol:
+ switch (uuser->suser.priv_proto) {
+ case SNMP_PRIV_DES:
+ memcpy(&val->v.oid, &oid_usmDESPrivProtocol,
+ sizeof(oid_usmDESPrivProtocol));
+ break;
+ case SNMP_PRIV_AES:
+ memcpy(&val->v.oid, &oid_usmAesCfb128Protocol,
+ sizeof(oid_usmAesCfb128Protocol));
+ break;
+ default:
+ memcpy(&val->v.oid, &oid_usmNoPrivProtocol,
+ sizeof(oid_usmNoPrivProtocol));
+ break;
+ }
+ break;
+ case LEAF_usmUserPrivKeyChange:
+ case LEAF_usmUserOwnPrivKeyChange:
+ return (string_get(val, (char *)uuser->suser.priv_key, 0));
+ case LEAF_usmUserPublic:
+ return (string_get(val, uuser->user_public,
+ uuser->user_public_len));
+ case LEAF_usmUserStorageType:
+ val->v.integer = uuser->type;
+ break;
+ case LEAF_usmUserStatus:
+ val->v.integer = uuser->status;
+ break;
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+static int
+usm_user_index_decode(const struct asn_oid *oid, uint sub, uint8_t *engine,
+ uint32_t *elen, char *uname)
+{
+ uint32_t i, nlen;
+ int uname_off;
+
+ if (oid->subs[sub] > SNMP_ENGINE_ID_SIZ)
+ return (-1);
+
+ for (i = 0; i < oid->subs[sub]; i++)
+ engine[i] = oid->subs[sub + i + 1];
+ *elen = i;
+
+ uname_off = sub + oid->subs[sub] + 1;
+ if ((nlen = oid->subs[uname_off]) >= SNMP_ADM_STR32_SIZ)
+ return (-1);
+
+ for (i = 0; i < nlen; i++)
+ uname[i] = oid->subs[uname_off + i + 1];
+ uname[nlen] = '\0';
+
+ return (0);
+}
+
+static void
+usm_append_userindex(struct asn_oid *oid, uint sub,
+ const struct usm_user *uuser)
+{
+ uint32_t i;
+
+ oid->len = sub + uuser->user_engine_len + strlen(uuser->suser.sec_name);
+ oid->len += 2;
+ oid->subs[sub] = uuser->user_engine_len;
+ for (i = 1; i < uuser->user_engine_len + 1; i++)
+ oid->subs[sub + i] = uuser->user_engine_id[i - 1];
+
+ sub += uuser->user_engine_len + 1;
+ oid->subs[sub] = strlen(uuser->suser.sec_name);
+ for (i = 1; i <= oid->subs[sub]; i++)
+ oid->subs[sub + i] = uuser->suser.sec_name[i - 1];
+}
+
+static struct usm_user *
+usm_get_user(const struct asn_oid *oid, uint sub)
+{
+ uint32_t enginelen;
+ char username[SNMP_ADM_STR32_SIZ];
+ uint8_t engineid[SNMP_ENGINE_ID_SIZ];
+
+ if (usm_user_index_decode(oid, sub, engineid, &enginelen, username) < 0)
+ return (NULL);
+
+ return (usm_find_user(engineid, enginelen, username));
+}
+
+static struct usm_user *
+usm_get_next_user(const struct asn_oid *oid, uint sub)
+{
+ uint32_t enginelen;
+ char username[SNMP_ADM_STR32_SIZ];
+ uint8_t engineid[SNMP_ENGINE_ID_SIZ];
+ struct usm_user *uuser;
+
+ if (oid->len - sub == 0)
+ return (usm_first_user());
+
+ if (usm_user_index_decode(oid, sub, engineid, &enginelen, username) < 0)
+ return (NULL);
+
+ if ((uuser = usm_find_user(engineid, enginelen, username)) != NULL)
+ return (usm_next_user(uuser));
+
+ return (NULL);
+}
+
+/*
+ * USM snmp module initialization hook.
+ * Returns 0 on success, < 0 on error.
+ */
+static int
+usm_init(struct lmodule * mod, int argc __unused, char *argv[] __unused)
+{
+ usm_module = mod;
+ usm_lock = random();
+ bsnmpd_reset_usm_stats();
+ return (0);
+}
+
+/*
+ * USM snmp module finalization hook.
+ */
+static int
+usm_fini(void)
+{
+ usm_flush_users();
+ or_unregister(reg_usm);
+
+ return (0);
+}
+
+/*
+ * USM snmp module start operation.
+ */
+static void
+usm_start(void)
+{
+ reg_usm = or_register(&oid_usm,
+ "The MIB module for managing SNMP User-Based Security Model.",
+ usm_module);
+}
+
+static void
+usm_dump(void)
+{
+ struct usm_user *uuser;
+ struct snmpd_usmstat *usmstats;
+ const char *const authstr[] = {
+ "noauth",
+ "md5",
+ "sha",
+ NULL
+ };
+ const char *const privstr[] = {
+ "nopriv",
+ "des",
+ "aes",
+ NULL
+ };
+
+ if ((usmstats = bsnmpd_get_usm_stats()) != NULL) {
+ syslog(LOG_ERR, "UnsupportedSecLevels\t\t%u",
+ usmstats->unsupported_seclevels);
+ syslog(LOG_ERR, "NotInTimeWindows\t\t%u",
+ usmstats->not_in_time_windows);
+ syslog(LOG_ERR, "UnknownUserNames\t\t%u",
+ usmstats->unknown_users);
+ syslog(LOG_ERR, "UnknownEngineIDs\t\t%u",
+ usmstats->unknown_engine_ids);
+ syslog(LOG_ERR, "WrongDigests\t\t%u",
+ usmstats->wrong_digests);
+ syslog(LOG_ERR, "DecryptionErrors\t\t%u",
+ usmstats->decrypt_errors);
+ }
+
+ syslog(LOG_ERR, "USM users");
+ for (uuser = usm_first_user(); uuser != NULL;
+ (uuser = usm_next_user(uuser)))
+ syslog(LOG_ERR, "user %s\t\t%s, %s", uuser->suser.sec_name,
+ authstr[uuser->suser.auth_proto],
+ privstr[uuser->suser.priv_proto]);
+}
+
+const char usm_comment[] = \
+"This module implements SNMP User-based Security Model defined in RFC 3414.";
+
+const struct snmp_module config = {
+ .comment = usm_comment,
+ .init = usm_init,
+ .fini = usm_fini,
+ .start = usm_start,
+ .tree = usm_ctree,
+ .dump = usm_dump,
+ .tree_size = usm_CTREE_SIZE,
+};
diff --git a/contrib/bsnmp/snmp_usm/usm_tree.def b/contrib/bsnmp/snmp_usm/usm_tree.def
new file mode 100755
index 0000000..8358d7b
--- /dev/null
+++ b/contrib/bsnmp/snmp_usm/usm_tree.def
@@ -0,0 +1,109 @@
+#-
+# Copyright (C) 2010 The FreeBSD Foundation
+# All rights reserved.
+#
+# This software was developed by Shteryana Sotirova Shopova under
+# sponsorship from the FreeBSD Foundation.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+typedef StorageType ENUM (
+ 1 other
+ 2 volatile
+ 3 nonVolatile
+ 4 permanent
+ 5 readOnly
+)
+
+typedef RowStatus ENUM (
+ 1 active
+ 2 notInService
+ 3 notReady
+ 4 createAndGo
+ 5 createAndWait
+ 6 destroy
+)
+
+(1 internet
+ (6 snmpV2
+ (3 snmpModules
+ (10 snmpFrameworkMIB
+ (1 snmpFrameworkAdmin
+ (1 snmpAuthProtocols
+ (1 usmNoAuthProtocol
+ )
+ (2 usmHMACMD5AuthProtocol
+ )
+ (3 usmHMACSHAAuthProtocol
+ )
+ )
+ (2 snmpPrivProtocols
+ (1 usmNoPrivProtocol
+ )
+ (2 usmDESPrivProtocol
+ )
+ (4 usmAesCfb128Protocol
+ )
+ )
+ )
+ )
+ (15 snmpUsmMIB
+ (1 usmMIBObjects
+ (1 usmStats
+ (1 usmStatsUnsupportedSecLevels COUNTER op_usm_stats GET)
+ (2 usmStatsNotInTimeWindows COUNTER op_usm_stats GET)
+ (3 usmStatsUnknownUserNames COUNTER op_usm_stats GET)
+ (4 usmStatsUnknownEngineIDs COUNTER op_usm_stats GET)
+ (5 usmStatsWrongDigests COUNTER op_usm_stats GET)
+ (6 usmStatsDecryptionErrors COUNTER op_usm_stats GET)
+ )
+ (2 usmUser
+ (1 usmUserSpinLock INTEGER op_usm_lock GET SET)
+ (2 usmUserTable
+ (1 usmUserEntry : OCTETSTRING | SnmpEngineID OCTETSTRING op_usm_users
+ (1 usmUserEngineID OCTETSTRING | SnmpEngineID)
+ (2 usmUserName OCTETSTRING)
+ (3 usmUserSecurityName OCTETSTRING | SnmpAdminString GET)
+ (4 usmUserCloneFrom OID GET SET)
+ (5 usmUserAuthProtocol OID GET SET)
+ (6 usmUserAuthKeyChange OCTETSTRING | KeyChange GET SET)
+ (7 usmUserOwnAuthKeyChange OCTETSTRING | KeyChange GET SET)
+ (8 usmUserPrivProtocol OID GET SET)
+ (9 usmUserPrivKeyChange OCTETSTRING | KeyChange GET SET)
+ (10 usmUserOwnPrivKeyChange OCTETSTRING | KeyChange GET SET)
+ (11 usmUserPublic OCTETSTRING GET SET)
+ (12 usmUserStorageType StorageType GET SET)
+ (13 usmUserStatus RowStatus GET SET)
+ )
+ )
+ )
+ )
+ )
+ (20 snmpUsmAesMIB
+ )
+ )
+ )
+)
+
diff --git a/contrib/bsnmp/snmp_vacm/snmp_vacm.3 b/contrib/bsnmp/snmp_vacm/snmp_vacm.3
new file mode 100755
index 0000000..9ad25be
--- /dev/null
+++ b/contrib/bsnmp/snmp_vacm/snmp_vacm.3
@@ -0,0 +1,94 @@
+.\"-
+.\" Copyright (C) 2010 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This documentation was written by Shteryana Sotirova Shopova under
+.\" sponsorship from the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 7, 2010
+.Dt SNMP_VACM 3
+.Os
+.Sh NAME
+.Nm snmp_vacm
+.Nd "View-based Access Control module for
+.Xr bsnmpd 1
+.Sh LIBRARY
+.Pq begemotSnmpdModulePath."vacm" = "/usr/lib/snmp_vacm.so"
+.Sh DESCRIPTION
+The
+.Nm snmp_vacm
+module implements SNMPv3 View-based Access Control Model MIB as defined in
+RFC 3415. The module is used to manage the internal lists of SNMPv1, v2c and
+v3 user names and groups and their access rights to fetch or modify the values
+of the MIB objects maintained by
+.Nm bsnmpd
+and the modules loaded in the daemon.
+The module must be loaded for
+.Nm bsnmpd
+to implement proper view-based access control. If the module is not loaded,
+access is granted to all configured SNMPv1 & SNMPv2c communities and SNMPv3
+USM users.
+.Sh IMPLEMENTATION NOTES
+An entry in any table implemented by this MIB may be created by setting the
+relevant RowStatus column to createAndGo (4) - in fact, any other value for
+those columns in a SET operation will cause an error. When an entry is created,
+any of its columns that is not used as index, is set to the default value as
+specified in the SNMP-VIEW-BASED-ACM-MIB. All entries maintained by the module
+are persistent after reboot if created via
+.Nm bsnmpd 's
+config file, otherwise entries created via SNMP are lost after reboot.
+A short description of the objects in the MIB follows.
+.Bl -tag -width "XXXXXXXXX"
+.It Va vacmContextTable
+A read-only table that consists of a list of SNMP contexts available in
+.Nm bsnmpd .
+.It Va vacmSecurityToGroupTable
+The table contains a list of SNMPv1, v2c and v3 user names and the groups
+they belong to.
+.It Va vacmAccessTable
+The table contains a list of SNMP contexts to groups mappings and respectively
+the names of the SNMP views under those contexts, to which users in the group
+are granted read-only, read-write access or receive notifications for the
+objects under the subtree in the relevant view.
+.It Va vacmViewTreeFamilyTable
+The table contains a list of SNMP views, i.e. entries specifying the OID of a
+MIB subtree and whether access to the objects under this subtree is to be
+allowed or forbiden.
+.El
+.Sh FILES
+.Bl -tag -width "XXXXXXXXX"
+.It Pa /usr/share/snmp/defs/vacm_tree.def
+The description of the MIB tree implemented by
+.Nm .
+.El
+.Sh SEE ALSO
+.Xr bsnmpd 1 ,
+.Xr gensnmptree 1 ,
+.Xr snmpmod 3
+.Sh STANDARDS
+IETF RFC 3415
+.Sh AUTHORS
+.An Shteryana Shopova Aq syrinx@FreeBSD.org
diff --git a/contrib/bsnmp/snmp_vacm/vacm_snmp.c b/contrib/bsnmp/snmp_vacm/vacm_snmp.c
new file mode 100755
index 0000000..cdec9f4
--- /dev/null
+++ b/contrib/bsnmp/snmp_vacm/vacm_snmp.c
@@ -0,0 +1,1026 @@
+/*-
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Shteryana Sotirova Shopova under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/queue.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmpmod.h"
+
+#include "vacm_tree.h"
+#include "vacm_oid.h"
+
+static struct lmodule *vacm_module;
+/* For the registration. */
+static const struct asn_oid oid_vacm = OIDX_snmpVacmMIB;
+
+static uint reg_vacm;
+
+static int32_t vacm_lock;
+
+/*
+ * Internal datastructures and forward declarations.
+ */
+static void vacm_append_userindex(struct asn_oid *,
+ uint, const struct vacm_user *);
+static int vacm_user_index_decode(const struct asn_oid *,
+ uint, int32_t *, char *);
+static struct vacm_user *vacm_get_user(const struct asn_oid *,
+ uint);
+static struct vacm_user *vacm_get_next_user(const struct asn_oid *,
+ uint);
+static void vacm_append_access_rule_index(struct asn_oid *,
+ uint, const struct vacm_access *);
+static int vacm_access_rule_index_decode(const struct asn_oid *,
+ uint, char *, char *, int32_t *, int32_t *);
+static struct vacm_access * vacm_get_access_rule(const struct asn_oid *,
+ uint);
+static struct vacm_access * vacm_get_next_access_rule(const struct asn_oid *,
+ uint);
+static int vacm_view_index_decode(const struct asn_oid *, uint,
+ char *, struct asn_oid *);
+static void vacm_append_viewindex(struct asn_oid *, uint,
+ const struct vacm_view *);
+static struct vacm_view *vacm_get_view(const struct asn_oid *, uint);
+static struct vacm_view *vacm_get_next_view(const struct asn_oid *, uint);
+static struct vacm_view *vacm_get_view_by_name(u_char *, u_int);
+static struct vacm_context *vacm_get_context(const struct asn_oid *, uint);
+static struct vacm_context *vacm_get_next_context(const struct asn_oid *,
+ uint);
+static void vacm_append_ctxindex(struct asn_oid *, uint,
+ const struct vacm_context *);
+
+int
+op_vacm_context(struct snmp_context *ctx __unused, struct snmp_value *val,
+ uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
+{
+ char cname[SNMP_ADM_STR32_SIZ];
+ size_t cnamelen;
+ struct vacm_context *vacm_ctx;
+
+ if (val->var.subs[sub - 1] != LEAF_vacmContextName)
+ abort();
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if ((vacm_ctx = vacm_get_context(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_GETNEXT:
+ if ((vacm_ctx = vacm_get_next_context(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ vacm_append_ctxindex(&val->var, sub, vacm_ctx);
+ break;
+
+ case SNMP_OP_SET:
+ if ((vacm_ctx = vacm_get_context(&val->var, sub)) != NULL)
+ return (SNMP_ERR_WRONG_VALUE);
+ if (community != COMM_INITIALIZE)
+ return (SNMP_ERR_NOT_WRITEABLE);
+ if (val->var.subs[sub] >= SNMP_ADM_STR32_SIZ)
+ return (SNMP_ERR_WRONG_VALUE);
+ if (index_decode(&val->var, sub, iidx, &cname, &cnamelen))
+ return (SNMP_ERR_GENERR);
+ cname[cnamelen] = '\0';
+ if ((vacm_ctx = vacm_add_context(cname, reg_vacm)) == NULL)
+ return (SNMP_ERR_GENERR);
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ /* FALLTHROUGH*/
+ case SNMP_OP_ROLLBACK:
+ return (SNMP_ERR_NOERROR);
+ default:
+ abort();
+ }
+
+ return (string_get(val, vacm_ctx->ctxname, -1));
+}
+
+int
+op_vacm_security_to_group(struct snmp_context *ctx, struct snmp_value *val,
+ uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
+{
+ int32_t smodel;
+ char uname[SNMP_ADM_STR32_SIZ];
+ struct vacm_user *user;
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if ((user = vacm_get_user(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_GETNEXT:
+ if ((user = vacm_get_next_user(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ vacm_append_userindex(&val->var, sub, user);
+ break;
+
+ case SNMP_OP_SET:
+ if ((user = vacm_get_user(&val->var, sub)) == NULL &&
+ val->var.subs[sub - 1] != LEAF_vacmSecurityToGroupStatus)
+ return (SNMP_ERR_NOSUCHNAME);
+
+ if (user != NULL) {
+ if (community != COMM_INITIALIZE &&
+ user->type == StorageType_readOnly)
+ return (SNMP_ERR_NOT_WRITEABLE);
+ if (user->status == RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_vacmGroupName:
+ ctx->scratch->ptr1 = user->group->groupname;
+ ctx->scratch->int1 = strlen(user->group->groupname);
+ return (vacm_user_set_group(user,
+ val->v.octetstring.octets,val->v.octetstring.len));
+
+ case LEAF_vacmSecurityToGroupStorageType:
+ return (SNMP_ERR_INCONS_VALUE);
+
+ case LEAF_vacmSecurityToGroupStatus:
+ if (user == NULL) {
+ if (val->v.integer != RowStatus_createAndGo ||
+ vacm_user_index_decode(&val->var, sub,
+ &smodel, uname) < 0)
+ return (SNMP_ERR_INCONS_VALUE);
+ user = vacm_new_user(smodel, uname);
+ if (user == NULL)
+ return (SNMP_ERR_GENERR);
+ user->status = RowStatus_destroy;
+ if (community != COMM_INITIALIZE)
+ user->type = StorageType_volatile;
+ else
+ user->type = StorageType_readOnly;
+ } else if (val->v.integer != RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = user->status;
+ user->status = val->v.integer;
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ if (val->var.subs[sub - 1] != LEAF_vacmSecurityToGroupStatus)
+ return (SNMP_ERR_NOERROR);
+ if ((user = vacm_get_user(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+ switch (val->v.integer) {
+ case RowStatus_destroy:
+ return (vacm_delete_user(user));
+
+ case RowStatus_createAndGo:
+ user->status = RowStatus_active;
+ break;
+
+ default:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_ROLLBACK:
+ if ((user = vacm_get_user(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_vacmGroupName:
+ return (vacm_user_set_group(user, ctx->scratch->ptr1,
+ ctx->scratch->int1));
+
+ case LEAF_vacmSecurityToGroupStatus:
+ if (ctx->scratch->int1 == RowStatus_destroy)
+ return (vacm_delete_user(user));
+ user->status = ctx->scratch->int1;
+ break;
+
+ default:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ default:
+ abort();
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_vacmGroupName:
+ return (string_get(val, user->group->groupname, -1));
+ case LEAF_vacmSecurityToGroupStorageType:
+ val->v.integer = user->type;
+ break;
+ case LEAF_vacmSecurityToGroupStatus:
+ val->v.integer = user->status;
+ break;
+ default:
+ abort();
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+int
+op_vacm_access(struct snmp_context *ctx, struct snmp_value *val, uint32_t sub,
+ uint32_t iidx __unused, enum snmp_op op)
+{
+ int32_t smodel, slevel;
+ char gname[SNMP_ADM_STR32_SIZ], cprefix[SNMP_ADM_STR32_SIZ];
+ struct vacm_access *acl;
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if ((acl = vacm_get_access_rule(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_GETNEXT:
+ if ((acl = vacm_get_next_access_rule(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ vacm_append_access_rule_index(&val->var, sub, acl);
+ break;
+
+ case SNMP_OP_SET:
+ if ((acl = vacm_get_access_rule(&val->var, sub)) == NULL &&
+ val->var.subs[sub - 1] != LEAF_vacmAccessStatus)
+ return (SNMP_ERR_NOSUCHNAME);
+ if (acl != NULL && community != COMM_INITIALIZE &&
+ acl->type == StorageType_readOnly)
+ return (SNMP_ERR_NOT_WRITEABLE);
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_vacmAccessContextMatch:
+ ctx->scratch->int1 = acl->ctx_match;
+ if (val->v.integer == vacmAccessContextMatch_exact)
+ acl->ctx_match = 1;
+ else if (val->v.integer == vacmAccessContextMatch_prefix)
+ acl->ctx_match = 0;
+ else
+ return (SNMP_ERR_WRONG_VALUE);
+ break;
+
+ case LEAF_vacmAccessReadViewName:
+ ctx->scratch->ptr1 = acl->read_view;
+ acl->read_view = vacm_get_view_by_name(val->v.octetstring.octets, val->v.octetstring.len);
+ if (acl->read_view == NULL) {
+ acl->read_view = ctx->scratch->ptr1;
+ return (SNMP_ERR_INCONS_VALUE);
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case LEAF_vacmAccessWriteViewName:
+ ctx->scratch->ptr1 = acl->write_view;
+ if ((acl->write_view =
+ vacm_get_view_by_name(val->v.octetstring.octets,
+ val->v.octetstring.len)) == NULL) {
+ acl->write_view = ctx->scratch->ptr1;
+ return (SNMP_ERR_INCONS_VALUE);
+ }
+ break;
+
+ case LEAF_vacmAccessNotifyViewName:
+ ctx->scratch->ptr1 = acl->notify_view;
+ if ((acl->notify_view =
+ vacm_get_view_by_name(val->v.octetstring.octets,
+ val->v.octetstring.len)) == NULL) {
+ acl->notify_view = ctx->scratch->ptr1;
+ return (SNMP_ERR_INCONS_VALUE);
+ }
+ break;
+
+ case LEAF_vacmAccessStorageType:
+ return (SNMP_ERR_INCONS_VALUE);
+
+ case LEAF_vacmAccessStatus:
+ if (acl == NULL) {
+ if (val->v.integer != RowStatus_createAndGo ||
+ vacm_access_rule_index_decode(&val->var,
+ sub, gname, cprefix, &smodel, &slevel) < 0)
+ return (SNMP_ERR_INCONS_VALUE);
+ if ((acl = vacm_new_access_rule(gname, cprefix,
+ smodel, slevel)) == NULL)
+ return (SNMP_ERR_GENERR);
+ acl->status = RowStatus_destroy;
+ if (community != COMM_INITIALIZE)
+ acl->type = StorageType_volatile;
+ else
+ acl->type = StorageType_readOnly;
+ } else if (val->v.integer != RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = acl->status;
+ acl->status = val->v.integer;
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ if (val->var.subs[sub - 1] != LEAF_vacmAccessStatus)
+ return (SNMP_ERR_NOERROR);
+ if ((acl = vacm_get_access_rule(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+ if (val->v.integer == RowStatus_destroy)
+ return (vacm_delete_access_rule(acl));
+ else
+ acl->status = RowStatus_active;
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_ROLLBACK:
+ if ((acl = vacm_get_access_rule(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_vacmAccessContextMatch:
+ acl->ctx_match = ctx->scratch->int1;
+ break;
+ case LEAF_vacmAccessReadViewName:
+ acl->read_view = ctx->scratch->ptr1;
+ break;
+ case LEAF_vacmAccessWriteViewName:
+ acl->write_view = ctx->scratch->ptr1;
+ break;
+ case LEAF_vacmAccessNotifyViewName:
+ acl->notify_view = ctx->scratch->ptr1;
+ break;
+ case LEAF_vacmAccessStatus:
+ if (ctx->scratch->int1 == RowStatus_destroy)
+ return (vacm_delete_access_rule(acl));
+ default:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ default:
+ abort();
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_vacmAccessContextMatch:
+ return (string_get(val, acl->ctx_prefix, -1));
+ case LEAF_vacmAccessReadViewName:
+ if (acl->read_view != NULL)
+ return (string_get(val, acl->read_view->viewname, -1));
+ else
+ return (string_get(val, NULL, 0));
+ case LEAF_vacmAccessWriteViewName:
+ if (acl->write_view != NULL)
+ return (string_get(val, acl->write_view->viewname, -1));
+ else
+ return (string_get(val, NULL, 0));
+ case LEAF_vacmAccessNotifyViewName:
+ if (acl->notify_view != NULL)
+ return (string_get(val, acl->notify_view->viewname, -1));
+ else
+ return (string_get(val, NULL, 0));
+ case LEAF_vacmAccessStorageType:
+ val->v.integer = acl->type;
+ break;
+ case LEAF_vacmAccessStatus:
+ val->v.integer = acl->status;
+ break;
+ default:
+ abort();
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+int
+op_vacm_view_lock(struct snmp_context *ctx __unused, struct snmp_value *val,
+ uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
+{
+ if (val->var.subs[sub - 1] != LEAF_vacmViewSpinLock)
+ return (SNMP_ERR_NOSUCHNAME);
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if (++vacm_lock == INT32_MAX)
+ vacm_lock = 0;
+ val->v.integer = vacm_lock;
+ break;
+
+ case SNMP_OP_GETNEXT:
+ abort();
+
+ case SNMP_OP_SET:
+ if (val->v.integer != vacm_lock)
+ return (SNMP_ERR_INCONS_VALUE);
+ break;
+
+ case SNMP_OP_ROLLBACK:
+ /* FALLTHROUGH */
+ case SNMP_OP_COMMIT:
+ break;
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+int
+op_vacm_view(struct snmp_context *ctx, struct snmp_value *val, uint32_t sub,
+ uint32_t iidx __unused, enum snmp_op op)
+{
+ char vname[SNMP_ADM_STR32_SIZ];
+ struct asn_oid oid;
+ struct vacm_view *view;
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if ((view = vacm_get_view(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_GETNEXT:
+ if ((view = vacm_get_next_view(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ vacm_append_viewindex(&val->var, sub, view);
+ break;
+
+ case SNMP_OP_SET:
+ if ((view = vacm_get_view(&val->var, sub)) == NULL &&
+ val->var.subs[sub - 1] != LEAF_vacmViewTreeFamilyStatus)
+ return (SNMP_ERR_NOSUCHNAME);
+
+ if (view != NULL) {
+ if (community != COMM_INITIALIZE &&
+ view->type == StorageType_readOnly)
+ return (SNMP_ERR_NOT_WRITEABLE);
+ if (view->status == RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_vacmViewTreeFamilyMask:
+ if (val->v.octetstring.len > sizeof(view->mask))
+ ctx->scratch->ptr1 = malloc(sizeof(view->mask));
+ if (ctx->scratch->ptr1 == NULL)
+ return (SNMP_ERR_GENERR);
+ memset(ctx->scratch->ptr1, 0, sizeof(view->mask));
+ memcpy(ctx->scratch->ptr1, view->mask,
+ sizeof(view->mask));
+ memset(view->mask, 0, sizeof(view->mask));
+ memcpy(view->mask, val->v.octetstring.octets,
+ val->v.octetstring.len);
+ break;
+
+ case LEAF_vacmViewTreeFamilyType:
+ ctx->scratch->int1 = view->exclude;
+ if (val->v.integer == vacmViewTreeFamilyType_included)
+ view->exclude = 0;
+ else if (val->v.integer == vacmViewTreeFamilyType_excluded)
+ view->exclude = 1;
+ else
+ return (SNMP_ERR_WRONG_VALUE);
+ break;
+
+ case LEAF_vacmViewTreeFamilyStorageType:
+ return (SNMP_ERR_INCONS_VALUE);
+
+ case LEAF_vacmViewTreeFamilyStatus:
+ if (view == NULL) {
+ if (val->v.integer != RowStatus_createAndGo ||
+ vacm_view_index_decode(&val->var, sub, vname,
+ &oid) < 0)
+ return (SNMP_ERR_INCONS_VALUE);
+ if ((view = vacm_new_view(vname, &oid)) == NULL)
+ return (SNMP_ERR_GENERR);
+ view->status = RowStatus_destroy;
+ if (community != COMM_INITIALIZE)
+ view->type = StorageType_volatile;
+ else
+ view->type = StorageType_readOnly;
+ } else if (val->v.integer != RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = view->status;
+ view->status = val->v.integer;
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_vacmViewTreeFamilyMask:
+ free(ctx->scratch->ptr1);
+ break;
+ case LEAF_vacmViewTreeFamilyStatus:
+ if ((view = vacm_get_view(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+ switch (val->v.integer) {
+ case RowStatus_destroy:
+ return (vacm_delete_view(view));
+
+ case RowStatus_createAndGo:
+ view->status = RowStatus_active;
+ break;
+
+ default:
+ /* NOTREACHED*/
+ return (SNMP_ERR_GENERR);
+ }
+ default:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_ROLLBACK:
+ if ((view = vacm_get_view(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_vacmViewTreeFamilyMask:
+ memcpy(view->mask, ctx->scratch->ptr1,
+ sizeof(view->mask));
+ free(ctx->scratch->ptr1);
+ break;
+ case LEAF_vacmViewTreeFamilyType:
+ view->exclude = ctx->scratch->int1;
+ break;
+ case LEAF_vacmViewTreeFamilyStatus:
+ if (ctx->scratch->int1 == RowStatus_destroy)
+ return (vacm_delete_view(view));
+ break;
+ default:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ default:
+ abort();
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_vacmViewTreeFamilyMask:
+ return (string_get(val, view->mask, sizeof(view->mask)));
+ case LEAF_vacmViewTreeFamilyType:
+ if (view->exclude)
+ val->v.integer = vacmViewTreeFamilyType_excluded;
+ else
+ val->v.integer = vacmViewTreeFamilyType_included;
+ break;
+ case LEAF_vacmViewTreeFamilyStorageType:
+ val->v.integer = view->type;
+ break;
+ case LEAF_vacmViewTreeFamilyStatus:
+ val->v.integer = view->status;
+ break;
+ default:
+ abort();
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+static void
+vacm_append_userindex(struct asn_oid *oid, uint sub,
+ const struct vacm_user *user)
+{
+ uint32_t i;
+
+ oid->len = sub + strlen(user->secname) + 2;
+ oid->subs[sub++] = user->sec_model;
+ oid->subs[sub] = strlen(user->secname);
+ for (i = 1; i <= strlen(user->secname); i++)
+ oid->subs[sub + i] = user->secname[i - 1];
+}
+
+static int
+vacm_user_index_decode(const struct asn_oid *oid, uint sub,
+ int32_t *smodel, char *uname)
+{
+ uint32_t i;
+
+ *smodel = oid->subs[sub++];
+
+ if (oid->subs[sub] >= SNMP_ADM_STR32_SIZ)
+ return (-1);
+
+ for (i = 0; i < oid->subs[sub]; i++)
+ uname[i] = oid->subs[sub + i + 1];
+ uname[i] = '\0';
+
+ return (0);
+}
+
+static struct vacm_user *
+vacm_get_user(const struct asn_oid *oid, uint sub)
+{
+ int32_t smodel;
+ char uname[SNMP_ADM_STR32_SIZ];
+ struct vacm_user *user;
+
+ if (vacm_user_index_decode(oid, sub, &smodel, uname) < 0)
+ return (NULL);
+
+ for (user = vacm_first_user(); user != NULL; user = vacm_next_user(user))
+ if (strcmp(uname, user->secname) == 0 &&
+ user->sec_model == smodel)
+ return (user);
+
+ return (NULL);
+}
+
+static struct vacm_user *
+vacm_get_next_user(const struct asn_oid *oid, uint sub)
+{
+ int32_t smodel;
+ char uname[SNMP_ADM_STR32_SIZ];
+ struct vacm_user *user;
+
+ if (oid->len - sub == 0)
+ return (vacm_first_user());
+
+ if (vacm_user_index_decode(oid, sub, &smodel, uname) < 0)
+ return (NULL);
+
+ for (user = vacm_first_user(); user != NULL; user = vacm_next_user(user))
+ if (strcmp(uname, user->secname) == 0 &&
+ user->sec_model == smodel)
+ return (vacm_next_user(user));
+
+ return (NULL);
+}
+
+static void
+vacm_append_access_rule_index(struct asn_oid *oid, uint sub,
+ const struct vacm_access *acl)
+{
+ uint32_t i;
+
+ oid->len = sub + strlen(acl->group->groupname) +
+ strlen(acl->ctx_prefix) + 4;
+
+ oid->subs[sub] = strlen(acl->group->groupname);
+ for (i = 1; i <= strlen(acl->group->groupname); i++)
+ oid->subs[sub + i] = acl->group->groupname[i - 1];
+ sub += strlen(acl->group->groupname) + 1;
+
+ oid->subs[sub] = strlen(acl->ctx_prefix);
+ for (i = 1; i <= strlen(acl->ctx_prefix); i++)
+ oid->subs[sub + i] = acl->ctx_prefix[i - 1];
+ sub += strlen(acl->ctx_prefix) + 1;
+ oid->subs[sub++] = acl->sec_model;
+ oid->subs[sub] = acl->sec_level;
+}
+
+static int
+vacm_access_rule_index_decode(const struct asn_oid *oid, uint sub, char *gname,
+ char *cprefix, int32_t *smodel, int32_t *slevel)
+{
+ uint32_t i;
+
+ if (oid->subs[sub] >= SNMP_ADM_STR32_SIZ)
+ return (-1);
+
+ for (i = 0; i < oid->subs[sub]; i++)
+ gname[i] = oid->subs[sub + i + 1];
+ gname[i] = '\0';
+ sub += strlen(gname) + 1;
+
+ if (oid->subs[sub] >= SNMP_ADM_STR32_SIZ)
+ return (-1);
+
+ for (i = 0; i < oid->subs[sub]; i++)
+ cprefix[i] = oid->subs[sub + i + 1];
+ cprefix[i] = '\0';
+ sub += strlen(cprefix) + 1;
+
+ *smodel = oid->subs[sub++];
+ *slevel = oid->subs[sub];
+
+ return (0);
+}
+
+struct vacm_access *
+vacm_get_access_rule(const struct asn_oid *oid, uint sub)
+{
+ int32_t smodel, slevel;
+ char gname[SNMP_ADM_STR32_SIZ], prefix[SNMP_ADM_STR32_SIZ];
+ struct vacm_access *acl;
+
+ if (vacm_access_rule_index_decode(oid, sub, gname, prefix, &smodel,
+ &slevel) < 0)
+ return (NULL);
+
+ for (acl = vacm_first_access_rule(); acl != NULL;
+ acl = vacm_next_access_rule(acl))
+ if (strcmp(gname, acl->group->groupname) == 0 &&
+ strcmp(prefix, acl->ctx_prefix) == 0 &&
+ smodel == acl->sec_model && slevel == acl->sec_level)
+ return (acl);
+
+ return (NULL);
+}
+
+struct vacm_access *
+vacm_get_next_access_rule(const struct asn_oid *oid __unused, uint sub __unused)
+{
+ int32_t smodel, slevel;
+ char gname[SNMP_ADM_STR32_SIZ], prefix[SNMP_ADM_STR32_SIZ];
+ struct vacm_access *acl;
+
+ if (oid->len - sub == 0)
+ return (vacm_first_access_rule());
+
+ if (vacm_access_rule_index_decode(oid, sub, gname, prefix, &smodel,
+ &slevel) < 0)
+ return (NULL);
+
+ for (acl = vacm_first_access_rule(); acl != NULL;
+ acl = vacm_next_access_rule(acl))
+ if (strcmp(gname, acl->group->groupname) == 0 &&
+ strcmp(prefix, acl->ctx_prefix) == 0 &&
+ smodel == acl->sec_model && slevel == acl->sec_model)
+ return (vacm_next_access_rule(acl));
+
+ return (NULL);
+}
+
+static int
+vacm_view_index_decode(const struct asn_oid *oid, uint sub, char *vname,
+ struct asn_oid *view_oid)
+{
+ uint32_t i;
+ int viod_off;
+
+ if (oid->subs[sub] >= SNMP_ADM_STR32_SIZ)
+ return (-1);
+
+ for (i = 0; i < oid->subs[sub]; i++)
+ vname[i] = oid->subs[sub + i + 1];
+ vname[i] = '\0';
+
+ viod_off = sub + oid->subs[sub] + 1;
+ if ((view_oid->len = oid->subs[viod_off]) > ASN_MAXOIDLEN)
+ return (-1);
+
+ memcpy(&view_oid->subs[0], &oid->subs[viod_off + 1],
+ view_oid->len * sizeof(view_oid->subs[0]));
+
+ return (0);
+}
+
+static void
+vacm_append_viewindex(struct asn_oid *oid, uint sub, const struct vacm_view *view)
+{
+ uint32_t i;
+
+ oid->len = sub + strlen(view->viewname) + 1;
+ oid->subs[sub] = strlen(view->viewname);
+ for (i = 1; i <= strlen(view->viewname); i++)
+ oid->subs[sub + i] = view->viewname[i - 1];
+
+ sub += strlen(view->viewname) + 1;
+ oid->subs[sub] = view->subtree.len;
+ oid->len++;
+ asn_append_oid(oid, &view->subtree);
+}
+
+struct vacm_view *
+vacm_get_view(const struct asn_oid *oid, uint sub)
+{
+ char vname[SNMP_ADM_STR32_SIZ];
+ struct asn_oid subtree;
+ struct vacm_view *view;
+
+ if (vacm_view_index_decode(oid, sub, vname, &subtree) < 0)
+ return (NULL);
+
+ for (view = vacm_first_view(); view != NULL; view = vacm_next_view(view))
+ if (strcmp(vname, view->viewname) == 0 &&
+ asn_compare_oid(&subtree, &view->subtree)== 0)
+ return (view);
+
+ return (NULL);
+}
+
+struct vacm_view *
+vacm_get_next_view(const struct asn_oid *oid, uint sub)
+{
+ char vname[SNMP_ADM_STR32_SIZ];
+ struct asn_oid subtree;
+ struct vacm_view *view;
+
+ if (oid->len - sub == 0)
+ return (vacm_first_view());
+
+ if (vacm_view_index_decode(oid, sub, vname, &subtree) < 0)
+ return (NULL);
+
+ for (view = vacm_first_view(); view != NULL; view = vacm_next_view(view))
+ if (strcmp(vname, view->viewname) == 0 &&
+ asn_compare_oid(&subtree, &view->subtree)== 0)
+ return (vacm_next_view(view));
+
+ return (NULL);
+}
+
+static struct vacm_view *
+vacm_get_view_by_name(u_char *octets, u_int len)
+{
+ struct vacm_view *view;
+
+ for (view = vacm_first_view(); view != NULL; view = vacm_next_view(view))
+ if (strlen(view->viewname) == len &&
+ memcmp(octets, view->viewname, len) == 0)
+ return (view);
+
+ return (NULL);
+}
+
+static struct vacm_context *
+vacm_get_context(const struct asn_oid *oid, uint sub)
+{
+ char cname[SNMP_ADM_STR32_SIZ];
+ size_t cnamelen;
+ u_int index_count;
+ struct vacm_context *vacm_ctx;
+
+ if (oid->subs[sub] >= SNMP_ADM_STR32_SIZ)
+ return (NULL);
+
+ index_count = 0;
+ index_count = SNMP_INDEX(index_count, 1);
+ if (index_decode(oid, sub, index_count, &cname, &cnamelen))
+ return (NULL);
+
+ for (vacm_ctx = vacm_first_context(); vacm_ctx != NULL;
+ vacm_ctx = vacm_next_context(vacm_ctx))
+ if (strcmp(cname, vacm_ctx->ctxname) == 0)
+ return (vacm_ctx);
+
+ return (NULL);
+}
+
+static struct vacm_context *
+vacm_get_next_context(const struct asn_oid *oid, uint sub)
+{
+ char cname[SNMP_ADM_STR32_SIZ];
+ size_t cnamelen;
+ u_int index_count;
+ struct vacm_context *vacm_ctx;
+
+ if (oid->len - sub == 0)
+ return (vacm_first_context());
+
+ if (oid->subs[sub] >= SNMP_ADM_STR32_SIZ)
+ return (NULL);
+
+ index_count = 0;
+ index_count = SNMP_INDEX(index_count, 1);
+ if (index_decode(oid, sub, index_count, &cname, &cnamelen))
+ return (NULL);
+
+ for (vacm_ctx = vacm_first_context(); vacm_ctx != NULL;
+ vacm_ctx = vacm_next_context(vacm_ctx))
+ if (strcmp(cname, vacm_ctx->ctxname) == 0)
+ return (vacm_next_context(vacm_ctx));
+
+ return (NULL);
+}
+
+static void
+vacm_append_ctxindex(struct asn_oid *oid, uint sub,
+ const struct vacm_context *ctx)
+{
+ uint32_t i;
+
+ oid->len = sub + strlen(ctx->ctxname) + 1;
+ oid->subs[sub] = strlen(ctx->ctxname);
+ for (i = 1; i <= strlen(ctx->ctxname); i++)
+ oid->subs[sub + i] = ctx->ctxname[i - 1];
+}
+
+/*
+ * VACM snmp module initialization hook.
+ * Returns 0 on success, < 0 on error.
+ */
+static int
+vacm_init(struct lmodule *mod, int argc __unused, char *argv[] __unused)
+{
+ vacm_module = mod;
+ vacm_lock = random();
+ vacm_groups_init();
+
+ /* XXX: TODO - initialize structures */
+ return (0);
+}
+
+/*
+ * VACM snmp module finalization hook.
+ */
+static int
+vacm_fini(void)
+{
+ /* XXX: TODO - cleanup */
+ vacm_flush_contexts(reg_vacm);
+ or_unregister(reg_vacm);
+
+ return (0);
+}
+
+/*
+ * VACM snmp module start operation.
+ */
+static void
+vacm_start(void)
+{
+ static char dflt_ctx[] = "";
+
+ reg_vacm = or_register(&oid_vacm,
+ "The MIB module for managing SNMP View-based Access Control Model.",
+ vacm_module);
+
+ (void)vacm_add_context(dflt_ctx, reg_vacm);
+}
+
+static void
+vacm_dump(void)
+{
+ struct vacm_context *vacmctx;
+ struct vacm_user *vuser;
+ struct vacm_access *vacl;
+ struct vacm_view *view;
+ static char oidbuf[ASN_OIDSTRLEN];
+
+ syslog(LOG_ERR, "\n");
+ syslog(LOG_ERR, "Context list:");
+ for (vacmctx = vacm_first_context(); vacmctx != NULL;
+ vacmctx = vacm_next_context(vacmctx))
+ syslog(LOG_ERR, "Context \"%s\", module id %d",
+ vacmctx->ctxname, vacmctx->regid);
+
+ syslog(LOG_ERR, "VACM users:");
+ for (vuser = vacm_first_user(); vuser != NULL;
+ vuser = vacm_next_user(vuser))
+ syslog(LOG_ERR, "Uname %s, Group %s, model %d", vuser->secname,
+ vuser->group!= NULL?vuser->group->groupname:"Unknown",
+ vuser->sec_model);
+
+ syslog(LOG_ERR, "VACM Access rules:");
+ for (vacl = vacm_first_access_rule(); vacl != NULL;
+ vacl = vacm_next_access_rule(vacl))
+ syslog(LOG_ERR, "Group %s, CtxPrefix %s, Model %d, Level %d, "
+ "RV %s, WR %s, NV %s", vacl->group!=NULL?
+ vacl->group->groupname:"Unknown", vacl->ctx_prefix,
+ vacl->sec_model, vacl->sec_level, vacl->read_view!=NULL?
+ vacl->read_view->viewname:"None", vacl->write_view!=NULL?
+ vacl->write_view->viewname:"None", vacl->notify_view!=NULL?
+ vacl->notify_view->viewname:"None");
+
+ syslog(LOG_ERR, "VACM Views:");
+ for (view = vacm_first_view(); view != NULL; view = vacm_next_view(view))
+ syslog(LOG_ERR, "View %s, Tree %s - %s", view->viewname,
+ asn_oid2str_r(&view->subtree, oidbuf), view->exclude?
+ "excluded":"included");
+}
+
+const char vacm_comment[] = \
+"This module implements SNMP View-based Access Control Model defined in RFC 3415.";
+
+const struct snmp_module config = {
+ .comment = vacm_comment,
+ .init = vacm_init,
+ .fini = vacm_fini,
+ .start = vacm_start,
+ .tree = vacm_ctree,
+ .dump = vacm_dump,
+ .tree_size = vacm_CTREE_SIZE,
+};
diff --git a/contrib/bsnmp/snmp_vacm/vacm_tree.def b/contrib/bsnmp/snmp_vacm/vacm_tree.def
new file mode 100755
index 0000000..db70f7d
--- /dev/null
+++ b/contrib/bsnmp/snmp_vacm/vacm_tree.def
@@ -0,0 +1,104 @@
+#-
+# Copyright (C) 2010 The FreeBSD Foundation
+# All rights reserved.
+#
+# This software was developed by Shteryana Sotirova Shopova under
+# sponsorship from the FreeBSD Foundation.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+typedef StorageType ENUM (
+ 1 other
+ 2 volatile
+ 3 nonVolatile
+ 4 permanent
+ 5 readOnly
+)
+
+typedef RowStatus ENUM (
+ 1 active
+ 2 notInService
+ 3 notReady
+ 4 createAndGo
+ 5 createAndWait
+ 6 destroy
+)
+
+(1 internet
+ (6 snmpV2
+ (3 snmpModules
+ (16 snmpVacmMIB
+ (1 vacmMIBObjects
+ (1 vacmContextTable
+ (1 vacmContextEntry : OCTETSTRING op_vacm_context
+ (1 vacmContextName OCTETSTRING GET)
+ )
+ )
+ (2 vacmSecurityToGroupTable
+ (1 vacmSecurityToGroupEntry : INTEGER OCTETSTRING op_vacm_security_to_group
+ (1 vacmSecurityModel INTEGER)
+ (2 vacmSecurityName OCTETSTRING)
+ (3 vacmGroupName OCTETSTRING GET SET)
+ (4 vacmSecurityToGroupStorageType StorageType GET SET)
+ (5 vacmSecurityToGroupStatus RowStatus GET SET)
+ )
+ )
+ (4 vacmAccessTable
+ (1 vacmAccessEntry : OCTETSTRING OCTETSTRING INTEGER ENUM ( 1 noAuthNoPriv 2 authNoPriv 3 authPriv ) op_vacm_access
+ (1 vacmAccessContextPrefix OCTETSTRING)
+ (2 vacmAccessSecurityModel INTEGER)
+ (3 vacmAccessSecurityLevel ENUM ( 1 noAuthNoPriv 2 authNoPriv 3 authPriv ))
+ (4 vacmAccessContextMatch ENUM ( 1 exact 2 prefix ) GET SET)
+ (5 vacmAccessReadViewName OCTETSTRING GET SET)
+ (6 vacmAccessWriteViewName OCTETSTRING GET SET)
+ (7 vacmAccessNotifyViewName OCTETSTRING GET SET)
+ (8 vacmAccessStorageType StorageType GET SET)
+ (9 vacmAccessStatus RowStatus GET SET)
+ )
+ )
+ (5 vacmMIBViews
+ (1 vacmViewSpinLock INTEGER op_vacm_view_lock GET SET)
+ (2 vacmViewTreeFamilyTable
+ (1 vacmViewTreeFamilyEntry : OCTETSTRING OID op_vacm_view
+ (1 vacmViewTreeFamilyViewName OCTETSTRING)
+ (2 vacmViewTreeFamilySubtree OID)
+ (3 vacmViewTreeFamilyMask OCTETSTRING GET SET)
+ (4 vacmViewTreeFamilyType ENUM ( 1 included 2 excluded ) GET SET)
+ (5 vacmViewTreeFamilyStorageType StorageType GET SET)
+ (6 vacmViewTreeFamilyStatus RowStatus GET SET)
+ )
+ )
+ )
+ )
+ (2 vacmMIBConformance
+ (1 vacmMIBCompliances
+ )
+ (2 vacmMIBGroups
+ )
+ )
+ )
+ )
+ )
+)
diff --git a/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt b/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt
index 40b2cf0..3262ada 100644
--- a/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt
+++ b/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt
@@ -139,7 +139,8 @@ begemotSnmpdVersionEnable OBJECT-TYPE
bits are defined:
0x00000001 - SNMPv1
- 0x00000002 - SNMPv2c"
+ 0x00000002 - SNMPv2c
+ 0x00000004 - SNMPv3"
DEFVAL { 3 }
::= { begemotSnmpdConfig 5 }
diff --git a/contrib/bsnmp/snmpd/action.c b/contrib/bsnmp/snmpd/action.c
index 3d91ce3..ebba0f5 100644
--- a/contrib/bsnmp/snmpd/action.c
+++ b/contrib/bsnmp/snmpd/action.c
@@ -34,6 +34,7 @@
* Variable access for SNMPd
*/
#include <sys/types.h>
+#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/un.h>
#include <sys/utsname.h>
@@ -42,6 +43,7 @@
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
+#include <errno.h>
#include <syslog.h>
#include "snmpmod.h"
@@ -162,7 +164,83 @@ init_actvals(void)
return (0);
}
+/*
+ * Initialize global variables of the snmpEngine group.
+ */
+int
+init_snmpd_engine(void)
+{
+ char *hostid;
+
+ snmpd_engine.engine_boots = 1;
+ snmpd_engine.engine_time = 1;
+ snmpd_engine.max_msg_size = 1500; /* XXX */
+
+ snmpd_engine.engine_id[0] = ((OID_freeBSD & 0xff000000) >> 24) | 0x80;
+ snmpd_engine.engine_id[1] = (OID_freeBSD & 0xff0000) >> 16;
+ snmpd_engine.engine_id[2] = (OID_freeBSD & 0xff00) >> 8;
+ snmpd_engine.engine_id[3] = OID_freeBSD & 0xff;
+ snmpd_engine.engine_id[4] = 128;
+ snmpd_engine.engine_len = 5;
+
+ if ((hostid = act_getkernint(KERN_HOSTID)) == NULL)
+ return (-1);
+
+ if (strlen(hostid) > SNMP_ENGINE_ID_SIZ - snmpd_engine.engine_len) {
+ memcpy(snmpd_engine.engine_id + snmpd_engine.engine_len,
+ hostid, SNMP_ENGINE_ID_SIZ - snmpd_engine.engine_len);
+ snmpd_engine.engine_len = SNMP_ENGINE_ID_SIZ;
+ } else {
+ memcpy(snmpd_engine.engine_id + snmpd_engine.engine_len,
+ hostid, strlen(hostid));
+ snmpd_engine.engine_len += strlen(hostid);
+ }
+
+ free(hostid);
+
+ return (0);
+}
+
+int
+set_snmpd_engine(void)
+{
+ FILE *fp;
+ uint32_t i;
+ uint8_t *cptr, engine[2 * SNMP_ENGINE_ID_SIZ + 2];
+ uint8_t myengine[2 * SNMP_ENGINE_ID_SIZ + 2];
+
+ if (engine_file[0] == '\0')
+ return (-1);
+
+ cptr = myengine;
+ for (i = 0; i < snmpd_engine.engine_len; i++)
+ cptr += sprintf(cptr, "%.2x", snmpd_engine.engine_id[i]);
+ *cptr++ = '\n';
+ *cptr++ = '\0';
+
+ if ((fp = fopen(engine_file, "r+")) != NULL) {
+ if (fgets(engine, sizeof(engine) - 1, fp) == NULL ||
+ fscanf(fp, "%u", &snmpd_engine.engine_boots) <= 0) {
+ fclose(fp);
+ goto save_boots;
+ }
+ fclose(fp);
+ if (strcmp(myengine, engine) != 0)
+ snmpd_engine.engine_boots = 1;
+ else
+ snmpd_engine.engine_boots++;
+ } else if (errno != ENOENT)
+ return (-1);
+
+save_boots:
+ if ((fp = fopen(engine_file, "w+")) == NULL)
+ return (-1);
+ fprintf(fp, "%s%u\n", myengine, snmpd_engine.engine_boots);
+ fclose(fp);
+
+ return (0);
+}
/*************************************************************
*
@@ -980,6 +1058,103 @@ op_snmp_set(struct snmp_context *ctx __unused, struct snmp_value *value,
}
/*
+ * SNMP Engine
+ */
+int
+op_snmp_engine(struct snmp_context *ctx __unused, struct snmp_value *value,
+ u_int sub, u_int iidx __unused, enum snmp_op op)
+{
+ asn_subid_t which = value->var.subs[sub - 1];
+
+ switch (op) {
+ case SNMP_OP_GETNEXT:
+ abort();
+
+ case SNMP_OP_GET:
+ break;
+
+ case SNMP_OP_SET:
+ if (community != COMM_INITIALIZE)
+ return (SNMP_ERR_NOT_WRITEABLE);
+ switch (which) {
+ case LEAF_snmpEngineID:
+ if (value->v.octetstring.len > SNMP_ENGINE_ID_SIZ)
+ return (SNMP_ERR_WRONG_VALUE);
+ ctx->scratch->ptr1 = malloc(snmpd_engine.engine_len);
+ if (ctx->scratch->ptr1 == NULL)
+ return (SNMP_ERR_GENERR);
+ memcpy(ctx->scratch->ptr1, snmpd_engine.engine_id,
+ snmpd_engine.engine_len);
+ ctx->scratch->int1 = snmpd_engine.engine_len;
+ snmpd_engine.engine_len = value->v.octetstring.len;
+ memcpy(snmpd_engine.engine_id,
+ value->v.octetstring.octets,
+ value->v.octetstring.len);
+ break;
+
+ case LEAF_snmpEngineMaxMessageSize:
+ ctx->scratch->int1 = snmpd_engine.max_msg_size;
+ snmpd_engine.max_msg_size = value->v.integer;
+ break;
+
+ default:
+ return (SNMP_ERR_NOT_WRITEABLE);
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_ROLLBACK:
+ switch (which) {
+ case LEAF_snmpEngineID:
+ snmpd_engine.engine_len = ctx->scratch->int1;
+ memcpy(snmpd_engine.engine_id, ctx->scratch->ptr1,
+ snmpd_engine.engine_len);
+ free(ctx->scratch->ptr1);
+ break;
+
+ case LEAF_snmpEngineMaxMessageSize:
+ snmpd_engine.max_msg_size = ctx->scratch->int1;
+ break;
+
+ default:
+ abort();
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ if (which == LEAF_snmpEngineID) {
+ if (set_snmpd_engine() < 0) {
+ snmpd_engine.engine_len = ctx->scratch->int1;
+ memcpy(snmpd_engine.engine_id,
+ ctx->scratch->ptr1, ctx->scratch->int1);
+ }
+ free(ctx->scratch->ptr1);
+ }
+ return (SNMP_ERR_NOERROR);
+ }
+
+
+ switch (which) {
+ case LEAF_snmpEngineID:
+ return (string_get(value, snmpd_engine.engine_id,
+ snmpd_engine.engine_len));
+ case LEAF_snmpEngineBoots:
+ value->v.integer = snmpd_engine.engine_boots;
+ break;
+ case LEAF_snmpEngineTime:
+ snmpd_engine.engine_time = (get_ticks() - start_tick) / 100ULL;
+ value->v.integer = snmpd_engine.engine_time;
+ break;
+ case LEAF_snmpEngineMaxMessageSize:
+ value->v.integer = snmpd_engine.max_msg_size;
+ break;
+ default:
+ return (SNMP_ERR_NOSUCHNAME);
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+/*
* Transport table
*/
int
diff --git a/contrib/bsnmp/snmpd/bsnmpd.1 b/contrib/bsnmp/snmpd/bsnmpd.1
index b609efd..76141bc 100644
--- a/contrib/bsnmp/snmpd/bsnmpd.1
+++ b/contrib/bsnmp/snmpd/bsnmpd.1
@@ -31,7 +31,7 @@
.\"
.\" $Begemot: bsnmp/snmpd/bsnmpd.1,v 1.12 2006/02/27 09:50:03 brandt_h Exp $
.\"
-.Dd October 23, 2010
+.Dd September 9, 2010
.Dt BSNMPD 1
.Os
.Sh NAME
@@ -42,6 +42,7 @@
.Op Fl dh
.Op Fl c Ar file
.Op Fl D Ar options
+.Op Fl e Ar file
.Op Fl I Ar paths
.Op Fl l Ar prefix
.Op Fl m Ar variable Ns Op = Ns Ar value
@@ -68,9 +69,11 @@ Use
.Ar file
as configuration file instead of the standard one.
.It Fl D Ar options
-Debugging options are specified as a comma separated string.
+Debugging options are specified with a
+.Fl o
+flag followed by a comma separated string of options.
The following options are available.
-.Bl -tag -width "trace=level"
+.Bl -tag -width ".It Cm trace Ns Cm = Ns Cm level"
.It Cm dump
Dump all sent and received PDUs to the terminal.
.It Cm events
@@ -80,8 +83,11 @@ to 10.
.It Cm trace Ns Cm = Ns Cm level
Set the snmp library trace flag to the specified
value.
-The value can be specified in the usual C-syntax for numbers.
.El
+The value can be specified in the usual C-syntax for numbers.
+.It Fl e Ar file
+Specify an alternate file where the agent's engine id and number of boots
+are saved.
.It Fl I Ar paths
Specify a colon separated list of directories to search for configuration
include files.
@@ -246,6 +252,8 @@ Default configuration file, where the default
.Aq prefix
is
.Dq snmpd .
+.It Pa /var/ Ns Ao Ar prefix Ac Ns \&.engine
+Default engine id file.
.It Pa /var/run/ Ns Ao Ar prefix Ac Ns \&.pid
Default pid file.
.It Pa /etc:/usr/etc/:/usr/local/etc
diff --git a/contrib/bsnmp/snmpd/config.c b/contrib/bsnmp/snmpd/config.c
index 48044ec..c4f1188 100644
--- a/contrib/bsnmp/snmpd/config.c
+++ b/contrib/bsnmp/snmpd/config.c
@@ -31,6 +31,7 @@
* Parse configuration file.
*/
#include <sys/types.h>
+#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
@@ -810,6 +811,7 @@ parse_oid(const char *varname, struct asn_oid *oid)
struct snmp_node *node;
u_int i;
u_char ip[4];
+ struct asn_oid str_oid;
for (node = tree; node < &tree[tree_size]; node++)
if (strcmp(varname, node->name) == 0)
@@ -824,7 +826,19 @@ parse_oid(const char *varname, struct asn_oid *oid)
report("subid too large %#"QUADXFMT, numval);
if (oid->len == ASN_MAXOIDLEN)
report("index too long");
- oid->subs[oid->len++] = numval;
+ if (gettoken() != ':')
+ oid->subs[oid->len++] = numval;
+ else {
+ str_oid.len = 0;
+ str_oid.subs[str_oid.len++] = numval;
+ while (gettoken() == TOK_NUM) {
+ str_oid.subs[str_oid.len++] = numval;
+ if (gettoken() != ':')
+ break;
+ }
+ oid->subs[oid->len++] = str_oid.len;
+ asn_append_oid(oid, &str_oid);
+ }
} else if (token == TOK_STR) {
if (strvallen + oid->len + 1 > ASN_MAXOIDLEN)
@@ -832,6 +846,7 @@ parse_oid(const char *varname, struct asn_oid *oid)
oid->subs[oid->len++] = strvallen;
for (i = 0; i < strvallen; i++)
oid->subs[oid->len++] = strval[i];
+ gettoken();
} else if (token == TOK_HOST) {
gethost(strval, ip);
@@ -839,10 +854,9 @@ parse_oid(const char *varname, struct asn_oid *oid)
report("index too long");
for (i = 0; i < 4; i++)
oid->subs[oid->len++] = ip[i];
-
+ gettoken();
} else
report("bad token in index");
- gettoken();
}
return (node);
@@ -1006,7 +1020,7 @@ parse_assign(const char *varname)
node = parse_oid(varname, &vindex);
if (token != '=')
- report("'=' expected");
+ report("'=' expected, got '%c'", token);
gettoken();
if (ignore) {
diff --git a/contrib/bsnmp/snmpd/export.c b/contrib/bsnmp/snmpd/export.c
index 9498361..08fb672 100644
--- a/contrib/bsnmp/snmpd/export.c
+++ b/contrib/bsnmp/snmpd/export.c
@@ -31,6 +31,7 @@
* Support functions for modules.
*/
#include <sys/types.h>
+#include <sys/queue.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/contrib/bsnmp/snmpd/main.c b/contrib/bsnmp/snmpd/main.c
index e3660c1..e008bf7 100644
--- a/contrib/bsnmp/snmpd/main.c
+++ b/contrib/bsnmp/snmpd/main.c
@@ -30,6 +30,8 @@
*
* SNMPd main stuff.
*/
+
+#include <sys/queue.h>
#include <sys/param.h>
#include <sys/un.h>
#include <sys/ucred.h>
@@ -60,6 +62,7 @@
#define PATH_PID "/var/run/%s.pid"
#define PATH_CONFIG "/etc/%s.config"
+#define PATH_ENGINE "/var/%s.engine"
uint64_t this_tick; /* start of processing of current packet (absolute) */
uint64_t start_tick; /* start of processing */
@@ -87,6 +90,11 @@ struct snmpd snmpd = {
};
struct snmpd_stats snmpd_stats;
+struct snmpd_usmstat snmpd_usmstats;
+
+/* snmpEngine */
+struct snmp_engine snmpd_engine;
+
/* snmpSerialNo */
int32_t snmp_serial_no;
@@ -102,6 +110,29 @@ static struct lmodules modules_start = TAILQ_HEAD_INITIALIZER(modules_start);
/* list of all known communities */
struct community_list community_list = TAILQ_HEAD_INITIALIZER(community_list);
+/* list of all known USM users */
+struct usm_userlist usm_userlist = SLIST_HEAD_INITIALIZER(usm_userlist);
+
+/* A list of all VACM users configured, including v1, v2c and v3 */
+struct vacm_userlist vacm_userlist = SLIST_HEAD_INITIALIZER(vacm_userlist);
+
+/* A list of all VACM groups */
+struct vacm_grouplist vacm_grouplist = SLIST_HEAD_INITIALIZER(vacm_grouplist);
+
+static struct vacm_group vacm_default_group = {
+ .groupname = "",
+};
+
+/* The list of configured access entries */
+struct vacm_accesslist vacm_accesslist = TAILQ_HEAD_INITIALIZER(vacm_accesslist);
+
+/* The list of configured views */
+struct vacm_viewlist vacm_viewlist = SLIST_HEAD_INITIALIZER(vacm_viewlist);
+
+/* The list of configured contexts */
+struct vacm_contextlist vacm_contextlist =
+ SLIST_HEAD_INITIALIZER(vacm_contextlist);
+
/* list of all installed object resources */
struct objres_list objres_list = TAILQ_HEAD_INITIALIZER(objres_list);
@@ -128,9 +159,13 @@ static int nprogargs;
u_int community;
static struct community *comm;
+/* current USM user */
+struct usm_user *usm_user;
+
/* file names */
static char config_file[MAXPATHLEN + 1];
static char pid_file[MAXPATHLEN + 1];
+char engine_file[MAXPATHLEN + 1];
#ifndef USE_LIBBEGEMOT
/* event context */
@@ -154,6 +189,12 @@ static const struct asn_oid
const struct asn_oid oid_zeroDotZero = { 2, { 0, 0 }};
+const struct asn_oid oid_usmUnknownEngineIDs =
+ { 11, { 1, 3, 6, 1, 6, 3, 15, 1, 1, 4, 0}};
+
+const struct asn_oid oid_usmNotInTimeWindows =
+ { 11, { 1, 3, 6, 1, 6, 3, 15, 1, 1, 2, 0}};
+
/* request id generator for traps */
u_int trap_reqid;
@@ -161,13 +202,15 @@ u_int trap_reqid;
static const char usgtxt[] = "\
Begemot simple SNMP daemon. Copyright (c) 2001-2002 Fraunhofer Institute for\n\
Open Communication Systems (FhG Fokus). All rights reserved.\n\
-usage: snmpd [-dh] [-c file] [-D options] [-I path] [-l prefix]\n\
- [-m variable=value] [-p file]\n\
+Copyright (c) 2010 The FreeBSD Foundation. All rights reserved.\n\
+usage: snmpd [-dh] [-c file] [-D options] [-e file] [-I path]\n\
+ [-l prefix] [-m variable=value] [-p file]\n\
options:\n\
-d don't daemonize\n\
-h print this info\n\
-c file specify configuration file\n\
-D options debugging options\n\
+ -e file specify engine id file\n\
-I path system include path\n\
-l prefix default basename for pid and config file\n\
-m var=val define variable\n\
@@ -243,7 +286,191 @@ snmp_output(struct snmp_pdu *pdu, u_char *sndbuf, size_t *sndlen,
}
/*
- * SNMP input. Start: decode the PDU, find the community.
+ * Check USM PDU header credentials against local SNMP Engine & users.
+ */
+static enum snmp_code
+snmp_pdu_auth_user(struct snmp_pdu *pdu)
+{
+ uint64_t etime;
+ usm_user = NULL;
+
+ /* un-authenticated snmpEngineId discovery */
+ if (pdu->engine.engine_len == 0 && strlen(pdu->user.sec_name) == 0) {
+ pdu->engine.engine_len = snmpd_engine.engine_len;
+ memcpy(pdu->engine.engine_id, snmpd_engine.engine_id,
+ snmpd_engine.engine_len);
+ pdu->engine.engine_boots = snmpd_engine.engine_boots;
+ pdu->engine.engine_time = snmpd_engine.engine_time;
+ pdu->flags |= SNMP_MSG_AUTODISCOVER;
+ return (SNMP_CODE_OK);
+ }
+
+ if ((usm_user = usm_find_user(pdu->engine.engine_id,
+ pdu->engine.engine_len, pdu->user.sec_name)) == NULL ||
+ usm_user->status != 1 /* active */)
+ return (SNMP_CODE_BADUSER);
+
+ if (usm_user->user_engine_len != snmpd_engine.engine_len ||
+ memcmp(usm_user->user_engine_id, snmpd_engine.engine_id,
+ snmpd_engine.engine_len) != 0)
+ return (SNMP_CODE_BADENGINE);
+
+ pdu->user.priv_proto = usm_user->suser.priv_proto;
+ memcpy(pdu->user.priv_key, usm_user->suser.priv_key,
+ sizeof(pdu->user.priv_key));
+
+ /* authenticated snmpEngineId discovery */
+ if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0) {
+ etime = (get_ticks() - start_tick) / 100ULL;
+ if (etime < INT32_MAX)
+ snmpd_engine.engine_time = etime;
+ else {
+ start_tick = get_ticks();
+ set_snmpd_engine();
+ snmpd_engine.engine_time = start_tick;
+ }
+
+ pdu->user.auth_proto = usm_user->suser.auth_proto;
+ memcpy(pdu->user.auth_key, usm_user->suser.auth_key,
+ sizeof(pdu->user.auth_key));
+
+ if (pdu->engine.engine_boots == 0 &&
+ pdu->engine.engine_time == 0) {
+ pdu->flags |= SNMP_MSG_AUTODISCOVER;
+ return (SNMP_CODE_OK);
+ }
+
+ if (pdu->engine.engine_boots != snmpd_engine.engine_boots ||
+ abs(pdu->engine.engine_time - snmpd_engine.engine_time) >
+ SNMP_TIME_WINDOW)
+ return (SNMP_CODE_NOTINTIME);
+ }
+
+ if (((pdu->flags & SNMP_MSG_PRIV_FLAG) != 0 &&
+ (pdu->flags & SNMP_MSG_AUTH_FLAG) == 0) ||
+ ((pdu->flags & SNMP_MSG_AUTH_FLAG) == 0 &&
+ usm_user->suser.auth_proto != SNMP_AUTH_NOAUTH) ||
+ ((pdu->flags & SNMP_MSG_PRIV_FLAG) == 0 &&
+ usm_user->suser.priv_proto != SNMP_PRIV_NOPRIV))
+ return (SNMP_CODE_BADSECLEVEL);
+
+ return (SNMP_CODE_OK);
+}
+
+/*
+ * Check whether access to each of var bindings in the PDU is allowed based
+ * on the user credentials against the configured User groups & VACM views.
+ */
+static enum snmp_code
+snmp_pdu_auth_access(struct snmp_pdu *pdu, int32_t *ip)
+{
+ const char *uname;
+ int32_t suboid, smodel;
+ uint32_t i;
+ struct vacm_user *vuser;
+ struct vacm_access *acl;
+ struct vacm_context *vacmctx;
+ struct vacm_view *view;
+
+ /*
+ * At least a default context exists if the snmpd_vacm(3) module is
+ * running.
+ */
+ if (SLIST_EMPTY(&vacm_contextlist) ||
+ (pdu->flags & SNMP_MSG_AUTODISCOVER) != 0)
+ return (SNMP_CODE_OK);
+
+ switch (pdu->version) {
+ case SNMP_V1:
+ if ((uname = comm_string(community)) == NULL)
+ return (SNMP_CODE_FAILED);
+ smodel = SNMP_SECMODEL_SNMPv1;
+ break;
+
+ case SNMP_V2c:
+ if ((uname = comm_string(community)) == NULL)
+ return (SNMP_CODE_FAILED);
+ smodel = SNMP_SECMODEL_SNMPv2c;
+ break;
+
+ case SNMP_V3:
+ uname = pdu->user.sec_name;
+ if ((smodel = pdu->security_model) != SNMP_SECMODEL_USM)
+ return (SNMP_CODE_FAILED);
+ /* Compare the PDU context engine id against the agent's */
+ if (pdu->context_engine_len != snmpd_engine.engine_len ||
+ memcmp(pdu->context_engine, snmpd_engine.engine_id,
+ snmpd_engine.engine_len) != 0)
+ return (SNMP_CODE_FAILED);
+ break;
+
+ default:
+ abort();
+ }
+
+ SLIST_FOREACH(vuser, &vacm_userlist, vvu)
+ if (strcmp(uname, vuser->secname) == 0 &&
+ vuser->sec_model == smodel)
+ break;
+
+ if (vuser == NULL || vuser->group == NULL)
+ return (SNMP_CODE_FAILED);
+
+ /* XXX: shteryana - recheck */
+ TAILQ_FOREACH_REVERSE(acl, &vacm_accesslist, vacm_accesslist, vva) {
+ if (acl->group != vuser->group)
+ continue;
+ SLIST_FOREACH(vacmctx, &vacm_contextlist, vcl)
+ if (memcmp(vacmctx->ctxname, acl->ctx_prefix,
+ acl->ctx_match) == 0)
+ goto match;
+ }
+
+ return (SNMP_CODE_FAILED);
+
+match:
+
+ switch (pdu->type) {
+ case SNMP_PDU_GET:
+ case SNMP_PDU_GETNEXT:
+ case SNMP_PDU_GETBULK:
+ if ((view = acl->read_view) == NULL)
+ return (SNMP_CODE_FAILED);
+ break;
+
+ case SNMP_PDU_SET:
+ if ((view = acl->write_view) == NULL)
+ return (SNMP_CODE_FAILED);
+ break;
+
+ case SNMP_PDU_TRAP:
+ case SNMP_PDU_INFORM:
+ case SNMP_PDU_TRAP2:
+ case SNMP_PDU_REPORT:
+ if ((view = acl->notify_view) == NULL)
+ return (SNMP_CODE_FAILED);
+ break;
+ case SNMP_PDU_RESPONSE:
+ /* NOTREACHED */
+ return (SNMP_CODE_FAILED);
+ default:
+ abort();
+ }
+
+ for (i = 0; i < pdu->nbindings; i++) {
+ /* XXX - view->mask*/
+ suboid = asn_is_suboid(&view->subtree, &pdu->bindings[i].var);
+ if ((!suboid && !view->exclude) || (suboid && view->exclude)) {
+ *ip = i + 1;
+ return (SNMP_CODE_FAILED);
+ }
+ }
+
+ return (SNMP_CODE_OK);
+}
+
+/*
+ * SNMP input. Start: decode the PDU, find the user or community.
*/
enum snmpd_input_err
snmp_input_start(const u_char *buf, size_t len, const char *source,
@@ -254,6 +481,9 @@ snmp_input_start(const u_char *buf, size_t len, const char *source,
enum snmpd_input_err ret;
int sret;
+ /* update uptime */
+ this_tick = get_ticks();
+
b.asn_cptr = buf;
b.asn_len = len;
@@ -269,11 +499,27 @@ snmp_input_start(const u_char *buf, size_t len, const char *source,
}
b.asn_len = *pdulen = (size_t)sret;
- code = snmp_pdu_decode(&b, pdu, ip);
+ memset(pdu, 0, sizeof(*pdu));
+ if ((code = snmp_pdu_decode_header(&b, pdu)) != SNMP_CODE_OK)
+ goto decoded;
- snmpd_stats.inPkts++;
+ if (pdu->version == SNMP_V3) {
+ if (pdu->security_model != SNMP_SECMODEL_USM) {
+ code = SNMP_CODE_FAILED;
+ goto decoded;
+ }
+ if ((code = snmp_pdu_auth_user(pdu)) != SNMP_CODE_OK)
+ goto decoded;
+ if ((code = snmp_pdu_decode_secmode(&b, pdu)) != SNMP_CODE_OK)
+ goto decoded;
+ }
+ code = snmp_pdu_decode_scoped(&b, pdu, ip);
ret = SNMPD_INPUT_OK;
+
+decoded:
+ snmpd_stats.inPkts++;
+
switch (code) {
case SNMP_CODE_FAILED:
@@ -300,6 +546,30 @@ snmp_input_start(const u_char *buf, size_t len, const char *source,
ret = SNMPD_INPUT_VALBADENC;
break;
+ case SNMP_CODE_BADSECLEVEL:
+ snmpd_usmstats.unsupported_seclevels++;
+ return (SNMPD_INPUT_FAILED);
+
+ case SNMP_CODE_NOTINTIME:
+ snmpd_usmstats.not_in_time_windows++;
+ return (SNMPD_INPUT_FAILED);
+
+ case SNMP_CODE_BADUSER:
+ snmpd_usmstats.unknown_users++;
+ return (SNMPD_INPUT_FAILED);
+
+ case SNMP_CODE_BADENGINE:
+ snmpd_usmstats.unknown_engine_ids++;
+ return (SNMPD_INPUT_FAILED);
+
+ case SNMP_CODE_BADDIGEST:
+ snmpd_usmstats.wrong_digests++;
+ return (SNMPD_INPUT_FAILED);
+
+ case SNMP_CODE_EDECRYPT:
+ snmpd_usmstats.decrypt_errors++;
+ return (SNMPD_INPUT_FAILED);
+
case SNMP_CODE_OK:
switch (pdu->version) {
@@ -313,6 +583,11 @@ snmp_input_start(const u_char *buf, size_t len, const char *source,
goto bad_vers;
break;
+ case SNMP_V3:
+ if (!(snmpd.version_enable & VERS_ENABLE_V3))
+ goto bad_vers;
+ break;
+
case SNMP_Verr:
goto bad_vers;
}
@@ -325,25 +600,47 @@ snmp_input_start(const u_char *buf, size_t len, const char *source,
}
/*
- * Look, whether we know the community
+ * Look, whether we know the community or user
*/
- TAILQ_FOREACH(comm, &community_list, link)
- if (comm->string != NULL &&
- strcmp(comm->string, pdu->community) == 0)
- break;
- if (comm == NULL) {
- snmpd_stats.inBadCommunityNames++;
- snmp_pdu_free(pdu);
- if (snmpd.auth_traps)
- snmp_send_trap(&oid_authenticationFailure,
- (struct snmp_value *)NULL);
- ret = SNMPD_INPUT_BAD_COMM;
- } else
- community = comm->value;
+ if (pdu->version != SNMP_V3) {
+ TAILQ_FOREACH(comm, &community_list, link)
+ if (comm->string != NULL &&
+ strcmp(comm->string, pdu->community) == 0)
+ break;
- /* update uptime */
- this_tick = get_ticks();
+ if (comm == NULL) {
+ snmpd_stats.inBadCommunityNames++;
+ snmp_pdu_free(pdu);
+ if (snmpd.auth_traps)
+ snmp_send_trap(&oid_authenticationFailure,
+ (struct snmp_value *)NULL);
+ ret = SNMPD_INPUT_BAD_COMM;
+ } else
+ community = comm->value;
+ } else if (pdu->nbindings == 0) {
+ /* RFC 3414 - snmpEngineID Discovery */
+ if (strlen(pdu->user.sec_name) == 0) {
+ asn_append_oid(&(pdu->bindings[pdu->nbindings++].var),
+ &oid_usmUnknownEngineIDs);
+ pdu->context_engine_len = snmpd_engine.engine_len;
+ memcpy(pdu->context_engine, snmpd_engine.engine_id,
+ snmpd_engine.engine_len);
+ } else if (pdu->engine.engine_boots == 0 &&
+ pdu->engine.engine_time == 0) {
+ asn_append_oid(&(pdu->bindings[pdu->nbindings++].var),
+ &oid_usmNotInTimeWindows);
+ pdu->engine.engine_boots = snmpd_engine.engine_boots;
+ pdu->engine.engine_time = snmpd_engine.engine_time;
+ }
+ } else if (usm_user->suser.auth_proto != SNMP_AUTH_NOAUTH &&
+ (pdu->engine.engine_boots == 0 || pdu->engine.engine_time == 0)) {
+ snmpd_usmstats.not_in_time_windows++;
+ ret = SNMP_CODE_FAILED;
+ }
+
+ if ((code = snmp_pdu_auth_access(pdu, ip)) != SNMP_CODE_OK)
+ ret = SNMP_CODE_FAILED;
return (ret);
}
@@ -960,7 +1257,8 @@ snmpd_input(struct port_input *pi, struct tport *tport)
* If that is a module community and the module has a proxy function,
* the hand it over to the module.
*/
- if (comm->owner != NULL && comm->owner->config->proxy != NULL) {
+ if (comm != NULL && comm->owner != NULL &&
+ comm->owner->config->proxy != NULL) {
perr = (*comm->owner->config->proxy)(&pdu, tport->transport,
&tport->index, pi->peer, pi->peerlen, ierr, vi,
!pi->cred || pi->priv);
@@ -1016,9 +1314,10 @@ snmpd_input(struct port_input *pi, struct tport *tport)
/*
* Check community
*/
- if ((pi->cred && !pi->priv && pdu.type == SNMP_PDU_SET) ||
+ if (pdu.version < SNMP_V3 &&
+ ((pi->cred && !pi->priv && pdu.type == SNMP_PDU_SET) ||
(community != COMM_WRITE &&
- (pdu.type == SNMP_PDU_SET || community != COMM_READ))) {
+ (pdu.type == SNMP_PDU_SET || community != COMM_READ)))) {
snmpd_stats.inBadCommunityUses++;
snmp_pdu_free(&pdu);
snmp_input_consume(pi);
@@ -1337,7 +1636,7 @@ main(int argc, char *argv[])
struct tport *p;
const char *prefix = "snmpd";
struct lmodule *m;
- char *value, *option;
+ char *value = NULL, *option; /* XXX */
struct transport *t;
#define DBG_DUMP 0
@@ -1355,7 +1654,7 @@ main(int argc, char *argv[])
snmp_debug = snmp_debug_func;
asn_error = asn_error_func;
- while ((opt = getopt(argc, argv, "c:dD:hI:l:m:p:")) != EOF)
+ while ((opt = getopt(argc, argv, "c:dD:e:hI:l:m:p:")) != EOF)
switch (opt) {
case 'c':
@@ -1401,6 +1700,9 @@ main(int argc, char *argv[])
}
break;
+ case 'e':
+ strlcpy(engine_file, optarg, sizeof(engine_file));
+ break;
case 'h':
fprintf(stderr, "%s", usgtxt);
exit(0);
@@ -1471,6 +1773,7 @@ main(int argc, char *argv[])
snprintf(config_file, sizeof(config_file), PATH_CONFIG, prefix);
init_actvals();
+ init_snmpd_engine();
this_tick = get_ticks();
start_tick = this_tick;
@@ -1497,6 +1800,9 @@ main(int argc, char *argv[])
evSetDebug(evctx, 10, stderr);
#endif
+ if (engine_file[0] == '\0')
+ snprintf(engine_file, sizeof(engine_file), PATH_ENGINE, prefix);
+
if (read_config(config_file, NULL)) {
syslog(LOG_ERR, "error in config file");
exit(1);
@@ -1601,7 +1907,7 @@ main(int argc, char *argv[])
}
uint64_t
-get_ticks()
+get_ticks(void)
{
struct timeval tv;
uint64_t ret;
@@ -2374,3 +2680,566 @@ or_unregister(u_int idx)
return;
}
}
+
+/*
+ * RFC 3414 User-based Security Model support
+ */
+
+struct snmpd_usmstat *
+bsnmpd_get_usm_stats(void)
+{
+ return (&snmpd_usmstats);
+}
+
+void
+bsnmpd_reset_usm_stats(void)
+{
+ memset(&snmpd_usmstats, 0, sizeof(&snmpd_usmstats));
+}
+
+struct usm_user *
+usm_first_user(void)
+{
+ return (SLIST_FIRST(&usm_userlist));
+}
+
+struct usm_user *
+usm_next_user(struct usm_user *uuser)
+{
+ if (uuser == NULL)
+ return (NULL);
+
+ return (SLIST_NEXT(uuser, up));
+}
+
+struct usm_user *
+usm_find_user(uint8_t *engine, uint32_t elen, char *uname)
+{
+ struct usm_user *uuser;
+
+ SLIST_FOREACH(uuser, &usm_userlist, up)
+ if (uuser->user_engine_len == elen &&
+ memcmp(uuser->user_engine_id, engine, elen) == 0 &&
+ strlen(uuser->suser.sec_name) == strlen(uname) &&
+ strcmp(uuser->suser.sec_name, uname) == 0)
+ break;
+
+ return (uuser);
+}
+
+static int
+usm_compare_user(struct usm_user *u1, struct usm_user *u2)
+{
+ uint32_t i;
+
+ if (u1->user_engine_len < u2->user_engine_len)
+ return (-1);
+ if (u1->user_engine_len > u2->user_engine_len)
+ return (1);
+
+ for (i = 0; i < u1->user_engine_len; i++) {
+ if (u1->user_engine_id[i] < u2->user_engine_id[i])
+ return (-1);
+ if (u1->user_engine_id[i] > u2->user_engine_id[i])
+ return (1);
+ }
+
+ if (strlen(u1->suser.sec_name) < strlen(u2->suser.sec_name))
+ return (-1);
+ if (strlen(u1->suser.sec_name) > strlen(u2->suser.sec_name))
+ return (1);
+
+ for (i = 0; i < strlen(u1->suser.sec_name); i++) {
+ if (u1->suser.sec_name[i] < u2->suser.sec_name[i])
+ return (-1);
+ if (u1->suser.sec_name[i] > u2->suser.sec_name[i])
+ return (1);
+ }
+
+ return (0);
+}
+
+struct usm_user *
+usm_new_user(uint8_t *eid, uint32_t elen, char *uname)
+{
+ int cmp;
+ struct usm_user *uuser, *temp, *prev;
+
+ for (uuser = usm_first_user(); uuser != NULL;
+ (uuser = usm_next_user(uuser))) {
+ if (uuser->user_engine_len == elen &&
+ strlen(uname) == strlen(uuser->suser.sec_name) &&
+ strcmp(uname, uuser->suser.sec_name) == 0 &&
+ memcmp(eid, uuser->user_engine_id, elen) == 0)
+ return (NULL);
+ }
+
+ if ((uuser = (struct usm_user *)malloc(sizeof(*uuser))) == NULL)
+ return (NULL);
+
+ memset(uuser, 0, sizeof(struct usm_user));
+ strlcpy(uuser->suser.sec_name, uname, SNMP_ADM_STR32_SIZ);
+ memcpy(uuser->user_engine_id, eid, elen);
+ uuser->user_engine_len = elen;
+
+ if ((prev = SLIST_FIRST(&usm_userlist)) == NULL ||
+ usm_compare_user(uuser, prev) < 0) {
+ SLIST_INSERT_HEAD(&usm_userlist, uuser, up);
+ return (uuser);
+ }
+
+ SLIST_FOREACH(temp, &usm_userlist, up) {
+ if ((cmp = usm_compare_user(uuser, temp)) <= 0)
+ break;
+ prev = temp;
+ }
+
+ if (temp == NULL || cmp < 0)
+ SLIST_INSERT_AFTER(prev, uuser, up);
+ else if (cmp > 0)
+ SLIST_INSERT_AFTER(temp, uuser, up);
+ else {
+ syslog(LOG_ERR, "User %s exists", uuser->suser.sec_name);
+ free(uuser);
+ return (NULL);
+ }
+
+ return (uuser);
+}
+
+void
+usm_delete_user(struct usm_user *uuser)
+{
+ SLIST_REMOVE(&usm_userlist, uuser, usm_user, up);
+ free(uuser);
+}
+
+void
+usm_flush_users(void)
+{
+ struct usm_user *uuser;
+
+ while ((uuser = SLIST_FIRST(&usm_userlist)) != NULL) {
+ SLIST_REMOVE_HEAD(&usm_userlist, up);
+ free(uuser);
+ }
+
+ SLIST_INIT(&usm_userlist);
+}
+
+/*
+ * RFC 3415 View-based Access Control Model support
+ */
+struct vacm_user *
+vacm_first_user(void)
+{
+ return (SLIST_FIRST(&vacm_userlist));
+}
+
+struct vacm_user *
+vacm_next_user(struct vacm_user *vuser)
+{
+ if (vuser == NULL)
+ return (NULL);
+
+ return (SLIST_NEXT(vuser, vvu));
+}
+
+static int
+vacm_compare_user(struct vacm_user *v1, struct vacm_user *v2)
+{
+ uint32_t i;
+
+ if (v1->sec_model < v2->sec_model)
+ return (-1);
+ if (v1->sec_model > v2->sec_model)
+ return (1);
+
+ if (strlen(v1->secname) < strlen(v2->secname))
+ return (-1);
+ if (strlen(v1->secname) > strlen(v2->secname))
+ return (1);
+
+ for (i = 0; i < strlen(v1->secname); i++) {
+ if (v1->secname[i] < v2->secname[i])
+ return (-1);
+ if (v1->secname[i] > v2->secname[i])
+ return (1);
+ }
+
+ return (0);
+}
+
+struct vacm_user *
+vacm_new_user(int32_t smodel, char *uname)
+{
+ int cmp;
+ struct vacm_user *user, *temp, *prev;
+
+ SLIST_FOREACH(user, &vacm_userlist, vvu)
+ if (strcmp(uname, user->secname) == 0 &&
+ smodel == user->sec_model)
+ return (NULL);
+
+ if ((user = (struct vacm_user *)malloc(sizeof(*user))) == NULL)
+ return (NULL);
+
+ memset(user, 0, sizeof(*user));
+ user->group = &vacm_default_group;
+ SLIST_INSERT_HEAD(&vacm_default_group.group_users, user, vvg);
+ user->sec_model = smodel;
+ strlcpy(user->secname, uname, sizeof(user->secname));
+
+ if ((prev = SLIST_FIRST(&vacm_userlist)) == NULL ||
+ vacm_compare_user(user, prev) < 0) {
+ SLIST_INSERT_HEAD(&vacm_userlist, user, vvu);
+ return (user);
+ }
+
+ SLIST_FOREACH(temp, &vacm_userlist, vvu) {
+ if ((cmp = vacm_compare_user(user, temp)) <= 0)
+ break;
+ prev = temp;
+ }
+
+ if (temp == NULL || cmp < 0)
+ SLIST_INSERT_AFTER(prev, user, vvu);
+ else if (cmp > 0)
+ SLIST_INSERT_AFTER(temp, user, vvu);
+ else {
+ syslog(LOG_ERR, "User %s exists", user->secname);
+ free(user);
+ return (NULL);
+ }
+
+ return (user);
+}
+
+int
+vacm_delete_user(struct vacm_user *user)
+{
+ if (user->group != NULL && user->group != &vacm_default_group) {
+ SLIST_REMOVE(&user->group->group_users, user, vacm_user, vvg);
+ if (SLIST_EMPTY(&user->group->group_users)) {
+ SLIST_REMOVE(&vacm_grouplist, user->group,
+ vacm_group, vge);
+ free(user->group);
+ }
+ }
+
+ SLIST_REMOVE(&vacm_userlist, user, vacm_user, vvu);
+ free(user);
+
+ return (0);
+}
+
+int
+vacm_user_set_group(struct vacm_user *user, u_char *octets, u_int len)
+{
+ struct vacm_group *group;
+
+ if (len >= SNMP_ADM_STR32_SIZ)
+ return (-1);
+
+ SLIST_FOREACH(group, &vacm_grouplist, vge)
+ if (strlen(group->groupname) == len &&
+ memcmp(octets, group->groupname, len) == 0)
+ break;
+
+ if (group == NULL) {
+ if ((group = (struct vacm_group *)malloc(sizeof(*group))) == NULL)
+ return (-1);
+ memset(group, 0, sizeof(*group));
+ memcpy(group->groupname, octets, len);
+ group->groupname[len] = '\0';
+ SLIST_INSERT_HEAD(&vacm_grouplist, group, vge);
+ }
+
+ SLIST_REMOVE(&user->group->group_users, user, vacm_user, vvg);
+ SLIST_INSERT_HEAD(&group->group_users, user, vvg);
+ user->group = group;
+
+ return (0);
+}
+
+void
+vacm_groups_init(void)
+{
+ SLIST_INSERT_HEAD(&vacm_grouplist, &vacm_default_group, vge);
+}
+
+struct vacm_access *
+vacm_first_access_rule(void)
+{
+ return (TAILQ_FIRST(&vacm_accesslist));
+}
+
+struct vacm_access *
+vacm_next_access_rule(struct vacm_access *acl)
+{
+ if (acl == NULL)
+ return (NULL);
+
+ return (TAILQ_NEXT(acl, vva));
+}
+
+static int
+vacm_compare_access_rule(struct vacm_access *v1, struct vacm_access *v2)
+{
+ uint32_t i;
+
+ if (strlen(v1->group->groupname) < strlen(v2->group->groupname))
+ return (-1);
+ if (strlen(v1->group->groupname) > strlen(v2->group->groupname))
+ return (1);
+
+ for (i = 0; i < strlen(v1->group->groupname); i++) {
+ if (v1->group->groupname[i] < v2->group->groupname[i])
+ return (-1);
+ if (v1->group->groupname[i] > v2->group->groupname[i])
+ return (1);
+ }
+
+ if (strlen(v1->ctx_prefix) < strlen(v2->ctx_prefix))
+ return (-1);
+ if (strlen(v1->ctx_prefix) > strlen(v2->ctx_prefix))
+ return (1);
+
+ for (i = 0; i < strlen(v1->ctx_prefix); i++) {
+ if (v1->ctx_prefix[i] < v2->ctx_prefix[i])
+ return (-1);
+ if (v1->ctx_prefix[i] > v2->ctx_prefix[i])
+ return (1);
+ }
+
+ if (v1->sec_model < v2->sec_model)
+ return (-1);
+ if (v1->sec_model > v2->sec_model)
+ return (1);
+
+ if (v1->sec_level < v2->sec_level)
+ return (-1);
+ if (v1->sec_level > v2->sec_level)
+ return (1);
+
+ return (0);
+}
+
+struct vacm_access *
+vacm_new_access_rule(char *gname, char *cprefix, int32_t smodel, int32_t slevel)
+{
+ struct vacm_group *group;
+ struct vacm_access *acl, *temp;
+
+ TAILQ_FOREACH(acl, &vacm_accesslist, vva) {
+ if (acl->group == NULL)
+ continue;
+ if (strcmp(gname, acl->group->groupname) == 0 &&
+ strcmp(cprefix, acl->ctx_prefix) == 0 &&
+ acl->sec_model == smodel && acl->sec_level == slevel)
+ return (NULL);
+ }
+
+ /* Make sure the group exists */
+ SLIST_FOREACH(group, &vacm_grouplist, vge)
+ if (strcmp(gname, group->groupname) == 0)
+ break;
+
+ if (group == NULL)
+ return (NULL);
+
+ if ((acl = (struct vacm_access *)malloc(sizeof(*acl))) == NULL)
+ return (NULL);
+
+ memset(acl, 0, sizeof(*acl));
+ acl->group = group;
+ strlcpy(acl->ctx_prefix, cprefix, sizeof(acl->ctx_prefix));
+ acl->sec_model = smodel;
+ acl->sec_level = slevel;
+
+ if ((temp = TAILQ_FIRST(&vacm_accesslist)) == NULL ||
+ vacm_compare_access_rule(acl, temp) < 0) {
+ TAILQ_INSERT_HEAD(&vacm_accesslist, acl, vva);
+ return (acl);
+ }
+
+ TAILQ_FOREACH(temp, &vacm_accesslist, vva)
+ if (vacm_compare_access_rule(acl, temp) < 0) {
+ TAILQ_INSERT_BEFORE(temp, acl, vva);
+ return (acl);
+ }
+
+ TAILQ_INSERT_TAIL(&vacm_accesslist, acl, vva);
+
+ return (acl);
+}
+
+int
+vacm_delete_access_rule(struct vacm_access *acl)
+{
+ TAILQ_REMOVE(&vacm_accesslist, acl, vva);
+ free(acl);
+
+ return (0);
+}
+
+struct vacm_view *
+vacm_first_view(void)
+{
+ return (SLIST_FIRST(&vacm_viewlist));
+}
+
+struct vacm_view *
+vacm_next_view(struct vacm_view *view)
+{
+ if (view == NULL)
+ return (NULL);
+
+ return (SLIST_NEXT(view, vvl));
+}
+
+static int
+vacm_compare_view(struct vacm_view *v1, struct vacm_view *v2)
+{
+ uint32_t i;
+
+ if (strlen(v1->viewname) < strlen(v2->viewname))
+ return (-1);
+ if (strlen(v1->viewname) > strlen(v2->viewname))
+ return (1);
+
+ for (i = 0; i < strlen(v1->viewname); i++) {
+ if (v1->viewname[i] < v2->viewname[i])
+ return (-1);
+ if (v1->viewname[i] > v2->viewname[i])
+ return (1);
+ }
+
+ return (asn_compare_oid(&v1->subtree, &v2->subtree));
+}
+
+struct vacm_view *
+vacm_new_view(char *vname, struct asn_oid *oid)
+{
+ int cmp;
+ struct vacm_view *view, *temp, *prev;
+
+ SLIST_FOREACH(view, &vacm_viewlist, vvl)
+ if (strcmp(vname, view->viewname) == 0)
+ return (NULL);
+
+ if ((view = (struct vacm_view *)malloc(sizeof(*view))) == NULL)
+ return (NULL);
+
+ memset(view, 0, sizeof(*view));
+ strlcpy(view->viewname, vname, sizeof(view->viewname));
+ asn_append_oid(&view->subtree, oid);
+
+ if ((prev = SLIST_FIRST(&vacm_viewlist)) == NULL ||
+ vacm_compare_view(view, prev) < 0) {
+ SLIST_INSERT_HEAD(&vacm_viewlist, view, vvl);
+ return (view);
+ }
+
+ SLIST_FOREACH(temp, &vacm_viewlist, vvl) {
+ if ((cmp = vacm_compare_view(view, temp)) <= 0)
+ break;
+ prev = temp;
+ }
+
+ if (temp == NULL || cmp < 0)
+ SLIST_INSERT_AFTER(prev, view, vvl);
+ else if (cmp > 0)
+ SLIST_INSERT_AFTER(temp, view, vvl);
+ else {
+ syslog(LOG_ERR, "View %s exists", view->viewname);
+ free(view);
+ return (NULL);
+ }
+
+ return (view);
+}
+
+int
+vacm_delete_view(struct vacm_view *view)
+{
+ SLIST_REMOVE(&vacm_viewlist, view, vacm_view, vvl);
+ free(view);
+
+ return (0);
+}
+
+struct vacm_context *
+vacm_first_context(void)
+{
+ return (SLIST_FIRST(&vacm_contextlist));
+}
+
+struct vacm_context *
+vacm_next_context(struct vacm_context *vacmctx)
+{
+ if (vacmctx == NULL)
+ return (NULL);
+
+ return (SLIST_NEXT(vacmctx, vcl));
+}
+
+struct vacm_context *
+vacm_add_context(char *ctxname, int regid)
+{
+ int cmp;
+ struct vacm_context *ctx, *temp, *prev;
+
+ SLIST_FOREACH(ctx, &vacm_contextlist, vcl)
+ if (strcmp(ctxname, ctx->ctxname) == 0) {
+ syslog(LOG_ERR, "Context %s exists", ctx->ctxname);
+ return (NULL);
+ }
+
+ if ((ctx = (struct vacm_context *)malloc(sizeof(*ctx))) == NULL)
+ return (NULL);
+
+ memset(ctx, 0, sizeof(*ctx));
+ strlcpy(ctx->ctxname, ctxname, sizeof(ctx->ctxname));
+ ctx->regid = regid;
+
+ if ((prev = SLIST_FIRST(&vacm_contextlist)) == NULL ||
+ strlen(ctx->ctxname) < strlen(prev->ctxname) ||
+ strcmp(ctx->ctxname, prev->ctxname) < 0) {
+ SLIST_INSERT_HEAD(&vacm_contextlist, ctx, vcl);
+ return (ctx);
+ }
+
+ SLIST_FOREACH(temp, &vacm_contextlist, vcl) {
+ if (strlen(ctx->ctxname) < strlen(temp->ctxname) ||
+ strcmp(ctx->ctxname, temp->ctxname) < 0) {
+ cmp = -1;
+ break;
+ }
+ prev = temp;
+ }
+
+ if (temp == NULL || cmp < 0)
+ SLIST_INSERT_AFTER(prev, ctx, vcl);
+ else if (cmp > 0)
+ SLIST_INSERT_AFTER(temp, ctx, vcl);
+ else {
+ syslog(LOG_ERR, "Context %s exists", ctx->ctxname);
+ free(ctx);
+ return (NULL);
+ }
+
+ return (ctx);
+}
+
+void
+vacm_flush_contexts(int regid)
+{
+ struct vacm_context *ctx, *temp;
+
+ SLIST_FOREACH_SAFE(ctx, &vacm_contextlist, vcl, temp)
+ if (ctx->regid == regid) {
+ SLIST_REMOVE(&vacm_contextlist, ctx, vacm_context, vcl);
+ free(ctx);
+ }
+}
diff --git a/contrib/bsnmp/snmpd/snmpd.h b/contrib/bsnmp/snmpd/snmpd.h
index 39d90b7..79fc699 100644
--- a/contrib/bsnmp/snmpd/snmpd.h
+++ b/contrib/bsnmp/snmpd/snmpd.h
@@ -30,7 +30,7 @@
*
* Private SNMPd data and functions.
*/
-#include <sys/queue.h>
+
#ifdef USE_LIBBEGEMOT
#include <rpoll.h>
#else
@@ -247,7 +247,8 @@ extern struct snmpd snmpd;
#define VERS_ENABLE_V1 0x00000001
#define VERS_ENABLE_V2C 0x00000002
-#define VERS_ENABLE_ALL 0x00000003
+#define VERS_ENABLE_V3 0x00000004
+#define VERS_ENABLE_ALL (VERS_ENABLE_V1 | VERS_ENABLE_V2C | VERS_ENABLE_V3)
/*
* The debug group
@@ -280,6 +281,11 @@ struct snmpd_stats {
extern struct snmpd_stats snmpd_stats;
/*
+ * SNMPd Engine
+ */
+extern struct snmp_engine snmpd_engine;
+
+/*
* OR Table
*/
struct objres {
@@ -322,6 +328,11 @@ extern const char *syspath;
extern int32_t snmp_serial_no;
int init_actvals(void);
+
+extern char engine_file[];
+int init_snmpd_engine(void);
+int set_snmpd_engine(void);
+
int read_config(const char *, struct lmodule *);
int define_macro(const char *name, const char *value);
diff --git a/contrib/bsnmp/snmpd/snmpmod.3 b/contrib/bsnmp/snmpd/snmpmod.3
index 6bea403..a142069 100644
--- a/contrib/bsnmp/snmpd/snmpmod.3
+++ b/contrib/bsnmp/snmpd/snmpmod.3
@@ -31,7 +31,7 @@
.\"
.\" $Begemot: bsnmp/snmpd/snmpmod.3,v 1.14 2005/10/04 13:30:35 brandt_h Exp $
.\"
-.Dd February 27, 2006
+.Dd September 9, 2010
.Dt SNMPMOD 3
.Os
.Sh NAME
@@ -60,6 +60,8 @@
.Nm comm_define ,
.Nm community ,
.Nm oid_zeroDotZero ,
+.Nm oid_usmUnknownEngineIDs ,
+.Nm oid_usmNotInTimeWindows ,
.Nm reqid_allocate ,
.Nm reqid_next ,
.Nm reqid_base ,
@@ -99,7 +101,16 @@
.Nm index_compare ,
.Nm index_compare_off ,
.Nm index_append ,
-.Nm index_append_off
+.Nm index_append_off,
+.Nm bsnmpd_get_usm_stats,
+.Nm bsnmpd_reset_usm_stats,
+.Nm usm_first_user,
+.Nm usm_next_user,
+.Nm usm_find_user,
+.Nm usm_new_user,
+.Nm usm_delete_user,
+.Nm usm_flush_users,
+.Nm usm_user
.Nd "SNMP daemon loadable module interface"
.Sh LIBRARY
Begemot SNMP library
@@ -228,6 +239,25 @@ Begemot SNMP library
.Fn index_append "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src"
.Ft void
.Fn index_append_off "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src" "u_int off"
+.Ft struct snmpd_usmstat *
+.Fn bsnmpd_get_usm_stats "void"
+.Ft void
+.Fn bsnmpd_reset_usm_stats "void"
+.Ft struct usm_user *
+.Fn usm_first_user "void"
+.Ft struct usm_user *
+.Fn usm_next_user "struct usm_user *uuser"
+.Ft struct usm_user *
+.Fn usm_find_user "uint8_t *engine" "uint32_t elen" "char *uname"
+.Ft struct usm_user *
+.Fn usm_new_user "uint8_t *engine" "uint32_t elen" "char *uname"
+.Ft void
+.Fn usm_delete_user "struct usm_user *"
+.Ft void
+.Fn usm_flush_users "void"
+.Vt extern struct usm_user *usm_user;
+.Vt extern const struct asn_oid oid_usmUnknownEngineIDs;
+.Vt extern const struct asn_oid oid_usmNotInTimeWindows;
.Sh DESCRIPTION
The
.Xr bsnmpd 1
@@ -539,7 +569,7 @@ This is the initial community string.
.El
.Pp
The function returns a globally unique community identifier.
-If a PDU is
+If a SNMPv1 or SNMPv2 PDU is
received who's community string matches, this identifier is set into the global
.Va community .
.Pp
@@ -549,10 +579,76 @@ returns the current community string for the given community.
.Pp
All communities defined by a module are automatically released when the module
is unloaded.
+.Ss THE USER-BASED SECURITY GROUP
+The scalar statistics of the USM group are held in the global variable
+.Va snmpd_usmstats :
+.Bd -literal -offset indent
+struct snmpd_usmstat {
+ uint32_t unsupported_seclevels;
+ uint32_t not_in_time_windows;
+ uint32_t unknown_users;
+ uint32_t unknown_engine_ids;
+ uint32_t wrong_digests;
+ uint32_t decrypt_errors;
+};
+.Ed
+.Fn bsnmpd_get_usm_stats
+returns a pointer to the global structure containing the statistics.
+.Fn bsnmpd_reset_usm_stats
+clears the statistics of the USM group.
+.Pp
+A global list of configured USM users is maintained by the daemon.
+.Bd -literal -offset indent
+struct usm_user {
+ struct snmp_user suser;
+ uint8_t user_engine_id[SNMP_ENGINE_ID_SIZ];
+ uint32_t user_engine_len;
+ char user_public[SNMP_USM_NAME_SIZ];
+ uint32_t user_public_len;
+ int32_t status;
+ int32_t type;
+ SLIST_ENTRY(usm_user) up;
+};
+.Ed
+This structure represents an USM user. The daemon only responds to SNMPv3 PDUs
+with user credentials matching an USM user entry in its global list.
+If a SNMPv3 PDU is received, whose security model is USM, the global
+.Va usm_user
+is set to point at the user entry that matches the credentials contained in
+the PDU.
+However, the daemon does not create or remove USM users, it gives an interface
+to external loadable module(s) to manage the list.
+.Fn usm_new_user
+adds an user entry in the list, and
+.Fn usm_delete_user
+deletes an existing entry from the list.
+.Fn usm_flush_users
+is used to remove all configured USM users.
+.Fn usm_first_user
+will return the first user in the list, or
+.Li NULL
+if the list is empty.
+.Fn usm_next_user
+will return the next user of a given entry if one exists, or
+.Li NULL .
+The list is sorted according to the USM user name and Engine ID.
+.Fn usm_find_user
+returns the USM user entry matching the given
+.Fa engine
+and
+.Fa uname
+or
+.Li NULL
+if an user with the specified name and engine id is not present in the list.
.Ss WELL KNOWN OIDS
The global variable
.Va oid_zeroDotZero
contains the OID 0.0.
+The global variables
+.Va oid_usmUnknownEngineIDs
+.Va oid_usmNotInTimeWindows
+contains the OIDs 1.3.6.1.6.3.15.1.1.4.0 and 1.3.6.1.6.3.15.1.1.2.0 used
+in the SNMPv3 USM Engine Discovery.
.Ss REQUEST ID RANGES
For modules that implement SNMP client functions besides SNMP agent functions
it may be necessary to identify SNMP requests by their identifier to allow
diff --git a/contrib/bsnmp/snmpd/snmpmod.h b/contrib/bsnmp/snmpd/snmpmod.h
index 5eba370..379070c 100644
--- a/contrib/bsnmp/snmpd/snmpmod.h
+++ b/contrib/bsnmp/snmpd/snmpmod.h
@@ -332,11 +332,137 @@ const char * comm_string(u_int);
/* community for current packet */
extern u_int community;
-/*
+/*
+ * SNMP User-based Security Model data. Modified via the snmp_usm(3) module.
+ */
+struct snmpd_usmstat {
+ uint32_t unsupported_seclevels;
+ uint32_t not_in_time_windows;
+ uint32_t unknown_users;
+ uint32_t unknown_engine_ids;
+ uint32_t wrong_digests;
+ uint32_t decrypt_errors;
+};
+
+extern struct snmpd_usmstat snmpd_usmstats;
+struct snmpd_usmstat *bsnmpd_get_usm_stats(void);
+void bsnmpd_reset_usm_stats(void);
+
+struct usm_user {
+ struct snmp_user suser;
+ uint8_t user_engine_id[SNMP_ENGINE_ID_SIZ];
+ uint32_t user_engine_len;
+ char user_public[SNMP_ADM_STR32_SIZ];
+ uint32_t user_public_len;
+ int32_t status;
+ int32_t type;
+ SLIST_ENTRY(usm_user) up;
+};
+
+SLIST_HEAD(usm_userlist, usm_user);
+struct usm_user *usm_first_user(void);
+struct usm_user *usm_next_user(struct usm_user *);
+struct usm_user *usm_find_user(uint8_t *, uint32_t, char *);
+struct usm_user *usm_new_user(uint8_t *, uint32_t, char *);
+void usm_delete_user(struct usm_user *);
+void usm_flush_users(void);
+
+/* USM user for current packet */
+extern struct usm_user *usm_user;
+
+/*
+ * SNMP View-based Access Control Model data. Modified via the snmp_vacm(3) module.
+ */
+struct vacm_group;
+
+struct vacm_user {
+ /* Security user name from USM */
+ char secname[SNMP_ADM_STR32_SIZ];
+ int32_t sec_model;
+ /* Back pointer to user assigned group name */
+ struct vacm_group *group;
+ int32_t type;
+ int32_t status;
+ SLIST_ENTRY(vacm_user) vvu;
+ SLIST_ENTRY(vacm_user) vvg;
+};
+
+SLIST_HEAD(vacm_userlist, vacm_user);
+
+struct vacm_group {
+ char groupname[SNMP_ADM_STR32_SIZ];
+ struct vacm_userlist group_users;
+ SLIST_ENTRY(vacm_group) vge;
+};
+
+SLIST_HEAD(vacm_grouplist, vacm_group);
+
+struct vacm_access {
+ /* The group name is index, not a column in the table */
+ struct vacm_group *group;
+ char ctx_prefix[SNMP_ADM_STR32_SIZ];
+ int32_t sec_model;
+ int32_t sec_level;
+ int32_t ctx_match;
+ struct vacm_view *read_view;
+ struct vacm_view *write_view;
+ struct vacm_view *notify_view;
+ int32_t type;
+ int32_t status;
+ TAILQ_ENTRY(vacm_access) vva;
+};
+
+TAILQ_HEAD(vacm_accesslist, vacm_access);
+
+struct vacm_view {
+ char viewname[SNMP_ADM_STR32_SIZ]; /* key */
+ struct asn_oid subtree; /* key */
+ uint8_t mask[16];
+ uint8_t exclude;
+ int32_t type;
+ int32_t status;
+ SLIST_ENTRY(vacm_view) vvl;
+};
+
+SLIST_HEAD(vacm_viewlist, vacm_view);
+
+struct vacm_context {
+ /* The ID of the module that registered this context */
+ int32_t regid;
+ char ctxname[SNMP_ADM_STR32_SIZ];
+ SLIST_ENTRY(vacm_context) vcl;
+};
+
+SLIST_HEAD(vacm_contextlist, vacm_context);
+
+void vacm_groups_init(void);
+struct vacm_user *vacm_first_user(void);
+struct vacm_user *vacm_next_user(struct vacm_user *);
+struct vacm_user *vacm_new_user(int32_t, char *);
+int vacm_delete_user(struct vacm_user *);
+int vacm_user_set_group(struct vacm_user *, u_char *, u_int);
+struct vacm_access *vacm_first_access_rule(void);
+struct vacm_access *vacm_next_access_rule(struct vacm_access *);
+struct vacm_access *vacm_new_access_rule(char *, char *, int32_t, int32_t);
+int vacm_delete_access_rule(struct vacm_access *);
+struct vacm_view *vacm_first_view(void);
+struct vacm_view *vacm_next_view(struct vacm_view *);
+struct vacm_view *vacm_new_view(char *, struct asn_oid *);
+int vacm_delete_view(struct vacm_view *);
+struct vacm_context *vacm_first_context(void);
+struct vacm_context *vacm_next_context(struct vacm_context *);
+struct vacm_context *vacm_add_context(char *, int32_t);
+void vacm_flush_contexts(int32_t);
+
+/*
* Well known OIDs
*/
extern const struct asn_oid oid_zeroDotZero;
+/* SNMPv3 Engine Discovery */
+extern const struct asn_oid oid_usmUnknownEngineIDs;
+extern const struct asn_oid oid_usmNotInTimeWindows;
+
/*
* Request ID ranges.
*
diff --git a/contrib/bsnmp/snmpd/trans_lsock.c b/contrib/bsnmp/snmpd/trans_lsock.c
index 3bcb333..2cddd48 100644
--- a/contrib/bsnmp/snmpd/trans_lsock.c
+++ b/contrib/bsnmp/snmpd/trans_lsock.c
@@ -31,6 +31,7 @@
* Local domain socket transport
*/
#include <sys/types.h>
+#include <sys/queue.h>
#include <sys/un.h>
#include <sys/stat.h>
diff --git a/contrib/bsnmp/snmpd/trans_udp.c b/contrib/bsnmp/snmpd/trans_udp.c
index 7e308ee..acab70e 100644
--- a/contrib/bsnmp/snmpd/trans_udp.c
+++ b/contrib/bsnmp/snmpd/trans_udp.c
@@ -31,6 +31,7 @@
* UDP transport
*/
#include <sys/types.h>
+#include <sys/queue.h>
#include <stdlib.h>
#include <syslog.h>
diff --git a/contrib/bsnmp/snmpd/trap.c b/contrib/bsnmp/snmpd/trap.c
index f37c1c8..18164cf 100644
--- a/contrib/bsnmp/snmpd/trap.c
+++ b/contrib/bsnmp/snmpd/trap.c
@@ -31,6 +31,7 @@
* TrapSinkTable
*/
#include <sys/types.h>
+#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/un.h>
#include <stdio.h>
diff --git a/contrib/bsnmp/snmpd/tree.def b/contrib/bsnmp/snmpd/tree.def
index 613bcde..00672eb 100644
--- a/contrib/bsnmp/snmpd/tree.def
+++ b/contrib/bsnmp/snmpd/tree.def
@@ -196,5 +196,15 @@
)
)
)
+ (10 snmpFrameworkMIB
+ (2 snmpFrameworkMIBObjects
+ (1 snmpEngine
+ (1 snmpEngineID OCTETSTRING | SnmpEngineID op_snmp_engine GET)
+ (2 snmpEngineBoots INTEGER op_snmp_engine GET)
+ (3 snmpEngineTime INTEGER op_snmp_engine GET)
+ (4 snmpEngineMaxMessageSize INTEGER op_snmp_engine GET)
+ )
+ )
+ )
))
)
diff --git a/contrib/traceroute/as.c b/contrib/traceroute/as.c
index ed2c440..fd2f961 100644
--- a/contrib/traceroute/as.c
+++ b/contrib/traceroute/as.c
@@ -56,13 +56,14 @@ struct aslookup {
};
void *
-as_setup(char *server)
+as_setup(const char *server)
{
struct aslookup *asn;
struct addrinfo hints, *res0, *res;
FILE *f;
int s, error;
+ s = -1;
if (server == NULL)
server = getenv("RA_SERVER");
if (server == NULL)
diff --git a/contrib/traceroute/as.h b/contrib/traceroute/as.h
index f0e66da..ce10b4b 100644
--- a/contrib/traceroute/as.h
+++ b/contrib/traceroute/as.h
@@ -30,6 +30,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-void *as_setup(char *);
+void *as_setup(const char *);
unsigned int as_lookup(void *, char *, sa_family_t);
void as_shutdown(void *);
diff --git a/contrib/traceroute/ifaddrlist.c b/contrib/traceroute/ifaddrlist.c
index 99c5fc1..b1d41d3 100644
--- a/contrib/traceroute/ifaddrlist.c
+++ b/contrib/traceroute/ifaddrlist.c
@@ -71,14 +71,14 @@ ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
{
register int fd, nipaddr;
#ifdef HAVE_SOCKADDR_SA_LEN
- register int n;
+ size_t n;
#endif
register struct ifreq *ifrp, *ifend, *ifnext, *mp;
register struct sockaddr_in *sin;
register struct ifaddrlist *al;
struct ifconf ifc;
struct ifreq ibuf[(32 * 1024) / sizeof(struct ifreq)], ifr;
-#define MAX_IPADDR (sizeof(ibuf) / sizeof(ibuf[0]))
+#define MAX_IPADDR ((int)(sizeof(ibuf) / sizeof(ibuf[0])))
static struct ifaddrlist ifaddrlist[MAX_IPADDR];
char device[sizeof(ifr.ifr_name) + 1];
@@ -91,10 +91,10 @@ ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
ifc.ifc_buf = (caddr_t)ibuf;
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 ||
- ifc.ifc_len < sizeof(struct ifreq)) {
+ ifc.ifc_len < (int)sizeof(struct ifreq)) {
if (errno == EINVAL)
(void)sprintf(errbuf,
- "SIOCGIFCONF: ifreq struct too small (%d bytes)",
+ "SIOCGIFCONF: ifreq struct too small (%zu bytes)",
sizeof(ibuf));
else
(void)sprintf(errbuf, "SIOCGIFCONF: %s",
diff --git a/contrib/traceroute/traceroute.c b/contrib/traceroute/traceroute.c
index e910d1b..db4d075 100644
--- a/contrib/traceroute/traceroute.c
+++ b/contrib/traceroute/traceroute.c
@@ -220,7 +220,6 @@ static const char rcsid[] =
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
-#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
@@ -1424,7 +1423,7 @@ tcp_check(const u_char *data, int seq)
return (ntohs(tcp->th_sport) == ident
&& ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq))
- && tcp->th_seq == (ident << 16) | (port + seq);
+ && tcp->th_seq == (((tcp_seq)ident << 16) | (port + seq));
}
void
@@ -1497,19 +1496,17 @@ u_short
p_cksum(struct ip *ip, u_short *data, int len)
{
static struct ipovly ipo;
- u_short sumh, sumd;
- u_long sumt;
+ u_short sum[2];
ipo.ih_pr = ip->ip_p;
ipo.ih_len = htons(len);
ipo.ih_src = ip->ip_src;
ipo.ih_dst = ip->ip_dst;
- sumh = in_cksum((u_short*)&ipo, sizeof(ipo)); /* pseudo ip hdr cksum */
- sumd = in_cksum((u_short*)data, len); /* payload data cksum */
- sumt = (sumh << 16) | (sumd);
+ sum[1] = in_cksum((u_short*)&ipo, sizeof(ipo)); /* pseudo ip hdr cksum */
+ sum[0] = in_cksum(data, len); /* payload data cksum */
- return ~in_cksum((u_short*)&sumt, sizeof(sumt));
+ return ~in_cksum(sum, sizeof(sum));
}
/*
diff --git a/crypto/openssl/ACKNOWLEDGMENTS b/crypto/openssl/ACKNOWLEDGMENTS
new file mode 100644
index 0000000..fb6dd91
--- /dev/null
+++ b/crypto/openssl/ACKNOWLEDGMENTS
@@ -0,0 +1,25 @@
+The OpenSSL project depends on volunteer efforts and financial support from
+the end user community. That support comes in the form of donations and paid
+sponsorships, software support contracts, paid consulting services
+and commissioned software development.
+
+Since all these activities support the continued development and improvement
+of OpenSSL we consider all these clients and customers as sponsors of the
+OpenSSL project.
+
+We would like to identify and thank the following such sponsors for their past
+or current significant support of the OpenSSL project:
+
+Very significant support:
+
+ OpenGear: www.opengear.com
+
+Significant support:
+
+ PSW Group: www.psw.net
+
+Please note that we ask permission to identify sponsors and that some sponsors
+we consider eligible for inclusion here have requested to remain anonymous.
+
+Additional sponsorship or financial support is always welcome: for more
+information please contact the OpenSSL Software Foundation.
diff --git a/crypto/openssl/CHANGES b/crypto/openssl/CHANGES
index 58fd57c..55820db 100644
--- a/crypto/openssl/CHANGES
+++ b/crypto/openssl/CHANGES
@@ -2,6 +2,18 @@
OpenSSL CHANGES
_______________
+ Changes between 0.9.8p and 0.9.8q [2 Dec 2010]
+
+ *) Disable code workaround for ancient and obsolete Netscape browsers
+ and servers: an attacker can use it in a ciphersuite downgrade attack.
+ Thanks to Martin Rex for discovering this bug. CVE-2010-4180
+ [Steve Henson]
+
+ *) Fixed J-PAKE implementation error, originally discovered by
+ Sebastien Martini, further info and confirmation from Stefan
+ Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
+ [Ben Laurie]
+
Changes between 0.9.8o and 0.9.8p [16 Nov 2010]
*) Fix extension code to avoid race conditions which can result in a buffer
diff --git a/crypto/openssl/FAQ b/crypto/openssl/FAQ
index f7bdc88..50e9314 100644
--- a/crypto/openssl/FAQ
+++ b/crypto/openssl/FAQ
@@ -52,6 +52,9 @@ OpenSSL - Frequently Asked Questions
* Why does the OpenSSL test suite fail in sha512t on x86 CPU?
* Why does compiler fail to compile sha512.c?
* Test suite still fails, what to do?
+* I think I've found a bug, what should I do?
+* I'm SURE I've found a bug, how do I report it?
+* I've found a security issue, how do I report it?
[PROG] Questions about programming with OpenSSL
@@ -79,7 +82,7 @@ OpenSSL - Frequently Asked Questions
* Which is the current version of OpenSSL?
The current version is available from <URL: http://www.openssl.org>.
-OpenSSL 1.0.0b was released on Nov 16th, 2010.
+OpenSSL 1.0.0c was released on Dec 2nd, 2010.
In addition to the current stable release, you can also access daily
snapshots of the OpenSSL development version at <URL:
@@ -131,7 +134,7 @@ OpenSSL. Information on the OpenSSL mailing lists is available from
* Where can I get a compiled version of OpenSSL?
You can finder pointers to binary distributions in
-http://www.openssl.org/related/binaries.html .
+<URL: http://www.openssl.org/related/binaries.html> .
Some applications that use OpenSSL are distributed in binary form.
When using such an application, you don't need to install OpenSSL
@@ -463,7 +466,7 @@ administrators.
Other projects do have other policies so you can for example extract the CA
bundle used by Mozilla and/or modssl as described in this article:
- http://www.mail-archive.com/modssl-users@modssl.org/msg16980.html
+ <URL: http://www.mail-archive.com/modssl-users@modssl.org/msg16980.html>
[BUILD] =======================================================================
@@ -505,7 +508,7 @@ when you run the test suite (using "make test"). The message returned is
"bc: 1 not implemented".
The best way to deal with this is to find another implementation of bc
-and compile/install it. GNU bc (see http://www.gnu.org/software/software.html
+and compile/install it. GNU bc (see <URL: http://www.gnu.org/software/software.html>
for download instructions) can be safely used, for example.
@@ -516,7 +519,7 @@ that the OpenSSL bntest throws at it. This gets triggered when you run the
test suite (using "make test"). The message returned is "bc: stack empty".
The best way to deal with this is to find another implementation of bc
-and compile/install it. GNU bc (see http://www.gnu.org/software/software.html
+and compile/install it. GNU bc (see <URL: http://www.gnu.org/software/software.html>
for download instructions) can be safely used, for example.
@@ -709,6 +712,46 @@ never make sense, and tend to emerge when you least expect them. In order
to identify one, drop optimization level, e.g. by editing CFLAG line in
top-level Makefile, recompile and re-run the test.
+* I think I've found a bug, what should I do?
+
+If you are a new user then it is quite likely you haven't found a bug and
+something is happening you aren't familiar with. Check this FAQ, the associated
+documentation and the mailing lists for similar queries. If you are still
+unsure whether it is a bug or not submit a query to the openssl-users mailing
+list.
+
+
+* I'm SURE I've found a bug, how do I report it?
+
+Bug reports with no security implications should be sent to the request
+tracker. This can be done by mailing the report to <rt@openssl.org> (or its
+alias <openssl-bugs@openssl.org>), please note that messages sent to the
+request tracker also appear in the public openssl-dev mailing list.
+
+The report should be in plain text. Any patches should be sent as
+plain text attachments because some mailers corrupt patches sent inline.
+If your issue affects multiple versions of OpenSSL check any patches apply
+cleanly and, if possible include patches to each affected version.
+
+The report should be given a meaningful subject line briefly summarising the
+issue. Just "bug in OpenSSL" or "bug in OpenSSL 0.9.8n" is not very helpful.
+
+By sending reports to the request tracker the bug can then be given a priority
+and assigned to the appropriate maintainer. The history of discussions can be
+accessed and if the issue has been addressed or a reason why not. If patches
+are only sent to openssl-dev they can be mislaid if a team member has to
+wade through months of old messages to review the discussion.
+
+See also <URL: http://www.openssl.org/support/rt.html>
+
+
+* I've found a security issue, how do I report it?
+
+If you think your bug has security implications then please send it to
+openssl-security@openssl.org if you don't get a prompt reply at least
+acknowledging receipt then resend or mail it directly to one of the
+more active team members (e.g. Steve).
+
[PROG] ========================================================================
* Is OpenSSL thread-safe?
diff --git a/crypto/openssl/Makefile b/crypto/openssl/Makefile
index f5e8546..1d0d2a0 100644
--- a/crypto/openssl/Makefile
+++ b/crypto/openssl/Makefile
@@ -4,7 +4,7 @@
## Makefile for OpenSSL
##
-VERSION=0.9.8p
+VERSION=0.9.8q
MAJOR=0
MINOR=9.8
SHLIB_VERSION_NUMBER=0.9.8
diff --git a/crypto/openssl/NEWS b/crypto/openssl/NEWS
index 65f4ef2..df190f8 100644
--- a/crypto/openssl/NEWS
+++ b/crypto/openssl/NEWS
@@ -5,6 +5,11 @@
This file gives a brief overview of the major changes between each OpenSSL
release. For more details please read the CHANGES file.
+ Major changes between OpenSSL 0.9.8p and OpenSSL 0.9.8q:
+
+ o Fix for security issue CVE-2010-4180
+ o Fix for CVE-2010-4252
+
Major changes between OpenSSL 0.9.8o and OpenSSL 0.9.8p:
o Fix for security issue CVE-2010-3864.
diff --git a/crypto/openssl/README b/crypto/openssl/README
index 36c1d5f..5b015b6 100644
--- a/crypto/openssl/README
+++ b/crypto/openssl/README
@@ -1,5 +1,5 @@
- OpenSSL 0.9.8p 16 Nov 2010
+ OpenSSL 0.9.8q 2 Dec 2010
Copyright (c) 1998-2009 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
diff --git a/crypto/openssl/crypto/evp/p_sign.c b/crypto/openssl/crypto/evp/p_sign.c
index bf41a0d..782d140 100644
--- a/crypto/openssl/crypto/evp/p_sign.c
+++ b/crypto/openssl/crypto/evp/p_sign.c
@@ -81,7 +81,7 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
unsigned char m[EVP_MAX_MD_SIZE];
unsigned int m_len;
int i,ok=0,v;
- MS_STATIC EVP_MD_CTX tmp_ctx;
+ EVP_MD_CTX tmp_ctx;
*siglen=0;
for (i=0; i<4; i++)
diff --git a/crypto/openssl/crypto/evp/p_verify.c b/crypto/openssl/crypto/evp/p_verify.c
index 2d46dff..072c127 100644
--- a/crypto/openssl/crypto/evp/p_verify.c
+++ b/crypto/openssl/crypto/evp/p_verify.c
@@ -68,7 +68,7 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
unsigned char m[EVP_MAX_MD_SIZE];
unsigned int m_len;
int i,ok=0,v;
- MS_STATIC EVP_MD_CTX tmp_ctx;
+ EVP_MD_CTX tmp_ctx;
for (i=0; i<4; i++)
{
diff --git a/crypto/openssl/crypto/jpake/jpake.c b/crypto/openssl/crypto/jpake/jpake.c
index 577b7ef..9736f89 100644
--- a/crypto/openssl/crypto/jpake/jpake.c
+++ b/crypto/openssl/crypto/jpake/jpake.c
@@ -283,23 +283,53 @@ int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx)
return 1;
}
+/* g^x is a legal value */
+static int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx)
+ {
+ BIGNUM *t;
+ int res;
+
+ if(BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0)
+ return 0;
+
+ t = BN_new();
+ BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx);
+ res = BN_is_one(t);
+ BN_free(t);
+
+ return res;
+ }
+
int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received)
{
- /* verify their ZKP(xc) */
+ if(!is_legal(received->p1.gx, ctx))
+ {
+ JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL);
+ return 0;
+ }
+
+ if(!is_legal(received->p2.gx, ctx))
+ {
+ JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL);
+ return 0;
+ }
+
+
+ /* verify their ZKP(xc) */
if(!verify_zkp(&received->p1, ctx->p.g, ctx))
{
JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED);
return 0;
}
- /* verify their ZKP(xd) */
+ /* verify their ZKP(xd) */
if(!verify_zkp(&received->p2, ctx->p.g, ctx))
{
JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED);
return 0;
}
- /* g^xd != 1 */
+ /* g^xd != 1 */
if(BN_is_one(received->p2.gx))
{
JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE);
diff --git a/crypto/openssl/crypto/jpake/jpake.h b/crypto/openssl/crypto/jpake/jpake.h
index 693ea18..fd143b4 100644
--- a/crypto/openssl/crypto/jpake/jpake.h
+++ b/crypto/openssl/crypto/jpake/jpake.h
@@ -115,6 +115,8 @@ void ERR_load_JPAKE_strings(void);
#define JPAKE_F_VERIFY_ZKP 100
/* Reason codes. */
+#define JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL 108
+#define JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL 109
#define JPAKE_R_G_TO_THE_X4_IS_ONE 105
#define JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH 106
#define JPAKE_R_HASH_OF_KEY_MISMATCH 107
diff --git a/crypto/openssl/crypto/jpake/jpake_err.c b/crypto/openssl/crypto/jpake/jpake_err.c
index 1b95067..a9a9dee 100644
--- a/crypto/openssl/crypto/jpake/jpake_err.c
+++ b/crypto/openssl/crypto/jpake/jpake_err.c
@@ -1,6 +1,6 @@
/* crypto/jpake/jpake_err.c */
/* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -80,6 +80,8 @@ static ERR_STRING_DATA JPAKE_str_functs[]=
static ERR_STRING_DATA JPAKE_str_reasons[]=
{
+{ERR_REASON(JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL),"g to the x3 is not legal"},
+{ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL),"g to the x4 is not legal"},
{ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_ONE) ,"g to the x4 is one"},
{ERR_REASON(JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH),"hash of hash of key mismatch"},
{ERR_REASON(JPAKE_R_HASH_OF_KEY_MISMATCH),"hash of key mismatch"},
diff --git a/crypto/openssl/crypto/opensslv.h b/crypto/openssl/crypto/opensslv.h
index a560e20..0da91c2 100644
--- a/crypto/openssl/crypto/opensslv.h
+++ b/crypto/openssl/crypto/opensslv.h
@@ -25,11 +25,11 @@
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
-#define OPENSSL_VERSION_NUMBER 0x0090810f
+#define OPENSSL_VERSION_NUMBER 0x0090811f
#ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8p-fips 16 Nov 2010"
+#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8q-fips 2 Dec 2010"
#else
-#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8p 16 Nov 2010"
+#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8q 2 Dec 2010"
#endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
diff --git a/crypto/openssl/crypto/stack/safestack.h b/crypto/openssl/crypto/stack/safestack.h
index 78cc485..b59c640 100644
--- a/crypto/openssl/crypto/stack/safestack.h
+++ b/crypto/openssl/crypto/stack/safestack.h
@@ -127,7 +127,7 @@ STACK_OF(type) \
sk_is_sorted(CHECKED_PTR_OF(STACK_OF(type), st))
#define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
- (STACK_OF(type) *)d2i_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), \
+ (STACK_OF(type) *)d2i_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type)*, st), \
pp, length, \
CHECKED_D2I_OF(type, d2i_func), \
CHECKED_SK_FREE_FUNC(type, free_func), \
diff --git a/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod b/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod
index 06025d1..a703ce0 100644
--- a/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod
+++ b/crypto/openssl/doc/ssl/SSL_CTX_set_options.pod
@@ -78,18 +78,7 @@ this breaks this server so 16 bytes is the way to go.
=item SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
-ssl3.netscape.com:443, first a connection is established with RC4-MD5.
-If it is then resumed, we end up using DES-CBC3-SHA. It should be
-RC4-MD5 according to 7.6.1.3, 'cipher_suite'.
-
-Netscape-Enterprise/2.01 (https://merchant.netscape.com) has this bug.
-It only really shows up when connecting via SSLv2/v3 then reconnecting
-via SSLv3. The cipher list changes....
-
-NEW INFORMATION. Try connecting with a cipher list of just
-DES-CBC-SHA:RC4-MD5. For some weird reason, each new connection uses
-RC4-MD5, but a re-connect tries to use DES-CBC-SHA. So netscape, when
-doing a re-connect, always takes the first cipher in the cipher list.
+As of OpenSSL 0.9.8q and 1.0.0c, this option has no effect.
=item SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
diff --git a/crypto/openssl/openssl.spec b/crypto/openssl/openssl.spec
index 6c659ff..e05d73a 100644
--- a/crypto/openssl/openssl.spec
+++ b/crypto/openssl/openssl.spec
@@ -2,7 +2,7 @@
%define libmaj 0
%define libmin 9
%define librel 8
-%define librev p
+%define librev q
Release: 1
%define openssldir /var/ssl
diff --git a/crypto/openssl/ssl/s3_clnt.c b/crypto/openssl/ssl/s3_clnt.c
index f0995b9..a7cb7a1 100644
--- a/crypto/openssl/ssl/s3_clnt.c
+++ b/crypto/openssl/ssl/s3_clnt.c
@@ -814,8 +814,11 @@ int ssl3_get_server_hello(SSL *s)
s->session->cipher_id = s->session->cipher->id;
if (s->hit && (s->session->cipher_id != c->id))
{
+/* Workaround is now obsolete */
+#if 0
if (!(s->options &
SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG))
+#endif
{
al=SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c
index e696450..e2d570f 100644
--- a/crypto/openssl/ssl/s3_srvr.c
+++ b/crypto/openssl/ssl/s3_srvr.c
@@ -927,6 +927,10 @@ int ssl3_get_client_hello(SSL *s)
break;
}
}
+/* Disabled because it can be used in a ciphersuite downgrade
+ * attack: CVE-2010-4180.
+ */
+#if 0
if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))
{
/* Special case as client bug workaround: the previously used cipher may
@@ -941,6 +945,7 @@ int ssl3_get_client_hello(SSL *s)
j = 1;
}
}
+#endif
if (j == 0)
{
/* we need to have the cipher in the cipher
diff --git a/etc/snmpd.config b/etc/snmpd.config
index b212f24..d729b37 100644
--- a/etc/snmpd.config
+++ b/etc/snmpd.config
@@ -12,6 +12,15 @@ system := 1 # FreeBSD
traphost := localhost
trapport := 162
+#
+# Set the SNMP engine ID.
+#
+# The snmpEngineID object required from the SNMPv3 Framework. If not explicitly set via
+# this configuration file, an ID is assigned based on the value of the
+# kern.hostid variable
+# engine := 0x80:0x10:0x08:0x10:0x80:0x25
+# snmpEngineID = $(engine)
+
# Change this!
read := "public"
# Uncomment begemotSnmpdCommunityString.0.2 below that sets the community
@@ -19,6 +28,26 @@ read := "public"
write := "geheim"
trap := "mytrap"
+# Declarations for SNMP-USER-BASED-SM-MIB authentication and privacy options
+NoAuthProtocol := 1.3.6.1.6.3.10.1.1.1
+HMACMD5AuthProtocol := 1.3.6.1.6.3.10.1.1.2
+HMACSHAAuthProtocol := 1.3.6.1.6.3.10.1.1.3
+NoPrivProtocol := 1.3.6.1.6.3.10.1.2.1
+DESPrivProtocol := 1.3.6.1.6.3.10.1.2.2
+AesCfb128Protocol := 1.3.6.1.6.3.10.1.2.4
+
+#
+# SNMPv3 USM User definition
+#
+# The localized hex password for a user may be obtained by setting SNMPUSER, SNMPPASSWD,
+# SNMPAUTH and SNMPPRIV environment variables to the desired parameters and invoking
+# 'bsnmpget -v 3 -D -K -o verbose' against the running bsnmpd(1). For other
+# usages refer to the bsnmpget(1) manual page. The following lines define a user "bsnmp"
+# with a private password "bsnmp", localized for the above engine ID.
+#
+# user1 := "bsnmp"
+# user1passwd := 0x1b:0x6d:0x9e:0x94:0xbe:0x19:0x17:0xfb:0xde:0x60:0x46:0xfe:0x59:0x6f:0x61:0x95:0xf2:0xc9:0x57:0x1f
+
#
# Configuration
#
@@ -72,6 +101,113 @@ begemotSnmpdModulePath."mibII" = "/usr/lib/snmp_mibII.so"
#begemotIfForcePoll = 2000
#
+# SNMPv3 User-based security module - must be loaded for SNMPv3 USM
+#
+#begemotSnmpdModulePath."usm" = "/usr/lib/snmp_usm.so"
+
+#
+# SNMPv3 USM User definition.
+#
+
+#%usm
+
+#
+# The following block creates a user with name "bsnmp" and sets privacy
+# and encryption options to SHA256 message digests and AES encryption
+# for this user.
+#
+# usmUserStatus.$(engine).$(user1) = 5
+# usmUserAuthProtocol.$(engine).$(user1) = $(HMACSHAAuthProtocol)
+# usmUserAuthKeyChange.$(engine).$(user1) = $(user1passwd)
+# usmUserPrivProtocol.$(engine).$(user1) = $(AesCfb128Protocol)
+# usmUserPrivKeyChange.$(engine).$(user1) = $(user1passwd)
+# usmUserStatus.$(engine).$(user1) = 1
+#
+
+#
+# The following block creates a user with name "public" with no authentication
+# or encryption options.
+#
+# usmUserStatus.$(engine).$(read) = 5
+# usmUserAuthProtocol.$(engine).$(read) = $(NoAuthProtocol)
+# usmUserPrivProtocol.$(engine).$(read) = $(NoPrivProtocol)
+# usmUserStatus.$(engine).$(read) = 1
+#
+
+#
+# SNMPv3 View-based Access Control module
+#
+#begemotSnmpdModulePath."vacm" = "/usr/lib/snmp_vacm.so"
+
+#
+# Definition of view-based access control entries.
+#
+#%vacm
+
+# Definition of a SNMPv1 group
+# vacmSecurityToGroupStatus.1.$(read) = 4
+# vacmGroupName.1.$(read) = $(read)
+
+# Definition of SNMPv2 group
+# vacmSecurityToGroupStatus.2.$(write) = 4
+# vacmGroupName.2.$(write) = $(write)
+
+# Definition of SNMPv3 group with users "bsnmp" and "public"
+# vacmSecurityToGroupStatus.3.$(user1) = 4
+# vacmGroupName.3.$(user1) = $(write)
+# vacmSecurityToGroupStatus.3.$(read) = 4
+# vacmGroupName.3.$(read) = $(write)
+
+#
+# The OID of the .iso.org.dod.internet subtree
+#
+# internetoid := 1.3.6.1
+# internetoidlen := 4
+
+# Enumerated values for the privacy options
+# noAuthNoPriv := 1
+# authNoPriv := 2
+# authPriv := 3
+
+#
+# Definitions of two views
+#
+# vacmViewTreeFamilyStatus."internet".$(internetoidlen).$(internetoid) = 4
+# vacmViewTreeFamilyStatus."restricted".$(internetoidlen).$(internetoid) = 4
+
+#
+# Access control
+#
+
+#
+# Read-only access for SNMPv1 users
+#
+# vacmAccessStatus.$(read)."".1.1 = 4
+# vacmAccessReadViewName.$(read)."".1.1 = "internet"
+
+#
+# Read-write access for SNMPv2 users
+#
+# vacmAccessStatus.$(write)."".2.1 = 4
+# vacmAccessReadViewName.$(write)."".2.1 = "internet"
+# vacmAccessWriteViewName.$(write)."".2.1 = "internet"
+
+#
+# Read-write-notify access for SNMPv3 USM users with noAuthNoPriv
+#
+# vacmAccessStatus.$(write)."".3.$(noAuthNoPriv) = 4
+# vacmAccessReadViewName.$(write)."".3.$(noAuthNoPriv) = "internet"
+# vacmAccessWriteViewName.$(write)."".3.$(noAuthNoPriv) = "internet"
+# vacmAccessNotifyViewName.$(write)."".3.$(noAuthNoPriv) = "internet"
+
+#
+#Read-write-notify access to restricted for SNMPv3 USM users with authPriv
+#
+# vacmAccessStatus.$(write)."".3.$(authPriv) = 4
+# vacmAccessReadViewName.$(write)."".3.$(authPriv) = "restricted"
+# vacmAccessWriteViewName.$(write)."".3.$(authPriv) = "restricted"
+# vacmAccessNotifyViewName.$(write)."".3.$(authPriv) = "restricted"
+
# Netgraph module
#
#begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
diff --git a/games/bcd/bcd.6 b/games/bcd/bcd.6
index dc64317..e9343fe 100644
--- a/games/bcd/bcd.6
+++ b/games/bcd/bcd.6
@@ -9,11 +9,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
diff --git a/games/caesar/caesar.6 b/games/caesar/caesar.6
index 28ffe86..91e9af8 100644
--- a/games/caesar/caesar.6
+++ b/games/caesar/caesar.6
@@ -9,11 +9,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
diff --git a/games/caesar/rot13.sh b/games/caesar/rot13.sh
index 1b88b63..853205b 100644
--- a/games/caesar/rot13.sh
+++ b/games/caesar/rot13.sh
@@ -11,11 +11,7 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
-# 3. All advertising materials mentioning features or use of this software
-# must display the following acknowledgement:
-# This product includes software developed by the University of
-# California, Berkeley and its contributors.
-# 4. Neither the name of the University nor the names of its contributors
+# 3. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@@ -32,6 +28,6 @@
# SUCH DAMAGE.
#
# @(#)rot13.sh 8.1 (Berkeley) 5/31/93
-#
+# $FreeBSD$
exec /usr/games/caesar 13 "$@"
diff --git a/games/factor/factor.6 b/games/factor/factor.6
index 07fc7b9..a4d35e9 100644
--- a/games/factor/factor.6
+++ b/games/factor/factor.6
@@ -12,11 +12,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
diff --git a/games/morse/morse.6 b/games/morse/morse.6
index f26d9db..f0d30d7 100644
--- a/games/morse/morse.6
+++ b/games/morse/morse.6
@@ -10,11 +10,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
diff --git a/games/number/number.6 b/games/number/number.6
index eb7892d..a8be9ff 100644
--- a/games/number/number.6
+++ b/games/number/number.6
@@ -9,11 +9,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
diff --git a/games/pom/pom.6 b/games/pom/pom.6
index 8634928..bb89436 100644
--- a/games/pom/pom.6
+++ b/games/pom/pom.6
@@ -9,11 +9,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
diff --git a/games/random/random.6 b/games/random/random.6
index 33a3511..5481576 100644
--- a/games/random/random.6
+++ b/games/random/random.6
@@ -9,11 +9,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
+.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
diff --git a/lib/csu/amd64/crt1.c b/lib/csu/amd64/crt1.c
index 3bc4809..998477a 100644
--- a/lib/csu/amd64/crt1.c
+++ b/lib/csu/amd64/crt1.c
@@ -24,6 +24,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#ifndef lint
#ifndef __GNUC__
#error "GCC is needed to compile this file"
@@ -92,5 +95,3 @@ __asm__("eprol:");
_init();
exit( main(argc, argv, env) );
}
-
-__asm__(".ident\t\"$FreeBSD$\"");
diff --git a/lib/csu/amd64/crti.S b/lib/csu/amd64/crti.S
index c46f001..37698ba 100644
--- a/lib/csu/amd64/crti.S
+++ b/lib/csu/amd64/crti.S
@@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.section .init,"ax",@progbits
.align 4
.globl _init
@@ -36,6 +39,3 @@ _init:
.type _fini,@function
_fini:
subq $8,%rsp
-
- .section .rodata
-.ascii "$FreeBSD$\0"
diff --git a/lib/csu/amd64/crtn.S b/lib/csu/amd64/crtn.S
index d6d09da..eb6d4df 100644
--- a/lib/csu/amd64/crtn.S
+++ b/lib/csu/amd64/crtn.S
@@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.section .init,"ax",@progbits
addq $8,%rsp
ret
@@ -30,6 +33,3 @@
.section .fini,"ax",@progbits
addq $8,%rsp
ret
-
- .section .rodata
-.ascii "$FreeBSD$\0"
diff --git a/lib/csu/arm/crt1.c b/lib/csu/arm/crt1.c
index 4319f17..f2d4dbf 100644
--- a/lib/csu/arm/crt1.c
+++ b/lib/csu/arm/crt1.c
@@ -39,6 +39,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#ifndef lint
#ifndef __GNUC__
#error "GCC is needed to compile this file"
@@ -49,7 +52,6 @@
#include "libc_private.h"
#include "crtbrand.c"
-#include <machine/asm.h>
struct Struct_Obj_Entry;
struct ps_strings;
@@ -136,5 +138,3 @@ __asm__(".text");
__asm__("eprol:");
__asm__(".previous");
#endif
-
-__asm__(".ident\t\"$FreeBSD$\"");
diff --git a/lib/csu/arm/crtn.S b/lib/csu/arm/crtn.S
index d148b1e..962f0ed 100644
--- a/lib/csu/arm/crtn.S
+++ b/lib/csu/arm/crtn.S
@@ -1,5 +1,6 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
+
.section .init,"ax",%progbits
ldmea fp, {fp, sp, pc}
mov pc, lr
diff --git a/lib/csu/i386-elf/crt1_c.c b/lib/csu/i386-elf/crt1_c.c
index c38f267..1eadc7c 100644
--- a/lib/csu/i386-elf/crt1_c.c
+++ b/lib/csu/i386-elf/crt1_c.c
@@ -26,6 +26,9 @@
* $FreeBSD$
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#ifndef lint
#ifndef __GNUC__
#error "GCC is needed to compile this file"
diff --git a/lib/csu/i386-elf/crt1_s.S b/lib/csu/i386-elf/crt1_s.S
index 949d164..f8c1d73 100644
--- a/lib/csu/i386-elf/crt1_s.S
+++ b/lib/csu/i386-elf/crt1_s.S
@@ -25,6 +25,8 @@
* $FreeBSD$
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
.text
.align 4
@@ -47,5 +49,3 @@ _start:
int3
.cfi_endproc
.size _start, . - _start
-
- .ident "$FreeBSD$"
diff --git a/lib/csu/i386-elf/crti.S b/lib/csu/i386-elf/crti.S
index bb11f3a..608dc21 100644
--- a/lib/csu/i386-elf/crti.S
+++ b/lib/csu/i386-elf/crti.S
@@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.section .init,"ax",@progbits
.align 4
.globl _init
@@ -36,6 +39,3 @@ _init:
.type _fini,@function
_fini:
sub $12,%esp /* re-align stack pointer */
-
- .section .rodata
-.ascii "$FreeBSD$\0"
diff --git a/lib/csu/i386-elf/crtn.S b/lib/csu/i386-elf/crtn.S
index bc90d31..9ce5bec 100644
--- a/lib/csu/i386-elf/crtn.S
+++ b/lib/csu/i386-elf/crtn.S
@@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.section .init,"ax",@progbits
add $12,%esp
ret
@@ -30,6 +33,3 @@
.section .fini,"ax",@progbits
add $12,%esp
ret
-
- .section .rodata
-.ascii "$FreeBSD$\0"
diff --git a/lib/csu/ia64/crt1.S b/lib/csu/ia64/crt1.S
index 10e1a63..6ff9cd9 100644
--- a/lib/csu/ia64/crt1.S
+++ b/lib/csu/ia64/crt1.S
@@ -24,7 +24,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
- .ident "$FreeBSD$"
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
.text
diff --git a/lib/csu/ia64/crti.S b/lib/csu/ia64/crti.S
index 1314cb3..66ef948 100644
--- a/lib/csu/ia64/crti.S
+++ b/lib/csu/ia64/crti.S
@@ -26,6 +26,9 @@
* $FreeBSD$
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
/*
* This file (and its companion crtn.S) form the terminators of the
* .init and .fini sections.
diff --git a/lib/csu/ia64/crtn.S b/lib/csu/ia64/crtn.S
index 26d40d3..681fba3 100644
--- a/lib/csu/ia64/crtn.S
+++ b/lib/csu/ia64/crtn.S
@@ -26,6 +26,9 @@
* $FreeBSD$
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.file "crtn.S"
.section .init,"ax",@progbits
diff --git a/lib/csu/powerpc/crt1.c b/lib/csu/powerpc/crt1.c
index 3a2f6dd..67de2f5 100644
--- a/lib/csu/powerpc/crt1.c
+++ b/lib/csu/powerpc/crt1.c
@@ -39,6 +39,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#ifndef lint
#ifndef __GNUC__
#error "GCC is needed to compile this file"
@@ -120,5 +123,3 @@ __asm__(".text");
__asm__("eprol:");
__asm__(".previous");
#endif
-
-__asm__(".ident\t\"$FreeBSD$\"");
diff --git a/lib/csu/powerpc/crti.S b/lib/csu/powerpc/crti.S
index 75d4345..544bfa9 100644
--- a/lib/csu/powerpc/crti.S
+++ b/lib/csu/powerpc/crti.S
@@ -22,7 +22,10 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.section .init,"ax",@progbits
.align 2
.globl _init
@@ -44,7 +47,3 @@ _fini:
stw 31,12(1)
stw 0,20(1)
mr 31,1
-
-
- .section .rodata
-.ascii "$FreeBSD$\0"
diff --git a/lib/csu/powerpc/crtn.S b/lib/csu/powerpc/crtn.S
index 80735cc..d3baa70 100644
--- a/lib/csu/powerpc/crtn.S
+++ b/lib/csu/powerpc/crtn.S
@@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.section .init,"ax",@progbits
lwz 11,0(1)
lwz 0,4(11)
@@ -39,7 +42,3 @@
lwz 31,-4(11)
mr 1,11
blr
-
-
- .section .rodata
-.ascii "$FreeBSD$\0"
diff --git a/lib/csu/powerpc64/crt1.c b/lib/csu/powerpc64/crt1.c
index 080691c..080bd4d 100644
--- a/lib/csu/powerpc64/crt1.c
+++ b/lib/csu/powerpc64/crt1.c
@@ -39,6 +39,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#ifndef lint
#ifndef __GNUC__
#error "GCC is needed to compile this file"
@@ -119,5 +122,3 @@ __asm__(".text");
__asm__("eprol:");
__asm__(".previous");
#endif
-
-__asm__(".ident\t\"$FreeBSD$\"");
diff --git a/lib/csu/powerpc64/crti.S b/lib/csu/powerpc64/crti.S
index 4118765..edca7ba 100644
--- a/lib/csu/powerpc64/crti.S
+++ b/lib/csu/powerpc64/crti.S
@@ -22,7 +22,10 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.section .init,"ax",@progbits
.align 2
.globl _init
@@ -56,6 +59,3 @@ _fini:
stdu 1,-48(1)
mflr 0
std 0,64(1)
-
- .section .rodata
-.ascii "$FreeBSD$\0"
diff --git a/lib/csu/powerpc64/crtn.S b/lib/csu/powerpc64/crtn.S
index 42ca083..c62f913 100644
--- a/lib/csu/powerpc64/crtn.S
+++ b/lib/csu/powerpc64/crtn.S
@@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.section .init,"ax",@progbits
ld %r1,0(%r1)
ld 0,16(%r1)
@@ -35,7 +38,3 @@
ld 0,16(%r1)
mtlr 0
blr
-
-
- .section .rodata
-.ascii "$FreeBSD$\0"
diff --git a/lib/csu/sparc64/crt1.c b/lib/csu/sparc64/crt1.c
index f27c59b..3593c95 100644
--- a/lib/csu/sparc64/crt1.c
+++ b/lib/csu/sparc64/crt1.c
@@ -30,6 +30,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#ifndef lint
#ifndef __GNUC__
#error "GCC is needed to compile this file"
@@ -121,5 +124,3 @@ __asm__(".text");
__asm__("eprol:");
__asm__(".previous");
#endif
-
-__asm__(".ident\t\"$FreeBSD$\"");
diff --git a/lib/csu/sparc64/crti.S b/lib/csu/sparc64/crti.S
index e3e81af..9e529a5 100644
--- a/lib/csu/sparc64/crti.S
+++ b/lib/csu/sparc64/crti.S
@@ -26,6 +26,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.file "crti.S"
/* The minimum stack frame size (bytes) is:
@@ -52,7 +55,3 @@ _init:
.align 4
_fini:
save %sp,-192,%sp
-
-
- .section .rodata
-.ascii "$FreeBSD$\0"
diff --git a/lib/csu/sparc64/crtn.S b/lib/csu/sparc64/crtn.S
index 7c0d160..5b6d4a7 100644
--- a/lib/csu/sparc64/crtn.S
+++ b/lib/csu/sparc64/crtn.S
@@ -26,6 +26,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
.file "crtn.S"
.section .init,"ax",@progbits
@@ -37,6 +40,3 @@
.align 4
ret
restore
-
- .section .rodata
-.ascii "$FreeBSD$\0"
diff --git a/lib/libarchive/archive_read_extract.c b/lib/libarchive/archive_read_extract.c
index 86b378b..8ae5dec 100644
--- a/lib/libarchive/archive_read_extract.c
+++ b/lib/libarchive/archive_read_extract.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#endif
#include "archive.h"
+#include "archive_entry.h"
#include "archive_private.h"
#include "archive_read_private.h"
#include "archive_write_disk_private.h"
@@ -107,7 +108,7 @@ archive_read_extract2(struct archive *_a, struct archive_entry *entry,
if (r != ARCHIVE_OK)
/* If _write_header failed, copy the error. */
archive_copy_error(&a->archive, ad);
- else
+ else if (archive_entry_size(entry) > 0)
/* Otherwise, pour data into the entry. */
r = copy_data(_a, ad);
r2 = archive_write_finish_entry(ad);
diff --git a/lib/libarchive/test/Makefile b/lib/libarchive/test/Makefile
index c721f57..f9fead9 100644
--- a/lib/libarchive/test/Makefile
+++ b/lib/libarchive/test/Makefile
@@ -2,10 +2,6 @@
# Where to find the libarchive sources
LA_SRCDIR=${.CURDIR}/..
-.PATH: ${LA_SRCDIR}
-
-# Get a list of all libarchive source files
-LA_SRCS!=make -f ${LA_SRCDIR}/Makefile -V SRCS
TESTS= \
test_acl_basic.c \
@@ -113,8 +109,8 @@ TESTS= \
test_write_open_memory.c
-# Build the test program using all libarchive sources + the test sources.
-SRCS= ${LA_SRCS} \
+# Build the test program.
+SRCS= \
${TESTS} \
list.h \
main.c \
@@ -125,14 +121,11 @@ NO_MAN=yes
PROG=libarchive_test
INTERNALPROG=yes # Don't install this; it's just for testing
DPADD=${LIBBZ2} ${LIBZ} ${LIBMD} ${LIBCRYPTO} ${LIBBSDXML}
-CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
-LDADD= -lz -lbz2 -lmd -lcrypto -lbsdxml
+LDADD= -L ${.OBJDIR}/.. -larchive
+LDADD+= -lz -lbz2 -llzma -lmd -lcrypto -lbsdxml
CFLAGS+= -g
CFLAGS+= -I${LA_SRCDIR} -I.
-
-# Uncomment to build and test lzma and xz support via liblzma
-#CFLAGS+= -I/usr/local/include -DHAVE_LIBLZMA=1 -DHAVE_LZMA_H=1
-#LDADD+= -L/usr/local/lib -llzma
+CFLAGS+= -DHAVE_LIBLZMA=1 -DHAVE_LZMA_H=1
# Uncomment to link against dmalloc
#LDADD+= -L/usr/local/lib -ldmalloc
diff --git a/lib/libarchive/test/test_acl_freebsd.c b/lib/libarchive/test/test_acl_freebsd.c
index 88efb19..fbb744d 100644
--- a/lib/libarchive/test/test_acl_freebsd.c
+++ b/lib/libarchive/test/test_acl_freebsd.c
@@ -220,6 +220,11 @@ DEFINE_TEST(test_acl_freebsd)
skipping("ACL tests require that ACL support be enabled on the filesystem");
return;
}
+ if (n != 0 && errno == EINVAL) {
+ close(fd);
+ skipping("POSIX.1e ACL tests require that POSIX.1e ACL support be enabled on the filesystem");
+ return;
+ }
failure("acl_set_fd(): errno = %d (%s)",
errno, strerror(errno));
assertEqualInt(0, n);
diff --git a/lib/libbsnmp/libbsnmp/Makefile b/lib/libbsnmp/libbsnmp/Makefile
index a0ceecd..d33808d 100644
--- a/lib/libbsnmp/libbsnmp/Makefile
+++ b/lib/libbsnmp/libbsnmp/Makefile
@@ -2,6 +2,8 @@
#
# Author: Harti Brandt <harti@freebsd.org>
+.include <bsd.own.mk>
+
CONTRIB= ${.CURDIR}/../../../contrib/bsnmp/lib
.PATH: ${CONTRIB}
@@ -11,8 +13,13 @@ SHLIBDIR?= /lib
CFLAGS+= -I${CONTRIB} -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY
CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DQUADFMT='"llu"' -DQUADXFMT='"llx"'
-SRCS= asn1.c snmp.c snmpagent.c snmpclient.c support.c
-INCS= asn1.h snmp.h snmpagent.h snmpclient.h
+.if ${MK_OPENSSL} != "no"
+CFLAGS+= -DHAVE_LIBCRYPTO
+LDADD+= -lcrypto
+.endif
+
+SRCS= asn1.c snmp.c snmpagent.c snmpclient.c snmpcrypto.c support.c
+INCS= asn1.h snmp.h snmpagent.h snmpclient.h
MAN= asn1.3 bsnmplib.3 bsnmpclient.3 bsnmpagent.3
.include <bsd.lib.mk>
diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c
index d718496..be7bc8a 100644
--- a/lib/libc/stdio/freopen.c
+++ b/lib/libc/stdio/freopen.c
@@ -150,14 +150,6 @@ freopen(file, mode, fp)
/* Get a new descriptor to refer to the new file. */
f = _open(file, oflags, DEFFILEMODE);
- if (f < 0 && isopen) {
- /* If out of fd's close the old one and try again. */
- if (errno == ENFILE || errno == EMFILE) {
- (void) (*fp->_close)(fp->_cookie);
- isopen = 0;
- f = _open(file, oflags, DEFFILEMODE);
- }
- }
sverrno = errno;
finish:
@@ -165,9 +157,11 @@ finish:
* Finish closing fp. Even if the open succeeded above, we cannot
* keep fp->_base: it may be the wrong size. This loses the effect
* of any setbuffer calls, but stdio has always done this before.
+ *
+ * Leave the existing file descriptor open until dup2() is called
+ * below to avoid races where a concurrent open() in another thread
+ * could claim the existing descriptor.
*/
- if (isopen)
- (void) (*fp->_close)(fp->_cookie);
if (fp->_flags & __SMBF)
free((char *)fp->_bf._base);
fp->_w = 0;
@@ -186,6 +180,8 @@ finish:
memset(&fp->_mbstate, 0, sizeof(mbstate_t));
if (f < 0) { /* did not get it after all */
+ if (isopen)
+ (void) (*fp->_close)(fp->_cookie);
fp->_flags = 0; /* set it free */
FUNLOCKFILE(fp);
errno = sverrno; /* restore in case _close clobbered */
@@ -197,11 +193,12 @@ finish:
* to maintain the descriptor. Various C library routines (perror)
* assume stderr is always fd STDERR_FILENO, even if being freopen'd.
*/
- if (wantfd >= 0 && f != wantfd) {
+ if (wantfd >= 0) {
if (_dup2(f, wantfd) >= 0) {
(void)_close(f);
f = wantfd;
- }
+ } else
+ (void)_close(fp->_file);
}
/*
diff --git a/lib/libgeom/libgeom.3 b/lib/libgeom/libgeom.3
index 04cf2fc..b897fad 100644
--- a/lib/libgeom/libgeom.3
+++ b/lib/libgeom/libgeom.3
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 16, 2010
+.Dd December 4, 2010
.Dt LIBGEOM 3
.Os
.Sh NAME
@@ -382,8 +382,6 @@ if (errstr != NULL)
err(1, "could not destroy ccd: %s", errstr);
gctl_free(H);
.Ed
-.Sh SEE ALSO
-.Pa http://ezine.daemonnews.org/200308/blueprints.html
.Sh HISTORY
The
.Nm geom
diff --git a/lib/msun/Makefile b/lib/msun/Makefile
index 87bd954..0048e25 100644
--- a/lib/msun/Makefile
+++ b/lib/msun/Makefile
@@ -45,7 +45,8 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \
e_expf.c e_fmod.c e_fmodf.c e_gamma.c e_gamma_r.c e_gammaf.c \
e_gammaf_r.c e_hypot.c e_hypotf.c e_j0.c e_j0f.c e_j1.c e_j1f.c \
e_jn.c e_jnf.c e_lgamma.c e_lgamma_r.c e_lgammaf.c e_lgammaf_r.c \
- e_log.c e_log10.c e_log10f.c e_logf.c e_pow.c e_powf.c e_rem_pio2.c \
+ e_log.c e_log10.c e_log10f.c e_log2.c e_log2f.c e_logf.c \
+ e_pow.c e_powf.c e_rem_pio2.c \
e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c e_scalbf.c \
e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c fenv.c \
k_cos.c k_cosf.c k_rem_pio2.c k_sin.c k_sinf.c \
@@ -113,6 +114,12 @@ COMMON_SRCS:= ${COMMON_SRCS:N${i:R}.c}
.endfor
.endif
+# Some files need certain gcc built-in functions to be disabled, since gcc's
+# model of the functions bogusly assumes -fno-trapping-math.
+XRINT_CFLAGS= -fno-builtin-rint -fno-builtin-rintf -fno-builtin-rintl
+CFLAGS+= ${XRINT_CFLAGS}
+XRINT_CFLAGS:= ${.IMPSRC:M*/s_nearbyint.c:C/^.+$/${XRINT_CFLAGS}/:C/^$//}
+
SRCS= ${COMMON_SRCS} ${ARCH_SRCS}
INCS= fenv.h math.h
@@ -169,7 +176,7 @@ MLINKS+=j0.3 j1.3 j0.3 jn.3 j0.3 y0.3 j0.3 y1.3 j0.3 y1f.3 j0.3 yn.3
MLINKS+=j0.3 j0f.3 j0.3 j1f.3 j0.3 jnf.3 j0.3 y0f.3 j0.3 ynf.3
MLINKS+=lgamma.3 gamma.3 lgamma.3 gammaf.3 lgamma.3 lgammaf.3 \
lgamma.3 tgamma.3 lgamma.3 tgammaf.3
-MLINKS+=log.3 log10.3 log.3 log10f.3 log.3 log1p.3 log.3 log1pf.3 log.3 logf.3
+MLINKS+=log.3 log10.3 log.3 log10f.3 log.3 log1p.3 log.3 log1pf.3 log.3 logf.3 log.3 log2.3 log.3 log2f.3
MLINKS+=lrint.3 llrint.3 lrint.3 llrintf.3 lrint.3 llrintl.3 \
lrint.3 lrintf.3 lrint.3 lrintl.3
MLINKS+=lround.3 llround.3 lround.3 llroundf.3 lround.3 llroundl.3 \
diff --git a/lib/msun/Symbol.map b/lib/msun/Symbol.map
index 429a76f..69618e6 100644
--- a/lib/msun/Symbol.map
+++ b/lib/msun/Symbol.map
@@ -222,4 +222,6 @@ FBSD_1.1 {
/* First added in 9.0-CURRENT */
FBSD_1.2 {
__isnanf;
+ log2;
+ log2f;
};
diff --git a/lib/msun/man/log.3 b/lib/msun/man/log.3
index 1934473..b9fd83c 100644
--- a/lib/msun/man/log.3
+++ b/lib/msun/man/log.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2008 David Schultz <das@FreeBSD.org>
+.\" Copyright (c) 2008-2010 David Schultz <das@FreeBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 17, 2008
+.Dd December 5, 2010
.Dt LOG 3
.Os
.Sh NAME
@@ -33,6 +33,8 @@
.Nm logl ,
.Nm log10 ,
.Nm log10f ,
+.Nm log2 ,
+.Nm log2f ,
.Nm log1p ,
.Nm log1pf
.Nd logarithm functions
@@ -49,6 +51,10 @@
.Ft float
.Fn log10f "float x"
.Ft double
+.Fn log2 "double x"
+.Ft float
+.Fn log2f "float x"
+.Ft double
.Fn log1p "double x"
.Ft float
.Fn log1pf "float x"
@@ -65,6 +71,12 @@ The
and
.Fn log10f
functions compute the logarithm base 10 of
+.Fa x ,
+while
+.Fn log2
+and
+.Fn log2f
+compute the logarithm base 2 of
.Fa x .
.Pp
The
@@ -97,6 +109,8 @@ The
.Fn logf ,
.Fn log10 ,
.Fn log10f ,
+.Fn log2 ,
+.Fn log2f ,
.Fn log1p ,
and
.Fn log1pf
diff --git a/lib/msun/man/math.3 b/lib/msun/man/math.3
index 4690a9a..39aa8ab 100644
--- a/lib/msun/man/math.3
+++ b/lib/msun/man/math.3
@@ -28,7 +28,7 @@
.\" from: @(#)math.3 6.10 (Berkeley) 5/6/91
.\" $FreeBSD$
.\"
-.Dd December 16, 2007
+.Dd December 5, 2010
.Dt MATH 3
.Os
.Sh NAME
@@ -182,7 +182,7 @@ lgamma log gamma function
log natural logarithm
log10 logarithm to base 10
log1p log(1+x)
-.\" log2 base 2 logarithm
+log2 base 2 logarithm
pow exponential x**y
sin trigonometric function
sinh hyperbolic function
@@ -194,8 +194,8 @@ y1 Bessel function of the second kind of the order 1
yn Bessel function of the second kind of the order n
.El
.Pp
-Unlike the algebraic functions listed earlier, the routines
-in this section may not produce a result that is correctly rounded,
+The routines
+in this section might not produce a result that is correctly rounded,
so reproducible results cannot be guaranteed across platforms.
For most of these functions, however, incorrect rounding occurs
rarely, and then only in very-close-to-halfway cases.
@@ -221,18 +221,19 @@ and
values, were written for or imported into subsequent versions of FreeBSD.
.Sh BUGS
The
-.Fn log2
-function is missing, and many functions are not available in their
+.Fn cbrt
+function and many of the transcendental functions
+are not available in their
.Vt "long double"
variants.
.Pp
Many of the routines to compute transcendental functions produce
inaccurate results in other than the default rounding mode.
.Pp
-On some architectures, trigonometric argument reduction is not
-performed accurately, resulting in errors greater than 1
-.Em ulp
-for large arguments to
+On the i386 platform, trigonometric argument reduction is not
+performed accurately for huge arguments, resulting in
+large errors
+for such arguments to
.Fn cos ,
.Fn sin ,
and
diff --git a/lib/msun/src/e_log2.c b/lib/msun/src/e_log2.c
new file mode 100644
index 0000000..6cf3dbc
--- /dev/null
+++ b/lib/msun/src/e_log2.c
@@ -0,0 +1,60 @@
+
+/* @(#)e_log10.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Return the base 2 logarithm of x. See k_log.c for details on the algorithm.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include "k_log.h"
+
+static const double
+two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */
+ivln2lo = 1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */
+
+static const double zero = 0.0;
+
+double
+__ieee754_log2(double x)
+{
+ double f,hi,lo;
+ int32_t i,k,hx;
+ u_int32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx&0x7fffffff)|lx)==0)
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+ GET_HIGH_WORD(hx,x);
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ hx &= 0x000fffff;
+ i = (hx+0x95f64)&0x100000;
+ SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
+ k += (i>>20);
+ f = __kernel_log(x);
+ hi = x = x - 1;
+ SET_LOW_WORD(hi,0);
+ lo = x - hi;
+ return (x+f)*ivln2lo + (lo+f)*ivln2hi + hi*ivln2hi + k;
+}
diff --git a/lib/msun/src/e_log2f.c b/lib/msun/src/e_log2f.c
new file mode 100644
index 0000000..bb308d3
--- /dev/null
+++ b/lib/msun/src/e_log2f.c
@@ -0,0 +1,58 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Return the base 2 logarithm of x. See k_log.c for details on the algorithm.
+ */
+
+#include "math.h"
+#include "math_private.h"
+#include "k_logf.h"
+
+static const float
+two25 = 3.3554432000e+07, /* 0x4c000000 */
+ivln2hi = 1.4428710938e+00, /* 0x3fb8b000 */
+ivln2lo = -1.7605285393e-04; /* 0xb9389ad4 */
+
+static const float zero = 0.0;
+
+float
+__ieee754_log2f(float x)
+{
+ float f,hi,lo;
+ int32_t i,k,hx;
+
+ GET_FLOAT_WORD(hx,x);
+
+ k=0;
+ if (hx < 0x00800000) { /* x < 2**-126 */
+ if ((hx&0x7fffffff)==0)
+ return -two25/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 25; x *= two25; /* subnormal number, scale up x */
+ GET_FLOAT_WORD(hx,x);
+ }
+ if (hx >= 0x7f800000) return x+x;
+ k += (hx>>23)-127;
+ hx &= 0x007fffff;
+ i = (hx+(0x4afb0d))&0x800000;
+ SET_FLOAT_WORD(x,hx|(i^0x3f800000)); /* normalize x or x/2 */
+ k += (i>>23);
+ f = __kernel_logf(x);
+ x = x - (float)1.0;
+ GET_FLOAT_WORD(hx,x);
+ SET_FLOAT_WORD(hi,hx&0xfffff000);
+ lo = x - hi;
+ return (x+f)*ivln2lo + (lo+f)*ivln2hi + hi*ivln2hi + k;
+}
diff --git a/lib/msun/src/k_log.h b/lib/msun/src/k_log.h
new file mode 100644
index 0000000..206355c
--- /dev/null
+++ b/lib/msun/src/k_log.h
@@ -0,0 +1,116 @@
+
+/* @(#)e_log.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* __kernel_log(x)
+ * Return log(x) - (x-1) for x in ~[sqrt(2)/2, sqrt(2)].
+ *
+ * The following describes the overall strategy for computing
+ * logarithms in base e. The argument reduction and adding the final
+ * term of the polynomial are done by the caller for increased accuracy
+ * when different bases are used.
+ *
+ * Method :
+ * 1. Argument Reduction: find k and f such that
+ * x = 2^k * (1+f),
+ * where sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ * 2. Approximation of log(1+f).
+ * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ * = 2s + s*R
+ * We use a special Reme algorithm on [0,0.1716] to generate
+ * a polynomial of degree 14 to approximate R The maximum error
+ * of this polynomial approximation is bounded by 2**-58.45. In
+ * other words,
+ * 2 4 6 8 10 12 14
+ * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
+ * (the values of Lg1 to Lg7 are listed in the program)
+ * and
+ * | 2 14 | -58.45
+ * | Lg1*s +...+Lg7*s - R(z) | <= 2
+ * | |
+ * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ * In order to guarantee error in log below 1ulp, we compute log
+ * by
+ * log(1+f) = f - s*(f - R) (if f is not too large)
+ * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
+ *
+ * 3. Finally, log(x) = k*ln2 + log(1+f).
+ * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ * Here ln2 is split into two floating point number:
+ * ln2_hi + ln2_lo,
+ * where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ * log(x) is NaN with signal if x < 0 (including -INF) ;
+ * log(+INF) is +INF; log(0) is -INF with signal;
+ * log(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+static const double
+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
+
+/*
+ * We always inline __kernel_log(), since doing so produces a
+ * substantial performance improvement (~40% on amd64).
+ */
+static inline double
+__kernel_log(double x)
+{
+ double hfsq,f,s,z,R,w,t1,t2;
+ int32_t hx,i,j;
+ u_int32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ f = x-1.0;
+ if((0x000fffff&(2+hx))<3) { /* -2**-20 <= f < 2**-20 */
+ if(f==0.0) return 0.0;
+ return f*f*(0.33333333333333333*f-0.5);
+ }
+ s = f/(2.0+f);
+ z = s*s;
+ hx &= 0x000fffff;
+ i = hx-0x6147a;
+ w = z*z;
+ j = 0x6b851-hx;
+ t1= w*(Lg2+w*(Lg4+w*Lg6));
+ t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+ i |= j;
+ R = t2+t1;
+ if (i>0) {
+ hfsq=0.5*f*f;
+ return s*(hfsq+R) - hfsq;
+ } else {
+ return s*(R-f);
+ }
+}
diff --git a/lib/msun/src/k_logf.h b/lib/msun/src/k_logf.h
new file mode 100644
index 0000000..d9f0f3d
--- /dev/null
+++ b/lib/msun/src/k_logf.h
@@ -0,0 +1,55 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * float version of __kernel_log(x). See k_log.c for details.
+ */
+
+static const float
+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
+
+static inline float
+__kernel_logf(float x)
+{
+ float hfsq,f,s,z,R,w,t1,t2;
+ int32_t ix,i,j;
+
+ GET_FLOAT_WORD(ix,x);
+
+ f = x-(float)1.0;
+ if((0x007fffff&(0x8000+ix))<0xc000) { /* -2**-9 <= f < 2**-9 */
+ if(f==0.0f) return 0.0f;
+ return f*f*((float)0.33333333333333333*f-(float)0.5);
+ }
+ s = f/((float)2.0+f);
+ z = s*s;
+ ix &= 0x007fffff;
+ i = ix-(0x6147a<<3);
+ w = z*z;
+ j = (0x6b851<<3)-ix;
+ t1= w*(Lg2+w*Lg4);
+ t2= z*(Lg1+w*Lg3);
+ i |= j;
+ R = t2+t1;
+ if(i>0) {
+ hfsq=(float)0.5*f*f;
+ return s*(hfsq+R) - hfsq;
+ } else {
+ return s*(R-f);
+ }
+}
diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h
index 9109727..9aa2484 100644
--- a/lib/msun/src/math.h
+++ b/lib/msun/src/math.h
@@ -236,6 +236,7 @@ double lgamma(double);
long long llrint(double);
long long llround(double);
double log1p(double);
+double log2(double);
double logb(double);
long lrint(double);
long lround(double);
@@ -319,6 +320,7 @@ int ilogbf(float) __pure2;
float ldexpf(float, int);
float log10f(float);
float log1pf(float);
+float log2f(float);
float logf(float);
float modff(float, float *); /* fundamentally !__pure2 */
diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h
index 10c92f4..d79f808 100644
--- a/lib/msun/src/math_private.h
+++ b/lib/msun/src/math_private.h
@@ -292,6 +292,7 @@ irint(double x)
#define __ieee754_acos acos
#define __ieee754_acosh acosh
#define __ieee754_log log
+#define __ieee754_log2 log2
#define __ieee754_atanh atanh
#define __ieee754_asin asin
#define __ieee754_atan2 atan2
@@ -330,6 +331,7 @@ irint(double x)
#define __ieee754_lgammaf_r lgammaf_r
#define __ieee754_gammaf_r gammaf_r
#define __ieee754_log10f log10f
+#define __ieee754_log2f log2f
#define __ieee754_sinhf sinhf
#define __ieee754_hypotf hypotf
#define __ieee754_j0f j0f
diff --git a/libexec/bootpd/rtmsg.c b/libexec/bootpd/rtmsg.c
index b691edc..8b81dab 100644
--- a/libexec/bootpd/rtmsg.c
+++ b/libexec/bootpd/rtmsg.c
@@ -126,7 +126,7 @@ int bsd_arp_set(ia, eaddr, len)
register struct sockaddr_dl *sdl;
register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm);
u_char *ea;
- struct timeval time;
+ struct timespec tp;
int op = RTM_ADD;
getsocket();
@@ -140,8 +140,8 @@ int bsd_arp_set(ia, eaddr, len)
doing_proxy = flags = export_only = expire_time = 0;
/* make arp entry temporary */
- gettimeofday(&time, 0);
- expire_time = time.tv_sec + 20 * 60;
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ expire_time = tp.tv_sec + 20 * 60;
tryagain:
if (rtmsg(RTM_GET) < 0) {
diff --git a/libexec/mknetid/parse_group.c b/libexec/mknetid/parse_group.c
index b34ee11..84cb991 100644
--- a/libexec/mknetid/parse_group.c
+++ b/libexec/mknetid/parse_group.c
@@ -126,7 +126,7 @@ grscan(int search, int gid)
if (_gr_group.gr_name[0] == '+')
continue;
if ((_gr_group.gr_passwd = strsep(&bp, ":\n")) == NULL)
- break;;
+ break;
if (!(cp = strsep(&bp, ":\n")))
continue;
_gr_group.gr_gid = atoi(cp);
diff --git a/sbin/fsck_ffs/SMM.doc/Makefile b/sbin/fsck_ffs/SMM.doc/Makefile
deleted file mode 100644
index 9ddc06f..0000000
--- a/sbin/fsck_ffs/SMM.doc/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# $FreeBSD$
-# @(#)Makefile 8.1 (Berkeley) 6/8/93
-
-DIR= smm/03.fsck_ffs
-SRCS= 0.t 1.t 2.t 3.t 4.t
-MACROS= -ms
-
-.include <bsd.doc.mk>
diff --git a/sbin/geom/class/eli/geli.8 b/sbin/geom/class/eli/geli.8
index 67f5ea9..b682d8c 100644
--- a/sbin/geom/class/eli/geli.8
+++ b/sbin/geom/class/eli/geli.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 20, 2010
+.Dd December 3, 2010
.Dt GELI 8
.Os
.Sh NAME
@@ -842,7 +842,7 @@ Enter passphrase:
.Nm
supports two encryption modes:
.Nm XTS ,
-which was standarized as
+which was standardized as
.Nm IEE P1619
and
.Nm CBC
@@ -873,6 +873,10 @@ changes with the data he owns without notice.
In other words
.Nm
will not protect your data against replay attacks.
+.Pp
+It is recommended to write the whole provider before the first use,
+in order to make sure that all sectors and their corresponding
+checksums are properly initialized into a consistent state.
.Sh SEE ALSO
.Xr crypto 4 ,
.Xr gbde 4 ,
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index e4292da..7c5d351 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -295,8 +295,6 @@ main(int argc, char *argv[])
sdl = (const struct sockaddr_dl *) ifa->ifa_addr;
else
sdl = NULL;
- if (sdl != NULL && sdl->sdl_type == IFT_USB)
- continue;
if (cp != NULL && strcmp(cp, ifa->ifa_name) == 0 && !namesonly)
continue;
iflen = strlcpy(name, ifa->ifa_name, sizeof(name));
@@ -307,6 +305,8 @@ main(int argc, char *argv[])
}
cp = ifa->ifa_name;
+ if ((ifa->ifa_flags & IFF_CANTCONFIG) != 0)
+ continue;
if (downonly && (ifa->ifa_flags & IFF_UP) != 0)
continue;
if (uponly && (ifa->ifa_flags & IFF_UP) == 0)
diff --git a/sbin/route/route.c b/sbin/route/route.c
index f0bb07b..49d14dd 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -115,11 +115,11 @@ static void mask_addr(void);
static void monitor(void);
static const char *netname(struct sockaddr *);
static void newroute(int, char **);
-static void pmsg_addrs(char *, int);
-static void pmsg_common(struct rt_msghdr *);
+static void pmsg_addrs(char *, int, size_t);
+static void pmsg_common(struct rt_msghdr *, size_t);
static int prefixlen(const char *);
static void print_getmsg(struct rt_msghdr *, int);
-static void print_rtmsg(struct rt_msghdr *, int);
+static void print_rtmsg(struct rt_msghdr *, size_t);
static const char *routename(struct sockaddr *);
static int rtmsg(int, int);
static void set_metric(char *, int);
@@ -1306,7 +1306,7 @@ const char *msgtypes[] = {
"RTM_NEWMADDR: new multicast group membership on iface",
"RTM_DELMADDR: multicast group membership removed from iface",
"RTM_IFANNOUNCE: interface arrival/departure",
- 0,
+ "RTM_IEEE80211: IEEE 802.11 wireless event",
};
char metricnames[] =
@@ -1324,8 +1324,11 @@ char ifnetflags[] =
char addrnames[] =
"\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";
+static const char errfmt[] =
+"\n%s: truncated route message, only %zu bytes left\n";
+
static void
-print_rtmsg(struct rt_msghdr *rtm, int msglen __unused)
+print_rtmsg(struct rt_msghdr *rtm, size_t msglen)
{
struct if_msghdr *ifm;
struct ifa_msghdr *ifam;
@@ -1342,13 +1345,22 @@ print_rtmsg(struct rt_msghdr *rtm, int msglen __unused)
rtm->rtm_version);
return;
}
- if (msgtypes[rtm->rtm_type] != NULL)
+ if (rtm->rtm_type < sizeof(msgtypes) / sizeof(msgtypes[0]))
(void)printf("%s: ", msgtypes[rtm->rtm_type]);
else
- (void)printf("#%d: ", rtm->rtm_type);
+ (void)printf("unknown type %d: ", rtm->rtm_type);
(void)printf("len %d, ", rtm->rtm_msglen);
+
+#define REQUIRE(x) do { \
+ if (msglen < sizeof(x)) \
+ goto badlen; \
+ else \
+ msglen -= sizeof(x); \
+ } while (0)
+
switch (rtm->rtm_type) {
case RTM_IFINFO:
+ REQUIRE(struct if_msghdr);
ifm = (struct if_msghdr *)rtm;
(void) printf("if# %d, ", ifm->ifm_index);
switch (ifm->ifm_data.ifi_link_state) {
@@ -1364,23 +1376,26 @@ print_rtmsg(struct rt_msghdr *rtm, int msglen __unused)
}
(void) printf("link: %s, flags:", state);
bprintf(stdout, ifm->ifm_flags, ifnetflags);
- pmsg_addrs((char *)(ifm + 1), ifm->ifm_addrs);
+ pmsg_addrs((char *)(ifm + 1), ifm->ifm_addrs, msglen);
break;
case RTM_NEWADDR:
case RTM_DELADDR:
+ REQUIRE(struct ifa_msghdr);
ifam = (struct ifa_msghdr *)rtm;
(void) printf("metric %d, flags:", ifam->ifam_metric);
bprintf(stdout, ifam->ifam_flags, routeflags);
- pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs);
+ pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs, msglen);
break;
#ifdef RTM_NEWMADDR
case RTM_NEWMADDR:
case RTM_DELMADDR:
+ REQUIRE(struct ifma_msghdr);
ifmam = (struct ifma_msghdr *)rtm;
- pmsg_addrs((char *)(ifmam + 1), ifmam->ifmam_addrs);
+ pmsg_addrs((char *)(ifmam + 1), ifmam->ifmam_addrs, msglen);
break;
#endif
case RTM_IFANNOUNCE:
+ REQUIRE(struct if_announcemsghdr);
ifan = (struct if_announcemsghdr *)rtm;
(void) printf("if# %d, what: ", ifan->ifan_index);
switch (ifan->ifan_what) {
@@ -1401,8 +1416,14 @@ print_rtmsg(struct rt_msghdr *rtm, int msglen __unused)
(void) printf("pid: %ld, seq %d, errno %d, flags:",
(long)rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno);
bprintf(stdout, rtm->rtm_flags, routeflags);
- pmsg_common(rtm);
+ pmsg_common(rtm, msglen);
}
+
+ return;
+
+badlen:
+ (void)printf(errfmt, __func__, msglen);
+#undef REQUIRE
}
static void
@@ -1490,7 +1511,7 @@ print_getmsg(struct rt_msghdr *rtm, int msglen)
#undef msec
#define RTA_IGN (RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD)
if (verbose)
- pmsg_common(rtm);
+ pmsg_common(rtm, msglen);
else if (rtm->rtm_addrs &~ RTA_IGN) {
(void) printf("sockaddrs: ");
bprintf(stdout, rtm->rtm_addrs, addrnames);
@@ -1500,17 +1521,21 @@ print_getmsg(struct rt_msghdr *rtm, int msglen)
}
static void
-pmsg_common(struct rt_msghdr *rtm)
+pmsg_common(struct rt_msghdr *rtm, size_t msglen)
{
(void) printf("\nlocks: ");
bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames);
(void) printf(" inits: ");
bprintf(stdout, rtm->rtm_inits, metricnames);
- pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs);
+ if (msglen > sizeof(struct rt_msghdr))
+ pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs,
+ msglen - sizeof(struct rt_msghdr));
+ else
+ (void) fflush(stdout);
}
static void
-pmsg_addrs(char *cp, int addrs)
+pmsg_addrs(char *cp, int addrs, size_t len)
{
struct sockaddr *sa;
int i;
@@ -1525,7 +1550,12 @@ pmsg_addrs(char *cp, int addrs)
for (i = 1; i != 0; i <<= 1)
if (i & addrs) {
sa = (struct sockaddr *)cp;
+ if (len == 0 || len < SA_SIZE(sa)) {
+ (void) printf(errfmt, __func__, len);
+ break;
+ }
(void) printf(" %s", routename(sa));
+ len -= SA_SIZE(sa);
cp += SA_SIZE(sa);
}
(void) putchar('\n');
diff --git a/secure/lib/libcrypto/Makefile.inc b/secure/lib/libcrypto/Makefile.inc
index 24e4243..24b8d88 100644
--- a/secure/lib/libcrypto/Makefile.inc
+++ b/secure/lib/libcrypto/Makefile.inc
@@ -3,8 +3,8 @@
.include <bsd.own.mk>
# OpenSSL version used for manual page generation
-OPENSSL_VER= 0.9.8p
-OPENSSL_DATE= 2010-11-16
+OPENSSL_VER= 0.9.8q
+OPENSSL_DATE= 2010-12-02
LCRYPTO_SRC= ${.CURDIR}/../../../crypto/openssl
LCRYPTO_DOC= ${.CURDIR}/../../../crypto/openssl/doc
diff --git a/secure/lib/libcrypto/man/ASN1_OBJECT_new.3 b/secure/lib/libcrypto/man/ASN1_OBJECT_new.3
index 7e0877c..a1e248e 100644
--- a/secure/lib/libcrypto/man/ASN1_OBJECT_new.3
+++ b/secure/lib/libcrypto/man/ASN1_OBJECT_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1_OBJECT_new 3"
-.TH ASN1_OBJECT_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ASN1_OBJECT_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ASN1_STRING_length.3 b/secure/lib/libcrypto/man/ASN1_STRING_length.3
index b79cb06..5472c30 100644
--- a/secure/lib/libcrypto/man/ASN1_STRING_length.3
+++ b/secure/lib/libcrypto/man/ASN1_STRING_length.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1_STRING_length 3"
-.TH ASN1_STRING_length 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ASN1_STRING_length 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ASN1_STRING_new.3 b/secure/lib/libcrypto/man/ASN1_STRING_new.3
index f9071aa..04b6e8a 100644
--- a/secure/lib/libcrypto/man/ASN1_STRING_new.3
+++ b/secure/lib/libcrypto/man/ASN1_STRING_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1_STRING_new 3"
-.TH ASN1_STRING_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ASN1_STRING_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3 b/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3
index 7dbae7d..a56f6aa 100644
--- a/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3
+++ b/secure/lib/libcrypto/man/ASN1_STRING_print_ex.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1_STRING_print_ex 3"
-.TH ASN1_STRING_print_ex 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ASN1_STRING_print_ex 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ASN1_generate_nconf.3 b/secure/lib/libcrypto/man/ASN1_generate_nconf.3
index f3d3036..6be122a 100644
--- a/secure/lib/libcrypto/man/ASN1_generate_nconf.3
+++ b/secure/lib/libcrypto/man/ASN1_generate_nconf.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1_generate_nconf 3"
-.TH ASN1_generate_nconf 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ASN1_generate_nconf 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_ctrl.3 b/secure/lib/libcrypto/man/BIO_ctrl.3
index ea0b20f..d58eb62 100644
--- a/secure/lib/libcrypto/man/BIO_ctrl.3
+++ b/secure/lib/libcrypto/man/BIO_ctrl.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_ctrl 3"
-.TH BIO_ctrl 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_ctrl 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_f_base64.3 b/secure/lib/libcrypto/man/BIO_f_base64.3
index 330d123..936ea90 100644
--- a/secure/lib/libcrypto/man/BIO_f_base64.3
+++ b/secure/lib/libcrypto/man/BIO_f_base64.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_base64 3"
-.TH BIO_f_base64 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_f_base64 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_f_buffer.3 b/secure/lib/libcrypto/man/BIO_f_buffer.3
index 1244970..ebc0c16 100644
--- a/secure/lib/libcrypto/man/BIO_f_buffer.3
+++ b/secure/lib/libcrypto/man/BIO_f_buffer.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_buffer 3"
-.TH BIO_f_buffer 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_f_buffer 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_f_cipher.3 b/secure/lib/libcrypto/man/BIO_f_cipher.3
index 1f7bd44..2a7f885 100644
--- a/secure/lib/libcrypto/man/BIO_f_cipher.3
+++ b/secure/lib/libcrypto/man/BIO_f_cipher.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_cipher 3"
-.TH BIO_f_cipher 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_f_cipher 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_f_md.3 b/secure/lib/libcrypto/man/BIO_f_md.3
index d202fd3..0f44132 100644
--- a/secure/lib/libcrypto/man/BIO_f_md.3
+++ b/secure/lib/libcrypto/man/BIO_f_md.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_md 3"
-.TH BIO_f_md 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_f_md 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_f_null.3 b/secure/lib/libcrypto/man/BIO_f_null.3
index 5d3be78..06f6cc7 100644
--- a/secure/lib/libcrypto/man/BIO_f_null.3
+++ b/secure/lib/libcrypto/man/BIO_f_null.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_null 3"
-.TH BIO_f_null 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_f_null 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_f_ssl.3 b/secure/lib/libcrypto/man/BIO_f_ssl.3
index 41928ec..8e95630 100644
--- a/secure/lib/libcrypto/man/BIO_f_ssl.3
+++ b/secure/lib/libcrypto/man/BIO_f_ssl.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_f_ssl 3"
-.TH BIO_f_ssl 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_f_ssl 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_find_type.3 b/secure/lib/libcrypto/man/BIO_find_type.3
index 3ee2466..ff8eb3a 100644
--- a/secure/lib/libcrypto/man/BIO_find_type.3
+++ b/secure/lib/libcrypto/man/BIO_find_type.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_find_type 3"
-.TH BIO_find_type 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_find_type 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_new.3 b/secure/lib/libcrypto/man/BIO_new.3
index e02e323..3457bae 100644
--- a/secure/lib/libcrypto/man/BIO_new.3
+++ b/secure/lib/libcrypto/man/BIO_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_new 3"
-.TH BIO_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_push.3 b/secure/lib/libcrypto/man/BIO_push.3
index 73f62a1..9d43372 100644
--- a/secure/lib/libcrypto/man/BIO_push.3
+++ b/secure/lib/libcrypto/man/BIO_push.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_push 3"
-.TH BIO_push 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_push 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_read.3 b/secure/lib/libcrypto/man/BIO_read.3
index ab91e12..d2d585a 100644
--- a/secure/lib/libcrypto/man/BIO_read.3
+++ b/secure/lib/libcrypto/man/BIO_read.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_read 3"
-.TH BIO_read 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_read 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_s_accept.3 b/secure/lib/libcrypto/man/BIO_s_accept.3
index 455b26b..17426b7 100644
--- a/secure/lib/libcrypto/man/BIO_s_accept.3
+++ b/secure/lib/libcrypto/man/BIO_s_accept.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_accept 3"
-.TH BIO_s_accept 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_s_accept 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_s_bio.3 b/secure/lib/libcrypto/man/BIO_s_bio.3
index afd3307..f4aa8a1 100644
--- a/secure/lib/libcrypto/man/BIO_s_bio.3
+++ b/secure/lib/libcrypto/man/BIO_s_bio.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_bio 3"
-.TH BIO_s_bio 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_s_bio 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_s_connect.3 b/secure/lib/libcrypto/man/BIO_s_connect.3
index 8f023d1..e55cd73 100644
--- a/secure/lib/libcrypto/man/BIO_s_connect.3
+++ b/secure/lib/libcrypto/man/BIO_s_connect.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_connect 3"
-.TH BIO_s_connect 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_s_connect 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_s_fd.3 b/secure/lib/libcrypto/man/BIO_s_fd.3
index 842794d..e710429 100644
--- a/secure/lib/libcrypto/man/BIO_s_fd.3
+++ b/secure/lib/libcrypto/man/BIO_s_fd.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_fd 3"
-.TH BIO_s_fd 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_s_fd 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_s_file.3 b/secure/lib/libcrypto/man/BIO_s_file.3
index 2dfe5af..fc036dd 100644
--- a/secure/lib/libcrypto/man/BIO_s_file.3
+++ b/secure/lib/libcrypto/man/BIO_s_file.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_file 3"
-.TH BIO_s_file 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_s_file 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_s_mem.3 b/secure/lib/libcrypto/man/BIO_s_mem.3
index 5fcedf0..c9ec1e3 100644
--- a/secure/lib/libcrypto/man/BIO_s_mem.3
+++ b/secure/lib/libcrypto/man/BIO_s_mem.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_mem 3"
-.TH BIO_s_mem 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_s_mem 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_s_null.3 b/secure/lib/libcrypto/man/BIO_s_null.3
index 72a3fd7..3f60757 100644
--- a/secure/lib/libcrypto/man/BIO_s_null.3
+++ b/secure/lib/libcrypto/man/BIO_s_null.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_null 3"
-.TH BIO_s_null 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_s_null 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_s_socket.3 b/secure/lib/libcrypto/man/BIO_s_socket.3
index 4c1248f..1261339 100644
--- a/secure/lib/libcrypto/man/BIO_s_socket.3
+++ b/secure/lib/libcrypto/man/BIO_s_socket.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_s_socket 3"
-.TH BIO_s_socket 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_s_socket 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_set_callback.3 b/secure/lib/libcrypto/man/BIO_set_callback.3
index e73953f..fb85633 100644
--- a/secure/lib/libcrypto/man/BIO_set_callback.3
+++ b/secure/lib/libcrypto/man/BIO_set_callback.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_set_callback 3"
-.TH BIO_set_callback 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_set_callback 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BIO_should_retry.3 b/secure/lib/libcrypto/man/BIO_should_retry.3
index 43cc348..22f6049 100644
--- a/secure/lib/libcrypto/man/BIO_should_retry.3
+++ b/secure/lib/libcrypto/man/BIO_should_retry.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BIO_should_retry 3"
-.TH BIO_should_retry 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BIO_should_retry 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_BLINDING_new.3 b/secure/lib/libcrypto/man/BN_BLINDING_new.3
index 7353094..a5a4591 100644
--- a/secure/lib/libcrypto/man/BN_BLINDING_new.3
+++ b/secure/lib/libcrypto/man/BN_BLINDING_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_BLINDING_new 3"
-.TH BN_BLINDING_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_BLINDING_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_CTX_new.3 b/secure/lib/libcrypto/man/BN_CTX_new.3
index d0873b0..bae185d 100644
--- a/secure/lib/libcrypto/man/BN_CTX_new.3
+++ b/secure/lib/libcrypto/man/BN_CTX_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_CTX_new 3"
-.TH BN_CTX_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_CTX_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_CTX_start.3 b/secure/lib/libcrypto/man/BN_CTX_start.3
index 078945a..4eb96a5 100644
--- a/secure/lib/libcrypto/man/BN_CTX_start.3
+++ b/secure/lib/libcrypto/man/BN_CTX_start.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_CTX_start 3"
-.TH BN_CTX_start 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_CTX_start 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_add.3 b/secure/lib/libcrypto/man/BN_add.3
index 97eb1d3..7cd7273 100644
--- a/secure/lib/libcrypto/man/BN_add.3
+++ b/secure/lib/libcrypto/man/BN_add.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_add 3"
-.TH BN_add 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_add 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_add_word.3 b/secure/lib/libcrypto/man/BN_add_word.3
index 7f2c2b4..486f63e 100644
--- a/secure/lib/libcrypto/man/BN_add_word.3
+++ b/secure/lib/libcrypto/man/BN_add_word.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_add_word 3"
-.TH BN_add_word 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_add_word 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_bn2bin.3 b/secure/lib/libcrypto/man/BN_bn2bin.3
index 01f967b..fee9e6d 100644
--- a/secure/lib/libcrypto/man/BN_bn2bin.3
+++ b/secure/lib/libcrypto/man/BN_bn2bin.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_bn2bin 3"
-.TH BN_bn2bin 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_bn2bin 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_cmp.3 b/secure/lib/libcrypto/man/BN_cmp.3
index de8f335..484e696 100644
--- a/secure/lib/libcrypto/man/BN_cmp.3
+++ b/secure/lib/libcrypto/man/BN_cmp.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_cmp 3"
-.TH BN_cmp 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_cmp 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_copy.3 b/secure/lib/libcrypto/man/BN_copy.3
index 14eb31d..f9cd1c1 100644
--- a/secure/lib/libcrypto/man/BN_copy.3
+++ b/secure/lib/libcrypto/man/BN_copy.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_copy 3"
-.TH BN_copy 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_copy 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_generate_prime.3 b/secure/lib/libcrypto/man/BN_generate_prime.3
index 7eea725..18a6d37 100644
--- a/secure/lib/libcrypto/man/BN_generate_prime.3
+++ b/secure/lib/libcrypto/man/BN_generate_prime.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_generate_prime 3"
-.TH BN_generate_prime 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_generate_prime 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_mod_inverse.3 b/secure/lib/libcrypto/man/BN_mod_inverse.3
index 0d03735..4a2e642 100644
--- a/secure/lib/libcrypto/man/BN_mod_inverse.3
+++ b/secure/lib/libcrypto/man/BN_mod_inverse.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_mod_inverse 3"
-.TH BN_mod_inverse 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_mod_inverse 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3 b/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3
index 81e884b..90b7d5a 100644
--- a/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3
+++ b/secure/lib/libcrypto/man/BN_mod_mul_montgomery.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_mod_mul_montgomery 3"
-.TH BN_mod_mul_montgomery 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_mod_mul_montgomery 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3 b/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3
index 93c477d..d846d34 100644
--- a/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3
+++ b/secure/lib/libcrypto/man/BN_mod_mul_reciprocal.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_mod_mul_reciprocal 3"
-.TH BN_mod_mul_reciprocal 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_mod_mul_reciprocal 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_new.3 b/secure/lib/libcrypto/man/BN_new.3
index ce78cc4..a6838d7 100644
--- a/secure/lib/libcrypto/man/BN_new.3
+++ b/secure/lib/libcrypto/man/BN_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_new 3"
-.TH BN_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_num_bytes.3 b/secure/lib/libcrypto/man/BN_num_bytes.3
index 7378123..e820563 100644
--- a/secure/lib/libcrypto/man/BN_num_bytes.3
+++ b/secure/lib/libcrypto/man/BN_num_bytes.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_num_bytes 3"
-.TH BN_num_bytes 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_num_bytes 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_rand.3 b/secure/lib/libcrypto/man/BN_rand.3
index 3ed82ad..7203182 100644
--- a/secure/lib/libcrypto/man/BN_rand.3
+++ b/secure/lib/libcrypto/man/BN_rand.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_rand 3"
-.TH BN_rand 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_rand 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_set_bit.3 b/secure/lib/libcrypto/man/BN_set_bit.3
index d873919..a68db1f 100644
--- a/secure/lib/libcrypto/man/BN_set_bit.3
+++ b/secure/lib/libcrypto/man/BN_set_bit.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_set_bit 3"
-.TH BN_set_bit 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_set_bit 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_swap.3 b/secure/lib/libcrypto/man/BN_swap.3
index 673f720..eac8113 100644
--- a/secure/lib/libcrypto/man/BN_swap.3
+++ b/secure/lib/libcrypto/man/BN_swap.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_swap 3"
-.TH BN_swap 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_swap 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/BN_zero.3 b/secure/lib/libcrypto/man/BN_zero.3
index c96e132..d07fc2f 100644
--- a/secure/lib/libcrypto/man/BN_zero.3
+++ b/secure/lib/libcrypto/man/BN_zero.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "BN_zero 3"
-.TH BN_zero 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH BN_zero 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/CONF_modules_free.3 b/secure/lib/libcrypto/man/CONF_modules_free.3
index 1daba20..9fd6d03 100644
--- a/secure/lib/libcrypto/man/CONF_modules_free.3
+++ b/secure/lib/libcrypto/man/CONF_modules_free.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "CONF_modules_free 3"
-.TH CONF_modules_free 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH CONF_modules_free 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/CONF_modules_load_file.3 b/secure/lib/libcrypto/man/CONF_modules_load_file.3
index d77e5fd..b7e6064 100644
--- a/secure/lib/libcrypto/man/CONF_modules_load_file.3
+++ b/secure/lib/libcrypto/man/CONF_modules_load_file.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "CONF_modules_load_file 3"
-.TH CONF_modules_load_file 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH CONF_modules_load_file 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3 b/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3
index 0d23e32..955b949 100644
--- a/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3
+++ b/secure/lib/libcrypto/man/CRYPTO_set_ex_data.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "CRYPTO_set_ex_data 3"
-.TH CRYPTO_set_ex_data 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH CRYPTO_set_ex_data 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DH_generate_key.3 b/secure/lib/libcrypto/man/DH_generate_key.3
index 390c498..cff5300 100644
--- a/secure/lib/libcrypto/man/DH_generate_key.3
+++ b/secure/lib/libcrypto/man/DH_generate_key.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DH_generate_key 3"
-.TH DH_generate_key 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DH_generate_key 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DH_generate_parameters.3 b/secure/lib/libcrypto/man/DH_generate_parameters.3
index fee07a2..374c05f 100644
--- a/secure/lib/libcrypto/man/DH_generate_parameters.3
+++ b/secure/lib/libcrypto/man/DH_generate_parameters.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DH_generate_parameters 3"
-.TH DH_generate_parameters 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DH_generate_parameters 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DH_get_ex_new_index.3 b/secure/lib/libcrypto/man/DH_get_ex_new_index.3
index 9f07078..e74c6ce 100644
--- a/secure/lib/libcrypto/man/DH_get_ex_new_index.3
+++ b/secure/lib/libcrypto/man/DH_get_ex_new_index.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DH_get_ex_new_index 3"
-.TH DH_get_ex_new_index 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DH_get_ex_new_index 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DH_new.3 b/secure/lib/libcrypto/man/DH_new.3
index 3cd7dd4..e169713 100644
--- a/secure/lib/libcrypto/man/DH_new.3
+++ b/secure/lib/libcrypto/man/DH_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DH_new 3"
-.TH DH_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DH_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DH_set_method.3 b/secure/lib/libcrypto/man/DH_set_method.3
index 08ee367..c5bf32c 100644
--- a/secure/lib/libcrypto/man/DH_set_method.3
+++ b/secure/lib/libcrypto/man/DH_set_method.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DH_set_method 3"
-.TH DH_set_method 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DH_set_method 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DH_size.3 b/secure/lib/libcrypto/man/DH_size.3
index 48bfc45..5f8c60e 100644
--- a/secure/lib/libcrypto/man/DH_size.3
+++ b/secure/lib/libcrypto/man/DH_size.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DH_size 3"
-.TH DH_size 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DH_size 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DSA_SIG_new.3 b/secure/lib/libcrypto/man/DSA_SIG_new.3
index a488145..4f48912 100644
--- a/secure/lib/libcrypto/man/DSA_SIG_new.3
+++ b/secure/lib/libcrypto/man/DSA_SIG_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_SIG_new 3"
-.TH DSA_SIG_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA_SIG_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DSA_do_sign.3 b/secure/lib/libcrypto/man/DSA_do_sign.3
index 4a9d3c8..f6da96b 100644
--- a/secure/lib/libcrypto/man/DSA_do_sign.3
+++ b/secure/lib/libcrypto/man/DSA_do_sign.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_do_sign 3"
-.TH DSA_do_sign 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA_do_sign 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DSA_dup_DH.3 b/secure/lib/libcrypto/man/DSA_dup_DH.3
index fe9e4b5..b13e50ee 100644
--- a/secure/lib/libcrypto/man/DSA_dup_DH.3
+++ b/secure/lib/libcrypto/man/DSA_dup_DH.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_dup_DH 3"
-.TH DSA_dup_DH 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA_dup_DH 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DSA_generate_key.3 b/secure/lib/libcrypto/man/DSA_generate_key.3
index b251ebd..2777dc8 100644
--- a/secure/lib/libcrypto/man/DSA_generate_key.3
+++ b/secure/lib/libcrypto/man/DSA_generate_key.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_generate_key 3"
-.TH DSA_generate_key 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA_generate_key 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DSA_generate_parameters.3 b/secure/lib/libcrypto/man/DSA_generate_parameters.3
index 13ee625..e5fcb26 100644
--- a/secure/lib/libcrypto/man/DSA_generate_parameters.3
+++ b/secure/lib/libcrypto/man/DSA_generate_parameters.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_generate_parameters 3"
-.TH DSA_generate_parameters 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA_generate_parameters 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DSA_get_ex_new_index.3 b/secure/lib/libcrypto/man/DSA_get_ex_new_index.3
index 3695cea..fd418dd 100644
--- a/secure/lib/libcrypto/man/DSA_get_ex_new_index.3
+++ b/secure/lib/libcrypto/man/DSA_get_ex_new_index.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_get_ex_new_index 3"
-.TH DSA_get_ex_new_index 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA_get_ex_new_index 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DSA_new.3 b/secure/lib/libcrypto/man/DSA_new.3
index 80c6d8d..b53c2a4 100644
--- a/secure/lib/libcrypto/man/DSA_new.3
+++ b/secure/lib/libcrypto/man/DSA_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_new 3"
-.TH DSA_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DSA_set_method.3 b/secure/lib/libcrypto/man/DSA_set_method.3
index 0c4c6df..9094acd 100644
--- a/secure/lib/libcrypto/man/DSA_set_method.3
+++ b/secure/lib/libcrypto/man/DSA_set_method.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_set_method 3"
-.TH DSA_set_method 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA_set_method 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DSA_sign.3 b/secure/lib/libcrypto/man/DSA_sign.3
index 1c205b6..5931f9c 100644
--- a/secure/lib/libcrypto/man/DSA_sign.3
+++ b/secure/lib/libcrypto/man/DSA_sign.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_sign 3"
-.TH DSA_sign 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA_sign 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/DSA_size.3 b/secure/lib/libcrypto/man/DSA_size.3
index d3241da..1aa3962 100644
--- a/secure/lib/libcrypto/man/DSA_size.3
+++ b/secure/lib/libcrypto/man/DSA_size.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA_size 3"
-.TH DSA_size 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA_size 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ERR_GET_LIB.3 b/secure/lib/libcrypto/man/ERR_GET_LIB.3
index 062f472..694b0e1 100644
--- a/secure/lib/libcrypto/man/ERR_GET_LIB.3
+++ b/secure/lib/libcrypto/man/ERR_GET_LIB.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_GET_LIB 3"
-.TH ERR_GET_LIB 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERR_GET_LIB 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ERR_clear_error.3 b/secure/lib/libcrypto/man/ERR_clear_error.3
index 9b5b424..4b93a2d 100644
--- a/secure/lib/libcrypto/man/ERR_clear_error.3
+++ b/secure/lib/libcrypto/man/ERR_clear_error.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_clear_error 3"
-.TH ERR_clear_error 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERR_clear_error 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ERR_error_string.3 b/secure/lib/libcrypto/man/ERR_error_string.3
index 586e74b..bf66a06 100644
--- a/secure/lib/libcrypto/man/ERR_error_string.3
+++ b/secure/lib/libcrypto/man/ERR_error_string.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_error_string 3"
-.TH ERR_error_string 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERR_error_string 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ERR_get_error.3 b/secure/lib/libcrypto/man/ERR_get_error.3
index 333c21e..b59ee3f 100644
--- a/secure/lib/libcrypto/man/ERR_get_error.3
+++ b/secure/lib/libcrypto/man/ERR_get_error.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_get_error 3"
-.TH ERR_get_error 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERR_get_error 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ERR_load_crypto_strings.3 b/secure/lib/libcrypto/man/ERR_load_crypto_strings.3
index fc47add..089c5ae 100644
--- a/secure/lib/libcrypto/man/ERR_load_crypto_strings.3
+++ b/secure/lib/libcrypto/man/ERR_load_crypto_strings.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_load_crypto_strings 3"
-.TH ERR_load_crypto_strings 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERR_load_crypto_strings 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ERR_load_strings.3 b/secure/lib/libcrypto/man/ERR_load_strings.3
index b537bd5..47f534b 100644
--- a/secure/lib/libcrypto/man/ERR_load_strings.3
+++ b/secure/lib/libcrypto/man/ERR_load_strings.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_load_strings 3"
-.TH ERR_load_strings 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERR_load_strings 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ERR_print_errors.3 b/secure/lib/libcrypto/man/ERR_print_errors.3
index 6226628..fa7516a 100644
--- a/secure/lib/libcrypto/man/ERR_print_errors.3
+++ b/secure/lib/libcrypto/man/ERR_print_errors.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_print_errors 3"
-.TH ERR_print_errors 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERR_print_errors 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ERR_put_error.3 b/secure/lib/libcrypto/man/ERR_put_error.3
index 9a04492..9c403c9 100644
--- a/secure/lib/libcrypto/man/ERR_put_error.3
+++ b/secure/lib/libcrypto/man/ERR_put_error.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_put_error 3"
-.TH ERR_put_error 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERR_put_error 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ERR_remove_state.3 b/secure/lib/libcrypto/man/ERR_remove_state.3
index 9acf4ef..55e717d 100644
--- a/secure/lib/libcrypto/man/ERR_remove_state.3
+++ b/secure/lib/libcrypto/man/ERR_remove_state.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_remove_state 3"
-.TH ERR_remove_state 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERR_remove_state 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ERR_set_mark.3 b/secure/lib/libcrypto/man/ERR_set_mark.3
index cd1a9e8..72934b8 100644
--- a/secure/lib/libcrypto/man/ERR_set_mark.3
+++ b/secure/lib/libcrypto/man/ERR_set_mark.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERR_set_mark 3"
-.TH ERR_set_mark 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERR_set_mark 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/EVP_BytesToKey.3 b/secure/lib/libcrypto/man/EVP_BytesToKey.3
index c844baa..9473bc3 100644
--- a/secure/lib/libcrypto/man/EVP_BytesToKey.3
+++ b/secure/lib/libcrypto/man/EVP_BytesToKey.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_BytesToKey 3"
-.TH EVP_BytesToKey 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH EVP_BytesToKey 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/EVP_DigestInit.3 b/secure/lib/libcrypto/man/EVP_DigestInit.3
index 21376c1..e7c79a4 100644
--- a/secure/lib/libcrypto/man/EVP_DigestInit.3
+++ b/secure/lib/libcrypto/man/EVP_DigestInit.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_DigestInit 3"
-.TH EVP_DigestInit 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH EVP_DigestInit 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/EVP_EncryptInit.3 b/secure/lib/libcrypto/man/EVP_EncryptInit.3
index 8b70c68..15e656a 100644
--- a/secure/lib/libcrypto/man/EVP_EncryptInit.3
+++ b/secure/lib/libcrypto/man/EVP_EncryptInit.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_EncryptInit 3"
-.TH EVP_EncryptInit 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH EVP_EncryptInit 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/EVP_OpenInit.3 b/secure/lib/libcrypto/man/EVP_OpenInit.3
index 7540ef3..0ba61ec 100644
--- a/secure/lib/libcrypto/man/EVP_OpenInit.3
+++ b/secure/lib/libcrypto/man/EVP_OpenInit.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_OpenInit 3"
-.TH EVP_OpenInit 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH EVP_OpenInit 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/EVP_PKEY_new.3 b/secure/lib/libcrypto/man/EVP_PKEY_new.3
index 8b06b98..e8350f4 100644
--- a/secure/lib/libcrypto/man/EVP_PKEY_new.3
+++ b/secure/lib/libcrypto/man/EVP_PKEY_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_PKEY_new 3"
-.TH EVP_PKEY_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH EVP_PKEY_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3 b/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3
index f5bfc7f..f9d31f2 100644
--- a/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3
+++ b/secure/lib/libcrypto/man/EVP_PKEY_set1_RSA.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_PKEY_set1_RSA 3"
-.TH EVP_PKEY_set1_RSA 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH EVP_PKEY_set1_RSA 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/EVP_SealInit.3 b/secure/lib/libcrypto/man/EVP_SealInit.3
index 89e2b26..1bba814 100644
--- a/secure/lib/libcrypto/man/EVP_SealInit.3
+++ b/secure/lib/libcrypto/man/EVP_SealInit.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_SealInit 3"
-.TH EVP_SealInit 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH EVP_SealInit 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/EVP_SignInit.3 b/secure/lib/libcrypto/man/EVP_SignInit.3
index 8810a98..49ad550 100644
--- a/secure/lib/libcrypto/man/EVP_SignInit.3
+++ b/secure/lib/libcrypto/man/EVP_SignInit.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_SignInit 3"
-.TH EVP_SignInit 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH EVP_SignInit 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/EVP_VerifyInit.3 b/secure/lib/libcrypto/man/EVP_VerifyInit.3
index c8bec9c..a622038 100644
--- a/secure/lib/libcrypto/man/EVP_VerifyInit.3
+++ b/secure/lib/libcrypto/man/EVP_VerifyInit.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EVP_VerifyInit 3"
-.TH EVP_VerifyInit 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH EVP_VerifyInit 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/OBJ_nid2obj.3 b/secure/lib/libcrypto/man/OBJ_nid2obj.3
index 3bfd7e8..cfc733b 100644
--- a/secure/lib/libcrypto/man/OBJ_nid2obj.3
+++ b/secure/lib/libcrypto/man/OBJ_nid2obj.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "OBJ_nid2obj 3"
-.TH OBJ_nid2obj 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH OBJ_nid2obj 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/OPENSSL_Applink.3 b/secure/lib/libcrypto/man/OPENSSL_Applink.3
index 19e5847..416d4c3 100644
--- a/secure/lib/libcrypto/man/OPENSSL_Applink.3
+++ b/secure/lib/libcrypto/man/OPENSSL_Applink.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL_Applink 3"
-.TH OPENSSL_Applink 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH OPENSSL_Applink 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3 b/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3
index dc83d0f..a829260 100644
--- a/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3
+++ b/secure/lib/libcrypto/man/OPENSSL_VERSION_NUMBER.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL_VERSION_NUMBER 3"
-.TH OPENSSL_VERSION_NUMBER 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH OPENSSL_VERSION_NUMBER 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/OPENSSL_config.3 b/secure/lib/libcrypto/man/OPENSSL_config.3
index a575c72..87ce97b 100644
--- a/secure/lib/libcrypto/man/OPENSSL_config.3
+++ b/secure/lib/libcrypto/man/OPENSSL_config.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL_config 3"
-.TH OPENSSL_config 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH OPENSSL_config 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/OPENSSL_ia32cap.3 b/secure/lib/libcrypto/man/OPENSSL_ia32cap.3
index a858672..0114c90 100644
--- a/secure/lib/libcrypto/man/OPENSSL_ia32cap.3
+++ b/secure/lib/libcrypto/man/OPENSSL_ia32cap.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL_ia32cap 3"
-.TH OPENSSL_ia32cap 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH OPENSSL_ia32cap 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3 b/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3
index 8af9b67..2cacde2 100644
--- a/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3
+++ b/secure/lib/libcrypto/man/OPENSSL_load_builtin_modules.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL_load_builtin_modules 3"
-.TH OPENSSL_load_builtin_modules 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH OPENSSL_load_builtin_modules 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3 b/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3
index 619800d..399d2dd 100644
--- a/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3
+++ b/secure/lib/libcrypto/man/OpenSSL_add_all_algorithms.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "OpenSSL_add_all_algorithms 3"
-.TH OpenSSL_add_all_algorithms 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH OpenSSL_add_all_algorithms 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/PKCS12_create.3 b/secure/lib/libcrypto/man/PKCS12_create.3
index 4e17ec3..8154477 100644
--- a/secure/lib/libcrypto/man/PKCS12_create.3
+++ b/secure/lib/libcrypto/man/PKCS12_create.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS12_create 3"
-.TH PKCS12_create 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH PKCS12_create 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/PKCS12_parse.3 b/secure/lib/libcrypto/man/PKCS12_parse.3
index ed53999..44df001 100644
--- a/secure/lib/libcrypto/man/PKCS12_parse.3
+++ b/secure/lib/libcrypto/man/PKCS12_parse.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS12_parse 3"
-.TH PKCS12_parse 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH PKCS12_parse 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/PKCS7_decrypt.3 b/secure/lib/libcrypto/man/PKCS7_decrypt.3
index 4cc2f8a..5e81459 100644
--- a/secure/lib/libcrypto/man/PKCS7_decrypt.3
+++ b/secure/lib/libcrypto/man/PKCS7_decrypt.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS7_decrypt 3"
-.TH PKCS7_decrypt 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH PKCS7_decrypt 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/PKCS7_encrypt.3 b/secure/lib/libcrypto/man/PKCS7_encrypt.3
index 61022a6..9507930 100644
--- a/secure/lib/libcrypto/man/PKCS7_encrypt.3
+++ b/secure/lib/libcrypto/man/PKCS7_encrypt.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS7_encrypt 3"
-.TH PKCS7_encrypt 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH PKCS7_encrypt 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/PKCS7_sign.3 b/secure/lib/libcrypto/man/PKCS7_sign.3
index e9c4021..89a2c17 100644
--- a/secure/lib/libcrypto/man/PKCS7_sign.3
+++ b/secure/lib/libcrypto/man/PKCS7_sign.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS7_sign 3"
-.TH PKCS7_sign 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH PKCS7_sign 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/PKCS7_verify.3 b/secure/lib/libcrypto/man/PKCS7_verify.3
index f35cda7..397725f 100644
--- a/secure/lib/libcrypto/man/PKCS7_verify.3
+++ b/secure/lib/libcrypto/man/PKCS7_verify.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS7_verify 3"
-.TH PKCS7_verify 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH PKCS7_verify 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RAND_add.3 b/secure/lib/libcrypto/man/RAND_add.3
index 208cecf..23f4d36 100644
--- a/secure/lib/libcrypto/man/RAND_add.3
+++ b/secure/lib/libcrypto/man/RAND_add.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_add 3"
-.TH RAND_add 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RAND_add 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RAND_bytes.3 b/secure/lib/libcrypto/man/RAND_bytes.3
index b97fb38..1da3eb6 100644
--- a/secure/lib/libcrypto/man/RAND_bytes.3
+++ b/secure/lib/libcrypto/man/RAND_bytes.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_bytes 3"
-.TH RAND_bytes 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RAND_bytes 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RAND_cleanup.3 b/secure/lib/libcrypto/man/RAND_cleanup.3
index 4785cd4..13f245f 100644
--- a/secure/lib/libcrypto/man/RAND_cleanup.3
+++ b/secure/lib/libcrypto/man/RAND_cleanup.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_cleanup 3"
-.TH RAND_cleanup 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RAND_cleanup 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RAND_egd.3 b/secure/lib/libcrypto/man/RAND_egd.3
index b7304ba..58784a9 100644
--- a/secure/lib/libcrypto/man/RAND_egd.3
+++ b/secure/lib/libcrypto/man/RAND_egd.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_egd 3"
-.TH RAND_egd 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RAND_egd 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RAND_load_file.3 b/secure/lib/libcrypto/man/RAND_load_file.3
index a6f82b7..b0edd2b 100644
--- a/secure/lib/libcrypto/man/RAND_load_file.3
+++ b/secure/lib/libcrypto/man/RAND_load_file.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_load_file 3"
-.TH RAND_load_file 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RAND_load_file 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RAND_set_rand_method.3 b/secure/lib/libcrypto/man/RAND_set_rand_method.3
index 19e509e..722925d 100644
--- a/secure/lib/libcrypto/man/RAND_set_rand_method.3
+++ b/secure/lib/libcrypto/man/RAND_set_rand_method.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RAND_set_rand_method 3"
-.TH RAND_set_rand_method 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RAND_set_rand_method 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_blinding_on.3 b/secure/lib/libcrypto/man/RSA_blinding_on.3
index 0c269dd..61aabbf 100644
--- a/secure/lib/libcrypto/man/RSA_blinding_on.3
+++ b/secure/lib/libcrypto/man/RSA_blinding_on.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_blinding_on 3"
-.TH RSA_blinding_on 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_blinding_on 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_check_key.3 b/secure/lib/libcrypto/man/RSA_check_key.3
index 33c586f..4fba01d 100644
--- a/secure/lib/libcrypto/man/RSA_check_key.3
+++ b/secure/lib/libcrypto/man/RSA_check_key.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_check_key 3"
-.TH RSA_check_key 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_check_key 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_generate_key.3 b/secure/lib/libcrypto/man/RSA_generate_key.3
index 026f87d4..d71fe32 100644
--- a/secure/lib/libcrypto/man/RSA_generate_key.3
+++ b/secure/lib/libcrypto/man/RSA_generate_key.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_generate_key 3"
-.TH RSA_generate_key 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_generate_key 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_get_ex_new_index.3 b/secure/lib/libcrypto/man/RSA_get_ex_new_index.3
index efea043..f0ea95a 100644
--- a/secure/lib/libcrypto/man/RSA_get_ex_new_index.3
+++ b/secure/lib/libcrypto/man/RSA_get_ex_new_index.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_get_ex_new_index 3"
-.TH RSA_get_ex_new_index 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_get_ex_new_index 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_new.3 b/secure/lib/libcrypto/man/RSA_new.3
index de3e2eb..331128e 100644
--- a/secure/lib/libcrypto/man/RSA_new.3
+++ b/secure/lib/libcrypto/man/RSA_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_new 3"
-.TH RSA_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3 b/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3
index 7925ab2..86fc5dd 100644
--- a/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3
+++ b/secure/lib/libcrypto/man/RSA_padding_add_PKCS1_type_1.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_padding_add_PKCS1_type_1 3"
-.TH RSA_padding_add_PKCS1_type_1 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_padding_add_PKCS1_type_1 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_print.3 b/secure/lib/libcrypto/man/RSA_print.3
index e6f0a2f..5337147 100644
--- a/secure/lib/libcrypto/man/RSA_print.3
+++ b/secure/lib/libcrypto/man/RSA_print.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_print 3"
-.TH RSA_print 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_print 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_private_encrypt.3 b/secure/lib/libcrypto/man/RSA_private_encrypt.3
index b657f51..94471c6 100644
--- a/secure/lib/libcrypto/man/RSA_private_encrypt.3
+++ b/secure/lib/libcrypto/man/RSA_private_encrypt.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_private_encrypt 3"
-.TH RSA_private_encrypt 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_private_encrypt 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_public_encrypt.3 b/secure/lib/libcrypto/man/RSA_public_encrypt.3
index 40e61ca..5edece8 100644
--- a/secure/lib/libcrypto/man/RSA_public_encrypt.3
+++ b/secure/lib/libcrypto/man/RSA_public_encrypt.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_public_encrypt 3"
-.TH RSA_public_encrypt 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_public_encrypt 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_set_method.3 b/secure/lib/libcrypto/man/RSA_set_method.3
index fa5e4a4..e746746 100644
--- a/secure/lib/libcrypto/man/RSA_set_method.3
+++ b/secure/lib/libcrypto/man/RSA_set_method.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_set_method 3"
-.TH RSA_set_method 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_set_method 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_sign.3 b/secure/lib/libcrypto/man/RSA_sign.3
index 212ab26..fc7f12a 100644
--- a/secure/lib/libcrypto/man/RSA_sign.3
+++ b/secure/lib/libcrypto/man/RSA_sign.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_sign 3"
-.TH RSA_sign 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_sign 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3 b/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3
index 21b12ad..feb01c7 100644
--- a/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3
+++ b/secure/lib/libcrypto/man/RSA_sign_ASN1_OCTET_STRING.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_sign_ASN1_OCTET_STRING 3"
-.TH RSA_sign_ASN1_OCTET_STRING 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_sign_ASN1_OCTET_STRING 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/RSA_size.3 b/secure/lib/libcrypto/man/RSA_size.3
index 0d161a8..ab5fcdb 100644
--- a/secure/lib/libcrypto/man/RSA_size.3
+++ b/secure/lib/libcrypto/man/RSA_size.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA_size 3"
-.TH RSA_size 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA_size 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/SMIME_read_PKCS7.3 b/secure/lib/libcrypto/man/SMIME_read_PKCS7.3
index 1b18c61..530f16e 100644
--- a/secure/lib/libcrypto/man/SMIME_read_PKCS7.3
+++ b/secure/lib/libcrypto/man/SMIME_read_PKCS7.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SMIME_read_PKCS7 3"
-.TH SMIME_read_PKCS7 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SMIME_read_PKCS7 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/SMIME_write_PKCS7.3 b/secure/lib/libcrypto/man/SMIME_write_PKCS7.3
index b583498..9f29d92 100644
--- a/secure/lib/libcrypto/man/SMIME_write_PKCS7.3
+++ b/secure/lib/libcrypto/man/SMIME_write_PKCS7.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SMIME_write_PKCS7 3"
-.TH SMIME_write_PKCS7 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SMIME_write_PKCS7 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3 b/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3
index 998f858..0aaaa10 100644
--- a/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3
+++ b/secure/lib/libcrypto/man/X509_NAME_ENTRY_get_object.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "X509_NAME_ENTRY_get_object 3"
-.TH X509_NAME_ENTRY_get_object 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH X509_NAME_ENTRY_get_object 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3 b/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3
index afc350f..db94069 100644
--- a/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3
+++ b/secure/lib/libcrypto/man/X509_NAME_add_entry_by_txt.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "X509_NAME_add_entry_by_txt 3"
-.TH X509_NAME_add_entry_by_txt 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH X509_NAME_add_entry_by_txt 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3 b/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3
index 49d9b7f..2e32476 100644
--- a/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3
+++ b/secure/lib/libcrypto/man/X509_NAME_get_index_by_NID.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "X509_NAME_get_index_by_NID 3"
-.TH X509_NAME_get_index_by_NID 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH X509_NAME_get_index_by_NID 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/X509_NAME_print_ex.3 b/secure/lib/libcrypto/man/X509_NAME_print_ex.3
index 3f905ec..0e4f215 100644
--- a/secure/lib/libcrypto/man/X509_NAME_print_ex.3
+++ b/secure/lib/libcrypto/man/X509_NAME_print_ex.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "X509_NAME_print_ex 3"
-.TH X509_NAME_print_ex 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH X509_NAME_print_ex 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/X509_new.3 b/secure/lib/libcrypto/man/X509_new.3
index d1b4dc8..72cf6f9 100644
--- a/secure/lib/libcrypto/man/X509_new.3
+++ b/secure/lib/libcrypto/man/X509_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "X509_new 3"
-.TH X509_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH X509_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/bio.3 b/secure/lib/libcrypto/man/bio.3
index a3bf79e..a43fa95 100644
--- a/secure/lib/libcrypto/man/bio.3
+++ b/secure/lib/libcrypto/man/bio.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "bio 3"
-.TH bio 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH bio 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/blowfish.3 b/secure/lib/libcrypto/man/blowfish.3
index df506af..8552647 100644
--- a/secure/lib/libcrypto/man/blowfish.3
+++ b/secure/lib/libcrypto/man/blowfish.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "blowfish 3"
-.TH blowfish 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH blowfish 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/bn.3 b/secure/lib/libcrypto/man/bn.3
index bd217c8..a22f61f 100644
--- a/secure/lib/libcrypto/man/bn.3
+++ b/secure/lib/libcrypto/man/bn.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "bn 3"
-.TH bn 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH bn 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/bn_internal.3 b/secure/lib/libcrypto/man/bn_internal.3
index b8aeb4f..9646e4a 100644
--- a/secure/lib/libcrypto/man/bn_internal.3
+++ b/secure/lib/libcrypto/man/bn_internal.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "bn_internal 3"
-.TH bn_internal 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH bn_internal 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/buffer.3 b/secure/lib/libcrypto/man/buffer.3
index 1fb8172..c468cc3 100644
--- a/secure/lib/libcrypto/man/buffer.3
+++ b/secure/lib/libcrypto/man/buffer.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "buffer 3"
-.TH buffer 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH buffer 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/crypto.3 b/secure/lib/libcrypto/man/crypto.3
index e13f9d7..8175f2f 100644
--- a/secure/lib/libcrypto/man/crypto.3
+++ b/secure/lib/libcrypto/man/crypto.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "crypto 3"
-.TH crypto 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH crypto 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3 b/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3
index b2548ab..68de02b 100644
--- a/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3
+++ b/secure/lib/libcrypto/man/d2i_ASN1_OBJECT.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_ASN1_OBJECT 3"
-.TH d2i_ASN1_OBJECT 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_ASN1_OBJECT 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_DHparams.3 b/secure/lib/libcrypto/man/d2i_DHparams.3
index d77b318..0d8d30f 100644
--- a/secure/lib/libcrypto/man/d2i_DHparams.3
+++ b/secure/lib/libcrypto/man/d2i_DHparams.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_DHparams 3"
-.TH d2i_DHparams 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_DHparams 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_DSAPublicKey.3 b/secure/lib/libcrypto/man/d2i_DSAPublicKey.3
index a00c837..69e8d7e 100644
--- a/secure/lib/libcrypto/man/d2i_DSAPublicKey.3
+++ b/secure/lib/libcrypto/man/d2i_DSAPublicKey.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_DSAPublicKey 3"
-.TH d2i_DSAPublicKey 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_DSAPublicKey 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3 b/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3
index b65a1ed..e658a3e 100644
--- a/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3
+++ b/secure/lib/libcrypto/man/d2i_PKCS8PrivateKey.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_PKCS8PrivateKey 3"
-.TH d2i_PKCS8PrivateKey 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_PKCS8PrivateKey 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_RSAPublicKey.3 b/secure/lib/libcrypto/man/d2i_RSAPublicKey.3
index fccaa2b..64f4414 100644
--- a/secure/lib/libcrypto/man/d2i_RSAPublicKey.3
+++ b/secure/lib/libcrypto/man/d2i_RSAPublicKey.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_RSAPublicKey 3"
-.TH d2i_RSAPublicKey 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_RSAPublicKey 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_X509.3 b/secure/lib/libcrypto/man/d2i_X509.3
index e98e687..f0580f1 100644
--- a/secure/lib/libcrypto/man/d2i_X509.3
+++ b/secure/lib/libcrypto/man/d2i_X509.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509 3"
-.TH d2i_X509 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_X509 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_X509_ALGOR.3 b/secure/lib/libcrypto/man/d2i_X509_ALGOR.3
index d12a8c1..4c4e298 100644
--- a/secure/lib/libcrypto/man/d2i_X509_ALGOR.3
+++ b/secure/lib/libcrypto/man/d2i_X509_ALGOR.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509_ALGOR 3"
-.TH d2i_X509_ALGOR 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_X509_ALGOR 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_X509_CRL.3 b/secure/lib/libcrypto/man/d2i_X509_CRL.3
index dc06175..8b4de84 100644
--- a/secure/lib/libcrypto/man/d2i_X509_CRL.3
+++ b/secure/lib/libcrypto/man/d2i_X509_CRL.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509_CRL 3"
-.TH d2i_X509_CRL 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_X509_CRL 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_X509_NAME.3 b/secure/lib/libcrypto/man/d2i_X509_NAME.3
index 954eed5..074c144 100644
--- a/secure/lib/libcrypto/man/d2i_X509_NAME.3
+++ b/secure/lib/libcrypto/man/d2i_X509_NAME.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509_NAME 3"
-.TH d2i_X509_NAME 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_X509_NAME 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_X509_REQ.3 b/secure/lib/libcrypto/man/d2i_X509_REQ.3
index 5f7c636..8cffc57 100644
--- a/secure/lib/libcrypto/man/d2i_X509_REQ.3
+++ b/secure/lib/libcrypto/man/d2i_X509_REQ.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509_REQ 3"
-.TH d2i_X509_REQ 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_X509_REQ 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/d2i_X509_SIG.3 b/secure/lib/libcrypto/man/d2i_X509_SIG.3
index 22e3d8a..f7e20b5 100644
--- a/secure/lib/libcrypto/man/d2i_X509_SIG.3
+++ b/secure/lib/libcrypto/man/d2i_X509_SIG.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_X509_SIG 3"
-.TH d2i_X509_SIG 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_X509_SIG 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/des.3 b/secure/lib/libcrypto/man/des.3
index e7b72b3..510fd18 100644
--- a/secure/lib/libcrypto/man/des.3
+++ b/secure/lib/libcrypto/man/des.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "des 3"
-.TH des 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH des 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/dh.3 b/secure/lib/libcrypto/man/dh.3
index bdd24a9..19bc676 100644
--- a/secure/lib/libcrypto/man/dh.3
+++ b/secure/lib/libcrypto/man/dh.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "dh 3"
-.TH dh 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH dh 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/dsa.3 b/secure/lib/libcrypto/man/dsa.3
index 997d635..80259da 100644
--- a/secure/lib/libcrypto/man/dsa.3
+++ b/secure/lib/libcrypto/man/dsa.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "dsa 3"
-.TH dsa 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH dsa 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ecdsa.3 b/secure/lib/libcrypto/man/ecdsa.3
index e0c1eb2..d048a87 100644
--- a/secure/lib/libcrypto/man/ecdsa.3
+++ b/secure/lib/libcrypto/man/ecdsa.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ecdsa 3"
-.TH ecdsa 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ecdsa 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/engine.3 b/secure/lib/libcrypto/man/engine.3
index 3c22397..e9ce280 100644
--- a/secure/lib/libcrypto/man/engine.3
+++ b/secure/lib/libcrypto/man/engine.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "engine 3"
-.TH engine 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH engine 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/err.3 b/secure/lib/libcrypto/man/err.3
index 77b1130..5e2fc04 100644
--- a/secure/lib/libcrypto/man/err.3
+++ b/secure/lib/libcrypto/man/err.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "err 3"
-.TH err 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH err 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/evp.3 b/secure/lib/libcrypto/man/evp.3
index 758cc14..d7a40f5 100644
--- a/secure/lib/libcrypto/man/evp.3
+++ b/secure/lib/libcrypto/man/evp.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "evp 3"
-.TH evp 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH evp 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/hmac.3 b/secure/lib/libcrypto/man/hmac.3
index f6eb5c6..7b90627 100644
--- a/secure/lib/libcrypto/man/hmac.3
+++ b/secure/lib/libcrypto/man/hmac.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "hmac 3"
-.TH hmac 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH hmac 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/lh_stats.3 b/secure/lib/libcrypto/man/lh_stats.3
index ddf5ff3..aeefa31 100644
--- a/secure/lib/libcrypto/man/lh_stats.3
+++ b/secure/lib/libcrypto/man/lh_stats.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "lh_stats 3"
-.TH lh_stats 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH lh_stats 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/lhash.3 b/secure/lib/libcrypto/man/lhash.3
index fd02624..bec634f 100644
--- a/secure/lib/libcrypto/man/lhash.3
+++ b/secure/lib/libcrypto/man/lhash.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "lhash 3"
-.TH lhash 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH lhash 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/md5.3 b/secure/lib/libcrypto/man/md5.3
index e91c877..c80bcef 100644
--- a/secure/lib/libcrypto/man/md5.3
+++ b/secure/lib/libcrypto/man/md5.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "md5 3"
-.TH md5 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH md5 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/mdc2.3 b/secure/lib/libcrypto/man/mdc2.3
index 8d6449d..13f03fd 100644
--- a/secure/lib/libcrypto/man/mdc2.3
+++ b/secure/lib/libcrypto/man/mdc2.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "mdc2 3"
-.TH mdc2 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH mdc2 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/pem.3 b/secure/lib/libcrypto/man/pem.3
index 9eea580..470a74f 100644
--- a/secure/lib/libcrypto/man/pem.3
+++ b/secure/lib/libcrypto/man/pem.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "pem 3"
-.TH pem 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH pem 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/rand.3 b/secure/lib/libcrypto/man/rand.3
index 63ec651..c5f654d 100644
--- a/secure/lib/libcrypto/man/rand.3
+++ b/secure/lib/libcrypto/man/rand.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "rand 3"
-.TH rand 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH rand 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/rc4.3 b/secure/lib/libcrypto/man/rc4.3
index 04a4d9a..fbcbf3c 100644
--- a/secure/lib/libcrypto/man/rc4.3
+++ b/secure/lib/libcrypto/man/rc4.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "rc4 3"
-.TH rc4 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH rc4 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ripemd.3 b/secure/lib/libcrypto/man/ripemd.3
index d1b5c62..abde3f8 100644
--- a/secure/lib/libcrypto/man/ripemd.3
+++ b/secure/lib/libcrypto/man/ripemd.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ripemd 3"
-.TH ripemd 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ripemd 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/rsa.3 b/secure/lib/libcrypto/man/rsa.3
index c0e4304..6bc5672 100644
--- a/secure/lib/libcrypto/man/rsa.3
+++ b/secure/lib/libcrypto/man/rsa.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "rsa 3"
-.TH rsa 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH rsa 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/sha.3 b/secure/lib/libcrypto/man/sha.3
index 2494f6b..b9120fa 100644
--- a/secure/lib/libcrypto/man/sha.3
+++ b/secure/lib/libcrypto/man/sha.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "sha 3"
-.TH sha 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH sha 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/threads.3 b/secure/lib/libcrypto/man/threads.3
index 512d8fe..5907668 100644
--- a/secure/lib/libcrypto/man/threads.3
+++ b/secure/lib/libcrypto/man/threads.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "threads 3"
-.TH threads 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH threads 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ui.3 b/secure/lib/libcrypto/man/ui.3
index af5ecfd..a009b9e 100644
--- a/secure/lib/libcrypto/man/ui.3
+++ b/secure/lib/libcrypto/man/ui.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ui 3"
-.TH ui 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ui 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/ui_compat.3 b/secure/lib/libcrypto/man/ui_compat.3
index e172642..5251803 100644
--- a/secure/lib/libcrypto/man/ui_compat.3
+++ b/secure/lib/libcrypto/man/ui_compat.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ui_compat 3"
-.TH ui_compat 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ui_compat 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libcrypto/man/x509.3 b/secure/lib/libcrypto/man/x509.3
index e4a41c5..fc20561 100644
--- a/secure/lib/libcrypto/man/x509.3
+++ b/secure/lib/libcrypto/man/x509.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "x509 3"
-.TH x509 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH x509 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CIPHER_get_name.3 b/secure/lib/libssl/man/SSL_CIPHER_get_name.3
index 117da98..0a28e0a 100644
--- a/secure/lib/libssl/man/SSL_CIPHER_get_name.3
+++ b/secure/lib/libssl/man/SSL_CIPHER_get_name.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CIPHER_get_name 3"
-.TH SSL_CIPHER_get_name 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CIPHER_get_name 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_COMP_add_compression_method.3 b/secure/lib/libssl/man/SSL_COMP_add_compression_method.3
index 978a085..2039b1c 100644
--- a/secure/lib/libssl/man/SSL_COMP_add_compression_method.3
+++ b/secure/lib/libssl/man/SSL_COMP_add_compression_method.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_COMP_add_compression_method 3"
-.TH SSL_COMP_add_compression_method 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_COMP_add_compression_method 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3 b/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3
index d57a48b..5c09f4e 100644
--- a/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3
+++ b/secure/lib/libssl/man/SSL_CTX_add_extra_chain_cert.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_add_extra_chain_cert 3"
-.TH SSL_CTX_add_extra_chain_cert 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_add_extra_chain_cert 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_add_session.3 b/secure/lib/libssl/man/SSL_CTX_add_session.3
index 3efbd2f..e74d1c9 100644
--- a/secure/lib/libssl/man/SSL_CTX_add_session.3
+++ b/secure/lib/libssl/man/SSL_CTX_add_session.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_add_session 3"
-.TH SSL_CTX_add_session 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_add_session 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_ctrl.3 b/secure/lib/libssl/man/SSL_CTX_ctrl.3
index 5b5555a..5fc2c53 100644
--- a/secure/lib/libssl/man/SSL_CTX_ctrl.3
+++ b/secure/lib/libssl/man/SSL_CTX_ctrl.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_ctrl 3"
-.TH SSL_CTX_ctrl 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_ctrl 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_flush_sessions.3 b/secure/lib/libssl/man/SSL_CTX_flush_sessions.3
index f0dba17..e1505be 100644
--- a/secure/lib/libssl/man/SSL_CTX_flush_sessions.3
+++ b/secure/lib/libssl/man/SSL_CTX_flush_sessions.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_flush_sessions 3"
-.TH SSL_CTX_flush_sessions 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_flush_sessions 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_free.3 b/secure/lib/libssl/man/SSL_CTX_free.3
index 3e54cb2..2a19b23 100644
--- a/secure/lib/libssl/man/SSL_CTX_free.3
+++ b/secure/lib/libssl/man/SSL_CTX_free.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_free 3"
-.TH SSL_CTX_free 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_free 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3 b/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3
index fd00dbb..45e37ad 100644
--- a/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3
+++ b/secure/lib/libssl/man/SSL_CTX_get_ex_new_index.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_get_ex_new_index 3"
-.TH SSL_CTX_get_ex_new_index 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_get_ex_new_index 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3 b/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3
index d72d30a..1825011 100644
--- a/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3
+++ b/secure/lib/libssl/man/SSL_CTX_get_verify_mode.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_get_verify_mode 3"
-.TH SSL_CTX_get_verify_mode 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_get_verify_mode 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3 b/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3
index 79b4db7..9aecb8f 100644
--- a/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3
+++ b/secure/lib/libssl/man/SSL_CTX_load_verify_locations.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_load_verify_locations 3"
-.TH SSL_CTX_load_verify_locations 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_load_verify_locations 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_new.3 b/secure/lib/libssl/man/SSL_CTX_new.3
index 7b54348..c10d335 100644
--- a/secure/lib/libssl/man/SSL_CTX_new.3
+++ b/secure/lib/libssl/man/SSL_CTX_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_new 3"
-.TH SSL_CTX_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_sess_number.3 b/secure/lib/libssl/man/SSL_CTX_sess_number.3
index 5937c78..45ca9f6 100644
--- a/secure/lib/libssl/man/SSL_CTX_sess_number.3
+++ b/secure/lib/libssl/man/SSL_CTX_sess_number.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_sess_number 3"
-.TH SSL_CTX_sess_number 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_sess_number 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3 b/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3
index 6956b71..e9cfa96 100644
--- a/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3
+++ b/secure/lib/libssl/man/SSL_CTX_sess_set_cache_size.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_sess_set_cache_size 3"
-.TH SSL_CTX_sess_set_cache_size 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_sess_set_cache_size 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3 b/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3
index b356475..5b12c7e 100644
--- a/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3
+++ b/secure/lib/libssl/man/SSL_CTX_sess_set_get_cb.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_sess_set_get_cb 3"
-.TH SSL_CTX_sess_set_get_cb 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_sess_set_get_cb 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_sessions.3 b/secure/lib/libssl/man/SSL_CTX_sessions.3
index d7eb624..b8f4666 100644
--- a/secure/lib/libssl/man/SSL_CTX_sessions.3
+++ b/secure/lib/libssl/man/SSL_CTX_sessions.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_sessions 3"
-.TH SSL_CTX_sessions 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_sessions 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_cert_store.3 b/secure/lib/libssl/man/SSL_CTX_set_cert_store.3
index 984f9c7..f53d4bc 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_cert_store.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_cert_store.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_cert_store 3"
-.TH SSL_CTX_set_cert_store 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_cert_store 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3
index 8e668c5..57d3f90 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_cert_verify_callback.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_cert_verify_callback 3"
-.TH SSL_CTX_set_cert_verify_callback 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_cert_verify_callback 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3 b/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3
index 4ad0c22..c6e1de2 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_cipher_list.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_cipher_list 3"
-.TH SSL_CTX_set_cipher_list 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_cipher_list 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3 b/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3
index 323bbce..6240f79 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_client_CA_list.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_client_CA_list 3"
-.TH SSL_CTX_set_client_CA_list 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_client_CA_list 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3 b/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3
index d0cc2a5..b5df457 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_client_cert_cb.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_client_cert_cb 3"
-.TH SSL_CTX_set_client_cert_cb 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_client_cert_cb 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3 b/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3
index 8be19f2..5dc40f5 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_default_passwd_cb.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_default_passwd_cb 3"
-.TH SSL_CTX_set_default_passwd_cb 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_default_passwd_cb 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3 b/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3
index 8452180..c57f634 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_generate_session_id.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_generate_session_id 3"
-.TH SSL_CTX_set_generate_session_id 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_generate_session_id 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_info_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_info_callback.3
index 62f601e..f01f8e3 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_info_callback.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_info_callback.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_info_callback 3"
-.TH SSL_CTX_set_info_callback 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_info_callback 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3 b/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3
index 06b8813..d9d5762 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_max_cert_list.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_max_cert_list 3"
-.TH SSL_CTX_set_max_cert_list 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_max_cert_list 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_mode.3 b/secure/lib/libssl/man/SSL_CTX_set_mode.3
index feedc14..5418b96 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_mode.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_mode.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_mode 3"
-.TH SSL_CTX_set_mode 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_mode 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3
index d203f28..1ef26ba 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_msg_callback.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_msg_callback 3"
-.TH SSL_CTX_set_msg_callback 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_msg_callback 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_options.3 b/secure/lib/libssl/man/SSL_CTX_set_options.3
index a9de479..b2e2cb4 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_options.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_options.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_options 3"
-.TH SSL_CTX_set_options 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_options 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -200,18 +200,7 @@ when operating in SSLv2/v3 compatibility mode, but as mentioned above,
this breaks this server so 16 bytes is the way to go.
.IP "\s-1SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG\s0" 4
.IX Item "SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG"
-ssl3.netscape.com:443, first a connection is established with \s-1RC4\-MD5\s0.
-If it is then resumed, we end up using \s-1DES\-CBC3\-SHA\s0. It should be
-\&\s-1RC4\-MD5\s0 according to 7.6.1.3, 'cipher_suite'.
-.Sp
-Netscape\-Enterprise/2.01 (https://merchant.netscape.com) has this bug.
-It only really shows up when connecting via SSLv2/v3 then reconnecting
-via SSLv3. The cipher list changes....
-.Sp
-\&\s-1NEW\s0 \s-1INFORMATION\s0. Try connecting with a cipher list of just
-\&\s-1DES\-CBC\-SHA:RC4\-MD5\s0. For some weird reason, each new connection uses
-\&\s-1RC4\-MD5\s0, but a re-connect tries to use DES-CBC-SHA. So netscape, when
-doing a re-connect, always takes the first cipher in the cipher list.
+As of OpenSSL 0.9.8q and 1.0.0c, this option has no effect.
.IP "\s-1SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG\s0" 4
.IX Item "SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG"
\&...
diff --git a/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3 b/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3
index 0696a6a..c60e048 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_quiet_shutdown.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_quiet_shutdown 3"
-.TH SSL_CTX_set_quiet_shutdown 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_quiet_shutdown 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3 b/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3
index a9eeafb..37dfbb0 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_session_cache_mode.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_session_cache_mode 3"
-.TH SSL_CTX_set_session_cache_mode 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_session_cache_mode 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3 b/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3
index 1d5cfe0..20348ff 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_session_id_context.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_session_id_context 3"
-.TH SSL_CTX_set_session_id_context 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_session_id_context 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3 b/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3
index 642092d..e716731 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_ssl_version.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_ssl_version 3"
-.TH SSL_CTX_set_ssl_version 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_ssl_version 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_timeout.3 b/secure/lib/libssl/man/SSL_CTX_set_timeout.3
index bb2cd32..2144d16 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_timeout.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_timeout.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_timeout 3"
-.TH SSL_CTX_set_timeout 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_timeout 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3
index c7c029c..e11f10b 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_tmp_dh_callback.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_tmp_dh_callback 3"
-.TH SSL_CTX_set_tmp_dh_callback 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_tmp_dh_callback 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3 b/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3
index c7d7051..6a1fd71 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_tmp_rsa_callback.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_tmp_rsa_callback 3"
-.TH SSL_CTX_set_tmp_rsa_callback 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_tmp_rsa_callback 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_set_verify.3 b/secure/lib/libssl/man/SSL_CTX_set_verify.3
index 7493237..1971e21 100644
--- a/secure/lib/libssl/man/SSL_CTX_set_verify.3
+++ b/secure/lib/libssl/man/SSL_CTX_set_verify.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_set_verify 3"
-.TH SSL_CTX_set_verify 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_set_verify 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_CTX_use_certificate.3 b/secure/lib/libssl/man/SSL_CTX_use_certificate.3
index a3a90d7..358dd6c 100644
--- a/secure/lib/libssl/man/SSL_CTX_use_certificate.3
+++ b/secure/lib/libssl/man/SSL_CTX_use_certificate.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_CTX_use_certificate 3"
-.TH SSL_CTX_use_certificate 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_CTX_use_certificate 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_SESSION_free.3 b/secure/lib/libssl/man/SSL_SESSION_free.3
index f5c1864..64d9b84 100644
--- a/secure/lib/libssl/man/SSL_SESSION_free.3
+++ b/secure/lib/libssl/man/SSL_SESSION_free.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_SESSION_free 3"
-.TH SSL_SESSION_free 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_SESSION_free 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3 b/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3
index a362255..553e43c 100644
--- a/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3
+++ b/secure/lib/libssl/man/SSL_SESSION_get_ex_new_index.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_SESSION_get_ex_new_index 3"
-.TH SSL_SESSION_get_ex_new_index 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_SESSION_get_ex_new_index 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_SESSION_get_time.3 b/secure/lib/libssl/man/SSL_SESSION_get_time.3
index cefd01a..bdbbb7a 100644
--- a/secure/lib/libssl/man/SSL_SESSION_get_time.3
+++ b/secure/lib/libssl/man/SSL_SESSION_get_time.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_SESSION_get_time 3"
-.TH SSL_SESSION_get_time 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_SESSION_get_time 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_accept.3 b/secure/lib/libssl/man/SSL_accept.3
index 29f5647..0c3a6d5 100644
--- a/secure/lib/libssl/man/SSL_accept.3
+++ b/secure/lib/libssl/man/SSL_accept.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_accept 3"
-.TH SSL_accept 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_accept 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_alert_type_string.3 b/secure/lib/libssl/man/SSL_alert_type_string.3
index 125ae01..2735e4b 100644
--- a/secure/lib/libssl/man/SSL_alert_type_string.3
+++ b/secure/lib/libssl/man/SSL_alert_type_string.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_alert_type_string 3"
-.TH SSL_alert_type_string 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_alert_type_string 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_clear.3 b/secure/lib/libssl/man/SSL_clear.3
index 38d2343..25bca22 100644
--- a/secure/lib/libssl/man/SSL_clear.3
+++ b/secure/lib/libssl/man/SSL_clear.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_clear 3"
-.TH SSL_clear 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_clear 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_connect.3 b/secure/lib/libssl/man/SSL_connect.3
index 800cd58..a51b65c 100644
--- a/secure/lib/libssl/man/SSL_connect.3
+++ b/secure/lib/libssl/man/SSL_connect.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_connect 3"
-.TH SSL_connect 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_connect 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_do_handshake.3 b/secure/lib/libssl/man/SSL_do_handshake.3
index 95581d3..664c22f 100644
--- a/secure/lib/libssl/man/SSL_do_handshake.3
+++ b/secure/lib/libssl/man/SSL_do_handshake.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_do_handshake 3"
-.TH SSL_do_handshake 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_do_handshake 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_free.3 b/secure/lib/libssl/man/SSL_free.3
index 89ea8de..d035365 100644
--- a/secure/lib/libssl/man/SSL_free.3
+++ b/secure/lib/libssl/man/SSL_free.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_free 3"
-.TH SSL_free 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_free 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_SSL_CTX.3 b/secure/lib/libssl/man/SSL_get_SSL_CTX.3
index dfba4a2..5f063e1 100644
--- a/secure/lib/libssl/man/SSL_get_SSL_CTX.3
+++ b/secure/lib/libssl/man/SSL_get_SSL_CTX.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_SSL_CTX 3"
-.TH SSL_get_SSL_CTX 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_SSL_CTX 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_ciphers.3 b/secure/lib/libssl/man/SSL_get_ciphers.3
index 3635e2e..56ea6e8 100644
--- a/secure/lib/libssl/man/SSL_get_ciphers.3
+++ b/secure/lib/libssl/man/SSL_get_ciphers.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_ciphers 3"
-.TH SSL_get_ciphers 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_ciphers 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_client_CA_list.3 b/secure/lib/libssl/man/SSL_get_client_CA_list.3
index 7088e60..3ae3739 100644
--- a/secure/lib/libssl/man/SSL_get_client_CA_list.3
+++ b/secure/lib/libssl/man/SSL_get_client_CA_list.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_client_CA_list 3"
-.TH SSL_get_client_CA_list 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_client_CA_list 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_current_cipher.3 b/secure/lib/libssl/man/SSL_get_current_cipher.3
index 1854b4a..d08981e 100644
--- a/secure/lib/libssl/man/SSL_get_current_cipher.3
+++ b/secure/lib/libssl/man/SSL_get_current_cipher.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_current_cipher 3"
-.TH SSL_get_current_cipher 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_current_cipher 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_default_timeout.3 b/secure/lib/libssl/man/SSL_get_default_timeout.3
index 3e81a0d..4c1d965 100644
--- a/secure/lib/libssl/man/SSL_get_default_timeout.3
+++ b/secure/lib/libssl/man/SSL_get_default_timeout.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_default_timeout 3"
-.TH SSL_get_default_timeout 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_default_timeout 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_error.3 b/secure/lib/libssl/man/SSL_get_error.3
index be41260..1289682 100644
--- a/secure/lib/libssl/man/SSL_get_error.3
+++ b/secure/lib/libssl/man/SSL_get_error.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_error 3"
-.TH SSL_get_error 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_error 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3 b/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3
index e98fa75..a81f4de 100644
--- a/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3
+++ b/secure/lib/libssl/man/SSL_get_ex_data_X509_STORE_CTX_idx.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_ex_data_X509_STORE_CTX_idx 3"
-.TH SSL_get_ex_data_X509_STORE_CTX_idx 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_ex_data_X509_STORE_CTX_idx 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_ex_new_index.3 b/secure/lib/libssl/man/SSL_get_ex_new_index.3
index 1fde9b3..4896c63 100644
--- a/secure/lib/libssl/man/SSL_get_ex_new_index.3
+++ b/secure/lib/libssl/man/SSL_get_ex_new_index.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_ex_new_index 3"
-.TH SSL_get_ex_new_index 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_ex_new_index 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_fd.3 b/secure/lib/libssl/man/SSL_get_fd.3
index 9e83cb1..ac7f7ea 100644
--- a/secure/lib/libssl/man/SSL_get_fd.3
+++ b/secure/lib/libssl/man/SSL_get_fd.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_fd 3"
-.TH SSL_get_fd 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_fd 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_peer_cert_chain.3 b/secure/lib/libssl/man/SSL_get_peer_cert_chain.3
index bb3cdd5..8ac8a69 100644
--- a/secure/lib/libssl/man/SSL_get_peer_cert_chain.3
+++ b/secure/lib/libssl/man/SSL_get_peer_cert_chain.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_peer_cert_chain 3"
-.TH SSL_get_peer_cert_chain 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_peer_cert_chain 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_peer_certificate.3 b/secure/lib/libssl/man/SSL_get_peer_certificate.3
index 9a505a9..26a51d8 100644
--- a/secure/lib/libssl/man/SSL_get_peer_certificate.3
+++ b/secure/lib/libssl/man/SSL_get_peer_certificate.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_peer_certificate 3"
-.TH SSL_get_peer_certificate 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_peer_certificate 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_rbio.3 b/secure/lib/libssl/man/SSL_get_rbio.3
index 9ed5c51..630a26e 100644
--- a/secure/lib/libssl/man/SSL_get_rbio.3
+++ b/secure/lib/libssl/man/SSL_get_rbio.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_rbio 3"
-.TH SSL_get_rbio 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_rbio 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_session.3 b/secure/lib/libssl/man/SSL_get_session.3
index 5864145..3e4d913 100644
--- a/secure/lib/libssl/man/SSL_get_session.3
+++ b/secure/lib/libssl/man/SSL_get_session.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_session 3"
-.TH SSL_get_session 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_session 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_verify_result.3 b/secure/lib/libssl/man/SSL_get_verify_result.3
index 709d9d2..5ce0d4c 100644
--- a/secure/lib/libssl/man/SSL_get_verify_result.3
+++ b/secure/lib/libssl/man/SSL_get_verify_result.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_verify_result 3"
-.TH SSL_get_verify_result 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_verify_result 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_get_version.3 b/secure/lib/libssl/man/SSL_get_version.3
index 04fc844..b52d556 100644
--- a/secure/lib/libssl/man/SSL_get_version.3
+++ b/secure/lib/libssl/man/SSL_get_version.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_get_version 3"
-.TH SSL_get_version 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_get_version 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_library_init.3 b/secure/lib/libssl/man/SSL_library_init.3
index e870dd2..abed958 100644
--- a/secure/lib/libssl/man/SSL_library_init.3
+++ b/secure/lib/libssl/man/SSL_library_init.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_library_init 3"
-.TH SSL_library_init 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_library_init 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_load_client_CA_file.3 b/secure/lib/libssl/man/SSL_load_client_CA_file.3
index 1f7ec03..154b3e7 100644
--- a/secure/lib/libssl/man/SSL_load_client_CA_file.3
+++ b/secure/lib/libssl/man/SSL_load_client_CA_file.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_load_client_CA_file 3"
-.TH SSL_load_client_CA_file 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_load_client_CA_file 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_new.3 b/secure/lib/libssl/man/SSL_new.3
index 74f2c88..b20687d 100644
--- a/secure/lib/libssl/man/SSL_new.3
+++ b/secure/lib/libssl/man/SSL_new.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_new 3"
-.TH SSL_new 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_new 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_pending.3 b/secure/lib/libssl/man/SSL_pending.3
index 44658b6..fb98f0e 100644
--- a/secure/lib/libssl/man/SSL_pending.3
+++ b/secure/lib/libssl/man/SSL_pending.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_pending 3"
-.TH SSL_pending 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_pending 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_read.3 b/secure/lib/libssl/man/SSL_read.3
index 3593bb3..69383c5 100644
--- a/secure/lib/libssl/man/SSL_read.3
+++ b/secure/lib/libssl/man/SSL_read.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_read 3"
-.TH SSL_read 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_read 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_rstate_string.3 b/secure/lib/libssl/man/SSL_rstate_string.3
index a166d95..694b38f 100644
--- a/secure/lib/libssl/man/SSL_rstate_string.3
+++ b/secure/lib/libssl/man/SSL_rstate_string.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_rstate_string 3"
-.TH SSL_rstate_string 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_rstate_string 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_session_reused.3 b/secure/lib/libssl/man/SSL_session_reused.3
index c749e3c..b6f2b0f 100644
--- a/secure/lib/libssl/man/SSL_session_reused.3
+++ b/secure/lib/libssl/man/SSL_session_reused.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_session_reused 3"
-.TH SSL_session_reused 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_session_reused 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_set_bio.3 b/secure/lib/libssl/man/SSL_set_bio.3
index 9466fb4..57b8d30 100644
--- a/secure/lib/libssl/man/SSL_set_bio.3
+++ b/secure/lib/libssl/man/SSL_set_bio.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_bio 3"
-.TH SSL_set_bio 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_set_bio 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_set_connect_state.3 b/secure/lib/libssl/man/SSL_set_connect_state.3
index 4ff119c..1b681a0 100644
--- a/secure/lib/libssl/man/SSL_set_connect_state.3
+++ b/secure/lib/libssl/man/SSL_set_connect_state.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_connect_state 3"
-.TH SSL_set_connect_state 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_set_connect_state 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_set_fd.3 b/secure/lib/libssl/man/SSL_set_fd.3
index 8b97fe5..3f9fddb 100644
--- a/secure/lib/libssl/man/SSL_set_fd.3
+++ b/secure/lib/libssl/man/SSL_set_fd.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_fd 3"
-.TH SSL_set_fd 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_set_fd 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_set_session.3 b/secure/lib/libssl/man/SSL_set_session.3
index eccb9ab..7e8c70c 100644
--- a/secure/lib/libssl/man/SSL_set_session.3
+++ b/secure/lib/libssl/man/SSL_set_session.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_session 3"
-.TH SSL_set_session 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_set_session 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_set_shutdown.3 b/secure/lib/libssl/man/SSL_set_shutdown.3
index c513c4c..9b211de 100644
--- a/secure/lib/libssl/man/SSL_set_shutdown.3
+++ b/secure/lib/libssl/man/SSL_set_shutdown.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_shutdown 3"
-.TH SSL_set_shutdown 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_set_shutdown 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_set_verify_result.3 b/secure/lib/libssl/man/SSL_set_verify_result.3
index 8b205cd..1cffb23 100644
--- a/secure/lib/libssl/man/SSL_set_verify_result.3
+++ b/secure/lib/libssl/man/SSL_set_verify_result.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_set_verify_result 3"
-.TH SSL_set_verify_result 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_set_verify_result 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_shutdown.3 b/secure/lib/libssl/man/SSL_shutdown.3
index e5e74c8..d794359 100644
--- a/secure/lib/libssl/man/SSL_shutdown.3
+++ b/secure/lib/libssl/man/SSL_shutdown.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_shutdown 3"
-.TH SSL_shutdown 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_shutdown 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_state_string.3 b/secure/lib/libssl/man/SSL_state_string.3
index df8ba49..f9e3cf1 100644
--- a/secure/lib/libssl/man/SSL_state_string.3
+++ b/secure/lib/libssl/man/SSL_state_string.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_state_string 3"
-.TH SSL_state_string 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_state_string 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_want.3 b/secure/lib/libssl/man/SSL_want.3
index 9b5e449..e61762d 100644
--- a/secure/lib/libssl/man/SSL_want.3
+++ b/secure/lib/libssl/man/SSL_want.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_want 3"
-.TH SSL_want 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_want 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/SSL_write.3 b/secure/lib/libssl/man/SSL_write.3
index cf6857b..2883ff8 100644
--- a/secure/lib/libssl/man/SSL_write.3
+++ b/secure/lib/libssl/man/SSL_write.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SSL_write 3"
-.TH SSL_write 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SSL_write 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/d2i_SSL_SESSION.3 b/secure/lib/libssl/man/d2i_SSL_SESSION.3
index 3e90307..233247b 100644
--- a/secure/lib/libssl/man/d2i_SSL_SESSION.3
+++ b/secure/lib/libssl/man/d2i_SSL_SESSION.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "d2i_SSL_SESSION 3"
-.TH d2i_SSL_SESSION 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH d2i_SSL_SESSION 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/lib/libssl/man/ssl.3 b/secure/lib/libssl/man/ssl.3
index 7a22abd..61e9bf8 100644
--- a/secure/lib/libssl/man/ssl.3
+++ b/secure/lib/libssl/man/ssl.3
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ssl 3"
-.TH ssl 3 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ssl 3 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/CA.pl.1 b/secure/usr.bin/openssl/man/CA.pl.1
index f9b2e48..7c3c4eb 100644
--- a/secure/usr.bin/openssl/man/CA.pl.1
+++ b/secure/usr.bin/openssl/man/CA.pl.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "CA.PL 1"
-.TH CA.PL 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH CA.PL 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/asn1parse.1 b/secure/usr.bin/openssl/man/asn1parse.1
index 78f59c5..3fd727b 100644
--- a/secure/usr.bin/openssl/man/asn1parse.1
+++ b/secure/usr.bin/openssl/man/asn1parse.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ASN1PARSE 1"
-.TH ASN1PARSE 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ASN1PARSE 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/ca.1 b/secure/usr.bin/openssl/man/ca.1
index e14eede..9de935d 100644
--- a/secure/usr.bin/openssl/man/ca.1
+++ b/secure/usr.bin/openssl/man/ca.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "CA 1"
-.TH CA 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH CA 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/ciphers.1 b/secure/usr.bin/openssl/man/ciphers.1
index 0ac0b1e..46f1f97 100644
--- a/secure/usr.bin/openssl/man/ciphers.1
+++ b/secure/usr.bin/openssl/man/ciphers.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "CIPHERS 1"
-.TH CIPHERS 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH CIPHERS 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/crl.1 b/secure/usr.bin/openssl/man/crl.1
index 82f022d..5ed5e4b 100644
--- a/secure/usr.bin/openssl/man/crl.1
+++ b/secure/usr.bin/openssl/man/crl.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "CRL 1"
-.TH CRL 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH CRL 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/crl2pkcs7.1 b/secure/usr.bin/openssl/man/crl2pkcs7.1
index 29dc7e7..55083e1 100644
--- a/secure/usr.bin/openssl/man/crl2pkcs7.1
+++ b/secure/usr.bin/openssl/man/crl2pkcs7.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "CRL2PKCS7 1"
-.TH CRL2PKCS7 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH CRL2PKCS7 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/dgst.1 b/secure/usr.bin/openssl/man/dgst.1
index a0373cc..9d33fdf 100644
--- a/secure/usr.bin/openssl/man/dgst.1
+++ b/secure/usr.bin/openssl/man/dgst.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DGST 1"
-.TH DGST 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DGST 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/dhparam.1 b/secure/usr.bin/openssl/man/dhparam.1
index e93899a..0a61289 100644
--- a/secure/usr.bin/openssl/man/dhparam.1
+++ b/secure/usr.bin/openssl/man/dhparam.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DHPARAM 1"
-.TH DHPARAM 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DHPARAM 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/dsa.1 b/secure/usr.bin/openssl/man/dsa.1
index 1879eab..e93e28a 100644
--- a/secure/usr.bin/openssl/man/dsa.1
+++ b/secure/usr.bin/openssl/man/dsa.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSA 1"
-.TH DSA 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSA 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/dsaparam.1 b/secure/usr.bin/openssl/man/dsaparam.1
index 9979766..b37bf6d 100644
--- a/secure/usr.bin/openssl/man/dsaparam.1
+++ b/secure/usr.bin/openssl/man/dsaparam.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "DSAPARAM 1"
-.TH DSAPARAM 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH DSAPARAM 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/ec.1 b/secure/usr.bin/openssl/man/ec.1
index 66ee41e..56c0b7a 100644
--- a/secure/usr.bin/openssl/man/ec.1
+++ b/secure/usr.bin/openssl/man/ec.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EC 1"
-.TH EC 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH EC 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/ecparam.1 b/secure/usr.bin/openssl/man/ecparam.1
index ec79e7a..eb5332d 100644
--- a/secure/usr.bin/openssl/man/ecparam.1
+++ b/secure/usr.bin/openssl/man/ecparam.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ECPARAM 1"
-.TH ECPARAM 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ECPARAM 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/enc.1 b/secure/usr.bin/openssl/man/enc.1
index f5e9c20..8330813 100644
--- a/secure/usr.bin/openssl/man/enc.1
+++ b/secure/usr.bin/openssl/man/enc.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ENC 1"
-.TH ENC 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ENC 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/errstr.1 b/secure/usr.bin/openssl/man/errstr.1
index d579aa0..b498d2f 100644
--- a/secure/usr.bin/openssl/man/errstr.1
+++ b/secure/usr.bin/openssl/man/errstr.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "ERRSTR 1"
-.TH ERRSTR 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH ERRSTR 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/gendsa.1 b/secure/usr.bin/openssl/man/gendsa.1
index 1a584a7..e271817 100644
--- a/secure/usr.bin/openssl/man/gendsa.1
+++ b/secure/usr.bin/openssl/man/gendsa.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "GENDSA 1"
-.TH GENDSA 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH GENDSA 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/genrsa.1 b/secure/usr.bin/openssl/man/genrsa.1
index 9b28efa..56d5dec 100644
--- a/secure/usr.bin/openssl/man/genrsa.1
+++ b/secure/usr.bin/openssl/man/genrsa.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "GENRSA 1"
-.TH GENRSA 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH GENRSA 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/nseq.1 b/secure/usr.bin/openssl/man/nseq.1
index 8e74ba1..e212c0c 100644
--- a/secure/usr.bin/openssl/man/nseq.1
+++ b/secure/usr.bin/openssl/man/nseq.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "NSEQ 1"
-.TH NSEQ 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH NSEQ 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/ocsp.1 b/secure/usr.bin/openssl/man/ocsp.1
index 8080acf..be1011b 100644
--- a/secure/usr.bin/openssl/man/ocsp.1
+++ b/secure/usr.bin/openssl/man/ocsp.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "OCSP 1"
-.TH OCSP 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH OCSP 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/openssl.1 b/secure/usr.bin/openssl/man/openssl.1
index 0cf9d61..8f6a7c3 100644
--- a/secure/usr.bin/openssl/man/openssl.1
+++ b/secure/usr.bin/openssl/man/openssl.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "OPENSSL 1"
-.TH OPENSSL 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH OPENSSL 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/passwd.1 b/secure/usr.bin/openssl/man/passwd.1
index 405c605..e88cebe 100644
--- a/secure/usr.bin/openssl/man/passwd.1
+++ b/secure/usr.bin/openssl/man/passwd.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PASSWD 1"
-.TH PASSWD 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH PASSWD 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/pkcs12.1 b/secure/usr.bin/openssl/man/pkcs12.1
index 9eeb47c..805d58c 100644
--- a/secure/usr.bin/openssl/man/pkcs12.1
+++ b/secure/usr.bin/openssl/man/pkcs12.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS12 1"
-.TH PKCS12 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH PKCS12 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/pkcs7.1 b/secure/usr.bin/openssl/man/pkcs7.1
index 40bf064..1f2619a 100644
--- a/secure/usr.bin/openssl/man/pkcs7.1
+++ b/secure/usr.bin/openssl/man/pkcs7.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS7 1"
-.TH PKCS7 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH PKCS7 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/pkcs8.1 b/secure/usr.bin/openssl/man/pkcs8.1
index 4cc0a68..36535de 100644
--- a/secure/usr.bin/openssl/man/pkcs8.1
+++ b/secure/usr.bin/openssl/man/pkcs8.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "PKCS8 1"
-.TH PKCS8 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH PKCS8 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/rand.1 b/secure/usr.bin/openssl/man/rand.1
index 115a453..9e501d0 100644
--- a/secure/usr.bin/openssl/man/rand.1
+++ b/secure/usr.bin/openssl/man/rand.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RAND 1"
-.TH RAND 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RAND 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/req.1 b/secure/usr.bin/openssl/man/req.1
index 8f5dd2b..8267f35 100644
--- a/secure/usr.bin/openssl/man/req.1
+++ b/secure/usr.bin/openssl/man/req.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "REQ 1"
-.TH REQ 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH REQ 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/rsa.1 b/secure/usr.bin/openssl/man/rsa.1
index b504453..60b4dc8 100644
--- a/secure/usr.bin/openssl/man/rsa.1
+++ b/secure/usr.bin/openssl/man/rsa.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSA 1"
-.TH RSA 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSA 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/rsautl.1 b/secure/usr.bin/openssl/man/rsautl.1
index a2ad8e6..be70710 100644
--- a/secure/usr.bin/openssl/man/rsautl.1
+++ b/secure/usr.bin/openssl/man/rsautl.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "RSAUTL 1"
-.TH RSAUTL 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH RSAUTL 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/s_client.1 b/secure/usr.bin/openssl/man/s_client.1
index 931189f..8605365 100644
--- a/secure/usr.bin/openssl/man/s_client.1
+++ b/secure/usr.bin/openssl/man/s_client.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "S_CLIENT 1"
-.TH S_CLIENT 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH S_CLIENT 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/s_server.1 b/secure/usr.bin/openssl/man/s_server.1
index e51e6f4..0e9eb14 100644
--- a/secure/usr.bin/openssl/man/s_server.1
+++ b/secure/usr.bin/openssl/man/s_server.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "S_SERVER 1"
-.TH S_SERVER 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH S_SERVER 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/s_time.1 b/secure/usr.bin/openssl/man/s_time.1
index e769409..3838925 100644
--- a/secure/usr.bin/openssl/man/s_time.1
+++ b/secure/usr.bin/openssl/man/s_time.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "S_TIME 1"
-.TH S_TIME 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH S_TIME 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/sess_id.1 b/secure/usr.bin/openssl/man/sess_id.1
index 3d59b8c..8ab621b 100644
--- a/secure/usr.bin/openssl/man/sess_id.1
+++ b/secure/usr.bin/openssl/man/sess_id.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SESS_ID 1"
-.TH SESS_ID 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SESS_ID 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/smime.1 b/secure/usr.bin/openssl/man/smime.1
index e6cab4c..1abe463 100644
--- a/secure/usr.bin/openssl/man/smime.1
+++ b/secure/usr.bin/openssl/man/smime.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SMIME 1"
-.TH SMIME 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SMIME 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/speed.1 b/secure/usr.bin/openssl/man/speed.1
index c6849b8..99dc0cd 100644
--- a/secure/usr.bin/openssl/man/speed.1
+++ b/secure/usr.bin/openssl/man/speed.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SPEED 1"
-.TH SPEED 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SPEED 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/spkac.1 b/secure/usr.bin/openssl/man/spkac.1
index d0760c1..28ebfa5 100644
--- a/secure/usr.bin/openssl/man/spkac.1
+++ b/secure/usr.bin/openssl/man/spkac.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "SPKAC 1"
-.TH SPKAC 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH SPKAC 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/verify.1 b/secure/usr.bin/openssl/man/verify.1
index 34338d2..9e81860 100644
--- a/secure/usr.bin/openssl/man/verify.1
+++ b/secure/usr.bin/openssl/man/verify.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "VERIFY 1"
-.TH VERIFY 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH VERIFY 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/version.1 b/secure/usr.bin/openssl/man/version.1
index 529043d..0ea1798 100644
--- a/secure/usr.bin/openssl/man/version.1
+++ b/secure/usr.bin/openssl/man/version.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "VERSION 1"
-.TH VERSION 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH VERSION 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/x509.1 b/secure/usr.bin/openssl/man/x509.1
index 34ea002..e3708b2 100644
--- a/secure/usr.bin/openssl/man/x509.1
+++ b/secure/usr.bin/openssl/man/x509.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "X509 1"
-.TH X509 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH X509 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/secure/usr.bin/openssl/man/x509v3_config.1 b/secure/usr.bin/openssl/man/x509v3_config.1
index ae7e180..e9935c1 100644
--- a/secure/usr.bin/openssl/man/x509v3_config.1
+++ b/secure/usr.bin/openssl/man/x509v3_config.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "X509V3_CONFIG 1"
-.TH X509V3_CONFIG 1 "2010-11-16" "0.9.8p" "OpenSSL"
+.TH X509V3_CONFIG 1 "2010-12-02" "0.9.8q" "OpenSSL"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff --git a/share/doc/psd/12.make/Makefile b/share/doc/psd/12.make/Makefile
index fdc38a7..b365683 100644
--- a/share/doc/psd/12.make/Makefile
+++ b/share/doc/psd/12.make/Makefile
@@ -4,6 +4,5 @@
VOLUME= psd/12.make
SRCS= stubs tutorial.ms
MACROS= -ms
-SRCDIR= ${.CURDIR}/../../../../usr.bin/make/PSD.doc
.include <bsd.doc.mk>
diff --git a/usr.bin/make/PSD.doc/stubs b/share/doc/psd/12.make/stubs
index 39d8def..39d8def 100644
--- a/usr.bin/make/PSD.doc/stubs
+++ b/share/doc/psd/12.make/stubs
diff --git a/usr.bin/make/PSD.doc/tutorial.ms b/share/doc/psd/12.make/tutorial.ms
index 320d5df..320d5df 100644
--- a/usr.bin/make/PSD.doc/tutorial.ms
+++ b/share/doc/psd/12.make/tutorial.ms
diff --git a/share/doc/psd/18.gprof/Makefile b/share/doc/psd/18.gprof/Makefile
index 1097072..2a5bed1 100644
--- a/share/doc/psd/18.gprof/Makefile
+++ b/share/doc/psd/18.gprof/Makefile
@@ -10,6 +10,5 @@ USE_SOELIM=
USE_PIC=
USE_TBL=
USE_EQN=
-SRCDIR= ${.CURDIR}/../../../../usr.bin/gprof/PSD.doc
.include <bsd.doc.mk>
diff --git a/usr.bin/gprof/PSD.doc/abstract.me b/share/doc/psd/18.gprof/abstract.me
index 28e8066..28e8066 100644
--- a/usr.bin/gprof/PSD.doc/abstract.me
+++ b/share/doc/psd/18.gprof/abstract.me
diff --git a/usr.bin/gprof/PSD.doc/gathering.me b/share/doc/psd/18.gprof/gathering.me
index 17130c3..17130c3 100644
--- a/usr.bin/gprof/PSD.doc/gathering.me
+++ b/share/doc/psd/18.gprof/gathering.me
diff --git a/usr.bin/gprof/PSD.doc/header.me b/share/doc/psd/18.gprof/header.me
index aef606d..aef606d 100644
--- a/usr.bin/gprof/PSD.doc/header.me
+++ b/share/doc/psd/18.gprof/header.me
diff --git a/usr.bin/gprof/PSD.doc/intro.me b/share/doc/psd/18.gprof/intro.me
index 3a872b2..3a872b2 100644
--- a/usr.bin/gprof/PSD.doc/intro.me
+++ b/share/doc/psd/18.gprof/intro.me
diff --git a/usr.bin/gprof/PSD.doc/postp.me b/share/doc/psd/18.gprof/postp.me
index d71fefb..d71fefb 100644
--- a/usr.bin/gprof/PSD.doc/postp.me
+++ b/share/doc/psd/18.gprof/postp.me
diff --git a/usr.bin/gprof/PSD.doc/postp1.pic b/share/doc/psd/18.gprof/postp1.pic
index 1446092..1446092 100644
--- a/usr.bin/gprof/PSD.doc/postp1.pic
+++ b/share/doc/psd/18.gprof/postp1.pic
diff --git a/usr.bin/gprof/PSD.doc/postp2.pic b/share/doc/psd/18.gprof/postp2.pic
index 3b31736..3b31736 100644
--- a/usr.bin/gprof/PSD.doc/postp2.pic
+++ b/share/doc/psd/18.gprof/postp2.pic
diff --git a/usr.bin/gprof/PSD.doc/postp3.pic b/share/doc/psd/18.gprof/postp3.pic
index 65eb2a7..65eb2a7 100644
--- a/usr.bin/gprof/PSD.doc/postp3.pic
+++ b/share/doc/psd/18.gprof/postp3.pic
diff --git a/usr.bin/gprof/PSD.doc/pres1.pic b/share/doc/psd/18.gprof/pres1.pic
index 0c311a1..0c311a1 100644
--- a/usr.bin/gprof/PSD.doc/pres1.pic
+++ b/share/doc/psd/18.gprof/pres1.pic
diff --git a/usr.bin/gprof/PSD.doc/pres2.pic b/share/doc/psd/18.gprof/pres2.pic
index c3a4ea0..c3a4ea0 100644
--- a/usr.bin/gprof/PSD.doc/pres2.pic
+++ b/share/doc/psd/18.gprof/pres2.pic
diff --git a/usr.bin/gprof/PSD.doc/present.me b/share/doc/psd/18.gprof/present.me
index 1dd7f62..1dd7f62 100644
--- a/usr.bin/gprof/PSD.doc/present.me
+++ b/share/doc/psd/18.gprof/present.me
diff --git a/usr.bin/gprof/PSD.doc/profiling.me b/share/doc/psd/18.gprof/profiling.me
index 227aedf..227aedf 100644
--- a/usr.bin/gprof/PSD.doc/profiling.me
+++ b/share/doc/psd/18.gprof/profiling.me
diff --git a/usr.bin/gprof/PSD.doc/refs.me b/share/doc/psd/18.gprof/refs.me
index 580d080..580d080 100644
--- a/usr.bin/gprof/PSD.doc/refs.me
+++ b/share/doc/psd/18.gprof/refs.me
diff --git a/share/doc/psd/22.rpcgen/Makefile b/share/doc/psd/22.rpcgen/Makefile
index 4c38add..04d4e9e 100644
--- a/share/doc/psd/22.rpcgen/Makefile
+++ b/share/doc/psd/22.rpcgen/Makefile
@@ -4,6 +4,5 @@ VOLUME= psd/22.rpcgen
SRCS= stubs rpcgen.ms
MACROS= -ms
USE_TBL=
-SRCDIR= ${.CURDIR}/../../../../lib/libc/rpc/PSD.doc
.include <bsd.doc.mk>
diff --git a/lib/libc/rpc/PSD.doc/rpcgen.ms b/share/doc/psd/22.rpcgen/rpcgen.ms
index e663e7f..e663e7f 100644
--- a/lib/libc/rpc/PSD.doc/rpcgen.ms
+++ b/share/doc/psd/22.rpcgen/rpcgen.ms
diff --git a/lib/libc/rpc/PSD.doc/stubs b/share/doc/psd/22.rpcgen/stubs
index 78b0a2c..78b0a2c 100644
--- a/lib/libc/rpc/PSD.doc/stubs
+++ b/share/doc/psd/22.rpcgen/stubs
diff --git a/share/doc/psd/23.rpc/Makefile b/share/doc/psd/23.rpc/Makefile
index 77849b6..930c677 100644
--- a/share/doc/psd/23.rpc/Makefile
+++ b/share/doc/psd/23.rpc/Makefile
@@ -5,6 +5,5 @@ SRCS= stubs rpc.prog.ms
MACROS= -ms
USE_TBL=
USE_PIC=
-SRCDIR= ${.CURDIR}/../../../../lib/libc/rpc/PSD.doc
.include <bsd.doc.mk>
diff --git a/lib/libc/rpc/PSD.doc/rpc.prog.ms b/share/doc/psd/23.rpc/rpc.prog.ms
index 8b79130..8b79130 100644
--- a/lib/libc/rpc/PSD.doc/rpc.prog.ms
+++ b/share/doc/psd/23.rpc/rpc.prog.ms
diff --git a/share/doc/psd/23.rpc/stubs b/share/doc/psd/23.rpc/stubs
new file mode 100644
index 0000000..78b0a2c
--- /dev/null
+++ b/share/doc/psd/23.rpc/stubs
@@ -0,0 +1,3 @@
+.\" $FreeBSD$
+.\"
+.if t .ftr L CR
diff --git a/share/doc/psd/24.xdr/Makefile b/share/doc/psd/24.xdr/Makefile
index 878dca1..8e30711 100644
--- a/share/doc/psd/24.xdr/Makefile
+++ b/share/doc/psd/24.xdr/Makefile
@@ -4,6 +4,5 @@ VOLUME= psd/24.xdr
SRCS= stubs xdr.nts.ms
MACROS= -ms
USE_EQN=
-SRCDIR= ${.CURDIR}/../../../../lib/libc/rpc/PSD.doc
.include <bsd.doc.mk>
diff --git a/share/doc/psd/24.xdr/stubs b/share/doc/psd/24.xdr/stubs
new file mode 100644
index 0000000..78b0a2c
--- /dev/null
+++ b/share/doc/psd/24.xdr/stubs
@@ -0,0 +1,3 @@
+.\" $FreeBSD$
+.\"
+.if t .ftr L CR
diff --git a/lib/libc/rpc/PSD.doc/xdr.nts.ms b/share/doc/psd/24.xdr/xdr.nts.ms
index 260c7f3..260c7f3 100644
--- a/lib/libc/rpc/PSD.doc/xdr.nts.ms
+++ b/share/doc/psd/24.xdr/xdr.nts.ms
diff --git a/share/doc/psd/25.xdrrfc/Makefile b/share/doc/psd/25.xdrrfc/Makefile
index 105135e..7045d45 100644
--- a/share/doc/psd/25.xdrrfc/Makefile
+++ b/share/doc/psd/25.xdrrfc/Makefile
@@ -4,6 +4,5 @@ VOLUME= psd/25.xdrrfc
SRCS= stubs xdr.rfc.ms
MACROS= -ms
USE_TBL=
-SRCDIR= ${.CURDIR}/../../../../lib/libc/rpc/PSD.doc
.include <bsd.doc.mk>
diff --git a/share/doc/psd/25.xdrrfc/stubs b/share/doc/psd/25.xdrrfc/stubs
new file mode 100644
index 0000000..78b0a2c
--- /dev/null
+++ b/share/doc/psd/25.xdrrfc/stubs
@@ -0,0 +1,3 @@
+.\" $FreeBSD$
+.\"
+.if t .ftr L CR
diff --git a/lib/libc/rpc/PSD.doc/xdr.rfc.ms b/share/doc/psd/25.xdrrfc/xdr.rfc.ms
index 480a339..480a339 100644
--- a/lib/libc/rpc/PSD.doc/xdr.rfc.ms
+++ b/share/doc/psd/25.xdrrfc/xdr.rfc.ms
diff --git a/share/doc/psd/26.rpcrfc/Makefile b/share/doc/psd/26.rpcrfc/Makefile
index 79214f1..3ffdc27 100644
--- a/share/doc/psd/26.rpcrfc/Makefile
+++ b/share/doc/psd/26.rpcrfc/Makefile
@@ -4,6 +4,5 @@ VOLUME= psd/26.rpcrfc
SRCS= stubs rpc.rfc.ms
MACROS= -ms
USE_TBL=
-SRCDIR= ${.CURDIR}/../../../../lib/libc/rpc/PSD.doc
.include <bsd.doc.mk>
diff --git a/lib/libc/rpc/PSD.doc/rpc.rfc.ms b/share/doc/psd/26.rpcrfc/rpc.rfc.ms
index 9a948bd..9a948bd 100644
--- a/lib/libc/rpc/PSD.doc/rpc.rfc.ms
+++ b/share/doc/psd/26.rpcrfc/rpc.rfc.ms
diff --git a/share/doc/psd/26.rpcrfc/stubs b/share/doc/psd/26.rpcrfc/stubs
new file mode 100644
index 0000000..78b0a2c
--- /dev/null
+++ b/share/doc/psd/26.rpcrfc/stubs
@@ -0,0 +1,3 @@
+.\" $FreeBSD$
+.\"
+.if t .ftr L CR
diff --git a/share/doc/psd/27.nfsrpc/Makefile b/share/doc/psd/27.nfsrpc/Makefile
index 5904787..c9d4f23 100644
--- a/share/doc/psd/27.nfsrpc/Makefile
+++ b/share/doc/psd/27.nfsrpc/Makefile
@@ -4,6 +4,5 @@ VOLUME= psd/27.nfsrfc
SRCS= stubs nfs.rfc.ms
MACROS= -ms
USE_TBL=
-SRCDIR= ${.CURDIR}/../../../../lib/libc/rpc/PSD.doc
.include <bsd.doc.mk>
diff --git a/lib/libc/rpc/PSD.doc/nfs.rfc.ms b/share/doc/psd/27.nfsrpc/nfs.rfc.ms
index 13d7619..13d7619 100644
--- a/lib/libc/rpc/PSD.doc/nfs.rfc.ms
+++ b/share/doc/psd/27.nfsrpc/nfs.rfc.ms
diff --git a/share/doc/psd/27.nfsrpc/stubs b/share/doc/psd/27.nfsrpc/stubs
new file mode 100644
index 0000000..78b0a2c
--- /dev/null
+++ b/share/doc/psd/27.nfsrpc/stubs
@@ -0,0 +1,3 @@
+.\" $FreeBSD$
+.\"
+.if t .ftr L CR
diff --git a/usr.sbin/config/SMM.doc/0.t b/share/doc/smm/02.config/0.t
index ae5bf77..ae5bf77 100644
--- a/usr.sbin/config/SMM.doc/0.t
+++ b/share/doc/smm/02.config/0.t
diff --git a/usr.sbin/config/SMM.doc/1.t b/share/doc/smm/02.config/1.t
index 453041b..453041b 100644
--- a/usr.sbin/config/SMM.doc/1.t
+++ b/share/doc/smm/02.config/1.t
diff --git a/usr.sbin/config/SMM.doc/2.t b/share/doc/smm/02.config/2.t
index 34e6b63..34e6b63 100644
--- a/usr.sbin/config/SMM.doc/2.t
+++ b/share/doc/smm/02.config/2.t
diff --git a/usr.sbin/config/SMM.doc/3.t b/share/doc/smm/02.config/3.t
index e0b6234..e0b6234 100644
--- a/usr.sbin/config/SMM.doc/3.t
+++ b/share/doc/smm/02.config/3.t
diff --git a/usr.sbin/config/SMM.doc/4.t b/share/doc/smm/02.config/4.t
index 7498185..7498185 100644
--- a/usr.sbin/config/SMM.doc/4.t
+++ b/share/doc/smm/02.config/4.t
diff --git a/usr.sbin/config/SMM.doc/5.t b/share/doc/smm/02.config/5.t
index 81f2a52..81f2a52 100644
--- a/usr.sbin/config/SMM.doc/5.t
+++ b/share/doc/smm/02.config/5.t
diff --git a/usr.sbin/config/SMM.doc/6.t b/share/doc/smm/02.config/6.t
index 49f6e91..49f6e91 100644
--- a/usr.sbin/config/SMM.doc/6.t
+++ b/share/doc/smm/02.config/6.t
diff --git a/share/doc/smm/02.config/Makefile b/share/doc/smm/02.config/Makefile
index 26ed70a..716eeda 100644
--- a/share/doc/smm/02.config/Makefile
+++ b/share/doc/smm/02.config/Makefile
@@ -5,6 +5,5 @@ VOLUME= smm/02.config
SRCS= 0.t 1.t 2.t 3.t 4.t 5.t 6.t a.t b.t c.t d.t e.t
MACROS= -ms
USE_TBL=
-SRCDIR= ${.CURDIR}/../../../../usr.sbin/config/SMM.doc
.include <bsd.doc.mk>
diff --git a/usr.sbin/config/SMM.doc/a.t b/share/doc/smm/02.config/a.t
index dfcb954..dfcb954 100644
--- a/usr.sbin/config/SMM.doc/a.t
+++ b/share/doc/smm/02.config/a.t
diff --git a/usr.sbin/config/SMM.doc/b.t b/share/doc/smm/02.config/b.t
index 901a009..901a009 100644
--- a/usr.sbin/config/SMM.doc/b.t
+++ b/share/doc/smm/02.config/b.t
diff --git a/usr.sbin/config/SMM.doc/c.t b/share/doc/smm/02.config/c.t
index 67b63ec..67b63ec 100644
--- a/usr.sbin/config/SMM.doc/c.t
+++ b/share/doc/smm/02.config/c.t
diff --git a/usr.sbin/config/SMM.doc/d.t b/share/doc/smm/02.config/d.t
index db9ab80..db9ab80 100644
--- a/usr.sbin/config/SMM.doc/d.t
+++ b/share/doc/smm/02.config/d.t
diff --git a/usr.sbin/config/SMM.doc/e.t b/share/doc/smm/02.config/e.t
index 0a9505b..0a9505b 100644
--- a/usr.sbin/config/SMM.doc/e.t
+++ b/share/doc/smm/02.config/e.t
diff --git a/usr.sbin/config/SMM.doc/spell.ok b/share/doc/smm/02.config/spell.ok
index dfc5df1..dfc5df1 100644
--- a/usr.sbin/config/SMM.doc/spell.ok
+++ b/share/doc/smm/02.config/spell.ok
diff --git a/sbin/fsck_ffs/SMM.doc/0.t b/share/doc/smm/03.fsck/0.t
index 5fe189d..5fe189d 100644
--- a/sbin/fsck_ffs/SMM.doc/0.t
+++ b/share/doc/smm/03.fsck/0.t
diff --git a/sbin/fsck_ffs/SMM.doc/1.t b/share/doc/smm/03.fsck/1.t
index 3098b49..3098b49 100644
--- a/sbin/fsck_ffs/SMM.doc/1.t
+++ b/share/doc/smm/03.fsck/1.t
diff --git a/sbin/fsck_ffs/SMM.doc/2.t b/share/doc/smm/03.fsck/2.t
index b294a6a..b294a6a 100644
--- a/sbin/fsck_ffs/SMM.doc/2.t
+++ b/share/doc/smm/03.fsck/2.t
diff --git a/sbin/fsck_ffs/SMM.doc/3.t b/share/doc/smm/03.fsck/3.t
index 522a222..522a222 100644
--- a/sbin/fsck_ffs/SMM.doc/3.t
+++ b/share/doc/smm/03.fsck/3.t
diff --git a/sbin/fsck_ffs/SMM.doc/4.t b/share/doc/smm/03.fsck/4.t
index 353fab3..353fab3 100644
--- a/sbin/fsck_ffs/SMM.doc/4.t
+++ b/share/doc/smm/03.fsck/4.t
diff --git a/share/doc/smm/03.fsck/Makefile b/share/doc/smm/03.fsck/Makefile
index fbdc009..88d1ec3 100644
--- a/share/doc/smm/03.fsck/Makefile
+++ b/share/doc/smm/03.fsck/Makefile
@@ -4,6 +4,5 @@
VOLUME= smm/03.fsck
SRCS= 0.t 1.t 2.t 3.t 4.t
MACROS= -ms
-SRCDIR= ${.CURDIR}/../../../../sbin/fsck_ffs/SMM.doc
.include <bsd.doc.mk>
diff --git a/usr.sbin/lpr/SMM.doc/0.t b/share/doc/smm/07.lpr/0.t
index 65ecd4e..65ecd4e 100644
--- a/usr.sbin/lpr/SMM.doc/0.t
+++ b/share/doc/smm/07.lpr/0.t
diff --git a/usr.sbin/lpr/SMM.doc/1.t b/share/doc/smm/07.lpr/1.t
index 1d34e9e..1d34e9e 100644
--- a/usr.sbin/lpr/SMM.doc/1.t
+++ b/share/doc/smm/07.lpr/1.t
diff --git a/usr.sbin/lpr/SMM.doc/2.t b/share/doc/smm/07.lpr/2.t
index 9da2ae2..9da2ae2 100644
--- a/usr.sbin/lpr/SMM.doc/2.t
+++ b/share/doc/smm/07.lpr/2.t
diff --git a/usr.sbin/lpr/SMM.doc/3.t b/share/doc/smm/07.lpr/3.t
index 8c950a9..8c950a9 100644
--- a/usr.sbin/lpr/SMM.doc/3.t
+++ b/share/doc/smm/07.lpr/3.t
diff --git a/usr.sbin/lpr/SMM.doc/4.t b/share/doc/smm/07.lpr/4.t
index 8800bc0..8800bc0 100644
--- a/usr.sbin/lpr/SMM.doc/4.t
+++ b/share/doc/smm/07.lpr/4.t
diff --git a/usr.sbin/lpr/SMM.doc/5.t b/share/doc/smm/07.lpr/5.t
index 137a342..137a342 100644
--- a/usr.sbin/lpr/SMM.doc/5.t
+++ b/share/doc/smm/07.lpr/5.t
diff --git a/usr.sbin/lpr/SMM.doc/6.t b/share/doc/smm/07.lpr/6.t
index 7087790..7087790 100644
--- a/usr.sbin/lpr/SMM.doc/6.t
+++ b/share/doc/smm/07.lpr/6.t
diff --git a/usr.sbin/lpr/SMM.doc/7.t b/share/doc/smm/07.lpr/7.t
index a6f6bea..a6f6bea 100644
--- a/usr.sbin/lpr/SMM.doc/7.t
+++ b/share/doc/smm/07.lpr/7.t
diff --git a/usr.sbin/lpr/SMM.doc/Makefile b/share/doc/smm/07.lpr/Makefile
index d80c8ce..20455e1 100644
--- a/usr.sbin/lpr/SMM.doc/Makefile
+++ b/share/doc/smm/07.lpr/Makefile
@@ -1,12 +1,9 @@
# From: @(#)Makefile 8.1 (Berkeley) 6/8/93
# $FreeBSD$
-BINDIR= /usr/share/doc
VOLUME= smm/07.lpd
SRCS= 0.t 1.t 2.t 3.t 4.t 5.t 6.t 7.t
MACROS= -ms
-
USE_TBL=
-SRCDIR= ${.CURDIR}
.include <bsd.doc.mk>
diff --git a/usr.sbin/lpr/SMM.doc/spell.ok b/share/doc/smm/07.lpr/spell.ok
index bf31319..bf31319 100644
--- a/usr.sbin/lpr/SMM.doc/spell.ok
+++ b/share/doc/smm/07.lpr/spell.ok
diff --git a/share/doc/smm/11.timedop/Makefile b/share/doc/smm/11.timedop/Makefile
index ad09e78..aec9918 100644
--- a/share/doc/smm/11.timedop/Makefile
+++ b/share/doc/smm/11.timedop/Makefile
@@ -4,6 +4,5 @@
VOLUME= smm/11.timedop
SRCS= timed.ms
MACROS= -ms
-SRCDIR= ${.CURDIR}/../../../../usr.sbin/timed/SMM.doc/timedop
.include <bsd.doc.mk>
diff --git a/usr.sbin/timed/SMM.doc/timedop/timed.ms b/share/doc/smm/11.timedop/timed.ms
index feea0b5..feea0b5 100644
--- a/usr.sbin/timed/SMM.doc/timedop/timed.ms
+++ b/share/doc/smm/11.timedop/timed.ms
diff --git a/share/doc/smm/12.timed/Makefile b/share/doc/smm/12.timed/Makefile
index 1d9ed5c..f844568 100644
--- a/share/doc/smm/12.timed/Makefile
+++ b/share/doc/smm/12.timed/Makefile
@@ -7,6 +7,5 @@ EXTRA= date loop time unused
MACROS= -ms
USE_SOELIM=
USE_TBL=
-SRCDIR= ${.CURDIR}/../../../../usr.sbin/timed/SMM.doc/timed
.include <bsd.doc.mk>
diff --git a/usr.sbin/timed/SMM.doc/timed/date b/share/doc/smm/12.timed/date
index e4e4d58..e4e4d58 100644
--- a/usr.sbin/timed/SMM.doc/timed/date
+++ b/share/doc/smm/12.timed/date
diff --git a/usr.sbin/timed/SMM.doc/timed/loop b/share/doc/smm/12.timed/loop
index 11ccb4d..11ccb4d 100644
--- a/usr.sbin/timed/SMM.doc/timed/loop
+++ b/share/doc/smm/12.timed/loop
diff --git a/usr.sbin/timed/SMM.doc/timed/spell.ok b/share/doc/smm/12.timed/spell.ok
index 8ecfe15..8ecfe15 100644
--- a/usr.sbin/timed/SMM.doc/timed/spell.ok
+++ b/share/doc/smm/12.timed/spell.ok
diff --git a/usr.sbin/timed/SMM.doc/timed/time b/share/doc/smm/12.timed/time
index 619d171..619d171 100644
--- a/usr.sbin/timed/SMM.doc/timed/time
+++ b/share/doc/smm/12.timed/time
diff --git a/usr.sbin/timed/SMM.doc/timed/timed.ms b/share/doc/smm/12.timed/timed.ms
index 412399a..412399a 100644
--- a/usr.sbin/timed/SMM.doc/timed/timed.ms
+++ b/share/doc/smm/12.timed/timed.ms
diff --git a/usr.sbin/timed/SMM.doc/timed/unused b/share/doc/smm/12.timed/unused
index adadfc3..adadfc3 100644
--- a/usr.sbin/timed/SMM.doc/timed/unused
+++ b/share/doc/smm/12.timed/unused
diff --git a/share/doc/usd/04.csh/Makefile b/share/doc/usd/04.csh/Makefile
index d22a7b9..5606b8f 100644
--- a/share/doc/usd/04.csh/Makefile
+++ b/share/doc/usd/04.csh/Makefile
@@ -5,6 +5,5 @@ VOLUME= usd/04.csh
SRCS= tabs csh.1 csh.2 csh.3 csh.4 csh.a csh.g
MACROS= -ms
USE_SOELIM=
-SRCDIR= ${.CURDIR}/../../../../bin/csh/USD.doc
.include <bsd.doc.mk>
diff --git a/bin/csh/USD.doc/csh.1 b/share/doc/usd/04.csh/csh.1
index 915cb23..915cb23 100644
--- a/bin/csh/USD.doc/csh.1
+++ b/share/doc/usd/04.csh/csh.1
diff --git a/bin/csh/USD.doc/csh.2 b/share/doc/usd/04.csh/csh.2
index 5fbf43c..5fbf43c 100644
--- a/bin/csh/USD.doc/csh.2
+++ b/share/doc/usd/04.csh/csh.2
diff --git a/bin/csh/USD.doc/csh.3 b/share/doc/usd/04.csh/csh.3
index 76ee1eb..76ee1eb 100644
--- a/bin/csh/USD.doc/csh.3
+++ b/share/doc/usd/04.csh/csh.3
diff --git a/bin/csh/USD.doc/csh.4 b/share/doc/usd/04.csh/csh.4
index 7ef24dc..7ef24dc 100644
--- a/bin/csh/USD.doc/csh.4
+++ b/share/doc/usd/04.csh/csh.4
diff --git a/bin/csh/USD.doc/csh.a b/share/doc/usd/04.csh/csh.a
index 22c8f76..22c8f76 100644
--- a/bin/csh/USD.doc/csh.a
+++ b/share/doc/usd/04.csh/csh.a
diff --git a/bin/csh/USD.doc/csh.g b/share/doc/usd/04.csh/csh.g
index ba1b161..ba1b161 100644
--- a/bin/csh/USD.doc/csh.g
+++ b/share/doc/usd/04.csh/csh.g
diff --git a/bin/csh/USD.doc/tabs b/share/doc/usd/04.csh/tabs
index 196d437..196d437 100644
--- a/bin/csh/USD.doc/tabs
+++ b/share/doc/usd/04.csh/tabs
diff --git a/share/doc/usd/05.dc/Makefile b/share/doc/usd/05.dc/Makefile
index 2b01e0c..fd1cffc 100644
--- a/share/doc/usd/05.dc/Makefile
+++ b/share/doc/usd/05.dc/Makefile
@@ -4,6 +4,5 @@
VOLUME= usd/05.dc
SRCS= dc
MACROS= -ms
-SRCDIR= ${.CURDIR}/../../../../usr.bin/dc/USD.doc
.include <bsd.doc.mk>
diff --git a/usr.bin/dc/USD.doc/dc b/share/doc/usd/05.dc/dc
index 4caa0f4..4caa0f4 100644
--- a/usr.bin/dc/USD.doc/dc
+++ b/share/doc/usd/05.dc/dc
diff --git a/share/doc/usd/06.bc/Makefile b/share/doc/usd/06.bc/Makefile
index 12dfedd..b4f340c 100644
--- a/share/doc/usd/06.bc/Makefile
+++ b/share/doc/usd/06.bc/Makefile
@@ -4,6 +4,5 @@
VOLUME= usd/06.bc
SRCS= bc
MACROS= -ms
-SRCDIR= ${.CURDIR}/../../../../usr.bin/bc/USD.doc
.include <bsd.doc.mk>
diff --git a/usr.bin/bc/USD.doc/bc b/share/doc/usd/06.bc/bc
index c4e68c6..c4e68c6 100644
--- a/usr.bin/bc/USD.doc/bc
+++ b/share/doc/usd/06.bc/bc
diff --git a/share/doc/usd/07.mail/Makefile b/share/doc/usd/07.mail/Makefile
index d5a6d3c..790aa96 100644
--- a/share/doc/usd/07.mail/Makefile
+++ b/share/doc/usd/07.mail/Makefile
@@ -6,6 +6,5 @@ SRCS= mail0.nr mail1.nr mail2.nr mail3.nr mail4.nr mail5.nr mail6.nr \
mail7.nr mail8.nr mail9.nr maila.nr
MACROS= -me
USE_TBL=
-SRCDIR= ${.CURDIR}/../../../../usr.bin/mail/USD.doc
.include <bsd.doc.mk>
diff --git a/usr.bin/mail/USD.doc/mail0.nr b/share/doc/usd/07.mail/mail0.nr
index e569a5f..e569a5f 100644
--- a/usr.bin/mail/USD.doc/mail0.nr
+++ b/share/doc/usd/07.mail/mail0.nr
diff --git a/usr.bin/mail/USD.doc/mail1.nr b/share/doc/usd/07.mail/mail1.nr
index 50e7883..50e7883 100644
--- a/usr.bin/mail/USD.doc/mail1.nr
+++ b/share/doc/usd/07.mail/mail1.nr
diff --git a/usr.bin/mail/USD.doc/mail2.nr b/share/doc/usd/07.mail/mail2.nr
index 0419859..0419859 100644
--- a/usr.bin/mail/USD.doc/mail2.nr
+++ b/share/doc/usd/07.mail/mail2.nr
diff --git a/usr.bin/mail/USD.doc/mail3.nr b/share/doc/usd/07.mail/mail3.nr
index 8b133ef..8b133ef 100644
--- a/usr.bin/mail/USD.doc/mail3.nr
+++ b/share/doc/usd/07.mail/mail3.nr
diff --git a/usr.bin/mail/USD.doc/mail4.nr b/share/doc/usd/07.mail/mail4.nr
index 1a1e046..1a1e046 100644
--- a/usr.bin/mail/USD.doc/mail4.nr
+++ b/share/doc/usd/07.mail/mail4.nr
diff --git a/usr.bin/mail/USD.doc/mail5.nr b/share/doc/usd/07.mail/mail5.nr
index 10e707c..10e707c 100644
--- a/usr.bin/mail/USD.doc/mail5.nr
+++ b/share/doc/usd/07.mail/mail5.nr
diff --git a/usr.bin/mail/USD.doc/mail6.nr b/share/doc/usd/07.mail/mail6.nr
index 0465a94..0465a94 100644
--- a/usr.bin/mail/USD.doc/mail6.nr
+++ b/share/doc/usd/07.mail/mail6.nr
diff --git a/usr.bin/mail/USD.doc/mail7.nr b/share/doc/usd/07.mail/mail7.nr
index 0b2590b..0b2590b 100644
--- a/usr.bin/mail/USD.doc/mail7.nr
+++ b/share/doc/usd/07.mail/mail7.nr
diff --git a/usr.bin/mail/USD.doc/mail8.nr b/share/doc/usd/07.mail/mail8.nr
index b09afbd..b09afbd 100644
--- a/usr.bin/mail/USD.doc/mail8.nr
+++ b/share/doc/usd/07.mail/mail8.nr
diff --git a/usr.bin/mail/USD.doc/mail9.nr b/share/doc/usd/07.mail/mail9.nr
index 271548e..271548e 100644
--- a/usr.bin/mail/USD.doc/mail9.nr
+++ b/share/doc/usd/07.mail/mail9.nr
diff --git a/usr.bin/mail/USD.doc/maila.nr b/share/doc/usd/07.mail/maila.nr
index 84b01fe..84b01fe 100644
--- a/usr.bin/mail/USD.doc/maila.nr
+++ b/share/doc/usd/07.mail/maila.nr
diff --git a/share/man/man3/fpgetround.3 b/share/man/man3/fpgetround.3
index 1e93c84..189e252 100644
--- a/share/man/man3/fpgetround.3
+++ b/share/man/man3/fpgetround.3
@@ -32,7 +32,7 @@
.\" @(#)fpgetround.3 1.0 (Berkeley) 9/23/93
.\" $FreeBSD$
.\"
-.Dd August 23, 1993
+.Dd December 3, 2010
.Dt FPGETROUND 3
.Os
.Sh NAME
@@ -164,6 +164,10 @@ and
.Fn fpsetprec
functions provide functionality unavailable on many platforms.
At present, they are implemented only on the i386 and amd64 platforms.
+Changing precision isn't a supported feature:
+it may be ineffective when code is compiled to take advantage of SSE,
+and many library functions and compiler optimizations depend upon the
+default precision for correct behavior.
.Sh SEE ALSO
.Xr fenv 3 ,
.Xr isnan 3
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index 990222f..ec86b43 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -1293,7 +1293,7 @@ the default address selection policy table set by
will be IPv4-preferred.
.Pp
This variable is deprecated. Use
-.Va ip6addtctl_policy
+.Va ip6addrctl_policy
instead.
.It Va ipv6_activate_all_interfaces
If the variable is
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index d757682..663466f 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -244,6 +244,7 @@ MAN= accept_filter.9 \
sysctl.9 \
sysctl_add_oid.9 \
sysctl_ctx_init.9 \
+ SYSINIT.9 \
taskqueue.9 \
thread_exit.9 \
time.9 \
@@ -1211,6 +1212,7 @@ MLINKS+=sysctl_ctx_init.9 sysctl_ctx_entry_add.9 \
sysctl_ctx_init.9 sysctl_ctx_entry_del.9 \
sysctl_ctx_init.9 sysctl_ctx_entry_find.9 \
sysctl_ctx_init.9 sysctl_ctx_free.9
+MLINKS+=SYSINIT.9 SYSUNINIT.9
MLINKS+=taskqueue.9 TASK_INIT.9 \
taskqueue.9 taskqueue_cancel.9 \
taskqueue.9 taskqueue_create.9 \
diff --git a/share/man/man9/SYSINIT.9 b/share/man/man9/SYSINIT.9
new file mode 100644
index 0000000..9140dd8
--- /dev/null
+++ b/share/man/man9/SYSINIT.9
@@ -0,0 +1,163 @@
+.\" Copyright (c) 2003 Hiten M. Pandya
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 1, 2010
+.Dt SYSINIT 9
+.Os
+.Sh NAME
+.Nm SYSINIT ,
+.Nm SYSUNINIT
+.Nd a framework for dynamic kernel initialization
+.Sh SYNOPSIS
+.In sys/param.h
+.In sys/kernel.h
+.Fn SYSINIT "uniquifier" "enum sysinit_sub_id subsystem" "enum sysinit_elem_order order" "sysinit_cfunc_t func" "const void *ident"
+.Fn SYSUNINIT "uniquifier" "enum sysinit_sub_id subsystem" "enum sysinit_elem_order order" "sysinit_cfunc_t func" "const void *ident"
+.Sh DESCRIPTION
+.Nm
+is a mechanism for scheduling the execution of initialization and teardown
+routines.
+This is similar to init and fini routines with the addition of explicit
+ordering metadata.
+It allows runtime ordering of subsystem initialization in the kernel as well
+as kernel modules (KLDs).
+.Pp
+The
+.Fn SYSINIT
+macro creates a
+.Vt struct sysinit
+and stores it in a startup linker set.
+The
+.Vt struct sysinit
+type as well as the subsystem identifier constants
+.Pq Dv SI_SUB_*
+and initialization ordering constants
+.Pq Dv SI_ORDER_*
+are defined in
+.In sys/kernel.h :
+.Bd -literal
+struct sysinit {
+ enum sysinit_sub_id subsystem; /* subsystem identifier*/
+ enum sysinit_elem_order order; /* init order within subsystem*/
+ sysinit_cfunc_t func; /* function */
+ const void *udata; /* multiplexer/argument */
+};
+.Ed
+.Pp
+The
+.Fn SYSINIT
+macro takes a
+.Fa uniquifier
+argument to identify the particular function dispatch data,
+the
+.Fa subsystem
+type of startup interface, the subsystem element
+.Fa order
+of initialization within the subsystem, the
+.Fa func
+function to call,
+and the data specified in
+.Fa ident
+argument to pass the function.
+.Pp
+The
+.Fn SYSUNINIT
+macro behaves similarly to the
+.Fn SYSINIT
+macro except that it adds the data to a shutdown linker set.
+.Pp
+The startup linker set for the kernel is scanned during boot to build a
+sorted list of initialization routines.
+The initialization routines are then executed in the sorted order.
+The
+.Fa subsystem
+is used as the primary key and is sorted in ascending order.
+The
+.Fa order
+is used as the secondary key and is sorted in ascending order.
+The relative order of two routines that have the same
+.Fa subsystem
+and
+.Fa order
+is undefined.
+.Pp
+The startup linker sets for modules that are loaded together with the kernel
+by the boot loader are scanned during the
+.Dv SI_SUB_KLD
+subsystem initialization.
+These modules' initialization routines are sorted and merged into the kernel's
+list of startup routines and are executed during boot along with the kernel's
+initialization routines.
+Note that this has the effect that any initialization routines in a kernel
+module that are scheduled earlier than
+.Dv SI_SUB_KLD
+are not executed until after
+.Dv SI_SUB_KLD
+during boot.
+.Pp
+The startup linker set for a kernel module loaded at runtime via
+.Xr kldload 2
+is scanned, sorted, and executed when the module is loaded.
+.Pp
+The shutdown linker set for a kernel module is scanned, sorted, and executed
+when a kernel module is unloaded.
+The teardown routines are sorted in the reverse order of the initialization
+routines.
+The teardown routines of the kernel and any loaded modules are
+.Sy not
+executed during shutdown.
+.Sh EXAMPLES
+This example shows the SYSINIT which displays the copyright notice during boot:
+.Bd -literal -offset indent
+static void
+print_caddr_t(void *data)
+{
+ printf("%s", (char *)data);
+}
+SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t,
+ copyright);
+.Ed
+.Sh SEE ALSO
+.Xr kld 4 ,
+.Xr DECLARE_MODULE 9 ,
+.Xr DEV_MODULE 9 ,
+.Xr DRIVER_MODULE 9 ,
+.Xr MTX_SYSINIT 9 ,
+.Xr SYSCALL_MODULE 9
+.Sh HISTORY
+The
+.Nm
+framework first appeared in
+.Fx 2.2 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+framework was written by
+.An Terrence Lambert Aq terry@FreeBSD.org .
+.Pp
+This manual page was written by
+.An Hiten Pandya Aq hmp@FreeBSD.org .
diff --git a/share/man/man9/bus_space.9 b/share/man/man9/bus_space.9
index 5a18dfb..b3234c4 100644
--- a/share/man/man9/bus_space.9
+++ b/share/man/man9/bus_space.9
@@ -719,6 +719,9 @@ or which return data read from bus space (i.e., functions which
do not obviously return an error code) do not fail.
They could only fail
if given invalid arguments, and in that case their behaviour is undefined.
+Functions which take a count of bytes have undefined results if the specified
+.Fa count
+is zero.
.Sh TYPES
Several types are defined in
.In machine/bus.h
diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot
index 9ecdf0b..3067c9e 100644
--- a/share/misc/committers-ports.dot
+++ b/share/misc/committers-ports.dot
@@ -80,6 +80,7 @@ eik [label="Oliver Eikemeier\neik@FreeBSD.org\n2003/11/12"]
erwin [label="Erwin Lansing\nerwin@FreeBSD.org\n2003/06/04"]
farrokhi [label="Babak Farrokhi\nfarrokhi@FreeBSD.org\n2006/11/07"]
fjoe [label="Max Khon\nfjoe@FreeBSD.org\n2001/08/06"]
+flo [label="Florian Smeets\nflo@FreeBSD.org\n2010/12/07"]
fluffy [label="Dima Panov\nfluffy@FreeBSD.org\n2009/08/10"]
flz [label="Florent Thoumie\nflz@FreeBSD.org\n2005/03/01"]
gabor [label="Gabor Kovesdan\ngabor@FreeBSD.org\n2006/12/05"]
@@ -230,6 +231,7 @@ erwin -> lth
erwin -> simon
fjoe -> danfe
+fjoe -> flo
fjoe -> krion
fjoe -> osa
@@ -262,6 +264,7 @@ itetcu -> dryice
itetcu -> sahil
jadawin -> bapt
+jadawin -> flo
joerg -> netchild
diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c
deleted file mode 100644
index 5a60bc1..0000000
--- a/sys/amd64/amd64/busdma_machdep.c
+++ /dev/null
@@ -1,1205 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998 Justin T. Gibbs.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification, immediately at the beginning of the file.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/bus.h>
-#include <sys/interrupt.h>
-#include <sys/kernel.h>
-#include <sys/ktr.h>
-#include <sys/lock.h>
-#include <sys/proc.h>
-#include <sys/mutex.h>
-#include <sys/mbuf.h>
-#include <sys/uio.h>
-#include <sys/sysctl.h>
-
-#include <vm/vm.h>
-#include <vm/vm_page.h>
-#include <vm/vm_map.h>
-
-#include <machine/atomic.h>
-#include <machine/bus.h>
-#include <machine/md_var.h>
-#include <machine/specialreg.h>
-
-#define MAX_BPAGES 8192
-
-struct bounce_zone;
-
-struct bus_dma_tag {
- bus_dma_tag_t parent;
- bus_size_t alignment;
- bus_size_t boundary;
- bus_addr_t lowaddr;
- bus_addr_t highaddr;
- bus_dma_filter_t *filter;
- void *filterarg;
- bus_size_t maxsize;
- u_int nsegments;
- bus_size_t maxsegsz;
- int flags;
- int ref_count;
- int map_count;
- bus_dma_lock_t *lockfunc;
- void *lockfuncarg;
- bus_dma_segment_t *segments;
- struct bounce_zone *bounce_zone;
-};
-
-struct bounce_page {
- vm_offset_t vaddr; /* kva of bounce buffer */
- bus_addr_t busaddr; /* Physical address */
- vm_offset_t datavaddr; /* kva of client data */
- bus_size_t datacount; /* client data count */
- STAILQ_ENTRY(bounce_page) links;
-};
-
-int busdma_swi_pending;
-
-struct bounce_zone {
- STAILQ_ENTRY(bounce_zone) links;
- STAILQ_HEAD(bp_list, bounce_page) bounce_page_list;
- int total_bpages;
- int free_bpages;
- int reserved_bpages;
- int active_bpages;
- int total_bounced;
- int total_deferred;
- int map_count;
- bus_size_t alignment;
- bus_addr_t lowaddr;
- char zoneid[8];
- char lowaddrid[20];
- struct sysctl_ctx_list sysctl_tree;
- struct sysctl_oid *sysctl_tree_top;
-};
-
-static struct mtx bounce_lock;
-static int total_bpages;
-static int busdma_zonecount;
-static STAILQ_HEAD(, bounce_zone) bounce_zone_list;
-
-SYSCTL_NODE(_hw, OID_AUTO, busdma, CTLFLAG_RD, 0, "Busdma parameters");
-SYSCTL_INT(_hw_busdma, OID_AUTO, total_bpages, CTLFLAG_RD, &total_bpages, 0,
- "Total bounce pages");
-
-struct bus_dmamap {
- struct bp_list bpages;
- int pagesneeded;
- int pagesreserved;
- bus_dma_tag_t dmat;
- void *buf; /* unmapped buffer pointer */
- bus_size_t buflen; /* unmapped buffer length */
- bus_dmamap_callback_t *callback;
- void *callback_arg;
- STAILQ_ENTRY(bus_dmamap) links;
-};
-
-static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist;
-static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist;
-static struct bus_dmamap nobounce_dmamap;
-
-static void init_bounce_pages(void *dummy);
-static int alloc_bounce_zone(bus_dma_tag_t dmat);
-static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages);
-static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
- int commit);
-static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
- vm_offset_t vaddr, bus_size_t size);
-static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
-static __inline int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr);
-
-/*
- * Return true if a match is made.
- *
- * To find a match walk the chain of bus_dma_tag_t's looking for 'paddr'.
- *
- * If paddr is within the bounds of the dma tag then call the filter callback
- * to check for a match, if there is no filter callback then assume a match.
- */
-static __inline int
-run_filter(bus_dma_tag_t dmat, bus_addr_t paddr)
-{
- int retval;
-
- retval = 0;
-
- do {
- if (((paddr > dmat->lowaddr && paddr <= dmat->highaddr)
- || ((paddr & (dmat->alignment - 1)) != 0))
- && (dmat->filter == NULL
- || (*dmat->filter)(dmat->filterarg, paddr) != 0))
- retval = 1;
-
- dmat = dmat->parent;
- } while (retval == 0 && dmat != NULL);
- return (retval);
-}
-
-/*
- * Convenience function for manipulating driver locks from busdma (during
- * busdma_swi, for example). Drivers that don't provide their own locks
- * should specify &Giant to dmat->lockfuncarg. Drivers that use their own
- * non-mutex locking scheme don't have to use this at all.
- */
-void
-busdma_lock_mutex(void *arg, bus_dma_lock_op_t op)
-{
- struct mtx *dmtx;
-
- dmtx = (struct mtx *)arg;
- switch (op) {
- case BUS_DMA_LOCK:
- mtx_lock(dmtx);
- break;
- case BUS_DMA_UNLOCK:
- mtx_unlock(dmtx);
- break;
- default:
- panic("Unknown operation 0x%x for busdma_lock_mutex!", op);
- }
-}
-
-/*
- * dflt_lock should never get called. It gets put into the dma tag when
- * lockfunc == NULL, which is only valid if the maps that are associated
- * with the tag are meant to never be defered.
- * XXX Should have a way to identify which driver is responsible here.
- */
-static void
-dflt_lock(void *arg, bus_dma_lock_op_t op)
-{
- panic("driver error: busdma dflt_lock called");
-}
-
-#define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3
-#define BUS_DMA_MIN_ALLOC_COMP BUS_DMA_BUS4
-/*
- * Allocate a device specific dma_tag.
- */
-int
-bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
- bus_size_t boundary, bus_addr_t lowaddr,
- bus_addr_t highaddr, bus_dma_filter_t *filter,
- void *filterarg, bus_size_t maxsize, int nsegments,
- bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
- void *lockfuncarg, bus_dma_tag_t *dmat)
-{
- bus_dma_tag_t newtag;
- int error = 0;
-
- /* Basic sanity checking */
- if (boundary != 0 && boundary < maxsegsz)
- maxsegsz = boundary;
-
- if (maxsegsz == 0) {
- return (EINVAL);
- }
-
- /* Return a NULL tag on failure */
- *dmat = NULL;
-
- newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF,
- M_ZERO | M_NOWAIT);
- if (newtag == NULL) {
- CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
- __func__, newtag, 0, error);
- return (ENOMEM);
- }
-
- newtag->parent = parent;
- newtag->alignment = alignment;
- newtag->boundary = boundary;
- newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1);
- newtag->highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1);
- newtag->filter = filter;
- newtag->filterarg = filterarg;
- newtag->maxsize = maxsize;
- newtag->nsegments = nsegments;
- newtag->maxsegsz = maxsegsz;
- newtag->flags = flags;
- newtag->ref_count = 1; /* Count ourself */
- newtag->map_count = 0;
- if (lockfunc != NULL) {
- newtag->lockfunc = lockfunc;
- newtag->lockfuncarg = lockfuncarg;
- } else {
- newtag->lockfunc = dflt_lock;
- newtag->lockfuncarg = NULL;
- }
- newtag->segments = NULL;
-
- /* Take into account any restrictions imposed by our parent tag */
- if (parent != NULL) {
- newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr);
- newtag->highaddr = MAX(parent->highaddr, newtag->highaddr);
- if (newtag->boundary == 0)
- newtag->boundary = parent->boundary;
- else if (parent->boundary != 0)
- newtag->boundary = MIN(parent->boundary,
- newtag->boundary);
- if (newtag->filter == NULL) {
- /*
- * Short circuit looking at our parent directly
- * since we have encapsulated all of its information
- */
- newtag->filter = parent->filter;
- newtag->filterarg = parent->filterarg;
- newtag->parent = parent->parent;
- }
- if (newtag->parent != NULL)
- atomic_add_int(&parent->ref_count, 1);
- }
-
- if (newtag->lowaddr < ptoa((vm_paddr_t)Maxmem)
- || newtag->alignment > 1)
- newtag->flags |= BUS_DMA_COULD_BOUNCE;
-
- if (((newtag->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
- (flags & BUS_DMA_ALLOCNOW) != 0) {
- struct bounce_zone *bz;
-
- /* Must bounce */
-
- if ((error = alloc_bounce_zone(newtag)) != 0) {
- free(newtag, M_DEVBUF);
- return (error);
- }
- bz = newtag->bounce_zone;
-
- if (ptoa(bz->total_bpages) < maxsize) {
- int pages;
-
- pages = atop(maxsize) - bz->total_bpages;
-
- /* Add pages to our bounce pool */
- if (alloc_bounce_pages(newtag, pages) < pages)
- error = ENOMEM;
- }
- /* Performed initial allocation */
- newtag->flags |= BUS_DMA_MIN_ALLOC_COMP;
- }
-
- if (error != 0) {
- free(newtag, M_DEVBUF);
- } else {
- *dmat = newtag;
- }
- CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
- __func__, newtag, (newtag != NULL ? newtag->flags : 0), error);
- return (error);
-}
-
-int
-bus_dma_tag_destroy(bus_dma_tag_t dmat)
-{
- bus_dma_tag_t dmat_copy;
- int error;
-
- error = 0;
- dmat_copy = dmat;
-
- if (dmat != NULL) {
-
- if (dmat->map_count != 0) {
- error = EBUSY;
- goto out;
- }
-
- while (dmat != NULL) {
- bus_dma_tag_t parent;
-
- parent = dmat->parent;
- atomic_subtract_int(&dmat->ref_count, 1);
- if (dmat->ref_count == 0) {
- if (dmat->segments != NULL)
- free(dmat->segments, M_DEVBUF);
- free(dmat, M_DEVBUF);
- /*
- * Last reference count, so
- * release our reference
- * count on our parent.
- */
- dmat = parent;
- } else
- dmat = NULL;
- }
- }
-out:
- CTR3(KTR_BUSDMA, "%s tag %p error %d", __func__, dmat_copy, error);
- return (error);
-}
-
-/*
- * Allocate a handle for mapping from kva/uva/physical
- * address space into bus device space.
- */
-int
-bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
-{
- int error;
-
- error = 0;
-
- if (dmat->segments == NULL) {
- dmat->segments = (bus_dma_segment_t *)malloc(
- sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF,
- M_NOWAIT);
- if (dmat->segments == NULL) {
- CTR3(KTR_BUSDMA, "%s: tag %p error %d",
- __func__, dmat, ENOMEM);
- return (ENOMEM);
- }
- }
-
- /*
- * Bouncing might be required if the driver asks for an active
- * exclusion region, a data alignment that is stricter than 1, and/or
- * an active address boundary.
- */
- if (dmat->flags & BUS_DMA_COULD_BOUNCE) {
-
- /* Must bounce */
- struct bounce_zone *bz;
- int maxpages;
-
- if (dmat->bounce_zone == NULL) {
- if ((error = alloc_bounce_zone(dmat)) != 0)
- return (error);
- }
- bz = dmat->bounce_zone;
-
- *mapp = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF,
- M_NOWAIT | M_ZERO);
- if (*mapp == NULL) {
- CTR3(KTR_BUSDMA, "%s: tag %p error %d",
- __func__, dmat, ENOMEM);
- return (ENOMEM);
- }
-
- /* Initialize the new map */
- STAILQ_INIT(&((*mapp)->bpages));
-
- /*
- * Attempt to add pages to our pool on a per-instance
- * basis up to a sane limit.
- */
- if (dmat->alignment > 1)
- maxpages = MAX_BPAGES;
- else
- maxpages = MIN(MAX_BPAGES, Maxmem -atop(dmat->lowaddr));
- if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0
- || (bz->map_count > 0 && bz->total_bpages < maxpages)) {
- int pages;
-
- pages = MAX(atop(dmat->maxsize), 1);
- pages = MIN(maxpages - bz->total_bpages, pages);
- pages = MAX(pages, 1);
- if (alloc_bounce_pages(dmat, pages) < pages)
- error = ENOMEM;
-
- if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) {
- if (error == 0)
- dmat->flags |= BUS_DMA_MIN_ALLOC_COMP;
- } else {
- error = 0;
- }
- }
- bz->map_count++;
- } else {
- *mapp = NULL;
- }
- if (error == 0)
- dmat->map_count++;
- CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
- __func__, dmat, dmat->flags, error);
- return (error);
-}
-
-/*
- * Destroy a handle for mapping from kva/uva/physical
- * address space into bus device space.
- */
-int
-bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
-{
- if (map != NULL && map != &nobounce_dmamap) {
- if (STAILQ_FIRST(&map->bpages) != NULL) {
- CTR3(KTR_BUSDMA, "%s: tag %p error %d",
- __func__, dmat, EBUSY);
- return (EBUSY);
- }
- if (dmat->bounce_zone)
- dmat->bounce_zone->map_count--;
- free(map, M_DEVBUF);
- }
- dmat->map_count--;
- CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat);
- return (0);
-}
-
-
-/*
- * Allocate a piece of memory that can be efficiently mapped into
- * bus device space based on the constraints lited in the dma tag.
- * A dmamap to for use with dmamap_load is also allocated.
- */
-int
-bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
- bus_dmamap_t *mapp)
-{
- int mflags;
-
- if (flags & BUS_DMA_NOWAIT)
- mflags = M_NOWAIT;
- else
- mflags = M_WAITOK;
-
- /* If we succeed, no mapping/bouncing will be required */
- *mapp = NULL;
-
- if (dmat->segments == NULL) {
- dmat->segments = (bus_dma_segment_t *)malloc(
- sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF,
- mflags);
- if (dmat->segments == NULL) {
- CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
- __func__, dmat, dmat->flags, ENOMEM);
- return (ENOMEM);
- }
- }
- if (flags & BUS_DMA_ZERO)
- mflags |= M_ZERO;
-
- /*
- * XXX:
- * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact
- * alignment guarantees of malloc need to be nailed down, and the
- * code below should be rewritten to take that into account.
- *
- * In the meantime, we'll warn the user if malloc gets it wrong.
- */
- if ((dmat->maxsize <= PAGE_SIZE) &&
- (dmat->alignment < dmat->maxsize) &&
- dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) {
- *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags);
- } else {
- /*
- * XXX Use Contigmalloc until it is merged into this facility
- * and handles multi-seg allocations. Nobody is doing
- * multi-seg allocations yet though.
- * XXX Certain AGP hardware does.
- */
- *vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags,
- 0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul,
- dmat->boundary);
- }
- if (*vaddr == NULL) {
- CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
- __func__, dmat, dmat->flags, ENOMEM);
- return (ENOMEM);
- } else if (vtophys(*vaddr) & (dmat->alignment - 1)) {
- printf("bus_dmamem_alloc failed to align memory properly.\n");
- }
- if (flags & BUS_DMA_NOCACHE)
- pmap_change_attr((vm_offset_t)*vaddr, dmat->maxsize,
- PAT_UNCACHEABLE);
- CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
- __func__, dmat, dmat->flags, 0);
- return (0);
-}
-
-/*
- * Free a piece of memory and it's allociated dmamap, that was allocated
- * via bus_dmamem_alloc. Make the same choice for free/contigfree.
- */
-void
-bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
-{
- /*
- * dmamem does not need to be bounced, so the map should be
- * NULL
- */
- if (map != NULL)
- panic("bus_dmamem_free: Invalid map freed\n");
- pmap_change_attr((vm_offset_t)vaddr, dmat->maxsize, PAT_WRITE_BACK);
- if ((dmat->maxsize <= PAGE_SIZE) &&
- (dmat->alignment < dmat->maxsize) &&
- dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem))
- free(vaddr, M_DEVBUF);
- else {
- contigfree(vaddr, dmat->maxsize, M_DEVBUF);
- }
- CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat, dmat->flags);
-}
-
-/*
- * Utility function to load a linear buffer. lastaddrp holds state
- * between invocations (for multiple-buffer loads). segp contains
- * the starting segment on entrace, and the ending segment on exit.
- * first indicates if this is the first invocation of this function.
- */
-static __inline int
-_bus_dmamap_load_buffer(bus_dma_tag_t dmat,
- bus_dmamap_t map,
- void *buf, bus_size_t buflen,
- pmap_t pmap,
- int flags,
- bus_addr_t *lastaddrp,
- bus_dma_segment_t *segs,
- int *segp,
- int first)
-{
- bus_size_t sgsize;
- bus_addr_t curaddr, lastaddr, baddr, bmask;
- vm_offset_t vaddr;
- bus_addr_t paddr;
- int seg;
-
- if (map == NULL)
- map = &nobounce_dmamap;
-
- if ((map != &nobounce_dmamap && map->pagesneeded == 0)
- && ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0)) {
- vm_offset_t vendaddr;
-
- CTR4(KTR_BUSDMA, "lowaddr= %d Maxmem= %d, boundary= %d, "
- "alignment= %d", dmat->lowaddr, ptoa((vm_paddr_t)Maxmem),
- dmat->boundary, dmat->alignment);
- CTR3(KTR_BUSDMA, "map= %p, nobouncemap= %p, pagesneeded= %d",
- map, &nobounce_dmamap, map->pagesneeded);
- /*
- * Count the number of bounce pages
- * needed in order to complete this transfer
- */
- vaddr = (vm_offset_t)buf;
- vendaddr = (vm_offset_t)buf + buflen;
-
- while (vaddr < vendaddr) {
- bus_size_t sg_len;
-
- sg_len = PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK);
- if (pmap)
- paddr = pmap_extract(pmap, vaddr);
- else
- paddr = pmap_kextract(vaddr);
- if (run_filter(dmat, paddr) != 0) {
- sg_len = roundup2(sg_len, dmat->alignment);
- map->pagesneeded++;
- }
- vaddr += sg_len;
- }
- CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
- }
-
- /* Reserve Necessary Bounce Pages */
- if (map->pagesneeded != 0) {
- mtx_lock(&bounce_lock);
- if (flags & BUS_DMA_NOWAIT) {
- if (reserve_bounce_pages(dmat, map, 0) != 0) {
- mtx_unlock(&bounce_lock);
- return (ENOMEM);
- }
- } else {
- if (reserve_bounce_pages(dmat, map, 1) != 0) {
- /* Queue us for resources */
- map->dmat = dmat;
- map->buf = buf;
- map->buflen = buflen;
- STAILQ_INSERT_TAIL(&bounce_map_waitinglist,
- map, links);
- mtx_unlock(&bounce_lock);
- return (EINPROGRESS);
- }
- }
- mtx_unlock(&bounce_lock);
- }
-
- vaddr = (vm_offset_t)buf;
- lastaddr = *lastaddrp;
- bmask = ~(dmat->boundary - 1);
-
- for (seg = *segp; buflen > 0 ; ) {
- bus_size_t max_sgsize;
-
- /*
- * Get the physical address for this segment.
- */
- if (pmap)
- curaddr = pmap_extract(pmap, vaddr);
- else
- curaddr = pmap_kextract(vaddr);
-
- /*
- * Compute the segment size, and adjust counts.
- */
- max_sgsize = MIN(buflen, dmat->maxsegsz);
- sgsize = PAGE_SIZE - ((vm_offset_t)curaddr & PAGE_MASK);
- if (map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
- sgsize = roundup2(sgsize, dmat->alignment);
- sgsize = MIN(sgsize, max_sgsize);
- curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
- } else {
- sgsize = MIN(sgsize, max_sgsize);
- }
-
- /*
- * Make sure we don't cross any boundaries.
- */
- if (dmat->boundary > 0) {
- baddr = (curaddr + dmat->boundary) & bmask;
- if (sgsize > (baddr - curaddr))
- sgsize = (baddr - curaddr);
- }
-
- /*
- * Insert chunk into a segment, coalescing with
- * previous segment if possible.
- */
- if (first) {
- segs[seg].ds_addr = curaddr;
- segs[seg].ds_len = sgsize;
- first = 0;
- } else {
- if (curaddr == lastaddr &&
- (segs[seg].ds_len + sgsize) <= dmat->maxsegsz &&
- (dmat->boundary == 0 ||
- (segs[seg].ds_addr & bmask) == (curaddr & bmask)))
- segs[seg].ds_len += sgsize;
- else {
- if (++seg >= dmat->nsegments)
- break;
- segs[seg].ds_addr = curaddr;
- segs[seg].ds_len = sgsize;
- }
- }
-
- lastaddr = curaddr + sgsize;
- vaddr += sgsize;
- buflen -= sgsize;
- }
-
- *segp = seg;
- *lastaddrp = lastaddr;
-
- /*
- * Did we fit?
- */
- return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
-}
-
-/*
- * Map the buffer buf into bus space using the dmamap map.
- */
-int
-bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
- bus_size_t buflen, bus_dmamap_callback_t *callback,
- void *callback_arg, int flags)
-{
- bus_addr_t lastaddr = 0;
- int error, nsegs = 0;
-
- if (map != NULL) {
- flags |= BUS_DMA_WAITOK;
- map->callback = callback;
- map->callback_arg = callback_arg;
- }
-
- error = _bus_dmamap_load_buffer(dmat, map, buf, buflen, NULL, flags,
- &lastaddr, dmat->segments, &nsegs, 1);
-
- CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
- __func__, dmat, dmat->flags, error, nsegs + 1);
-
- if (error == EINPROGRESS) {
- return (error);
- }
-
- if (error)
- (*callback)(callback_arg, dmat->segments, 0, error);
- else
- (*callback)(callback_arg, dmat->segments, nsegs + 1, 0);
-
- /*
- * Return ENOMEM to the caller so that it can pass it up the stack.
- * This error only happens when NOWAIT is set, so deferal is disabled.
- */
- if (error == ENOMEM)
- return (error);
-
- return (0);
-}
-
-
-/*
- * Like _bus_dmamap_load(), but for mbufs.
- */
-int
-bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map,
- struct mbuf *m0,
- bus_dmamap_callback2_t *callback, void *callback_arg,
- int flags)
-{
- int nsegs, error;
-
- M_ASSERTPKTHDR(m0);
-
- flags |= BUS_DMA_NOWAIT;
- nsegs = 0;
- error = 0;
- if (m0->m_pkthdr.len <= dmat->maxsize) {
- int first = 1;
- bus_addr_t lastaddr = 0;
- struct mbuf *m;
-
- for (m = m0; m != NULL && error == 0; m = m->m_next) {
- if (m->m_len > 0) {
- error = _bus_dmamap_load_buffer(dmat, map,
- m->m_data, m->m_len,
- NULL, flags, &lastaddr,
- dmat->segments, &nsegs, first);
- first = 0;
- }
- }
- } else {
- error = EINVAL;
- }
-
- if (error) {
- /* force "no valid mappings" in callback */
- (*callback)(callback_arg, dmat->segments, 0, 0, error);
- } else {
- (*callback)(callback_arg, dmat->segments,
- nsegs+1, m0->m_pkthdr.len, error);
- }
- CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
- __func__, dmat, dmat->flags, error, nsegs + 1);
- return (error);
-}
-
-int
-bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map,
- struct mbuf *m0, bus_dma_segment_t *segs, int *nsegs,
- int flags)
-{
- int error;
-
- M_ASSERTPKTHDR(m0);
-
- flags |= BUS_DMA_NOWAIT;
- *nsegs = 0;
- error = 0;
- if (m0->m_pkthdr.len <= dmat->maxsize) {
- int first = 1;
- bus_addr_t lastaddr = 0;
- struct mbuf *m;
-
- for (m = m0; m != NULL && error == 0; m = m->m_next) {
- if (m->m_len > 0) {
- error = _bus_dmamap_load_buffer(dmat, map,
- m->m_data, m->m_len,
- NULL, flags, &lastaddr,
- segs, nsegs, first);
- first = 0;
- }
- }
- } else {
- error = EINVAL;
- }
-
- /* XXX FIXME: Having to increment nsegs is really annoying */
- ++*nsegs;
- CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
- __func__, dmat, dmat->flags, error, *nsegs);
- return (error);
-}
-
-/*
- * Like _bus_dmamap_load(), but for uios.
- */
-int
-bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map,
- struct uio *uio,
- bus_dmamap_callback2_t *callback, void *callback_arg,
- int flags)
-{
- bus_addr_t lastaddr = 0;
- int nsegs, error, first, i;
- bus_size_t resid;
- struct iovec *iov;
- pmap_t pmap;
-
- flags |= BUS_DMA_NOWAIT;
- resid = uio->uio_resid;
- iov = uio->uio_iov;
-
- if (uio->uio_segflg == UIO_USERSPACE) {
- KASSERT(uio->uio_td != NULL,
- ("bus_dmamap_load_uio: USERSPACE but no proc"));
- pmap = vmspace_pmap(uio->uio_td->td_proc->p_vmspace);
- } else
- pmap = NULL;
-
- nsegs = 0;
- error = 0;
- first = 1;
- for (i = 0; i < uio->uio_iovcnt && resid != 0 && !error; i++) {
- /*
- * Now at the first iovec to load. Load each iovec
- * until we have exhausted the residual count.
- */
- bus_size_t minlen =
- resid < iov[i].iov_len ? resid : iov[i].iov_len;
- caddr_t addr = (caddr_t) iov[i].iov_base;
-
- if (minlen > 0) {
- error = _bus_dmamap_load_buffer(dmat, map,
- addr, minlen, pmap, flags, &lastaddr,
- dmat->segments, &nsegs, first);
- first = 0;
-
- resid -= minlen;
- }
- }
-
- if (error) {
- /* force "no valid mappings" in callback */
- (*callback)(callback_arg, dmat->segments, 0, 0, error);
- } else {
- (*callback)(callback_arg, dmat->segments,
- nsegs+1, uio->uio_resid, error);
- }
- CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
- __func__, dmat, dmat->flags, error, nsegs + 1);
- return (error);
-}
-
-/*
- * Release the mapping held by map.
- */
-void
-_bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
-{
- struct bounce_page *bpage;
-
- while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
- STAILQ_REMOVE_HEAD(&map->bpages, links);
- free_bounce_page(dmat, bpage);
- }
-}
-
-void
-_bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
-{
- struct bounce_page *bpage;
-
- if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
- /*
- * Handle data bouncing. We might also
- * want to add support for invalidating
- * the caches on broken hardware
- */
- CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
- "performing bounce", __func__, op, dmat, dmat->flags);
-
- if (op & BUS_DMASYNC_PREWRITE) {
- while (bpage != NULL) {
- bcopy((void *)bpage->datavaddr,
- (void *)bpage->vaddr,
- bpage->datacount);
- bpage = STAILQ_NEXT(bpage, links);
- }
- dmat->bounce_zone->total_bounced++;
- }
-
- if (op & BUS_DMASYNC_POSTREAD) {
- while (bpage != NULL) {
- bcopy((void *)bpage->vaddr,
- (void *)bpage->datavaddr,
- bpage->datacount);
- bpage = STAILQ_NEXT(bpage, links);
- }
- dmat->bounce_zone->total_bounced++;
- }
- }
-}
-
-static void
-init_bounce_pages(void *dummy __unused)
-{
-
- total_bpages = 0;
- STAILQ_INIT(&bounce_zone_list);
- STAILQ_INIT(&bounce_map_waitinglist);
- STAILQ_INIT(&bounce_map_callbacklist);
- mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF);
-}
-SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL);
-
-static struct sysctl_ctx_list *
-busdma_sysctl_tree(struct bounce_zone *bz)
-{
- return (&bz->sysctl_tree);
-}
-
-static struct sysctl_oid *
-busdma_sysctl_tree_top(struct bounce_zone *bz)
-{
- return (bz->sysctl_tree_top);
-}
-
-static int
-alloc_bounce_zone(bus_dma_tag_t dmat)
-{
- struct bounce_zone *bz;
-
- /* Check to see if we already have a suitable zone */
- STAILQ_FOREACH(bz, &bounce_zone_list, links) {
- if ((dmat->alignment <= bz->alignment)
- && (dmat->lowaddr >= bz->lowaddr)) {
- dmat->bounce_zone = bz;
- return (0);
- }
- }
-
- if ((bz = (struct bounce_zone *)malloc(sizeof(*bz), M_DEVBUF,
- M_NOWAIT | M_ZERO)) == NULL)
- return (ENOMEM);
-
- STAILQ_INIT(&bz->bounce_page_list);
- bz->free_bpages = 0;
- bz->reserved_bpages = 0;
- bz->active_bpages = 0;
- bz->lowaddr = dmat->lowaddr;
- bz->alignment = MAX(dmat->alignment, PAGE_SIZE);
- bz->map_count = 0;
- snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount);
- busdma_zonecount++;
- snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr);
- STAILQ_INSERT_TAIL(&bounce_zone_list, bz, links);
- dmat->bounce_zone = bz;
-
- sysctl_ctx_init(&bz->sysctl_tree);
- bz->sysctl_tree_top = SYSCTL_ADD_NODE(&bz->sysctl_tree,
- SYSCTL_STATIC_CHILDREN(_hw_busdma), OID_AUTO, bz->zoneid,
- CTLFLAG_RD, 0, "");
- if (bz->sysctl_tree_top == NULL) {
- sysctl_ctx_free(&bz->sysctl_tree);
- return (0); /* XXX error code? */
- }
-
- SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
- SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
- "total_bpages", CTLFLAG_RD, &bz->total_bpages, 0,
- "Total bounce pages");
- SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
- SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
- "free_bpages", CTLFLAG_RD, &bz->free_bpages, 0,
- "Free bounce pages");
- SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
- SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
- "reserved_bpages", CTLFLAG_RD, &bz->reserved_bpages, 0,
- "Reserved bounce pages");
- SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
- SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
- "active_bpages", CTLFLAG_RD, &bz->active_bpages, 0,
- "Active bounce pages");
- SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
- SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
- "total_bounced", CTLFLAG_RD, &bz->total_bounced, 0,
- "Total bounce requests");
- SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
- SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
- "total_deferred", CTLFLAG_RD, &bz->total_deferred, 0,
- "Total bounce requests that were deferred");
- SYSCTL_ADD_STRING(busdma_sysctl_tree(bz),
- SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
- "lowaddr", CTLFLAG_RD, bz->lowaddrid, 0, "");
- SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
- SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
- "alignment", CTLFLAG_RD, &bz->alignment, 0, "");
-
- return (0);
-}
-
-static int
-alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages)
-{
- struct bounce_zone *bz;
- int count;
-
- bz = dmat->bounce_zone;
- count = 0;
- while (numpages > 0) {
- struct bounce_page *bpage;
-
- bpage = (struct bounce_page *)malloc(sizeof(*bpage), M_DEVBUF,
- M_NOWAIT | M_ZERO);
-
- if (bpage == NULL)
- break;
- bpage->vaddr = (vm_offset_t)contigmalloc(PAGE_SIZE, M_DEVBUF,
- M_NOWAIT, 0ul,
- bz->lowaddr,
- PAGE_SIZE,
- 0);
- if (bpage->vaddr == 0) {
- free(bpage, M_DEVBUF);
- break;
- }
- bpage->busaddr = pmap_kextract(bpage->vaddr);
- mtx_lock(&bounce_lock);
- STAILQ_INSERT_TAIL(&bz->bounce_page_list, bpage, links);
- total_bpages++;
- bz->total_bpages++;
- bz->free_bpages++;
- mtx_unlock(&bounce_lock);
- count++;
- numpages--;
- }
- return (count);
-}
-
-static int
-reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int commit)
-{
- struct bounce_zone *bz;
- int pages;
-
- mtx_assert(&bounce_lock, MA_OWNED);
- bz = dmat->bounce_zone;
- pages = MIN(bz->free_bpages, map->pagesneeded - map->pagesreserved);
- if (commit == 0 && map->pagesneeded > (map->pagesreserved + pages))
- return (map->pagesneeded - (map->pagesreserved + pages));
- bz->free_bpages -= pages;
- bz->reserved_bpages += pages;
- map->pagesreserved += pages;
- pages = map->pagesneeded - map->pagesreserved;
-
- return (pages);
-}
-
-static bus_addr_t
-add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
- bus_size_t size)
-{
- struct bounce_zone *bz;
- struct bounce_page *bpage;
-
- KASSERT(dmat->bounce_zone != NULL, ("no bounce zone in dma tag"));
- KASSERT(map != NULL && map != &nobounce_dmamap,
- ("add_bounce_page: bad map %p", map));
-
- bz = dmat->bounce_zone;
- if (map->pagesneeded == 0)
- panic("add_bounce_page: map doesn't need any pages");
- map->pagesneeded--;
-
- if (map->pagesreserved == 0)
- panic("add_bounce_page: map doesn't need any pages");
- map->pagesreserved--;
-
- mtx_lock(&bounce_lock);
- bpage = STAILQ_FIRST(&bz->bounce_page_list);
- if (bpage == NULL)
- panic("add_bounce_page: free page list is empty");
-
- STAILQ_REMOVE_HEAD(&bz->bounce_page_list, links);
- bz->reserved_bpages--;
- bz->active_bpages++;
- mtx_unlock(&bounce_lock);
-
- if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
- /* Page offset needs to be preserved. */
- bpage->vaddr |= vaddr & PAGE_MASK;
- bpage->busaddr |= vaddr & PAGE_MASK;
- }
- bpage->datavaddr = vaddr;
- bpage->datacount = size;
- STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
- return (bpage->busaddr);
-}
-
-static void
-free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
-{
- struct bus_dmamap *map;
- struct bounce_zone *bz;
-
- bz = dmat->bounce_zone;
- bpage->datavaddr = 0;
- bpage->datacount = 0;
- if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
- /*
- * Reset the bounce page to start at offset 0. Other uses
- * of this bounce page may need to store a full page of
- * data and/or assume it starts on a page boundary.
- */
- bpage->vaddr &= ~PAGE_MASK;
- bpage->busaddr &= ~PAGE_MASK;
- }
-
- mtx_lock(&bounce_lock);
- STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links);
- bz->free_bpages++;
- bz->active_bpages--;
- if ((map = STAILQ_FIRST(&bounce_map_waitinglist)) != NULL) {
- if (reserve_bounce_pages(map->dmat, map, 1) == 0) {
- STAILQ_REMOVE_HEAD(&bounce_map_waitinglist, links);
- STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
- map, links);
- busdma_swi_pending = 1;
- bz->total_deferred++;
- swi_sched(vm_ih, 0);
- }
- }
- mtx_unlock(&bounce_lock);
-}
-
-void
-busdma_swi(void)
-{
- bus_dma_tag_t dmat;
- struct bus_dmamap *map;
-
- mtx_lock(&bounce_lock);
- while ((map = STAILQ_FIRST(&bounce_map_callbacklist)) != NULL) {
- STAILQ_REMOVE_HEAD(&bounce_map_callbacklist, links);
- mtx_unlock(&bounce_lock);
- dmat = map->dmat;
- (dmat->lockfunc)(dmat->lockfuncarg, BUS_DMA_LOCK);
- bus_dmamap_load(map->dmat, map, map->buf, map->buflen,
- map->callback, map->callback_arg, /*flags*/0);
- (dmat->lockfunc)(dmat->lockfuncarg, BUS_DMA_UNLOCK);
- mtx_lock(&bounce_lock);
- }
- mtx_unlock(&bounce_lock);
-}
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index 37e89a00..7ffa7a9 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -380,7 +380,6 @@ IDTVEC(fast_syscall)
movq %rsp,%rdi
call syscall
movq PCPU(CURPCB),%rax
- andq $~PCB_FULLCTX,PCB_FLAGS(%rax)
MEXITCOUNT
jmp doreti
diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c
index 613bce5..bc30174 100644
--- a/sys/amd64/amd64/genassym.c
+++ b/sys/amd64/amd64/genassym.c
@@ -161,7 +161,6 @@ ASSYM(PCB_SIZE, sizeof(struct pcb));
ASSYM(PCB_DBREGS, PCB_DBREGS);
ASSYM(PCB_32BIT, PCB_32BIT);
ASSYM(PCB_GS32BIT, PCB_GS32BIT);
-ASSYM(PCB_FULLCTX, PCB_FULLCTX);
ASSYM(COMMON_TSS_RSP0, offsetof(struct amd64tss, tss_rsp0));
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index 7e4319e..cd28d59 100644
--- a/sys/amd64/amd64/identcpu.c
+++ b/sys/amd64/amd64/identcpu.c
@@ -109,6 +109,8 @@ static int hw_clockrate;
SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD,
&hw_clockrate, 0, "CPU instruction clock rate");
+static eventhandler_tag tsc_post_tag;
+
static char cpu_brand[48];
static struct {
@@ -392,28 +394,6 @@ printcpuinfo(void)
* If this CPU supports P-state invariant TSC then
* mention the capability.
*/
- switch (cpu_vendor_id) {
- case CPU_VENDOR_AMD:
- if ((amd_pminfo & AMDPM_TSC_INVARIANT) ||
- CPUID_TO_FAMILY(cpu_id) >= 0x10 ||
- cpu_id == 0x60fb2)
- tsc_is_invariant = 1;
- break;
- case CPU_VENDOR_INTEL:
- if ((amd_pminfo & AMDPM_TSC_INVARIANT) ||
- (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
- CPUID_TO_MODEL(cpu_id) >= 0xe) ||
- (CPUID_TO_FAMILY(cpu_id) == 0xf &&
- CPUID_TO_MODEL(cpu_id) >= 0x3))
- tsc_is_invariant = 1;
- break;
- case CPU_VENDOR_CENTAUR:
- if (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
- CPUID_TO_MODEL(cpu_id) >= 0xf &&
- (rdmsr(0x1203) & 0x100000000ULL) == 0)
- tsc_is_invariant = 1;
- break;
- }
if (tsc_is_invariant)
printf("\n TSC: P-state invariant");
@@ -455,21 +435,29 @@ panicifcpuunsupported(void)
/* Update TSC freq with the value indicated by the caller. */
static void
-tsc_freq_changed(void *arg, const struct cf_level *level, int status)
+tsc_freq_changed(void *arg __unused, const struct cf_level *level, int status)
{
- /*
- * If there was an error during the transition or
- * TSC is P-state invariant, don't do anything.
- */
- if (status != 0 || tsc_is_invariant)
+
+ /* If there was an error during the transition, don't do anything. */
+ if (status != 0)
return;
/* Total setting for this level gives the new frequency in MHz. */
hw_clockrate = level->total_set.freq;
}
-EVENTHANDLER_DEFINE(cpufreq_post_change, tsc_freq_changed, NULL,
- EVENTHANDLER_PRI_ANY);
+static void
+hook_tsc_freq(void *arg __unused)
+{
+
+ if (tsc_is_invariant)
+ return;
+
+ tsc_post_tag = EVENTHANDLER_REGISTER(cpufreq_post_change,
+ tsc_freq_changed, NULL, EVENTHANDLER_PRI_ANY);
+}
+
+SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, NULL);
/*
* Final stage of CPU identification.
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 584473d..55b1ea3 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -492,7 +492,6 @@ sigreturn(td, uap)
#endif
kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
- td->td_pcb->pcb_flags |= PCB_FULLCTX;
td->td_pcb->pcb_full_iret = 1;
return (EJUSTRETURN);
}
@@ -564,13 +563,7 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
thread_unlock(curthread);
#endif
- /*
- * Calculate the difference in readings, convert to Mhz, and
- * subtract 0.5% of the total. Empirical testing has shown that
- * overhead in DELAY() works out to approximately this value.
- */
- tsc2 -= tsc1;
- *rate = tsc2 * 1000 - tsc2 * 5;
+ *rate = (tsc2 - tsc1) * 1000;
return (0);
}
@@ -876,6 +869,7 @@ exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
regs->tf_fs = _ufssel;
regs->tf_gs = _ugssel;
regs->tf_flags = TF_HASSEGS;
+ td->td_retval[1] = 0;
/*
* Reset the hardware debug registers if they were in use.
@@ -1906,8 +1900,8 @@ set_regs(struct thread *td, struct reg *regs)
tp->tf_fs = regs->r_fs;
tp->tf_gs = regs->r_gs;
tp->tf_flags = TF_HASSEGS;
+ td->td_pcb->pcb_full_iret = 1;
}
- td->td_pcb->pcb_flags |= PCB_FULLCTX;
return (0);
}
@@ -2094,7 +2088,6 @@ set_mcontext(struct thread *td, const mcontext_t *mcp)
td->td_pcb->pcb_fsbase = mcp->mc_fsbase;
td->td_pcb->pcb_gsbase = mcp->mc_gsbase;
}
- td->td_pcb->pcb_flags |= PCB_FULLCTX;
td->td_pcb->pcb_full_iret = 1;
return (0);
}
diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c
deleted file mode 100644
index 847c1eb..0000000
--- a/sys/amd64/amd64/tsc.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*-
- * Copyright (c) 1998-2003 Poul-Henning Kamp
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_clock.h"
-
-#include <sys/param.h>
-#include <sys/bus.h>
-#include <sys/cpu.h>
-#include <sys/malloc.h>
-#include <sys/systm.h>
-#include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/timetc.h>
-#include <sys/kernel.h>
-#include <sys/power.h>
-#include <sys/smp.h>
-#include <machine/clock.h>
-#include <machine/md_var.h>
-#include <machine/specialreg.h>
-
-#include "cpufreq_if.h"
-
-uint64_t tsc_freq;
-int tsc_is_broken;
-int tsc_is_invariant;
-static eventhandler_tag tsc_levels_tag, tsc_pre_tag, tsc_post_tag;
-
-SYSCTL_INT(_kern_timecounter, OID_AUTO, invariant_tsc, CTLFLAG_RDTUN,
- &tsc_is_invariant, 0, "Indicates whether the TSC is P-state invariant");
-TUNABLE_INT("kern.timecounter.invariant_tsc", &tsc_is_invariant);
-
-#ifdef SMP
-static int smp_tsc;
-SYSCTL_INT(_kern_timecounter, OID_AUTO, smp_tsc, CTLFLAG_RDTUN, &smp_tsc, 0,
- "Indicates whether the TSC is safe to use in SMP mode");
-TUNABLE_INT("kern.timecounter.smp_tsc", &smp_tsc);
-#endif
-
-static void tsc_freq_changed(void *arg, const struct cf_level *level,
- int status);
-static void tsc_freq_changing(void *arg, const struct cf_level *level,
- int *status);
-static unsigned tsc_get_timecount(struct timecounter *tc);
-static void tsc_levels_changed(void *arg, int unit);
-
-static struct timecounter tsc_timecounter = {
- tsc_get_timecount, /* get_timecount */
- 0, /* no poll_pps */
- ~0u, /* counter_mask */
- 0, /* frequency */
- "TSC", /* name */
- 800, /* quality (adjusted in code) */
-};
-
-void
-init_TSC(void)
-{
- u_int64_t tscval[2];
-
- if (bootverbose)
- printf("Calibrating TSC clock ... ");
-
- tscval[0] = rdtsc();
- DELAY(1000000);
- tscval[1] = rdtsc();
-
- tsc_freq = tscval[1] - tscval[0];
- if (bootverbose)
- printf("TSC clock: %lu Hz\n", tsc_freq);
-
- /*
- * Inform CPU accounting about our boot-time clock rate. Once the
- * system is finished booting, we will get the real max clock rate
- * via tsc_freq_max(). This also will be updated if someone loads
- * a cpufreq driver after boot that discovers a new max frequency.
- */
- set_cputicker(rdtsc, tsc_freq, 1);
-
- /* Register to find out about changes in CPU frequency. */
- tsc_pre_tag = EVENTHANDLER_REGISTER(cpufreq_pre_change,
- tsc_freq_changing, NULL, EVENTHANDLER_PRI_FIRST);
- tsc_post_tag = EVENTHANDLER_REGISTER(cpufreq_post_change,
- tsc_freq_changed, NULL, EVENTHANDLER_PRI_FIRST);
- tsc_levels_tag = EVENTHANDLER_REGISTER(cpufreq_levels_changed,
- tsc_levels_changed, NULL, EVENTHANDLER_PRI_ANY);
-}
-
-void
-init_TSC_tc(void)
-{
-
-#ifdef SMP
- /*
- * We can not use the TSC in SMP mode unless the TSCs on all CPUs
- * are somehow synchronized. Some hardware configurations do
- * this, but we have no way of determining whether this is the
- * case, so we do not use the TSC in multi-processor systems
- * unless the user indicated (by setting kern.timecounter.smp_tsc
- * to 1) that he believes that his TSCs are synchronized.
- */
- if (mp_ncpus > 1 && !smp_tsc)
- tsc_timecounter.tc_quality = -100;
-#endif
-
- if (tsc_freq != 0 && !tsc_is_broken) {
- tsc_timecounter.tc_frequency = tsc_freq;
- tc_init(&tsc_timecounter);
- }
-}
-
-/*
- * When cpufreq levels change, find out about the (new) max frequency. We
- * use this to update CPU accounting in case it got a lower estimate at boot.
- */
-static void
-tsc_levels_changed(void *arg, int unit)
-{
- device_t cf_dev;
- struct cf_level *levels;
- int count, error;
- uint64_t max_freq;
-
- /* Only use values from the first CPU, assuming all are equal. */
- if (unit != 0)
- return;
-
- /* Find the appropriate cpufreq device instance. */
- cf_dev = devclass_get_device(devclass_find("cpufreq"), unit);
- if (cf_dev == NULL) {
- printf("tsc_levels_changed() called but no cpufreq device?\n");
- return;
- }
-
- /* Get settings from the device and find the max frequency. */
- count = 64;
- levels = malloc(count * sizeof(*levels), M_TEMP, M_NOWAIT);
- if (levels == NULL)
- return;
- error = CPUFREQ_LEVELS(cf_dev, levels, &count);
- if (error == 0 && count != 0) {
- max_freq = (uint64_t)levels[0].total_set.freq * 1000000;
- set_cputicker(rdtsc, max_freq, 1);
- } else
- printf("tsc_levels_changed: no max freq found\n");
- free(levels, M_TEMP);
-}
-
-/*
- * If the TSC timecounter is in use, veto the pending change. It may be
- * possible in the future to handle a dynamically-changing timecounter rate.
- */
-static void
-tsc_freq_changing(void *arg, const struct cf_level *level, int *status)
-{
-
- if (*status != 0 || timecounter != &tsc_timecounter ||
- tsc_is_invariant)
- return;
-
- printf("timecounter TSC must not be in use when "
- "changing frequencies; change denied\n");
- *status = EBUSY;
-}
-
-/* Update TSC freq with the value indicated by the caller. */
-static void
-tsc_freq_changed(void *arg, const struct cf_level *level, int status)
-{
- /*
- * If there was an error during the transition or
- * TSC is P-state invariant, don't do anything.
- */
- if (status != 0 || tsc_is_invariant)
- return;
-
- /* Total setting for this level gives the new frequency in MHz. */
- tsc_freq = (uint64_t)level->total_set.freq * 1000000;
- tsc_timecounter.tc_frequency = tsc_freq;
-}
-
-static int
-sysctl_machdep_tsc_freq(SYSCTL_HANDLER_ARGS)
-{
- int error;
- uint64_t freq;
-
- if (tsc_timecounter.tc_frequency == 0)
- return (EOPNOTSUPP);
- freq = tsc_freq;
- error = sysctl_handle_quad(oidp, &freq, 0, req);
- if (error == 0 && req->newptr != NULL) {
- tsc_freq = freq;
- tsc_timecounter.tc_frequency = tsc_freq;
- }
- return (error);
-}
-
-SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_QUAD | CTLFLAG_RW,
- 0, 0, sysctl_machdep_tsc_freq, "QU", "");
-
-static unsigned
-tsc_get_timecount(struct timecounter *tc)
-{
- return (rdtsc());
-}
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index dafd376..b966393 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -339,15 +339,13 @@ cpu_set_syscall_retval(struct thread *td, int error)
* Reconstruct pc, we know that 'syscall' is 2 bytes,
* lcall $X,y is 7 bytes, int 0x80 is 2 bytes.
* We saved this in tf_err.
- * We have to do a full context restore so that %r10
- * (which was holding the value of %rcx) is restored
+ * %r10 (which was holding the value of %rcx) is restored
* for the next iteration.
- * r10 restore is only required for freebsd/amd64 processes,
+ * %r10 restore is only required for freebsd/amd64 processes,
* but shall be innocent for any ia32 ABI.
*/
td->td_frame->tf_rip -= td->td_frame->tf_err;
td->td_frame->tf_r10 = td->td_frame->tf_rcx;
- td->td_pcb->pcb_flags |= PCB_FULLCTX;
break;
case EJUSTRETURN:
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
index aefe9f0..e0f30e2 100644
--- a/sys/amd64/ia32/ia32_signal.c
+++ b/sys/amd64/ia32/ia32_signal.c
@@ -207,7 +207,6 @@ ia32_set_mcontext(struct thread *td, const struct ia32_mcontext *mcp)
tp->tf_rflags = rflags;
tp->tf_rsp = mcp->mc_esp;
tp->tf_ss = mcp->mc_ss;
- td->td_pcb->pcb_flags |= PCB_FULLCTX;
td->td_pcb->pcb_full_iret = 1;
return (0);
}
@@ -743,7 +742,7 @@ ia32_setregs(struct thread *td, struct image_params *imgp, u_long stack)
fpstate_drop(td);
/* Return via doreti so that we can change to a different %cs */
- pcb->pcb_flags |= PCB_FULLCTX | PCB_32BIT;
+ pcb->pcb_flags |= PCB_32BIT;
pcb->pcb_flags &= ~PCB_GS32BIT;
td->td_pcb->pcb_full_iret = 1;
td->td_retval[1] = 0;
diff --git a/sys/amd64/include/cpu.h b/sys/amd64/include/cpu.h
index 1c2871f..3cc4af7 100644
--- a/sys/amd64/include/cpu.h
+++ b/sys/amd64/include/cpu.h
@@ -56,6 +56,7 @@
#ifdef _KERNEL
extern char btext[];
extern char etext[];
+extern int tsc_present;
void cpu_halt(void);
void cpu_reset(void);
diff --git a/sys/amd64/include/pcb.h b/sys/amd64/include/pcb.h
index 1f4ff22..e226379 100644
--- a/sys/amd64/include/pcb.h
+++ b/sys/amd64/include/pcb.h
@@ -73,7 +73,6 @@ struct pcb {
#define PCB_USERFPUINITDONE 0x10 /* fpu user state is initialized */
#define PCB_GS32BIT 0x20 /* linux gs switch */
#define PCB_32BIT 0x40 /* process has 32 bit context (segs etc) */
-#define PCB_FULLCTX 0x80 /* full context restore on sysret */
uint16_t pcb_initial_fpucw;
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index f8719c4..3ebb980 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -865,13 +865,13 @@ exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack)
regs->tf_flags = TF_HASSEGS;
regs->tf_cs = _ucode32sel;
regs->tf_rbx = imgp->ps_strings;
- td->td_pcb->pcb_full_iret = 1;
load_cr0(rcr0() | CR0_MP | CR0_TS);
fpstate_drop(td);
- /* Return via doreti so that we can change to a different %cs */
- pcb->pcb_flags |= PCB_FULLCTX | PCB_32BIT;
+ /* Do full restore on return so that we can change to a different %cs */
+ pcb->pcb_flags |= PCB_32BIT;
pcb->pcb_flags &= ~PCB_GS32BIT;
+ pcb->pcb_full_iret = 1;
td->td_retval[1] = 0;
}
diff --git a/sys/arm/at91/at91_pmc.c b/sys/arm/at91/at91_pmc.c
index 03a7a6e..bbd0ac9 100644
--- a/sys/arm/at91/at91_pmc.c
+++ b/sys/arm/at91/at91_pmc.c
@@ -325,7 +325,7 @@ at91_pmc_clock_disable(struct at91_pmc_clock *clk)
static int
at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg)
{
- uint32_t mul, div, freq;;
+ uint32_t mul, div, freq;
freq = clk->parent->hz;
div = (reg >> clk->pll_div_shift) & clk->pll_div_mask;
diff --git a/sys/cddl/compat/opensolaris/sys/cyclic_impl.h b/sys/cddl/compat/opensolaris/sys/cyclic_impl.h
index a195251..57bb167 100644
--- a/sys/cddl/compat/opensolaris/sys/cyclic_impl.h
+++ b/sys/cddl/compat/opensolaris/sys/cyclic_impl.h
@@ -288,7 +288,14 @@ typedef struct cyc_id {
typedef struct cyc_xcallarg {
cyc_cpu_t *cyx_cpu;
- hrtime_t cyx_exp;
+ cyc_handler_t *cyx_hdlr;
+ cyc_time_t *cyx_when;
+ cyc_index_t cyx_ndx;
+ cyc_index_t *cyx_heap;
+ cyclic_t *cyx_cyclics;
+ cyc_index_t cyx_size;
+ uint16_t cyx_flags;
+ int cyx_wait;
} cyc_xcallarg_t;
#define CY_DEFAULT_PERCPU 1
diff --git a/sys/cddl/dev/cyclic/cyclic.c b/sys/cddl/dev/cyclic/cyclic.c
index df0de6b..b9a6979 100644
--- a/sys/cddl/dev/cyclic/cyclic.c
+++ b/sys/cddl/dev/cyclic/cyclic.c
@@ -473,73 +473,6 @@ cyclic_expire(cyc_cpu_t *cpu, cyc_index_t ndx, cyclic_t *cyclic)
(*handler)(arg);
}
-static void
-cyclic_enable_xcall(void *v)
-{
- cyc_xcallarg_t *argp = v;
- cyc_cpu_t *cpu = argp->cyx_cpu;
- cyc_backend_t *be = cpu->cyp_backend;
-
- be->cyb_enable(be->cyb_arg);
-}
-
-static void
-cyclic_enable(cyc_cpu_t *cpu)
-{
- cyc_backend_t *be = cpu->cyp_backend;
- cyc_xcallarg_t arg;
-
- arg.cyx_cpu = cpu;
-
- /* Cross call to the target CPU */
- be->cyb_xcall(be->cyb_arg, cpu->cyp_cpu, cyclic_enable_xcall, &arg);
-}
-
-static void
-cyclic_disable_xcall(void *v)
-{
- cyc_xcallarg_t *argp = v;
- cyc_cpu_t *cpu = argp->cyx_cpu;
- cyc_backend_t *be = cpu->cyp_backend;
-
- be->cyb_disable(be->cyb_arg);
-}
-
-static void
-cyclic_disable(cyc_cpu_t *cpu)
-{
- cyc_backend_t *be = cpu->cyp_backend;
- cyc_xcallarg_t arg;
-
- arg.cyx_cpu = cpu;
-
- /* Cross call to the target CPU */
- be->cyb_xcall(be->cyb_arg, cpu->cyp_cpu, cyclic_disable_xcall, &arg);
-}
-
-static void
-cyclic_reprogram_xcall(void *v)
-{
- cyc_xcallarg_t *argp = v;
- cyc_cpu_t *cpu = argp->cyx_cpu;
- cyc_backend_t *be = cpu->cyp_backend;
-
- be->cyb_reprogram(be->cyb_arg, argp->cyx_exp);
-}
-
-static void
-cyclic_reprogram(cyc_cpu_t *cpu, hrtime_t exp)
-{
- cyc_backend_t *be = cpu->cyp_backend;
- cyc_xcallarg_t arg;
-
- arg.cyx_cpu = cpu;
- arg.cyx_exp = exp;
-
- /* Cross call to the target CPU */
- be->cyb_xcall(be->cyb_arg, cpu->cyp_cpu, cyclic_reprogram_xcall, &arg);
-}
-
/*
* cyclic_fire(cpu_t *)
*
@@ -570,17 +503,15 @@ static void
cyclic_fire(cpu_t *c)
{
cyc_cpu_t *cpu = c->cpu_cyclic;
-
- mtx_lock_spin(&cpu->cyp_mtx);
-
+ cyc_backend_t *be = cpu->cyp_backend;
cyc_index_t *heap = cpu->cyp_heap;
cyclic_t *cyclic, *cyclics = cpu->cyp_cyclics;
+ void *arg = be->cyb_arg;
hrtime_t now = gethrtime();
hrtime_t exp;
if (cpu->cyp_nelems == 0) {
/* This is a spurious fire. */
- mtx_unlock_spin(&cpu->cyp_mtx);
return;
}
@@ -631,8 +562,45 @@ cyclic_fire(cpu_t *c)
* Now we have a cyclic in the root slot which isn't in the past;
* reprogram the interrupt source.
*/
- cyclic_reprogram(cpu, exp);
+ be->cyb_reprogram(arg, exp);
+}
+
+static void
+cyclic_expand_xcall(cyc_xcallarg_t *arg)
+{
+ cyc_cpu_t *cpu = arg->cyx_cpu;
+ cyc_index_t new_size = arg->cyx_size, size = cpu->cyp_size, i;
+ cyc_index_t *new_heap = arg->cyx_heap;
+ cyclic_t *cyclics = cpu->cyp_cyclics, *new_cyclics = arg->cyx_cyclics;
+
+ /* Disable preemption and interrupts. */
+ mtx_lock_spin(&cpu->cyp_mtx);
+
+ /*
+ * Assert that the new size is a power of 2.
+ */
+ ASSERT((new_size & (new_size - 1)) == 0);
+ ASSERT(new_size == (size << 1));
+ ASSERT(cpu->cyp_heap != NULL && cpu->cyp_cyclics != NULL);
+
+ bcopy(cpu->cyp_heap, new_heap, sizeof (cyc_index_t) * size);
+ bcopy(cyclics, new_cyclics, sizeof (cyclic_t) * size);
+
+ /*
+ * Set up the free list, and set all of the new cyclics to be CYF_FREE.
+ */
+ for (i = size; i < new_size; i++) {
+ new_heap[i] = i;
+ new_cyclics[i].cy_flags = CYF_FREE;
+ }
+ /*
+ * We can go ahead and plow the value of cyp_heap and cyp_cyclics;
+ * cyclic_expand() has kept a copy.
+ */
+ cpu->cyp_heap = new_heap;
+ cpu->cyp_cyclics = new_cyclics;
+ cpu->cyp_size = new_size;
mtx_unlock_spin(&cpu->cyp_mtx);
}
@@ -643,102 +611,70 @@ cyclic_fire(cpu_t *c)
static void
cyclic_expand(cyc_cpu_t *cpu)
{
- cyc_index_t new_size, old_size, i;
+ cyc_index_t new_size, old_size;
cyc_index_t *new_heap, *old_heap;
cyclic_t *new_cyclics, *old_cyclics;
+ cyc_xcallarg_t arg;
+ cyc_backend_t *be = cpu->cyp_backend;
ASSERT(MUTEX_HELD(&cpu_lock));
- if ((new_size = ((old_size = cpu->cyp_size) << 1)) == 0)
+ old_heap = cpu->cyp_heap;
+ old_cyclics = cpu->cyp_cyclics;
+
+ if ((new_size = ((old_size = cpu->cyp_size) << 1)) == 0) {
new_size = CY_DEFAULT_PERCPU;
+ ASSERT(old_heap == NULL && old_cyclics == NULL);
+ }
/*
* Check that the new_size is a power of 2.
*/
ASSERT(((new_size - 1) & new_size) == 0);
- /* Unlock the mutex while allocating memory so we can wait... */
- mtx_unlock_spin(&cpu->cyp_mtx);
-
new_heap = malloc(sizeof(cyc_index_t) * new_size, M_CYCLIC, M_WAITOK);
new_cyclics = malloc(sizeof(cyclic_t) * new_size, M_CYCLIC, M_ZERO | M_WAITOK);
- /* Grab the lock again now we've got the memory... */
- mtx_lock_spin(&cpu->cyp_mtx);
-
- /* Check if another thread beat us while the mutex was unlocked. */
- if (old_size != cpu->cyp_size) {
- /* Oh well, he won. */
- mtx_unlock_spin(&cpu->cyp_mtx);
-
- free(new_heap, M_CYCLIC);
- free(new_cyclics, M_CYCLIC);
-
- mtx_lock_spin(&cpu->cyp_mtx);
- return;
- }
-
- old_heap = cpu->cyp_heap;
- old_cyclics = cpu->cyp_cyclics;
-
- bcopy(cpu->cyp_heap, new_heap, sizeof (cyc_index_t) * old_size);
- bcopy(old_cyclics, new_cyclics, sizeof (cyclic_t) * old_size);
-
- /*
- * Set up the free list, and set all of the new cyclics to be CYF_FREE.
- */
- for (i = old_size; i < new_size; i++) {
- new_heap[i] = i;
- new_cyclics[i].cy_flags = CYF_FREE;
- }
+ arg.cyx_cpu = cpu;
+ arg.cyx_heap = new_heap;
+ arg.cyx_cyclics = new_cyclics;
+ arg.cyx_size = new_size;
- /*
- * We can go ahead and plow the value of cyp_heap and cyp_cyclics;
- * cyclic_expand() has kept a copy.
- */
- cpu->cyp_heap = new_heap;
- cpu->cyp_cyclics = new_cyclics;
- cpu->cyp_size = new_size;
+ be->cyb_xcall(be->cyb_arg, cpu->cyp_cpu,
+ (cyc_func_t)cyclic_expand_xcall, &arg);
if (old_cyclics != NULL) {
ASSERT(old_heap != NULL);
ASSERT(old_size != 0);
- mtx_unlock_spin(&cpu->cyp_mtx);
-
free(old_cyclics, M_CYCLIC);
free(old_heap, M_CYCLIC);
-
- mtx_lock_spin(&cpu->cyp_mtx);
}
}
-static cyc_index_t
-cyclic_add_here(cyc_cpu_t *cpu, cyc_handler_t *hdlr,
- cyc_time_t *when, uint16_t flags)
+static void
+cyclic_add_xcall(cyc_xcallarg_t *arg)
{
+ cyc_cpu_t *cpu = arg->cyx_cpu;
+ cyc_handler_t *hdlr = arg->cyx_hdlr;
+ cyc_time_t *when = arg->cyx_when;
+ cyc_backend_t *be = cpu->cyp_backend;
cyc_index_t ndx, nelems;
+ cyb_arg_t bar = be->cyb_arg;
cyclic_t *cyclic;
- ASSERT(MUTEX_HELD(&cpu_lock));
-
- mtx_lock_spin(&cpu->cyp_mtx);
-
- ASSERT(!(cpu->cyp_cpu->cpu_flags & CPU_OFFLINE));
- ASSERT(when->cyt_when >= 0 && when->cyt_interval > 0);
-
- while (cpu->cyp_nelems == cpu->cyp_size)
- cyclic_expand(cpu);
-
ASSERT(cpu->cyp_nelems < cpu->cyp_size);
+ /* Disable preemption and interrupts. */
+ mtx_lock_spin(&cpu->cyp_mtx);
nelems = cpu->cyp_nelems++;
- if (nelems == 0)
+ if (nelems == 0) {
/*
* If this is the first element, we need to enable the
* backend on this CPU.
*/
- cyclic_enable(cpu);
+ be->cyb_enable(bar);
+ }
ndx = cpu->cyp_heap[nelems];
cyclic = &cpu->cyp_cyclics[ndx];
@@ -746,14 +682,20 @@ cyclic_add_here(cyc_cpu_t *cpu, cyc_handler_t *hdlr,
ASSERT(cyclic->cy_flags == CYF_FREE);
cyclic->cy_interval = when->cyt_interval;
- if (when->cyt_when == 0)
- cyclic->cy_expire = gethrtime() + cyclic->cy_interval;
- else
+ if (when->cyt_when == 0) {
+ /*
+ * If a start time hasn't been explicitly specified, we'll
+ * start on the next interval boundary.
+ */
+ cyclic->cy_expire = (gethrtime() / cyclic->cy_interval + 1) *
+ cyclic->cy_interval;
+ } else {
cyclic->cy_expire = when->cyt_when;
+ }
cyclic->cy_handler = hdlr->cyh_func;
cyclic->cy_arg = hdlr->cyh_arg;
- cyclic->cy_flags = flags;
+ cyclic->cy_flags = arg->cyx_flags;
if (cyclic_upheap(cpu, nelems)) {
hrtime_t exp = cyclic->cy_expire;
@@ -762,31 +704,63 @@ cyclic_add_here(cyc_cpu_t *cpu, cyc_handler_t *hdlr,
* If our upheap propagated to the root, we need to
* reprogram the interrupt source.
*/
- cyclic_reprogram(cpu, exp);
+ be->cyb_reprogram(bar, exp);
}
-
mtx_unlock_spin(&cpu->cyp_mtx);
- return (ndx);
+ arg->cyx_ndx = ndx;
}
-
-static int
-cyclic_remove_here(cyc_cpu_t *cpu, cyc_index_t ndx, cyc_time_t *when, int wait)
+static cyc_index_t
+cyclic_add_here(cyc_cpu_t *cpu, cyc_handler_t *hdlr,
+ cyc_time_t *when, uint16_t flags)
{
- cyc_index_t nelems, i;
- cyclic_t *cyclic;
- cyc_index_t *heap, last;
+ cyc_backend_t *be = cpu->cyp_backend;
+ cyb_arg_t bar = be->cyb_arg;
+ cyc_xcallarg_t arg;
ASSERT(MUTEX_HELD(&cpu_lock));
- ASSERT(wait == CY_WAIT || wait == CY_NOWAIT);
+ ASSERT(!(cpu->cyp_cpu->cpu_flags & CPU_OFFLINE));
+ ASSERT(when->cyt_when >= 0 && when->cyt_interval > 0);
- mtx_lock_spin(&cpu->cyp_mtx);
+ if (cpu->cyp_nelems == cpu->cyp_size) {
+ /*
+ * This is expensive; it will cross call onto the other
+ * CPU to perform the expansion.
+ */
+ cyclic_expand(cpu);
+ ASSERT(cpu->cyp_nelems < cpu->cyp_size);
+ }
- heap = cpu->cyp_heap;
+ /*
+ * By now, we know that we're going to be able to successfully
+ * perform the add. Now cross call over to the CPU of interest to
+ * actually add our cyclic.
+ */
+ arg.cyx_cpu = cpu;
+ arg.cyx_hdlr = hdlr;
+ arg.cyx_when = when;
+ arg.cyx_flags = flags;
+
+ be->cyb_xcall(bar, cpu->cyp_cpu, (cyc_func_t)cyclic_add_xcall, &arg);
+
+ return (arg.cyx_ndx);
+}
+
+static void
+cyclic_remove_xcall(cyc_xcallarg_t *arg)
+{
+ cyc_cpu_t *cpu = arg->cyx_cpu;
+ cyc_backend_t *be = cpu->cyp_backend;
+ cyb_arg_t bar = be->cyb_arg;
+ cyc_index_t ndx = arg->cyx_ndx, nelems = cpu->cyp_nelems, i;
+ cyc_index_t *heap = cpu->cyp_heap, last;
+ cyclic_t *cyclic;
- nelems = cpu->cyp_nelems;
+ ASSERT(nelems > 0);
+ /* Disable preemption and interrupts. */
+ mtx_lock_spin(&cpu->cyp_mtx);
cyclic = &cpu->cyp_cyclics[ndx];
/*
@@ -794,11 +768,17 @@ cyclic_remove_here(cyc_cpu_t *cpu, cyc_index_t ndx, cyc_time_t *when, int wait)
* removed as part of a juggling operation, the expiration time
* will be used when the cyclic is added to the new CPU.
*/
- if (when != NULL) {
- when->cyt_when = cyclic->cy_expire;
- when->cyt_interval = cyclic->cy_interval;
+ if (arg->cyx_when != NULL) {
+ arg->cyx_when->cyt_when = cyclic->cy_expire;
+ arg->cyx_when->cyt_interval = cyclic->cy_interval;
}
+ /*
+ * Now set the flags to CYF_FREE. We don't need a membar_enter()
+ * between zeroing pend and setting the flags because we're at
+ * CY_HIGH_LEVEL (that is, the zeroing of pend and the setting
+ * of cy_flags appear atomic to softints).
+ */
cyclic->cy_flags = CYF_FREE;
for (i = 0; i < nelems; i++) {
@@ -811,19 +791,21 @@ cyclic_remove_here(cyc_cpu_t *cpu, cyc_index_t ndx, cyc_time_t *when, int wait)
cpu->cyp_nelems = --nelems;
- if (nelems == 0)
+ if (nelems == 0) {
/*
* If we just removed the last element, then we need to
* disable the backend on this CPU.
*/
- cyclic_disable(cpu);
+ be->cyb_disable(bar);
+ }
- if (i == nelems)
+ if (i == nelems) {
/*
* If we just removed the last element of the heap, then
* we don't have to downheap.
*/
- goto done;
+ goto out;
+ }
/*
* Swap the last element of the heap with the one we want to
@@ -833,17 +815,18 @@ cyclic_remove_here(cyc_cpu_t *cpu, cyc_index_t ndx, cyc_time_t *when, int wait)
heap[i] = (last = heap[nelems]);
heap[nelems] = ndx;
- if (i == 0)
+ if (i == 0) {
cyclic_downheap(cpu, 0);
- else {
+ } else {
if (cyclic_upheap(cpu, i) == 0) {
/*
* The upheap didn't propagate to the root; if it
* didn't propagate at all, we need to downheap.
*/
- if (heap[i] == last)
+ if (heap[i] == last) {
cyclic_downheap(cpu, i);
- goto done;
+ }
+ goto out;
}
}
@@ -854,10 +837,27 @@ cyclic_remove_here(cyc_cpu_t *cpu, cyc_index_t ndx, cyc_time_t *when, int wait)
cyclic = &cpu->cyp_cyclics[heap[0]];
ASSERT(nelems != 0);
- cyclic_reprogram(cpu, cyclic->cy_expire);
-
-done:
+ be->cyb_reprogram(bar, cyclic->cy_expire);
+out:
mtx_unlock_spin(&cpu->cyp_mtx);
+}
+
+static int
+cyclic_remove_here(cyc_cpu_t *cpu, cyc_index_t ndx, cyc_time_t *when, int wait)
+{
+ cyc_backend_t *be = cpu->cyp_backend;
+ cyc_xcallarg_t arg;
+
+ ASSERT(MUTEX_HELD(&cpu_lock));
+ ASSERT(wait == CY_WAIT || wait == CY_NOWAIT);
+
+ arg.cyx_ndx = ndx;
+ arg.cyx_cpu = cpu;
+ arg.cyx_when = when;
+ arg.cyx_wait = wait;
+
+ be->cyb_xcall(be->cyb_arg, cpu->cyp_cpu,
+ (cyc_func_t)cyclic_remove_xcall, &arg);
return (1);
}
@@ -1214,15 +1214,10 @@ cyclic_add_omni(cyc_omni_handler_t *omni)
idp->cyi_omni_hdlr = *omni;
- for (i = 0; i < MAXCPU; i++) {
- if (pcpu_find(i) == NULL)
- continue;
-
+ CPU_FOREACH(i) {
c = &solaris_cpu[i];
-
if ((cpu = c->cpu_cyclic) == NULL)
continue;
-
cyclic_omni_start(idp, cpu);
}
@@ -1325,12 +1320,8 @@ cyclic_mp_init(void)
mutex_enter(&cpu_lock);
- for (i = 0; i <= mp_maxid; i++) {
- if (pcpu_find(i) == NULL)
- continue;
-
+ CPU_FOREACH(i) {
c = &solaris_cpu[i];
-
if (c->cpu_cyclic == NULL)
cyclic_configure(c);
}
@@ -1346,10 +1337,8 @@ cyclic_uninit(void)
CPU_FOREACH(id) {
c = &solaris_cpu[id];
-
if (c->cpu_cyclic == NULL)
continue;
-
cyclic_unconfigure(c);
}
diff --git a/sys/cddl/dev/cyclic/i386/cyclic_machdep.c b/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
index 0b6ab59..1d0864a 100644
--- a/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
+++ b/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
@@ -121,13 +121,7 @@ static void reprogram(cyb_arg_t arg, hrtime_t exp)
static void xcall(cyb_arg_t arg, cpu_t *c, cyc_func_t func, void *param)
{
- /*
- * If the target CPU is the current one, just call the
- * function. This covers the non-SMP case.
- */
- if (c == &solaris_cpu[curcpu])
- (*func)(param);
- else
- smp_rendezvous_cpus((cpumask_t) (1 << c->cpuid), NULL,
- func, smp_no_rendevous_barrier, param);
+
+ smp_rendezvous_cpus((cpumask_t) (1 << c->cpuid), NULL,
+ func, smp_no_rendevous_barrier, param);
}
diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
index b4c7eaf..f86f535 100644
--- a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
@@ -115,26 +115,13 @@ dtrace_xcall(processorid_t cpu, dtrace_xcall_t func, void *arg)
{
cpumask_t cpus;
- critical_enter();
-
if (cpu == DTRACE_CPUALL)
cpus = all_cpus;
else
- cpus = (cpumask_t) (1 << cpu);
-
- /* If the current CPU is in the set, call the function directly: */
- if ((cpus & (1 << curcpu)) != 0) {
- (*func)(arg);
-
- /* Mask the current CPU from the set */
- cpus &= ~(1 << curcpu);
- }
-
- /* If there are any CPUs in the set, cross-call to those CPUs */
- if (cpus != 0)
- smp_rendezvous_cpus(cpus, NULL, func, smp_no_rendevous_barrier, arg);
+ cpus = (cpumask_t)1 << cpu;
- critical_exit();
+ smp_rendezvous_cpus(cpus, smp_no_rendevous_barrier, func,
+ smp_no_rendevous_barrier, arg);
}
static void
@@ -405,6 +392,7 @@ dtrace_gethrtime_init_cpu(void *arg)
static void
dtrace_gethrtime_init(void *arg)
{
+ struct pcpu *pc;
uint64_t tsc_f;
cpumask_t map;
int i;
@@ -437,15 +425,14 @@ dtrace_gethrtime_init(void *arg)
nsec_scale = ((uint64_t)NANOSEC << SCALE_SHIFT) / tsc_f;
/* The current CPU is the reference one. */
+ sched_pin();
tsc_skew[curcpu] = 0;
-
CPU_FOREACH(i) {
if (i == curcpu)
continue;
- map = 0;
- map |= (1 << curcpu);
- map |= (1 << i);
+ pc = pcpu_find(i);
+ map = PCPU_GET(cpumask) | pc->pc_cpumask;
smp_rendezvous_cpus(map, dtrace_gethrtime_init_sync,
dtrace_gethrtime_init_cpu,
@@ -453,6 +440,7 @@ dtrace_gethrtime_init(void *arg)
tsc_skew[i] = tgt_cpu_tsc - hst_cpu_tsc;
}
+ sched_unpin();
}
SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init, NULL);
diff --git a/sys/cddl/dev/dtrace/i386/dtrace_subr.c b/sys/cddl/dev/dtrace/i386/dtrace_subr.c
index 9d85873..be23808 100644
--- a/sys/cddl/dev/dtrace/i386/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/i386/dtrace_subr.c
@@ -115,26 +115,13 @@ dtrace_xcall(processorid_t cpu, dtrace_xcall_t func, void *arg)
{
cpumask_t cpus;
- critical_enter();
-
if (cpu == DTRACE_CPUALL)
cpus = all_cpus;
else
- cpus = (cpumask_t) (1 << cpu);
-
- /* If the current CPU is in the set, call the function directly: */
- if ((cpus & (1 << curcpu)) != 0) {
- (*func)(arg);
-
- /* Mask the current CPU from the set */
- cpus &= ~(1 << curcpu);
- }
-
- /* If there are any CPUs in the set, cross-call to those CPUs */
- if (cpus != 0)
- smp_rendezvous_cpus(cpus, NULL, func, smp_no_rendevous_barrier, arg);
+ cpus = (cpumask_t)1 << cpu;
- critical_exit();
+ smp_rendezvous_cpus(cpus, smp_no_rendevous_barrier, func,
+ smp_no_rendevous_barrier, arg);
}
static void
@@ -405,6 +392,7 @@ dtrace_gethrtime_init_cpu(void *arg)
static void
dtrace_gethrtime_init(void *arg)
{
+ struct pcpu *pc;
uint64_t tsc_f;
cpumask_t map;
int i;
@@ -437,15 +425,14 @@ dtrace_gethrtime_init(void *arg)
nsec_scale = ((uint64_t)NANOSEC << SCALE_SHIFT) / tsc_f;
/* The current CPU is the reference one. */
+ sched_pin();
tsc_skew[curcpu] = 0;
-
CPU_FOREACH(i) {
if (i == curcpu)
continue;
- map = 0;
- map |= (1 << curcpu);
- map |= (1 << i);
+ pc = pcpu_find(i);
+ map = PCPU_GET(cpumask) | pc->pc_cpumask;
smp_rendezvous_cpus(map, dtrace_gethrtime_init_sync,
dtrace_gethrtime_init_cpu,
@@ -453,6 +440,7 @@ dtrace_gethrtime_init(void *arg)
tsc_skew[i] = tgt_cpu_tsc - hst_cpu_tsc;
}
+ sched_unpin();
}
SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init, NULL);
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c
index 321125b..302573a 100644
--- a/sys/compat/ndis/kern_ndis.c
+++ b/sys/compat/ndis/kern_ndis.c
@@ -433,6 +433,19 @@ ndis_flush_sysctls(arg)
return (0);
}
+void *
+ndis_get_routine_address(functbl, name)
+ struct image_patch_table *functbl;
+ char *name;
+{
+ int i;
+
+ for (i = 0; functbl[i].ipt_name != NULL; i++)
+ if (strcmp(name, functbl[i].ipt_name) == 0)
+ return (functbl[i].ipt_wrap);
+ return (NULL);
+}
+
static void
ndis_return(dobj, arg)
device_object *dobj;
diff --git a/sys/compat/ndis/ndis_var.h b/sys/compat/ndis/ndis_var.h
index a66a1d7..2692e54 100644
--- a/sys/compat/ndis/ndis_var.h
+++ b/sys/compat/ndis/ndis_var.h
@@ -1729,6 +1729,7 @@ extern int ndis_mtop(struct mbuf *, ndis_packet **);
extern int ndis_ptom(struct mbuf **, ndis_packet *);
extern int ndis_get_info(void *, ndis_oid, void *, int *);
extern int ndis_set_info(void *, ndis_oid, void *, int *);
+extern void *ndis_get_routine_address(struct image_patch_table *, char *);
extern int ndis_get_supported_oids(void *, ndis_oid **, int *);
extern int ndis_send_packets(void *, ndis_packet **, int);
extern int ndis_send_packet(void *, ndis_packet *);
diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h
index 84c2a7f..2642626 100644
--- a/sys/compat/ndis/ntoskrnl_var.h
+++ b/sys/compat/ndis/ntoskrnl_var.h
@@ -1466,6 +1466,7 @@ extern uint32_t IoConnectInterrupt(kinterrupt **, void *, void *,
kspin_lock *, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t,
uint32_t, uint8_t);
extern uint8_t MmIsAddressValid(void *);
+extern void *MmGetSystemRoutineAddress(unicode_string *);
extern void *MmMapIoSpace(uint64_t, uint32_t, uint32_t);
extern void MmUnmapIoSpace(void *, size_t);
extern void MmBuildMdlForNonPagedPool(mdl *);
diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c
index a5caa88..4bdb6ef 100644
--- a/sys/compat/ndis/subr_ndis.c
+++ b/sys/compat/ndis/subr_ndis.c
@@ -197,6 +197,7 @@ static ndis_status NdisMMapIoSpace(void **, ndis_handle,
ndis_physaddr, uint32_t);
static void NdisMUnmapIoSpace(ndis_handle, void *, uint32_t);
static uint32_t NdisGetCacheFillSize(void);
+static void *NdisGetRoutineAddress(unicode_string *);
static uint32_t NdisMGetDmaAlignment(ndis_handle);
static ndis_status NdisMInitializeScatterGatherDma(ndis_handle,
uint8_t, uint32_t);
@@ -1642,6 +1643,17 @@ NdisGetCacheFillSize(void)
return (128);
}
+static void *
+NdisGetRoutineAddress(ustr)
+ unicode_string *ustr;
+{
+ ansi_string astr;
+
+ if (RtlUnicodeStringToAnsiString(&astr, ustr, TRUE))
+ return (NULL);
+ return (ndis_get_routine_address(ndis_functbl, astr.as_buf));
+}
+
static uint32_t
NdisMGetDmaAlignment(handle)
ndis_handle handle;
@@ -3246,6 +3258,7 @@ image_patch_table ndis_functbl[] = {
IMPORT_SFUNC(NdisInitializeString, 2),
IMPORT_SFUNC(NdisFreeString, 1),
IMPORT_SFUNC(NdisGetCurrentSystemTime, 1),
+ IMPORT_SFUNC(NdisGetRoutineAddress, 1),
IMPORT_SFUNC(NdisGetSystemUpTime, 1),
IMPORT_SFUNC(NdisGetVersion, 0),
IMPORT_SFUNC(NdisMSynchronizeWithInterrupt, 3),
diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c
index c523f8b..17016e0 100644
--- a/sys/compat/ndis/subr_ntoskrnl.c
+++ b/sys/compat/ndis/subr_ntoskrnl.c
@@ -2589,6 +2589,17 @@ MmGetPhysicalAddress(void *base)
return (pmap_extract(kernel_map->pmap, (vm_offset_t)base));
}
+void *
+MmGetSystemRoutineAddress(ustr)
+ unicode_string *ustr;
+{
+ ansi_string astr;
+
+ if (RtlUnicodeStringToAnsiString(&astr, ustr, TRUE))
+ return (NULL);
+ return (ndis_get_routine_address(ntoskrnl_functbl, astr.as_buf));
+}
+
uint8_t
MmIsAddressValid(vaddr)
void *vaddr;
@@ -4382,6 +4393,7 @@ image_patch_table ntoskrnl_functbl[] = {
IMPORT_SFUNC(MmUnmapLockedPages, 2),
IMPORT_SFUNC(MmBuildMdlForNonPagedPool, 1),
IMPORT_SFUNC(MmGetPhysicalAddress, 1),
+ IMPORT_SFUNC(MmGetSystemRoutineAddress, 1),
IMPORT_SFUNC(MmIsAddressValid, 1),
IMPORT_SFUNC(MmMapIoSpace, 3 + 1),
IMPORT_SFUNC(MmUnmapIoSpace, 2),
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 470aca5..2b56a15 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -97,7 +97,6 @@ amd64/amd64/atomic.c standard
amd64/amd64/autoconf.c standard
amd64/amd64/bios.c standard
amd64/amd64/bpf_jit_machdep.c optional bpf_jitter
-amd64/amd64/busdma_machdep.c standard
amd64/amd64/cpu_switch.S standard
amd64/amd64/db_disasm.c optional ddb
amd64/amd64/db_interface.c optional ddb
@@ -126,7 +125,6 @@ amd64/amd64/stack_machdep.c optional ddb | stack
amd64/amd64/support.S standard
amd64/amd64/sys_machdep.c standard
amd64/amd64/trap.c standard
-amd64/amd64/tsc.c standard
amd64/amd64/uio_machdep.c standard
amd64/amd64/uma_machdep.c standard
amd64/amd64/vm_machdep.c standard
@@ -318,6 +316,7 @@ x86/isa/isa_dma.c standard
x86/isa/nmi.c standard
x86/isa/orm.c optional isa
x86/pci/qpi.c standard
+x86/x86/busdma_machdep.c standard
x86/x86/dump_machdep.c standard
x86/x86/io_apic.c standard
x86/x86/local_apic.c standard
@@ -326,3 +325,4 @@ x86/x86/mptable.c optional mptable
x86/x86/mptable_pci.c optional mptable pci
x86/x86/msi.c optional pci
x86/x86/nexus.c standard
+x86/x86/tsc.c standard
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index c6a3260..179306b 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -272,7 +272,6 @@ i386/i386/autoconf.c standard
i386/i386/bios.c optional native
i386/i386/bioscall.s optional native
i386/i386/bpf_jit_machdep.c optional bpf_jitter
-i386/i386/busdma_machdep.c standard
i386/i386/db_disasm.c optional ddb
i386/i386/db_interface.c optional ddb
i386/i386/db_trace.c optional ddb
@@ -312,7 +311,6 @@ i386/i386/support.s standard
i386/i386/swtch.s standard
i386/i386/sys_machdep.c standard
i386/i386/trap.c standard
-i386/i386/tsc.c standard
i386/i386/uio_machdep.c standard
i386/i386/vm86.c standard
i386/i386/vm_machdep.c standard
@@ -407,6 +405,7 @@ x86/isa/isa_dma.c optional isa
x86/isa/nmi.c standard
x86/isa/orm.c optional isa
x86/pci/qpi.c standard
+x86/x86/busdma_machdep.c standard
x86/x86/dump_machdep.c standard
x86/x86/io_apic.c optional apic
x86/x86/local_apic.c optional apic
@@ -415,3 +414,4 @@ x86/x86/mptable.c optional apic native
x86/x86/mptable_pci.c optional apic pci
x86/x86/msi.c optional apic pci
x86/x86/nexus.c standard
+x86/x86/tsc.c standard
diff --git a/sys/conf/files.mips b/sys/conf/files.mips
index 61a9295..e5949d2 100644
--- a/sys/conf/files.mips
+++ b/sys/conf/files.mips
@@ -63,6 +63,7 @@ mips/mips/support.S standard
mips/mips/sys_machdep.c standard
mips/mips/swtch.S standard
mips/mips/uio_machdep.c standard
+mips/mips/uma_machdep.c standard
crypto/blowfish/bf_enc.c optional crypto | ipsec
crypto/des/des_enc.c optional crypto | ipsec | netsmb
geom/geom_bsd.c optional geom_bsd
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index ab88e22..158fbbd 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -134,7 +134,6 @@ i386/i386/autoconf.c standard
i386/i386/bios.c standard
i386/i386/bioscall.s standard
i386/i386/bpf_jit_machdep.c optional bpf_jitter
-i386/i386/busdma_machdep.c standard
i386/i386/db_disasm.c optional ddb
i386/i386/db_interface.c optional ddb
i386/i386/db_trace.c optional ddb
@@ -164,7 +163,6 @@ i386/i386/support.s standard
i386/i386/swtch.s standard
i386/i386/sys_machdep.c standard
i386/i386/trap.c standard
-i386/i386/tsc.c standard
i386/i386/uio_machdep.c standard
i386/i386/vm86.c standard
i386/i386/vm_machdep.c standard
@@ -251,6 +249,7 @@ pc98/pc98/pc98_machdep.c standard
x86/isa/atpic.c optional atpic
x86/isa/clock.c standard
x86/isa/isa.c optional isa
+x86/x86/busdma_machdep.c standard
x86/x86/dump_machdep.c standard
x86/x86/io_apic.c optional apic
x86/x86/local_apic.c optional apic
@@ -259,3 +258,4 @@ x86/x86/mptable.c optional apic
x86/x86/mptable_pci.c optional apic pci
x86/x86/msi.c optional apic pci
x86/x86/nexus.c standard
+x86/x86/tsc.c standard
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index d46b39f..4856715 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -83,6 +83,8 @@ powerpc/aim/locore.S optional aim no-obj
powerpc/aim/machdep.c optional aim
powerpc/aim/mmu_oea.c optional aim powerpc
powerpc/aim/mmu_oea64.c optional aim
+powerpc/aim/moea64_if.m optional aim
+powerpc/aim/moea64_native.c optional aim
powerpc/aim/mp_cpudep.c optional aim smp
powerpc/aim/nexus.c optional aim
powerpc/aim/ofwmagic.S optional aim
@@ -177,6 +179,7 @@ powerpc/powerpc/fuswintr.c standard
powerpc/powerpc/gdb_machdep.c optional gdb
powerpc/powerpc/in_cksum.c optional inet
powerpc/powerpc/intr_machdep.c standard
+powerpc/powerpc/iommu_if.m standard
powerpc/powerpc/mem.c optional mem
powerpc/powerpc/mmu_if.m standard
powerpc/powerpc/mp_machdep.c optional smp
diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c
index 44f4e19..130cd20 100644
--- a/sys/dev/aac/aac_cam.c
+++ b/sys/dev/aac/aac_cam.c
@@ -587,7 +587,8 @@ aac_cam_complete(struct aac_command *cm)
(device == T_PROCESSOR) ||
(sc->flags & AAC_FLAGS_CAM_PASSONLY))
ccb->csio.data_ptr[0] =
- ((device & 0xe0) | T_NODEVICE);
+ ((ccb->csio.data_ptr[0] & 0xe0) |
+ T_NODEVICE);
} else if (ccb->ccb_h.status == CAM_SEL_TIMEOUT &&
ccb->ccb_h.target_lun != 0) {
/* fix for INQUIRYs on Lun>0 */
diff --git a/sys/dev/acpica/acpi_hpet.c b/sys/dev/acpica/acpi_hpet.c
index efe5747..97fe991 100644
--- a/sys/dev/acpica/acpi_hpet.c
+++ b/sys/dev/acpica/acpi_hpet.c
@@ -303,6 +303,23 @@ hpet_find(ACPI_HANDLE handle, UINT32 level, void *context,
return (AE_OK);
}
+/*
+ * Find an existing IRQ resource that matches the requested IRQ range
+ * and return its RID. If one is not found, use a new RID.
+ */
+static int
+hpet_find_irq_rid(device_t dev, u_long start, u_long end)
+{
+ u_long irq;
+ int error, rid;
+
+ for (rid = 0;; rid++) {
+ error = bus_get_resource(dev, SYS_RES_IRQ, rid, &irq, NULL);
+ if (error != 0 || (start <= irq && irq <= end))
+ return (rid);
+ }
+}
+
/* Discover the HPET via the ACPI table of the same name. */
static void
hpet_identify(driver_t *driver, device_t parent)
@@ -540,6 +557,7 @@ hpet_attach(device_t dev)
dvectors &= ~(1 << t->irq);
}
if (t->irq >= 0) {
+ t->intr_rid = hpet_find_irq_rid(dev, t->irq, t->irq);
if (!(t->intr_res =
bus_alloc_resource(dev, SYS_RES_IRQ, &t->intr_rid,
t->irq, t->irq, 1, RF_ACTIVE))) {
@@ -590,12 +608,12 @@ hpet_attach(device_t dev)
}
bus_write_4(sc->mem_res, HPET_ISR, 0xffffffff);
sc->irq = -1;
- sc->intr_rid = -1;
/* If at least one timer needs legacy IRQ - set it up. */
if (sc->useirq) {
j = i = fls(cvectors) - 1;
while (j > 0 && (cvectors & (1 << (j - 1))) != 0)
j--;
+ sc->intr_rid = hpet_find_irq_rid(dev, j, i);
if (!(sc->intr_res = bus_alloc_resource(dev, SYS_RES_IRQ,
&sc->intr_rid, j, i, 1, RF_SHAREABLE | RF_ACTIVE)))
device_printf(dev,"Can't map interrupt.\n");
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 4b93d9b..f767215 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -172,6 +172,10 @@ static struct {
{0x614511ab, 0x00, "Marvell 88SX6145", AHCI_Q_NOFORCE|AHCI_Q_4CH|AHCI_Q_EDGEIS},
{0x91231b4b, 0x11, "Marvell 88SE912x", AHCI_Q_NOBSYRES},
{0x91231b4b, 0x00, "Marvell 88SE912x", AHCI_Q_EDGEIS|AHCI_Q_SATA2|AHCI_Q_NOBSYRES},
+ {0x06201103, 0x00, "HighPoint RocketRAID 620", AHCI_Q_NOBSYRES},
+ {0x06201b4b, 0x00, "HighPoint RocketRAID 620", AHCI_Q_NOBSYRES},
+ {0x06221103, 0x00, "HighPoint RocketRAID 622", AHCI_Q_NOBSYRES},
+ {0x06221b4b, 0x00, "HighPoint RocketRAID 622", AHCI_Q_NOBSYRES},
{0x044c10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
{0x044d10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
{0x044e10de, 0x00, "NVIDIA MCP65", AHCI_Q_NOAA},
diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
index 587b734..b2f72f5 100644
--- a/sys/dev/bwn/if_bwn.c
+++ b/sys/dev/bwn/if_bwn.c
@@ -2882,7 +2882,7 @@ bwn_set_channel(struct ieee80211com *ic)
error = bwn_switch_band(sc, ic->ic_curchan);
if (error)
- goto fail;;
+ goto fail;
bwn_mac_suspend(mac);
bwn_set_txretry(mac, BWN_RETRY_SHORT, BWN_RETRY_LONG);
chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
@@ -8260,7 +8260,7 @@ bwn_switch_band(struct bwn_softc *sc, struct ieee80211_channel *chan)
device_printf(sc->sc_dev, "switching to %s-GHz band\n",
IEEE80211_IS_CHAN_2GHZ(chan) ? "2" : "5");
- down_dev = sc->sc_curmac;;
+ down_dev = sc->sc_curmac;
status = down_dev->mac_status;
if (status >= BWN_MAC_STATUS_STARTED)
bwn_core_stop(down_dev);
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 6728a98..4cfda7f 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -525,7 +525,7 @@ em_attach(device_t dev)
/* Sysctl for setting the interface flow control */
em_set_flow_cntrl(adapter, "flow_control",
- "max number of rx packets to process",
+ "configure flow control",
&adapter->fc_setting, em_fc_setting);
/*
@@ -3751,46 +3751,43 @@ em_refresh_mbufs(struct rx_ring *rxr, int limit)
cleaned = -1;
while (i != limit) {
rxbuf = &rxr->rx_buffers[i];
- /*
- ** Just skip entries with a buffer,
- ** they can only be due to an error
- ** and are to be reused.
- */
- if (rxbuf->m_head != NULL)
- goto reuse;
- m = m_getjcl(M_DONTWAIT, MT_DATA,
- M_PKTHDR, adapter->rx_mbuf_sz);
- /*
- ** If we have a temporary resource shortage
- ** that causes a failure, just abort refresh
- ** for now, we will return to this point when
- ** reinvoked from em_rxeof.
- */
- if (m == NULL)
- goto update;
+ if (rxbuf->m_head == NULL) {
+ m = m_getjcl(M_DONTWAIT, MT_DATA,
+ M_PKTHDR, adapter->rx_mbuf_sz);
+ /*
+ ** If we have a temporary resource shortage
+ ** that causes a failure, just abort refresh
+ ** for now, we will return to this point when
+ ** reinvoked from em_rxeof.
+ */
+ if (m == NULL)
+ goto update;
+ } else
+ m = rxbuf->m_head;
+
m->m_len = m->m_pkthdr.len = adapter->rx_mbuf_sz;
+ m->m_flags |= M_PKTHDR;
+ m->m_data = m->m_ext.ext_buf;
/* Use bus_dma machinery to setup the memory mapping */
error = bus_dmamap_load_mbuf_sg(rxr->rxtag, rxbuf->map,
m, segs, &nsegs, BUS_DMA_NOWAIT);
if (error != 0) {
+ printf("Refresh mbufs: hdr dmamap load"
+ " failure - %d\n", error);
m_free(m);
+ rxbuf->m_head = NULL;
goto update;
}
-
- /* If nsegs is wrong then the stack is corrupt. */
- KASSERT(nsegs == 1, ("Too many segments returned!"));
-
+ rxbuf->m_head = m;
bus_dmamap_sync(rxr->rxtag,
rxbuf->map, BUS_DMASYNC_PREREAD);
- rxbuf->m_head = m;
rxr->rx_base[i].buffer_addr = htole64(segs[0].ds_addr);
-reuse:
+
cleaned = i;
/* Calculate next index */
if (++i == adapter->num_rx_desc)
i = 0;
- /* This is the work marker for refresh */
rxr->next_to_refresh = i;
}
update:
@@ -4208,8 +4205,8 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
len = le16toh(cur->length);
eop = (status & E1000_RXD_STAT_EOP) != 0;
- if ((rxr->discard == TRUE) || (cur->errors &
- E1000_RXD_ERR_FRAME_ERR_MASK)) {
+ if ((cur->errors & E1000_RXD_ERR_FRAME_ERR_MASK) ||
+ (rxr->discard == TRUE)) {
ifp->if_ierrors++;
++rxr->rx_discarded;
if (!eop) /* Catch subsequent segs */
@@ -4306,9 +4303,7 @@ next_desc:
static __inline void
em_rx_discard(struct rx_ring *rxr, int i)
{
- struct adapter *adapter = rxr->adapter;
struct em_buffer *rbuf;
- struct mbuf *m;
rbuf = &rxr->rx_buffers[i];
/* Free any previous pieces */
@@ -4318,14 +4313,14 @@ em_rx_discard(struct rx_ring *rxr, int i)
rxr->fmp = NULL;
rxr->lmp = NULL;
}
-
- /* Reset state, keep loaded DMA map and reuse */
- m = rbuf->m_head;
- m->m_len = m->m_pkthdr.len = adapter->rx_mbuf_sz;
- m->m_flags |= M_PKTHDR;
- m->m_data = m->m_ext.ext_buf;
- m->m_next = NULL;
-
+ /*
+ ** Free buffer and allow em_refresh_mbufs()
+ ** to clean up and recharge buffer.
+ */
+ if (rbuf->m_head) {
+ m_free(rbuf->m_head);
+ rbuf->m_head = NULL;
+ }
return;
}
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index 14ccede..ff3c2cf 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -3429,8 +3429,6 @@ igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp)
case ETHERTYPE_IPV6:
ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
ip_hlen = sizeof(struct ip6_hdr);
- if (mp->m_len < ehdrlen + ip_hlen)
- return (FALSE);
ipproto = ip6->ip6_nxt;
type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV6;
break;
diff --git a/sys/dev/ichwd/ichwd.c b/sys/dev/ichwd/ichwd.c
index 9ddec20..c64468a 100644
--- a/sys/dev/ichwd/ichwd.c
+++ b/sys/dev/ichwd/ichwd.c
@@ -288,30 +288,23 @@ static __inline void
ichwd_tmr_set(struct ichwd_softc *sc, unsigned int timeout)
{
- /*
- * If the datasheets are to be believed, the minimum value
- * actually varies from chipset to chipset - 4 for ICH5 and 2 for
- * all other chipsets. I suspect this is a bug in the ICH5
- * datasheet and that the minimum is uniformly 2, but I'd rather
- * err on the side of caution.
- */
- if (timeout < 4)
- timeout = 4;
+ if (timeout < TCO_RLD_TMR_MIN)
+ timeout = TCO_RLD_TMR_MIN;
if (sc->ich_version <= 5) {
uint8_t tmr_val8 = ichwd_read_tco_1(sc, TCO_TMR1);
- tmr_val8 &= 0xc0;
- if (timeout > 0x3f)
- timeout = 0x3f;
+ tmr_val8 &= (~TCO_RLD1_TMR_MAX & 0xff);
+ if (timeout > TCO_RLD1_TMR_MAX)
+ timeout = TCO_RLD1_TMR_MAX;
tmr_val8 |= timeout;
ichwd_write_tco_1(sc, TCO_TMR1, tmr_val8);
} else {
uint16_t tmr_val16 = ichwd_read_tco_2(sc, TCO_TMR2);
- tmr_val16 &= 0xfc00;
- if (timeout > 0x03ff)
- timeout = 0x03ff;
+ tmr_val16 &= (~TCO_RLD2_TMR_MAX & 0xffff);
+ if (timeout > TCO_RLD2_TMR_MAX)
+ timeout = TCO_RLD2_TMR_MAX;
tmr_val16 |= timeout;
ichwd_write_tco_2(sc, TCO_TMR2, tmr_val16);
}
@@ -520,8 +513,9 @@ ichwd_attach(device_t dev)
device_get_desc(dev), sc->ich_version);
/*
- * Determine if we are coming up after a watchdog-induced reset.
- * This bit is cleared in ichwd_sts_reset().
+ * Determine if we are coming up after a watchdog-induced reset. Some
+ * BIOSes may clear this bit at bootup, preventing us from reporting
+ * this case on such systems. We clear this bit in ichwd_sts_reset().
*/
if ((ichwd_read_tco_2(sc, TCO2_STS) & TCO_SECOND_TO_STS) != 0)
device_printf(dev,
diff --git a/sys/dev/ichwd/ichwd.h b/sys/dev/ichwd/ichwd.h
index c0a1141..442460b 100644
--- a/sys/dev/ichwd/ichwd.h
+++ b/sys/dev/ichwd/ichwd.h
@@ -199,6 +199,17 @@ struct ichwd_softc {
#define TCO_TMR_HALT 0x0800 /* clear to enable WDT */
#define TCO_CNT_PRESERVE 0x0200 /* preserve these bits */
+/*
+ * Masks for the TCO timer value field in TCO_RLD.
+ * If the datasheets are to be believed, the minimum value actually varies
+ * from chipset to chipset - 4 for ICH5 and 2 for all other chipsets.
+ * I suspect this is a bug in the ICH5 datasheet and that the minimum is
+ * uniformly 2, but I'd rather err on the side of caution.
+ */
+#define TCO_RLD_TMR_MIN 0x0004
+#define TCO_RLD1_TMR_MAX 0x003f
+#define TCO_RLD2_TMR_MAX 0x03ff
+
/* approximate length in nanoseconds of one WDT tick (about 0.6 sec) */
#define ICHWD_TICK 600000000
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index 1d58ef8..a59d8fd 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -223,7 +223,7 @@ static int iwn5000_save_calib_result(struct iwn_softc *,
struct iwn_phy_calib *, int, int);
static void iwn5000_free_calib_results(struct iwn_softc *);
static int iwn5000_chrystal_calib(struct iwn_softc *);
-static int iwn5000_send_calib_query(struct iwn_softc *);
+static int iwn5000_send_calib_query(struct iwn_softc *, uint32_t);
static int iwn5000_rx_calib_result(struct iwn_softc *,
struct iwn_rx_desc *, struct iwn_rx_data *);
static int iwn5000_send_wimax_coex(struct iwn_softc *);
@@ -756,6 +756,7 @@ iwn_hal_attach(struct iwn_softc *sc)
default:
sc->txchainmask = IWN_ANT_ABC;
sc->rxchainmask = IWN_ANT_ABC;
+ sc->calib_runtime = IWN_CALIB_DC;
break;
}
sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |
@@ -767,8 +768,9 @@ iwn_hal_attach(struct iwn_softc *sc)
sc->fwname = "iwn6050fw";
sc->txchainmask = IWN_ANT_AB;
sc->rxchainmask = IWN_ANT_AB;
- sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_DC | IWN_CALIB_LO |
+ sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |
IWN_CALIB_TX_IQ | IWN_CALIB_BASE_BAND;
+ sc->calib_runtime = IWN_CALIB_DC;
break;
case IWN_HW_REV_TYPE_6005:
sc->sc_hal = &iwn5000_hal;
@@ -778,6 +780,7 @@ iwn_hal_attach(struct iwn_softc *sc)
sc->rxchainmask = IWN_ANT_AB;
sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |
IWN_CALIB_TX_IQ | IWN_CALIB_BASE_BAND;
+ sc->calib_runtime = IWN_CALIB_DC;
break;
default:
device_printf(sc->sc_dev, "adapter type %d not supported\n",
@@ -1980,7 +1983,8 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/*
* RUN -> RUN transition; Just restart the timers.
*/
- if (vap->iv_state == IEEE80211_S_RUN) {
+ if (vap->iv_state == IEEE80211_S_RUN &&
+ vap->iv_opmode != IEEE80211_M_MONITOR) {
iwn_calib_reset(sc);
break;
}
@@ -4848,11 +4852,9 @@ iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
struct iwn_node_info node;
int error;
- sc->calib.state = IWN_CALIB_STATE_INIT;
-
if (ic->ic_opmode == IEEE80211_M_MONITOR) {
/* Link LED blinks while monitoring. */
- iwn_set_led(sc, IWN_LED_LINK, 5, 5);
+ iwn_set_led(sc, IWN_LED_LINK, 20, 20);
return 0;
}
error = iwn_set_timing(sc, ni);
@@ -5316,7 +5318,7 @@ iwn5000_chrystal_calib(struct iwn_softc *sc)
* only once at first boot.
*/
static int
-iwn5000_send_calib_query(struct iwn_softc *sc)
+iwn5000_send_calib_query(struct iwn_softc *sc, uint32_t cfg)
{
#define CALIB_INIT_CFG 0xffffffff;
struct iwn5000_calib_config cmd;
@@ -5324,12 +5326,15 @@ iwn5000_send_calib_query(struct iwn_softc *sc)
memset(&cmd, 0, sizeof cmd);
cmd.ucode.once.enable = CALIB_INIT_CFG;
- cmd.ucode.once.start = CALIB_INIT_CFG;
- cmd.ucode.once.send = CALIB_INIT_CFG;
- cmd.ucode.flags = CALIB_INIT_CFG;
+ if (cfg == 0) {
+ cmd.ucode.once.start = CALIB_INIT_CFG;
+ cmd.ucode.once.send = CALIB_INIT_CFG;
+ cmd.ucode.flags = CALIB_INIT_CFG;
+ } else
+ cmd.ucode.once.start = cfg;
- DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: query calibration results\n",
- __func__);
+ DPRINTF(sc, IWN_DEBUG_CALIBRATE,
+ "%s: query calibration results, cfg %x\n", __func__, cfg);
error = iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof cmd, 0);
if (error != 0)
@@ -5559,7 +5564,7 @@ iwn5000_post_alive(struct iwn_softc *sc)
* Query other calibration results from the initialization
* firmware.
*/
- error = iwn5000_send_calib_query(sc);
+ error = iwn5000_send_calib_query(sc, 0);
if (error != 0) {
device_printf(sc->sc_dev,
"%s: could not query calibration, error=%d\n",
@@ -5579,6 +5584,19 @@ iwn5000_post_alive(struct iwn_softc *sc)
* firmware to the runtime firmware.
*/
error = iwn5000_send_calib_results(sc);
+
+ /*
+ * Tell the runtime firmware to do certain calibration types.
+ */
+ if (sc->calib_runtime != 0) {
+ error = iwn5000_send_calib_query(sc, sc->calib_runtime);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "%s: could not send query calibration, "
+ "error=%d, cfg=%x\n", __func__, error,
+ sc->calib_runtime);
+ }
+ }
}
return error;
}
diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
index f8b45b6..deb0be7 100644
--- a/sys/dev/iwn/if_iwnvar.h
+++ b/sys/dev/iwn/if_iwnvar.h
@@ -264,6 +264,7 @@ struct iwn_softc {
int calib_cnt;
struct iwn_calib_state calib;
u_int calib_init;
+ u_int calib_runtime;
#define IWN_CALIB_XTAL (1 << IWN_CALIB_IDX_XTAL)
#define IWN_CALIB_DC (1 << IWN_CALIB_IDX_DC)
#define IWN_CALIB_LO (1 << IWN_CALIB_IDX_LO)
diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c
index 338172a..e246bf3 100644
--- a/sys/dev/ixgbe/ixgbe.c
+++ b/sys/dev/ixgbe/ixgbe.c
@@ -46,7 +46,7 @@ int ixgbe_display_debug_stats = 0;
/*********************************************************************
* Driver version
*********************************************************************/
-char ixgbe_driver_version[] = "2.3.6";
+char ixgbe_driver_version[] = "2.3.7";
/*********************************************************************
* PCI Device ID Table
@@ -3023,16 +3023,12 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp)
case ETHERTYPE_IP:
ip = (struct ip *)(mp->m_data + ehdrlen);
ip_hlen = ip->ip_hl << 2;
- if (mp->m_len < ehdrlen + ip_hlen)
- return (FALSE);
ipproto = ip->ip_p;
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
break;
case ETHERTYPE_IPV6:
ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
ip_hlen = sizeof(struct ip6_hdr);
- if (mp->m_len < ehdrlen + ip_hlen)
- return (FALSE);
ipproto = ip6->ip6_nxt;
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6;
break;
diff --git a/sys/dev/mfi/mfi_cam.c b/sys/dev/mfi/mfi_cam.c
index fe1ffe5..5137c36 100644
--- a/sys/dev/mfi/mfi_cam.c
+++ b/sys/dev/mfi/mfi_cam.c
@@ -340,14 +340,14 @@ mfip_done(struct mfi_command *cm)
ccbh->status = CAM_REQ_CMP;
csio->scsi_status = pt->header.scsi_status;
if (ccbh->flags & CAM_CDB_POINTER)
- command = ccb->csio.cdb_io.cdb_ptr[0];
+ command = csio->cdb_io.cdb_ptr[0];
else
- command = ccb->csio.cdb_io.cdb_bytes[0];
+ command = csio->cdb_io.cdb_bytes[0];
if (command == INQUIRY) {
- device = ccb->csio.data_ptr[0] & 0x1f;
+ device = csio->data_ptr[0] & 0x1f;
if ((device == T_DIRECT) || (device == T_PROCESSOR))
csio->data_ptr[0] =
- (device & 0xe0) | T_NODEVICE;
+ (csio->data_ptr[0] & 0xe0) | T_NODEVICE;
}
break;
}
diff --git a/sys/dev/mps/mps.c b/sys/dev/mps/mps.c
index 1fb37e2..61cbaa6 100644
--- a/sys/dev/mps/mps.c
+++ b/sys/dev/mps/mps.c
@@ -1282,7 +1282,7 @@ mps_dispatch_event(struct mps_softc *sc, uintptr_t data,
MPI2_EVENT_NOTIFICATION_REPLY *reply)
{
struct mps_event_handle *eh;
- int event, handled = 0;;
+ int event, handled = 0;
event = reply->Event;
TAILQ_FOREACH(eh, &sc->event_list, eh_list) {
diff --git a/sys/dev/siba/siba_bwn.c b/sys/dev/siba/siba_bwn.c
index b335484..1e0ba0d 100644
--- a/sys/dev/siba/siba_bwn.c
+++ b/sys/dev/siba/siba_bwn.c
@@ -326,7 +326,7 @@ static int
siba_bwn_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct siba_dev_softc *sd;
- struct siba_softc *siba;;
+ struct siba_softc *siba;
sd = device_get_ivars(child);
siba = sd->sd_bus;
diff --git a/sys/dev/sis/if_sisreg.h b/sys/dev/sis/if_sisreg.h
index 28d4390..058d9e7 100644
--- a/sys/dev/sis/if_sisreg.h
+++ b/sys/dev/sis/if_sisreg.h
@@ -497,7 +497,7 @@ struct sis_softc {
int sis_tx_prod;
int sis_tx_cons;
int sis_tx_cnt;
- int sis_rx_cons;;
+ int sis_rx_cons;
bus_addr_t sis_rx_paddr;
bus_addr_t sis_tx_paddr;
struct callout sis_stat_ch;
diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c
index 98dac91..8be6fc8 100644
--- a/sys/dev/usb/net/if_axe.c
+++ b/sys/dev/usb/net/if_axe.c
@@ -200,7 +200,8 @@ static const struct usb_config axe_config[AXE_N_TRANSFER] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
- .bufsize = AXE_BULK_BUF_SIZE,
+ .frames = 16,
+ .bufsize = 16 * MCLBYTES,
.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
.callback = axe_bulk_write_callback,
.timeout = 10000, /* 10 seconds */
@@ -939,7 +940,7 @@ axe_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
struct ifnet *ifp = uether_getifp(&sc->sc_ue);
struct usb_page_cache *pc;
struct mbuf *m;
- int pos;
+ int nframes, pos;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
@@ -956,40 +957,34 @@ tr_setup:
*/
return;
}
- pos = 0;
- pc = usbd_xfer_get_frame(xfer, 0);
-
- while (1) {
+ for (nframes = 0; nframes < 16 &&
+ !IFQ_DRV_IS_EMPTY(&ifp->if_snd); nframes++) {
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
-
- if (m == NULL) {
- if (pos > 0)
- break; /* send out data */
- return;
- }
- if (m->m_pkthdr.len > MCLBYTES) {
- m->m_pkthdr.len = MCLBYTES;
- }
+ if (m == NULL)
+ break;
+ usbd_xfer_set_frame_offset(xfer, nframes * MCLBYTES,
+ nframes);
+ pos = 0;
+ pc = usbd_xfer_get_frame(xfer, nframes);
if (AXE_IS_178_FAMILY(sc)) {
-
hdr.len = htole16(m->m_pkthdr.len);
hdr.ilen = ~hdr.len;
-
usbd_copy_in(pc, pos, &hdr, sizeof(hdr));
-
pos += sizeof(hdr);
-
- /*
- * NOTE: Some drivers force a short packet
- * by appending a dummy header with zero
- * length at then end of the USB transfer.
- * This driver uses the
- * USB_FORCE_SHORT_XFER flag instead.
- */
+ usbd_m_copy_in(pc, pos, m, 0, m->m_pkthdr.len);
+ pos += m->m_pkthdr.len;
+ if ((pos % 512) == 0) {
+ hdr.len = 0;
+ hdr.ilen = 0xffff;
+ usbd_copy_in(pc, pos, &hdr,
+ sizeof(hdr));
+ pos += sizeof(hdr);
+ }
+ } else {
+ usbd_m_copy_in(pc, pos, m, 0, m->m_pkthdr.len);
+ pos += m->m_pkthdr.len;
}
- usbd_m_copy_in(pc, pos, m, 0, m->m_pkthdr.len);
- pos += m->m_pkthdr.len;
/*
* XXX
@@ -1010,22 +1005,16 @@ tr_setup:
m_freem(m);
- if (AXE_IS_178_FAMILY(sc)) {
- if (pos > (AXE_BULK_BUF_SIZE - MCLBYTES - sizeof(hdr))) {
- /* send out frame(s) */
- break;
- }
- } else {
- /* send out frame */
- break;
- }
+ /* Set frame length. */
+ usbd_xfer_set_frame_len(xfer, nframes, pos);
+ }
+ if (nframes != 0) {
+ usbd_xfer_set_frames(xfer, nframes);
+ usbd_transfer_submit(xfer);
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
}
-
- usbd_xfer_set_frame_len(xfer, 0, pos);
- usbd_transfer_submit(xfer);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return;
-
+ /* NOTREACHED */
default: /* Error */
DPRINTFN(11, "transfer error, %s\n",
usbd_errstr(error));
diff --git a/sys/dev/usb/usb_pf.c b/sys/dev/usb/usb_pf.c
index 4ac0eeb..2658907 100644
--- a/sys/dev/usb/usb_pf.c
+++ b/sys/dev/usb/usb_pf.c
@@ -64,6 +64,7 @@ usbpf_attach(struct usb_bus *ubus)
ifp = ubus->ifp = if_alloc(IFT_USB);
if_initname(ifp, "usbus", device_get_unit(ubus->bdev));
+ ifp->if_flags = IFF_CANTCONFIG;
if_attach(ifp);
if_up(ifp);
diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c
index 60767388..293c4bf 100644
--- a/sys/dev/usb/usb_request.c
+++ b/sys/dev/usb/usb_request.c
@@ -793,6 +793,10 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
if (err) {
goto done;
}
+ /* if the device disappeared, just give up */
+ if (!(UGETW(ps.wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) {
+ goto done;
+ }
/* check if reset is complete */
if (UGETW(ps.wPortChange) & UPS_C_PORT_RESET) {
break;
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index f6edc91..72d5910 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -1248,8 +1248,25 @@ wpi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
IEEE80211_UNLOCK(ic);
WPI_LOCK(sc);
- if (nstate == IEEE80211_S_AUTH) {
- /* The node must be registered in the firmware before auth */
+ if (nstate == IEEE80211_S_SCAN && vap->iv_state != IEEE80211_S_INIT) {
+ /*
+ * On !INIT -> SCAN transitions, we need to clear any possible
+ * knowledge about associations.
+ */
+ error = wpi_config(sc);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "%s: device config failed, error %d\n",
+ __func__, error);
+ }
+ }
+ if (nstate == IEEE80211_S_AUTH ||
+ (nstate == IEEE80211_S_ASSOC && vap->iv_state == IEEE80211_S_RUN)) {
+ /*
+ * The node must be registered in the firmware before auth.
+ * Also the associd must be cleared on RUN -> ASSOC
+ * transitions.
+ */
error = wpi_auth(sc, vap);
if (error != 0) {
device_printf(sc->sc_dev,
diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c
index 8ff8757..2e08bb1 100644
--- a/sys/dev/xen/blkfront/blkfront.c
+++ b/sys/dev/xen/blkfront/blkfront.c
@@ -508,7 +508,7 @@ blkfront_initialize(struct xb_softc *sc)
sc->ring_pages = 1;
sc->max_requests = BLKIF_MAX_RING_REQUESTS(PAGE_SIZE);
sc->max_request_segments = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
- sc->max_request_size = sc->max_request_segments * PAGE_SIZE;
+ sc->max_request_size = (sc->max_request_segments - 1) * PAGE_SIZE;
sc->max_request_blocks = BLKIF_SEGS_TO_BLOCKS(sc->max_request_segments);
/*
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 908c028..9f657d6 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -147,12 +147,20 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
if (nfsrv_openpluslock > NFSRV_V4STATELIMIT)
return (NFSERR_RESOURCE);
- if ((nd->nd_flag & ND_GSS) && nfsrv_nogsscallback)
+ if (nfsrv_issuedelegs == 0 ||
+ ((nd->nd_flag & ND_GSS) != 0 && nfsrv_nogsscallback != 0))
/*
- * Don't do callbacks for AUTH_GSS.
- * (Since these aren't yet debugged, they might cause the
- * server to crap out, if they get past the Init call to
- * the client.)
+ * Don't do callbacks when delegations are disabled or
+ * for AUTH_GSS unless enabled via nfsrv_nogsscallback.
+ * If establishing a callback connection is attempted
+ * when a firewall is blocking the callback path, the
+ * server may wait too long for the connect attempt to
+ * succeed during the Open. Some clients, such as Linux,
+ * may timeout and give up on the Open before the server
+ * replies. Also, since AUTH_GSS callbacks are not
+ * yet interoperability tested, they might cause the
+ * server to crap out, if they get past the Init call to
+ * the client.
*/
new_clp->lc_program = 0;
diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c
index 454c759..f9d3d0d 100644
--- a/sys/geom/part/g_part_mbr.c
+++ b/sys/geom/part/g_part_mbr.c
@@ -449,12 +449,6 @@ g_part_mbr_read(struct g_part_table *basetable, struct g_consumer *cp)
basetable->gpt_heads = heads;
}
}
- if ((ent.dp_start % basetable->gpt_sectors) != 0)
- printf("GEOM: %s: partition %d does not start on a "
- "track boundary.\n", pp->name, index + 1);
- if ((ent.dp_size % basetable->gpt_sectors) != 0)
- printf("GEOM: %s: partition %d does not end on a "
- "track boundary.\n", pp->name, index + 1);
entry = (struct g_part_mbr_entry *)g_part_new_entry(basetable,
index + 1, ent.dp_start, ent.dp_start + ent.dp_size - 1);
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index afdedc2..3bcc416 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -100,6 +100,8 @@ static int hw_clockrate;
SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD,
&hw_clockrate, 0, "CPU instruction clock rate");
+static eventhandler_tag tsc_post_tag;
+
static char cpu_brand[48];
#define MAX_BRAND_INDEX 8
@@ -856,28 +858,6 @@ printcpuinfo(void)
* If this CPU supports P-state invariant TSC then
* mention the capability.
*/
- switch (cpu_vendor_id) {
- case CPU_VENDOR_AMD:
- if ((amd_pminfo & AMDPM_TSC_INVARIANT) ||
- CPUID_TO_FAMILY(cpu_id) >= 0x10 ||
- cpu_id == 0x60fb2)
- tsc_is_invariant = 1;
- break;
- case CPU_VENDOR_INTEL:
- if ((amd_pminfo & AMDPM_TSC_INVARIANT) ||
- (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
- CPUID_TO_MODEL(cpu_id) >= 0xe) ||
- (CPUID_TO_FAMILY(cpu_id) == 0xf &&
- CPUID_TO_MODEL(cpu_id) >= 0x3))
- tsc_is_invariant = 1;
- break;
- case CPU_VENDOR_CENTAUR:
- if (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
- CPUID_TO_MODEL(cpu_id) >= 0xf &&
- (rdmsr(0x1203) & 0x100000000ULL) == 0)
- tsc_is_invariant = 1;
- break;
- }
if (tsc_is_invariant)
printf("\n TSC: P-state invariant");
@@ -1071,21 +1051,29 @@ identifycyrix(void)
/* Update TSC freq with the value indicated by the caller. */
static void
-tsc_freq_changed(void *arg, const struct cf_level *level, int status)
+tsc_freq_changed(void *arg __unused, const struct cf_level *level, int status)
{
- /*
- * If there was an error during the transition or
- * TSC is P-state invariant, don't do anything.
- */
- if (status != 0 || tsc_is_invariant)
+
+ /* If there was an error during the transition, don't do anything. */
+ if (status != 0)
return;
/* Total setting for this level gives the new frequency in MHz. */
hw_clockrate = level->total_set.freq;
}
-EVENTHANDLER_DEFINE(cpufreq_post_change, tsc_freq_changed, NULL,
- EVENTHANDLER_PRI_ANY);
+static void
+hook_tsc_freq(void *arg __unused)
+{
+
+ if (tsc_is_invariant)
+ return;
+
+ tsc_post_tag = EVENTHANDLER_REGISTER(cpufreq_post_change,
+ tsc_freq_changed, NULL, EVENTHANDLER_PRI_ANY);
+}
+
+SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, NULL);
/*
* Final stage of CPU identification. -- Should I check TI?
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 49800d9..a04e578 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -1157,12 +1157,16 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
thread_unlock(curthread);
#endif
+ tsc2 -= tsc1;
+ if (tsc_freq != 0 && !tsc_is_broken) {
+ *rate = tsc2 * 1000;
+ return (0);
+ }
+
/*
- * Calculate the difference in readings, convert to Mhz, and
- * subtract 0.5% of the total. Empirical testing has shown that
+ * Subtract 0.5% of the total. Empirical testing has shown that
* overhead in DELAY() works out to approximately this value.
*/
- tsc2 -= tsc1;
*rate = tsc2 * 1000 - tsc2 * 5;
return (0);
}
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 7efa29c..b7d3648 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -1213,7 +1213,7 @@ pmap_pte(pmap_t pmap, vm_offset_t va)
}
return (PADDR2 + (i386_btop(va) & (NPTEPG - 1)));
}
- return (0);
+ return (NULL);
}
/*
@@ -1291,21 +1291,19 @@ pmap_pte_quick(pmap_t pmap, vm_offset_t va)
vm_paddr_t
pmap_extract(pmap_t pmap, vm_offset_t va)
{
+ pt_entry_t pte, *ptep;
vm_paddr_t rtval;
- pt_entry_t *pte;
- pd_entry_t pde;
rtval = 0;
PMAP_LOCK(pmap);
- pde = pmap->pm_pdir[va >> PDRSHIFT];
- if (pde != 0) {
- if ((pde & PG_PS) != 0)
- rtval = (pde & PG_PS_FRAME) | (va & PDRMASK);
- else {
- pte = pmap_pte(pmap, va);
- rtval = (*pte & PG_FRAME) | (va & PAGE_MASK);
- pmap_pte_release(pte);
- }
+ ptep = pmap_pte(pmap, va);
+ pte = (ptep != NULL) ? *ptep : 0;
+ pmap_pte_release(ptep);
+ if ((pte & PG_V) != 0) {
+ if ((pte & PG_PS) != 0)
+ rtval = (pte & PG_PS_FRAME) | (va & PDRMASK);
+ else
+ rtval = (pte & PG_FRAME) | (va & PAGE_MASK);
}
PMAP_UNLOCK(pmap);
return (rtval);
@@ -1321,40 +1319,30 @@ pmap_extract(pmap_t pmap, vm_offset_t va)
vm_page_t
pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
{
- pd_entry_t pde;
- pt_entry_t pte;
+ pt_entry_t pte, *ptep;
+ vm_paddr_t locked_pa, pa;
vm_page_t m;
- vm_paddr_t pa;
- pa = 0;
+ locked_pa = 0;
m = NULL;
PMAP_LOCK(pmap);
retry:
- pde = *pmap_pde(pmap, va);
- if (pde != 0) {
- if (pde & PG_PS) {
- if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) {
- if (vm_page_pa_tryrelock(pmap, (pde & PG_PS_FRAME) |
- (va & PDRMASK), &pa))
- goto retry;
- m = PHYS_TO_VM_PAGE((pde & PG_PS_FRAME) |
- (va & PDRMASK));
- vm_page_hold(m);
- }
- } else {
- sched_pin();
- pte = *pmap_pte_quick(pmap, va);
- if (pte != 0 &&
- ((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) {
- if (vm_page_pa_tryrelock(pmap, pte & PG_FRAME, &pa))
- goto retry;
- m = PHYS_TO_VM_PAGE(pte & PG_FRAME);
- vm_page_hold(m);
- }
- sched_unpin();
- }
+ ptep = pmap_pte(pmap, va);
+ pte = (ptep != NULL) ? *ptep : 0;
+ pmap_pte_release(ptep);
+ if ((pte & PG_V) != 0 &&
+ ((pte & PG_RW) != 0 || (prot & VM_PROT_WRITE) == 0)) {
+ if ((pte & PG_PS) != 0) {
+ /* Compute the physical address of the 4KB page. */
+ pa = (pte & PG_PS_FRAME) | (va & PG_FRAME & PDRMASK);
+ } else
+ pa = pte & PG_FRAME;
+ if (vm_page_pa_tryrelock(pmap, pa, &locked_pa))
+ goto retry;
+ m = PHYS_TO_VM_PAGE(pa);
+ vm_page_hold(m);
+ PA_UNLOCK(locked_pa);
}
- PA_UNLOCK_COND(pa);
PMAP_UNLOCK(pmap);
return (m);
}
@@ -4991,39 +4979,30 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode)
int
pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa)
{
- pd_entry_t *pdep;
pt_entry_t *ptep, pte;
vm_paddr_t pa;
int val;
PMAP_LOCK(pmap);
retry:
- pdep = pmap_pde(pmap, addr);
- if (*pdep != 0) {
- if (*pdep & PG_PS) {
- pte = *pdep;
+ ptep = pmap_pte(pmap, addr);
+ pte = (ptep != NULL) ? *ptep : 0;
+ pmap_pte_release(ptep);
+ if ((pte & PG_V) != 0) {
+ val = MINCORE_INCORE;
+ if ((pte & PG_PS) != 0) {
+ val |= MINCORE_SUPER;
/* Compute the physical address of the 4KB page. */
- pa = ((*pdep & PG_PS_FRAME) | (addr & PDRMASK)) &
- PG_FRAME;
- val = MINCORE_SUPER;
- } else {
- ptep = pmap_pte(pmap, addr);
- pte = *ptep;
- pmap_pte_release(ptep);
+ pa = (pte & PG_PS_FRAME) | (addr & PG_FRAME & PDRMASK);
+ } else
pa = pte & PG_FRAME;
- val = 0;
- }
- } else {
- pte = 0;
- pa = 0;
- val = 0;
- }
- if ((pte & PG_V) != 0) {
- val |= MINCORE_INCORE;
if ((pte & (PG_M | PG_RW)) == (PG_M | PG_RW))
val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
if ((pte & PG_A) != 0)
val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER;
+ } else {
+ val = 0;
+ pa = 0;
}
if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) !=
(MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) &&
diff --git a/sys/i386/include/cpu.h b/sys/i386/include/cpu.h
index 83defe2..75fc0c6 100644
--- a/sys/i386/include/cpu.h
+++ b/sys/i386/include/cpu.h
@@ -56,7 +56,7 @@
#ifdef _KERNEL
extern char btext[];
extern char etext[];
-extern u_int tsc_present;
+extern int tsc_present;
void cpu_halt(void);
void cpu_reset(void);
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index b86ea91..80a0907 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -460,6 +460,7 @@ proc0_init(void *dummy __unused)
td->td_pri_class = PRI_TIMESHARE;
td->td_user_pri = PUSER;
td->td_base_user_pri = PUSER;
+ td->td_lend_user_pri = PRI_MAX;
td->td_priority = PVM;
td->td_base_pri = PUSER;
td->td_oncpu = 0;
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 126c668..61d9531 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -97,9 +97,7 @@ struct fork_args {
/* ARGSUSED */
int
-fork(td, uap)
- struct thread *td;
- struct fork_args *uap;
+fork(struct thread *td, struct fork_args *uap)
{
int error;
struct proc *p2;
@@ -135,9 +133,7 @@ vfork(td, uap)
}
int
-rfork(td, uap)
- struct thread *td;
- struct rfork_args *uap;
+rfork(struct thread *td, struct rfork_args *uap)
{
struct proc *p2;
int error;
@@ -197,12 +193,59 @@ sysctl_kern_randompid(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_kern, OID_AUTO, randompid, CTLTYPE_INT|CTLFLAG_RW,
0, 0, sysctl_kern_randompid, "I", "Random PID modulus");
+static int
+fork_norfproc(struct thread *td, int flags, struct proc **procp)
+{
+ int error;
+ struct proc *p1;
+
+ KASSERT((flags & RFPROC) == 0,
+ ("fork_norfproc called with RFPROC set"));
+ p1 = td->td_proc;
+ *procp = NULL;
+
+ if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) &&
+ (flags & (RFCFDG | RFFDG))) {
+ PROC_LOCK(p1);
+ if (thread_single(SINGLE_BOUNDARY)) {
+ PROC_UNLOCK(p1);
+ return (ERESTART);
+ }
+ PROC_UNLOCK(p1);
+ }
+
+ error = vm_forkproc(td, NULL, NULL, NULL, flags);
+ if (error)
+ goto fail;
+
+ /*
+ * Close all file descriptors.
+ */
+ if (flags & RFCFDG) {
+ struct filedesc *fdtmp;
+ fdtmp = fdinit(td->td_proc->p_fd);
+ fdfree(td);
+ p1->p_fd = fdtmp;
+ }
+
+ /*
+ * Unshare file descriptors (from parent).
+ */
+ if (flags & RFFDG)
+ fdunshare(p1, td);
+
+fail:
+ if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) &&
+ (flags & (RFCFDG | RFFDG))) {
+ PROC_LOCK(p1);
+ thread_single_end();
+ PROC_UNLOCK(p1);
+ }
+ return (error);
+}
+
int
-fork1(td, flags, pages, procp)
- struct thread *td;
- int flags;
- int pages;
- struct proc **procp;
+fork1(struct thread *td, int flags, int pages, struct proc **procp)
{
struct proc *p1, *p2, *pptr;
struct proc *newproc;
@@ -227,47 +270,8 @@ fork1(td, flags, pages, procp)
* Here we don't create a new process, but we divorce
* certain parts of a process from itself.
*/
- if ((flags & RFPROC) == 0) {
- if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) &&
- (flags & (RFCFDG | RFFDG))) {
- PROC_LOCK(p1);
- if (thread_single(SINGLE_BOUNDARY)) {
- PROC_UNLOCK(p1);
- return (ERESTART);
- }
- PROC_UNLOCK(p1);
- }
-
- error = vm_forkproc(td, NULL, NULL, NULL, flags);
- if (error)
- goto norfproc_fail;
-
- /*
- * Close all file descriptors.
- */
- if (flags & RFCFDG) {
- struct filedesc *fdtmp;
- fdtmp = fdinit(td->td_proc->p_fd);
- fdfree(td);
- p1->p_fd = fdtmp;
- }
-
- /*
- * Unshare file descriptors (from parent).
- */
- if (flags & RFFDG)
- fdunshare(p1, td);
-
-norfproc_fail:
- if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) &&
- (flags & (RFCFDG | RFFDG))) {
- PROC_LOCK(p1);
- thread_single_end();
- PROC_UNLOCK(p1);
- }
- *procp = NULL;
- return (error);
- }
+ if ((flags & RFPROC) == 0)
+ return (fork_norfproc(td, flags, procp));
/*
* XXX
@@ -539,6 +543,7 @@ again:
td2->td_sigstk = td->td_sigstk;
td2->td_sigmask = td->td_sigmask;
td2->td_flags = TDF_INMEM;
+ td2->td_lend_user_pri = PRI_MAX;
#ifdef VIMAGE
td2->td_vnet = NULL;
@@ -798,10 +803,8 @@ fail1:
* is called from the MD fork_trampoline() entry point.
*/
void
-fork_exit(callout, arg, frame)
- void (*callout)(void *, struct trapframe *);
- void *arg;
- struct trapframe *frame;
+fork_exit(void (*callout)(void *, struct trapframe *), void *arg,
+ struct trapframe *frame)
{
struct proc *p;
struct thread *td;
@@ -855,9 +858,7 @@ fork_exit(callout, arg, frame)
* first parameter and is called when returning to a new userland process.
*/
void
-fork_return(td, frame)
- struct thread *td;
- struct trapframe *frame;
+fork_return(struct thread *td, struct trapframe *frame)
{
userret(td, frame);
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 5f07590..7161a99 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -81,15 +81,54 @@ MTX_SYSINIT(zombie_lock, &zombie_lock, "zombie lock", MTX_SPIN);
static void thread_zombie(struct thread *);
+#define TID_BUFFER_SIZE 1024
+
struct mtx tid_lock;
static struct unrhdr *tid_unrhdr;
-
+static lwpid_t tid_buffer[TID_BUFFER_SIZE];
+static int tid_head, tid_tail;
static MALLOC_DEFINE(M_TIDHASH, "tidhash", "thread hash");
struct tidhashhead *tidhashtbl;
u_long tidhash;
struct rwlock tidhash_lock;
+static lwpid_t
+tid_alloc(void)
+{
+ lwpid_t tid;
+
+ tid = alloc_unr(tid_unrhdr);
+ if (tid != -1)
+ return (tid);
+ mtx_lock(&tid_lock);
+ if (tid_head == tid_tail) {
+ mtx_unlock(&tid_lock);
+ return (-1);
+ }
+ tid = tid_buffer[tid_head++];
+ tid_head %= TID_BUFFER_SIZE;
+ mtx_unlock(&tid_lock);
+ return (tid);
+}
+
+static void
+tid_free(lwpid_t tid)
+{
+ lwpid_t tmp_tid = -1;
+
+ mtx_lock(&tid_lock);
+ if ((tid_tail + 1) % TID_BUFFER_SIZE == tid_head) {
+ tmp_tid = tid_buffer[tid_head++];
+ tid_head = (tid_head + 1) % TID_BUFFER_SIZE;
+ }
+ tid_buffer[tid_tail++] = tid;
+ tid_tail %= TID_BUFFER_SIZE;
+ mtx_unlock(&tid_lock);
+ if (tmp_tid != -1)
+ free_unr(tid_unrhdr, tmp_tid);
+}
+
/*
* Prepare a thread for use.
*/
@@ -102,7 +141,7 @@ thread_ctor(void *mem, int size, void *arg, int flags)
td->td_state = TDS_INACTIVE;
td->td_oncpu = NOCPU;
- td->td_tid = alloc_unr(tid_unrhdr);
+ td->td_tid = tid_alloc();
/*
* Note that td_critnest begins life as 1 because the thread is not
@@ -110,6 +149,7 @@ thread_ctor(void *mem, int size, void *arg, int flags)
* end of a context switch.
*/
td->td_critnest = 1;
+ td->td_lend_user_pri = PRI_MAX;
EVENTHANDLER_INVOKE(thread_ctor, td);
#ifdef AUDIT
audit_thread_alloc(td);
@@ -155,7 +195,7 @@ thread_dtor(void *mem, int size, void *arg)
osd_thread_exit(td);
EVENTHANDLER_INVOKE(thread_dtor, td);
- free_unr(tid_unrhdr, td->td_tid);
+ tid_free(td->td_tid);
}
/*
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 43570ce..e7b9b32 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -1407,17 +1407,19 @@ umtx_propagate_priority(struct thread *td)
for (;;) {
td = pi->pi_owner;
- if (td == NULL)
+ if (td == NULL || td == curthread)
return;
MPASS(td->td_proc != NULL);
MPASS(td->td_proc->p_magic == P_MAGIC);
- if (UPRI(td) <= pri)
- return;
-
thread_lock(td);
- sched_lend_user_prio(td, pri);
+ if (td->td_lend_user_pri > pri)
+ sched_lend_user_prio(td, pri);
+ else {
+ thread_unlock(td);
+ break;
+ }
thread_unlock(td);
/*
@@ -3587,8 +3589,8 @@ umtx_thread_cleanup(struct thread *td)
pi->pi_owner = NULL;
TAILQ_REMOVE(&uq->uq_pi_contested, pi, pi_link);
}
+ mtx_unlock_spin(&umtx_lock);
thread_lock(td);
- td->td_flags &= ~TDF_UBORROWING;
+ sched_unlend_user_prio(td, PRI_MAX);
thread_unlock(td);
- mtx_unlock_spin(&umtx_lock);
}
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index 9face64..6278126 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -879,25 +879,23 @@ sched_prio(struct thread *td, u_char prio)
void
sched_user_prio(struct thread *td, u_char prio)
{
- u_char oldprio;
THREAD_LOCK_ASSERT(td, MA_OWNED);
td->td_base_user_pri = prio;
- if (td->td_flags & TDF_UBORROWING && td->td_user_pri <= prio)
+ if (td->td_lend_user_pri <= prio)
return;
- oldprio = td->td_user_pri;
td->td_user_pri = prio;
}
void
sched_lend_user_prio(struct thread *td, u_char prio)
{
- u_char oldprio;
THREAD_LOCK_ASSERT(td, MA_OWNED);
- td->td_flags |= TDF_UBORROWING;
- oldprio = td->td_user_pri;
- td->td_user_pri = prio;
+ if (prio < td->td_lend_user_pri)
+ td->td_lend_user_pri = prio;
+ if (prio < td->td_user_pri)
+ td->td_user_pri = prio;
}
void
@@ -907,12 +905,11 @@ sched_unlend_user_prio(struct thread *td, u_char prio)
THREAD_LOCK_ASSERT(td, MA_OWNED);
base_pri = td->td_base_user_pri;
- if (prio >= base_pri) {
- td->td_flags &= ~TDF_UBORROWING;
- sched_user_prio(td, base_pri);
- } else {
- sched_lend_user_prio(td, prio);
- }
+ td->td_lend_user_pri = prio;
+ if (prio > base_pri)
+ td->td_user_pri = base_pri;
+ else
+ td->td_user_pri = prio;
}
void
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 030c98d..fb30fdb 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -1677,8 +1677,8 @@ sched_user_prio(struct thread *td, u_char prio)
{
td->td_base_user_pri = prio;
- if (td->td_flags & TDF_UBORROWING && td->td_user_pri <= prio)
- return;
+ if (td->td_lend_user_pri <= prio)
+ return;
td->td_user_pri = prio;
}
@@ -1687,8 +1687,10 @@ sched_lend_user_prio(struct thread *td, u_char prio)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
- td->td_flags |= TDF_UBORROWING;
- td->td_user_pri = prio;
+ if (prio < td->td_lend_user_pri)
+ td->td_lend_user_pri = prio;
+ if (prio < td->td_user_pri)
+ td->td_user_pri = prio;
}
void
@@ -1698,12 +1700,11 @@ sched_unlend_user_prio(struct thread *td, u_char prio)
THREAD_LOCK_ASSERT(td, MA_OWNED);
base_pri = td->td_base_user_pri;
- if (prio >= base_pri) {
- td->td_flags &= ~TDF_UBORROWING;
- sched_user_prio(td, base_pri);
- } else {
- sched_lend_user_prio(td, prio);
- }
+ td->td_lend_user_pri = prio;
+ if (prio > base_pri)
+ td->td_user_pri = base_pri;
+ else
+ td->td_user_pri = prio;
}
/*
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 63437bc..8920201 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/protosw.h>
+#include <sys/queue.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
#include <sys/socket.h>
@@ -115,6 +116,13 @@ static struct unp_head unp_shead; /* (l) List of stream sockets. */
static struct unp_head unp_dhead; /* (l) List of datagram sockets. */
static struct unp_head unp_sphead; /* (l) List of seqpacket sockets. */
+struct unp_defer {
+ SLIST_ENTRY(unp_defer) ud_link;
+ struct file *ud_fp;
+};
+static SLIST_HEAD(, unp_defer) unp_defers;
+static int unp_defers_count;
+
static const struct sockaddr sun_noname = { sizeof(sun_noname), AF_LOCAL };
/*
@@ -126,6 +134,13 @@ static const struct sockaddr sun_noname = { sizeof(sun_noname), AF_LOCAL };
static struct task unp_gc_task;
/*
+ * The close of unix domain sockets attached as SCM_RIGHTS is
+ * postponed to the taskqueue, to avoid arbitrary recursion depth.
+ * The attached sockets might have another sockets attached.
+ */
+static struct task unp_defer_task;
+
+/*
* Both send and receive buffers are allocated PIPSIZ bytes of buffering for
* stream sockets, although the total for sender and receiver is actually
* only PIPSIZ.
@@ -162,8 +177,11 @@ SYSCTL_ULONG(_net_local_seqpacket, OID_AUTO, maxseqpacket, CTLFLAG_RW,
&unpsp_sendspace, 0, "Default seqpacket send space.");
SYSCTL_ULONG(_net_local_seqpacket, OID_AUTO, recvspace, CTLFLAG_RW,
&unpsp_recvspace, 0, "Default seqpacket receive space.");
-SYSCTL_INT(_net_local, OID_AUTO, inflight, CTLFLAG_RD, &unp_rights, 0,
+SYSCTL_INT(_net_local, OID_AUTO, inflight, CTLFLAG_RD, &unp_rights, 0,
"File descriptors in flight.");
+SYSCTL_INT(_net_local, OID_AUTO, deferred, CTLFLAG_RD,
+ &unp_defers_count, 0,
+ "File descriptors deferred to taskqueue for close.");
/*
* Locking and synchronization:
@@ -213,6 +231,7 @@ SYSCTL_INT(_net_local, OID_AUTO, inflight, CTLFLAG_RD, &unp_rights, 0,
*/
static struct rwlock unp_link_rwlock;
static struct mtx unp_list_lock;
+static struct mtx unp_defers_lock;
#define UNP_LINK_LOCK_INIT() rw_init(&unp_link_rwlock, \
"unp_link_rwlock")
@@ -234,6 +253,11 @@ static struct mtx unp_list_lock;
#define UNP_LIST_LOCK() mtx_lock(&unp_list_lock)
#define UNP_LIST_UNLOCK() mtx_unlock(&unp_list_lock)
+#define UNP_DEFERRED_LOCK_INIT() mtx_init(&unp_defers_lock, \
+ "unp_defer", NULL, MTX_DEF)
+#define UNP_DEFERRED_LOCK() mtx_lock(&unp_defers_lock)
+#define UNP_DEFERRED_UNLOCK() mtx_unlock(&unp_defers_lock)
+
#define UNP_PCB_LOCK_INIT(unp) mtx_init(&(unp)->unp_mtx, \
"unp_mtx", "unp_mtx", \
MTX_DUPOK|MTX_DEF|MTX_RECURSE)
@@ -259,8 +283,9 @@ static void unp_init(void);
static int unp_internalize(struct mbuf **, struct thread *);
static void unp_internalize_fp(struct file *);
static int unp_externalize(struct mbuf *, struct mbuf **);
-static void unp_externalize_fp(struct file *);
+static int unp_externalize_fp(struct file *);
static struct mbuf *unp_addsockcred(struct thread *, struct mbuf *);
+static void unp_process_defers(void * __unused, int);
/*
* Definitions of protocols supported in the LOCAL domain.
@@ -1764,9 +1789,12 @@ unp_init(void)
LIST_INIT(&unp_dhead);
LIST_INIT(&unp_shead);
LIST_INIT(&unp_sphead);
+ SLIST_INIT(&unp_defers);
TASK_INIT(&unp_gc_task, 0, unp_gc, NULL);
+ TASK_INIT(&unp_defer_task, 0, unp_process_defers, NULL);
UNP_LINK_LOCK_INIT();
UNP_LIST_LOCK_INIT();
+ UNP_DEFERRED_LOCK_INIT();
}
static int
@@ -1970,9 +1998,45 @@ fptounp(struct file *fp)
static void
unp_discard(struct file *fp)
{
+ struct unp_defer *dr;
+
+ if (unp_externalize_fp(fp)) {
+ dr = malloc(sizeof(*dr), M_TEMP, M_WAITOK);
+ dr->ud_fp = fp;
+ UNP_DEFERRED_LOCK();
+ SLIST_INSERT_HEAD(&unp_defers, dr, ud_link);
+ UNP_DEFERRED_UNLOCK();
+ atomic_add_int(&unp_defers_count, 1);
+ taskqueue_enqueue(taskqueue_thread, &unp_defer_task);
+ } else
+ (void) closef(fp, (struct thread *)NULL);
+}
- unp_externalize_fp(fp);
- (void) closef(fp, (struct thread *)NULL);
+static void
+unp_process_defers(void *arg __unused, int pending)
+{
+ struct unp_defer *dr;
+ SLIST_HEAD(, unp_defer) drl;
+ int count;
+
+ SLIST_INIT(&drl);
+ for (;;) {
+ UNP_DEFERRED_LOCK();
+ if (SLIST_FIRST(&unp_defers) == NULL) {
+ UNP_DEFERRED_UNLOCK();
+ break;
+ }
+ SLIST_SWAP(&unp_defers, &drl, unp_defer);
+ UNP_DEFERRED_UNLOCK();
+ count = 0;
+ while ((dr = SLIST_FIRST(&drl)) != NULL) {
+ SLIST_REMOVE_HEAD(&drl, ud_link);
+ closef(dr->ud_fp, NULL);
+ free(dr, M_TEMP);
+ count++;
+ }
+ atomic_add_int(&unp_defers_count, -count);
+ }
}
static void
@@ -1990,16 +2054,21 @@ unp_internalize_fp(struct file *fp)
UNP_LINK_WUNLOCK();
}
-static void
+static int
unp_externalize_fp(struct file *fp)
{
struct unpcb *unp;
+ int ret;
UNP_LINK_WLOCK();
- if ((unp = fptounp(fp)) != NULL)
+ if ((unp = fptounp(fp)) != NULL) {
unp->unp_msgcount--;
+ ret = 1;
+ } else
+ ret = 0;
unp_rights--;
UNP_LINK_WUNLOCK();
+ return (ret);
}
/*
diff --git a/sys/mips/adm5120/adm5120_machdep.c b/sys/mips/adm5120/adm5120_machdep.c
index 90a6b90..bc7b7b0 100644
--- a/sys/mips/adm5120/adm5120_machdep.c
+++ b/sys/mips/adm5120/adm5120_machdep.c
@@ -97,6 +97,9 @@ mips_init(void)
phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
phys_avail[1] = ctob(realmem);
+ dump_avail[0] = phys_avail[0];
+ dump_avail[1] = phys_avail[1];
+
physmem = realmem;
init_param1();
diff --git a/sys/mips/alchemy/alchemy_machdep.c b/sys/mips/alchemy/alchemy_machdep.c
index a94d995..047fa42 100644
--- a/sys/mips/alchemy/alchemy_machdep.c
+++ b/sys/mips/alchemy/alchemy_machdep.c
@@ -97,6 +97,9 @@ mips_init(void)
phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
phys_avail[1] = ctob(realmem);
+ dump_avail[0] = phys_avail[0];
+ dump_avail[1] = phys_avail[1];
+
physmem = realmem;
init_param1();
diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c
index ec355cc..c8abc74 100644
--- a/sys/mips/atheros/ar71xx_machdep.c
+++ b/sys/mips/atheros/ar71xx_machdep.c
@@ -184,6 +184,9 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused,
phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
phys_avail[1] = ctob(realmem);
+ dump_avail[0] = phys_avail[0];
+ dump_avail[1] = phys_avail[1] - phys_avail[0];
+
physmem = realmem;
/*
diff --git a/sys/mips/cavium/octeon_machdep.c b/sys/mips/cavium/octeon_machdep.c
index 886595c..edb92af 100644
--- a/sys/mips/cavium/octeon_machdep.c
+++ b/sys/mips/cavium/octeon_machdep.c
@@ -265,7 +265,7 @@ octeon_memory_init(void)
{
vm_paddr_t phys_end;
int64_t addr;
- unsigned i;
+ unsigned i, j;
phys_end = round_page(MIPS_KSEG0_TO_PHYS((vm_offset_t)&end));
@@ -274,6 +274,9 @@ octeon_memory_init(void)
phys_avail[0] = phys_end;
phys_avail[1] = 96 << 20;
+ dump_avail[0] = phys_avail[0];
+ dump_avail[1] = phys_avail[1];
+
realmem = physmem = btoc(phys_avail[1] - phys_avail[0]);
return;
}
@@ -314,6 +317,9 @@ octeon_memory_init(void)
i += 2;
}
+ for (j = 0; j < i; j++)
+ dump_avail[j] = phys_avail[j];
+
realmem = physmem;
}
diff --git a/sys/mips/idt/idt_machdep.c b/sys/mips/idt/idt_machdep.c
index 0dfee66..6c76c26 100644
--- a/sys/mips/idt/idt_machdep.c
+++ b/sys/mips/idt/idt_machdep.c
@@ -167,6 +167,9 @@ platform_start(__register_t a0, __register_t a1,
phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
phys_avail[1] = ctob(realmem);
+ dump_avail[0] = phys_avail[0];
+ dump_avail[1] = phys_avail[1];
+
physmem = realmem;
/*
diff --git a/sys/mips/include/md_var.h b/sys/mips/include/md_var.h
index 3cebbdc..3e46ad3 100644
--- a/sys/mips/include/md_var.h
+++ b/sys/mips/include/md_var.h
@@ -77,6 +77,8 @@ void platform_identify(void);
extern int busdma_swi_pending;
void busdma_swi(void);
-struct dumperinfo;
-void minidumpsys(struct dumperinfo *);
+struct dumperinfo;
+void dump_add_page(vm_paddr_t);
+void dump_drop_page(vm_paddr_t);
+void minidumpsys(struct dumperinfo *);
#endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/mips/include/pmap.h b/sys/mips/include/pmap.h
index c082abb..cdbf9bc 100644
--- a/sys/mips/include/pmap.h
+++ b/sys/mips/include/pmap.h
@@ -163,6 +163,9 @@ void pmap_kenter_temporary_free(vm_paddr_t pa);
int pmap_compute_pages_to_dump(void);
void pmap_flush_pvcache(vm_page_t m);
int pmap_emulate_modified(pmap_t pmap, vm_offset_t va);
+void pmap_grow_direct_page_cache(void);
+vm_page_t pmap_alloc_direct_page(unsigned int index, int req);
+
#endif /* _KERNEL */
#endif /* !LOCORE */
diff --git a/sys/mips/include/vmparam.h b/sys/mips/include/vmparam.h
index 3050a91..212a0c3 100644
--- a/sys/mips/include/vmparam.h
+++ b/sys/mips/include/vmparam.h
@@ -46,11 +46,6 @@
/*
* Machine dependent constants mips processors.
*/
-/*
- * USRTEXT is the start of the user text/data space, while USRSTACK
- * is the top (end) of the user stack.
- */
-#define USRTEXT (1*PAGE_SIZE)
/*
* Virtual memory related constants, all in bytes
@@ -94,7 +89,6 @@
#define VM_MAX_ADDRESS ((vm_offset_t)(intptr_t)(int32_t)0xffffffff)
#define VM_MINUSER_ADDRESS ((vm_offset_t)0x00000000)
-#define VM_MAX_MMAP_ADDR VM_MAXUSER_ADDRESS
#ifdef __mips_n64
#define VM_MAXUSER_ADDRESS (VM_MINUSER_ADDRESS + (NPDEPG * NBSEG))
@@ -155,6 +149,8 @@
#define VM_INITIAL_PAGEIN 16
#endif
+#define UMA_MD_SMALL_ALLOC
+
/*
* max number of non-contig chunks of physical RAM you can have
*/
diff --git a/sys/mips/malta/malta_machdep.c b/sys/mips/malta/malta_machdep.c
index 6cbdcd8..0ff34cb 100644
--- a/sys/mips/malta/malta_machdep.c
+++ b/sys/mips/malta/malta_machdep.c
@@ -181,6 +181,9 @@ mips_init(void)
phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end);
phys_avail[1] = ctob(realmem);
+ dump_avail[0] = phys_avail[0];
+ dump_avail[1] = phys_avail[1];
+
physmem = realmem;
init_param1();
diff --git a/sys/mips/mips/minidump_machdep.c b/sys/mips/mips/minidump_machdep.c
index 1ac384a..cded3ae 100644
--- a/sys/mips/mips/minidump_machdep.c
+++ b/sys/mips/mips/minidump_machdep.c
@@ -83,7 +83,7 @@ is_dumpable(vm_paddr_t pa)
return (0);
}
-static void
+void
dump_add_page(vm_paddr_t pa)
{
int idx, bit;
@@ -94,7 +94,7 @@ dump_add_page(vm_paddr_t pa)
atomic_set_int(&vm_page_dump[idx], 1ul << bit);
}
-static void
+void
dump_drop_page(vm_paddr_t pa)
{
int idx, bit;
diff --git a/sys/mips/mips/mp_machdep.c b/sys/mips/mips/mp_machdep.c
index 2b993cb..41de5fb 100644
--- a/sys/mips/mips/mp_machdep.c
+++ b/sys/mips/mips/mp_machdep.c
@@ -164,7 +164,7 @@ mips_ipi_handler(void *arg)
break;
case IPI_HARDCLOCK:
CTR1(KTR_SMP, "%s: IPI_HARDCLOCK", __func__);
- hardclockintr();;
+ hardclockintr();
break;
default:
panic("Unknown IPI 0x%0x on cpu %d", ipi, curcpu);
diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c
index 4e2b34e..7b0d09b 100644
--- a/sys/mips/mips/pmap.c
+++ b/sys/mips/mips/pmap.c
@@ -185,8 +185,6 @@ static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags);
static vm_page_t _pmap_allocpte(pmap_t pmap, unsigned ptepindex, int flags);
static int pmap_unuse_pt(pmap_t, vm_offset_t, vm_page_t);
static int init_pte_prot(vm_offset_t va, vm_page_t m, vm_prot_t prot);
-static vm_page_t pmap_alloc_pte_page(unsigned int index, int req);
-static void pmap_grow_pte_page_cache(void);
#ifdef SMP
static void pmap_invalidate_page_action(void *arg);
@@ -196,14 +194,15 @@ static void pmap_update_page_action(void *arg);
#ifndef __mips_n64
/*
- * This structure is for high memory (memory above 512Meg in 32 bit)
- * This memory area does not have direct mapping, so we a mechanism to do
- * temporary per-CPU mapping to access these addresses.
+ * This structure is for high memory (memory above 512Meg in 32 bit) support.
+ * The highmem area does not have a KSEG0 mapping, and we need a mechanism to
+ * do temporary per-CPU mappings for pmap_zero_page, pmap_copy_page etc.
*
- * At bootup we reserve 2 virtual pages per CPU for mapping highmem pages, to
- * access a highmem physical address on a CPU, we will disable interrupts and
- * add the mapping from the reserved virtual address for the CPU to the physical
- * address in the kernel pagetable.
+ * At bootup, we reserve 2 virtual pages per CPU for mapping highmem pages. To
+ * access a highmem physical address on a CPU, we map the physical address to
+ * the reserved virtual address for the CPU in the kernel pagetable. This is
+ * done with interrupts disabled(although a spinlock and sched_pin would be
+ * sufficient).
*/
struct local_sysmaps {
vm_offset_t base;
@@ -520,11 +519,11 @@ again:
}
/*
- * In 32 bit, we may have memory which cannot be mapped directly
- * this memory will need temporary mapping before it can be
+ * In 32 bit, we may have memory which cannot be mapped directly.
+ * This memory will need temporary mapping before it can be
* accessed.
*/
- if (!MIPS_DIRECT_MAPPABLE(phys_avail[i - 1]))
+ if (!MIPS_DIRECT_MAPPABLE(phys_avail[i - 1] - 1))
need_local_mappings = 1;
/*
@@ -893,7 +892,7 @@ pmap_map(vm_offset_t *virt, vm_offset_t start, vm_offset_t end, int prot)
{
vm_offset_t va, sva;
- if (MIPS_DIRECT_MAPPABLE(end))
+ if (MIPS_DIRECT_MAPPABLE(end - 1))
return (MIPS_PHYS_TO_DIRECT(start));
va = sva = *virt;
@@ -1061,8 +1060,8 @@ pmap_pinit0(pmap_t pmap)
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
}
-static void
-pmap_grow_pte_page_cache()
+void
+pmap_grow_direct_page_cache()
{
#ifdef __mips_n64
@@ -1072,8 +1071,8 @@ pmap_grow_pte_page_cache()
#endif
}
-static vm_page_t
-pmap_alloc_pte_page(unsigned int index, int req)
+vm_page_t
+pmap_alloc_direct_page(unsigned int index, int req)
{
vm_page_t m;
@@ -1106,8 +1105,8 @@ pmap_pinit(pmap_t pmap)
/*
* allocate the page directory page
*/
- while ((ptdpg = pmap_alloc_pte_page(NUSERPGTBLS, VM_ALLOC_NORMAL)) == NULL)
- pmap_grow_pte_page_cache();
+ while ((ptdpg = pmap_alloc_direct_page(NUSERPGTBLS, VM_ALLOC_NORMAL)) == NULL)
+ pmap_grow_direct_page_cache();
ptdva = MIPS_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(ptdpg));
pmap->pm_segtab = (pd_entry_t *)ptdva;
@@ -1140,11 +1139,11 @@ _pmap_allocpte(pmap_t pmap, unsigned ptepindex, int flags)
/*
* Find or fabricate a new pagetable page
*/
- if ((m = pmap_alloc_pte_page(ptepindex, VM_ALLOC_NORMAL)) == NULL) {
+ if ((m = pmap_alloc_direct_page(ptepindex, VM_ALLOC_NORMAL)) == NULL) {
if (flags & M_WAITOK) {
PMAP_UNLOCK(pmap);
vm_page_unlock_queues();
- pmap_grow_pte_page_cache();
+ pmap_grow_direct_page_cache();
vm_page_lock_queues();
PMAP_LOCK(pmap);
}
@@ -1312,7 +1311,7 @@ pmap_growkernel(vm_offset_t addr)
#ifdef __mips_n64
if (*pdpe == 0) {
/* new intermediate page table entry */
- nkpg = pmap_alloc_pte_page(nkpt, VM_ALLOC_INTERRUPT);
+ nkpg = pmap_alloc_direct_page(nkpt, VM_ALLOC_INTERRUPT);
if (nkpg == NULL)
panic("pmap_growkernel: no memory to grow kernel");
*pdpe = (pd_entry_t)MIPS_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(nkpg));
@@ -1332,7 +1331,7 @@ pmap_growkernel(vm_offset_t addr)
/*
* This index is bogus, but out of the way
*/
- nkpg = pmap_alloc_pte_page(nkpt, VM_ALLOC_INTERRUPT);
+ nkpg = pmap_alloc_direct_page(nkpt, VM_ALLOC_INTERRUPT);
if (!nkpg)
panic("pmap_growkernel: no memory to grow kernel");
nkpt++;
@@ -3099,7 +3098,7 @@ pads(pmap_t pm)
va >= VM_MAXUSER_ADDRESS)
continue;
ptep = pmap_pte(pm, va);
- if (pmap_pte_v(ptep))
+ if (pte_test(ptep, PTE_V))
printf("%x:%x ", va, *(int *)ptep);
}
diff --git a/sys/mips/mips/uma_machdep.c b/sys/mips/mips/uma_machdep.c
new file mode 100644
index 0000000..690fc23
--- /dev/null
+++ b/sys/mips/mips/uma_machdep.c
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
+#include <vm/uma.h>
+#include <vm/uma_int.h>
+#include <machine/md_var.h>
+#include <machine/vmparam.h>
+
+void *
+uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
+{
+ static vm_pindex_t color;
+ vm_paddr_t pa;
+ vm_page_t m;
+ int pflags;
+ void *va;
+
+ *flags = UMA_SLAB_PRIV;
+
+ if ((wait & (M_NOWAIT|M_USE_RESERVE)) == M_NOWAIT)
+ pflags = VM_ALLOC_INTERRUPT;
+ else
+ pflags = VM_ALLOC_SYSTEM;
+
+ for (;;) {
+ m = pmap_alloc_direct_page(color++, pflags);
+ if (m == NULL) {
+ if (wait & M_NOWAIT)
+ return (NULL);
+ else
+ pmap_grow_direct_page_cache();
+ } else
+ break;
+ }
+
+ pa = VM_PAGE_TO_PHYS(m);
+ va = (void *)MIPS_PHYS_TO_DIRECT(pa);
+ if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
+ bzero(va, PAGE_SIZE);
+ return (va);
+}
+
+void
+uma_small_free(void *mem, int size, u_int8_t flags)
+{
+ vm_page_t m;
+ vm_paddr_t pa;
+
+ pa = MIPS_DIRECT_TO_PHYS((vm_offset_t)mem);
+ m = PHYS_TO_VM_PAGE(pa);
+ m->wire_count--;
+ vm_page_free(m);
+ atomic_subtract_int(&cnt.v_wire_count, 1);
+}
diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c
index 73fab5a..b4059e6 100644
--- a/sys/mips/mips/vm_machdep.c
+++ b/sys/mips/mips/vm_machdep.c
@@ -538,6 +538,9 @@ sf_buf_free(struct sf_buf *sf)
void
swi_vm(void *dummy)
{
+
+ if (busdma_swi_pending)
+ busdma_swi();
}
int
diff --git a/sys/mips/rmi/dev/nlge/if_nlge.c b/sys/mips/rmi/dev/nlge/if_nlge.c
index 9ff88ea..5c3dd2f 100644
--- a/sys/mips/rmi/dev/nlge/if_nlge.c
+++ b/sys/mips/rmi/dev/nlge/if_nlge.c
@@ -213,7 +213,6 @@ static int send_fmn_msg_tx(struct nlge_softc *, struct msgrng_msg *,
//#define DEBUG
#ifdef DEBUG
static int mac_debug = 1;
-static int reg_dump = 0;
#undef PDEBUG
#define PDEBUG(fmt, args...) \
do {\
diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c
index 8f96633..5a5bb79 100644
--- a/sys/mips/rmi/xlr_machdep.c
+++ b/sys/mips/rmi/xlr_machdep.c
@@ -363,6 +363,9 @@ xlr_mem_init(void)
(void *)phys_avail[0],
(void *)phys_avail[1]);
+ dump_avail[0] = phys_avail[0];
+ dump_avail[1] = phys_avail[1];
+
} else {
/*
* Can't use this code yet, because most of the fixed allocations happen from
@@ -390,6 +393,10 @@ xlr_mem_init(void)
(void *)phys_avail[j],
(void *)phys_avail[j+1]);
}
+
+ dump_avail[j] = phys_avail[j];
+ dump_avail[j+1] = phys_avail[j+1];
+
physsz += boot_map->physmem_map[i].size;
}
}
diff --git a/sys/mips/rmi/xlr_pci.c b/sys/mips/rmi/xlr_pci.c
index 3204691..8cdaede 100644
--- a/sys/mips/rmi/xlr_pci.c
+++ b/sys/mips/rmi/xlr_pci.c
@@ -105,13 +105,6 @@ __FBSDID("$FreeBSD$");
(MSI_MIPS_DATA_TRGRLVL | MSI_MIPS_DATA_DELFIXED | \
MSI_MIPS_DATA_ASSERT | (irq))
-#define DEBUG
-#ifdef DEBUG
-#define dbg_devprintf device_printf
-#else
-#define dbg_devprintf(dev, fmt, ...)
-#endif
-
struct xlr_pcib_softc {
bus_dma_tag_t sc_pci_dmat; /* PCI DMA tag pointer */
};
diff --git a/sys/mips/sentry5/s5_machdep.c b/sys/mips/sentry5/s5_machdep.c
index 00e6231..4491b93 100644
--- a/sys/mips/sentry5/s5_machdep.c
+++ b/sys/mips/sentry5/s5_machdep.c
@@ -91,7 +91,7 @@ platform_cpu_init()
static void
mips_init(void)
{
- int i;
+ int i, j;
printf("entry: mips_init()\n");
@@ -128,6 +128,9 @@ mips_init(void)
realmem = btoc(physmem);
#endif
+ for (j = 0; j < i; j++)
+ dump_avail[j] = phys_avail[j];
+
physmem = realmem;
init_param1();
diff --git a/sys/mips/sibyte/sb_machdep.c b/sys/mips/sibyte/sb_machdep.c
index ba4b62e9..ac30451 100644
--- a/sys/mips/sibyte/sb_machdep.c
+++ b/sys/mips/sibyte/sb_machdep.c
@@ -138,7 +138,7 @@ sb_intr_init(int cpuid)
static void
mips_init(void)
{
- int i, cfe_mem_idx, tmp;
+ int i, j, cfe_mem_idx, tmp;
uint64_t maxmem;
#ifdef CFE_ENV
@@ -225,6 +225,9 @@ mips_init(void)
realmem = btoc(physmem);
#endif
+ for (j = 0; j < i; j++)
+ dump_avail[j] = phys_avail[j];
+
physmem = realmem;
init_param1();
diff --git a/sys/net/if.h b/sys/net/if.h
index a99b4a7..d291da8 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -145,7 +145,7 @@ struct if_data {
#define IFF_LINK2 0x4000 /* per link layer defined bit */
#define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */
#define IFF_MULTICAST 0x8000 /* (i) supports multicast */
-/* 0x10000 */
+#define IFF_CANTCONFIG 0x10000 /* (i) unconfigurable using ioctl(2) */
#define IFF_PPROMISC 0x20000 /* (n) user-requested promisc mode */
#define IFF_MONITOR 0x40000 /* (n) user-requested monitor mode */
#define IFF_STATICARP 0x80000 /* (n) static ARP */
@@ -165,7 +165,7 @@ struct if_data {
#define IFF_CANTCHANGE \
(IFF_BROADCAST|IFF_POINTOPOINT|IFF_DRV_RUNNING|IFF_DRV_OACTIVE|\
IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_SMART|IFF_PROMISC|\
- IFF_DYING)
+ IFF_DYING|IFF_CANTCONFIG)
/*
* Values for if_link_state.
diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c
index 0399393..a1adb85 100644
--- a/sys/netinet/ip_fastfwd.c
+++ b/sys/netinet/ip_fastfwd.c
@@ -218,7 +218,7 @@ ip_fastforward(struct mbuf *m)
*/
hlen = ip->ip_hl << 2;
if (hlen < sizeof(struct ip)) { /* minimum header length */
- IPSTAT_INC(ips_badlen);
+ IPSTAT_INC(ips_badhlen);
goto drop;
}
if (hlen > m->m_len) {
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index 05b40f7..bd484a7 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -3081,14 +3081,17 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
int num_frs = 0;
int chunk_freed;
int non_revocable;
- uint16_t frag_strt, frag_end;
- uint32_t last_frag_high;
+ uint16_t frag_strt, frag_end, prev_frag_end;
- tp1 = NULL;
- last_frag_high = 0;
+ tp1 = TAILQ_FIRST(&asoc->sent_queue);
+ prev_frag_end = 0;
chunk_freed = 0;
for (i = 0; i < (num_seg + num_nr_seg); i++) {
+ if (i == num_seg) {
+ prev_frag_end = 0;
+ tp1 = TAILQ_FIRST(&asoc->sent_queue);
+ }
frag = (struct sctp_gap_ack_block *)sctp_m_getptr(m, *offset,
sizeof(struct sctp_gap_ack_block), (uint8_t *) & block);
*offset += sizeof(block);
@@ -3097,58 +3100,29 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
}
frag_strt = ntohs(frag->start);
frag_end = ntohs(frag->end);
- /* some sanity checks on the fragment offsets */
+
if (frag_strt > frag_end) {
- /* this one is malformed, skip */
+ /* This gap report is malformed, skip it. */
continue;
}
- if (compare_with_wrap((frag_end + last_tsn), *biggest_tsn_acked,
- MAX_TSN))
- *biggest_tsn_acked = frag_end + last_tsn;
-
- /* mark acked dgs and find out the highestTSN being acked */
- if (tp1 == NULL) {
+ if (frag_strt <= prev_frag_end) {
+ /* This gap report is not in order, so restart. */
tp1 = TAILQ_FIRST(&asoc->sent_queue);
- /* save the locations of the last frags */
- last_frag_high = frag_end + last_tsn;
- } else {
- /*
- * now lets see if we need to reset the queue due to
- * a out-of-order SACK fragment
- */
- if (compare_with_wrap(frag_strt + last_tsn,
- last_frag_high, MAX_TSN)) {
- /*
- * if the new frag starts after the last TSN
- * frag covered, we are ok and this one is
- * beyond the last one
- */
- ;
- } else {
- /*
- * ok, they have reset us, so we need to
- * reset the queue this will cause extra
- * hunting but hey, they chose the
- * performance hit when they failed to order
- * their gaps
- */
- tp1 = TAILQ_FIRST(&asoc->sent_queue);
- }
- last_frag_high = frag_end + last_tsn;
+ }
+ if (compare_with_wrap((last_tsn + frag_end), *biggest_tsn_acked, MAX_TSN)) {
+ *biggest_tsn_acked = last_tsn + frag_end;
}
if (i < num_seg) {
non_revocable = 0;
} else {
non_revocable = 1;
}
- if (i == num_seg) {
- tp1 = NULL;
- }
if (sctp_process_segment_range(stcb, &tp1, last_tsn, frag_strt, frag_end,
non_revocable, &num_frs, biggest_newly_acked_tsn,
this_sack_lowest_newack, ecn_seg_sums)) {
chunk_freed = 1;
}
+ prev_frag_end = frag_end;
}
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
if (num_frs)
@@ -4817,7 +4791,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
}
}
/********************************************/
- /* drop the acked chunks from the sendqueue */
+ /* drop the acked chunks from the sentqueue */
/********************************************/
asoc->last_acked_seq = cum_ack;
@@ -4925,9 +4899,10 @@ done_with_it:
* we had some before and now we have NONE.
*/
- if (num_seg)
+ if (num_seg) {
sctp_check_for_revoked(stcb, asoc, cum_ack, biggest_tsn_acked);
- else if (asoc->saw_sack_with_frags) {
+ asoc->saw_sack_with_frags = 1;
+ } else if (asoc->saw_sack_with_frags) {
int cnt_revoked = 0;
tp1 = TAILQ_FIRST(&asoc->sent_queue);
@@ -4963,10 +4938,10 @@ done_with_it:
}
asoc->saw_sack_with_frags = 0;
}
- if (num_seg || num_nr_seg)
- asoc->saw_sack_with_frags = 1;
+ if (num_nr_seg > 0)
+ asoc->saw_sack_with_nr_frags = 1;
else
- asoc->saw_sack_with_frags = 0;
+ asoc->saw_sack_with_nr_frags = 0;
/* JRS - Use the congestion control given in the CC module */
asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, accum_moved, reneged_all, will_exit_fast_recovery);
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index ad4209f..88d67a3 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -4644,6 +4644,7 @@ process_control_chunks:
((compare_with_wrap(cum_ack, stcb->asoc.last_acked_seq, MAX_TSN)) ||
(cum_ack == stcb->asoc.last_acked_seq)) &&
(stcb->asoc.saw_sack_with_frags == 0) &&
+ (stcb->asoc.saw_sack_with_nr_frags == 0) &&
(!TAILQ_EMPTY(&stcb->asoc.sent_queue))
) {
/*
@@ -4737,6 +4738,7 @@ process_control_chunks:
((compare_with_wrap(cum_ack, stcb->asoc.last_acked_seq, MAX_TSN)) ||
(cum_ack == stcb->asoc.last_acked_seq)) &&
(stcb->asoc.saw_sack_with_frags == 0) &&
+ (stcb->asoc.saw_sack_with_nr_frags == 0) &&
(!TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
/*
* We have a SIMPLE sack having no
diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h
index 56f4946..94d0395 100644
--- a/sys/netinet/sctp_structs.h
+++ b/sys/netinet/sctp_structs.h
@@ -1058,6 +1058,7 @@ struct sctp_association {
uint8_t delayed_connection;
uint8_t ifp_had_enobuf;
uint8_t saw_sack_with_frags;
+ uint8_t saw_sack_with_nr_frags;
uint8_t in_asocid_hash;
uint8_t assoc_up_sent;
uint8_t adaptation_needed;
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index c4ff308..fe8bada 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1053,15 +1053,6 @@ nd6_free(struct llentry *ln, int gc)
return (next);
}
- if (ln->ln_router || dr) {
- /*
- * rt6_flush must be called whether or not the neighbor
- * is in the Default Router List.
- * See a corresponding comment in nd6_na_input().
- */
- rt6_flush(&L3_ADDR_SIN6(ln)->sin6_addr, ifp);
- }
-
if (dr) {
/*
* Unreachablity of a router might affect the default
@@ -1077,8 +1068,28 @@ nd6_free(struct llentry *ln, int gc)
* or the entry itself will be deleted.
*/
ln->ln_state = ND6_LLINFO_INCOMPLETE;
+ }
+
+ if (ln->ln_router || dr) {
/*
+ * We need to unlock to avoid a LOR with rt6_flush() with the
+ * rnh and for the calls to pfxlist_onlink_check() and
+ * defrouter_select() in the block further down for calls
+ * into nd6_lookup(). We still hold a ref.
+ */
+ LLE_WUNLOCK(ln);
+
+ /*
+ * rt6_flush must be called whether or not the neighbor
+ * is in the Default Router List.
+ * See a corresponding comment in nd6_na_input().
+ */
+ rt6_flush(&L3_ADDR_SIN6(ln)->sin6_addr, ifp);
+ }
+
+ if (dr) {
+ /*
* Since defrouter_select() does not affect the
* on-link determination and MIP6 needs the check
* before the default router selection, we perform
@@ -1087,13 +1098,13 @@ nd6_free(struct llentry *ln, int gc)
pfxlist_onlink_check();
/*
- * Refresh default router list. Have to unlock as
- * it calls into nd6_lookup(), still holding a ref.
+ * Refresh default router list.
*/
- LLE_WUNLOCK(ln);
defrouter_select();
- LLE_WLOCK(ln);
}
+
+ if (ln->ln_router || dr)
+ LLE_WLOCK(ln);
}
/*
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 03933a6..5a27646 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -1092,12 +1092,16 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
thread_unlock(curthread);
#endif
+ tsc2 -= tsc1;
+ if (tsc_freq != 0 && !tsc_is_broken) {
+ *rate = tsc2 * 1000;
+ return (0);
+ }
+
/*
- * Calculate the difference in readings, convert to Mhz, and
- * subtract 0.5% of the total. Empirical testing has shown that
+ * Subtract 0.5% of the total. Empirical testing has shown that
* overhead in DELAY() works out to approximately this value.
*/
- tsc2 -= tsc1;
*rate = tsc2 * 1000 - tsc2 * 5;
return (0);
}
diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
index 7bd07e1..6f99081 100644
--- a/sys/powerpc/aim/mmu_oea.c
+++ b/sys/powerpc/aim/mmu_oea.c
@@ -161,24 +161,6 @@ __FBSDID("$FreeBSD$");
#define VSID_TO_SR(vsid) ((vsid) & 0xf)
#define VSID_TO_HASH(vsid) (((vsid) >> 4) & 0xfffff)
-#define PVO_PTEGIDX_MASK 0x007 /* which PTEG slot */
-#define PVO_PTEGIDX_VALID 0x008 /* slot is valid */
-#define PVO_WIRED 0x010 /* PVO entry is wired */
-#define PVO_MANAGED 0x020 /* PVO entry is managed */
-#define PVO_EXECUTABLE 0x040 /* PVO entry is executable */
-#define PVO_BOOTSTRAP 0x080 /* PVO entry allocated during
- bootstrap */
-#define PVO_FAKE 0x100 /* fictitious phys page */
-#define PVO_VADDR(pvo) ((pvo)->pvo_vaddr & ~ADDR_POFF)
-#define PVO_ISEXECUTABLE(pvo) ((pvo)->pvo_vaddr & PVO_EXECUTABLE)
-#define PVO_ISFAKE(pvo) ((pvo)->pvo_vaddr & PVO_FAKE)
-#define PVO_PTEGIDX_GET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_MASK)
-#define PVO_PTEGIDX_ISSET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_VALID)
-#define PVO_PTEGIDX_CLR(pvo) \
- ((void)((pvo)->pvo_vaddr &= ~(PVO_PTEGIDX_VALID|PVO_PTEGIDX_MASK)))
-#define PVO_PTEGIDX_SET(pvo, i) \
- ((void)((pvo)->pvo_vaddr |= (i)|PVO_PTEGIDX_VALID))
-
#define MOEA_PVO_CHECK(pvo)
struct ofw_map {
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 506676f..cd791f8 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -155,79 +155,13 @@ __FBSDID("$FreeBSD$");
#include <machine/trap.h>
#include <machine/mmuvar.h>
+#include "mmu_oea64.h"
#include "mmu_if.h"
+#include "moea64_if.h"
-#define MOEA_DEBUG
-
-#define TODO panic("%s: not implemented", __func__);
void moea64_release_vsid(uint64_t vsid);
uintptr_t moea64_get_unique_vsid(void);
-static __inline register_t
-cntlzd(volatile register_t a) {
- register_t b;
- __asm ("cntlzd %0, %1" : "=r"(b) : "r"(a));
- return b;
-}
-
-#define PTESYNC() __asm __volatile("ptesync");
-#define TLBSYNC() __asm __volatile("tlbsync; ptesync");
-#define SYNC() __asm __volatile("sync");
-#define EIEIO() __asm __volatile("eieio");
-
-/*
- * The tlbie instruction must be executed in 64-bit mode
- * so we have to twiddle MSR[SF] around every invocation.
- * Just to add to the fun, exceptions must be off as well
- * so that we can't trap in 64-bit mode. What a pain.
- */
-struct mtx tlbie_mutex;
-
-static __inline void
-TLBIE(uint64_t vpn) {
-#ifndef __powerpc64__
- register_t vpn_hi, vpn_lo;
- register_t msr;
- register_t scratch;
-#endif
-
- vpn <<= ADDR_PIDX_SHFT;
- vpn &= ~(0xffffULL << 48);
-
- mtx_lock_spin(&tlbie_mutex);
-#ifdef __powerpc64__
- __asm __volatile("\
- ptesync; \
- tlbie %0; \
- eieio; \
- tlbsync; \
- ptesync;"
- :: "r"(vpn) : "memory");
-#else
- vpn_hi = (uint32_t)(vpn >> 32);
- vpn_lo = (uint32_t)vpn;
-
- __asm __volatile("\
- mfmsr %0; \
- mr %1, %0; \
- insrdi %1,%5,1,0; \
- mtmsrd %1; isync; \
- ptesync; \
- \
- sld %1,%2,%4; \
- or %1,%1,%3; \
- tlbie %1; \
- \
- mtmsrd %0; isync; \
- eieio; \
- tlbsync; \
- ptesync;"
- : "=r"(msr), "=r"(scratch) : "r"(vpn_hi), "r"(vpn_lo), "r"(32), "r"(1)
- : "memory");
-#endif
- mtx_unlock_spin(&tlbie_mutex);
-}
-
#define DISABLE_TRANS(msr) msr = mfmsr(); mtmsr(msr & ~PSL_DR); isync()
#define ENABLE_TRANS(msr) mtmsr(msr); isync()
@@ -235,24 +169,6 @@ TLBIE(uint64_t vpn) {
#define VSID_TO_HASH(vsid) (((vsid) >> 4) & 0xfffff)
#define VSID_HASH_MASK 0x0000007fffffffffULL
-#define PVO_PTEGIDX_MASK 0x007UL /* which PTEG slot */
-#define PVO_PTEGIDX_VALID 0x008UL /* slot is valid */
-#define PVO_WIRED 0x010UL /* PVO entry is wired */
-#define PVO_MANAGED 0x020UL /* PVO entry is managed */
-#define PVO_BOOTSTRAP 0x080UL /* PVO entry allocated during
- bootstrap */
-#define PVO_FAKE 0x100UL /* fictitious phys page */
-#define PVO_LARGE 0x200UL /* large page */
-#define PVO_VADDR(pvo) ((pvo)->pvo_vaddr & ~ADDR_POFF)
-#define PVO_ISFAKE(pvo) ((pvo)->pvo_vaddr & PVO_FAKE)
-#define PVO_PTEGIDX_GET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_MASK)
-#define PVO_PTEGIDX_ISSET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_VALID)
-#define PVO_PTEGIDX_CLR(pvo) \
- ((void)((pvo)->pvo_vaddr &= ~(PVO_PTEGIDX_VALID|PVO_PTEGIDX_MASK)))
-#define PVO_PTEGIDX_SET(pvo, i) \
- ((void)((pvo)->pvo_vaddr |= (i)|PVO_PTEGIDX_VALID))
-#define PVO_VSID(pvo) ((pvo)->pvo_vpn >> 16)
-
#define MOEA_PVO_CHECK(pvo)
#define LOCK_TABLE() mtx_lock(&moea64_table_mutex)
@@ -277,7 +193,6 @@ static int regions_sz, pregions_sz;
extern void bs_remap_earlyboot(void);
-
/*
* Lock for the pteg and pvo tables.
*/
@@ -287,7 +202,6 @@ struct mtx moea64_slb_mutex;
/*
* PTEG data.
*/
-static struct lpteg *moea64_pteg_table;
u_int moea64_pteg_count;
u_int moea64_pteg_mask;
@@ -337,8 +251,8 @@ SYSCTL_INT(_machdep, OID_AUTO, moea64_pvo_remove_calls, CTLFLAG_RD,
&moea64_pvo_remove_calls, 0, "");
vm_offset_t moea64_scratchpage_va[2];
-uint64_t moea64_scratchpage_vpn[2];
-struct lpte *moea64_scratchpage_pte[2];
+struct pvo_entry *moea64_scratchpage_pvo[2];
+uintptr_t moea64_scratchpage_pte[2];
struct mtx moea64_scratchpage_mtx;
uint64_t moea64_large_page_mask = 0;
@@ -346,41 +260,23 @@ int moea64_large_page_size = 0;
int moea64_large_page_shift = 0;
/*
- * Allocate physical memory for use in moea64_bootstrap.
- */
-static vm_offset_t moea64_bootstrap_alloc(vm_size_t, u_int);
-
-/*
- * PTE calls.
- */
-static int moea64_pte_insert(u_int, struct lpte *);
-
-/*
* PVO calls.
*/
-static int moea64_pvo_enter(pmap_t, uma_zone_t, struct pvo_head *,
+static int moea64_pvo_enter(mmu_t, pmap_t, uma_zone_t, struct pvo_head *,
vm_offset_t, vm_offset_t, uint64_t, int);
-static void moea64_pvo_remove(struct pvo_entry *);
+static void moea64_pvo_remove(mmu_t, struct pvo_entry *);
static struct pvo_entry *moea64_pvo_find_va(pmap_t, vm_offset_t);
-static struct lpte *moea64_pvo_to_pte(const struct pvo_entry *);
/*
* Utility routines.
*/
-static void moea64_bootstrap(mmu_t mmup,
- vm_offset_t kernelstart, vm_offset_t kernelend);
-static void moea64_cpu_bootstrap(mmu_t, int ap);
-static void moea64_enter_locked(pmap_t, vm_offset_t, vm_page_t,
- vm_prot_t, boolean_t);
-static boolean_t moea64_query_bit(vm_page_t, u_int64_t);
-static u_int moea64_clear_bit(vm_page_t, u_int64_t);
+static void moea64_enter_locked(mmu_t, pmap_t, vm_offset_t,
+ vm_page_t, vm_prot_t, boolean_t);
+static boolean_t moea64_query_bit(mmu_t, vm_page_t, u_int64_t);
+static u_int moea64_clear_bit(mmu_t, vm_page_t, u_int64_t);
static void moea64_kremove(mmu_t, vm_offset_t);
-static void moea64_syncicache(pmap_t pmap, vm_offset_t va,
+static void moea64_syncicache(mmu_t, pmap_t pmap, vm_offset_t va,
vm_offset_t pa, vm_size_t sz);
-static void tlbia(void);
-#ifdef __powerpc64__
-static void slbia(void);
-#endif
/*
* Kernel MMU interface
@@ -463,8 +359,6 @@ static mmu_method_t moea64_methods[] = {
MMUMETHOD(mmu_page_set_memattr, moea64_page_set_memattr),
/* Internal interfaces */
- MMUMETHOD(mmu_bootstrap, moea64_bootstrap),
- MMUMETHOD(mmu_cpu_bootstrap, moea64_cpu_bootstrap),
MMUMETHOD(mmu_mapdev, moea64_mapdev),
MMUMETHOD(mmu_mapdev_attr, moea64_mapdev_attr),
MMUMETHOD(mmu_unmapdev, moea64_unmapdev),
@@ -476,7 +370,7 @@ static mmu_method_t moea64_methods[] = {
{ 0, 0 }
};
-MMU_DEF(oea64_mmu, MMU_TYPE_G5, moea64_methods, 0);
+MMU_DEF(oea64_mmu, "mmu_oea64_base", moea64_methods, 0);
static __inline u_int
va_to_pteg(uint64_t vsid, vm_offset_t addr, int large)
@@ -542,81 +436,6 @@ moea64_pte_create(struct lpte *pt, uint64_t vsid, vm_offset_t va,
pt->pte_lo = pte_lo;
}
-static __inline void
-moea64_pte_synch(struct lpte *pt, struct lpte *pvo_pt)
-{
-
- ASSERT_TABLE_LOCK();
-
- pvo_pt->pte_lo |= pt->pte_lo & (LPTE_REF | LPTE_CHG);
-}
-
-static __inline void
-moea64_pte_clear(struct lpte *pt, uint64_t vpn, u_int64_t ptebit)
-{
- ASSERT_TABLE_LOCK();
-
- /*
- * As shown in Section 7.6.3.2.3
- */
- pt->pte_lo &= ~ptebit;
- TLBIE(vpn);
-}
-
-static __inline void
-moea64_pte_set(struct lpte *pt, struct lpte *pvo_pt)
-{
-
- ASSERT_TABLE_LOCK();
- pvo_pt->pte_hi |= LPTE_VALID;
-
- /*
- * Update the PTE as defined in section 7.6.3.1.
- * Note that the REF/CHG bits are from pvo_pt and thus should have
- * been saved so this routine can restore them (if desired).
- */
- pt->pte_lo = pvo_pt->pte_lo;
- EIEIO();
- pt->pte_hi = pvo_pt->pte_hi;
- PTESYNC();
- moea64_pte_valid++;
-}
-
-static __inline void
-moea64_pte_unset(struct lpte *pt, struct lpte *pvo_pt, uint64_t vpn)
-{
- ASSERT_TABLE_LOCK();
- pvo_pt->pte_hi &= ~LPTE_VALID;
-
- /*
- * Force the reg & chg bits back into the PTEs.
- */
- SYNC();
-
- /*
- * Invalidate the pte.
- */
- pt->pte_hi &= ~LPTE_VALID;
- TLBIE(vpn);
-
- /*
- * Save the reg & chg bits.
- */
- moea64_pte_synch(pt, pvo_pt);
- moea64_pte_valid--;
-}
-
-static __inline void
-moea64_pte_change(struct lpte *pt, struct lpte *pvo_pt, uint64_t vpn)
-{
-
- /*
- * Invalidate the PTE
- */
- moea64_pte_unset(pt, pvo_pt, vpn);
- moea64_pte_set(pt, pvo_pt);
-}
-
static __inline uint64_t
moea64_calc_wimg(vm_offset_t pa, vm_memattr_t ma)
{
@@ -696,49 +515,6 @@ om_cmp(const void *a, const void *b)
}
static void
-moea64_cpu_bootstrap(mmu_t mmup, int ap)
-{
- int i = 0;
- #ifdef __powerpc64__
- struct slb *slb = PCPU_GET(slb);
- #endif
-
- /*
- * Initialize segment registers and MMU
- */
-
- mtmsr(mfmsr() & ~PSL_DR & ~PSL_IR); isync();
-
- /*
- * Install kernel SLB entries
- */
-
- #ifdef __powerpc64__
- slbia();
-
- for (i = 0; i < 64; i++) {
- if (!(slb[i].slbe & SLBE_VALID))
- continue;
-
- __asm __volatile ("slbmte %0, %1" ::
- "r"(slb[i].slbv), "r"(slb[i].slbe));
- }
- #else
- for (i = 0; i < 16; i++)
- mtsrin(i << ADDR_SR_SHFT, kernel_pmap->pm_sr[i]);
- #endif
-
- /*
- * Install page table
- */
-
- __asm __volatile ("ptesync; mtsdr1 %0; isync"
- :: "r"((uintptr_t)moea64_pteg_table
- | (64 - cntlzd(moea64_pteg_mask >> 11))));
- tlbia();
-}
-
-static void
moea64_add_ofw_mappings(mmu_t mmup, phandle_t mmu, size_t sz)
{
struct ofw_map translations[sz/sizeof(struct ofw_map)];
@@ -874,7 +650,7 @@ moea64_setup_direct_map(mmu_t mmup, vm_offset_t kernelstart,
pregions[i].mr_start + pregions[i].mr_size)
pte_lo |= LPTE_G;
- moea64_pvo_enter(kernel_pmap, moea64_upvo_zone,
+ moea64_pvo_enter(mmup, kernel_pmap, moea64_upvo_zone,
&moea64_pvo_kunmanaged, pa, pa,
pte_lo, PVO_WIRED | PVO_LARGE |
VM_PROT_EXECUTE);
@@ -882,10 +658,6 @@ moea64_setup_direct_map(mmu_t mmup, vm_offset_t kernelstart,
}
PMAP_UNLOCK(kernel_pmap);
} else {
- size = moea64_pteg_count * sizeof(struct lpteg);
- off = (vm_offset_t)(moea64_pteg_table);
- for (pa = off; pa < off + size; pa += PAGE_SIZE)
- moea64_kenter(mmup, pa, pa);
size = sizeof(struct pvo_head) * moea64_pteg_count;
off = (vm_offset_t)(moea64_pvo_table);
for (pa = off; pa < off + size; pa += PAGE_SIZE)
@@ -911,18 +683,11 @@ moea64_setup_direct_map(mmu_t mmup, vm_offset_t kernelstart,
ENABLE_TRANS(msr);
}
-static void
-moea64_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
+void
+moea64_early_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
{
- ihandle_t mmui;
- phandle_t chosen;
- phandle_t mmu;
- size_t sz;
int i, j;
- vm_size_t size, physsz, hwphyssz;
- vm_offset_t pa, va;
- register_t msr;
- void *dpcpu;
+ vm_size_t physsz, hwphyssz;
#ifndef __powerpc64__
/* We don't have a direct map since there is no BAT */
@@ -1009,9 +774,6 @@ moea64_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
physmem = btoc(physsz);
- /*
- * Allocate PTEG table.
- */
#ifdef PTEGCOUNT
moea64_pteg_count = PTEGCOUNT;
#else
@@ -1022,27 +784,20 @@ moea64_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
moea64_pteg_count >>= 1;
#endif /* PTEGCOUNT */
+}
- size = moea64_pteg_count * sizeof(struct lpteg);
- CTR2(KTR_PMAP, "moea64_bootstrap: %d PTEGs, %d bytes",
- moea64_pteg_count, size);
+void
+moea64_mid_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
+{
+ vm_size_t size;
+ register_t msr;
+ int i;
/*
- * We now need to allocate memory. This memory, to be allocated,
- * has to reside in a page table. The page table we are about to
- * allocate. We don't have BAT. So drop to data real mode for a minute
- * as a measure of last resort. We do this a couple times.
+ * Set PTEG mask
*/
-
- moea64_pteg_table = (struct lpteg *)moea64_bootstrap_alloc(size, size);
- DISABLE_TRANS(msr);
- bzero((void *)moea64_pteg_table, moea64_pteg_count * sizeof(struct lpteg));
- ENABLE_TRANS(msr);
-
moea64_pteg_mask = moea64_pteg_count - 1;
- CTR1(KTR_PMAP, "moea64_bootstrap: PTEG table at %p", moea64_pteg_table);
-
/*
* Allocate pv/overflow lists.
*/
@@ -1066,11 +821,6 @@ moea64_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
mtx_init(&moea64_slb_mutex, "SLB table", NULL, MTX_DEF);
/*
- * Initialize the TLBIE lock. TLBIE can only be executed by one CPU.
- */
- mtx_init(&tlbie_mutex, "tlbie mutex", NULL, MTX_SPIN);
-
- /*
* Initialise the unmanaged pvo pool.
*/
moea64_bpvo_pool = (struct pvo_entry *)moea64_bootstrap_alloc(
@@ -1109,6 +859,18 @@ moea64_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
*/
moea64_setup_direct_map(mmup, kernelstart, kernelend);
+}
+
+void
+moea64_late_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
+{
+ ihandle_t mmui;
+ phandle_t chosen;
+ phandle_t mmu;
+ size_t sz;
+ int i;
+ vm_offset_t pa, va;
+ void *dpcpu;
/*
* Set up the Open Firmware pmap and add its mappings if not in real
@@ -1137,7 +899,7 @@ moea64_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
/*
* Initialize MMU and remap early physical mappings
*/
- moea64_cpu_bootstrap(mmup,0);
+ MMU_CPU_BOOTSTRAP(mmup,0);
mtmsr(mfmsr() | PSL_DR | PSL_IR); isync();
pmap_bootstrapped++;
bs_remap_earlyboot();
@@ -1173,47 +935,6 @@ moea64_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
#endif
/*
- * Allocate some things for page zeroing. We put this directly
- * in the page table, marked with LPTE_LOCKED, to avoid any
- * of the PVO book-keeping or other parts of the VM system
- * from even knowing that this hack exists.
- */
-
- if (!hw_direct_map) {
- mtx_init(&moea64_scratchpage_mtx, "pvo zero page", NULL,
- MTX_DEF);
- for (i = 0; i < 2; i++) {
- struct lpte pt;
- uint64_t vsid;
- int pteidx, ptegidx;
-
- moea64_scratchpage_va[i] = (virtual_end+1) - PAGE_SIZE;
- virtual_end -= PAGE_SIZE;
-
- LOCK_TABLE();
-
- vsid = va_to_vsid(kernel_pmap,
- moea64_scratchpage_va[i]);
- moea64_pte_create(&pt, vsid, moea64_scratchpage_va[i],
- LPTE_NOEXEC, 0);
- pt.pte_hi |= LPTE_LOCKED;
-
- moea64_scratchpage_vpn[i] = (vsid << 16) |
- ((moea64_scratchpage_va[i] & ADDR_PIDX) >>
- ADDR_PIDX_SHFT);
- ptegidx = va_to_pteg(vsid, moea64_scratchpage_va[i], 0);
- pteidx = moea64_pte_insert(ptegidx, &pt);
- if (pt.pte_hi & LPTE_HID)
- ptegidx ^= moea64_pteg_mask;
-
- moea64_scratchpage_pte[i] =
- &moea64_pteg_table[ptegidx].pt[pteidx];
-
- UNLOCK_TABLE();
- }
- }
-
- /*
* Allocate a kernel stack with a guard page for thread0 and map it
* into the kernel page map.
*/
@@ -1255,6 +976,36 @@ moea64_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
va += PAGE_SIZE;
}
dpcpu_init(dpcpu, 0);
+
+ /*
+ * Allocate some things for page zeroing. We put this directly
+ * in the page table, marked with LPTE_LOCKED, to avoid any
+ * of the PVO book-keeping or other parts of the VM system
+ * from even knowing that this hack exists.
+ */
+
+ if (!hw_direct_map) {
+ mtx_init(&moea64_scratchpage_mtx, "pvo zero page", NULL,
+ MTX_DEF);
+ for (i = 0; i < 2; i++) {
+ moea64_scratchpage_va[i] = (virtual_end+1) - PAGE_SIZE;
+ virtual_end -= PAGE_SIZE;
+
+ moea64_kenter(mmup, moea64_scratchpage_va[i], 0);
+
+ moea64_scratchpage_pvo[i] = moea64_pvo_find_va(
+ kernel_pmap, (vm_offset_t)moea64_scratchpage_va[i]);
+ LOCK_TABLE();
+ moea64_scratchpage_pte[i] = MOEA64_PVO_TO_PTE(
+ mmup, moea64_scratchpage_pvo[i]);
+ moea64_scratchpage_pvo[i]->pvo_pte.lpte.pte_hi
+ |= LPTE_LOCKED;
+ MOEA64_PTE_CHANGE(mmup, moea64_scratchpage_pte[i],
+ &moea64_scratchpage_pvo[i]->pvo_pte.lpte,
+ moea64_scratchpage_pvo[i]->pvo_vpn);
+ UNLOCK_TABLE();
+ }
+ }
}
/*
@@ -1294,7 +1045,7 @@ void
moea64_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired)
{
struct pvo_entry *pvo;
- struct lpte *pt;
+ uintptr_t pt;
uint64_t vsid;
int i, ptegidx;
@@ -1303,7 +1054,7 @@ moea64_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired)
if (pvo != NULL) {
LOCK_TABLE();
- pt = moea64_pvo_to_pte(pvo);
+ pt = MOEA64_PVO_TO_PTE(mmu, pvo);
if (wired) {
if ((pvo->pvo_vaddr & PVO_WIRED) == 0)
@@ -1317,9 +1068,9 @@ moea64_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired)
pvo->pvo_pte.lpte.pte_hi &= ~LPTE_WIRED;
}
- if (pt != NULL) {
+ if (pt != -1) {
/* Update wiring flag in page table. */
- moea64_pte_change(pt, &pvo->pvo_pte.lpte,
+ MOEA64_PTE_CHANGE(mmu, pt, &pvo->pvo_pte.lpte,
pvo->pvo_vpn);
} else if (wired) {
/*
@@ -1330,7 +1081,8 @@ moea64_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired)
ptegidx = va_to_pteg(vsid, PVO_VADDR(pvo),
pvo->pvo_vaddr & PVO_LARGE);
- i = moea64_pte_insert(ptegidx, &pvo->pvo_pte.lpte);
+ i = MOEA64_PTE_INSERT(mmu, ptegidx, &pvo->pvo_pte.lpte);
+
if (i >= 0) {
PVO_PTEGIDX_CLR(pvo);
PVO_PTEGIDX_SET(pvo, i);
@@ -1350,22 +1102,18 @@ moea64_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired)
*/
static __inline
-void moea64_set_scratchpage_pa(int which, vm_offset_t pa) {
+void moea64_set_scratchpage_pa(mmu_t mmup, int which, vm_offset_t pa) {
KASSERT(!hw_direct_map, ("Using OEA64 scratchpage with a direct map!"));
mtx_assert(&moea64_scratchpage_mtx, MA_OWNED);
- moea64_scratchpage_pte[which]->pte_hi &= ~LPTE_VALID;
- TLBIE(moea64_scratchpage_vpn[which]);
-
- moea64_scratchpage_pte[which]->pte_lo &=
+ moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo &=
~(LPTE_WIMG | LPTE_RPGN);
- moea64_scratchpage_pte[which]->pte_lo |=
+ moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo |=
moea64_calc_wimg(pa, VM_MEMATTR_DEFAULT) | (uint64_t)pa;
- EIEIO();
-
- moea64_scratchpage_pte[which]->pte_hi |= LPTE_VALID;
- PTESYNC(); isync();
+ MOEA64_PTE_CHANGE(mmup, moea64_scratchpage_pte[which],
+ &moea64_scratchpage_pvo[which]->pvo_pte.lpte,
+ moea64_scratchpage_pvo[which]->pvo_vpn);
}
void
@@ -1382,8 +1130,8 @@ moea64_copy_page(mmu_t mmu, vm_page_t msrc, vm_page_t mdst)
} else {
mtx_lock(&moea64_scratchpage_mtx);
- moea64_set_scratchpage_pa(0,src);
- moea64_set_scratchpage_pa(1,dst);
+ moea64_set_scratchpage_pa(mmu, 0, src);
+ moea64_set_scratchpage_pa(mmu, 1, dst);
kcopy((void *)moea64_scratchpage_va[0],
(void *)moea64_scratchpage_va[1], PAGE_SIZE);
@@ -1406,7 +1154,7 @@ moea64_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size)
bzero((caddr_t)pa + off, size);
} else {
mtx_lock(&moea64_scratchpage_mtx);
- moea64_set_scratchpage_pa(0,pa);
+ moea64_set_scratchpage_pa(mmu, 0, pa);
bzero((caddr_t)moea64_scratchpage_va[0] + off, size);
mtx_unlock(&moea64_scratchpage_mtx);
}
@@ -1427,7 +1175,7 @@ moea64_zero_page(mmu_t mmu, vm_page_t m)
if (!hw_direct_map) {
mtx_lock(&moea64_scratchpage_mtx);
- moea64_set_scratchpage_pa(0,pa);
+ moea64_set_scratchpage_pa(mmu, 0, pa);
va = moea64_scratchpage_va[0];
} else {
va = pa;
@@ -1459,7 +1207,7 @@ moea64_enter(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
vm_page_lock_queues();
PMAP_LOCK(pmap);
- moea64_enter_locked(pmap, va, m, prot, wired);
+ moea64_enter_locked(mmu, pmap, va, m, prot, wired);
vm_page_unlock_queues();
PMAP_UNLOCK(pmap);
}
@@ -1473,8 +1221,8 @@ moea64_enter(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
*/
static void
-moea64_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
- boolean_t wired)
+moea64_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m,
+ vm_prot_t prot, boolean_t wired)
{
struct pvo_head *pvo_head;
uma_zone_t zone;
@@ -1528,20 +1276,20 @@ moea64_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
if ((m->flags & PG_FICTITIOUS) != 0)
pvo_flags |= PVO_FAKE;
- error = moea64_pvo_enter(pmap, zone, pvo_head, va, VM_PAGE_TO_PHYS(m),
- pte_lo, pvo_flags);
+ error = moea64_pvo_enter(mmu, pmap, zone, pvo_head, va,
+ VM_PAGE_TO_PHYS(m), pte_lo, pvo_flags);
/*
* Flush the page from the instruction cache if this page is
* mapped executable and cacheable.
*/
- if ((pte_lo & (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) {
- moea64_syncicache(pmap, va, VM_PAGE_TO_PHYS(m), PAGE_SIZE);
- }
+ if ((pte_lo & (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0)
+ moea64_syncicache(mmu, pmap, va, VM_PAGE_TO_PHYS(m), PAGE_SIZE);
}
static void
-moea64_syncicache(pmap_t pmap, vm_offset_t va, vm_offset_t pa, vm_size_t sz)
+moea64_syncicache(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_offset_t pa,
+ vm_size_t sz)
{
/*
@@ -1568,7 +1316,7 @@ moea64_syncicache(pmap_t pmap, vm_offset_t va, vm_offset_t pa, vm_size_t sz)
mtx_lock(&moea64_scratchpage_mtx);
- moea64_set_scratchpage_pa(1,pa & ~ADDR_POFF);
+ moea64_set_scratchpage_pa(mmu, 1, pa & ~ADDR_POFF);
__syncicache((void *)(moea64_scratchpage_va[1] +
(va & ADDR_POFF)), sz);
@@ -1600,7 +1348,7 @@ moea64_enter_object(mmu_t mmu, pmap_t pm, vm_offset_t start, vm_offset_t end,
vm_page_lock_queues();
PMAP_LOCK(pm);
while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
- moea64_enter_locked(pm, start + ptoa(diff), m, prot &
+ moea64_enter_locked(mmu, pm, start + ptoa(diff), m, prot &
(VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
m = TAILQ_NEXT(m, listq);
}
@@ -1615,8 +1363,8 @@ moea64_enter_quick(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_page_t m,
vm_page_lock_queues();
PMAP_LOCK(pm);
- moea64_enter_locked(pm, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE),
- FALSE);
+ moea64_enter_locked(mmu, pm, va, m,
+ prot & (VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
vm_page_unlock_queues();
PMAP_UNLOCK(pm);
}
@@ -1669,6 +1417,8 @@ retry:
return (m);
}
+static mmu_t installed_mmu;
+
static void *
moea64_uma_page_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
{
@@ -1709,7 +1459,7 @@ moea64_uma_page_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
va = VM_PAGE_TO_PHYS(m);
- moea64_pvo_enter(kernel_pmap, moea64_upvo_zone,
+ moea64_pvo_enter(installed_mmu, kernel_pmap, moea64_upvo_zone,
&moea64_pvo_kunmanaged, va, VM_PAGE_TO_PHYS(m), LPTE_M,
PVO_WIRED | PVO_BOOTSTRAP);
@@ -1736,6 +1486,7 @@ moea64_init(mmu_t mmu)
UMA_ZONE_VM | UMA_ZONE_NOFREE);
if (!hw_direct_map) {
+ installed_mmu = mmu;
uma_zone_set_allocf(moea64_upvo_zone,moea64_uma_page_alloc);
uma_zone_set_allocf(moea64_mpvo_zone,moea64_uma_page_alloc);
}
@@ -1749,7 +1500,7 @@ moea64_is_referenced(mmu_t mmu, vm_page_t m)
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
("moea64_is_referenced: page %p is not managed", m));
- return (moea64_query_bit(m, PTE_REF));
+ return (moea64_query_bit(mmu, m, PTE_REF));
}
boolean_t
@@ -1768,7 +1519,7 @@ moea64_is_modified(mmu_t mmu, vm_page_t m)
if ((m->oflags & VPO_BUSY) == 0 &&
(m->flags & PG_WRITEABLE) == 0)
return (FALSE);
- return (moea64_query_bit(m, LPTE_CHG));
+ return (moea64_query_bit(mmu, m, LPTE_CHG));
}
boolean_t
@@ -1790,7 +1541,7 @@ moea64_clear_reference(mmu_t mmu, vm_page_t m)
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
("moea64_clear_reference: page %p is not managed", m));
- moea64_clear_bit(m, LPTE_REF);
+ moea64_clear_bit(mmu, m, LPTE_REF);
}
void
@@ -1810,7 +1561,7 @@ moea64_clear_modify(mmu_t mmu, vm_page_t m)
*/
if ((m->flags & PG_WRITEABLE) == 0)
return;
- moea64_clear_bit(m, LPTE_CHG);
+ moea64_clear_bit(mmu, m, LPTE_CHG);
}
/*
@@ -1820,7 +1571,7 @@ void
moea64_remove_write(mmu_t mmu, vm_page_t m)
{
struct pvo_entry *pvo;
- struct lpte *pt;
+ uintptr_t pt;
pmap_t pmap;
uint64_t lo;
@@ -1838,21 +1589,21 @@ moea64_remove_write(mmu_t mmu, vm_page_t m)
return;
vm_page_lock_queues();
lo = moea64_attr_fetch(m);
- SYNC();
+ powerpc_sync();
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
pmap = pvo->pvo_pmap;
PMAP_LOCK(pmap);
LOCK_TABLE();
if ((pvo->pvo_pte.lpte.pte_lo & LPTE_PP) != LPTE_BR) {
- pt = moea64_pvo_to_pte(pvo);
+ pt = MOEA64_PVO_TO_PTE(mmu, pvo);
pvo->pvo_pte.lpte.pte_lo &= ~LPTE_PP;
pvo->pvo_pte.lpte.pte_lo |= LPTE_BR;
- if (pt != NULL) {
- moea64_pte_synch(pt, &pvo->pvo_pte.lpte);
+ if (pt != -1) {
+ MOEA64_PTE_SYNCH(mmu, pt, &pvo->pvo_pte.lpte);
lo |= pvo->pvo_pte.lpte.pte_lo;
pvo->pvo_pte.lpte.pte_lo &= ~LPTE_CHG;
- moea64_pte_change(pt, &pvo->pvo_pte.lpte,
- pvo->pvo_vpn);
+ MOEA64_PTE_CHANGE(mmu, pt,
+ &pvo->pvo_pte.lpte, pvo->pvo_vpn);
if (pvo->pvo_pmap == kernel_pmap)
isync();
}
@@ -1886,7 +1637,7 @@ moea64_ts_referenced(mmu_t mmu, vm_page_t m)
KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
("moea64_ts_referenced: page %p is not managed", m));
- return (moea64_clear_bit(m, LPTE_REF));
+ return (moea64_clear_bit(mmu, m, LPTE_REF));
}
/*
@@ -1897,7 +1648,7 @@ moea64_page_set_memattr(mmu_t mmu, vm_page_t m, vm_memattr_t ma)
{
struct pvo_entry *pvo;
struct pvo_head *pvo_head;
- struct lpte *pt;
+ uintptr_t pt;
pmap_t pmap;
uint64_t lo;
@@ -1913,11 +1664,11 @@ moea64_page_set_memattr(mmu_t mmu, vm_page_t m, vm_memattr_t ma)
pmap = pvo->pvo_pmap;
PMAP_LOCK(pmap);
LOCK_TABLE();
- pt = moea64_pvo_to_pte(pvo);
+ pt = MOEA64_PVO_TO_PTE(mmu, pvo);
pvo->pvo_pte.lpte.pte_lo &= ~LPTE_WIMG;
pvo->pvo_pte.lpte.pte_lo |= lo;
- if (pt != NULL) {
- moea64_pte_change(pt, &pvo->pvo_pte.lpte,
+ if (pt != -1) {
+ MOEA64_PTE_CHANGE(mmu, pt, &pvo->pvo_pte.lpte,
pvo->pvo_vpn);
if (pvo->pvo_pmap == kernel_pmap)
isync();
@@ -1941,7 +1692,7 @@ moea64_kenter_attr(mmu_t mmu, vm_offset_t va, vm_offset_t pa, vm_memattr_t ma)
pte_lo = moea64_calc_wimg(pa, ma);
PMAP_LOCK(kernel_pmap);
- error = moea64_pvo_enter(kernel_pmap, moea64_upvo_zone,
+ error = moea64_pvo_enter(mmu, kernel_pmap, moea64_upvo_zone,
&moea64_pvo_kunmanaged, va, pa, pte_lo,
PVO_WIRED | VM_PROT_EXECUTE);
@@ -1952,9 +1703,8 @@ moea64_kenter_attr(mmu_t mmu, vm_offset_t va, vm_offset_t pa, vm_memattr_t ma)
/*
* Flush the memory from the instruction cache.
*/
- if ((pte_lo & (LPTE_I | LPTE_G)) == 0) {
+ if ((pte_lo & (LPTE_I | LPTE_G)) == 0)
__syncicache((void *)va, PAGE_SIZE);
- }
PMAP_UNLOCK(kernel_pmap);
}
@@ -2183,7 +1933,7 @@ moea64_protect(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva,
vm_prot_t prot)
{
struct pvo_entry *pvo;
- struct lpte *pt;
+ uintptr_t pt;
CTR4(KTR_PMAP, "moea64_protect: pm=%p sva=%#x eva=%#x prot=%#x", pm, sva,
eva, prot);
@@ -2209,7 +1959,7 @@ moea64_protect(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva,
* copy.
*/
LOCK_TABLE();
- pt = moea64_pvo_to_pte(pvo);
+ pt = MOEA64_PVO_TO_PTE(mmu, pvo);
/*
* Change the protection of the page.
@@ -2223,11 +1973,12 @@ moea64_protect(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva,
/*
* If the PVO is in the page table, update that pte as well.
*/
- if (pt != NULL) {
- moea64_pte_change(pt, &pvo->pvo_pte.lpte, pvo->pvo_vpn);
+ if (pt != -1) {
+ MOEA64_PTE_CHANGE(mmu, pt, &pvo->pvo_pte.lpte,
+ pvo->pvo_vpn);
if ((pvo->pvo_pte.lpte.pte_lo &
(LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) {
- moea64_syncicache(pm, sva,
+ moea64_syncicache(mmu, pm, sva,
pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN,
PAGE_SIZE);
}
@@ -2314,7 +2065,7 @@ moea64_remove(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva)
for (; sva < eva; sva += PAGE_SIZE) {
pvo = moea64_pvo_find_va(pm, sva);
if (pvo != NULL)
- moea64_pvo_remove(pvo);
+ moea64_pvo_remove(mmu, pvo);
}
vm_page_unlock_queues();
PMAP_UNLOCK(pm);
@@ -2339,7 +2090,7 @@ moea64_remove_all(mmu_t mmu, vm_page_t m)
MOEA_PVO_CHECK(pvo); /* sanity check */
pmap = pvo->pvo_pmap;
PMAP_LOCK(pmap);
- moea64_pvo_remove(pvo);
+ moea64_pvo_remove(mmu, pvo);
PMAP_UNLOCK(pmap);
}
if ((m->flags & PG_WRITEABLE) && moea64_is_modified(mmu, m)) {
@@ -2355,7 +2106,7 @@ moea64_remove_all(mmu_t mmu, vm_page_t m)
* Can only be called from moea64_bootstrap before avail start and end are
* calculated.
*/
-static vm_offset_t
+vm_offset_t
moea64_bootstrap_alloc(vm_size_t size, u_int align)
{
vm_offset_t s, e;
@@ -2396,53 +2147,10 @@ moea64_bootstrap_alloc(vm_size_t size, u_int align)
panic("moea64_bootstrap_alloc: could not allocate memory");
}
-static void
-tlbia(void)
-{
- vm_offset_t i;
- #ifndef __powerpc64__
- register_t msr, scratch;
- #endif
-
- TLBSYNC();
-
- for (i = 0; i < 0xFF000; i += 0x00001000) {
- #ifdef __powerpc64__
- __asm __volatile("tlbiel %0" :: "r"(i));
- #else
- __asm __volatile("\
- mfmsr %0; \
- mr %1, %0; \
- insrdi %1,%3,1,0; \
- mtmsrd %1; \
- isync; \
- \
- tlbiel %2; \
- \
- mtmsrd %0; \
- isync;"
- : "=r"(msr), "=r"(scratch) : "r"(i), "r"(1));
- #endif
- }
-
- EIEIO();
- TLBSYNC();
-}
-
-#ifdef __powerpc64__
-static void
-slbia(void)
-{
- register_t seg0;
-
- __asm __volatile ("slbia");
- __asm __volatile ("slbmfee %0,%1; slbie %0;" : "=r"(seg0) : "r"(0));
-}
-#endif
-
static int
-moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
- vm_offset_t va, vm_offset_t pa, uint64_t pte_lo, int flags)
+moea64_pvo_enter(mmu_t mmu, pmap_t pm, uma_zone_t zone,
+ struct pvo_head *pvo_head, vm_offset_t va, vm_offset_t pa,
+ uint64_t pte_lo, int flags)
{
struct pvo_entry *pvo;
uint64_t vsid;
@@ -2488,7 +2196,7 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
(pte_lo & LPTE_PP)) {
if (!(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID)) {
/* Re-insert if spilled */
- i = moea64_pte_insert(ptegidx,
+ i = MOEA64_PTE_INSERT(mmu, ptegidx,
&pvo->pvo_pte.lpte);
if (i >= 0)
PVO_PTEGIDX_SET(pvo, i);
@@ -2497,7 +2205,7 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
UNLOCK_TABLE();
return (0);
}
- moea64_pvo_remove(pvo);
+ moea64_pvo_remove(mmu, pvo);
break;
}
}
@@ -2572,7 +2280,7 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
/*
* We hope this succeeds but it isn't required.
*/
- i = moea64_pte_insert(ptegidx, &pvo->pvo_pte.lpte);
+ i = MOEA64_PTE_INSERT(mmu, ptegidx, &pvo->pvo_pte.lpte);
if (i >= 0) {
PVO_PTEGIDX_SET(pvo, i);
} else {
@@ -2598,18 +2306,18 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
}
static void
-moea64_pvo_remove(struct pvo_entry *pvo)
+moea64_pvo_remove(mmu_t mmu, struct pvo_entry *pvo)
{
- struct lpte *pt;
+ uintptr_t pt;
/*
* If there is an active pte entry, we need to deactivate it (and
* save the ref & cfg bits).
*/
LOCK_TABLE();
- pt = moea64_pvo_to_pte(pvo);
- if (pt != NULL) {
- moea64_pte_unset(pt, &pvo->pvo_pte.lpte, pvo->pvo_vpn);
+ pt = MOEA64_PVO_TO_PTE(mmu, pvo);
+ if (pt != -1) {
+ MOEA64_PTE_UNSET(mmu, pt, &pvo->pvo_pte.lpte, pvo->pvo_vpn);
PVO_PTEGIDX_CLR(pvo);
} else {
moea64_pte_overflow--;
@@ -2698,192 +2406,11 @@ moea64_pvo_find_va(pmap_t pm, vm_offset_t va)
return (pvo);
}
-static struct lpte *
-moea64_pvo_to_pte(const struct pvo_entry *pvo)
-{
- struct lpte *pt;
- int pteidx, ptegidx;
- uint64_t vsid;
-
- ASSERT_TABLE_LOCK();
-
- /* If the PTEG index is not set, then there is no page table entry */
- if (!PVO_PTEGIDX_ISSET(pvo))
- return (NULL);
-
- /*
- * Calculate the ptegidx
- */
- vsid = PVO_VSID(pvo);
- ptegidx = va_to_pteg(vsid, PVO_VADDR(pvo),
- pvo->pvo_vaddr & PVO_LARGE);
-
- /*
- * We can find the actual pte entry without searching by grabbing
- * the PTEG index from 3 unused bits in pvo_vaddr and by
- * noticing the HID bit.
- */
- if (pvo->pvo_pte.lpte.pte_hi & LPTE_HID)
- ptegidx ^= moea64_pteg_mask;
-
- pteidx = (ptegidx << 3) | PVO_PTEGIDX_GET(pvo);
-
- if ((pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) &&
- !PVO_PTEGIDX_ISSET(pvo)) {
- panic("moea64_pvo_to_pte: pvo %p has valid pte in pvo but no "
- "valid pte index", pvo);
- }
-
- if ((pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) == 0 &&
- PVO_PTEGIDX_ISSET(pvo)) {
- panic("moea64_pvo_to_pte: pvo %p has valid pte index in pvo "
- "pvo but no valid pte", pvo);
- }
-
- pt = &moea64_pteg_table[pteidx >> 3].pt[pteidx & 7];
- if ((pt->pte_hi ^ (pvo->pvo_pte.lpte.pte_hi & ~LPTE_VALID)) ==
- LPTE_VALID) {
- if ((pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) == 0) {
- panic("moea64_pvo_to_pte: pvo %p has valid pte in "
- "moea64_pteg_table %p but invalid in pvo", pvo, pt);
- }
-
- if (((pt->pte_lo ^ pvo->pvo_pte.lpte.pte_lo) &
- ~(LPTE_M|LPTE_CHG|LPTE_REF)) != 0) {
- panic("moea64_pvo_to_pte: pvo %p pte does not match "
- "pte %p in moea64_pteg_table difference is %#x",
- pvo, pt,
- (uint32_t)(pt->pte_lo ^ pvo->pvo_pte.lpte.pte_lo));
- }
-
- return (pt);
- }
-
- if (pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) {
- panic("moea64_pvo_to_pte: pvo %p has invalid pte %p in "
- "moea64_pteg_table but valid in pvo", pvo, pt);
- }
-
- return (NULL);
-}
-
-static __inline int
-moea64_pte_spillable_ident(u_int ptegidx)
-{
- struct lpte *pt;
- int i, j, k;
-
- /* Start at a random slot */
- i = mftb() % 8;
- k = -1;
- for (j = 0; j < 8; j++) {
- pt = &moea64_pteg_table[ptegidx].pt[(i + j) % 8];
- if (pt->pte_hi & (LPTE_LOCKED | LPTE_WIRED))
- continue;
-
- /* This is a candidate, so remember it */
- k = (i + j) % 8;
-
- /* Try to get a page that has not been used lately */
- if (!(pt->pte_lo & LPTE_REF))
- return (k);
- }
-
- return (k);
-}
-
-static int
-moea64_pte_insert(u_int ptegidx, struct lpte *pvo_pt)
-{
- struct lpte *pt;
- struct pvo_entry *pvo;
- u_int pteg_bktidx;
- int i;
-
- ASSERT_TABLE_LOCK();
-
- /*
- * First try primary hash.
- */
- pteg_bktidx = ptegidx;
- for (pt = moea64_pteg_table[pteg_bktidx].pt, i = 0; i < 8; i++, pt++) {
- if ((pt->pte_hi & (LPTE_VALID | LPTE_LOCKED)) == 0) {
- pvo_pt->pte_hi &= ~LPTE_HID;
- moea64_pte_set(pt, pvo_pt);
- return (i);
- }
- }
-
- /*
- * Now try secondary hash.
- */
- pteg_bktidx ^= moea64_pteg_mask;
- for (pt = moea64_pteg_table[pteg_bktidx].pt, i = 0; i < 8; i++, pt++) {
- if ((pt->pte_hi & (LPTE_VALID | LPTE_LOCKED)) == 0) {
- pvo_pt->pte_hi |= LPTE_HID;
- moea64_pte_set(pt, pvo_pt);
- return (i);
- }
- }
-
- /*
- * Out of luck. Find a PTE to sacrifice.
- */
- pteg_bktidx = ptegidx;
- i = moea64_pte_spillable_ident(pteg_bktidx);
- if (i < 0) {
- pteg_bktidx ^= moea64_pteg_mask;
- i = moea64_pte_spillable_ident(pteg_bktidx);
- }
-
- if (i < 0) {
- /* No freeable slots in either PTEG? We're hosed. */
- panic("moea64_pte_insert: overflow");
- return (-1);
- }
-
- if (pteg_bktidx == ptegidx)
- pvo_pt->pte_hi &= ~LPTE_HID;
- else
- pvo_pt->pte_hi |= LPTE_HID;
-
- /*
- * Synchronize the sacrifice PTE with its PVO, then mark both
- * invalid. The PVO will be reused when/if the VM system comes
- * here after a fault.
- */
- pt = &moea64_pteg_table[pteg_bktidx].pt[i];
-
- if (pt->pte_hi & LPTE_HID)
- pteg_bktidx ^= moea64_pteg_mask; /* PTEs indexed by primary */
-
- LIST_FOREACH(pvo, &moea64_pvo_table[pteg_bktidx], pvo_olink) {
- if (pvo->pvo_pte.lpte.pte_hi == pt->pte_hi) {
- KASSERT(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID,
- ("Invalid PVO for valid PTE!"));
- moea64_pte_unset(pt, &pvo->pvo_pte.lpte, pvo->pvo_vpn);
- PVO_PTEGIDX_CLR(pvo);
- moea64_pte_overflow++;
- break;
- }
- }
-
- KASSERT(pvo->pvo_pte.lpte.pte_hi == pt->pte_hi,
- ("Unable to find PVO for spilled PTE"));
-
- /*
- * Set the new PTE.
- */
- moea64_pte_set(pt, pvo_pt);
-
- return (i);
-}
-
static boolean_t
-moea64_query_bit(vm_page_t m, u_int64_t ptebit)
+moea64_query_bit(mmu_t mmu, vm_page_t m, u_int64_t ptebit)
{
struct pvo_entry *pvo;
- struct lpte *pt;
+ uintptr_t pt;
if (moea64_attr_fetch(m) & ptebit)
return (TRUE);
@@ -2910,7 +2437,7 @@ moea64_query_bit(vm_page_t m, u_int64_t ptebit)
* themselves. Sync so that any pending REF/CHG bits are flushed to
* the PTEs.
*/
- SYNC();
+ powerpc_sync();
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
MOEA_PVO_CHECK(pvo); /* sanity check */
@@ -2920,9 +2447,9 @@ moea64_query_bit(vm_page_t m, u_int64_t ptebit)
* ptebit is set, cache it and return success.
*/
LOCK_TABLE();
- pt = moea64_pvo_to_pte(pvo);
- if (pt != NULL) {
- moea64_pte_synch(pt, &pvo->pvo_pte.lpte);
+ pt = MOEA64_PVO_TO_PTE(mmu, pvo);
+ if (pt != -1) {
+ MOEA64_PTE_SYNCH(mmu, pt, &pvo->pvo_pte.lpte);
if (pvo->pvo_pte.lpte.pte_lo & ptebit) {
UNLOCK_TABLE();
@@ -2940,11 +2467,11 @@ moea64_query_bit(vm_page_t m, u_int64_t ptebit)
}
static u_int
-moea64_clear_bit(vm_page_t m, u_int64_t ptebit)
+moea64_clear_bit(mmu_t mmu, vm_page_t m, u_int64_t ptebit)
{
u_int count;
struct pvo_entry *pvo;
- struct lpte *pt;
+ uintptr_t pt;
vm_page_lock_queues();
@@ -2960,7 +2487,7 @@ moea64_clear_bit(vm_page_t m, u_int64_t ptebit)
* table, we don't have to worry about further accesses setting the
* REF/CHG bits.
*/
- SYNC();
+ powerpc_sync();
/*
* For each pvo entry, clear the pvo's ptebit. If this pvo has a
@@ -2971,12 +2498,13 @@ moea64_clear_bit(vm_page_t m, u_int64_t ptebit)
MOEA_PVO_CHECK(pvo); /* sanity check */
LOCK_TABLE();
- pt = moea64_pvo_to_pte(pvo);
- if (pt != NULL) {
- moea64_pte_synch(pt, &pvo->pvo_pte.lpte);
+ pt = MOEA64_PVO_TO_PTE(mmu, pvo);
+ if (pt != -1) {
+ MOEA64_PTE_SYNCH(mmu, pt, &pvo->pvo_pte.lpte);
if (pvo->pvo_pte.lpte.pte_lo & ptebit) {
count++;
- moea64_pte_clear(pt, pvo->pvo_vpn, ptebit);
+ MOEA64_PTE_CLEAR(mmu, pt, &pvo->pvo_pte.lpte,
+ pvo->pvo_vpn, ptebit);
}
}
pvo->pvo_pte.lpte.pte_lo &= ~ptebit;
@@ -3058,7 +2586,7 @@ moea64_unmapdev(mmu_t mmu, vm_offset_t va, vm_size_t size)
kmem_free(kernel_map, base, size);
}
-static void
+void
moea64_sync_icache(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_size_t sz)
{
struct pvo_entry *pvo;
@@ -3074,7 +2602,7 @@ moea64_sync_icache(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_size_t sz)
if (pvo != NULL) {
pa = (pvo->pvo_pte.pte.pte_lo & LPTE_RPGN) |
(va & ADDR_POFF);
- moea64_syncicache(pm, va, pa, len);
+ moea64_syncicache(mmu, pm, va, pa, len);
}
va += len;
sz -= len;
diff --git a/sys/powerpc/aim/mmu_oea64.h b/sys/powerpc/aim/mmu_oea64.h
new file mode 100644
index 0000000..101181d
--- /dev/null
+++ b/sys/powerpc/aim/mmu_oea64.h
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (C) 2010 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _POWERPC_AIM_MMU_OEA64_H
+#define _POWERPC_AIM_MMU_OEA64_H
+
+#include <machine/mmuvar.h>
+
+extern mmu_def_t oea64_mmu;
+
+/*
+ * Helper routines
+ */
+
+/* Allocate physical memory for use in moea64_bootstrap. */
+vm_offset_t moea64_bootstrap_alloc(vm_size_t, u_int);
+
+/*
+ * Bootstrap subroutines
+ *
+ * An MMU_BOOTSTRAP() implementation looks like this:
+ * moea64_early_bootstrap();
+ * Allocate Page Table
+ * moea64_mid_bootstrap();
+ * Add mappings for MMU resources
+ * moea64_late_bootstrap();
+ */
+
+void moea64_early_bootstrap(mmu_t mmup, vm_offset_t kernelstart,
+ vm_offset_t kernelend);
+void moea64_mid_bootstrap(mmu_t mmup, vm_offset_t kernelstart,
+ vm_offset_t kernelend);
+void moea64_late_bootstrap(mmu_t mmup, vm_offset_t kernelstart,
+ vm_offset_t kernelend);
+
+/*
+ * Statistics
+ */
+
+extern u_int moea64_pte_valid;
+extern u_int moea64_pte_overflow;
+
+/*
+ * State variables
+ */
+
+extern struct pvo_head *moea64_pvo_table;
+extern int moea64_large_page_shift;
+extern u_int moea64_pteg_count;
+extern u_int moea64_pteg_mask;
+
+#endif /* _POWERPC_AIM_MMU_OEA64_H */
+
diff --git a/sys/powerpc/aim/moea64_if.m b/sys/powerpc/aim/moea64_if.m
new file mode 100644
index 0000000..f041838
--- /dev/null
+++ b/sys/powerpc/aim/moea64_if.m
@@ -0,0 +1,115 @@
+#-
+# Copyright (c) 2010 Nathan Whitehorn
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+
+#include <machine/mmuvar.h>
+
+/**
+ * MOEA64 kobj methods for 64-bit Book-S page table
+ * manipulation routines used, for example, by hypervisors.
+ */
+
+INTERFACE moea64;
+
+
+/**
+ * Copy ref/changed bits from PTE referenced by _pt_cookie to _pvo_pt.
+ */
+METHOD void pte_synch {
+ mmu_t _mmu;
+ uintptr_t _pt_cookie;
+ struct lpte *_pvo_pt;
+};
+
+/**
+ * Clear bits ptebit (a mask) from the low word of the PTE referenced by
+ * _pt_cookie. Note that _pvo_pt is for reference use only -- the bit should
+ * NOT be cleared there.
+ */
+METHOD void pte_clear {
+ mmu_t _mmu;
+ uintptr_t _pt_cookie;
+ struct lpte *_pvo_pt;
+ uint64_t _vpn;
+ uint64_t _ptebit;
+};
+
+/**
+ * Invalidate the PTE referenced by _pt_cookie, synchronizing its validity
+ * and ref/changed bits after completion.
+ */
+METHOD void pte_unset {
+ mmu_t _mmu;
+ uintptr_t _pt_cookie;
+ struct lpte *_pvo_pt;
+ uint64_t _vpn;
+};
+
+/**
+ * Update the PTE referenced by _pt_cookie with the values in _pvo_pt,
+ * making sure that the values of ref/changed bits are preserved and
+ * synchronized back to _pvo_pt.
+ */
+METHOD void pte_change {
+ mmu_t _mmu;
+ uintptr_t _pt_cookie;
+ struct lpte *_pvo_pt;
+ uint64_t _vpn;
+};
+
+
+/**
+ * Insert the PTE _pvo_pt into the PTEG group _ptegidx, returning the index
+ * of the PTE in its group at completion, or -1 if no slots were free. Must
+ * not replace PTEs marked LPTE_WIRED or LPTE_LOCKED, and must set LPTE_HID
+ * and LPTE_VALID appropriately in _pvo_pt.
+ */
+METHOD int pte_insert {
+ mmu_t _mmu;
+ u_int _ptegidx;
+ struct lpte *_pvo_pt;
+};
+
+/**
+ * Return the page table reference cookie corresponding to _pvo, or -1 if
+ * the _pvo is not currently in the page table.
+ */
+METHOD uintptr_t pvo_to_pte {
+ mmu_t _mmu;
+ const struct pvo_entry *_pvo;
+};
+
+
diff --git a/sys/powerpc/aim/moea64_native.c b/sys/powerpc/aim/moea64_native.c
new file mode 100644
index 0000000..a386b93
--- /dev/null
+++ b/sys/powerpc/aim/moea64_native.c
@@ -0,0 +1,637 @@
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <matt@3am-software.com> of Allegro Networks, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $NetBSD: pmap.c,v 1.28 2000/03/26 20:42:36 kleink Exp $
+ */
+/*-
+ * Copyright (C) 2001 Benno Rice.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Native 64-bit page table operations for running without a hypervisor.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+
+#include <sys/kdb.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_pager.h>
+
+#include <machine/md_var.h>
+#include <machine/mmuvar.h>
+
+#include "mmu_oea64.h"
+#include "mmu_if.h"
+#include "moea64_if.h"
+
+#define PTESYNC() __asm __volatile("ptesync");
+#define TLBSYNC() __asm __volatile("tlbsync; ptesync");
+#define SYNC() __asm __volatile("sync");
+#define EIEIO() __asm __volatile("eieio");
+
+#define VSID_HASH_MASK 0x0000007fffffffffULL
+
+/*
+ * The tlbie instruction must be executed in 64-bit mode
+ * so we have to twiddle MSR[SF] around every invocation.
+ * Just to add to the fun, exceptions must be off as well
+ * so that we can't trap in 64-bit mode. What a pain.
+ */
+struct mtx tlbie_mutex;
+
+static __inline void
+TLBIE(uint64_t vpn) {
+#ifndef __powerpc64__
+ register_t vpn_hi, vpn_lo;
+ register_t msr;
+ register_t scratch;
+#endif
+
+ vpn <<= ADDR_PIDX_SHFT;
+ vpn &= ~(0xffffULL << 48);
+
+ mtx_lock_spin(&tlbie_mutex);
+#ifdef __powerpc64__
+ __asm __volatile("\
+ ptesync; \
+ tlbie %0; \
+ eieio; \
+ tlbsync; \
+ ptesync;"
+ :: "r"(vpn) : "memory");
+#else
+ vpn_hi = (uint32_t)(vpn >> 32);
+ vpn_lo = (uint32_t)vpn;
+
+ __asm __volatile("\
+ mfmsr %0; \
+ mr %1, %0; \
+ insrdi %1,%5,1,0; \
+ mtmsrd %1; isync; \
+ ptesync; \
+ \
+ sld %1,%2,%4; \
+ or %1,%1,%3; \
+ tlbie %1; \
+ \
+ mtmsrd %0; isync; \
+ eieio; \
+ tlbsync; \
+ ptesync;"
+ : "=r"(msr), "=r"(scratch) : "r"(vpn_hi), "r"(vpn_lo), "r"(32), "r"(1)
+ : "memory");
+#endif
+ mtx_unlock_spin(&tlbie_mutex);
+}
+
+#define DISABLE_TRANS(msr) msr = mfmsr(); mtmsr(msr & ~PSL_DR); isync()
+#define ENABLE_TRANS(msr) mtmsr(msr); isync()
+
+/*
+ * PTEG data.
+ */
+static struct lpteg *moea64_pteg_table;
+
+/*
+ * PTE calls.
+ */
+static int moea64_pte_insert_native(mmu_t, u_int, struct lpte *);
+static uintptr_t moea64_pvo_to_pte_native(mmu_t, const struct pvo_entry *);
+static void moea64_pte_synch_native(mmu_t, uintptr_t pt,
+ struct lpte *pvo_pt);
+static void moea64_pte_clear_native(mmu_t, uintptr_t pt,
+ struct lpte *pvo_pt, uint64_t vpn, uint64_t ptebit);
+static void moea64_pte_change_native(mmu_t, uintptr_t pt,
+ struct lpte *pvo_pt, uint64_t vpn);
+static void moea64_pte_unset_native(mmu_t mmu, uintptr_t pt,
+ struct lpte *pvo_pt, uint64_t vpn);
+
+/*
+ * Utility routines.
+ */
+static void moea64_bootstrap_native(mmu_t mmup,
+ vm_offset_t kernelstart, vm_offset_t kernelend);
+static void moea64_cpu_bootstrap_native(mmu_t, int ap);
+static void tlbia(void);
+
+static mmu_method_t moea64_native_methods[] = {
+ /* Internal interfaces */
+ MMUMETHOD(mmu_bootstrap, moea64_bootstrap_native),
+ MMUMETHOD(mmu_cpu_bootstrap, moea64_cpu_bootstrap_native),
+
+ MMUMETHOD(moea64_pte_synch, moea64_pte_synch_native),
+ MMUMETHOD(moea64_pte_clear, moea64_pte_clear_native),
+ MMUMETHOD(moea64_pte_unset, moea64_pte_unset_native),
+ MMUMETHOD(moea64_pte_change, moea64_pte_change_native),
+ MMUMETHOD(moea64_pte_insert, moea64_pte_insert_native),
+ MMUMETHOD(moea64_pvo_to_pte, moea64_pvo_to_pte_native),
+
+ { 0, 0 }
+};
+
+MMU_DEF_INHERIT(oea64_mmu_native, MMU_TYPE_G5, moea64_native_methods,
+ 0, oea64_mmu);
+
+static __inline u_int
+va_to_pteg(uint64_t vsid, vm_offset_t addr, int large)
+{
+ uint64_t hash;
+ int shift;
+
+ shift = large ? moea64_large_page_shift : ADDR_PIDX_SHFT;
+ hash = (vsid & VSID_HASH_MASK) ^ (((uint64_t)addr & ADDR_PIDX) >>
+ shift);
+ return (hash & moea64_pteg_mask);
+}
+
+static void
+moea64_pte_synch_native(mmu_t mmu, uintptr_t pt_cookie, struct lpte *pvo_pt)
+{
+ struct lpte *pt = (struct lpte *)pt_cookie;
+
+ pvo_pt->pte_lo |= pt->pte_lo & (LPTE_REF | LPTE_CHG);
+}
+
+static void
+moea64_pte_clear_native(mmu_t mmu, uintptr_t pt_cookie, struct lpte *pvo_pt,
+ uint64_t vpn, uint64_t ptebit)
+{
+ struct lpte *pt = (struct lpte *)pt_cookie;
+
+ /*
+ * As shown in Section 7.6.3.2.3
+ */
+ pt->pte_lo &= ~ptebit;
+ TLBIE(vpn);
+}
+
+static void
+moea64_pte_set_native(struct lpte *pt, struct lpte *pvo_pt)
+{
+
+ pvo_pt->pte_hi |= LPTE_VALID;
+
+ /*
+ * Update the PTE as defined in section 7.6.3.1.
+ * Note that the REF/CHG bits are from pvo_pt and thus should have
+ * been saved so this routine can restore them (if desired).
+ */
+ pt->pte_lo = pvo_pt->pte_lo;
+ EIEIO();
+ pt->pte_hi = pvo_pt->pte_hi;
+ PTESYNC();
+ moea64_pte_valid++;
+}
+
+static void
+moea64_pte_unset_native(mmu_t mmu, uintptr_t pt_cookie, struct lpte *pvo_pt,
+ uint64_t vpn)
+{
+ struct lpte *pt = (struct lpte *)pt_cookie;
+
+ pvo_pt->pte_hi &= ~LPTE_VALID;
+
+ /*
+ * Force the reg & chg bits back into the PTEs.
+ */
+ SYNC();
+
+ /*
+ * Invalidate the pte.
+ */
+ pt->pte_hi &= ~LPTE_VALID;
+ TLBIE(vpn);
+
+ /*
+ * Save the reg & chg bits.
+ */
+ moea64_pte_synch_native(mmu, pt_cookie, pvo_pt);
+ moea64_pte_valid--;
+}
+
+static void
+moea64_pte_change_native(mmu_t mmu, uintptr_t pt, struct lpte *pvo_pt,
+ uint64_t vpn)
+{
+
+ /*
+ * Invalidate the PTE
+ */
+ moea64_pte_unset_native(mmu, pt, pvo_pt, vpn);
+ moea64_pte_set_native((struct lpte *)pt, pvo_pt);
+}
+
+static void
+moea64_cpu_bootstrap_native(mmu_t mmup, int ap)
+{
+ int i = 0;
+ #ifdef __powerpc64__
+ struct slb *slb = PCPU_GET(slb);
+ register_t seg0;
+ #endif
+
+ /*
+ * Initialize segment registers and MMU
+ */
+
+ mtmsr(mfmsr() & ~PSL_DR & ~PSL_IR); isync();
+
+ /*
+ * Install kernel SLB entries
+ */
+
+ #ifdef __powerpc64__
+ __asm __volatile ("slbia");
+ __asm __volatile ("slbmfee %0,%1; slbie %0;" : "=r"(seg0) :
+ "r"(0));
+
+ for (i = 0; i < 64; i++) {
+ if (!(slb[i].slbe & SLBE_VALID))
+ continue;
+
+ __asm __volatile ("slbmte %0, %1" ::
+ "r"(slb[i].slbv), "r"(slb[i].slbe));
+ }
+ #else
+ for (i = 0; i < 16; i++)
+ mtsrin(i << ADDR_SR_SHFT, kernel_pmap->pm_sr[i]);
+ #endif
+
+ /*
+ * Install page table
+ */
+
+ __asm __volatile ("ptesync; mtsdr1 %0; isync"
+ :: "r"((uintptr_t)moea64_pteg_table
+ | (uintptr_t)(flsl(moea64_pteg_mask >> 11))));
+ tlbia();
+}
+
+static void
+moea64_bootstrap_native(mmu_t mmup, vm_offset_t kernelstart,
+ vm_offset_t kernelend)
+{
+ vm_size_t size;
+ vm_offset_t off;
+ vm_paddr_t pa;
+ register_t msr;
+
+ moea64_early_bootstrap(mmup, kernelstart, kernelend);
+
+ /*
+ * Allocate PTEG table.
+ */
+
+ size = moea64_pteg_count * sizeof(struct lpteg);
+ CTR2(KTR_PMAP, "moea64_bootstrap: %d PTEGs, %d bytes",
+ moea64_pteg_count, size);
+
+ /*
+ * We now need to allocate memory. This memory, to be allocated,
+ * has to reside in a page table. The page table we are about to
+ * allocate. We don't have BAT. So drop to data real mode for a minute
+ * as a measure of last resort. We do this a couple times.
+ */
+
+ moea64_pteg_table = (struct lpteg *)moea64_bootstrap_alloc(size, size);
+ DISABLE_TRANS(msr);
+ bzero((void *)moea64_pteg_table, moea64_pteg_count * sizeof(struct lpteg));
+ ENABLE_TRANS(msr);
+
+ CTR1(KTR_PMAP, "moea64_bootstrap: PTEG table at %p", moea64_pteg_table);
+
+ /*
+ * Initialize the TLBIE lock. TLBIE can only be executed by one CPU.
+ */
+ mtx_init(&tlbie_mutex, "tlbie mutex", NULL, MTX_SPIN);
+
+ moea64_mid_bootstrap(mmup, kernelstart, kernelend);
+
+ /*
+ * Add a mapping for the page table itself if there is no direct map.
+ */
+ if (!hw_direct_map) {
+ size = moea64_pteg_count * sizeof(struct lpteg);
+ off = (vm_offset_t)(moea64_pteg_table);
+ DISABLE_TRANS(msr);
+ for (pa = off; pa < off + size; pa += PAGE_SIZE)
+ pmap_kenter(pa, pa);
+ ENABLE_TRANS(msr);
+ }
+
+ /* Bring up virtual memory */
+ moea64_late_bootstrap(mmup, kernelstart, kernelend);
+}
+
+static void
+tlbia(void)
+{
+ vm_offset_t i;
+ #ifndef __powerpc64__
+ register_t msr, scratch;
+ #endif
+
+ TLBSYNC();
+
+ for (i = 0; i < 0xFF000; i += 0x00001000) {
+ #ifdef __powerpc64__
+ __asm __volatile("tlbiel %0" :: "r"(i));
+ #else
+ __asm __volatile("\
+ mfmsr %0; \
+ mr %1, %0; \
+ insrdi %1,%3,1,0; \
+ mtmsrd %1; \
+ isync; \
+ \
+ tlbiel %2; \
+ \
+ mtmsrd %0; \
+ isync;"
+ : "=r"(msr), "=r"(scratch) : "r"(i), "r"(1));
+ #endif
+ }
+
+ EIEIO();
+ TLBSYNC();
+}
+
+static uintptr_t
+moea64_pvo_to_pte_native(mmu_t mmu, const struct pvo_entry *pvo)
+{
+ struct lpte *pt;
+ int pteidx, ptegidx;
+ uint64_t vsid;
+
+ /* If the PTEG index is not set, then there is no page table entry */
+ if (!PVO_PTEGIDX_ISSET(pvo))
+ return (-1);
+
+ /*
+ * Calculate the ptegidx
+ */
+ vsid = PVO_VSID(pvo);
+ ptegidx = va_to_pteg(vsid, PVO_VADDR(pvo),
+ pvo->pvo_vaddr & PVO_LARGE);
+
+ /*
+ * We can find the actual pte entry without searching by grabbing
+ * the PTEG index from 3 unused bits in pvo_vaddr and by
+ * noticing the HID bit.
+ */
+ if (pvo->pvo_pte.lpte.pte_hi & LPTE_HID)
+ ptegidx ^= moea64_pteg_mask;
+
+ pteidx = (ptegidx << 3) | PVO_PTEGIDX_GET(pvo);
+
+ if ((pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) &&
+ !PVO_PTEGIDX_ISSET(pvo)) {
+ panic("moea64_pvo_to_pte: pvo %p has valid pte in pvo but no "
+ "valid pte index", pvo);
+ }
+
+ if ((pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) == 0 &&
+ PVO_PTEGIDX_ISSET(pvo)) {
+ panic("moea64_pvo_to_pte: pvo %p has valid pte index in pvo "
+ "pvo but no valid pte", pvo);
+ }
+
+ pt = &moea64_pteg_table[pteidx >> 3].pt[pteidx & 7];
+ if ((pt->pte_hi ^ (pvo->pvo_pte.lpte.pte_hi & ~LPTE_VALID)) ==
+ LPTE_VALID) {
+ if ((pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) == 0) {
+ panic("moea64_pvo_to_pte: pvo %p has valid pte in "
+ "moea64_pteg_table %p but invalid in pvo", pvo, pt);
+ }
+
+ if (((pt->pte_lo ^ pvo->pvo_pte.lpte.pte_lo) &
+ ~(LPTE_M|LPTE_CHG|LPTE_REF)) != 0) {
+ panic("moea64_pvo_to_pte: pvo %p pte does not match "
+ "pte %p in moea64_pteg_table difference is %#x",
+ pvo, pt,
+ (uint32_t)(pt->pte_lo ^ pvo->pvo_pte.lpte.pte_lo));
+ }
+
+ return ((uintptr_t)pt);
+ }
+
+ if (pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) {
+ panic("moea64_pvo_to_pte: pvo %p has invalid pte %p in "
+ "moea64_pteg_table but valid in pvo", pvo, pt);
+ }
+
+ return (-1);
+}
+
+static __inline int
+moea64_pte_spillable_ident(u_int ptegidx)
+{
+ struct lpte *pt;
+ int i, j, k;
+
+ /* Start at a random slot */
+ i = mftb() % 8;
+ k = -1;
+ for (j = 0; j < 8; j++) {
+ pt = &moea64_pteg_table[ptegidx].pt[(i + j) % 8];
+ if (pt->pte_hi & (LPTE_LOCKED | LPTE_WIRED))
+ continue;
+
+ /* This is a candidate, so remember it */
+ k = (i + j) % 8;
+
+ /* Try to get a page that has not been used lately */
+ if (!(pt->pte_lo & LPTE_REF))
+ return (k);
+ }
+
+ return (k);
+}
+
+static int
+moea64_pte_insert_native(mmu_t mmu, u_int ptegidx, struct lpte *pvo_pt)
+{
+ struct lpte *pt;
+ struct pvo_entry *pvo;
+ u_int pteg_bktidx;
+ int i;
+
+ /*
+ * First try primary hash.
+ */
+ pteg_bktidx = ptegidx;
+ for (pt = moea64_pteg_table[pteg_bktidx].pt, i = 0; i < 8; i++, pt++) {
+ if ((pt->pte_hi & (LPTE_VALID | LPTE_LOCKED)) == 0) {
+ pvo_pt->pte_hi &= ~LPTE_HID;
+ moea64_pte_set_native(pt, pvo_pt);
+ return (i);
+ }
+ }
+
+ /*
+ * Now try secondary hash.
+ */
+ pteg_bktidx ^= moea64_pteg_mask;
+ for (pt = moea64_pteg_table[pteg_bktidx].pt, i = 0; i < 8; i++, pt++) {
+ if ((pt->pte_hi & (LPTE_VALID | LPTE_LOCKED)) == 0) {
+ pvo_pt->pte_hi |= LPTE_HID;
+ moea64_pte_set_native(pt, pvo_pt);
+ return (i);
+ }
+ }
+
+ /*
+ * Out of luck. Find a PTE to sacrifice.
+ */
+ pteg_bktidx = ptegidx;
+ i = moea64_pte_spillable_ident(pteg_bktidx);
+ if (i < 0) {
+ pteg_bktidx ^= moea64_pteg_mask;
+ i = moea64_pte_spillable_ident(pteg_bktidx);
+ }
+
+ if (i < 0) {
+ /* No freeable slots in either PTEG? We're hosed. */
+ panic("moea64_pte_insert: overflow");
+ return (-1);
+ }
+
+ if (pteg_bktidx == ptegidx)
+ pvo_pt->pte_hi &= ~LPTE_HID;
+ else
+ pvo_pt->pte_hi |= LPTE_HID;
+
+ /*
+ * Synchronize the sacrifice PTE with its PVO, then mark both
+ * invalid. The PVO will be reused when/if the VM system comes
+ * here after a fault.
+ */
+ pt = &moea64_pteg_table[pteg_bktidx].pt[i];
+
+ if (pt->pte_hi & LPTE_HID)
+ pteg_bktidx ^= moea64_pteg_mask; /* PTEs indexed by primary */
+
+ LIST_FOREACH(pvo, &moea64_pvo_table[pteg_bktidx], pvo_olink) {
+ if (pvo->pvo_pte.lpte.pte_hi == pt->pte_hi) {
+ KASSERT(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID,
+ ("Invalid PVO for valid PTE!"));
+ moea64_pte_unset_native(mmu, (uintptr_t)pt,
+ &pvo->pvo_pte.lpte, pvo->pvo_vpn);
+ PVO_PTEGIDX_CLR(pvo);
+ moea64_pte_overflow++;
+ break;
+ }
+ }
+
+ KASSERT(pvo->pvo_pte.lpte.pte_hi == pt->pte_hi,
+ ("Unable to find PVO for spilled PTE"));
+
+ /*
+ * Set the new PTE.
+ */
+ moea64_pte_set_native(pt, pvo_pt);
+
+ return (i);
+}
+
diff --git a/sys/powerpc/include/bus_dma.h b/sys/powerpc/include/bus_dma.h
index d10a055..e070a94 100644
--- a/sys/powerpc/include/bus_dma.h
+++ b/sys/powerpc/include/bus_dma.h
@@ -30,4 +30,8 @@
#include <sys/bus_dma.h>
+struct device;
+
+int bus_dma_tag_set_iommu(bus_dma_tag_t, struct device *iommu, void *cookie);
+
#endif /* _POWERPC_BUS_DMA_H_ */
diff --git a/sys/powerpc/include/pmap.h b/sys/powerpc/include/pmap.h
index c030416..2b26185 100644
--- a/sys/powerpc/include/pmap.h
+++ b/sys/powerpc/include/pmap.h
@@ -121,6 +121,25 @@ struct pvo_entry {
};
LIST_HEAD(pvo_head, pvo_entry);
+#define PVO_PTEGIDX_MASK 0x007UL /* which PTEG slot */
+#define PVO_PTEGIDX_VALID 0x008UL /* slot is valid */
+#define PVO_WIRED 0x010UL /* PVO entry is wired */
+#define PVO_MANAGED 0x020UL /* PVO entry is managed */
+#define PVO_EXECUTABLE 0x040UL /* PVO entry is executable */
+#define PVO_BOOTSTRAP 0x080UL /* PVO entry allocated during
+ bootstrap */
+#define PVO_FAKE 0x100UL /* fictitious phys page */
+#define PVO_LARGE 0x200UL /* large page */
+#define PVO_VADDR(pvo) ((pvo)->pvo_vaddr & ~ADDR_POFF)
+#define PVO_ISFAKE(pvo) ((pvo)->pvo_vaddr & PVO_FAKE)
+#define PVO_PTEGIDX_GET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_MASK)
+#define PVO_PTEGIDX_ISSET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_VALID)
+#define PVO_PTEGIDX_CLR(pvo) \
+ ((void)((pvo)->pvo_vaddr &= ~(PVO_PTEGIDX_VALID|PVO_PTEGIDX_MASK)))
+#define PVO_PTEGIDX_SET(pvo, i) \
+ ((void)((pvo)->pvo_vaddr |= (i)|PVO_PTEGIDX_VALID))
+#define PVO_VSID(pvo) ((pvo)->pvo_vpn >> 16)
+
struct md_page {
u_int64_t mdpg_attrs;
vm_memattr_t mdpg_cache_attrs;
diff --git a/sys/powerpc/include/pte.h b/sys/powerpc/include/pte.h
index 6c4eb93..8b9dd4e 100644
--- a/sys/powerpc/include/pte.h
+++ b/sys/powerpc/include/pte.h
@@ -95,8 +95,8 @@ struct lpteg {
/* High quadword: */
#define LPTE_VSID_SHIFT 12
#define LPTE_API 0x0000000000000F80ULL
-#define LPTE_WIRED 0x0000000000000010ULL
-#define LPTE_LOCKED 0x0000000000000008ULL
+#define LPTE_LOCKED 0x0000000000000040ULL
+#define LPTE_WIRED 0x0000000000000008ULL
#define LPTE_BIG 0x0000000000000004ULL /* 4kb/16Mb page */
#define LPTE_HID 0x0000000000000002ULL
#define LPTE_VALID 0x0000000000000001ULL
diff --git a/sys/powerpc/powerpc/busdma_machdep.c b/sys/powerpc/powerpc/busdma_machdep.c
index f66413f..84e3bc6 100644
--- a/sys/powerpc/powerpc/busdma_machdep.c
+++ b/sys/powerpc/powerpc/busdma_machdep.c
@@ -53,7 +53,9 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/md_var.h>
-#define MAX_BPAGES 8192
+#include "iommu_if.h"
+
+#define MAX_BPAGES MIN(8192, physmem/40)
struct bounce_zone;
@@ -73,8 +75,9 @@ struct bus_dma_tag {
int map_count;
bus_dma_lock_t *lockfunc;
void *lockfuncarg;
- bus_dma_segment_t *segments;
struct bounce_zone *bounce_zone;
+ device_t iommu;
+ void *iommu_cookie;
};
struct bounce_page {
@@ -121,6 +124,8 @@ struct bus_dmamap {
bus_dma_tag_t dmat;
void *buf; /* unmapped buffer pointer */
bus_size_t buflen; /* unmapped buffer length */
+ bus_dma_segment_t *segments;
+ int nsegs;
bus_dmamap_callback_t *callback;
void *callback_arg;
STAILQ_ENTRY(bus_dmamap) links;
@@ -128,7 +133,6 @@ struct bus_dmamap {
static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist;
static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist;
-static struct bus_dmamap nobounce_dmamap;
static void init_bounce_pages(void *dummy);
static int alloc_bounce_zone(bus_dma_tag_t dmat);
@@ -156,10 +160,14 @@ run_filter(bus_dma_tag_t dmat, bus_addr_t paddr)
retval = 0;
do {
- if (((paddr > dmat->lowaddr && paddr <= dmat->highaddr)
- || ((paddr & (dmat->alignment - 1)) != 0))
- && (dmat->filter == NULL
- || (*dmat->filter)(dmat->filterarg, paddr) != 0))
+ if (dmat->filter == NULL && dmat->iommu == NULL &&
+ paddr > dmat->lowaddr && paddr <= dmat->highaddr)
+ retval = 1;
+ if (dmat->filter == NULL &&
+ (paddr & (dmat->alignment - 1)) != 0)
+ retval = 1;
+ if (dmat->filter != NULL &&
+ (*dmat->filter)(dmat->filterarg, paddr) != 0)
retval = 1;
dmat = dmat->parent;
@@ -258,7 +266,6 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
newtag->lockfunc = dflt_lock;
newtag->lockfuncarg = NULL;
}
- newtag->segments = NULL;
/* Take into account any restrictions imposed by our parent tag */
if (parent != NULL) {
@@ -280,10 +287,14 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
}
if (newtag->parent != NULL)
atomic_add_int(&parent->ref_count, 1);
+ newtag->iommu = parent->iommu;
+ newtag->iommu_cookie = parent->iommu_cookie;
}
- if (newtag->lowaddr < ptoa((vm_paddr_t)Maxmem)
- || newtag->alignment > 1)
+ if (newtag->lowaddr < ptoa((vm_paddr_t)Maxmem) && newtag->iommu == NULL)
+ newtag->flags |= BUS_DMA_COULD_BOUNCE;
+
+ if (newtag->alignment > 1)
newtag->flags |= BUS_DMA_COULD_BOUNCE;
if (((newtag->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
@@ -343,8 +354,6 @@ bus_dma_tag_destroy(bus_dma_tag_t dmat)
parent = dmat->parent;
atomic_subtract_int(&dmat->ref_count, 1);
if (dmat->ref_count == 0) {
- if (dmat->segments != NULL)
- free(dmat->segments, M_DEVBUF);
free(dmat, M_DEVBUF);
/*
* Last reference count, so
@@ -372,17 +381,15 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
error = 0;
- if (dmat->segments == NULL) {
- dmat->segments = (bus_dma_segment_t *)malloc(
- sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF,
- M_NOWAIT);
- if (dmat->segments == NULL) {
- CTR3(KTR_BUSDMA, "%s: tag %p error %d",
- __func__, dmat, ENOMEM);
- return (ENOMEM);
- }
+ *mapp = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (*mapp == NULL) {
+ CTR3(KTR_BUSDMA, "%s: tag %p error %d",
+ __func__, dmat, ENOMEM);
+ return (ENOMEM);
}
+
/*
* Bouncing might be required if the driver asks for an active
* exclusion region, a data alignment that is stricter than 1, and/or
@@ -400,14 +407,6 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
}
bz = dmat->bounce_zone;
- *mapp = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF,
- M_NOWAIT | M_ZERO);
- if (*mapp == NULL) {
- CTR3(KTR_BUSDMA, "%s: tag %p error %d",
- __func__, dmat, ENOMEM);
- return (ENOMEM);
- }
-
/* Initialize the new map */
STAILQ_INIT(&((*mapp)->bpages));
@@ -437,9 +436,18 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
}
}
bz->map_count++;
- } else {
- *mapp = NULL;
}
+
+ (*mapp)->nsegs = 0;
+ (*mapp)->segments = (bus_dma_segment_t *)malloc(
+ sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF,
+ M_NOWAIT);
+ if ((*mapp)->segments == NULL) {
+ CTR3(KTR_BUSDMA, "%s: tag %p error %d",
+ __func__, dmat, ENOMEM);
+ return (ENOMEM);
+ }
+
if (error == 0)
dmat->map_count++;
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
@@ -454,7 +462,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
int
bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
{
- if (map != NULL && map != &nobounce_dmamap) {
+ if (dmat->flags & BUS_DMA_COULD_BOUNCE) {
if (STAILQ_FIRST(&map->bpages) != NULL) {
CTR3(KTR_BUSDMA, "%s: tag %p error %d",
__func__, dmat, EBUSY);
@@ -462,8 +470,9 @@ bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
}
if (dmat->bounce_zone)
dmat->bounce_zone->map_count--;
- free(map, M_DEVBUF);
}
+ free(map->segments, M_DEVBUF);
+ free(map, M_DEVBUF);
dmat->map_count--;
CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat);
return (0);
@@ -486,19 +495,8 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
else
mflags = M_WAITOK;
- /* If we succeed, no mapping/bouncing will be required */
- *mapp = NULL;
-
- if (dmat->segments == NULL) {
- dmat->segments = (bus_dma_segment_t *)malloc(
- sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF,
- mflags);
- if (dmat->segments == NULL) {
- CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
- __func__, dmat, dmat->flags, ENOMEM);
- return (ENOMEM);
- }
- }
+ bus_dmamap_create(dmat, flags, mapp);
+
if (flags & BUS_DMA_ZERO)
mflags |= M_ZERO;
@@ -535,7 +533,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
#ifdef NOTYET
if (flags & BUS_DMA_NOCACHE)
pmap_change_attr((vm_offset_t)*vaddr, dmat->maxsize,
- PAT_UNCACHEABLE);
+ VM_MEMATTR_UNCACHEABLE);
#endif
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
__func__, dmat, dmat->flags, 0);
@@ -549,14 +547,10 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
void
bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
{
- /*
- * dmamem does not need to be bounced, so the map should be
- * NULL
- */
- if (map != NULL)
- panic("bus_dmamem_free: Invalid map freed\n");
+ bus_dmamap_destroy(dmat, map);
+
#ifdef NOTYET
- pmap_change_attr((vm_offset_t)vaddr, dmat->maxsize, PAT_WRITE_BACK);
+ pmap_change_attr((vm_offset_t)vaddr, dmat->maxsize, VM_MEMATTR_DEFAULT);
#endif
if ((dmat->maxsize <= PAGE_SIZE) &&
(dmat->alignment < dmat->maxsize) &&
@@ -591,18 +585,13 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
bus_addr_t paddr;
int seg;
- if (map == NULL)
- map = &nobounce_dmamap;
-
- if ((map != &nobounce_dmamap && map->pagesneeded == 0)
- && ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0)) {
+ if (map->pagesneeded == 0 && ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0)) {
vm_offset_t vendaddr;
CTR4(KTR_BUSDMA, "lowaddr= %d Maxmem= %d, boundary= %d, "
"alignment= %d", dmat->lowaddr, ptoa((vm_paddr_t)Maxmem),
dmat->boundary, dmat->alignment);
- CTR3(KTR_BUSDMA, "map= %p, nobouncemap= %p, pagesneeded= %d",
- map, &nobounce_dmamap, map->pagesneeded);
+ CTR2(KTR_BUSDMA, "map= %p, pagesneeded= %d", map, map->pagesneeded);
/*
* Count the number of bounce pages
* needed in order to complete this transfer
@@ -731,29 +720,36 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
bus_size_t buflen, bus_dmamap_callback_t *callback,
void *callback_arg, int flags)
{
- bus_addr_t lastaddr = 0;
- int error, nsegs = 0;
+ bus_addr_t lastaddr = 0;
+ int error;
- if (map != NULL) {
+ if (dmat->flags & BUS_DMA_COULD_BOUNCE) {
flags |= BUS_DMA_WAITOK;
map->callback = callback;
map->callback_arg = callback_arg;
}
+ map->nsegs = 0;
error = _bus_dmamap_load_buffer(dmat, map, buf, buflen, NULL, flags,
- &lastaddr, dmat->segments, &nsegs, 1);
+ &lastaddr, map->segments, &map->nsegs, 1);
+ map->nsegs++;
CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
- __func__, dmat, dmat->flags, error, nsegs + 1);
+ __func__, dmat, dmat->flags, error, map->nsegs);
if (error == EINPROGRESS) {
return (error);
}
+ if (dmat->iommu != NULL)
+ IOMMU_MAP(dmat->iommu, map->segments, &map->nsegs, dmat->lowaddr,
+ dmat->highaddr, dmat->alignment, dmat->boundary,
+ dmat->iommu_cookie);
+
if (error)
- (*callback)(callback_arg, dmat->segments, 0, error);
+ (*callback)(callback_arg, map->segments, 0, error);
else
- (*callback)(callback_arg, dmat->segments, nsegs + 1, 0);
+ (*callback)(callback_arg, map->segments, map->nsegs, 0);
/*
* Return ENOMEM to the caller so that it can pass it up the stack.
@@ -775,12 +771,12 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map,
bus_dmamap_callback2_t *callback, void *callback_arg,
int flags)
{
- int nsegs, error;
+ int error;
M_ASSERTPKTHDR(m0);
flags |= BUS_DMA_NOWAIT;
- nsegs = 0;
+ map->nsegs = 0;
error = 0;
if (m0->m_pkthdr.len <= dmat->maxsize) {
int first = 1;
@@ -792,7 +788,7 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map,
error = _bus_dmamap_load_buffer(dmat, map,
m->m_data, m->m_len,
NULL, flags, &lastaddr,
- dmat->segments, &nsegs, first);
+ map->segments, &map->nsegs, first);
first = 0;
}
}
@@ -800,15 +796,21 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map,
error = EINVAL;
}
+ map->nsegs++;
+ if (dmat->iommu != NULL)
+ IOMMU_MAP(dmat->iommu, map->segments, &map->nsegs, dmat->lowaddr,
+ dmat->highaddr, dmat->alignment, dmat->boundary,
+ dmat->iommu_cookie);
+
if (error) {
/* force "no valid mappings" in callback */
- (*callback)(callback_arg, dmat->segments, 0, 0, error);
+ (*callback)(callback_arg, map->segments, 0, 0, error);
} else {
- (*callback)(callback_arg, dmat->segments,
- nsegs+1, m0->m_pkthdr.len, error);
+ (*callback)(callback_arg, map->segments,
+ map->nsegs, m0->m_pkthdr.len, error);
}
CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
- __func__, dmat, dmat->flags, error, nsegs + 1);
+ __func__, dmat, dmat->flags, error, map->nsegs);
return (error);
}
@@ -844,6 +846,15 @@ bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map,
/* XXX FIXME: Having to increment nsegs is really annoying */
++*nsegs;
+
+ if (dmat->iommu != NULL)
+ IOMMU_MAP(dmat->iommu, segs, nsegs, dmat->lowaddr,
+ dmat->highaddr, dmat->alignment, dmat->boundary,
+ dmat->iommu_cookie);
+
+ map->nsegs = *nsegs;
+ memcpy(map->segments, segs, map->nsegs*sizeof(segs[0]));
+
CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
__func__, dmat, dmat->flags, error, *nsegs);
return (error);
@@ -859,7 +870,7 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map,
int flags)
{
bus_addr_t lastaddr = 0;
- int nsegs, error, first, i;
+ int error, first, i;
bus_size_t resid;
struct iovec *iov;
pmap_t pmap;
@@ -875,7 +886,7 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map,
} else
pmap = NULL;
- nsegs = 0;
+ map->nsegs = 0;
error = 0;
first = 1;
for (i = 0; i < uio->uio_iovcnt && resid != 0 && !error; i++) {
@@ -890,22 +901,28 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map,
if (minlen > 0) {
error = _bus_dmamap_load_buffer(dmat, map,
addr, minlen, pmap, flags, &lastaddr,
- dmat->segments, &nsegs, first);
+ map->segments, &map->nsegs, first);
first = 0;
resid -= minlen;
}
}
+ map->nsegs++;
+ if (dmat->iommu != NULL)
+ IOMMU_MAP(dmat->iommu, map->segments, &map->nsegs, dmat->lowaddr,
+ dmat->highaddr, dmat->alignment, dmat->boundary,
+ dmat->iommu_cookie);
+
if (error) {
/* force "no valid mappings" in callback */
- (*callback)(callback_arg, dmat->segments, 0, 0, error);
+ (*callback)(callback_arg, map->segments, 0, 0, error);
} else {
- (*callback)(callback_arg, dmat->segments,
- nsegs+1, uio->uio_resid, error);
+ (*callback)(callback_arg, map->segments,
+ map->nsegs, uio->uio_resid, error);
}
CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
- __func__, dmat, dmat->flags, error, nsegs + 1);
+ __func__, dmat, dmat->flags, error, map->nsegs);
return (error);
}
@@ -917,6 +934,11 @@ _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
{
struct bounce_page *bpage;
+ if (dmat->iommu) {
+ IOMMU_UNMAP(dmat->iommu, map->segments, map->nsegs, dmat->iommu_cookie);
+ map->nsegs = 0;
+ }
+
while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
STAILQ_REMOVE_HEAD(&map->bpages, links);
free_bounce_page(dmat, bpage);
@@ -1122,8 +1144,6 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
struct bounce_page *bpage;
KASSERT(dmat->bounce_zone != NULL, ("no bounce zone in dma tag"));
- KASSERT(map != NULL && map != &nobounce_dmamap,
- ("add_bounce_page: bad map %p", map));
bz = dmat->bounce_zone;
if (map->pagesneeded == 0)
@@ -1210,3 +1230,13 @@ busdma_swi(void)
}
mtx_unlock(&bounce_lock);
}
+
+int
+bus_dma_tag_set_iommu(bus_dma_tag_t tag, struct device *iommu, void *cookie)
+{
+ tag->iommu = iommu;
+ tag->iommu_cookie = cookie;
+
+ return (0);
+}
+
diff --git a/sys/powerpc/powerpc/iommu_if.m b/sys/powerpc/powerpc/iommu_if.m
new file mode 100644
index 0000000..dec70e3
--- /dev/null
+++ b/sys/powerpc/powerpc/iommu_if.m
@@ -0,0 +1,54 @@
+#-
+# Copyright (c) 2010 Nathan Whitehorn
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# from: src/sys/kern/bus_if.m,v 1.21 2002/04/21 11:16:10 markm Exp
+# $FreeBSD$
+#
+
+#include <machine/bus.h>
+
+#include <sys/bus.h>
+#include <sys/bus_dma.h>
+
+INTERFACE iommu;
+
+METHOD int map {
+ device_t iommu;
+ bus_dma_segment_t *segs;
+ int *nsegs;
+ bus_addr_t lowaddr;
+ bus_addr_t highaddr;
+ bus_size_t alignment;
+ bus_size_t boundary;
+ void *cookie;
+};
+
+METHOD int unmap {
+ device_t iommu;
+ bus_dma_segment_t *segs;
+ int nsegs;
+ void *cookie;
+};
+
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 257d272..3c796e2 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 900026 /* Master, propagated to newvers */
+#define __FreeBSD_version 900027 /* Master, propagated to newvers */
#ifdef _KERNEL
#define P_OSREL_SIGSEGV 700004
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 02f228c..48ef012 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -214,6 +214,7 @@ struct thread {
lwpid_t td_tid; /* (b) Thread ID. */
sigqueue_t td_sigqueue; /* (c) Sigs arrived, not delivered. */
#define td_siglist td_sigqueue.sq_signals
+ u_char td_lend_user_pri; /* (t) Lend user pri. */
/* Cleared during fork1() */
#define td_startzero td_flags
@@ -343,7 +344,7 @@ do { \
#define TDF_CANSWAP 0x00000040 /* Thread can be swapped. */
#define TDF_SLEEPABORT 0x00000080 /* sleepq_abort was called. */
#define TDF_KTH_SUSP 0x00000100 /* kthread is suspended */
-#define TDF_UBORROWING 0x00000200 /* Thread is borrowing user pri. */
+#define TDF_UNUSED09 0x00000200 /* --available-- */
#define TDF_BOUNDARY 0x00000400 /* Thread suspended at user boundary */
#define TDF_ASTPENDING 0x00000800 /* Thread has some asynchronous events. */
#define TDF_TIMOFAIL 0x00001000 /* Timeout from sleep after we were awake. */
diff --git a/sys/sys/queue.h b/sys/sys/queue.h
index 257679b..f0bae8d 100644
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -213,6 +213,12 @@ struct { \
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
} while (0)
+#define SLIST_SWAP(head1, head2, type) do { \
+ struct type *swap_first = SLIST_FIRST(head1); \
+ SLIST_FIRST(head1) = SLIST_FIRST(head2); \
+ SLIST_FIRST(head2) = swap_first; \
+} while (0)
+
/*
* Singly-linked Tail queue declarations.
*/
diff --git a/sys/teken/teken_subr.h b/sys/teken/teken_subr.h
index c84679a..2934bcc 100644
--- a/sys/teken/teken_subr.h
+++ b/sys/teken/teken_subr.h
@@ -1299,10 +1299,9 @@ teken_subr_vertical_position_absolute(teken_t *t, unsigned int row)
{
t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1;
- if (row >= t->t_originreg.ts_end)
+ if (t->t_cursor.tp_row >= t->t_originreg.ts_end)
t->t_cursor.tp_row = t->t_originreg.ts_end - 1;
-
t->t_stateflags &= ~TS_WRAPPED;
teken_funcs_cursor(t);
}
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 35552a6..1a51af8 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -671,6 +671,41 @@ vm_map_wakeup(vm_map_t map)
wakeup(&map->root);
}
+void
+vm_map_busy(vm_map_t map)
+{
+
+ VM_MAP_ASSERT_LOCKED(map);
+ map->busy++;
+}
+
+void
+vm_map_unbusy(vm_map_t map)
+{
+
+ VM_MAP_ASSERT_LOCKED(map);
+ KASSERT(map->busy, ("vm_map_unbusy: not busy"));
+ if (--map->busy == 0 && (map->flags & MAP_BUSY_WAKEUP)) {
+ vm_map_modflags(map, 0, MAP_BUSY_WAKEUP);
+ wakeup(&map->busy);
+ }
+}
+
+void
+vm_map_wait_busy(vm_map_t map)
+{
+
+ VM_MAP_ASSERT_LOCKED(map);
+ while (map->busy) {
+ vm_map_modflags(map, MAP_BUSY_WAKEUP, 0);
+ if (map->system_map)
+ msleep(&map->busy, &map->system_mtx, 0, "mbusy", 0);
+ else
+ sx_sleep(&map->busy, &map->lock, 0, "mbusy", 0);
+ }
+ map->timestamp++;
+}
+
long
vmspace_resident_count(struct vmspace *vmspace)
{
@@ -718,6 +753,7 @@ _vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max)
map->flags = 0;
map->root = NULL;
map->timestamp = 0;
+ map->busy = 0;
}
void
@@ -2382,12 +2418,14 @@ vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end,
entry->object.vm_object->type == OBJT_SG);
/*
* Release the map lock, relying on the in-transition
- * mark.
+ * mark. Mark the map busy for fork.
*/
+ vm_map_busy(map);
vm_map_unlock(map);
rv = vm_fault_wire(map, saved_start, saved_end,
fictitious);
vm_map_lock(map);
+ vm_map_unbusy(map);
if (last_timestamp + 1 != map->timestamp) {
/*
* Look again for the entry because the map was
@@ -2995,6 +3033,8 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_charge)
int locked;
vm_map_lock(old_map);
+ if (old_map->busy)
+ vm_map_wait_busy(old_map);
vm2 = vmspace_alloc(old_map->min_offset, old_map->max_offset);
if (vm2 == NULL)
goto unlock_and_return;
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index f7fc5f5..fecbffe 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -187,12 +187,14 @@ struct vm_map {
pmap_t pmap; /* (c) Physical map */
#define min_offset header.start /* (c) */
#define max_offset header.end /* (c) */
+ int busy;
};
/*
* vm_flags_t values
*/
#define MAP_WIREFUTURE 0x01 /* wire all future pages */
+#define MAP_BUSY_WAKEUP 0x02
#ifdef _KERNEL
static __inline vm_offset_t
@@ -275,6 +277,9 @@ int _vm_map_lock_upgrade(vm_map_t map, const char *file, int line);
void _vm_map_lock_downgrade(vm_map_t map, const char *file, int line);
int vm_map_locked(vm_map_t map);
void vm_map_wakeup(vm_map_t map);
+void vm_map_busy(vm_map_t map);
+void vm_map_unbusy(vm_map_t map);
+void vm_map_wait_busy(vm_map_t map);
#define vm_map_lock(map) _vm_map_lock(map, LOCK_FILE, LOCK_LINE)
#define vm_map_unlock(map) _vm_map_unlock(map, LOCK_FILE, LOCK_LINE)
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index f2dba2c..a73e03a 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -276,14 +276,14 @@ mmap(td, uap)
if (addr + size < addr)
return (EINVAL);
} else {
- /*
- * XXX for non-fixed mappings where no hint is provided or
- * the hint would fall in the potential heap space,
- * place it after the end of the largest possible heap.
- *
- * There should really be a pmap call to determine a reasonable
- * location.
- */
+ /*
+ * XXX for non-fixed mappings where no hint is provided or
+ * the hint would fall in the potential heap space,
+ * place it after the end of the largest possible heap.
+ *
+ * There should really be a pmap call to determine a reasonable
+ * location.
+ */
PROC_LOCK(td->td_proc);
if (addr == 0 ||
(addr >= round_page((vm_offset_t)vms->vm_taddr) &&
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 863b842..1208ea0 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -430,11 +430,12 @@ vm_page_startup(vm_offset_t vaddr)
*/
new_end = vm_reserv_startup(&vaddr, new_end, high_water);
#endif
-#ifdef __amd64__
+#if defined(__amd64__) || defined(__mips__)
/*
- * pmap_map on amd64 comes out of the direct-map, not kvm like i386,
- * so the pages must be tracked for a crashdump to include this data.
- * This includes the vm_page_array and the early UMA bootstrap pages.
+ * pmap_map on amd64 and mips can come out of the direct-map, not kvm
+ * like i386, so the pages must be tracked for a crashdump to include
+ * this data. This includes the vm_page_array and the early UMA
+ * bootstrap pages.
*/
for (pa = new_end; pa < phys_avail[biggestone + 1]; pa += PAGE_SIZE)
dump_add_page(pa);
diff --git a/sys/i386/i386/busdma_machdep.c b/sys/x86/x86/busdma_machdep.c
index 45ab8b3..feca1a6 100644
--- a/sys/i386/i386/busdma_machdep.c
+++ b/sys/x86/x86/busdma_machdep.c
@@ -28,9 +28,6 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/kdb.h>
-#include <ddb/ddb.h>
-#include <ddb/db_output.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/bus.h>
@@ -53,7 +50,11 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include <machine/specialreg.h>
+#ifdef __i386__
#define MAX_BPAGES 512
+#else
+#define MAX_BPAGES 8192
+#endif
#define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3
#define BUS_DMA_MIN_ALLOC_COMP BUS_DMA_BUS4
@@ -249,8 +250,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
newtag->alignment = alignment;
newtag->boundary = boundary;
newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1);
- newtag->highaddr = trunc_page((vm_paddr_t)highaddr) +
- (PAGE_SIZE - 1);
+ newtag->highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1);
newtag->filter = filter;
newtag->filterarg = filterarg;
newtag->maxsize = maxsize;
@@ -597,15 +597,19 @@ _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap,
vendaddr = (vm_offset_t)buf + buflen;
while (vaddr < vendaddr) {
+ bus_size_t sg_len;
+
+ sg_len = PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK);
if (pmap)
paddr = pmap_extract(pmap, vaddr);
else
paddr = pmap_kextract(vaddr);
if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
run_filter(dmat, paddr) != 0) {
+ sg_len = roundup2(sg_len, dmat->alignment);
map->pagesneeded++;
}
- vaddr += (PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK));
+ vaddr += sg_len;
}
CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
}
@@ -672,6 +676,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
bmask = ~(dmat->boundary - 1);
for (seg = *segp; buflen > 0 ; ) {
+ bus_size_t max_sgsize;
+
/*
* Get the physical address for this segment.
*/
@@ -683,11 +689,16 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
/*
* Compute the segment size, and adjust counts.
*/
- sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
- if (sgsize > dmat->maxsegsz)
- sgsize = dmat->maxsegsz;
- if (buflen < sgsize)
- sgsize = buflen;
+ max_sgsize = MIN(buflen, dmat->maxsegsz);
+ sgsize = PAGE_SIZE - ((vm_offset_t)curaddr & PAGE_MASK);
+ if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
+ map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
+ sgsize = roundup2(sgsize, dmat->alignment);
+ sgsize = MIN(sgsize, max_sgsize);
+ curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
+ } else {
+ sgsize = MIN(sgsize, max_sgsize);
+ }
/*
* Make sure we don't cross any boundaries.
@@ -698,10 +709,6 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
sgsize = (baddr - curaddr);
}
- if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
- map->pagesneeded != 0 && run_filter(dmat, curaddr))
- curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
-
/*
* Insert chunk into a segment, coalescing with
* previous segment if possible.
@@ -861,7 +868,7 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map,
bus_dmamap_callback2_t *callback, void *callback_arg,
int flags)
{
- bus_addr_t lastaddr;
+ bus_addr_t lastaddr = 0;
int nsegs, error, first, i;
bus_size_t resid;
struct iovec *iov;
@@ -881,7 +888,6 @@ bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map,
nsegs = 0;
error = 0;
first = 1;
- lastaddr = (bus_addr_t) 0;
for (i = 0; i < uio->uio_iovcnt && resid != 0 && !error; i++) {
/*
* Now at the first iovec to load. Load each iovec
diff --git a/sys/i386/i386/tsc.c b/sys/x86/x86/tsc.c
index 882b442..e39c4af 100644
--- a/sys/i386/i386/tsc.c
+++ b/sys/x86/x86/tsc.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/power.h>
#include <sys/smp.h>
#include <machine/clock.h>
+#include <machine/cputypes.h>
#include <machine/md_var.h>
#include <machine/specialreg.h>
@@ -49,7 +50,7 @@ __FBSDID("$FreeBSD$");
uint64_t tsc_freq;
int tsc_is_broken;
int tsc_is_invariant;
-u_int tsc_present;
+int tsc_present;
static eventhandler_tag tsc_levels_tag, tsc_pre_tag, tsc_post_tag;
SYSCTL_INT(_kern_timecounter, OID_AUTO, invariant_tsc, CTLFLAG_RDTUN,
@@ -103,14 +104,38 @@ init_TSC(void)
if (bootverbose)
printf("TSC clock: %ju Hz\n", (intmax_t)tsc_freq);
+ switch (cpu_vendor_id) {
+ case CPU_VENDOR_AMD:
+ if ((amd_pminfo & AMDPM_TSC_INVARIANT) ||
+ CPUID_TO_FAMILY(cpu_id) >= 0x10)
+ tsc_is_invariant = 1;
+ break;
+ case CPU_VENDOR_INTEL:
+ if ((amd_pminfo & AMDPM_TSC_INVARIANT) ||
+ (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+ CPUID_TO_MODEL(cpu_id) >= 0xe) ||
+ (CPUID_TO_FAMILY(cpu_id) == 0xf &&
+ CPUID_TO_MODEL(cpu_id) >= 0x3))
+ tsc_is_invariant = 1;
+ break;
+ case CPU_VENDOR_CENTAUR:
+ if (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
+ CPUID_TO_MODEL(cpu_id) >= 0xf &&
+ (rdmsr(0x1203) & 0x100000000ULL) == 0)
+ tsc_is_invariant = 1;
+ break;
+ }
+
/*
- * Inform CPU accounting about our boot-time clock rate. Once the
- * system is finished booting, we will get the real max clock rate
- * via tsc_freq_max(). This also will be updated if someone loads
- * a cpufreq driver after boot that discovers a new max frequency.
+ * Inform CPU accounting about our boot-time clock rate. This will
+ * be updated if someone loads a cpufreq driver after boot that
+ * discovers a new max frequency.
*/
set_cputicker(rdtsc, tsc_freq, 1);
+ if (tsc_is_invariant)
+ return;
+
/* Register to find out about changes in CPU frequency. */
tsc_pre_tag = EVENTHANDLER_REGISTER(cpufreq_pre_change,
tsc_freq_changing, NULL, EVENTHANDLER_PRI_FIRST);
@@ -207,8 +232,7 @@ static void
tsc_freq_changing(void *arg, const struct cf_level *level, int *status)
{
- if (*status != 0 || timecounter != &tsc_timecounter ||
- tsc_is_invariant)
+ if (*status != 0 || timecounter != &tsc_timecounter)
return;
printf("timecounter TSC must not be in use when "
@@ -220,11 +244,9 @@ tsc_freq_changing(void *arg, const struct cf_level *level, int *status)
static void
tsc_freq_changed(void *arg, const struct cf_level *level, int status)
{
- /*
- * If there was an error during the transition or
- * TSC is P-state invariant, don't do anything.
- */
- if (status != 0 || tsc_is_invariant)
+
+ /* If there was an error during the transition, don't do anything. */
+ if (status != 0)
return;
/* Total setting for this level gives the new frequency in MHz. */
diff --git a/sys/xen/evtchn/evtchn.c b/sys/xen/evtchn/evtchn.c
index 3832277..3ad2e2c 100644
--- a/sys/xen/evtchn/evtchn.c
+++ b/sys/xen/evtchn/evtchn.c
@@ -256,7 +256,7 @@ find_unbound_irq(void)
}
static int
-bind_caller_port_to_irq(unsigned int caller_port)
+bind_caller_port_to_irq(unsigned int caller_port, int * port)
{
int irq;
@@ -271,7 +271,7 @@ bind_caller_port_to_irq(unsigned int caller_port)
}
irq_bindcount[irq]++;
- unmask_evtchn(caller_port);
+ *port = caller_port;
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -279,7 +279,7 @@ bind_caller_port_to_irq(unsigned int caller_port)
}
static int
-bind_local_port_to_irq(unsigned int local_port)
+bind_local_port_to_irq(unsigned int local_port, int * port)
{
int irq;
@@ -298,7 +298,7 @@ bind_local_port_to_irq(unsigned int local_port)
evtchn_to_irq[local_port] = irq;
irq_info[irq] = mk_irq_info(IRQT_LOCAL_PORT, 0, local_port);
irq_bindcount[irq]++;
- unmask_evtchn(local_port);
+ *port = local_port;
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -306,7 +306,7 @@ bind_local_port_to_irq(unsigned int local_port)
}
static int
-bind_listening_port_to_irq(unsigned int remote_domain)
+bind_listening_port_to_irq(unsigned int remote_domain, int * port)
{
struct evtchn_alloc_unbound alloc_unbound;
int err;
@@ -317,12 +317,12 @@ bind_listening_port_to_irq(unsigned int remote_domain)
err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
&alloc_unbound);
- return err ? : bind_local_port_to_irq(alloc_unbound.port);
+ return err ? : bind_local_port_to_irq(alloc_unbound.port, port);
}
static int
bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
- unsigned int remote_port)
+ unsigned int remote_port, int * port)
{
struct evtchn_bind_interdomain bind_interdomain;
int err;
@@ -333,11 +333,11 @@ bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
&bind_interdomain);
- return err ? : bind_local_port_to_irq(bind_interdomain.local_port);
+ return err ? : bind_local_port_to_irq(bind_interdomain.local_port, port);
}
static int
-bind_virq_to_irq(unsigned int virq, unsigned int cpu)
+bind_virq_to_irq(unsigned int virq, unsigned int cpu, int * port)
{
struct evtchn_bind_virq bind_virq;
int evtchn = 0, irq;
@@ -363,7 +363,7 @@ bind_virq_to_irq(unsigned int virq, unsigned int cpu)
}
irq_bindcount[irq]++;
- unmask_evtchn(evtchn);
+ *port = evtchn;
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -371,10 +371,8 @@ out:
}
-extern int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu);
-
-int
-bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
+static int
+bind_ipi_to_irq(unsigned int ipi, unsigned int cpu, int * port)
{
struct evtchn_bind_ipi bind_ipi;
int irq;
@@ -398,7 +396,7 @@ bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
bind_evtchn_to_cpu(evtchn, cpu);
}
irq_bindcount[irq]++;
- unmask_evtchn(evtchn);
+ *port = evtchn;
out:
mtx_unlock_spin(&irq_mapping_update_lock);
@@ -449,9 +447,10 @@ bind_caller_port_to_irqhandler(unsigned int caller_port,
unsigned long irqflags, unsigned int *irqp)
{
unsigned int irq;
+ int port = -1;
int error;
- irq = bind_caller_port_to_irq(caller_port);
+ irq = bind_caller_port_to_irq(caller_port, &port);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
error = intr_add_handler(devname, irq, NULL, handler, arg, irqflags,
&xp->xp_pins[irq].xp_cookie);
@@ -460,6 +459,8 @@ bind_caller_port_to_irqhandler(unsigned int caller_port,
unbind_from_irq(irq);
return (error);
}
+ if (port != -1)
+ unmask_evtchn(port);
if (irqp)
*irqp = irq;
@@ -473,9 +474,10 @@ bind_listening_port_to_irqhandler(unsigned int remote_domain,
unsigned long irqflags, unsigned int *irqp)
{
unsigned int irq;
+ int port = -1;
int error;
- irq = bind_listening_port_to_irq(remote_domain);
+ irq = bind_listening_port_to_irq(remote_domain, &port);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
error = intr_add_handler(devname, irq, NULL, handler, arg, irqflags,
&xp->xp_pins[irq].xp_cookie);
@@ -483,6 +485,8 @@ bind_listening_port_to_irqhandler(unsigned int remote_domain,
unbind_from_irq(irq);
return (error);
}
+ if (port != -1)
+ unmask_evtchn(port);
if (irqp)
*irqp = irq;
@@ -496,9 +500,10 @@ bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
unsigned int *irqp)
{
unsigned int irq;
+ int port = -1;
int error;
- irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port);
+ irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port, &port);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
error = intr_add_handler(devname, irq, NULL, handler, arg,
irqflags, &xp->xp_pins[irq].xp_cookie);
@@ -506,6 +511,8 @@ bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
unbind_from_irq(irq);
return (error);
}
+ if (port != -1)
+ unmask_evtchn(port);
if (irqp)
*irqp = irq;
@@ -518,9 +525,10 @@ bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
void *arg, unsigned long irqflags, unsigned int *irqp)
{
unsigned int irq;
+ int port = -1;
int error;
- irq = bind_virq_to_irq(virq, cpu);
+ irq = bind_virq_to_irq(virq, cpu, &port);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
error = intr_add_handler(devname, irq, filter, handler,
arg, irqflags, &xp->xp_pins[irq].xp_cookie);
@@ -528,6 +536,8 @@ bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
unbind_from_irq(irq);
return (error);
}
+ if (port != -1)
+ unmask_evtchn(port);
if (irqp)
*irqp = irq;
@@ -540,9 +550,10 @@ bind_ipi_to_irqhandler(unsigned int ipi, unsigned int cpu,
unsigned long irqflags, unsigned int *irqp)
{
unsigned int irq;
+ int port = -1;
int error;
- irq = bind_ipi_to_irq(ipi, cpu);
+ irq = bind_ipi_to_irq(ipi, cpu, &port);
intr_register_source(&xp->xp_pins[irq].xp_intsrc);
error = intr_add_handler(devname, irq, filter, NULL,
NULL, irqflags, &xp->xp_pins[irq].xp_cookie);
@@ -550,6 +561,8 @@ bind_ipi_to_irqhandler(unsigned int ipi, unsigned int cpu,
unbind_from_irq(irq);
return (error);
}
+ if (port != -1)
+ unmask_evtchn(port);
if (irqp)
*irqp = irq;
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index 02a4ce3..db8251c 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -1869,7 +1869,6 @@ OLD_FILES+=usr/lib/libfl_p.a
OLD_FILES+=usr/lib/libform_p.a
OLD_FILES+=usr/lib/libformw_p.a
OLD_FILES+=usr/lib/libftpio_p.a
-OLD_FILES+=usr/lib/libg2c_p.a
OLD_FILES+=usr/lib/libgcc_p.a
OLD_FILES+=usr/lib/libgeom_p.a
OLD_FILES+=usr/lib/libgnuregex_p.a
diff --git a/tools/regression/lib/msun/Makefile b/tools/regression/lib/msun/Makefile
index 4a19dc2..eb9a6ae 100644
--- a/tools/regression/lib/msun/Makefile
+++ b/tools/regression/lib/msun/Makefile
@@ -1,8 +1,8 @@
# $FreeBSD$
TESTS= test-conj test-csqrt test-exponential test-fenv test-fma \
- test-fmaxmin test-ilogb test-invtrig test-lrint \
- test-lround test-nan test-next test-rem test-trig
+ test-fmaxmin test-ilogb test-invtrig test-logarithm test-lrint \
+ test-lround test-nan test-nearbyint test-next test-rem test-trig
CFLAGS+= -O0 -lm
.PHONY: tests
diff --git a/tools/regression/lib/msun/test-exponential.c b/tools/regression/lib/msun/test-exponential.c
index 6111e96..53a6116 100644
--- a/tools/regression/lib/msun/test-exponential.c
+++ b/tools/regression/lib/msun/test-exponential.c
@@ -89,7 +89,7 @@ __FBSDID("$FreeBSD$");
int
fpequal(long double x, long double y)
{
- return ((x == y && signbit(x) == signbit(y)) || isnan(x) && isnan(y));
+ return ((x == y && !signbit(x) == !signbit(y)) || isnan(x) && isnan(y));
}
void
diff --git a/tools/regression/lib/msun/test-fma.c b/tools/regression/lib/msun/test-fma.c
index 5511eb3..00620f8 100644
--- a/tools/regression/lib/msun/test-fma.c
+++ b/tools/regression/lib/msun/test-fma.c
@@ -85,7 +85,8 @@ int
fpequal(long double x, long double y)
{
- return ((x == y && signbit(x) == signbit(y)) || (isnan(x) && isnan(y)));
+ return ((x == y && !signbit(x) == !signbit(y))
+ || (isnan(x) && isnan(y)));
}
static void
diff --git a/tools/regression/lib/msun/test-fmaxmin.c b/tools/regression/lib/msun/test-fmaxmin.c
index f1e0a7e..fdba529 100644
--- a/tools/regression/lib/msun/test-fmaxmin.c
+++ b/tools/regression/lib/msun/test-fmaxmin.c
@@ -46,11 +46,12 @@ __FBSDID("$FreeBSD$");
* fpequal(NaN, NaN) is true
* fpequal(+0.0, -0.0) is false
*/
-inline int
+static inline int
fpequal(long double x, long double y)
{
- return ((x == y && signbit(x) == signbit(y)) || (isnan(x) && isnan(y)));
+ return ((x == y && !signbit(x) == !signbit(y))
+ || (isnan(x) && isnan(y)));
}
/*
@@ -63,7 +64,7 @@ fpequal(long double x, long double y)
feclearexcept(ALL_STD_EXCEPT); \
long double __result = func((__x), (__y)); \
if (fetestexcept(ALL_STD_EXCEPT)) { \
- fprintf(stderr, #func "(%L.20g, %L.20g) raised 0x%x\n", \
+ fprintf(stderr, #func "(%.20Lg, %.20Lg) raised 0x%x\n", \
(x), (y), fetestexcept(FE_ALL_EXCEPT)); \
ok = 0; \
} \
@@ -104,7 +105,7 @@ testall_r(long double big, long double small)
* in all rounding modes and with the arguments in different orders.
* The input 'big' must be >= 'small'.
*/
-int
+void
testall(int testnum, long double big, long double small)
{
static const int rmodes[] = {
diff --git a/tools/regression/lib/msun/test-invtrig.c b/tools/regression/lib/msun/test-invtrig.c
index 5900f5b..05d310f 100644
--- a/tools/regression/lib/msun/test-invtrig.c
+++ b/tools/regression/lib/msun/test-invtrig.c
@@ -118,7 +118,7 @@ fpequal(long double x, long double y, long double tol)
if (isnan(x) && isnan(y))
return (1);
- if (signbit(x) != signbit(y))
+ if (!signbit(x) != !signbit(y))
return (0);
if (x == y)
return (1);
diff --git a/tools/regression/lib/msun/test-logarithm.c b/tools/regression/lib/msun/test-logarithm.c
new file mode 100644
index 0000000..52f562c
--- /dev/null
+++ b/tools/regression/lib/msun/test-logarithm.c
@@ -0,0 +1,158 @@
+/*-
+ * Copyright (c) 2008-2010 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Tests for corner cases in log*().
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <assert.h>
+#include <fenv.h>
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
+ FE_OVERFLOW | FE_UNDERFLOW)
+
+#pragma STDC FENV_ACCESS ON
+
+/*
+ * Test that a function returns the correct value and sets the
+ * exception flags correctly. The exceptmask specifies which
+ * exceptions we should check. We need to be lenient for several
+ * reasoons, but mainly because on some architectures it's impossible
+ * to raise FE_OVERFLOW without raising FE_INEXACT.
+ *
+ * These are macros instead of functions so that assert provides more
+ * meaningful error messages.
+ *
+ * XXX The volatile here is to avoid gcc's bogus constant folding and work
+ * around the lack of support for the FENV_ACCESS pragma.
+ */
+#define test(func, x, result, exceptmask, excepts) do { \
+ volatile long double _d = x; \
+ assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
+ assert(fpequal((func)(_d), (result))); \
+ assert(((func), fetestexcept(exceptmask) == (excepts))); \
+} while (0)
+
+/* Test all the functions that compute log(x). */
+#define testall0(x, result, exceptmask, excepts) do { \
+ test(log, x, result, exceptmask, excepts); \
+ test(logf, x, result, exceptmask, excepts); \
+ test(log2, x, result, exceptmask, excepts); \
+ test(log2f, x, result, exceptmask, excepts); \
+ test(log10, x, result, exceptmask, excepts); \
+ test(log10f, x, result, exceptmask, excepts); \
+} while (0)
+
+/* Test all the functions that compute log(1+x). */
+#define testall1(x, result, exceptmask, excepts) do { \
+ test(log1p, x, result, exceptmask, excepts); \
+ test(log1pf, x, result, exceptmask, excepts); \
+} while (0)
+
+/*
+ * Determine whether x and y are equal, with two special rules:
+ * +0.0 != -0.0
+ * NaN == NaN
+ */
+int
+fpequal(long double x, long double y)
+{
+ return ((x == y && !signbit(x) == !signbit(y)) || isnan(x) && isnan(y));
+}
+
+void
+run_generic_tests(void)
+{
+
+ /* exp(1) == 0, no exceptions raised */
+ testall0(1.0, 0.0, ALL_STD_EXCEPT, 0);
+ testall1(0.0, 0.0, ALL_STD_EXCEPT, 0);
+ testall1(-0.0, -0.0, ALL_STD_EXCEPT, 0);
+
+ /* log(NaN) == NaN, no exceptions raised */
+ testall0(NAN, NAN, ALL_STD_EXCEPT, 0);
+ testall1(NAN, NAN, ALL_STD_EXCEPT, 0);
+
+ /* log(Inf) == Inf, no exceptions raised */
+ testall0(INFINITY, INFINITY, ALL_STD_EXCEPT, 0);
+ testall1(INFINITY, INFINITY, ALL_STD_EXCEPT, 0);
+
+ /* log(x) == NaN for x < 0, invalid exception raised */
+ testall0(-INFINITY, NAN, ALL_STD_EXCEPT, FE_INVALID);
+ testall1(-INFINITY, NAN, ALL_STD_EXCEPT, FE_INVALID);
+ testall0(-1.0, NAN, ALL_STD_EXCEPT, FE_INVALID);
+ testall1(-1.5, NAN, ALL_STD_EXCEPT, FE_INVALID);
+
+ /* log(0) == -Inf, divide-by-zero exception */
+ testall0(0.0, -INFINITY, ALL_STD_EXCEPT & ~FE_INEXACT, FE_DIVBYZERO);
+ testall0(-0.0, -INFINITY, ALL_STD_EXCEPT & ~FE_INEXACT, FE_DIVBYZERO);
+ testall1(-1.0, -INFINITY, ALL_STD_EXCEPT & ~FE_INEXACT, FE_DIVBYZERO);
+}
+
+void
+run_log2_tests(void)
+{
+ int i;
+
+ /*
+ * We should insist that log2() return exactly the correct
+ * result and not raise an inexact exception for powers of 2.
+ */
+ feclearexcept(FE_ALL_EXCEPT);
+ for (i = FLT_MIN_EXP - FLT_MANT_DIG; i < FLT_MAX_EXP; i++) {
+ assert(log2f(ldexpf(1.0, i)) == i);
+ assert(fetestexcept(ALL_STD_EXCEPT) == 0);
+ }
+ for (i = DBL_MIN_EXP - DBL_MANT_DIG; i < DBL_MAX_EXP; i++) {
+ assert(log2(ldexp(1.0, i)) == i);
+ assert(fetestexcept(ALL_STD_EXCEPT) == 0);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ printf("1..2\n");
+
+ run_generic_tests();
+ printf("ok 1 - logarithm\n");
+
+ run_log2_tests();
+ printf("ok 2 - logarithm\n");
+
+ return (0);
+}
diff --git a/tools/regression/lib/msun/test-logarithm.t b/tools/regression/lib/msun/test-logarithm.t
new file mode 100644
index 0000000..8bdfd03
--- /dev/null
+++ b/tools/regression/lib/msun/test-logarithm.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+executable=`basename $0 .t`
+
+make $executable 2>&1 > /dev/null
+
+exec ./$executable
diff --git a/tools/regression/lib/msun/test-lrint.c b/tools/regression/lib/msun/test-lrint.c
index 1693a34a..ba099aa 100644
--- a/tools/regression/lib/msun/test-lrint.c
+++ b/tools/regression/lib/msun/test-lrint.c
@@ -41,9 +41,14 @@ __FBSDID("$FreeBSD$");
#include <ieeefp.h>
#endif
+/*
+ * XXX The volatile here is to avoid gcc's bogus constant folding and work
+ * around the lack of support for the FENV_ACCESS pragma.
+ */
#define test(func, x, result, excepts) do { \
+ volatile double _d = x; \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert((func)(x) == (result) || fetestexcept(FE_INVALID)); \
+ assert((func)(_d) == (result) || fetestexcept(FE_INVALID)); \
assert(fetestexcept(FE_ALL_EXCEPT) == (excepts)); \
} while (0)
diff --git a/tools/regression/lib/msun/test-nearbyint.c b/tools/regression/lib/msun/test-nearbyint.c
new file mode 100644
index 0000000..630ddb9
--- /dev/null
+++ b/tools/regression/lib/msun/test-nearbyint.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2010 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Tests for nearbyint{,f,l}()
+ *
+ * TODO:
+ * - adapt tests for rint(3)
+ * - tests for harder values (more mantissa bits than float)
+ * - tests in other rounding modes
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <assert.h>
+#include <fenv.h>
+#include <math.h>
+#include <stdio.h>
+
+#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
+ FE_OVERFLOW | FE_UNDERFLOW)
+
+/*
+ * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
+ * Fail an assertion if they differ.
+ */
+static int
+fpequal(long double d1, long double d2)
+{
+
+ if (d1 != d2)
+ return (isnan(d1) && isnan(d2));
+ return (copysignl(1.0, d1) == copysignl(1.0, d2));
+}
+
+static void testit(int testnum, float in, float out)
+{
+
+ feclearexcept(ALL_STD_EXCEPT);
+ assert(fpequal(out, nearbyintf(in)));
+ assert(fpequal(-out, nearbyintf(-in)));
+ assert(fetestexcept(ALL_STD_EXCEPT) == 0);
+
+ assert(fpequal(out, nearbyint(in)));
+ assert(fpequal(-out, nearbyint(-in)));
+ assert(fetestexcept(ALL_STD_EXCEPT) == 0);
+
+ assert(fpequal(out, nearbyintl(in)));
+ assert(fpequal(-out, nearbyintl(-in)));
+ assert(fetestexcept(ALL_STD_EXCEPT) == 0);
+
+ printf("ok %d\t\t# nearbyint(%g)\n", testnum, in);
+}
+
+static const float tests[] = {
+/* input output (expected) */
+ 0.0, 0.0,
+ 0.5, 0.0,
+ M_PI, 3,
+ 65536.5, 65536,
+ INFINITY, INFINITY,
+ NAN, NAN,
+};
+
+int
+main(int argc, char *argv[])
+{
+ static const int ntests = sizeof(tests) / sizeof(tests[0]) / 2;
+ int i;
+
+ printf("1..%d\n", ntests);
+ for (i = 0; i < ntests; i++)
+ testit(i + 1, tests[i * 2], tests[i * 2 + 1]);
+
+ return (0);
+}
diff --git a/tools/regression/lib/msun/test-nearbyint.t b/tools/regression/lib/msun/test-nearbyint.t
new file mode 100644
index 0000000..8bdfd03
--- /dev/null
+++ b/tools/regression/lib/msun/test-nearbyint.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+executable=`basename $0 .t`
+
+make $executable 2>&1 > /dev/null
+
+exec ./$executable
diff --git a/tools/regression/lib/msun/test-trig.c b/tools/regression/lib/msun/test-trig.c
index e08c4a7..1ac7873 100644
--- a/tools/regression/lib/msun/test-trig.c
+++ b/tools/regression/lib/msun/test-trig.c
@@ -90,7 +90,7 @@ __FBSDID("$FreeBSD$");
int
fpequal(long double x, long double y)
{
- return ((x == y && signbit(x) == signbit(y)) || isnan(x) && isnan(y));
+ return ((x == y && !signbit(x) == !signbit(y)) || isnan(x) && isnan(y));
}
/*
diff --git a/tools/regression/sockets/unix_gc/unix_gc.c b/tools/regression/sockets/unix_gc/unix_gc.c
index a60aa85..8cae2d9 100644
--- a/tools/regression/sockets/unix_gc/unix_gc.c
+++ b/tools/regression/sockets/unix_gc/unix_gc.c
@@ -55,27 +55,36 @@ static char dpath[PATH_MAX];
static const char *test;
static int
-getopenfiles(void)
+getsysctl(const char *name)
{
size_t len;
int i;
len = sizeof(i);
- if (sysctlbyname("kern.openfiles", &i, &len, NULL, 0) < 0)
- err(-1, "kern.openfiles");
+ if (sysctlbyname(name, &i, &len, NULL, 0) < 0)
+ err(-1, "%s", name);
return (i);
}
static int
+getopenfiles(void)
+{
+
+ return (getsysctl("kern.openfiles"));
+}
+
+static int
getinflight(void)
{
- size_t len;
- int i;
- len = sizeof(i);
- if (sysctlbyname("net.local.inflight", &i, &len, NULL, 0) < 0)
- err(-1, "net.local.inflight");
- return (i);
+ return (getsysctl("net.local.inflight"));
+}
+
+static int
+getdeferred(void)
+{
+
+ return (getsysctl("net.local.deferred"));
}
static void
@@ -707,6 +716,40 @@ listen_connect_drop(void)
test_sysctls(inflight, openfiles);
}
+static void
+recursion(void)
+{
+ int fd[2], ff[2];
+ int inflight, openfiles, deferred, deferred1;
+
+ test = "recursion";
+ printf("%s\n", test);
+ save_sysctls(&inflight, &openfiles);
+ deferred = getdeferred();
+
+ my_socketpair(fd);
+
+ for (;;) {
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, ff) == -1) {
+ if (errno == EMFILE || errno == ENFILE)
+ break;
+ err(-1, "socketpair");
+ }
+ sendfd(ff[0], fd[0]);
+ sendfd(ff[0], fd[1]);
+ close2(fd[1], fd[0]);
+ fd[0] = ff[0];
+ fd[1] = ff[1];
+ }
+ close2(fd[0], fd[1]);
+ sleep(1);
+ test_sysctls(inflight, openfiles);
+ deferred1 = getdeferred();
+ if (deferred != deferred1)
+ errx(-1, "recursion: deferred before %d after %d", deferred,
+ deferred1);
+}
+
#define RMDIR "rm -Rf "
int
main(int argc, char *argv[])
@@ -757,6 +800,8 @@ main(int argc, char *argv[])
listen_connect_nothing();
listen_connect_drop();
+ recursion();
+
printf("Finish: inflight %d open %d\n", getinflight(),
getopenfiles());
return (0);
diff --git a/tools/regression/usr.bin/printf/regress.m5.out b/tools/regression/usr.bin/printf/regress.m5.out
new file mode 100644
index 0000000..2838468
--- /dev/null
+++ b/tools/regression/usr.bin/printf/regress.m5.out
@@ -0,0 +1 @@
+-d
diff --git a/tools/regression/usr.bin/printf/regress.sh b/tools/regression/usr.bin/printf/regress.sh
index 86c600f..980fc70 100644
--- a/tools/regression/usr.bin/printf/regress.sh
+++ b/tools/regression/usr.bin/printf/regress.sh
@@ -2,7 +2,7 @@
REGRESSION_START($1)
-echo '1..8'
+echo '1..9'
REGRESSION_TEST(`b', `printf "abc%b%b" "def\n" "\cghi"')
REGRESSION_TEST(`d', `printf "%d,%5d,%.5d,%0*d,%.*d\n" 123 123 123 5 123 5 123')
@@ -11,6 +11,7 @@ REGRESSION_TEST(`m1', `printf "%c%%%d\0\045\n" abc \"abc')
REGRESSION_TEST(`m2', `printf "abc\n\cdef"')
REGRESSION_TEST(`m3', `printf "%%%s\n" abc def ghi jkl')
REGRESSION_TEST(`m4', `printf "%d,%f,%c,%s\n"')
+REGRESSION_TEST(`m5', `printf -- "-d\n"')
REGRESSION_TEST(`s', `printf "%.3s,%-5s\n" abcd abc')
REGRESSION_END()
diff --git a/tools/tools/nanobsd/nanobsd.sh b/tools/tools/nanobsd/nanobsd.sh
index 0ecf847..ec1fd6b 100644
--- a/tools/tools/nanobsd/nanobsd.sh
+++ b/tools/tools/nanobsd/nanobsd.sh
@@ -182,7 +182,7 @@ make_conf_build ( ) (
echo "${CONF_WORLD}" > ${NANO_MAKE_CONF_BUILD}
echo "${CONF_BUILD}" >> ${NANO_MAKE_CONF_BUILD}
- echo "_WITHOUT_SRCCONF=t" >> ${NANO_MAKE_CONF_BUILD}
+ echo "SRCCONF=/dev/null" >> ${NANO_MAKE_CONF_BUILD}
)
build_world ( ) (
@@ -404,7 +404,7 @@ newfs_part ( ) (
lbl=$3
echo newfs ${NANO_NEWFS} ${NANO_LABEL:+-L${NANO_LABEL}${lbl}} ${dev}
newfs ${NANO_NEWFS} ${NANO_LABEL:+-L${NANO_LABEL}${lbl}} ${dev}
- mount ${dev} ${mnt}
+ mount -o async ${dev} ${mnt}
)
populate_slice ( ) (
@@ -513,8 +513,8 @@ create_i386_diskimage ( ) (
-y ${NANO_HEADS}`
else
echo "Creating md backing file..."
- dd if=/dev/zero of=${IMG} bs=${NANO_SECTS}b \
- count=`expr ${NANO_MEDIASIZE} / ${NANO_SECTS}`
+ rm -f ${IMG}
+ dd if=/dev/zero of=${IMG} seek=${NANO_MEDIASIZE} count=0
MD=`mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} \
-y ${NANO_HEADS}`
fi
diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd
index e5118da..ef88394 100644
--- a/usr.bin/calendar/calendars/calendar.freebsd
+++ b/usr.bin/calendar/calendars/calendar.freebsd
@@ -159,6 +159,7 @@
05/25 Tom Rhodes <trhodes@FreeBSD.org> born in Ellwood City, Pennsylvania, United States, 1981
05/25 Roman Divacky <rdivacky@FreeBSD.org> born in Brno, Czech Republic, 1983
05/26 Jim Pirzyk <pirzyk@FreeBSD.org> born in Chicago, Illinois, United States, 1968
+05/26 Florian Smeets <flo@FreeBSD.org> born in Schwerte, Nordrhein-Westfalen, Germany, 1982
05/27 Ollivier Robert <roberto@FreeBSD.org> born in Paris, France, 1967
05/29 Wilko Bulte <wilko@FreeBSD.org> born in Arnhem, the Netherlands, 1965
05/29 Seigo Tanimura <tanimura@FreeBSD.org> born in Kitakyushu, Fukuoka, Japan, 1976
diff --git a/usr.bin/man/man.sh b/usr.bin/man/man.sh
index 454a3c3..7b6b928 100755
--- a/usr.bin/man/man.sh
+++ b/usr.bin/man/man.sh
@@ -94,6 +94,7 @@ check_cat() {
if exists "$1"; then
use_cat=yes
catpage=$found
+ setup_cattool $catpage
decho " Found catpage $catpage"
return 0
else
@@ -108,12 +109,14 @@ check_man() {
if exists "$1"; then
# We have a match, check for a cat page
manpage=$found
+ setup_cattool $manpage
decho " Found manpage $manpage"
if exists "$2" && is_newer $found $manpage; then
# cat page found and is newer, use that
use_cat=yes
catpage=$found
+ setup_cattool $catpage
decho " Using catpage $catpage"
else
# no cat page or is older
@@ -240,6 +243,35 @@ manpath_warnings() {
fi
}
+# Usage: man_check_for_so page path
+# Returns: True if able to resolve the file, false if it ended in tears.
+# Detects the presence of the .so directive and causes the file to be
+# redirected to another source file.
+man_check_for_so() {
+ local IFS line tstr
+
+ unset IFS
+
+ # We need to loop to accommodate multiple .so directives.
+ while true
+ do
+ line=$($cattool $manpage | head -1)
+ case "$line" in
+ .so*) trim "${line#.so}"
+ decho "$manpage includes $tstr"
+ # Glob and check for the file.
+ if ! check_man "$path/$tstr*" ""; then
+ decho " Unable to find $tstr"
+ return 1
+ fi
+ ;;
+ *) break ;;
+ esac
+ done
+
+ return 0
+}
+
# Usage: man_display_page
# Display either the manpage or catpage depending on the use_cat variable
man_display_page() {
@@ -258,10 +290,10 @@ man_display_page() {
ret=0
else
if [ $debug -gt 0 ]; then
- decho "Command: $ZCAT $catpage | $PAGER"
+ decho "Command: $cattool $catpage | $PAGER"
ret=0
else
- eval "$ZCAT $catpage | $PAGER"
+ eval "$cattool $catpage | $PAGER"
ret=$?
fi
fi
@@ -343,10 +375,10 @@ man_display_page() {
fi
if [ $debug -gt 0 ]; then
- decho "Command: $ZCAT $manpage | $pipeline"
+ decho "Command: $cattool $manpage | $pipeline"
ret=0
else
- eval "$ZCAT $manpage | $pipeline"
+ eval "$cattool $manpage | $pipeline"
ret=$?
fi
}
@@ -361,10 +393,13 @@ man_find_and_display() {
case "$1" in
*/*) if [ -f "$1" -a -r "$1" ]; then
decho "Found a usable page, displaying that"
- found_page=yes
unset use_cat
manpage="$1"
- man_display_page
+ setup_cattool $manpage
+ if man_check_for_so $manpage $(dirname $manpage); then
+ found_page=yes
+ man_display_page
+ fi
return
fi
;;
@@ -380,35 +415,41 @@ man_find_and_display() {
# Check if there is a MACHINE specific manpath.
if find_file $p $sect $MACHINE "$1"; then
- found_page=yes
- man_display_page
- if [ -n "$aflag" ]; then
- continue 2
- else
- return
+ if man_check_for_so $manpage $p; then
+ found_page=yes
+ man_display_page
+ if [ -n "$aflag" ]; then
+ continue 2
+ else
+ return
+ fi
fi
fi
# Check if there is a MACHINE_ARCH
# specific manpath.
if find_file $p $sect $MACHINE_ARCH "$1"; then
- found_page=yes
- man_display_page
- if [ -n "$aflag" ]; then
- continue 2
- else
- return
+ if man_check_for_so $manpage $p; then
+ found_page=yes
+ man_display_page
+ if [ -n "$aflag" ]; then
+ continue 2
+ else
+ return
+ fi
fi
fi
# Check plain old manpath.
if find_file $p $sect '' "$1"; then
- found_page=yes
- man_display_page
- if [ -n "$aflag" ]; then
- continue 2
- else
- return
+ if man_check_for_so $manpage $p; then
+ found_page=yes
+ man_display_page
+ if [ -n "$aflag" ]; then
+ continue 2
+ else
+ return
+ fi
fi
fi
done
@@ -749,6 +790,19 @@ search_whatis() {
exit $rval
}
+# Usage: setup_cattool page
+# Finds an appropriate decompressor based on extension
+setup_cattool() {
+ case "$1" in
+ *.bz) cattool='/usr/bin/bzcat' ;;
+ *.bz2) cattool='/usr/bin/bzcat' ;;
+ *.gz) cattool='/usr/bin/zcat' ;;
+ *.lzma) cattool='/usr/bin/lzcat' ;;
+ *.xz) cattool='/usr/bin/xzcat' ;;
+ *) cattool='/usr/bin/zcat -f' ;;
+ esac
+}
+
# Usage: setup_pager
# Correctly sets $PAGER
setup_pager() {
@@ -845,11 +899,11 @@ TBL=/usr/bin/tbl
TROFF='/usr/bin/groff -S -man'
REFER=/usr/bin/refer
VGRIND=/usr/bin/vgrind
-ZCAT='/usr/bin/zcat -f'
debug=0
man_default_sections='1:1aout:8:2:3:n:4:5:6:7:9:l'
man_default_path='/usr/share/man:/usr/share/openssl/man:/usr/local/man'
+cattool='/usr/bin/zcat -f'
config_global='/etc/man.conf'
diff --git a/usr.bin/printf/printf.c b/usr.bin/printf/printf.c
index 4ac23c6..55cfcc8 100644
--- a/usr.bin/printf/printf.c
+++ b/usr.bin/printf/printf.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-#if !defined(BUILTIN) && !defined(SHELL)
+#ifndef SHELL
#ifndef lint
static char const copyright[] =
"@(#) Copyright (c) 1989, 1993\n\
@@ -69,9 +69,7 @@ static const char rcsid[] =
#define warnx3(a, b, c) warnx(a, b, c)
#endif
-#ifndef BUILTIN
#include <locale.h>
-#endif
#define PF(f, func) do { \
char *b = NULL; \
@@ -105,17 +103,13 @@ static void usage(void);
static char **gargv;
int
-#ifdef BUILTIN
-progprintf(int argc, char *argv[])
-#else
main(int argc, char *argv[])
-#endif
{
size_t len;
int ch, chopped, end, rval;
char *format, *fmt, *start;
-#if !defined(BUILTIN) && !defined(SHELL)
+#ifndef SHELL
(void) setlocale(LC_NUMERIC, "");
#endif
#ifdef SHELL
diff --git a/usr.bin/stat/Makefile b/usr.bin/stat/Makefile
index 808c41e..1a54979 100644
--- a/usr.bin/stat/Makefile
+++ b/usr.bin/stat/Makefile
@@ -1,7 +1,6 @@
# $FreeBSD$
PROG= stat
-WARNS?= 2
LINKS= ${BINDIR}/stat ${BINDIR}/readlink
MLINKS= stat.1 readlink.1
diff --git a/usr.bin/stat/stat.1 b/usr.bin/stat/stat.1
index 8bbdda4..92a8515 100644
--- a/usr.bin/stat/stat.1
+++ b/usr.bin/stat/stat.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: stat.1,v 1.11 2003/05/08 13:07:10 wiz Exp $
+.\" $NetBSD: stat.1,v 1.28 2010/04/05 21:25:01 joerg Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 24, 2010
+.Dd December 5, 2010
.Dt STAT 1
.Os
.Sh NAME
@@ -43,15 +43,15 @@
.Op Fl t Ar timefmt
.Op Ar
.Nm readlink
-.Op Fl n
+.Op Fl fn
.Op Ar
.Sh DESCRIPTION
The
.Nm
utility displays information about the file pointed to by
.Ar file .
-Read, write or execute permissions of the named file are not required, but
-all directories listed in the path name leading to the file must be
+Read, write, or execute permissions of the named file are not required, but
+all directories listed in the pathname leading to the file must be
searchable.
If no argument is given,
.Nm
@@ -60,13 +60,42 @@ displays information about the file descriptor for standard input.
When invoked as
.Nm readlink ,
only the target of the symbolic link is printed.
-If the given argument is not a symbolic link,
+If the given argument is not a symbolic link and the
+.Fl f
+option is not specified,
.Nm readlink
will print nothing and exit with an error.
+If the
+.Fl f
+option is specified, the output is canonicalized by following every symlink
+in every component of the given path recursively.
+.Nm readlink
+will resolve both absolute and relative paths, and return the absolute pathname
+corresponding to
+.Ar file .
+In this case, the argument does not need to be a symbolic link.
.Pp
The information displayed is obtained by calling
.Xr lstat 2
with the given argument and evaluating the returned structure.
+The default format displays the
+.Fa st_dev ,
+.Fa st_ino ,
+.Fa st_mode ,
+.Fa st_nlink ,
+.Fa st_uid ,
+.Fa st_gid ,
+.Fa st_rdev ,
+.Fa st_size ,
+.Fa st_atime ,
+.Fa st_mtime ,
+.Fa st_ctime ,
+.Fa st_birthtime ,
+.Fa st_blksize ,
+.Fa st_blocks ,
+and
+.Fa st_flags
+fields, in that order.
.Pp
The options are as follows:
.Bl -tag -width indent
@@ -107,6 +136,14 @@ will refer to the target of
if file is a symbolic link, and not to
.Ar file
itself.
+If the link is broken or the target does not exist,
+fall back on
+.Xr lstat 2
+and report information about the link.
+.It Fl l
+Display output in
+.Ic ls Fl lT
+format.
.It Fl n
Do not force a newline to appear at the end of each piece of output.
.It Fl q
@@ -136,7 +173,8 @@ display the raw, numerical value (for example, times in seconds since the
epoch, etc.).
.It Fl s
Display information in
-.Dq "shell output" ,
+.Dq shell output
+format,
suitable for initializing variables.
.It Fl x
Display information in a more verbose way as known from some
@@ -334,49 +372,62 @@ A required field specifier, being one of the following:
.It Cm d
Device upon which
.Ar file
-resides.
+resides
+.Pq Fa st_dev .
.It Cm i
.Ar file Ns 's
-inode number.
+inode number
+.Pq Fa st_ino .
.It Cm p
-File type and permissions.
+File type and permissions
+.Pq Fa st_mode .
.It Cm l
Number of hard links to
-.Ar file .
+.Ar file
+.Pq Fa st_nlink .
.It Cm u , g
User ID and group ID of
.Ar file Ns 's
-owner.
+owner
+.Pq Fa st_uid , st_gid .
.It Cm r
-Device number for character and block device special files.
+Device number for character and block device special files
+.Pq Fa st_rdev .
.It Cm a , m , c , B
The time
.Ar file
-was last accessed or modified, of when the inode was last changed, or
-the birth time of the inode.
+was last accessed or modified, or when the inode was last changed, or
+the birth time of the inode
+.Pq Fa st_atime , st_mtime , st_ctime , st_birthtime .
.It Cm z
The size of
.Ar file
-in bytes.
+in bytes
+.Pq Fa st_size .
.It Cm b
Number of blocks allocated for
-.Ar file .
+.Ar file
+.Pq Fa st_blocks .
.It Cm k
-Optimal file system I/O operation block size.
+Optimal file system I/O operation block size
+.Pq Fa st_blksize .
.It Cm f
User defined flags for
.Ar file .
.It Cm v
-Inode generation number.
+Inode generation number
+.Pq Fa st_gen .
.El
.Pp
-The following four field specifiers are not drawn directly from the
+The following five field specifiers are not drawn directly from the
data in
.Vt "struct stat" ,
but are:
.Bl -tag -width indent
.It Cm N
The name of the file.
+.It Cm R
+The absolute pathname corresponding to the file.
.It Cm T
The file type, either as in
.Nm ls Fl F
@@ -406,12 +457,12 @@ as an output form, with the
exception of
.Cm p
which defaults to
-.Cm O ,
+.Cm O ;
.Cm a , m ,
and
.Cm c
which default to
-.Cm D ,
+.Cm D ;
and
.Cm Y , T ,
and
@@ -421,8 +472,15 @@ which default to
.Sh EXIT STATUS
.Ex -std stat readlink
.Sh EXAMPLES
+If no options are specified, the default format is
+"%d %i %Sp %l %Su %Sg %r %z \e"%Sa\e" \e"%Sm\e" \e"%Sc\e" \e"%SB\e" %k %b %#Xf %N".
+.Bd -literal -offset indent
+\*[Gt] stat /tmp/bar
+0 78852 -rw-r--r-- 1 root wheel 0 0 "Jul 8 10:26:03 2004" "Jul 8 10:26:03 2004" "Jul 8 10:28:13 2004" "Jan 1 09:00:00 1970" 16384 0 0 /tmp/bar
+.Ed
+.Pp
Given a symbolic link
-.Pa foo
+.Dq foo
that points from
.Pa /tmp/foo
to
diff --git a/usr.bin/stat/stat.c b/usr.bin/stat/stat.c
index 1ab10ea..950c76a 100644
--- a/usr.bin/stat/stat.c
+++ b/usr.bin/stat/stat.c
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#if 0
#ifndef lint
-__RCSID("$NetBSD: stat.c,v 1.13 2003/07/25 03:21:17 atatat Exp $");
+__RCSID("$NetBSD: stat.c,v 1.30 2010/11/25 04:33:30 dholland Exp $");
#endif
#endif
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <ctype.h>
#include <err.h>
+#include <errno.h>
#include <grp.h>
#include <limits.h>
#include <paths.h>
@@ -152,6 +153,7 @@ __FBSDID("$FreeBSD$");
#define MIDDLE_PIECE 'M'
#define LOW_PIECE 'L'
+#define SHOW_realpath 'R'
#define SHOW_st_dev 'd'
#define SHOW_st_ino 'i'
#define SHOW_st_mode 'p'
@@ -175,7 +177,7 @@ __FBSDID("$FreeBSD$");
void usage(const char *);
void output(const struct stat *, const char *,
- const char *, int, int, int);
+ const char *, int, int);
int format1(const struct stat *, /* stat info */
const char *, /* the file name */
const char *, int, /* the format string itself */
@@ -186,7 +188,7 @@ int format1(const struct stat *, /* stat info */
char *xfflagstostr(unsigned long);
#endif
-char *timefmt;
+const char *timefmt;
int linkfail;
#define addchar(s, c, nl) \
@@ -201,7 +203,7 @@ main(int argc, char *argv[])
struct stat st;
int ch, rc, errs, am_readlink;
int lsF, fmtchar, usestat, fn, nonl, quiet;
- char *statfmt, *options, *synopsis;
+ const char *statfmt, *options, *synopsis;
char dname[sizeof _PATH_DEV + SPECNAMELEN] = _PATH_DEV;
const char *file;
@@ -217,8 +219,8 @@ main(int argc, char *argv[])
if (strcmp(getprogname(), "readlink") == 0) {
am_readlink = 1;
- options = "n";
- synopsis = "[-n] [file ...]";
+ options = "fn";
+ synopsis = "[-fn] [file ...]";
statfmt = "%Y";
fmtchar = 'f';
quiet = 1;
@@ -242,6 +244,10 @@ main(int argc, char *argv[])
quiet = 1;
break;
case 'f':
+ if (am_readlink) {
+ statfmt = "%R";
+ break;
+ }
statfmt = optarg;
/* FALLTHROUGH */
case 'l':
@@ -313,8 +319,17 @@ main(int argc, char *argv[])
rc = fstat(STDIN_FILENO, &st);
} else {
file = argv[0];
- if (usestat)
- rc = stat(file, &st);
+ if (usestat) {
+ /*
+ * Try stat() and if it fails, fall back to
+ * lstat() just in case we're examining a
+ * broken symlink.
+ */
+ if ((rc = stat(file, &st)) == -1 &&
+ errno == ENOENT &&
+ (rc = lstat(file, &st)) == -1)
+ errno = ENOENT;
+ }
else
rc = lstat(file, &st);
}
@@ -326,7 +341,7 @@ main(int argc, char *argv[])
warn("%s: stat", file);
}
else
- output(&st, file, statfmt, fn, nonl, quiet);
+ output(&st, file, statfmt, fn, nonl);
argv++;
argc--;
@@ -368,10 +383,10 @@ usage(const char *synopsis)
*/
void
output(const struct stat *st, const char *file,
- const char *statfmt, int fn, int nonl, int quiet)
+ const char *statfmt, int fn, int nonl)
{
int flags, size, prec, ofmt, hilo, what;
- char buf[PATH_MAX];
+ char buf[PATH_MAX + 4 + 1];
const char *subfmt;
int nl, t, i;
@@ -508,6 +523,7 @@ output(const struct stat *st, const char *file,
}
switch (*statfmt) {
+ fmtcase(what, SHOW_realpath);
fmtcase(what, SHOW_st_dev);
fmtcase(what, SHOW_st_ino);
fmtcase(what, SHOW_st_mode);
@@ -540,7 +556,7 @@ output(const struct stat *st, const char *file,
buf, sizeof(buf),
flags, size, prec, ofmt, hilo, what);
- for (i = 0; i < t && i < sizeof(buf); i++)
+ for (i = 0; i < t && i < (int)(sizeof(buf) - 1); i++)
addchar(stdout, buf[i], &nl);
continue;
@@ -567,7 +583,8 @@ format1(const struct stat *st,
int hilo, int what)
{
u_int64_t data;
- char *sdata, lfmt[24], tmp[20];
+ char *stmp, lfmt[24], tmp[20];
+ const char *sdata;
char smode[12], sid[12], path[PATH_MAX + 4];
struct passwd *pw;
struct group *gr;
@@ -628,28 +645,29 @@ format1(const struct stat *st,
small = (sizeof(st->st_mode) == 4);
data = st->st_mode;
strmode(st->st_mode, smode);
- sdata = smode;
- l = strlen(sdata);
- if (sdata[l - 1] == ' ')
- sdata[--l] = '\0';
+ stmp = smode;
+ l = strlen(stmp);
+ if (stmp[l - 1] == ' ')
+ stmp[--l] = '\0';
if (hilo == HIGH_PIECE) {
data >>= 12;
- sdata += 1;
- sdata[3] = '\0';
+ stmp += 1;
+ stmp[3] = '\0';
hilo = 0;
}
else if (hilo == MIDDLE_PIECE) {
data = (data >> 9) & 07;
- sdata += 4;
- sdata[3] = '\0';
+ stmp += 4;
+ stmp[3] = '\0';
hilo = 0;
}
else if (hilo == LOW_PIECE) {
data &= 0777;
- sdata += 7;
- sdata[3] = '\0';
+ stmp += 7;
+ stmp[3] = '\0';
hilo = 0;
}
+ sdata = stmp;
formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX |
FMTF_STRING;
if (ofmt == 0)
@@ -710,7 +728,6 @@ format1(const struct stat *st,
ts = *tsp; /* copy so we can muck with it */
small = (sizeof(ts.tv_sec) == 4);
data = ts.tv_sec;
- small = 1;
tm = localtime(&ts.tv_sec);
(void)strftime(path, sizeof(path), timefmt, tm);
sdata = path;
@@ -766,6 +783,26 @@ format1(const struct stat *st,
ofmt = FMTF_UNSIGNED;
break;
#endif /* HAVE_STRUCT_STAT_ST_GEN */
+ case SHOW_realpath:
+ small = 0;
+ data = 0;
+ if (file == NULL) {
+ (void)strncpy(path, "(stdin)", sizeof(path));
+ sdata = path;
+ } else {
+ snprintf(path, sizeof(path), " -> ");
+ if (realpath(file, path + 4) == NULL) {
+ linkfail = 1;
+ l = 0;
+ path[0] = '\0';
+ }
+ sdata = path + (ofmt == FMTF_STRING ? 0 : 4);
+ }
+
+ formats = FMTF_STRING;
+ if (ofmt == 0)
+ ofmt = FMTF_STRING;
+ break;
case SHOW_symlink:
small = 0;
data = 0;
@@ -791,24 +828,23 @@ format1(const struct stat *st,
case SHOW_filetype:
small = 0;
data = 0;
- sdata = smode;
- sdata[0] = '\0';
+ sdata = "";
if (hilo == 0 || hilo == LOW_PIECE) {
switch (st->st_mode & S_IFMT) {
- case S_IFIFO: (void)strcat(sdata, "|"); break;
- case S_IFDIR: (void)strcat(sdata, "/"); break;
+ case S_IFIFO: sdata = "|"; break;
+ case S_IFDIR: sdata = "/"; break;
case S_IFREG:
if (st->st_mode &
(S_IXUSR | S_IXGRP | S_IXOTH))
- (void)strcat(sdata, "*");
+ sdata = "*";
break;
- case S_IFLNK: (void)strcat(sdata, "@"); break;
- case S_IFSOCK: (void)strcat(sdata, "="); break;
+ case S_IFLNK: sdata = "@"; break;
+ case S_IFSOCK: sdata = "="; break;
#ifdef S_IFWHT
- case S_IFWHT: (void)strcat(sdata, "%"); break;
+ case S_IFWHT: sdata = "%"; break;
#endif /* S_IFWHT */
#ifdef S_IFDOOR
- case S_IFDOOR: (void)strcat(sdata, ">"); break;
+ case S_IFDOOR: sdata = ">"; break;
#endif /* S_IFDOOR */
}
hilo = 0;
@@ -914,8 +950,9 @@ format1(const struct stat *st,
(void)snprintf(tmp, sizeof(tmp), "%d", size);
(void)strcat(lfmt, tmp);
}
- (void)strcat(lfmt, "d");
- return (snprintf(buf, blen, lfmt, ts.tv_sec));
+ (void)strcat(lfmt, "lld");
+ return (snprintf(buf, blen, lfmt,
+ (long long)ts.tv_sec));
}
/*
@@ -938,7 +975,8 @@ format1(const struct stat *st,
(void)snprintf(tmp, sizeof(tmp), "%d", size);
(void)strcat(lfmt, tmp);
}
- (void)strcat(lfmt, "d");
+ /* Seconds: time_t cast to long long. */
+ (void)strcat(lfmt, "lld");
/*
* The stuff after the decimal point always needs zero
@@ -949,8 +987,10 @@ format1(const struct stat *st,
/*
* We can "print" at most nine digits of precision. The
* rest we will pad on at the end.
+ *
+ * Nanoseconds: long.
*/
- (void)snprintf(tmp, sizeof(tmp), "%dd", prec > 9 ? 9 : prec);
+ (void)snprintf(tmp, sizeof(tmp), "%dld", prec > 9 ? 9 : prec);
(void)strcat(lfmt, tmp);
/*
@@ -964,8 +1004,8 @@ format1(const struct stat *st,
* Use the format, and then tack on any zeroes that
* might be required to make up the requested precision.
*/
- l = snprintf(buf, blen, lfmt, ts.tv_sec, ts.tv_nsec);
- for (; prec > 9 && l < blen; prec--, l++)
+ l = snprintf(buf, blen, lfmt, (long long)ts.tv_sec, ts.tv_nsec);
+ for (; prec > 9 && l < (int)blen; prec--, l++)
(void)strcat(buf, "0");
return (l);
}
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index 7ef8e19..f19553d2 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -518,7 +518,7 @@ get_string(pid_t pid, void *offset, int max)
buf = realloc(buf, totalsize);
size = BLOCKSIZE;
} else {
- buf[totalsize] = '\0';
+ buf[totalsize - 1] = '\0';
return (buf);
}
}
diff --git a/usr.sbin/Makefile.amd64 b/usr.sbin/Makefile.amd64
index 61f94c4..232831b 100644
--- a/usr.sbin/Makefile.amd64
+++ b/usr.sbin/Makefile.amd64
@@ -27,4 +27,7 @@ SUBDIR+= ndiscvt
.endif
SUBDIR+= sicontrol
SUBDIR+= spkrtest
+.if ${MK_SYSINSTALL} != "no"
+SUBDIR+= sade
+.endif
SUBDIR+= zzz
diff --git a/usr.sbin/ac/ac.c b/usr.sbin/ac/ac.c
index c584cd4..5dc8271 100644
--- a/usr.sbin/ac/ac.c
+++ b/usr.sbin/ac/ac.c
@@ -584,7 +584,7 @@ ac(const char *file)
if (!(Flags & AC_W))
usht.ut_tv.tv_sec = time(NULL);
else
- usht.ut_tv.tv_sec = ut_timecopy;;
+ usht.ut_tv.tv_sec = ut_timecopy;
usht.ut_type = SHUTDOWN_TIME;
if (Flags & AC_D) {
diff --git a/usr.sbin/boot0cfg/boot0cfg.c b/usr.sbin/boot0cfg/boot0cfg.c
index fe2c755..cd3bfe2 100644
--- a/usr.sbin/boot0cfg/boot0cfg.c
+++ b/usr.sbin/boot0cfg/boot0cfg.c
@@ -356,8 +356,6 @@ write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size)
if (n != mbr_size)
errx(1, "%s: short write", fname);
return;
- } else {
- err(1, "write_mbr: %s", fname);
}
/*
diff --git a/usr.sbin/bsnmpd/Makefile b/usr.sbin/bsnmpd/Makefile
index c948108..632753d 100644
--- a/usr.sbin/bsnmpd/Makefile
+++ b/usr.sbin/bsnmpd/Makefile
@@ -2,6 +2,7 @@
SUBDIR= gensnmptree \
bsnmpd \
- modules
+ modules \
+ tools
.include <bsd.subdir.mk>
diff --git a/usr.sbin/bsnmpd/bsnmpd/Makefile b/usr.sbin/bsnmpd/bsnmpd/Makefile
index e74f675..f7e9b23 100644
--- a/usr.sbin/bsnmpd/bsnmpd/Makefile
+++ b/usr.sbin/bsnmpd/bsnmpd/Makefile
@@ -2,6 +2,8 @@
#
# Author: Harti Brandt <harti@freebsd.org>
+.include <bsd.own.mk>
+
CONTRIB=${.CURDIR}/../../../contrib/bsnmp
.PATH: ${CONTRIB}/snmpd
@@ -11,7 +13,7 @@ SRCS+= oid.h tree.c tree.h
XSYM= snmpMIB begemotSnmpdModuleTable begemotSnmpd begemotTrapSinkTable \
sysUpTime snmpTrapOID coldStart authenticationFailure \
begemotSnmpdTransUdp begemotSnmpdTransLsock begemotSnmpdLocalPortTable \
- freeBSDVersion
+ freeBSD freeBSDVersion
CLEANFILES= oid.h tree.c tree.h
MAN= bsnmpd.1 snmpmod.3
NO_WERROR=
@@ -31,6 +33,10 @@ LDADD= -lbegemot -lbsnmp -lwrap
LDFLAGS= -export-dynamic
+.if ${MK_OPENSSL} != "no"
+CFLAGS+= -DHAVE_LIBCRYPTO
+.endif
+
oid.h: tree.def Makefile
gensnmptree -e ${XSYM} < ${.ALLSRC:M*.def} > ${.TARGET}
diff --git a/usr.sbin/bsnmpd/modules/Makefile b/usr.sbin/bsnmpd/modules/Makefile
index c2b7360..f7deb77 100644
--- a/usr.sbin/bsnmpd/modules/Makefile
+++ b/usr.sbin/bsnmpd/modules/Makefile
@@ -13,6 +13,8 @@ SUBDIR= ${_snmp_atm} \
snmp_hostres \
snmp_mibII \
snmp_pf \
+ snmp_usm \
+ snmp_vacm \
snmp_wlan
.if ${MK_NETGRAPH_SUPPORT} != "no"
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
index c7178f3..bc4bc35 100644
--- a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
@@ -26,6 +26,7 @@
* $FreeBSD$
*/
+#include <sys/queue.h>
#include <bsnmp/snmpmod.h>
#include <net/pfvar.h>
diff --git a/usr.sbin/bsnmpd/modules/snmp_usm/Makefile b/usr.sbin/bsnmpd/modules/snmp_usm/Makefile
new file mode 100755
index 0000000..4ae818a
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_usm/Makefile
@@ -0,0 +1,22 @@
+# $FreeBSD$
+#
+# Author: Shteryana Shopova <syrinx@freebsd.org>
+
+CONTRIB= ${.CURDIR}/../../../../contrib/bsnmp
+.PATH: ${CONTRIB}/snmp_usm
+
+MOD= usm
+SRCS= usm_snmp.c
+XSYM= snmpUsmMIB usmNoAuthProtocol usmHMACMD5AuthProtocol \
+ usmHMACSHAAuthProtocol usmNoPrivProtocol usmDESPrivProtocol \
+ usmAesCfb128Protocol usmUserSecurityName
+
+MAN= snmp_usm.3
+
+CFLAGS+= -I${CONTRIB}/lib -I${CONTRIB}/snmpd -DSNMPTREE_TYPES
+CFLAGS+= -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY -DHAVE_SYS_TREE_H
+
+DEFS= ${MOD}_tree.def
+BMIBS=
+
+.include <bsd.snmpmod.mk>
diff --git a/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile b/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile
new file mode 100755
index 0000000..1be8d62
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile
@@ -0,0 +1,20 @@
+# $FreeBSD$
+#
+# Author: Shteryana Shopova <syrinx@freebsd.org>
+
+CONTRIB= ${.CURDIR}/../../../../contrib/bsnmp
+.PATH: ${CONTRIB}/snmp_vacm
+
+MOD= vacm
+SRCS= vacm_snmp.c
+XSYM= snmpVacmMIB
+
+MAN= snmp_vacm.3
+
+CFLAGS+= -I${CONTRIB}/lib -I${CONTRIB}/snmpd -DSNMPTREE_TYPES
+CFLAGS+= -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY -DHAVE_SYS_TREE_H
+
+DEFS= ${MOD}_tree.def
+BMIBS=
+
+.include <bsd.snmpmod.mk>
diff --git a/usr.sbin/bsnmpd/tools/Makefile b/usr.sbin/bsnmpd/tools/Makefile
new file mode 100644
index 0000000..3ffc01e
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+# Author: Shteryana Shopova <syrinx@FreeBSD.org>
+
+SUBDIR= libbsnmptools \
+ bsnmptools
+
+.include <bsd.subdir.mk>
diff --git a/usr.sbin/bsnmpd/tools/Makefile.inc b/usr.sbin/bsnmpd/tools/Makefile.inc
new file mode 100644
index 0000000..e08fe26
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/Makefile.inc
@@ -0,0 +1,13 @@
+# $FreeBSD$
+# Author: Shteryana Shopova <syrinx@FreeBSD.org>
+
+BINDIR?= /usr/bin
+
+CFLAGS+= -I. -I${.CURDIR}
+
+.if exists(${.OBJDIR}/../libbsnmptools)
+LIBBSNMPTOOLSDIR= ${.OBJDIR}/../libbsnmptools
+.else
+LIBBSNMPTOOLSDIR= ${.CURDIR}/../libbsnmptools
+.endif
+LIBBSNMPTOOLS= ${LIBBSNMPTOOLSDIR}/libbsnmptools.a
diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/Makefile b/usr.sbin/bsnmpd/tools/bsnmptools/Makefile
new file mode 100644
index 0000000..94a1cea
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/Makefile
@@ -0,0 +1,28 @@
+# $FreeBSD$
+# Author: Shteryana Shopova <syrinx@FreeBSD.org>
+
+.include <bsd.own.mk>
+
+.PATH: ${.CURDIR}
+
+PROG= bsnmpget
+
+DPADD+= ${LIBBSNMP} ${LIBBSNMPTOOLS}
+LDADD+= -lbsnmp -lbsnmptools
+CFLAGS+= -I${.CURDIR}/../libbsnmptools
+LDFLAGS+= -L${LIBBSNMPTOOLSDIR}
+
+.if ${MK_OPENSSL} != "no"
+DPADD+= ${LIBCRYPTO}
+LDADD+= -lcrypto
+.endif
+
+LINKS= ${BINDIR}/bsnmpget ${BINDIR}/bsnmpwalk
+LINKS+= ${BINDIR}/bsnmpget ${BINDIR}/bsnmpset
+
+MAN= bsnmpget.1
+
+MLINKS= bsnmpget.1 bsnmpwalk.1
+MLINKS+= bsnmpget.1 bsnmpset.1
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1 b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1
new file mode 100644
index 0000000..aa3f911
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.1
@@ -0,0 +1,401 @@
+.\"
+.\" Copyright (c) 2010 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" Portions of this documentation were written by Shteryana Sotirova Shopova
+.\" under sponsorship from the FreeBSD Foundation.
+.\"
+.\" Copyright (c) 2005-2007 The FreeBSD Project.
+.\" All rights reserved.
+.\"
+.\" Author: Shteryana Shopova <syrinx@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 17, 2007
+.Dt BSNMPGET 1
+.Os
+.Sh NAME
+.Nm bsnmpget ,
+.Nm bsnmpwalk ,
+.Nm bsnmpset
+.Nd "simple tools for querying SNMP agents"
+.Sh SYNOPSIS
+.Nm
+.Op Fl aDdehnK
+.Op Fl A Ar options
+.Op Fl b Ar buffersize
+.Op Fl C Ar options
+.Op Fl I Ar options
+.Op Fl i Ar filelist
+.Op Fl l Ar filename
+.Op Fl M Ar max-repetitions
+.Op Fl N Ar non-repeaters
+.Op Fl o Ar output
+.Op Fl P Ar options
+.Op Fl p Ar pdu
+.Op Fl r Ar retries
+.Op Fl s Ar [trans::][community@][server][:port]
+.Op Fl t Ar timeout
+.Op Fl U Ar options
+.Op Fl v Ar version
+.Op Ar OID ...
+.Pp
+.Nm bsnmpwalk
+.Op Fl dhnK
+.Op Fl A Ar options
+.Op Fl b Ar buffersize
+.Op Fl C Ar options
+.Op Fl I Ar options
+.Op Fl i Ar filelist
+.Op Fl l Ar filename
+.Op Fl o Ar output
+.Op Fl P Ar options
+.Op Fl r Ar retries
+.Op Fl s Ar [trans::][community@][server][:port]
+.Op Fl t Ar timeout
+.Op Fl U Ar options
+.Op Fl v Ar version
+.Op Ar OID ...
+.Pp
+.Nm bsnmpset
+.Op Fl adehnK
+.Op Fl A Ar options
+.Op Fl b Ar buffersize
+.Op Fl C Ar options
+.Op Fl I Ar options
+.Op Fl i Ar filelist
+.Op Fl l Ar filename
+.Op Fl o Ar output
+.Op Fl P Ar options
+.Op Fl r Ar retries
+.Op Fl s Ar [trans::][community@][server][:port]
+.Op Fl t Ar timeout
+.Op Fl U Ar options
+.Op Fl v Ar version
+.Ar OID Ns = Ar syntax Ns : Ns Ar value
+.Op Ar OID Ns = Ar syntax Ns : Ns Ar value ...
+.Sh DESCRIPTION
+.Nm ,
+.Nm bsnmpwalk
+and
+.Nm bsnmpset
+are simple tools for retrieving management information from and setting
+management information to a Simple Network Managment Protocol (SNMP) agent.
+.Pp
+Depending on the options
+.Nm bsnmpget
+constructs either a SMNP GetRequest, GetNextRequest
+or a GetBulkRequest packet, fills in the object identifiers (OIDs) of the
+objects whose values will be retrived, waits for a response and prints it if
+received successfully.
+.Pp
+.Nm Bsnmpwalk
+queries an agent with SMNP GetNextRequest packets,
+asking for values of OID instances that are a part of the object subtree
+rooted at the provided OIDs.
+.Pp
+.Nm Bsnmpset
+constructs a SMNP SetRequest packet, fills in the OIDs (object identifiers),
+syntaxes and values of the objects whose values are to be set and waits for a
+responce from server.
+.Sh OPTIONS
+.Pp
+The options are as follows (not all apply to all three programs):
+.Bl -tag -width ".It Fl D Ar options"
+.It Fl A Ar options
+Authentication options to use with SNMPv3 PDUs
+.Bl -tag -width
+.It Cm proto=[md5|sha]
+The protocol to use when calculating the PDU message digest.
+.It Cm key=authkey
+A binary localized authentication key to use when calculating the PDU message
+digest.
+.El
+.Pp
+By default SNMPv3 PDUs are sent unauthenticated.
+.It Fl a
+Skip any sanity checks when adding OIDs to a Protocol Data Unit (PDU):
+ingore syntax/access type, allow adding of non-leaf objects for GetPdu and
+read-only objects to a SetPDU.
+.It Fl b Ar buffersize
+Tune the size of buffers used to send and receive packets.
+The default size is 10000 bytes which should be enough unless an agent sends
+a really large octetstring.
+The maximum allowed length is 65535 according to the Structure of Management
+Information (SMIv2).
+.It Fl C Ar options
+The context to query with SNMPv3 PDUs.
+.Bl -tag -width
+.It Cm context=name
+The context name. Default is "" (empty).
+.It Cm context-engine=engine-id
+The SNMP Engine ID of the context to query with SNMPv3 PDUs, represented as
+binary octet string. By default, this is set to the Engine ID of the SNMP agent.
+.El
+.It Fl D
+Perform SNMP USM Engine Discovery, rather than sending a request for the value
+of a specific object.
+.It Fl d
+Turn on debugging.
+This option will cause the packets sent and received to be dumped to the
+terminal.
+.It Fl e
+Retry on error.
+If an error is returned in the response PDU, resend the request removing the
+variable that caused the error until a valid response is received.
+This is only usefull for a GetRequest- and a GetNextRequest-PDU.
+.It Fl h
+Print a short help text with default values for various options.
+.It Fl I Ar options
+Load each MIB description file from the given list to translate symbolic
+object names to their numerical representation and vice versa.
+Use the other options to obtain a non-default behaviour:
+.Bl -tag -width
+.It Cm cut=OID
+Specifies the initial OID that was cut by
+.Xr gensnmpdef 1
+when producing the MIB description file.
+The default value is .iso(1).org(3).dod(6) which is what should have been
+used for all the files installed under /usr/share/snmp/defs/ .
+Use this only if you generated your own files, providing a '-c' option to
+.Xr gensnmpdef 1 .
+.It Cm path=filedir
+The directory where files in the list will be searched.
+The default is
+.Pa /usr/share/snmp/defs/ .
+.It Cm file=filelist
+A comma separated list of files to which the two options above will apply.
+.El
+.Pp
+The file suboption has to come after the other suboptions so that their
+non-default values will be applied to the list of files.
+The order of the other suboptions before each file suboption can be random.
+Suboptions may be separated either by commas or by spaces.
+If using spaces make sure the entire option string is one argument, for
+example using quotes.
+.It Fl i Ar filelist
+List of MIB description files produced by
+.Xr gensnmpdef 1 which
+.Nm bsnmpget ,
+.Nm bsnmpwalk
+or
+.Nm bsnmpset
+will search to translate numerical OIDs to their symbolic object names.
+Multiple files can be provided either giving this option multiple times
+or a comma separated list of file names.
+If a filename begins with a letter the default directory,
+/usr/share/snmp/defs/ ,
+will be searched.
+.It Fl K
+Calculate and display the localized authentication and privacy keys
+corresponding to a plain text password. The password is obtain via the
+environment. Additionally, if one or more OIDs are specified, the calculated
+keys are used when processing the SNMPv3 requests.
+.It Fl l Ar filename
+The path of the posix local (unix domain) socket if local
+transport is used.
+.It Fl M Ar max-repetitions
+The value for the max-repetitions field in a GetBulk PDU.
+Default is 1.
+.It Fl N Ar non-repeaters
+The value for the non-repeaters field in a GetBulk PDU.
+Default is 0.
+.It Fl n
+Only use numerical representations for input and output OIDs and do not
+try to resolve symbolic object names.
+Note that
+.Nm bsnmpget ,
+.Nm bsnmpwalk
+and
+.Nm bsnmpset
+will print numerical OIDs anyway if the corresponding string representation
+is not found in the MIB description files.
+.It Fl o Ar [quiet|short|verbose]
+The format used to print the received response.
+Quiet only prints values, short (default) prints an abbreviated OID
+representation and the value.
+In addition to the short output verbose prints the type before the value.
+.It Fl P Ar options
+Privacy options to use with SNMPv3 PDUs
+.Bl -tag -width
+.It Cm proto=[aes|des]
+The protocol to use when encypting/decrypting SNMPv3 PDU data.
+.It Cm key=privkey
+A binary localized privacy key to use when encypting/decrypting SNMPv3 PDU data.
+.El
+.Pp
+By default plain text SNMPv3 PDUs are sent.
+.It Fl p Ar [get|getnext|getbulk]
+The PDU type to send by
+.Nm bsmpget .
+Default is get.
+.It Fl r Ar retries
+Number of resends of request packets before giving up if the agent does
+not respond after the first try.
+Default is 3.
+.It Fl s Ar [trans::] Ns Ar [community@] Ns Ar [server] Ns Ar [:port]
+Each of the server specification components is optional but at least one
+has to be provided if '-s' option is used.
+The server specification is constructed in the following manner:
+.Bl -tag -width
+.It Cm trans::
+Transport type may be one of udp, stream or dgram.
+If this option is not provided an udp inet/inet6 socket will be used, which
+is the most common.
+Stream stands for a posix local stream socket and a posix local datagram
+socket will be used if dgram is specified.
+.It Cm community@
+Specify an SNMP community string to be used when sending packets.
+If the option is skipped the default "public" will be used for
+.Nm
+and
+.Nm bsnmpwalk
+and the default "private" community string will be used for
+.Nm bsnmpset .
+.It Cm server
+This might be either the IP address or the hostname where the agent is
+listening.
+The default is 'localhost'.
+.It Cm port
+The destination port to send the requests to.
+This is useful if the SNMP agent listens on a non-default port.
+Default is given by the 'snmp' entry in /etc/services, port 161.
+.El
+.It Fl t Ar timeout
+Number of seconds before resending a request packet if the agent does
+not respond.
+The default value is 3 seconds.
+.It Fl U Ar options
+User credentials when sending SNMPv3 PDUs.
+.Bl -tag -width
+.It Cm engine=id
+The Engine ID of the SNMP agent represented as a binary octet string.
+.It Cm engine-boots=value
+The value of the snmpEngineBoots of the SNMP agent.
+.It Cm engine-time=value
+The value of the snmpEngineTime of the SNMP agent.
+.Pp
+If any of the above is not specified, SNMP USM Engine Discovery is attempted.
+This is also the default behavior.
+.It Cm name=username
+The USM user name to include in the SNMPv3 PDUs. By default, the user name is
+obtain via the environment
+.El
+.It Fl v Ar version
+The SNMP protocol version to use when sending requests. SNMP versions 1, 2 and
+3 are supported.
+If no version option is provided
+.Nm bsnmpget ,
+.Nm bsnmpwalk
+and
+.Nm bsnmpset
+will use version 2.
+Note that GetBulkRequest-PDUs were introduced in SNMPv2 thus setting the
+version to 1 is incompatiable with sending a GetBulk PDU.
+.It OID
+The object identifier whose value to retrive.
+At least one OID should be provided for
+.Nm bsnmpget
+to be able to send a request.
+.Pp
+For
+.Nm bsnmpwalk
+this is the root object identifier of the subtree whose values are to be
+retrived.
+If no OID is provided
+.Nm bsnmpwalk
+will walk the mib2 subtree rooted
+at .iso(1).org(3).dod(6).internet(1).mgmt(2).mib2(1) .
+.Pp
+Any of the formats used to print a single variable
+is valid as input OID:
+.Bl -tag -width
+.It 1.3.6.1.2.1.25.1.1.0
+.It sysDescr
+.It ifPhysAddress.1
+.It ifRcvAddressStatus.2.6.255.255.255.255.255.255
+.It ifRcvAddressType[2,ff:ff:ff:ff:ff:ff]
+.It ifRcvAddressStatus[Integer:1,OctetString:ff:ff:ff:ff:ff:ff]
+(requires '-o verbose' option)
+.El
+.Pp
+Square brackets are used to denote an entry's indexes.
+When used in an input OID, the square brackets may have to be
+escaped or the OID has to be quoted to protect it from the shell.
+Note there is no difference between ifName.1 and "ifName[1]".
+.It OID Ns = Ns Ar [syntax Ns :] Ns Ar value
+The object identifier with its syntax type and value that is to be set.
+At least one such string OID=[syntax:]value should be provided to
+.Nm bsnmpset
+to be able to send a request.
+.Bl -tag -width
+.It Cm OID
+OID may be input as a string, a string followed by a random number of integers
+(suboids) separated by dots, a sequence of integers separated by dots - that is
+if '-n' options is used - and in such case a syntax is required for every value,
+or a string followed by square brackets (used to denote an entry's indexes) and
+corresponding indexes.
+Any of formats used to print a single variable by
+.Nm bsnmpset is
+valid for inpit OID as well:
+.Bl -tag -width
+.It 1.3.6.1.2.1.25.1.1.0=TimeTicks:537615486
+.It sysLocation=OctetString:"@ Home" (with '-o verbose' option)
+.It sysLocation.0="@ Home"
+.It 1.3.6.1.2.1.2.2.1.6.1=OctetString:ffffffffffff
+.It ifPhysAddress.1="00:02:b3:1d:1c:a3"
+.It ifRcvAddressStatus.1.6.255.255.255.255.255.255=1
+.It "ifRcvAddressStatus[Integer:1,OctetString:ff:ff:ff:ff:ff:ff]=Integer:1"
+(with '-o verbose' option)
+.El
+.It Cm syntax
+where syntax string is one of :
+Integer, OctetString, OID, IpAddress, Counter32, Gauge, TimeTicks, Counter64.
+.It Cm value
+The value to be set - IP address in form of u.u.u.u - for example
+1.3.1.6.1.2.0=IpAddress:192.168.0.1, strings require inverted-commas if they
+contain any special characters or spaces, all other numeric types don't.
+.El
+.Sh ENVIRONMENT
+.Nm ,
+.Nm bsnmpwalk
+and
+.Nm bsnmpset
+use the following environment variables:
+.Bl -tag -width SNMPAUTH
+.It Ev SNMPAUTH
+Specifies a default SNMP USM authentication protocol.
+.It Ev SNMPPRIV
+Specifies a default SNMP USM privacy protocol.
+.It Ev SNMPUSER
+Specifies a default SNMP USM user name.
+.It Ev SNMPPASSWD
+Specifies the SNMP USM plain text password to use when calculating localized
+authentication and privacy keys. If this variable exists in the environment,
+SMNPv3 is the default version to use for outgoing requests.
+.Sh SEE ALSO
+.Xr gensnmpdef 1
+.Sh AUTHORS
+.An Shteryana Shopova Aq syrinx@FreeBSD.org
diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
new file mode 100644
index 0000000..c05a05a
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
@@ -0,0 +1,1275 @@
+/*-
+ * Copyright (c) 2005-2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation and use in source and
+ * binary forms, with or without modification, are permitted provided that
+ * the following conditions are met:
+ *
+ * 1. Redistributions of source code or documentation must retain the above
+ * copyright notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Bsnmpget and bsnmpwalk are simple tools for querying SNMP agents,
+ * bsnmpset can be used to set MIB objects in an agent.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/queue.h>
+#include <sys/types.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+#include <bsnmp/snmpclient.h>
+#include "bsnmptc.h"
+#include "bsnmptools.h"
+
+static const char *program_name = NULL;
+static enum program_e {
+ BSNMPGET,
+ BSNMPWALK,
+ BSNMPSET
+} program;
+
+/* *****************************************************************************
+ * Common bsnmptools functions.
+ */
+static void
+usage(void)
+{
+ fprintf(stderr,
+"Usage:\n"
+"%s %s [-A options] [-b buffersize] [-C options] [-I options]\n"
+"\t[-i filelist] [-l filename]%s [-o output] [-P options]\n"
+"\t%s[-r retries] [-s [trans::][community@][server][:port]]\n"
+"\t[-t timeout] [-U options] [-v version]%s\n",
+ program_name,
+ (program == BSNMPGET) ? "[-aDdehnK]" :
+ (program == BSNMPWALK) ? "[-dhnK]" :
+ (program == BSNMPSET) ? "[-adehnK]" :
+ "",
+ (program == BSNMPGET) ? " [-M max-repetitions] [-N non-repeaters]" : "",
+ (program == BSNMPGET) ? "[-p pdu] " : "",
+ (program == BSNMPGET) ? " OID [OID ...]" :
+ (program == BSNMPWALK || program == BSNMPSET) ? " [OID ...]" :
+ ""
+ );
+}
+
+static int32_t
+parse_max_repetitions(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ uint32_t v;
+
+ assert(opt_arg != NULL);
+
+ v = strtoul(opt_arg, (void *) NULL, 10);
+
+ if (v > SNMP_MAX_BINDINGS) {
+ warnx("Max repetitions value greater than %d maximum allowed.",
+ SNMP_MAX_BINDINGS);
+ return (-1);
+ }
+
+ SET_MAXREP(snmptoolctx, v);
+ return (2);
+}
+
+static int32_t
+parse_non_repeaters(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ uint32_t v;
+
+ assert(opt_arg != NULL);
+
+ v = strtoul(opt_arg, (void *) NULL, 10);
+
+ if (v > SNMP_MAX_BINDINGS) {
+ warnx("Non repeaters value greater than %d maximum allowed.",
+ SNMP_MAX_BINDINGS);
+ return (-1);
+ }
+
+ SET_NONREP(snmptoolctx, v);
+ return (2);
+}
+
+static int32_t
+parse_pdu_type(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ assert(opt_arg != NULL);
+
+ if (strcasecmp(opt_arg, "getbulk") == 0)
+ SET_PDUTYPE(snmptoolctx, SNMP_PDU_GETBULK);
+ else if (strcasecmp(opt_arg, "getnext") == 0)
+ SET_PDUTYPE(snmptoolctx, SNMP_PDU_GETNEXT);
+ else if (strcasecmp(opt_arg, "get") == 0)
+ SET_PDUTYPE(snmptoolctx, SNMP_PDU_GET);
+ else {
+ warnx("PDU type '%s' not supported.", opt_arg);
+ return (-1);
+ }
+
+ return (2);
+}
+
+static int32_t
+snmptool_parse_options(struct snmp_toolinfo *snmptoolctx, int argc, char **argv)
+{
+ int32_t count, optnum = 0;
+ int ch;
+ const char *opts;
+
+ switch (program) {
+ case BSNMPWALK:
+ opts = "dhnKA:b:C:I:i:l:o:P:r:s:t:U:v:";
+ break;
+ case BSNMPGET:
+ opts = "aDdehnKA:b:C:I:i:l:M:N:o:P:p:r:s:t:U:v:";
+ break;
+ case BSNMPSET:
+ opts = "adehnKA:b:C:I:i:l:o:P:r:s:t:U:v:";
+ break;
+ default:
+ return (-1);
+ }
+
+ while ((ch = getopt(argc, argv, opts)) != EOF) {
+ switch (ch) {
+ case 'A':
+ count = parse_authentication(snmptoolctx, optarg);
+ break;
+ case 'a':
+ count = parse_skip_access(snmptoolctx);
+ break;
+ case 'b':
+ count = parse_buflen(optarg);
+ break;
+ case 'D':
+ count = parse_discovery(snmptoolctx);
+ break;
+ case 'd':
+ count = parse_debug();
+ break;
+ case 'e':
+ count = parse_errors(snmptoolctx);
+ break;
+ case 'h':
+ usage();
+ return (-2);
+ case 'C':
+ count = parse_context(snmptoolctx, optarg);
+ break;
+ case 'I':
+ count = parse_include(snmptoolctx, optarg);
+ break;
+ case 'i':
+ count = parse_file(snmptoolctx, optarg);
+ break;
+ case 'K':
+ count = parse_local_key(snmptoolctx);
+ break;
+ case 'l':
+ count = parse_local_path(optarg);
+ break;
+ case 'M':
+ count = parse_max_repetitions(snmptoolctx, optarg);
+ break;
+ case 'N':
+ count = parse_non_repeaters(snmptoolctx, optarg);
+ break;
+ case 'n':
+ count = parse_num_oids(snmptoolctx);
+ break;
+ case 'o':
+ count = parse_output(snmptoolctx, optarg);
+ break;
+ case 'P':
+ count = parse_privacy(snmptoolctx, optarg);
+ break;
+ case 'p':
+ count = parse_pdu_type(snmptoolctx, optarg);
+ break;
+ case 'r':
+ count = parse_retry(optarg);
+ break;
+ case 's':
+ count = parse_server(optarg);
+ break;
+ case 't':
+ count = parse_timeout(optarg);
+ break;
+ case 'U':
+ count = parse_user_security(snmptoolctx, optarg);
+ break;
+ case 'v':
+ count = parse_version(optarg);
+ break;
+ case '?':
+ default:
+ usage();
+ return (-1);
+ }
+ if (count < 0)
+ return (-1);
+ optnum += count;
+ }
+
+ return (optnum);
+}
+
+/*
+ * Read user input OID - one of following formats:
+ * 1) 1.2.1.1.2.1.0 - that is if option numeric was giveni;
+ * 2) string - in such case append .0 to the asn_oid subs;
+ * 3) string.1 - no additional proccessing required in such case.
+ */
+static char *
+snmptools_parse_stroid(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_object *obj, char *argv)
+{
+ char string[MAXSTR], *str;
+ int32_t i = 0;
+ struct asn_oid in_oid;
+
+ str = argv;
+
+ if (*str == '.')
+ str++;
+
+ while (isalpha(*str) || *str == '_' || (i != 0 && isdigit(*str))) {
+ str++;
+ i++;
+ }
+
+ if (i <= 0 || i >= MAXSTR)
+ return (NULL);
+
+ memset(&in_oid, 0, sizeof(struct asn_oid));
+ if ((str = snmp_parse_suboid((argv + i), &in_oid)) == NULL) {
+ warnx("Invalid OID - %s", argv);
+ return (NULL);
+ }
+
+ strlcpy(string, argv, i + 1);
+ if (snmp_lookup_oidall(snmptoolctx, obj, string) < 0) {
+ warnx("No entry for %s in mapping lists", string);
+ return (NULL);
+ }
+
+ /* If OID given on command line append it. */
+ if (in_oid.len > 0)
+ asn_append_oid(&(obj->val.var), &in_oid);
+ else if (*str == '[') {
+ if ((str = snmp_parse_index(snmptoolctx, str + 1, obj)) == NULL)
+ return (NULL);
+ } else if (obj->val.syntax > 0 && GET_PDUTYPE(snmptoolctx) ==
+ SNMP_PDU_GET) {
+ if (snmp_suboid_append(&(obj->val.var), (asn_subid_t) 0) < 0)
+ return (NULL);
+ }
+
+ return (str);
+}
+
+static int32_t
+snmptools_parse_oid(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_object *obj, char *argv)
+{
+ if (argv == NULL)
+ return (-1);
+
+ if (ISSET_NUMERIC(snmptoolctx)) {
+ if (snmp_parse_numoid(argv, &(obj->val.var)) < 0)
+ return (-1);
+ } else {
+ if (snmptools_parse_stroid(snmptoolctx, obj, argv) == NULL &&
+ snmp_parse_numoid(argv, &(obj->val.var)) < 0)
+ return (-1);
+ }
+
+ return (1);
+}
+
+static int32_t
+snmptool_add_vbind(struct snmp_pdu *pdu, struct snmp_object *obj)
+{
+ if (obj->error > 0)
+ return (0);
+
+ asn_append_oid(&(pdu->bindings[pdu->nbindings].var), &(obj->val.var));
+ pdu->nbindings++;
+
+ return (pdu->nbindings);
+}
+
+/* *****************************************************************************
+ * bsnmpget private functions.
+ */
+static int32_t
+snmpget_verify_vbind(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu,
+ struct snmp_object *obj)
+{
+ if (pdu->version == SNMP_V1 && obj->val.syntax ==
+ SNMP_SYNTAX_COUNTER64) {
+ warnx("64-bit counters are not supported in SNMPv1 PDU");
+ return (-1);
+ }
+
+ if (ISSET_NUMERIC(snmptoolctx) || pdu->type == SNMP_PDU_GETNEXT ||
+ pdu->type == SNMP_PDU_GETBULK)
+ return (1);
+
+ if (pdu->type == SNMP_PDU_GET && obj->val.syntax == SNMP_SYNTAX_NULL) {
+ warnx("Only leaf object values can be added to GET PDU");
+ return (-1);
+ }
+
+ return (1);
+}
+
+/*
+ * In case of a getbulk PDU, the error_status and error_index fields are used by
+ * libbsnmp to hold the values of the non-repeaters and max-repetitions fields
+ * that are present only in the getbulk - so before sending the PDU make sure
+ * these have correct values as well.
+ */
+static void
+snmpget_fix_getbulk(struct snmp_pdu *pdu, uint32_t max_rep, uint32_t non_rep)
+{
+ assert(pdu != NULL);
+
+ if (pdu->nbindings < non_rep)
+ pdu->error_status = pdu->nbindings;
+ else
+ pdu->error_status = non_rep;
+
+ if (max_rep > 0)
+ pdu->error_index = max_rep;
+ else
+ pdu->error_index = 1;
+}
+
+static int
+snmptool_get(struct snmp_toolinfo *snmptoolctx)
+{
+ struct snmp_pdu req, resp;
+
+ snmp_pdu_create(&req, GET_PDUTYPE(snmptoolctx));
+
+ while ((snmp_pdu_add_bindings(snmptoolctx, snmpget_verify_vbind,
+ snmptool_add_vbind, &req, SNMP_MAX_BINDINGS)) > 0) {
+
+ if (GET_PDUTYPE(snmptoolctx) == SNMP_PDU_GETBULK)
+ snmpget_fix_getbulk(&req, GET_MAXREP(snmptoolctx),
+ GET_NONREP(snmptoolctx));
+
+ if (snmp_dialog(&req, &resp) == -1) {
+ warnx("Snmp dialog - %s", strerror(errno));
+ break;
+ }
+
+ if (snmp_parse_resp(&resp, &req) >= 0) {
+ snmp_output_resp(snmptoolctx, &resp);
+ break;
+ }
+
+ snmp_output_err_resp(snmptoolctx, &resp);
+ if (GET_PDUTYPE(snmptoolctx) == SNMP_PDU_GETBULK ||
+ !ISSET_RETRY(snmptoolctx))
+ break;
+
+ /*
+ * Loop through the object list and set object->error to the
+ * varbinding that caused the error.
+ */
+ if (snmp_object_seterror(snmptoolctx,
+ &(resp.bindings[resp.error_index - 1]),
+ resp.error_status) <= 0)
+ break;
+
+ fprintf(stderr, "Retrying...\n");
+ snmp_pdu_free(&resp);
+ snmp_pdu_create(&req, GET_PDUTYPE(snmptoolctx));
+ }
+
+ snmp_pdu_free(&resp);
+
+ return (0);
+}
+
+
+/* *****************************************************************************
+ * bsnmpwalk private functions.
+ */
+/* The default tree to walk. */
+static const struct asn_oid snmp_mibII_OID = {
+ 6 , { 1, 3, 6, 1, 2, 1 }
+};
+
+static int32_t
+snmpwalk_add_default(struct snmp_toolinfo *snmptoolctx __unused,
+ struct snmp_object *obj, char *string __unused)
+{
+ asn_append_oid(&(obj->val.var), &snmp_mibII_OID);
+ return (1);
+}
+
+/*
+ * Prepare the next GetNext/Get PDU to send.
+ */
+static void
+snmpwalk_nextpdu_create(uint32_t op, struct asn_oid *var, struct snmp_pdu *pdu)
+{
+ snmp_pdu_create(pdu, op);
+ asn_append_oid(&(pdu->bindings[0].var), var);
+ pdu->nbindings = 1;
+}
+
+static int
+snmptool_walk(struct snmp_toolinfo *snmptoolctx)
+{
+ struct snmp_pdu req, resp;
+ struct asn_oid root; /* Keep the inital oid. */
+ int32_t outputs, rc;
+
+ snmp_pdu_create(&req, SNMP_PDU_GETNEXT);
+
+ while ((rc = snmp_pdu_add_bindings(snmptoolctx, NULL,
+ snmptool_add_vbind, &req, 1)) > 0) {
+
+ /* Remember the root where the walk started from. */
+ memset(&root, 0, sizeof(struct asn_oid));
+ asn_append_oid(&root, &(req.bindings[0].var));
+
+ outputs = 0;
+ while (snmp_dialog(&req, &resp) >= 0) {
+ if ((snmp_parse_resp(&resp, &req)) < 0) {
+ snmp_output_err_resp(snmptoolctx, &resp);
+ snmp_pdu_free(&resp);
+ outputs = -1;
+ break;
+ }
+
+ if (!(asn_is_suboid(&root, &(resp.bindings[0].var)))) {
+ snmp_pdu_free(&resp);
+ break;
+ }
+
+ if (snmp_output_resp(snmptoolctx, &resp)!= 0) {
+ snmp_pdu_free(&resp);
+ outputs = -1;
+ break;
+ }
+ outputs++;
+ snmp_pdu_free(&resp);
+
+ snmpwalk_nextpdu_create(SNMP_PDU_GETNEXT,
+ &(resp.bindings[0].var), &req);
+ }
+
+ /* Just in case our root was a leaf. */
+ if (outputs == 0) {
+ snmpwalk_nextpdu_create(SNMP_PDU_GET, &root, &req);
+ if (snmp_dialog(&req, &resp) == SNMP_CODE_OK) {
+ if (snmp_parse_resp(&resp,&req) < 0)
+ snmp_output_err_resp(snmptoolctx, &resp);
+ else
+ snmp_output_resp(snmptoolctx, &(resp));
+
+ snmp_pdu_free(&resp);
+ } else
+ warnx("Snmp dialog - %s", strerror(errno));
+ }
+
+ if (snmp_object_remove(snmptoolctx, &root) < 0) {
+ warnx("snmp_object_remove");
+ break;
+ }
+
+ snmp_pdu_create(&req, SNMP_PDU_GETNEXT);
+ }
+
+ if (rc == 0)
+ return (0);
+ else
+ return (1);
+}
+
+/* *****************************************************************************
+ * bsnmpset private functions.
+ */
+
+static int32_t
+parse_oid_numeric(struct snmp_value *value, char *val)
+{
+ char *endptr;
+ int32_t saved_errno;
+ asn_subid_t suboid;
+
+ do {
+ saved_errno = errno;
+ errno = 0;
+ suboid = strtoul(val, &endptr, 10);
+ if (errno != 0) {
+ warnx("Value %s not supported - %s", val,
+ strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+ errno = saved_errno;
+ if ((asn_subid_t) suboid > ASN_MAXID) {
+ warnx("Suboid %u > ASN_MAXID", suboid);
+ return (-1);
+ }
+ if (snmp_suboid_append(&(value->v.oid), suboid) < 0)
+ return (-1);
+ val = endptr + 1;
+ } while (*endptr == '.');
+
+ if (*endptr != '\0')
+ warnx("OID value %s not supported", val);
+
+ value->syntax = SNMP_SYNTAX_OID;
+ return (0);
+}
+
+/*
+ * Allow OID leaf in both forms:
+ * 1) 1.3.6.1.2... -> in such case call directly the function reading raw OIDs;
+ * 2) begemotSnmpdAgentFreeBSD -> lookup the ASN OID corresponding to that.
+ */
+static int32_t
+parse_oid_string(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_value *value, char *string)
+{
+ struct snmp_object obj;
+
+ if (isdigit(string[0]))
+ return (parse_oid_numeric(value, string));
+
+ memset(&obj, 0, sizeof(struct snmp_object));
+ if (snmp_lookup_enumoid(snmptoolctx, &obj, string) < 0) {
+ warnx("Unknown OID enum string - %s", string);
+ return (-1);
+ }
+
+ asn_append_oid(&(value->v.oid), &(obj.val.var));
+ return (1);
+}
+
+static int32_t
+parse_ip(struct snmp_value * value, char * val)
+{
+ uint32_t v;
+ int32_t i;
+ char *endptr, *str;
+
+ str = val;
+ for (i = 0; i < 4; i++) {
+ v = strtoul(str, &endptr, 10);
+ if (v > 0xff)
+ return (-1);
+ if (*endptr != '.' && *endptr != '\0' && i != 3)
+ break;
+ str = endptr + 1;
+ value->v.ipaddress[i] = (uint8_t) v;
+ }
+
+ value->syntax = SNMP_SYNTAX_IPADDRESS;
+ return (0);
+}
+
+static int32_t
+parse_int(struct snmp_value *value, char *val)
+{
+ char *endptr;
+ int32_t v, saved_errno;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtol(val, &endptr, 10);
+
+ if (errno != 0) {
+ warnx("Value %s not supported - %s", val, strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ value->syntax = SNMP_SYNTAX_INTEGER;
+ value->v.integer = v;
+ errno = saved_errno;
+
+ return (0);
+}
+
+static int32_t
+parse_int_string(struct snmp_object *object, char *val)
+{
+ int32_t v;
+
+ if (isdigit(val[0]))
+ return ((parse_int(&(object->val), val)));
+
+ if (object->info == NULL) {
+ warnx("Unknown enumerated integer type - %s", val);
+ return (-1);
+ }
+ if ((v = enum_number_lookup(object->info->snmp_enum, val)) < 0)
+ warnx("Unknown enumerated integer type - %s", val);
+
+ object->val.v.integer = v;
+ return (1);
+}
+
+/*
+ * Here syntax may be one of SNMP_SYNTAX_COUNTER, SNMP_SYNTAX_GAUGE,
+ * SNMP_SYNTAX_TIMETICKS.
+ */
+static int32_t
+parse_uint(struct snmp_value *value, char *val)
+{
+ char *endptr;
+ uint32_t v = 0;
+ int32_t saved_errno;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoul(val, &endptr, 10);
+
+ if (errno != 0) {
+ warnx("Value %s not supported - %s", val, strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ value->v.uint32 = v;
+ errno = saved_errno;
+
+ return (0);
+}
+
+static int32_t
+parse_ticks(struct snmp_value *value, char *val)
+{
+ if (parse_uint(value, val) < 0)
+ return (-1);
+
+ value->syntax = SNMP_SYNTAX_TIMETICKS;
+ return (0);
+}
+
+static int32_t
+parse_gauge(struct snmp_value *value, char *val)
+{
+ if (parse_uint(value, val) < 0)
+ return (-1);
+
+ value->syntax = SNMP_SYNTAX_GAUGE;
+ return (0);
+}
+
+static int32_t
+parse_counter(struct snmp_value *value, char *val)
+{
+ if (parse_uint(value, val) < 0)
+ return (-1);
+
+ value->syntax = SNMP_SYNTAX_COUNTER;
+ return (0);
+}
+
+static int32_t
+parse_uint64(struct snmp_value *value, char *val)
+{
+ char *endptr;
+ int32_t saved_errno;
+ uint64_t v;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoull(val, &endptr, 10);
+
+ if (errno != 0) {
+ warnx("Value %s not supported - %s", val, strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ value->syntax = SNMP_SYNTAX_COUNTER64;
+ value->v.counter64 = v;
+ errno = saved_errno;
+
+ return (0);
+}
+
+static int32_t
+parse_syntax_val(struct snmp_value *value, enum snmp_syntax syntax, char *val)
+{
+ switch (syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ return (parse_int(value, val));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (parse_ip(value, val));
+ case SNMP_SYNTAX_COUNTER:
+ return (parse_counter(value, val));
+ case SNMP_SYNTAX_GAUGE:
+ return (parse_gauge(value, val));
+ case SNMP_SYNTAX_TIMETICKS:
+ return (parse_ticks(value, val));
+ case SNMP_SYNTAX_COUNTER64:
+ return (parse_uint64(value, val));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_tc2oct(SNMP_STRING, value, val));
+ case SNMP_SYNTAX_OID:
+ return (parse_oid_numeric(value, val));
+ default:
+ /* NOTREACHED */
+ break;
+ }
+
+ return (-1);
+}
+
+/*
+ * Parse a command line argument of type OID=syntax:value and fill in whatever
+ * fields can be derived from the input into snmp_value structure. Reads numeric
+ * OIDs.
+ */
+static int32_t
+parse_pair_numoid_val(char *str, struct snmp_value *snmp_val)
+{
+ int32_t cnt;
+ char *ptr;
+ enum snmp_syntax syntax;
+ char oid_str[ASN_OIDSTRLEN];
+
+ ptr = str;
+ for (cnt = 0; cnt < ASN_OIDSTRLEN; cnt++)
+ if (ptr[cnt] == '=')
+ break;
+
+ if (cnt >= ASN_OIDSTRLEN) {
+ warnx("OID too long - %s", str);
+ return (-1);
+ }
+ strlcpy(oid_str, ptr, (size_t) (cnt + 1));
+
+ ptr = str + cnt + 1;
+ for (cnt = 0; cnt < MAX_CMD_SYNTAX_LEN; cnt++)
+ if(ptr[cnt] == ':')
+ break;
+
+ if (cnt >= MAX_CMD_SYNTAX_LEN) {
+ warnx("Unknown syntax in OID - %s", str);
+ return (-1);
+ }
+
+ if ((syntax = parse_syntax(ptr)) <= SNMP_SYNTAX_NULL) {
+ warnx("Unknown syntax in OID - %s", ptr);
+ return (-1);
+ }
+
+ ptr = ptr + cnt + 1;
+ for (cnt = 0; cnt < MAX_OCTSTRING_LEN; cnt++)
+ if (ptr[cnt] == '\0')
+ break;
+
+ if (ptr[cnt] != '\0') {
+ warnx("Value string too long - %s",ptr);
+ return (-1);
+ }
+
+ /*
+ * Here try parsing the OIDs and syntaxes and then check values - have
+ * to know syntax to check value boundaries.
+ */
+ if (snmp_parse_numoid(oid_str, &(snmp_val->var)) < 0) {
+ warnx("Error parsing OID %s",oid_str);
+ return (-1);
+ }
+
+ if (parse_syntax_val(snmp_val, syntax, ptr) < 0)
+ return (-1);
+
+ return (1);
+}
+
+/* XXX-BZ aruments should be swapped. */
+static int32_t
+parse_syntax_strval(struct snmp_toolinfo *snmptoolctx, char *str,
+ struct snmp_object *object)
+{
+ uint32_t len;
+ enum snmp_syntax syn;
+
+ /*
+ * Syntax string here not required - still may be present.
+ */
+
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) {
+ for (len = 0 ; *(str + len) != ':'; len++) {
+ if (*(str + len) == '\0') {
+ warnx("Syntax missing in value - %s", str);
+ return (-1);
+ }
+ }
+ if ((syn = parse_syntax(str)) <= SNMP_SYNTAX_NULL) {
+ warnx("Unknown syntax in - %s", str);
+ return (-1);
+ }
+ if (syn != object->val.syntax) {
+ if (!ISSET_ERRIGNORE(snmptoolctx)) {
+ warnx("Bad syntax in - %s", str);
+ return (-1);
+ } else
+ object->val.syntax = syn;
+ }
+ len++;
+ } else
+ len = 0;
+
+ switch (object->val.syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ return (parse_int_string(object, str + len));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (parse_ip(&(object->val), str + len));
+ case SNMP_SYNTAX_COUNTER:
+ return (parse_counter(&(object->val), str + len));
+ case SNMP_SYNTAX_GAUGE:
+ return (parse_gauge(&(object->val), str + len));
+ case SNMP_SYNTAX_TIMETICKS:
+ return (parse_ticks(&(object->val), str + len));
+ case SNMP_SYNTAX_COUNTER64:
+ return (parse_uint64(&(object->val), str + len));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_tc2oct(object->info->tc, &(object->val),
+ str + len));
+ case SNMP_SYNTAX_OID:
+ return (parse_oid_string(snmptoolctx, &(object->val),
+ str + len));
+ default:
+ /* NOTREACHED */
+ break;
+ }
+
+ return (-1);
+}
+
+static int32_t
+parse_pair_stroid_val(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_object *obj, char *argv)
+{
+ char *ptr;
+
+ if ((ptr = snmptools_parse_stroid(snmptoolctx, obj, argv)) == NULL)
+ return (-1);
+
+ if (*ptr != '=') {
+ warnx("Value to set expected after OID");
+ return (-1);
+ }
+
+ if (parse_syntax_strval(snmptoolctx, ptr + 1, obj) < 0)
+ return (-1);
+
+ return (1);
+}
+
+
+static int32_t
+snmpset_parse_oid(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_object *obj, char *argv)
+{
+ if (argv == NULL)
+ return (-1);
+
+ if (ISSET_NUMERIC(snmptoolctx)) {
+ if (parse_pair_numoid_val(argv, &(obj->val)) < 0)
+ return (-1);
+ } else {
+ if (parse_pair_stroid_val(snmptoolctx, obj, argv) < 0)
+ return (-1);
+ }
+
+ return (1);
+}
+
+static int32_t
+add_ip_syntax(struct snmp_value *dst, struct snmp_value *src)
+{
+ int8_t i;
+
+ dst->syntax = SNMP_SYNTAX_IPADDRESS;
+ for (i = 0; i < 4; i++)
+ dst->v.ipaddress[i] = src->v.ipaddress[i];
+
+ return (1);
+}
+
+static int32_t
+add_octstring_syntax(struct snmp_value *dst, struct snmp_value *src)
+{
+ if (src->v.octetstring.len > ASN_MAXOCTETSTRING) {
+ warnx("OctetString len too big - %u",src->v.octetstring.len);
+ return (-1);
+ }
+
+ if ((dst->v.octetstring.octets = malloc(src->v.octetstring.len)) ==
+ NULL) {
+ syslog(LOG_ERR, "malloc() failed - %s", strerror(errno));
+ return (-1);
+ }
+
+ memcpy(dst->v.octetstring.octets, src->v.octetstring.octets,
+ src->v.octetstring.len);
+ dst->syntax = SNMP_SYNTAX_OCTETSTRING;
+ dst->v.octetstring.len = src->v.octetstring.len;
+
+ return(0);
+}
+
+static int32_t
+add_oid_syntax(struct snmp_value *dst, struct snmp_value *src)
+{
+ asn_append_oid(&(dst->v.oid), &(src->v.oid));
+ dst->syntax = SNMP_SYNTAX_OID;
+ return (0);
+}
+
+/*
+ * Check syntax - if one of SNMP_SYNTAX_NULL, SNMP_SYNTAX_NOSUCHOBJECT,
+ * SNMP_SYNTAX_NOSUCHINSTANCE, SNMP_SYNTAX_ENDOFMIBVIEW or anything not known -
+ * return error.
+ */
+static int32_t
+snmpset_add_value(struct snmp_value *dst, struct snmp_value *src)
+{
+ if (dst == NULL || src == NULL)
+ return (-1);
+
+ switch (src->syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ dst->v.integer = src->v.integer;
+ dst->syntax = SNMP_SYNTAX_INTEGER;
+ break;
+ case SNMP_SYNTAX_TIMETICKS:
+ dst->v.uint32 = src->v.uint32;
+ dst->syntax = SNMP_SYNTAX_TIMETICKS;
+ break;
+ case SNMP_SYNTAX_GAUGE:
+ dst->v.uint32 = src->v.uint32;
+ dst->syntax = SNMP_SYNTAX_GAUGE;
+ break;
+ case SNMP_SYNTAX_COUNTER:
+ dst->v.uint32 = src->v.uint32;
+ dst->syntax = SNMP_SYNTAX_COUNTER;
+ break;
+ case SNMP_SYNTAX_COUNTER64:
+ dst->v.counter64 = src->v.counter64;
+ dst->syntax = SNMP_SYNTAX_COUNTER64;
+ break;
+ case SNMP_SYNTAX_IPADDRESS:
+ add_ip_syntax(dst, src);
+ break;
+ case SNMP_SYNTAX_OCTETSTRING:
+ add_octstring_syntax(dst, src);
+ break;
+ case SNMP_SYNTAX_OID:
+ add_oid_syntax(dst, src);
+ break;
+ default:
+ warnx("Unknown syntax %d", src->syntax);
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int32_t
+snmpset_verify_vbind(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu,
+ struct snmp_object *obj)
+{
+ if (pdu->version == SNMP_V1 && obj->val.syntax ==
+ SNMP_SYNTAX_COUNTER64) {
+ warnx("64-bit counters are not supported in SNMPv1 PDU");
+ return (-1);
+ }
+
+ if (ISSET_NUMERIC(snmptoolctx) || ISSET_ERRIGNORE(snmptoolctx))
+ return (1);
+
+ if (obj->info->access < SNMP_ACCESS_SET) {
+ warnx("Object %s not accessible for set - try 'bsnmpset -a'",
+ obj->info->string);
+ return (-1);
+ }
+
+ return (1);
+}
+
+static int32_t
+snmpset_add_vbind(struct snmp_pdu *pdu, struct snmp_object *obj)
+{
+ if (pdu->nbindings > SNMP_MAX_BINDINGS) {
+ warnx("Too many OIDs for one PDU");
+ return (-1);
+ }
+
+ if (obj->error > 0)
+ return (0);
+
+ if (snmpset_add_value(&(pdu->bindings[pdu->nbindings]), &(obj->val))
+ < 0)
+ return (-1);
+
+ asn_append_oid(&(pdu->bindings[pdu->nbindings].var), &(obj->val.var));
+ pdu->nbindings++;
+
+ return (pdu->nbindings);
+}
+
+static int
+snmptool_set(struct snmp_toolinfo *snmptoolctx)
+{
+ struct snmp_pdu req, resp;
+
+ snmp_pdu_create(&req, SNMP_PDU_SET);
+
+ while ((snmp_pdu_add_bindings(snmptoolctx, snmpset_verify_vbind,
+ snmpset_add_vbind, &req, SNMP_MAX_BINDINGS)) > 0) {
+ if (snmp_dialog(&req, &resp)) {
+ warnx("Snmp dialog - %s", strerror(errno));
+ break;
+ }
+
+ if (snmp_pdu_check(&req, &resp) > 0) {
+ if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET)
+ snmp_output_resp(snmptoolctx, &resp);
+ break;
+ }
+
+ snmp_output_err_resp(snmptoolctx, &resp);
+ if (!ISSET_RETRY(snmptoolctx))
+ break;
+
+ if (snmp_object_seterror(snmptoolctx,
+ &(resp.bindings[resp.error_index - 1]),
+ resp.error_status) <= 0)
+ break;
+
+ fprintf(stderr, "Retrying...\n");
+ snmp_pdu_free(&req);
+ snmp_pdu_free(&resp);
+ snmp_pdu_create(&req, SNMP_PDU_SET);
+ }
+
+ snmp_pdu_free(&resp);
+
+ return (0);
+}
+
+/* *****************************************************************************
+ * main
+ */
+/*
+ * According to command line options prepare SNMP Get | GetNext | GetBulk PDU.
+ * Wait for a responce and print it.
+ */
+/*
+ * Do a 'snmp walk' - according to command line options request for values
+ * lexicographically subsequent and subrooted at a common node. Send a GetNext
+ * PDU requesting the value for each next variable and print the responce. Stop
+ * when a Responce PDU is received that contains the value of a variable not
+ * subrooted at the variable the walk started.
+ */
+int
+main(int argc, char ** argv)
+{
+ struct snmp_toolinfo snmptoolctx;
+ int32_t oid_cnt, last_oid, opt_num;
+ int rc = 0;
+
+ /* Make sure program_name is set and valid. */
+ if (*argv == NULL)
+ program_name = "snmptool";
+ else {
+ program_name = strrchr(*argv, '/');
+ if (program_name != NULL)
+ program_name++;
+ else
+ program_name = *argv;
+ }
+
+ if (program_name == NULL) {
+ fprintf(stderr, "Error: No program name?\n");
+ exit (1);
+ } else if (strcmp(program_name, "bsnmpget") == 0)
+ program = BSNMPGET;
+ else if (strcmp(program_name, "bsnmpwalk") == 0)
+ program = BSNMPWALK;
+ else if (strcmp(program_name, "bsnmpset") == 0)
+ program = BSNMPSET;
+ else {
+ fprintf(stderr, "Unknown snmp tool name '%s'.\n", program_name);
+ exit (1);
+ }
+
+ /* Initialize. */
+ if (snmptool_init(&snmptoolctx) < 0)
+ exit (1);
+
+ if ((opt_num = snmptool_parse_options(&snmptoolctx, argc, argv)) < 0) {
+ snmp_tool_freeall(&snmptoolctx);
+ /* On -h (help) exit without error. */
+ if (opt_num == -2)
+ exit(0);
+ else
+ exit(1);
+ }
+
+ oid_cnt = argc - opt_num - 1;
+ if (oid_cnt == 0) {
+ switch (program) {
+ case BSNMPGET:
+ if (!ISSET_EDISCOVER(&snmptoolctx) &&
+ !ISSET_LOCALKEY(&snmptoolctx)) {
+ fprintf(stderr, "No OID given.\n");
+ usage();
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+ break;
+
+ case BSNMPWALK:
+ if (snmp_object_add(&snmptoolctx, snmpwalk_add_default,
+ NULL) < 0) {
+ fprintf(stderr,
+ "Error setting default subtree.\n");
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+ break;
+
+ case BSNMPSET:
+ fprintf(stderr, "No OID given.\n");
+ usage();
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+ }
+
+ if (snmp_import_all(&snmptoolctx) < 0) {
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+
+ /* A simple sanity check - can not send GETBULK when using SNMPv1. */
+ if (program == BSNMPGET && snmp_client.version == SNMP_V1 &&
+ GET_PDUTYPE(&snmptoolctx) == SNMP_PDU_GETBULK) {
+ fprintf(stderr, "Cannot send GETBULK PDU with SNMPv1.\n");
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+
+ for (last_oid = argc - 1; oid_cnt > 0; last_oid--, oid_cnt--) {
+ if ((snmp_object_add(&snmptoolctx, (program == BSNMPSET) ?
+ snmpset_parse_oid : snmptools_parse_oid,
+ argv[last_oid])) < 0) {
+ fprintf(stderr, "Error parsing OID string '%s'.\n",
+ argv[last_oid]);
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+ }
+
+ if (snmp_open(NULL, NULL, NULL, NULL)) {
+ warnx("Failed to open snmp session: %s.", strerror(errno));
+ snmp_tool_freeall(&snmptoolctx);
+ exit(1);
+ }
+
+ if (snmp_client.version == SNMP_V3 && snmp_client.engine.engine_len == 0)
+ SET_EDISCOVER(&snmptoolctx);
+
+ if (ISSET_EDISCOVER(&snmptoolctx) &&
+ snmp_discover_engine(snmptoolctx.passwd) < 0) {
+ warnx("Unknown SNMP Engine ID: %s.", strerror(errno));
+ rc = 1;
+ goto cleanup;
+ }
+
+ if (GET_OUTPUT(&snmptoolctx) == OUTPUT_VERBOSE ||
+ ISSET_EDISCOVER(&snmptoolctx))
+ snmp_output_engine();
+
+ if (snmp_client.version == SNMP_V3 && ISSET_LOCALKEY(&snmptoolctx) &&
+ !ISSET_EDISCOVER(&snmptoolctx)) {
+ if (snmp_passwd_to_keys(&snmp_client.user,
+ snmptoolctx.passwd) != SNMP_CODE_OK ||
+ snmp_get_local_keys(&snmp_client.user,
+ snmp_client.engine.engine_id,
+ snmp_client.engine.engine_len) != SNMP_CODE_OK) {
+ warnx("Failed to get keys: %s.", strerror(errno));
+ rc = 1;
+ goto cleanup;
+ }
+ }
+
+ if (GET_OUTPUT(&snmptoolctx) == OUTPUT_VERBOSE ||
+ ISSET_EDISCOVER(&snmptoolctx))
+ snmp_output_keys();
+
+ if (ISSET_EDISCOVER(&snmptoolctx) && snmptoolctx.objects == 0)
+ goto cleanup;
+
+ switch (program) {
+ case BSNMPGET:
+ rc = snmptool_get(&snmptoolctx);
+ break;
+ case BSNMPWALK:
+ rc = snmptool_walk(&snmptoolctx);
+ break;
+ case BSNMPSET:
+ rc = snmptool_set(&snmptoolctx);
+ break;
+ }
+
+
+cleanup:
+ snmp_tool_freeall(&snmptoolctx);
+ snmp_close();
+
+ exit(rc);
+}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/Makefile b/usr.sbin/bsnmpd/tools/libbsnmptools/Makefile
new file mode 100644
index 0000000..f2b71b6
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/Makefile
@@ -0,0 +1,14 @@
+#
+# $FreeBSD$
+#
+
+.PATH: ${.CURDIR}
+
+LIB= bsnmptools
+#INTERNALLIB=
+SRCS= bsnmpimport.c bsnmpmap.c bsnmptools.c bsnmptc.c
+CFLAGS+= -g -Wall -Werror
+
+SHLIB_MAJOR= 0
+
+.include <bsd.lib.mk>
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpimport.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpimport.c
new file mode 100644
index 0000000..b92532f
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpimport.c
@@ -0,0 +1,971 @@
+/*-
+ * Copyright (c) 2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation and use in source and
+ * binary forms, with or without modification, are permitted provided that
+ * the following conditions are met:
+ *
+ * 1. Redistributions of source code or documentation must retain the above
+ * copyright notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Read file containing table description - reuse magic from gensnmptree.c.
+ * Hopefully one day most of the code here will be part of libbsnmp and
+ * this duplication won't be necessary.
+ *
+ * Syntax is:
+ * ---------
+ * file := top | top file
+ *
+ * top := tree | typedef | include
+ *
+ * tree := head elements ')'
+ *
+ * entry := head ':' index STRING elements ')'
+ *
+ * leaf := head type STRING ACCESS ')'
+ *
+ * column := head type ACCESS ')'
+ *
+ * type := BASETYPE | BASETYPE '|' subtype | enum | bits
+ *
+ * subtype := STRING
+ *
+ * enum := ENUM '(' value ')'
+ *
+ * bits := BITS '(' value ')'
+ *
+ * value := INT STRING | INT STRING value
+ *
+ * head := '(' INT STRING
+ *
+ * elements := EMPTY | elements element
+ *
+ * element := tree | leaf | column
+ *
+ * index := type | index type
+ *
+ * typedef := 'typedef' STRING type
+ *
+ * include := 'include' filespec
+ *
+ * filespec := '"' STRING '"' | '<' STRING '>'
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/uio.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+#include <bsnmp/snmpagent.h> /* SNMP_INDEXES_MAX */
+#include "bsnmptc.h"
+#include "bsnmptools.h"
+
+enum snmp_tbl_entry {
+ ENTRY_NONE = 0,
+ ENTRY_INDEX,
+ ENTRY_DATA
+};
+
+enum {
+ FL_GET = 0x01,
+ FL_SET = 0x02,
+};
+
+/************************************************************
+ *
+ * Allocate memory and panic just in the case...
+ */
+static void *
+xalloc(size_t size)
+{
+ void *ptr;
+
+ if ((ptr = malloc(size)) == NULL)
+ err(1, "allocing %zu bytes", size);
+
+ return (ptr);
+}
+
+static char *
+savestr(const char *s)
+{
+ if (s == NULL)
+ return (NULL);
+
+ return (strcpy(xalloc(strlen(s) + 1), s));
+}
+
+/************************************************************
+ *
+ * Input stack
+ */
+struct input {
+ FILE *fp;
+ uint32_t lno;
+ char *fname;
+ char *path;
+ LIST_ENTRY(input) link;
+};
+
+LIST_HEAD(, input) inputs = LIST_HEAD_INITIALIZER(inputs);
+struct input *input = NULL;
+int32_t pbchar = -1;
+
+#define MAX_PATHS 100
+
+static const char *paths[MAX_PATHS + 1] = {
+ "/usr/share/snmp/defs",
+ "/usr/local/share/snmp/defs",
+ NULL
+};
+
+static void
+input_new(FILE *fp, const char *path, const char *fname)
+{
+ struct input *ip;
+
+ ip = xalloc(sizeof(*ip));
+ ip->fp = fp;
+ ip->lno = 1;
+ ip->fname = savestr(fname);
+ ip->path = savestr(path);
+ LIST_INSERT_HEAD(&inputs, ip, link);
+
+ input = ip;
+}
+
+static void
+input_close(void)
+{
+ if (input == NULL)
+ return;
+
+ fclose(input->fp);
+ free(input->fname);
+ free(input->path);
+ LIST_REMOVE(input, link);
+ free(input);
+
+ input = LIST_FIRST(&inputs);
+}
+
+static FILE *
+tryopen(const char *path, const char *fname)
+{
+ char *fn;
+ FILE *fp;
+
+ if (path == NULL)
+ fn = savestr(fname);
+ else {
+ fn = xalloc(strlen(path) + strlen(fname) + 2);
+ sprintf(fn, "%s/%s", path, fname);
+ }
+ fp = fopen(fn, "r");
+ free(fn);
+ return (fp);
+}
+
+static int32_t
+input_fopen(const char *fname)
+{
+ FILE *fp;
+ u_int p;
+
+ if (fname[0] == '/' || fname[0] == '.' || fname[0] == '~') {
+ if ((fp = tryopen(NULL, fname)) != NULL) {
+ input_new(fp, NULL, fname);
+ return (0);
+ }
+
+ } else {
+
+ for (p = 0; paths[p] != NULL; p++)
+ if ((fp = tryopen(paths[p], fname)) != NULL) {
+ input_new(fp, paths[p], fname);
+ return (0);
+ }
+ }
+
+ warnx("cannot open '%s'", fname);
+ return (-1);
+}
+
+static int32_t
+tgetc(void)
+{
+ int c;
+
+ if (pbchar != -1) {
+ c = pbchar;
+ pbchar = -1;
+ return (c);
+ }
+
+ for (;;) {
+ if (input == NULL)
+ return (EOF);
+
+ if ((c = getc(input->fp)) != EOF)
+ return (c);
+
+ input_close();
+ }
+}
+
+static int32_t
+tungetc(int c)
+{
+
+ if (pbchar != -1)
+ return (-1);
+
+ pbchar = c;
+ return (1);
+}
+
+/************************************************************
+ *
+ * Parsing input
+ */
+enum tok {
+ TOK_EOF = 0200, /* end-of-file seen */
+ TOK_NUM, /* number */
+ TOK_STR, /* string */
+ TOK_ACCESS, /* access operator */
+ TOK_TYPE, /* type operator */
+ TOK_ENUM, /* enum token (kind of a type) */
+ TOK_TYPEDEF, /* typedef directive */
+ TOK_DEFTYPE, /* defined type */
+ TOK_INCLUDE, /* include directive */
+ TOK_FILENAME, /* filename ("foo.bar" or <foo.bar>) */
+ TOK_BITS, /* bits token (kind of a type) */
+ TOK_ERR /* unexpected char - exit */
+};
+
+static const struct {
+ const char *str;
+ enum tok tok;
+ uint32_t val;
+} keywords[] = {
+ { "GET", TOK_ACCESS, FL_GET },
+ { "SET", TOK_ACCESS, FL_SET },
+ { "NULL", TOK_TYPE, SNMP_SYNTAX_NULL },
+ { "INTEGER", TOK_TYPE, SNMP_SYNTAX_INTEGER },
+ { "INTEGER32", TOK_TYPE, SNMP_SYNTAX_INTEGER },
+ { "UNSIGNED32", TOK_TYPE, SNMP_SYNTAX_GAUGE },
+ { "OCTETSTRING", TOK_TYPE, SNMP_SYNTAX_OCTETSTRING },
+ { "IPADDRESS", TOK_TYPE, SNMP_SYNTAX_IPADDRESS },
+ { "OID", TOK_TYPE, SNMP_SYNTAX_OID },
+ { "TIMETICKS", TOK_TYPE, SNMP_SYNTAX_TIMETICKS },
+ { "COUNTER", TOK_TYPE, SNMP_SYNTAX_COUNTER },
+ { "GAUGE", TOK_TYPE, SNMP_SYNTAX_GAUGE },
+ { "COUNTER64", TOK_TYPE, SNMP_SYNTAX_COUNTER64 },
+ { "ENUM", TOK_ENUM, SNMP_SYNTAX_INTEGER },
+ { "BITS", TOK_BITS, SNMP_SYNTAX_OCTETSTRING },
+ { "typedef", TOK_TYPEDEF, 0 },
+ { "include", TOK_INCLUDE, 0 },
+ { NULL, 0, 0 }
+};
+
+struct {
+ /* Current OID type, regarding table membership. */
+ enum snmp_tbl_entry tbl_type;
+ /* A pointer to a structure in table list to add to its members. */
+ struct snmp_index_entry *table_idx;
+} table_data;
+
+struct asn_oid current_oid;
+char nexttok[MAXSTR];
+u_long val; /* integer values */
+int32_t all_cond; /* all conditions are true */
+int32_t saved_token = -1;
+
+/* Prepare the global data before parsing a new file. */
+static void
+snmp_import_init(struct asn_oid *append)
+{
+ memset(&table_data, 0, sizeof(table_data));
+ memset(&current_oid, 0, sizeof(struct asn_oid));
+ memset(nexttok, 0, MAXSTR);
+
+ if (append != NULL)
+ asn_append_oid(&current_oid, append);
+
+ all_cond = 0;
+ val = 0;
+ saved_token = -1;
+}
+
+static int32_t
+gettoken(struct snmp_toolinfo *snmptoolctx)
+{
+ int c;
+ struct enum_type *t;
+
+ if (saved_token != -1) {
+ c = saved_token;
+ saved_token = -1;
+ return (c);
+ }
+
+ again:
+ /*
+ * Skip any whitespace before the next token.
+ */
+ while ((c = tgetc()) != EOF) {
+ if (c == '\n')
+ input->lno++;
+ if (!isspace(c))
+ break;
+ }
+ if (c == EOF)
+ return (TOK_EOF);
+
+ if (!isascii(c)) {
+ warnx("unexpected character %#2x", (u_int) c);
+ return (TOK_ERR);
+ }
+
+ /*
+ * Skip comments.
+ */
+ if (c == '#') {
+ while ((c = tgetc()) != EOF) {
+ if (c == '\n') {
+ input->lno++;
+ goto again;
+ }
+ }
+ warnx("unexpected EOF in comment");
+ return (TOK_ERR);
+ }
+
+ /*
+ * Single character tokens.
+ */
+ if (strchr("():|", c) != NULL)
+ return (c);
+
+ if (c == '"' || c == '<') {
+ int32_t end = c;
+ size_t n = 0;
+
+ val = 1;
+ if (c == '<') {
+ val = 0;
+ end = '>';
+ }
+
+ while ((c = tgetc()) != EOF) {
+ if (c == end)
+ break;
+ if (n == sizeof(nexttok) - 1) {
+ nexttok[n++] = '\0';
+ warnx("filename too long '%s...'", nexttok);
+ return (TOK_ERR);
+ }
+ nexttok[n++] = c;
+ }
+ nexttok[n++] = '\0';
+ return (TOK_FILENAME);
+ }
+
+ /*
+ * Sort out numbers.
+ */
+ if (isdigit(c)) {
+ size_t n = 0;
+ nexttok[n++] = c;
+ while ((c = tgetc()) != EOF) {
+ if (!isdigit(c)) {
+ if (tungetc(c) < 0)
+ return (TOK_ERR);
+ break;
+ }
+ if (n == sizeof(nexttok) - 1) {
+ nexttok[n++] = '\0';
+ warnx("number too long '%s...'", nexttok);
+ return (TOK_ERR);
+ }
+ nexttok[n++] = c;
+ }
+ nexttok[n++] = '\0';
+ sscanf(nexttok, "%lu", &val);
+ return (TOK_NUM);
+ }
+
+ /*
+ * So that has to be a string.
+ */
+ if (isalpha(c) || c == '_' || c == '-') {
+ size_t n = 0;
+ nexttok[n++] = c;
+ while ((c = tgetc()) != EOF) {
+ if (!isalnum(c) && c != '_' && c != '-') {
+ if (tungetc (c) < 0)
+ return (TOK_ERR);
+ break;
+ }
+ if (n == sizeof(nexttok) - 1) {
+ nexttok[n++] = '\0';
+ warnx("string too long '%s...'", nexttok);
+ return (TOK_ERR);
+ }
+ nexttok[n++] = c;
+ }
+ nexttok[n++] = '\0';
+
+ /*
+ * Keywords.
+ */
+ for (c = 0; keywords[c].str != NULL; c++)
+ if (strcmp(keywords[c].str, nexttok) == 0) {
+ val = keywords[c].val;
+ return (keywords[c].tok);
+ }
+
+ if ((t = snmp_enumtc_lookup(snmptoolctx, nexttok)) != NULL) {
+ val = t->syntax;
+ return (TOK_DEFTYPE);
+ }
+
+ return (TOK_STR);
+ }
+
+ if (isprint(c))
+ warnx("%u: unexpected character '%c'", input->lno, c);
+ else
+ warnx("%u: unexpected character 0x%02x", input->lno, (u_int) c);
+
+ return (TOK_ERR);
+}
+
+/*
+ * Update table information.
+ */
+static struct snmp_index_entry *
+snmp_import_update_table(enum snmp_tbl_entry te, struct snmp_index_entry *tbl)
+{
+ switch (te) {
+ case ENTRY_NONE:
+ if (table_data.tbl_type == ENTRY_NONE)
+ return (NULL);
+ if (table_data.tbl_type == ENTRY_INDEX)
+ table_data.table_idx = NULL;
+ table_data.tbl_type--;
+ return (NULL);
+
+ case ENTRY_INDEX:
+ if (tbl == NULL)
+ warnx("No table_index to add!!!");
+ table_data.table_idx = tbl;
+ table_data.tbl_type = ENTRY_INDEX;
+ return (tbl);
+
+ case ENTRY_DATA:
+ if (table_data.tbl_type == ENTRY_INDEX) {
+ table_data.tbl_type = ENTRY_DATA;
+ return (table_data.table_idx);
+ }
+ return (NULL);
+
+ default:
+ /* NOTREACHED */
+ warnx("Unknown table entry type!!!");
+ break;
+ }
+
+ return (NULL);
+}
+
+static int32_t
+parse_enum(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
+ struct enum_pairs *enums)
+{
+ while ((*tok = gettoken(snmptoolctx)) == TOK_STR) {
+ if (enum_pair_insert(enums, val, nexttok) < 0)
+ return (-1);
+ if ((*tok = gettoken(snmptoolctx)) != TOK_NUM)
+ break;
+ }
+
+ if (*tok != ')') {
+ warnx("')' at end of enums");
+ return (-1);
+ }
+
+ return (1);
+}
+
+static int32_t
+parse_subtype(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
+ enum snmp_tc *tc)
+{
+ if ((*tok = gettoken(snmptoolctx)) != TOK_STR) {
+ warnx("subtype expected after '|'");
+ return (-1);
+ }
+
+ *tc = snmp_get_tc(nexttok);
+ *tok = gettoken(snmptoolctx);
+
+ return (1);
+}
+
+static int32_t
+parse_type(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
+ enum snmp_tc *tc, struct enum_pairs **snmp_enum)
+{
+ int32_t syntax, mem;
+
+ syntax = val;
+ *tc = 0;
+
+ if (*tok == TOK_ENUM || *tok == TOK_BITS) {
+ if (*snmp_enum == NULL) {
+ if ((*snmp_enum = enum_pairs_init()) == NULL)
+ return (-1);
+ mem = 1;
+ *tc = SNMP_TC_OWN;
+ } else
+ mem = 0;
+
+ if (gettoken(snmptoolctx) != '(') {
+ warnx("'(' expected after ENUM/BITS");
+ return (-1);
+ }
+
+ if ((*tok = gettoken(snmptoolctx)) != TOK_NUM) {
+ warnx("need value for ENUM//BITS");
+ if (mem == 1) {
+ free(*snmp_enum);
+ *snmp_enum = NULL;
+ }
+ return (-1);
+ }
+
+ if (parse_enum(snmptoolctx, tok, *snmp_enum) < 0) {
+ enum_pairs_free(*snmp_enum);
+ *snmp_enum = NULL;
+ return (-1);
+ }
+
+ *tok = gettoken(snmptoolctx);
+
+ } else if (*tok == TOK_DEFTYPE) {
+ struct enum_type *t;
+
+ *tc = 0;
+ t = snmp_enumtc_lookup(snmptoolctx, nexttok);
+ if (t != NULL)
+ *snmp_enum = t->snmp_enum;
+
+ *tok = gettoken(snmptoolctx);
+
+ } else {
+ if ((*tok = gettoken(snmptoolctx)) == '|') {
+ if (parse_subtype(snmptoolctx, tok, tc) < 0)
+ return (-1);
+ }
+ }
+
+ return (syntax);
+}
+
+static int32_t
+snmp_import_head(struct snmp_toolinfo *snmptoolctx)
+{
+ enum tok tok;
+
+ if ((tok = gettoken(snmptoolctx)) == '(')
+ tok = gettoken(snmptoolctx);
+
+ if (tok != TOK_NUM || val > ASN_MAXID ) {
+ warnx("Suboid expected - line %d", input->lno);
+ return (-1);
+ }
+
+ if (gettoken(snmptoolctx) != TOK_STR) {
+ warnx("Node name expected at line %d", input->lno);
+ return (-1);
+ }
+
+ return (1);
+}
+
+static int32_t
+snmp_import_table(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *obj)
+{
+ int32_t i;
+ enum snmp_tc tc;
+ enum tok tok;
+ struct snmp_index_entry *entry;
+
+ if ((entry = malloc(sizeof(struct snmp_index_entry))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ memset(entry, 0, sizeof(struct snmp_index_entry));
+ STAILQ_INIT(&(entry->index_list));
+
+ for (i = 0, tok = gettoken(snmptoolctx); i < SNMP_INDEXES_MAX; i++) {
+ int32_t syntax;
+ struct enum_pairs *enums = NULL;
+
+ if (tok != TOK_TYPE && tok != TOK_DEFTYPE && tok != TOK_ENUM &&
+ tok != TOK_BITS)
+ break;
+
+ if ((syntax = parse_type(snmptoolctx, &tok, &tc, &enums)) < 0) {
+ enum_pairs_free(enums);
+ snmp_index_listfree(&(entry->index_list));
+ free(entry);
+ return (-1);
+ }
+
+ if (snmp_syntax_insert(&(entry->index_list), enums, syntax,
+ tc) < 0) {
+ snmp_index_listfree(&(entry->index_list));
+ enum_pairs_free(enums);
+ free(entry);
+ return (-1);
+ }
+ }
+
+ if (i == 0 || i > SNMP_INDEXES_MAX) {
+ warnx("Bad number of indexes at line %d", input->lno);
+ snmp_index_listfree(&(entry->index_list));
+ free(entry);
+ return (-1);
+ }
+
+ if (tok != TOK_STR) {
+ warnx("String expected after indexes at line %d", input->lno);
+ snmp_index_listfree(&(entry->index_list));
+ free(entry);
+ return (-1);
+ }
+
+ entry->string = obj->string;
+ entry->strlen = obj->strlen;
+ asn_append_oid(&(entry->var), &(obj->var));
+
+ if ((i = snmp_table_insert(snmptoolctx, entry)) < 0) {
+ snmp_index_listfree(&(entry->index_list));
+ free(entry);
+ return (-1);
+ } else if (i == 0) {
+ /* Same entry already present in lists. */
+ free(entry->string);
+ free(entry);
+ }
+
+ (void) snmp_import_update_table(ENTRY_INDEX, entry);
+
+ return (1);
+}
+
+/*
+ * Read everything after the syntax type that is certainly a leaf OID info.
+ */
+static int32_t
+snmp_import_leaf(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
+ struct snmp_oid2str *oid2str)
+{
+ int32_t i, syntax;
+
+ if ((syntax = parse_type(snmptoolctx, tok, &(oid2str->tc), &(oid2str->snmp_enum)))
+ < 0)
+ return(-1);
+
+ oid2str->syntax = syntax;
+ /*
+ * That is the name of the function, corresponding to the entry.
+ * It is used by bsnmpd, but is not interesting for us.
+ */
+ if (*tok == TOK_STR)
+ *tok = gettoken(snmptoolctx);
+
+ for (i = 0; i < SNMP_ACCESS_GETSET && *tok == TOK_ACCESS; i++) {
+ oid2str->access |= (uint32_t) val;
+ *tok = gettoken(snmptoolctx);
+ }
+
+ if (*tok != ')') {
+ warnx("')' expected at end of line %d", input->lno);
+ return (-1);
+ }
+
+ oid2str->table_idx = snmp_import_update_table(ENTRY_DATA, NULL);
+
+ if ((i = snmp_leaf_insert(snmptoolctx, oid2str)) < 0) {
+ warnx("Error adding leaf %s to list", oid2str->string);
+ return (-1);
+ }
+
+ /*
+ * Same entry is already present in the mapping lists and
+ * the new one was not inserted.
+ */
+ if (i == 0) {
+ free(oid2str->string);
+ free(oid2str);
+ }
+
+ (void) snmp_import_update_table(ENTRY_NONE, NULL);
+
+ return (1);
+}
+
+static int32_t
+snmp_import_object(struct snmp_toolinfo *snmptoolctx)
+{
+ char *string;
+ int i;
+ enum tok tok;
+ struct snmp_oid2str *oid2str;
+
+ if (snmp_import_head(snmptoolctx) < 0)
+ return (-1);
+
+ if ((oid2str = malloc(sizeof(struct snmp_oid2str))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ if ((string = malloc(strlen(nexttok) + 1)) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ free(oid2str);
+ return (-1);
+ }
+
+ memset(oid2str, 0, sizeof(struct snmp_oid2str));
+ strlcpy(string, nexttok, strlen(nexttok) + 1);
+ oid2str->string = string;
+ oid2str->strlen = strlen(nexttok);
+
+ asn_append_oid(&(oid2str->var), &(current_oid));
+ if (snmp_suboid_append(&(oid2str->var), (asn_subid_t) val) < 0)
+ goto error;
+
+ /*
+ * Prepared the entry - now figure out where to insert it.
+ * After the object we have following options:
+ * 1) new line, blank, ) - then it is an enum oid -> snmp_enumlist;
+ * 2) new line , ( - nonleaf oid -> snmp_nodelist;
+ * 2) ':' - table entry - a variable length SYNTAX_TYPE (one or more)
+ * may follow and second string must end line -> snmp_tablelist;
+ * 3) OID , string ) - this is a trap entry or a leaf -> snmp_oidlist;
+ * 4) SYNTAX_TYPE, string (not always), get/set modifier - always last
+ * and )- this is definitely a leaf.
+ */
+
+ switch (tok = gettoken(snmptoolctx)) {
+ case ')':
+ if ((i = snmp_enum_insert(snmptoolctx, oid2str)) < 0)
+ goto error;
+ if (i == 0) {
+ free(oid2str->string);
+ free(oid2str);
+ }
+ return (1);
+
+ case '(':
+ if (snmp_suboid_append(&current_oid, (asn_subid_t) val) < 0)
+ goto error;
+
+ /*
+ * Ignore the error for nodes since the .def files currently
+ * contain different strings for 1.3.6.1.2.1 - mibII. Only make
+ * sure the memory is freed and don't complain.
+ */
+ if ((i = snmp_node_insert(snmptoolctx, oid2str)) <= 0) {
+ free(string);
+ free(oid2str);
+ }
+ return (snmp_import_object(snmptoolctx));
+
+ case ':':
+ if (snmp_suboid_append(&current_oid, (asn_subid_t) val) < 0)
+ goto error;
+ if (snmp_import_table(snmptoolctx, oid2str) < 0)
+ goto error;
+ /*
+ * A different table entry type was malloced and the data is
+ * contained there.
+ */
+ free(oid2str);
+ return (1);
+
+ case TOK_TYPE:
+ /* FALLTHROUGH */
+ case TOK_DEFTYPE:
+ /* FALLTHROUGH */
+ case TOK_ENUM:
+ /* FALLTHROUGH */
+ case TOK_BITS:
+ if (snmp_import_leaf(snmptoolctx, &tok, oid2str) < 0)
+ goto error;
+ return (1);
+
+ default:
+ warnx("Unexpected token at line %d - %s", input->lno,
+ input->fname);
+ break;
+ }
+
+error:
+ snmp_mapping_entryfree(oid2str);
+
+ return (-1);
+}
+
+static int32_t
+snmp_import_tree(struct snmp_toolinfo *snmptoolctx, enum tok *tok)
+{
+ while (*tok != TOK_EOF) {
+ switch (*tok) {
+ case TOK_ERR:
+ return (-1);
+ case '(':
+ if (snmp_import_object(snmptoolctx) < 0)
+ return (-1);
+ break;
+ case ')':
+ if (snmp_suboid_pop(&current_oid) < 0)
+ return (-1);
+ (void) snmp_import_update_table(ENTRY_NONE, NULL);
+ break;
+ default:
+ /* Anything else here would be illegal. */
+ return (-1);
+ }
+ *tok = gettoken(snmptoolctx);
+ }
+
+ return (0);
+}
+
+static int32_t
+snmp_import_top(struct snmp_toolinfo *snmptoolctx, enum tok *tok)
+{
+ enum snmp_tc tc;
+ struct enum_type *t;
+
+ if (*tok == '(')
+ return (snmp_import_tree(snmptoolctx, tok));
+
+ if (*tok == TOK_TYPEDEF) {
+ if ((*tok = gettoken(snmptoolctx)) != TOK_STR) {
+ warnx("type name expected after typedef - %s",
+ input->fname);
+ return (-1);
+ }
+
+ t = snmp_enumtc_init(nexttok);
+
+ *tok = gettoken(snmptoolctx);
+ t->is_enum = (*tok == TOK_ENUM);
+ t->is_bits = (*tok == TOK_BITS);
+ t->syntax = parse_type(snmptoolctx, tok, &tc, &(t->snmp_enum));
+ snmp_enumtc_insert(snmptoolctx, t);
+
+ return (1);
+ }
+
+ if (*tok == TOK_INCLUDE) {
+ int i;
+
+ *tok = gettoken(snmptoolctx);
+ if (*tok != TOK_FILENAME) {
+ warnx("filename expected in include directive - %s",
+ nexttok);
+ return (-1);
+ }
+
+ if (( i = add_filename(snmptoolctx, nexttok, NULL, 1)) == 0) {
+ *tok = gettoken(snmptoolctx);
+ return (1);
+ }
+
+ if (i == -1)
+ return (-1);
+
+ input_fopen(nexttok);
+ *tok = gettoken(snmptoolctx);
+ return (1);
+ }
+
+ warnx("'(' or 'typedef' expected - %s", nexttok);
+ return (-1);
+}
+
+static int32_t
+snmp_import(struct snmp_toolinfo *snmptoolctx)
+{
+ int i;
+ enum tok tok;
+
+ tok = gettoken(snmptoolctx);
+
+ do
+ i = snmp_import_top(snmptoolctx, &tok);
+ while (i > 0);
+
+ return (i);
+}
+
+/*
+ * Read a .def file and import oid<->string mapping.
+ * Mappings are inserted into a global structure containing list for each OID
+ * syntax type.
+ */
+int32_t
+snmp_import_file(struct snmp_toolinfo *snmptoolctx, struct fname *file)
+{
+ int idx;
+
+ snmp_import_init(&(file->cut));
+ input_fopen(file->name);
+ if ((idx = snmp_import(snmptoolctx)) < 0)
+ warnx("Failed to read mappings from file %s", file->name);
+
+ input_close();
+
+ return (idx);
+}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c
new file mode 100644
index 0000000..a6d14a2
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmpmap.c
@@ -0,0 +1,1018 @@
+/*-
+ * Copyright (c) 2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation and use in source and
+ * binary forms, with or without modification, are permitted provided that
+ * the following conditions are met:
+ *
+ * 1. Redistributions of source code or documentation must retain the above
+ * copyright notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/uio.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+#include "bsnmptc.h"
+#include "bsnmptools.h"
+
+extern int _bsnmptools_debug;
+#define DEBUG if (_bsnmptools_debug) fprintf
+
+/* Allocate memory and initialize list. */
+struct snmp_mappings *
+snmp_mapping_init(void)
+{
+ struct snmp_mappings *m;
+
+ if ((m = malloc(sizeof(struct snmp_mappings))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (NULL);
+ }
+
+ memset(m, 0, sizeof(struct snmp_mappings));
+ return (m);
+}
+
+#define snmp_nodelist mappings->nodelist
+#define snmp_intlist mappings->intlist
+#define snmp_octlist mappings->octlist
+#define snmp_oidlist mappings->oidlist
+#define snmp_iplist mappings->iplist
+#define snmp_ticklist mappings->ticklist
+#define snmp_cntlist mappings->cntlist
+#define snmp_gaugelist mappings->gaugelist
+#define snmp_cnt64list mappings->cnt64list
+#define snmp_enumlist mappings->enumlist
+#define snmp_tablelist mappings->tablelist
+#define snmp_tclist mappings->tclist
+
+void
+enum_pairs_free(struct enum_pairs *headp)
+{
+ struct enum_pair *e;
+
+ if (headp == NULL)
+ return;
+
+ while ((e = STAILQ_FIRST(headp)) != NULL) {
+ STAILQ_REMOVE_HEAD(headp, link);
+
+ if (e->enum_str)
+ free(e->enum_str);
+ free(e);
+ }
+
+ free(headp);
+}
+
+void
+snmp_mapping_entryfree(struct snmp_oid2str *entry)
+{
+ if (entry->string)
+ free(entry->string);
+
+ if (entry->tc == SNMP_TC_OWN)
+ enum_pairs_free(entry->snmp_enum);
+
+ free(entry);
+}
+
+static void
+snmp_mapping_listfree(struct snmp_mapping *headp)
+{
+ struct snmp_oid2str *p;
+
+ while ((p = SLIST_FIRST(headp)) != NULL) {
+ SLIST_REMOVE_HEAD(headp, link);
+
+ if (p->string)
+ free(p->string);
+
+ if (p->tc == SNMP_TC_OWN)
+ enum_pairs_free(p->snmp_enum);
+ free(p);
+ }
+
+ SLIST_INIT(headp);
+}
+
+void
+snmp_index_listfree(struct snmp_idxlist *headp)
+{
+ struct index *i;
+
+ while ((i = STAILQ_FIRST(headp)) != NULL) {
+ STAILQ_REMOVE_HEAD(headp, link);
+ if (i->tc == SNMP_TC_OWN)
+ enum_pairs_free(i->snmp_enum);
+ free(i);
+ }
+
+ STAILQ_INIT(headp);
+}
+
+static void
+snmp_mapping_table_listfree(struct snmp_table_index *headp)
+{
+ struct snmp_index_entry *t;
+
+ while ((t = SLIST_FIRST(headp)) != NULL) {
+ SLIST_REMOVE_HEAD(headp, link);
+
+ if (t->string)
+ free(t->string);
+
+ snmp_index_listfree(&(t->index_list));
+ free(t);
+ }
+}
+
+static void
+snmp_enumtc_listfree(struct snmp_enum_tc *headp)
+{
+ struct enum_type *t;
+
+ while ((t = SLIST_FIRST(headp)) != NULL) {
+ SLIST_REMOVE_HEAD(headp, link);
+
+ if (t->name)
+ free(t->name);
+ enum_pairs_free(t->snmp_enum);
+ free(t);
+ }
+}
+
+int
+snmp_mapping_free(struct snmp_toolinfo *snmptoolctx)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
+ return (-1);
+
+ snmp_mapping_listfree(&snmptoolctx->snmp_nodelist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_intlist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_octlist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_oidlist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_iplist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_ticklist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_cntlist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_gaugelist);
+ snmp_mapping_listfree(&snmptoolctx->snmp_cnt64list);
+ snmp_mapping_listfree(&snmptoolctx->snmp_enumlist);
+ snmp_mapping_table_listfree(&snmptoolctx->snmp_tablelist);
+ snmp_enumtc_listfree(&snmptoolctx->snmp_tclist);
+ free(snmptoolctx->mappings);
+
+ return (0);
+}
+
+static void
+snmp_dump_enumpairs(struct enum_pairs *headp)
+{
+ struct enum_pair *entry;
+
+ if (headp == NULL)
+ return;
+
+ fprintf(stderr,"enums: ");
+ STAILQ_FOREACH(entry, headp, link)
+ fprintf(stderr,"%d - %s, ", entry->enum_val,
+ (entry->enum_str == NULL)?"NULL":entry->enum_str);
+
+ fprintf(stderr,"; ");
+}
+
+void
+snmp_dump_oid2str(struct snmp_oid2str *entry)
+{
+ char buf[ASN_OIDSTRLEN];
+
+ if (entry != NULL) {
+ memset(buf, 0, sizeof(buf));
+ asn_oid2str_r(&(entry->var), buf);
+ DEBUG(stderr, "%s - %s - %d - %d - %d", buf, entry->string,
+ entry->syntax, entry->access, entry->strlen);
+ snmp_dump_enumpairs(entry->snmp_enum);
+ DEBUG(stderr,"%s \n", (entry->table_idx == NULL)?"No table":
+ entry->table_idx->string);
+ }
+}
+
+static void
+snmp_dump_indexlist(struct snmp_idxlist *headp)
+{
+ struct index *entry;
+
+ if (headp == NULL)
+ return;
+
+ STAILQ_FOREACH(entry, headp, link) {
+ fprintf(stderr,"%d, ", entry->syntax);
+ snmp_dump_enumpairs(entry->snmp_enum);
+ }
+
+ fprintf(stderr,"\n");
+}
+
+/* Initialize the enum pairs list of a oid2str entry. */
+struct enum_pairs *
+enum_pairs_init(void)
+{
+ struct enum_pairs *snmp_enum;
+
+ if ((snmp_enum = malloc(sizeof(struct enum_pairs))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (NULL);
+ }
+
+ STAILQ_INIT(snmp_enum);
+ return (snmp_enum);
+}
+
+/*
+ * Given a number and string, allocate memory for a (int, string) pair and add
+ * it to the given oid2str mapping entry's enum pairs list.
+ */
+int32_t
+enum_pair_insert(struct enum_pairs *headp, int32_t enum_val, char *enum_str)
+{
+ struct enum_pair *e_new;
+
+ if ((e_new = malloc(sizeof(struct enum_pair))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ memset(e_new, 0, sizeof(struct enum_pair));
+
+ if ((e_new->enum_str = malloc(strlen(enum_str) + 1)) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ free(e_new);
+ return (-1);
+ }
+
+ e_new->enum_val = enum_val;
+ strlcpy(e_new->enum_str, enum_str, strlen(enum_str) + 1);
+ STAILQ_INSERT_TAIL(headp, e_new, link);
+
+ return (1);
+
+}
+
+/*
+ * Insert an entry in a list - entries are lexicographicaly order by asn_oid.
+ * Returns 1 on success, -1 if list is not initialized, 0 if a matching oid already
+ * exists. Error cheking is left to calling function.
+ */
+static int
+snmp_mapping_insert(struct snmp_mapping *headp, struct snmp_oid2str *entry)
+{
+ int32_t rc;
+ struct snmp_oid2str *temp, *prev;
+
+ if (entry == NULL)
+ return(-1);
+
+ if ((prev = SLIST_FIRST(headp)) == NULL ||
+ asn_compare_oid(&(entry->var), &(prev->var)) < 0) {
+ SLIST_INSERT_HEAD(headp, entry, link);
+ return (1);
+ } else
+ rc = -1; /* Make the compiler happy. */
+
+ SLIST_FOREACH(temp, headp, link) {
+ if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0)
+ break;
+ prev = temp;
+ rc = -1;
+ }
+
+ switch (rc) {
+ case 0:
+ /* Ops, matching OIDs - hope the rest info also matches. */
+ if (strncmp(temp->string, entry->string, entry->strlen)) {
+ syslog(LOG_INFO, "Matching OIDs with different string "
+ "mappings: old - %s, new - %s", temp->string,
+ entry->string);
+ return (-1);
+ }
+ /*
+ * Ok, we have that already.
+ * As long as the strings match - don't complain.
+ */
+ return (0);
+
+ case 1:
+ SLIST_INSERT_AFTER(temp, entry, link);
+ break;
+
+ case -1:
+ SLIST_INSERT_AFTER(prev, entry, link);
+ break;
+
+ default:
+ /* NOTREACHED */
+ return (-1);
+ }
+
+ return (1);
+}
+
+int32_t
+snmp_node_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_nodelist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_int_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_intlist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_oct_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_octlist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_oid_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_oidlist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_ip_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_iplist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_tick_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_ticklist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_cnt_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_cntlist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_gauge_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_gaugelist,entry));
+
+ return (-1);
+}
+
+static int32_t
+snmp_cnt64_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_cnt64list,entry));
+
+ return (-1);
+}
+
+int32_t
+snmp_enum_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ if (snmptoolctx != NULL && snmptoolctx->mappings)
+ return (snmp_mapping_insert(&snmptoolctx->snmp_enumlist,entry));
+
+ return (-1);
+}
+
+int32_t
+snmp_leaf_insert(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *entry)
+{
+ switch (entry->syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ return (snmp_int_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_oct_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_OID:
+ return (snmp_oid_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (snmp_ip_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_COUNTER:
+ return (snmp_cnt_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_GAUGE:
+ return (snmp_gauge_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_TIMETICKS:
+ return (snmp_tick_insert(snmptoolctx, entry));
+ case SNMP_SYNTAX_COUNTER64:
+ return (snmp_cnt64_insert(snmptoolctx, entry));
+ default:
+ break;
+ }
+
+ return (-1);
+}
+
+static int32_t
+snmp_index_insert(struct snmp_idxlist *headp, struct index *idx)
+{
+ if (headp == NULL || index == NULL)
+ return (-1);
+
+ STAILQ_INSERT_TAIL(headp, idx, link);
+ return (1);
+}
+
+int32_t
+snmp_syntax_insert(struct snmp_idxlist *headp, struct enum_pairs *enums,
+ enum snmp_syntax syntax, enum snmp_tc tc)
+{
+ struct index *idx;
+
+ if ((idx = malloc(sizeof(struct index))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ memset(idx, 0, sizeof(struct index));
+
+ if (snmp_index_insert(headp, idx) < 0) {
+ free(idx);
+ return (-1);
+ }
+
+ idx->syntax = syntax;
+ idx->snmp_enum = enums;
+ idx->tc = tc;
+
+ return (1);
+}
+
+int32_t
+snmp_table_insert(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_index_entry *entry)
+{
+ int32_t rc;
+ struct snmp_index_entry *temp, *prev;
+
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL ||
+ entry == NULL)
+ return(-1);
+
+ if ((prev = SLIST_FIRST(&snmptoolctx->snmp_tablelist)) == NULL ||
+ asn_compare_oid(&(entry->var), &(prev->var)) < 0) {
+ SLIST_INSERT_HEAD(&snmptoolctx->snmp_tablelist, entry, link);
+ return (1);
+ } else
+ rc = -1; /* Make the compiler happy. */
+
+ SLIST_FOREACH(temp, &snmptoolctx->snmp_tablelist, link) {
+ if ((rc = asn_compare_oid(&(entry->var), &(temp->var))) <= 0)
+ break;
+ prev = temp;
+ rc = -1;
+ }
+
+ switch (rc) {
+ case 0:
+ /* Ops, matching OIDs - hope the rest info also matches. */
+ if (strncmp(temp->string, entry->string, entry->strlen)) {
+ syslog(LOG_INFO, "Matching OIDs with different string "
+ "mapping - old - %s, new - %s", temp->string,
+ entry->string);
+ return (-1);
+ }
+ return(0);
+
+ case 1:
+ SLIST_INSERT_AFTER(temp, entry, link);
+ break;
+
+ case -1:
+ SLIST_INSERT_AFTER(prev, entry, link);
+ break;
+
+ default:
+ /* NOTREACHED */
+ return (-1);
+ }
+
+ return (1);
+}
+
+struct enum_type *
+snmp_enumtc_init(char *name)
+{
+ struct enum_type *enum_tc;
+
+ if ((enum_tc = malloc(sizeof(struct enum_type))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (NULL);
+ }
+
+ memset(enum_tc, 0, sizeof(struct enum_type));
+ if ((enum_tc->name = malloc(strlen(name) + 1)) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ free(enum_tc);
+ return (NULL);
+ }
+ strlcpy(enum_tc->name, name, strlen(name) + 1);
+
+ return (enum_tc);
+}
+
+void
+snmp_enumtc_free(struct enum_type *tc)
+{
+ if (tc->name)
+ free(tc->name);
+ if (tc->snmp_enum)
+ enum_pairs_free(tc->snmp_enum);
+ free(tc);
+}
+
+void
+snmp_enumtc_insert(struct snmp_toolinfo *snmptoolctx, struct enum_type *entry)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
+ return; /* XXX no error handling? */
+
+ SLIST_INSERT_HEAD(&snmptoolctx->snmp_tclist, entry, link);
+}
+
+struct enum_type *
+snmp_enumtc_lookup(struct snmp_toolinfo *snmptoolctx, char *name)
+{
+ struct enum_type *temp;
+
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
+ return (NULL);
+
+ SLIST_FOREACH(temp, &snmptoolctx->snmp_tclist, link) {
+ if (strcmp(temp->name, name) == 0)
+ return (temp);
+ }
+ return (NULL);
+}
+
+static void
+snmp_mapping_dumplist(struct snmp_mapping *headp)
+{
+ char buf[ASN_OIDSTRLEN];
+ struct snmp_oid2str *entry;
+
+ if (headp == NULL)
+ return;
+
+ SLIST_FOREACH(entry,headp,link) {
+ memset(buf, 0, sizeof(buf));
+ asn_oid2str_r(&(entry->var), buf);
+ fprintf(stderr, "%s - %s - %d - %d - %d", buf, entry->string,
+ entry->syntax, entry->access ,entry->strlen);
+ fprintf(stderr," - %s \n", (entry->table_idx == NULL)?
+ "No table":entry->table_idx->string);
+ }
+}
+
+static void
+snmp_mapping_dumptable(struct snmp_table_index *headp)
+{
+ char buf[ASN_OIDSTRLEN];
+ struct snmp_index_entry *entry;
+
+ if (headp == NULL)
+ return;
+
+ SLIST_FOREACH(entry, headp, link) {
+ memset(buf, 0, sizeof(buf));
+ asn_oid2str_r(&(entry->var), buf);
+ fprintf(stderr,"%s - %s - %d - ", buf, entry->string,
+ entry->strlen);
+ snmp_dump_indexlist(&(entry->index_list));
+ }
+}
+
+void
+snmp_mapping_dump(struct snmp_toolinfo *snmptoolctx /* int bits */)
+{
+ if (!_bsnmptools_debug)
+ return;
+
+ if (snmptoolctx == NULL) {
+ fprintf(stderr,"No snmptool context!\n");
+ return;
+ }
+
+ if (snmptoolctx->mappings == NULL) {
+ fprintf(stderr,"No mappings!\n");
+ return;
+ }
+
+ fprintf(stderr,"snmp_nodelist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_nodelist);
+
+ fprintf(stderr,"snmp_intlist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_intlist);
+
+ fprintf(stderr,"snmp_octlist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_octlist);
+
+ fprintf(stderr,"snmp_oidlist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_oidlist);
+
+ fprintf(stderr,"snmp_iplist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_iplist);
+
+ fprintf(stderr,"snmp_ticklist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_ticklist);
+
+ fprintf(stderr,"snmp_cntlist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_cntlist);
+
+ fprintf(stderr,"snmp_gaugelist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_gaugelist);
+
+ fprintf(stderr,"snmp_cnt64list:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_cnt64list);
+
+ fprintf(stderr,"snmp_enumlist:\n");
+ snmp_mapping_dumplist(&snmptoolctx->snmp_enumlist);
+
+ fprintf(stderr,"snmp_tablelist:\n");
+ snmp_mapping_dumptable(&snmptoolctx->snmp_tablelist);
+}
+
+char *
+enum_string_lookup(struct enum_pairs *headp, int32_t enum_val)
+{
+ struct enum_pair *temp;
+
+ if (headp == NULL)
+ return (NULL);
+
+ STAILQ_FOREACH(temp, headp, link) {
+ if (temp->enum_val == enum_val)
+ return (temp->enum_str);
+ }
+
+ return (NULL);
+}
+
+int32_t
+enum_number_lookup(struct enum_pairs *headp, char *e_str)
+{
+ struct enum_pair *tmp;
+
+ if (headp == NULL)
+ return (-1);
+
+ STAILQ_FOREACH(tmp, headp, link)
+ if (strncmp(tmp->enum_str, e_str, strlen(tmp->enum_str)) == 0)
+ return (tmp->enum_val);
+
+ return (-1);
+}
+
+static int32_t
+snmp_lookuplist_string(struct snmp_mapping *headp, struct snmp_object *s)
+{
+ struct snmp_oid2str *temp;
+
+ if (headp == NULL)
+ return (-1);
+
+ SLIST_FOREACH(temp, headp, link)
+ if (asn_compare_oid(&(temp->var), &(s->val.var)) == 0)
+ break;
+
+ if ((s->info = temp) == NULL)
+ return (-1);
+
+ return (1);
+}
+
+/* provided an asn_oid find the corresponding string for it */
+static int32_t
+snmp_lookup_leaf(struct snmp_mapping *headp, struct snmp_object *s)
+{
+ struct snmp_oid2str *temp;
+
+ if (headp == NULL)
+ return (-1);
+
+ SLIST_FOREACH(temp,headp,link) {
+ if ((asn_compare_oid(&(temp->var), &(s->val.var)) == 0) ||
+ (asn_is_suboid(&(temp->var), &(s->val.var)))) {
+ s->info = temp;
+ return (1);
+ }
+ }
+
+ return (-1);
+}
+
+int32_t
+snmp_lookup_leafstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
+ return (-1);
+
+ switch (s->val.syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ return (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s));
+ case SNMP_SYNTAX_OID:
+ return (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s));
+ case SNMP_SYNTAX_COUNTER:
+ return (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s));
+ case SNMP_SYNTAX_GAUGE:
+ return (snmp_lookup_leaf(
+ &snmptoolctx->snmp_gaugelist, s));
+ case SNMP_SYNTAX_TIMETICKS:
+ return (snmp_lookup_leaf(
+ &snmptoolctx->snmp_ticklist, s));
+ case SNMP_SYNTAX_COUNTER64:
+ return (snmp_lookup_leaf(
+ &snmptoolctx->snmp_cnt64list, s));
+ case SNMP_SYNTAX_NOSUCHOBJECT:
+ /* FALLTHROUGH */
+ case SNMP_SYNTAX_NOSUCHINSTANCE:
+ /* FALLTHROUGH */
+ case SNMP_SYNTAX_ENDOFMIBVIEW:
+ return (snmp_lookup_allstring(snmptoolctx, s));
+ default:
+ warnx("Unknown syntax - %d", s->val.syntax);
+ break;
+ }
+
+ return (-1);
+}
+
+int32_t
+snmp_lookup_enumstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
+ return (-1);
+
+ return (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s));
+}
+
+int32_t
+snmp_lookup_oidstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
+ return (-1);
+
+ return (snmp_lookuplist_string(&snmptoolctx->snmp_oidlist, s));
+}
+
+int32_t
+snmp_lookup_nodestring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL || s == NULL)
+ return (-1);
+
+ return (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s));
+}
+
+int32_t
+snmp_lookup_allstring(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s)
+{
+ if (snmptoolctx == NULL || snmptoolctx->mappings == NULL)
+ return (-1);
+
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_intlist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_octlist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_oidlist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_iplist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_cntlist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_gaugelist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_ticklist, s) > 0)
+ return (1);
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_cnt64list, s) > 0)
+ return (1);
+ if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0)
+ return (1);
+ if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0)
+ return (1);
+
+ return (-1);
+}
+
+int32_t
+snmp_lookup_nonleaf_string(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_object *s)
+{
+ if (snmptoolctx == NULL)
+ return (-1);
+
+ if (snmp_lookuplist_string(&snmptoolctx->snmp_nodelist, s) > 0)
+ return (1);
+ if (snmp_lookuplist_string(&snmptoolctx->snmp_enumlist, s) > 0)
+ return (1);
+
+ return (-1);
+}
+
+static int32_t
+snmp_lookup_oidlist(struct snmp_mapping *hp, struct snmp_object *s, char *oid)
+{
+ struct snmp_oid2str *temp;
+
+ if (hp == NULL)
+ return (-1);
+
+ SLIST_FOREACH(temp, hp, link) {
+ if (temp->strlen != strlen(oid))
+ continue;
+
+ if (strncmp(temp->string, oid, temp->strlen))
+ continue;
+
+ s->val.syntax = temp->syntax;
+ s->info = temp;
+ asn_append_oid(&(s->val.var), &(temp->var));
+ return (1);
+ }
+
+ return (-1);
+}
+
+static int32_t
+snmp_lookup_tablelist(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_table_index *headp, struct snmp_object *s, char *oid)
+{
+ struct snmp_index_entry *temp;
+
+ if (snmptoolctx == NULL || headp == NULL)
+ return (-1);
+
+ SLIST_FOREACH(temp, headp, link) {
+ if (temp->strlen != strlen(oid))
+ continue;
+
+ if (strncmp(temp->string, oid, temp->strlen))
+ continue;
+
+ /*
+ * Another hack here - if we were given a table name
+ * return the corresponding pointer to it's entry.
+ * That should not change the reponce we'll get.
+ */
+ s->val.syntax = SNMP_SYNTAX_NULL;
+ asn_append_oid(&(s->val.var), &(temp->var));
+ if (snmp_lookup_leaf(&snmptoolctx->snmp_nodelist, s) > 0)
+ return (1);
+ else
+ return (-1);
+ }
+
+ return (-1);
+}
+
+int32_t
+snmp_lookup_oidall(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
+ char *oid)
+{
+ if (snmptoolctx == NULL || s == NULL || oid == NULL)
+ return (-1);
+
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist, s, oid) > 0)
+ return (1);
+ if (snmp_lookup_tablelist(snmptoolctx, &snmptoolctx->snmp_tablelist,
+ s, oid) > 0)
+ return (1);
+
+ return (-1);
+}
+
+int32_t
+snmp_lookup_enumoid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
+ char *oid)
+{
+ if (snmptoolctx == NULL || s == NULL)
+ return (-1);
+
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_enumlist, s, oid));
+}
+
+int32_t
+snmp_lookup_oid(struct snmp_toolinfo *snmptoolctx, struct snmp_object *s,
+ char *oid)
+{
+ if (snmptoolctx == NULL || s == NULL)
+ return (-1);
+
+ switch (s->val.syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_intlist,
+ s, oid));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_octlist,
+ s, oid));
+ case SNMP_SYNTAX_OID:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_oidlist,
+ s, oid));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_iplist,
+ s, oid));
+ case SNMP_SYNTAX_COUNTER:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_cntlist,
+ s, oid));
+ case SNMP_SYNTAX_GAUGE:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_gaugelist,
+ s, oid));
+ case SNMP_SYNTAX_TIMETICKS:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_ticklist,
+ s, oid));
+ case SNMP_SYNTAX_COUNTER64:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_cnt64list,
+ s, oid));
+ case SNMP_SYNTAX_NULL:
+ return (snmp_lookup_oidlist(&snmptoolctx->snmp_nodelist,
+ s, oid));
+ default:
+ warnx("Unknown syntax - %d", s->val.syntax);
+ break;
+ }
+
+ return (-1);
+}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.c
new file mode 100644
index 0000000..dc22c69
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.c
@@ -0,0 +1,1287 @@
+/*-
+ * Copyright (c) 2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation and use in source and
+ * binary forms, with or without modification, are permitted provided that
+ * the following conditions are met:
+ *
+ * 1. Redistributions of source code or documentation must retain the above
+ * copyright notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Textual conventions for OctetStrings
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+#include "bsnmptc.h"
+#include "bsnmptools.h"
+
+/* OctetString, DisplayString */
+static char *snmp_oct2str(uint32_t, char *, char *);
+static char *snmp_str2asn_oid(char *, struct asn_oid *);
+static int parse_octetstring(struct snmp_value *, char *);
+
+/* DateAndTime */
+static char *snmp_octstr2date(uint32_t, char *, char *);
+static char *snmp_date2asn_oid(char * , struct asn_oid *);
+static int parse_dateandtime(struct snmp_value *, char *);
+
+/* PhysAddress */
+static char *snmp_oct2physAddr(uint32_t, char *, char *);
+static char *snmp_addr2asn_oid(char *, struct asn_oid *);
+static int parse_physaddress(struct snmp_value *, char *);
+
+/* NTPTimeStamp */
+static char *snmp_oct2ntp_ts(uint32_t, char *, char *);
+static char *snmp_ntp_ts2asn_oid(char *, struct asn_oid *);
+static int parse_ntp_ts(struct snmp_value *, char *);
+
+/* BridgeId */
+static char *snmp_oct2bridgeid(uint32_t, char *, char *);
+static char *snmp_bridgeid2oct(char *, struct asn_oid *);
+static int parse_bridge_id(struct snmp_value *, char *);
+
+/* BridgePortId */
+static char *snmp_oct2bport_id(uint32_t, char *, char *);
+static char *snmp_bport_id2oct(char *, struct asn_oid *);
+static int parse_bport_id(struct snmp_value *, char *);
+
+/* InetAddress */
+static char *snmp_oct2inetaddr(uint32_t len, char *octets, char *buf);
+static char *snmp_inetaddr2oct(char *str, struct asn_oid *oid);
+static int32_t parse_inetaddr(struct snmp_value *value, char *string);
+
+static char *snmp_oct2bits(uint32_t len, char *octets, char *buf);
+static char *snmp_bits2oct(char *str, struct asn_oid *oid);
+static int32_t parse_bits(struct snmp_value *value, char *string);
+
+struct snmp_text_conv {
+ enum snmp_tc tc;
+ const char *tc_str;
+ int32_t len;
+ snmp_oct2tc_f oct2tc;
+ snmp_tc2oid_f tc2oid;
+ snmp_tc2oct_f tc2oct;
+} text_convs[] = {
+ { SNMP_STRING, "OctetString", SNMP_VAR_STRSZ,
+ snmp_oct2str, snmp_str2asn_oid, parse_octetstring },
+
+ { SNMP_DISPLAYSTRING, "DisplayString" , SNMP_VAR_STRSZ,
+ snmp_oct2str, snmp_str2asn_oid, parse_octetstring },
+
+ { SNMP_DATEANDTIME, "DateAndTime", SNMP_DATETIME_STRSZ,
+ snmp_octstr2date, snmp_date2asn_oid, parse_dateandtime },
+
+ { SNMP_PHYSADDR, "PhysAddress", SNMP_PHYSADDR_STRSZ,
+ snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress },
+
+ { SNMP_ATMESI, "AtmESI", SNMP_PHYSADDR_STRSZ,
+ snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress },
+
+ { SNMP_NTP_TIMESTAMP, "NTPTimeStamp", SNMP_NTP_TS_STRSZ,
+ snmp_oct2ntp_ts, snmp_ntp_ts2asn_oid, parse_ntp_ts },
+
+ { SNMP_MACADDRESS, "MacAddress", SNMP_PHYSADDR_STRSZ,
+ snmp_oct2physAddr, snmp_addr2asn_oid, parse_physaddress },
+
+ { SNMP_BRIDGE_ID, "BridgeId", SNMP_BRIDGEID_STRSZ,
+ snmp_oct2bridgeid, snmp_bridgeid2oct, parse_bridge_id },
+
+ { SNMP_BPORT_ID, "BridgePortId", SNMP_BPORT_STRSZ,
+ snmp_oct2bport_id, snmp_bport_id2oct, parse_bport_id },
+
+ { SNMP_INETADDRESS, "InetAddress", SNMP_INADDRS_STRSZ,
+ snmp_oct2inetaddr, snmp_inetaddr2oct, parse_inetaddr },
+
+ { SNMP_TC_OWN, "BITS", SNMP_VAR_STRSZ,
+ snmp_oct2bits, snmp_bits2oct, parse_bits },
+
+ { SNMP_UNKNOWN, "Unknown", SNMP_VAR_STRSZ, snmp_oct2str,
+ snmp_str2asn_oid, parse_octetstring } /* keep last */
+};
+
+/* Common API */
+enum snmp_tc
+snmp_get_tc(char *str)
+{
+ int i;
+ for (i = 0; i < SNMP_UNKNOWN; i++) {
+ if (!strncmp(text_convs[i].tc_str, str,
+ strlen(text_convs[i].tc_str)))
+ return (text_convs[i].tc);
+ }
+
+ return (SNMP_STRING);
+}
+
+char *
+snmp_oct2tc(enum snmp_tc tc, uint32_t len, char *octets)
+{
+ uint32_t tc_len;
+ char * buf;
+
+ if (tc < 0 || tc > SNMP_UNKNOWN)
+ tc = SNMP_UNKNOWN;
+
+ if (text_convs[tc].len > 0)
+ tc_len = text_convs[tc].len;
+ else
+ tc_len = 2 * len + 3;
+
+ if ((buf = malloc(tc_len)) == NULL ) {
+ syslog(LOG_ERR, "malloc failed - %s", strerror(errno));
+ return (NULL);
+ }
+
+ memset(buf, 0, tc_len);
+ if (text_convs[tc].oct2tc(len, octets, buf) == NULL) {
+ free(buf);
+ return (NULL);
+ }
+
+ return (buf);
+}
+
+char *
+snmp_tc2oid(enum snmp_tc tc, char *str, struct asn_oid *oid)
+{
+ if (tc < 0 || tc > SNMP_UNKNOWN)
+ tc = SNMP_UNKNOWN;
+
+ return (text_convs[tc].tc2oid(str, oid));
+}
+
+int32_t
+snmp_tc2oct(enum snmp_tc tc, struct snmp_value *value, char *string)
+{
+ if (tc < 0 || tc > SNMP_UNKNOWN)
+ tc = SNMP_UNKNOWN;
+
+ return (text_convs[tc].tc2oct(value, string));
+}
+
+/*****************************************************
+* Basic OctetString type.
+*/
+static char *
+snmp_oct2str(uint32_t len, char *octets, char *buf)
+{
+ uint8_t binary = 0;
+ uint32_t i;
+ char *ptr;
+
+ if (len > MAX_OCTSTRING_LEN || octets == NULL || buf == NULL)
+ return (NULL);
+
+ for (ptr = buf, i = 0; i < len; i++)
+ if (!isprint(octets[i])) {
+ binary = 1;
+ buf += sprintf(buf, "0x");
+ break;
+ }
+
+ for (ptr = buf, i = 0; i < len; i++)
+ if (!binary)
+ ptr += sprintf(ptr, "%c", octets[i]);
+ else
+ ptr += sprintf(ptr, "%2.2x", (u_char)octets[i]);
+
+ return (buf);
+}
+
+static char *
+snmp_str2asn_oid(char *str, struct asn_oid *oid)
+{
+ uint32_t i, len = 0;
+
+ /*
+ * OctetStrings are allowed max length of ASN_MAXOCTETSTRING,
+ * but trying to index an entry with such a long OctetString
+ * will fail anyway.
+ */
+ for (len = 0; len < ASN_MAXOIDLEN; len++) {
+ if (strchr(",]", *(str + len)) != NULL)
+ break;
+ }
+
+ if (len >= ASN_MAXOIDLEN)
+ return (NULL);
+
+ if (snmp_suboid_append(oid, (asn_subid_t) len) < 0)
+ return (NULL);
+
+ for (i = 0; i < len; i++)
+ if (snmp_suboid_append(oid, (asn_subid_t) *(str + i)) < 0)
+ return (NULL);
+
+ return (str + len);
+}
+
+static int32_t
+parse_octetstring(struct snmp_value *value, char *val)
+{
+ size_t len;
+
+ if ((len = strlen(val)) >= MAX_OCTSTRING_LEN) {
+ warnx("Octetstring too long - %d is max allowed",
+ MAX_OCTSTRING_LEN - 1);
+ return (-1);
+ }
+
+ value->v.octetstring.len = len;
+
+ if((value->v.octetstring.octets = malloc(len)) == NULL) {
+ syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ memcpy(value->v.octetstring.octets, val, len);
+ value->syntax = SNMP_SYNTAX_OCTETSTRING;
+
+ return (0);
+}
+
+/*************************************************************
+ * DateAndTime
+ *************************************************************
+ * rfc 2579 specification:
+ * DateAndTime ::= TEXTUAL-CONVENTION
+ * DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
+ * STATUS current
+ * DESCRIPTION
+ * "A date-time specification.
+ *
+ * field octets contents range
+ * ----- ------ -------- -----
+ * 1 1-2 year* 0..65536
+ * 2 3 month 1..12
+ * 3 4 day 1..31
+ * 4 5 hour 0..23
+ * 5 6 minutes 0..59
+ * 6 7 seconds 0..60
+ * (use 60 for leap-second)
+ * 7 8 deci-seconds 0..9
+ * 8 9 direction from UTC '+' / '-'
+ * 9 10 hours from UTC* 0..13
+ * 10 11 minutes from UTC 0..59
+ *
+ * * Notes:
+ * - the value of year is in network-byte order
+ * - daylight saving time in New Zealand is +13
+ *
+ * For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
+ * displayed as:
+ *
+ * 1992-5-26,13:30:15.0,-4:0
+ */
+static char *
+snmp_octstr2date(uint32_t len, char *octets, char *buf)
+{
+ int year;
+ char *ptr;
+
+ if (len != SNMP_DATETIME_OCTETS || octets == NULL || buf == NULL)
+ return (NULL);
+
+ buf[0]= '\0';
+ year = (octets[0] << 8);
+ year += (octets[1]);
+
+ ptr = buf;
+ ptr += sprintf(ptr, "%4.4d-%.2d-%.2d, ", year, octets[2],octets[3]);
+ ptr += sprintf(ptr, "%2.2d:%2.2d:%2.2d.%.2d, ", octets[4],octets[5],
+ octets[6],octets[7]);
+ ptr += sprintf(ptr, "%c%.2d:%.2d", octets[8],octets[9],octets[10]);
+
+ return (buf);
+}
+
+static char *
+snmp_date2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr, *ptr;
+ uint32_t v;
+ int32_t saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) SNMP_DATETIME_OCTETS) < 0)
+ return (NULL);
+
+ /* Read 'YYYY-' and write it in two subs. */
+ ptr = str;
+ saved_errno = errno;
+ errno = 0;
+ v = strtoul(ptr, &endptr, 10);
+ if (v > 0xffff)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != '-')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) ((v & 0xff00) >> 8)) < 0)
+ return (NULL);
+ if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff)) < 0)
+ return (NULL);
+
+ /* 'MM-' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != '-')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'DD,' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != '-')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'HH:' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != ':')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'MM:' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != ':')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'SS.' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != '.')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'M(mseconds),' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != ',')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'UTC' - optional */
+ ptr = endptr + 1;
+ if (*ptr == 'U' && *(ptr + 1) == 'T' && *(ptr + 1) == 'C')
+ ptr += 3;
+
+ /* '+/-' */
+ if (*ptr == '-' || *ptr == '+') {
+ if (snmp_suboid_append(oid, (asn_subid_t) (*ptr)) < 0)
+ return (NULL);
+ } else
+ goto error1;
+
+ /* 'HH:' */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (*endptr != ':')
+ goto error1;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ /* 'MM' - last one - ignore endptr here. */
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0)
+ goto error;
+ else
+ errno = saved_errno;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+
+ error:
+ errno = saved_errno;
+ error1:
+ warnx("Date value %s not supported", str);
+ return (NULL);
+}
+
+/* Read a DateAndTime string eg. 1992-5-26,13:30:15.0,-4:0. */
+static int32_t
+parse_dateandtime(struct snmp_value *sv, char *val)
+{
+ char *endptr;
+ uint32_t v;
+ uint8_t date[SNMP_DATETIME_OCTETS];
+
+ /* 'YYYY-' */
+ v = strtoul(val, &endptr, 10);
+ if (v > 0xffff || *endptr != '-')
+ goto error;
+ date[0] = ((v & 0xff00) >> 8);
+ date[1] = (v & 0xff);
+ val = endptr + 1;
+
+ /* 'MM-' */
+ v = strtoul(val, &endptr, 10);
+ if (v == 0 || v > 12 || *endptr != '-')
+ goto error;
+ date[2] = v;
+ val = endptr + 1;
+
+ /* 'DD,' */
+ v = strtoul(val, &endptr, 10);
+ if (v == 0 || v > 31 || *endptr != ',')
+ goto error;
+ date[3] = v;
+ val = endptr + 1;
+
+ /* 'HH:' */
+ v = strtoul(val, &endptr, 10);
+ if (v > 23 || *endptr != ':')
+ goto error;
+ date[4] = v;
+ val = endptr + 1;
+
+ /* 'MM:' */
+ v = strtoul(val, &endptr, 10);
+ if (v > 59 || *endptr != ':')
+ goto error;
+ date[5] = v;
+ val = endptr + 1;
+
+ /* 'SS.' */
+ v = strtoul(val, &endptr, 10);
+ if (v > 60 || *endptr != '.')
+ goto error;
+ date[6] = v;
+ val = endptr + 1;
+
+ /* '(deci-)s,' */
+ v = strtoul(val, &endptr, 10);
+ if (v > 9 || *endptr != ',')
+ goto error;
+ date[7] = v;
+ val = endptr + 1;
+
+ /* offset - '+/-' */
+ if (*val != '-' && *val != '+')
+ goto error;
+ date[8] = (uint8_t) *val;
+ val = endptr + 1;
+
+ /* 'HH:' - offset from UTC */
+ v = strtoul(val, &endptr, 10);
+ if (v > 13 || *endptr != ':')
+ goto error;
+ date[9] = v;
+ val = endptr + 1;
+
+ /* 'MM'\0'' offset from UTC */
+ v = strtoul(val, &endptr, 10);
+ if (v > 59 || *endptr != '\0')
+ goto error;
+ date[10] = v;
+
+ if ((sv->v.octetstring.octets = malloc(SNMP_DATETIME_OCTETS)) == NULL) {
+ warnx("malloc() failed - %s", strerror(errno));
+ return (-1);
+ }
+
+ sv->v.octetstring.len = SNMP_DATETIME_OCTETS;
+ memcpy(sv->v.octetstring.octets, date, SNMP_DATETIME_OCTETS);
+ sv->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+
+ error:
+ warnx("Date value %s not supported", val);
+ return (-1);
+}
+
+/**************************************************************
+ * PhysAddress
+ */
+static char *
+snmp_oct2physAddr(uint32_t len, char *octets, char *buf)
+{
+ char *ptr;
+ uint32_t i;
+
+ if (len != SNMP_PHYSADDR_OCTETS || octets == NULL || buf == NULL)
+ return (NULL);
+
+ buf[0]= '\0';
+
+ ptr = buf;
+ ptr += sprintf(ptr, "%2.2x", octets[0]);
+ for (i = 1; i < 6; i++)
+ ptr += sprintf(ptr, ":%2.2x", octets[i]);
+
+ return (buf);
+}
+
+static char *
+snmp_addr2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr, *ptr;
+ uint32_t v, i;
+ int saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) SNMP_PHYSADDR_OCTETS) < 0)
+ return (NULL);
+
+ ptr = str;
+ for (i = 0; i < 5; i++) {
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 16);
+ errno = saved_errno;
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", str);
+ return (NULL);
+ }
+ if (*endptr != ':') {
+ warnx("Failed adding oid - %s",str);
+ return (NULL);
+ }
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+ ptr = endptr + 1;
+ }
+
+ /* The last one - don't check the ending char here. */
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 16);
+ errno = saved_errno;
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", str);
+ return (NULL);
+ }
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+static int32_t
+parse_physaddress(struct snmp_value *sv, char *val)
+{
+ char *endptr;
+ int32_t i;
+ uint32_t v;
+ uint8_t phys_addr[SNMP_PHYSADDR_OCTETS];
+
+ for (i = 0; i < 5; i++) {
+ v = strtoul(val, &endptr, 16);
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", val);
+ return (-1);
+ }
+ if(*endptr != ':') {
+ warnx("Failed reading octet - %s", val);
+ return (-1);
+ }
+ phys_addr[i] = v;
+ val = endptr + 1;
+ }
+
+ /* The last one - don't check the ending char here. */
+ v = strtoul(val, &endptr, 16);
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", val);
+ return (-1);
+ }
+ phys_addr[5] = v;
+
+ if ((sv->v.octetstring.octets = malloc(SNMP_PHYSADDR_OCTETS)) == NULL) {
+ syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ sv->v.octetstring.len = SNMP_PHYSADDR_OCTETS;
+ memcpy(sv->v.octetstring.octets, phys_addr, SNMP_PHYSADDR_OCTETS);
+ sv->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+}
+
+/**************************************************************
+ * NTPTimeStamp
+ **************************************************************
+ * NTP MIB, Revision 0.2, 7/25/97:
+ * NTPTimeStamp ::= TEXTUAL-CONVENTION
+ * DISPLAY-HINT "4x.4x"
+ * STATUS current
+ * DESCRIPTION
+ * ""
+ * SYNTAX OCTET STRING (SIZE(8))
+ */
+static char *
+snmp_oct2ntp_ts(uint32_t len, char *octets, char *buf)
+{
+ char *ptr;
+ uint32_t i;
+
+ if (len != SNMP_NTP_TS_OCTETS || octets == NULL || buf == NULL)
+ return (NULL);
+
+ buf[0]= '\0';
+
+ ptr = buf;
+ i = octets[0] * 1000 + octets[1] * 100 + octets[2] * 10 + octets[3];
+ ptr += sprintf(ptr, "%4.4d", i);
+ i = octets[4] * 1000 + octets[5] * 100 + octets[6] * 10 + octets[7];
+ ptr += sprintf(ptr, ".%4.4d", i);
+
+ return (buf);
+}
+
+static char *
+snmp_ntp_ts2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr, *ptr;
+ uint32_t v, i, d;
+ struct asn_oid suboid;
+ int saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) SNMP_NTP_TS_OCTETS) < 0)
+ return (NULL);
+
+ ptr = str;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0 || (v / 1000) > 9) {
+ warnx("Integer value %s not supported", str);
+ errno = saved_errno;
+ return (NULL);
+ } else
+ errno = saved_errno;
+
+ if (*endptr != '.') {
+ warnx("Failed adding oid - %s",str);
+ return (NULL);
+ }
+
+ memset(&suboid, 0, sizeof(struct asn_oid));
+ suboid.len = SNMP_NTP_TS_OCTETS;
+
+ for (i = 0, d = 1000; i < 4; i++) {
+ suboid.subs[i] = v / d;
+ v = v % d;
+ d = d / 10;
+ }
+
+ ptr = endptr + 1;
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ if (errno != 0 || (v / 1000) > 9) {
+ warnx("Integer value %s not supported", str);
+ errno = saved_errno;
+ return (NULL);
+ } else
+ errno = saved_errno;
+
+ for (i = 0, d = 1000; i < 4; i++) {
+ suboid.subs[i + 4] = v / d;
+ v = v % d;
+ d = d / 10;
+ }
+
+ asn_append_oid(oid, &suboid);
+ return (endptr);
+}
+
+static int32_t
+parse_ntp_ts(struct snmp_value *sv, char *val)
+{
+ char *endptr;
+ int32_t i, d, saved_errno;
+ uint32_t v;
+ uint8_t ntp_ts[SNMP_NTP_TS_OCTETS];
+
+ saved_errno = errno;
+ v = strtoul(val, &endptr, 10);
+ if (errno != 0 || (v / 1000) > 9) {
+ saved_errno = errno;
+ warnx("Integer value %s not supported", val);
+ return (-1);
+ } else
+ saved_errno = errno;
+
+ if (*endptr != '.') {
+ warnx("Failed reading octet - %s", val);
+ return (-1);
+ }
+
+ for (i = 0, d = 1000; i < 4; i++) {
+ ntp_ts[i] = v / d;
+ v = v % d;
+ d = d / 10;
+ }
+ val = endptr + 1;
+
+ saved_errno = errno;
+ v = strtoul(val, &endptr, 10);
+ if (errno != 0 || (v / 1000) > 9) {
+ saved_errno = errno;
+ warnx("Integer value %s not supported", val);
+ return (-1);
+ } else
+ saved_errno = errno;
+
+ for (i = 0, d = 1000; i < 4; i++) {
+ ntp_ts[i + 4] = v / d;
+ v = v % d;
+ d = d / 10;
+ }
+
+ if ((sv->v.octetstring.octets = malloc(SNMP_NTP_TS_OCTETS)) == NULL) {
+ syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ sv->v.octetstring.len = SNMP_NTP_TS_OCTETS;
+ memcpy(sv->v.octetstring.octets, ntp_ts, SNMP_NTP_TS_OCTETS);
+ sv->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+}
+
+/**************************************************************
+ * BridgeId
+ **************************************************************
+ * BRIDGE-MIB, REVISION "200509190000Z"
+ * BridgeId ::= TEXTUAL-CONVENTION
+ * STATUS current
+ * DESCRIPTION
+ * "The Bridge-Identifier, as used in the Spanning Tree
+ * Protocol, to uniquely identify a bridge. Its first two
+ * octets (in network byte order) contain a priority value,
+ * and its last 6 octets contain the MAC address used to
+ * refer to a bridge in a unique fashion (typically, the
+ * numerically smallest MAC address of all ports on the
+ * bridge)."
+ * SYNTAX OCTET STRING (SIZE (8))
+ */
+static char *
+snmp_oct2bridgeid(uint32_t len, char *octets, char *buf)
+{
+ char *ptr;
+ uint32_t i, priority;
+
+ if (len != SNMP_BRIDGEID_OCTETS || octets == NULL || buf == NULL)
+ return (NULL);
+
+ buf[0]= '\0';
+ ptr = buf;
+
+ priority = octets[0] << 8;
+ priority += octets[1];
+ if (priority > SNMP_MAX_BRIDGE_PRIORITY) {
+ warnx("Invalid bridge priority %d", priority);
+ return (NULL);
+ } else
+ ptr += sprintf(ptr, "%d.", octets[0]);
+
+ ptr += sprintf(ptr, "%2.2x", octets[2]);
+
+ for (i = 1; i < 6; i++)
+ ptr += sprintf(ptr, ":%2.2x", octets[i + 2]);
+
+ return (buf);
+}
+
+static char *
+snmp_bridgeid2oct(char *str, struct asn_oid *oid)
+{
+ char *endptr, *ptr;
+ uint32_t v, i;
+ int32_t saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) SNMP_BRIDGEID_OCTETS) < 0)
+ return (NULL);
+
+ ptr = str;
+ /* Read the priority. */
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ errno = 0;
+
+ if (v > SNMP_MAX_BRIDGE_PRIORITY || errno != 0 || *endptr != '.') {
+ errno = saved_errno;
+ warnx("Bad bridge priority value %d", v);
+ return (NULL);
+ }
+
+ if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff00)) < 0)
+ return (NULL);
+
+ if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xff)) < 0)
+ return (NULL);
+
+ ptr = endptr + 1;
+ for (i = 0; i < 5; i++) {
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 16);
+ errno = saved_errno;
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", str);
+ return (NULL);
+ }
+ if (*endptr != ':') {
+ warnx("Failed adding oid - %s",str);
+ return (NULL);
+ }
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+ ptr = endptr + 1;
+ }
+
+ /* The last one - don't check the ending char here. */
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 16);
+ errno = saved_errno;
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", str);
+ return (NULL);
+ }
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+static int32_t
+parse_bridge_id(struct snmp_value *sv, char *string)
+{
+ char *ptr, *endptr;
+ int32_t i, saved_errno;
+ uint32_t v;
+ uint8_t bridge_id[SNMP_BRIDGEID_OCTETS];
+
+ ptr = string;
+ /* Read the priority. */
+ saved_errno = errno;
+ errno = 0;
+ v = strtoul(string, &endptr, 10);
+ errno = saved_errno;
+
+ if (v > SNMP_MAX_BRIDGE_PRIORITY || errno != 0 || *endptr != '.') {
+ errno = saved_errno;
+ warnx("Bad bridge priority value %d", v);
+ return (-1);
+ }
+
+ bridge_id[0] = (v & 0xff00);
+ bridge_id[1] = (v & 0xff);
+
+ string = endptr + 1;
+
+ for (i = 0; i < 5; i++) {
+ v = strtoul(string, &endptr, 16);
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", string);
+ return (-1);
+ }
+ if(*endptr != ':') {
+ warnx("Failed reading octet - %s", string);
+ return (-1);
+ }
+ bridge_id[i + 2] = v;
+ string = endptr + 1;
+ }
+
+ /* The last one - don't check the ending char here. */
+ v = strtoul(string, &endptr, 16);
+ if (v > 0xff) {
+ warnx("Integer value %s not supported", string);
+ return (-1);
+ }
+ bridge_id[7] = v;
+
+ if ((sv->v.octetstring.octets = malloc(SNMP_BRIDGEID_OCTETS)) == NULL) {
+ syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ sv->v.octetstring.len = SNMP_BRIDGEID_OCTETS;
+ memcpy(sv->v.octetstring.octets, bridge_id, SNMP_BRIDGEID_OCTETS);
+ sv->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+}
+
+/**************************************************************
+ * BridgePortId
+ **************************************************************
+ * BEGEMOT-BRIDGE-MIB, LAST-UPDATED "200608100000Z"
+ * BridgePortId ::= TEXTUAL-CONVENTION
+ * DISPLAY-HINT "1x.1x"
+ * STATUS current
+ * DESCRIPTION
+ * "A port identifier that contains a bridge port's STP priority
+ * in the first octet and the port number in the second octet."
+ * SYNTAX OCTET STRING (SIZE(2))
+ */
+static char *
+snmp_oct2bport_id(uint32_t len, char *octets, char *buf)
+{
+ char *ptr;
+
+ if (len != SNMP_BPORT_OCTETS || octets == NULL || buf == NULL)
+ return (NULL);
+
+ buf[0]= '\0';
+ ptr = buf;
+
+ ptr += sprintf(ptr, "%d.", octets[0]);
+ ptr += sprintf(ptr, "%d", octets[1]);
+
+ return (buf);
+}
+
+static char *
+snmp_bport_id2oct(char *str, struct asn_oid *oid)
+{
+ char *endptr, *ptr;
+ uint32_t v;
+ int saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) SNMP_BPORT_OCTETS) < 0)
+ return (NULL);
+
+ ptr = str;
+ /* Read the priority. */
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 10);
+ errno = 0;
+
+ if (v > SNMP_MAX_BPORT_PRIORITY || errno != 0 || *endptr != '.') {
+ errno = saved_errno;
+ warnx("Bad bridge port priority value %d", v);
+ return (NULL);
+ }
+
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ saved_errno = errno;
+ v = strtoul(ptr, &endptr, 16);
+ errno = saved_errno;
+
+ if (v > 0xff) {
+ warnx("Bad port number - %d", v);
+ return (NULL);
+ }
+
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+static int32_t
+parse_bport_id(struct snmp_value *value, char *string)
+{
+ char *ptr, *endptr;
+ int saved_errno;
+ uint32_t v;
+ uint8_t bport_id[SNMP_BPORT_OCTETS];
+
+ ptr = string;
+ /* Read the priority. */
+ saved_errno = errno;
+ errno = 0;
+ v = strtoul(string, &endptr, 10);
+ errno = saved_errno;
+
+ if (v > SNMP_MAX_BPORT_PRIORITY || errno != 0 || *endptr != '.') {
+ errno = saved_errno;
+ warnx("Bad bridge port priority value %d", v);
+ return (-1);
+ }
+
+ bport_id[0] = v;
+
+ string = endptr + 1;
+ v = strtoul(string, &endptr, 16);
+ if (v > 0xff) {
+ warnx("Bad port number - %d", v);
+ return (-1);
+ }
+
+ bport_id[1] = v;
+
+ if ((value->v.octetstring.octets = malloc(SNMP_BPORT_OCTETS)) == NULL) {
+ syslog(LOG_ERR,"malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ value->v.octetstring.len = SNMP_BPORT_OCTETS;
+ memcpy(value->v.octetstring.octets, bport_id, SNMP_BPORT_OCTETS);
+ value->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+}
+/**************************************************************
+ * InetAddress
+ **************************************************************
+ * INET-ADDRESS-MIB, REVISION "200502040000Z"
+ * InetAddress ::= TEXTUAL-CONVENTION
+ * STATUS current
+ * DESCRIPTION
+ * "Denotes a generic Internet address.
+ *
+ * An InetAddress value is always interpreted within the context
+ * of an InetAddressType value. Every usage of the InetAddress
+ * textual convention is required to specify the InetAddressType
+ * object that provides the context. It is suggested that the
+ * InetAddressType object be logically registered before the
+ * object(s) that use the InetAddress textual convention, if
+ * they appear in the same logical row.
+ *
+ * The value of an InetAddress object must always be
+ * consistent with the value of the associated InetAddressType
+ * object. Attempts to set an InetAddress object to a value
+ * inconsistent with the associated InetAddressType
+ * must fail with an inconsistentValue error.
+ *
+ * When this textual convention is used as the syntax of an
+ * index object, there may be issues with the limit of 128
+ * sub-identifiers specified in SMIv2, STD 58. In this case,
+ * the object definition MUST include a 'SIZE' clause to
+ * limit the number of potential instance sub-identifiers;
+ * otherwise the applicable constraints MUST be stated in
+ * the appropriate conceptual row DESCRIPTION clauses, or
+ * in the surrounding documentation if there is no single
+ * DESCRIPTION clause that is appropriate."
+ * SYNTAX OCTET STRING (SIZE (0..255))
+ **************************************************************
+ * TODO: FIXME!!! syrinx: Since we do not support checking the
+ * consistency of a varbinding based on the value of a previous
+ * one, try to guess the type of address based on the
+ * OctetString SIZE - 4 for IPv4, 16 for IPv6, others currently
+ * not supported.
+ */
+static char *
+snmp_oct2inetaddr(uint32_t len, char *octets, char *buf)
+{
+ int af;
+ void *ip;
+ struct in_addr ipv4;
+ struct in6_addr ipv6;
+
+ if (len > MAX_OCTSTRING_LEN || octets == NULL || buf == NULL)
+ return (NULL);
+
+ switch (len) {
+ /* XXX: FIXME - IPv4*/
+ case 4:
+ memcpy(&ipv4.s_addr, octets, sizeof(ipv4.s_addr));
+ af = AF_INET;
+ ip = &ipv4;
+ break;
+
+ /* XXX: FIXME - IPv4*/
+ case 16:
+ memcpy(ipv6.s6_addr, octets, sizeof(ipv6.s6_addr));
+ af = AF_INET6;
+ ip = &ipv6;
+ break;
+
+ default:
+ return (NULL);
+ }
+
+ if (inet_ntop(af, ip, buf, SNMP_INADDRS_STRSZ) == NULL) {
+ warnx("inet_ntop failed - %s", strerror(errno));
+ return (NULL);
+ }
+
+ return (buf);
+}
+
+static char *
+snmp_inetaddr2oct(char *str, struct asn_oid *oid)
+{
+ return (NULL);
+}
+
+static int32_t
+parse_inetaddr(struct snmp_value *value, char *string)
+{
+ return (-1);
+}
+
+/**************************************************************
+ * SNMP BITS type - XXX: FIXME
+ **************************************************************/
+static char *
+snmp_oct2bits(uint32_t len, char *octets, char *buf)
+{
+ int i, bits;
+ uint64_t value;
+
+ if (len > sizeof(value) || octets == NULL || buf == NULL)
+ return (NULL);
+
+ for (i = len, value = 0, bits = 0; i > 0; i--, bits += 8)
+ value += octets[i] << bits;
+
+ buf[0]= '\0';
+ sprintf(buf, "0x%llx.",(long long unsigned) value);
+
+ return (buf);
+}
+
+static char *
+snmp_bits2oct(char *str, struct asn_oid *oid)
+{
+ char *endptr;
+ int i, size, bits, saved_errno;
+ uint64_t v, mask = 0xFF00000000000000;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoull(str, &endptr, 16);
+ if (errno != 0) {
+ warnx("Bad BITS value %s - %s", str, strerror(errno));
+ errno = saved_errno;
+ return (NULL);
+ }
+
+ bits = 8;
+ /* Determine length - up to 8 octets supported so far. */
+ for (size = sizeof(v); size > 0; size--) {
+ if ((v & mask) != 0)
+ break;
+ mask = mask >> bits;
+ }
+
+ if (size == 0)
+ size = 1;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) size) < 0)
+ return (NULL);
+
+ for (i = 0, bits = 0; i < size; i++, bits += 8)
+ if (snmp_suboid_append(oid,
+ (asn_subid_t)((v & mask) >> bits)) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+static int32_t
+parse_bits(struct snmp_value *value, char *string)
+{
+ char *endptr;
+ int i, size, bits, saved_errno;
+ uint64_t v, mask = 0xFF00000000000000;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoull(string, &endptr, 16);
+
+ if (errno != 0) {
+ warnx("Bad BITS value %s - %s", string, strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ bits = 8;
+ /* Determine length - up to 8 octets supported so far. */
+ for (size = sizeof(v); size > 0; size--) {
+ if ((v & mask) != 0)
+ break;
+ mask = mask >> bits;
+ }
+
+ if (size == 0)
+ size = 1;
+
+ if ((value->v.octetstring.octets = malloc(size)) == NULL) {
+ syslog(LOG_ERR, "malloc failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ value->v.octetstring.len = size;
+ for (i = 0, bits = 0; i < size; i++, bits += 8)
+ value->v.octetstring.octets[i] = (v & mask) >> bits;
+ value->syntax = SNMP_SYNTAX_OCTETSTRING;
+ return (1);
+}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.h b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.h
new file mode 100644
index 0000000..fd06676
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptc.h
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation and use in source and
+ * binary forms, with or without modification, are permitted provided that
+ * the following conditions are met:
+ *
+ * 1. Redistributions of source code or documentation must retain the above
+ * copyright notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Textual conventions for snmp
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BSNMP_TEXT_CONV_H_
+#define _BSNMP_TEXT_CONV_H_
+
+/* Variable display length string. */
+#define SNMP_VAR_STRSZ -1
+
+/*
+ * 11 bytes - octets that represent DateAndTime Textual convention
+ * and the size of string used to diplay that.
+ */
+#define SNMP_DATETIME_OCTETS 11
+#define SNMP_DATETIME_STRSZ 32
+
+/*
+ * 6 bytes - octets that represent PhysAddress Textual convention
+ * and the size of string used to diplay that.
+ */
+#define SNMP_PHYSADDR_OCTETS 6
+#define SNMP_PHYSADDR_STRSZ 19
+
+/* NTPTimeStamp. */
+#define SNMP_NTP_TS_OCTETS 8
+#define SNMP_NTP_TS_STRSZ 10
+
+/* BridgeId. */
+#define SNMP_BRIDGEID_OCTETS 8
+#define SNMP_BRIDGEID_STRSZ 25
+#define SNMP_MAX_BRIDGE_PRIORITY 65535
+
+/* BridgePortId. */
+#define SNMP_BPORT_OCTETS 2
+#define SNMP_BPORT_STRSZ 7
+#define SNMP_MAX_BPORT_PRIORITY 255
+
+/* InetAddress. */
+#define SNMP_INADDRS_STRSZ INET6_ADDRSTRLEN
+
+enum snmp_tc {
+ SNMP_STRING = 0,
+ SNMP_DISPLAYSTRING = 1,
+ SNMP_DATEANDTIME = 2,
+ SNMP_PHYSADDR = 3,
+ SNMP_ATMESI = 4,
+ SNMP_NTP_TIMESTAMP = 5,
+ SNMP_MACADDRESS = 6,
+ SNMP_BRIDGE_ID = 7,
+ SNMP_BPORT_ID = 8,
+ SNMP_INETADDRESS = 9,
+ SNMP_TC_OWN = 10,
+ SNMP_UNKNOWN, /* keep last */
+};
+
+typedef char * (*snmp_oct2tc_f) (uint32_t len, char *octs, char *buf);
+typedef char * (*snmp_tc2oid_f) (char *str, struct asn_oid *oid);
+typedef int32_t (*snmp_tc2oct_f) (struct snmp_value *value, char *string);
+
+enum snmp_tc snmp_get_tc(char *str);
+char *snmp_oct2tc(enum snmp_tc tc, uint32_t len, char *octets);
+char *snmp_tc2oid(enum snmp_tc tc, char *str, struct asn_oid *oid);
+int32_t snmp_tc2oct(enum snmp_tc tc, struct snmp_value *value, char *string);
+
+#endif /* _BSNMP_TEXT_CONV_H_ */
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
new file mode 100755
index 0000000..dbaac5b
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
@@ -0,0 +1,2121 @@
+/*-
+ * Copyright (c) 2005-2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation and use in source and
+ * binary forms, with or without modification, are permitted provided that
+ * the following conditions are met:
+ *
+ * 1. Redistributions of source code or documentation must retain the above
+ * copyright notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Helper functions for snmp client tools
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/uio.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <bsnmp/asn1.h>
+#include <bsnmp/snmp.h>
+#include <bsnmp/snmpclient.h>
+#include "bsnmptc.h"
+#include "bsnmptools.h"
+
+/* Internal varibale to turn on library debugging for testing and to
+ * find bugs. It is not exported via the header file.
+ * XXX should we cover it by some #ifdef BSNMPTOOLS_DEBUG? */
+int _bsnmptools_debug = 0;
+
+/* Default files to import mapping from if none explicitly provided. */
+#define bsnmpd_defs "/usr/share/snmp/defs/tree.def"
+#define mibII_defs "/usr/share/snmp/defs/mibII_tree.def"
+
+/*
+ * The .iso.org.dod oid that has to be prepended to every OID when requesting
+ * a value.
+ */
+const struct asn_oid IsoOrgDod_OID = {
+ 3, { 1, 3, 6 }
+};
+
+
+#define SNMP_ERR_UNKNOWN 0
+
+/*
+ * An array of error strings corresponding to error definitions from libbsnmp.
+ */
+static const struct {
+ const char *str;
+ int32_t error;
+} error_strings[] = {
+ { "Unknown", SNMP_ERR_UNKNOWN },
+ { "Too big ", SNMP_ERR_TOOBIG },
+ { "No such Name", SNMP_ERR_NOSUCHNAME },
+ { "Bad Value", SNMP_ERR_BADVALUE },
+ { "Readonly", SNMP_ERR_READONLY },
+ { "General error", SNMP_ERR_GENERR },
+ { "No access", SNMP_ERR_NO_ACCESS },
+ { "Wrong type", SNMP_ERR_WRONG_TYPE },
+ { "Wrong lenght", SNMP_ERR_WRONG_LENGTH },
+ { "Wrong encoding", SNMP_ERR_WRONG_ENCODING },
+ { "Wrong value", SNMP_ERR_WRONG_VALUE },
+ { "No creation", SNMP_ERR_NO_CREATION },
+ { "Inconsistent value", SNMP_ERR_INCONS_VALUE },
+ { "Resource unavailable", SNMP_ERR_RES_UNAVAIL },
+ { "Commit failed", SNMP_ERR_COMMIT_FAILED },
+ { "Undo failed", SNMP_ERR_UNDO_FAILED },
+ { "Authorization error", SNMP_ERR_AUTH_ERR },
+ { "Not writable", SNMP_ERR_NOT_WRITEABLE },
+ { "Inconsistent name", SNMP_ERR_INCONS_NAME },
+ { NULL, 0 }
+};
+
+/* This one and any following are exceptions. */
+#define SNMP_SYNTAX_UNKNOWN SNMP_SYNTAX_NOSUCHOBJECT
+
+static const struct {
+ const char *str;
+ enum snmp_syntax stx;
+} syntax_strings[] = {
+ { "Null", SNMP_SYNTAX_NULL },
+ { "Integer", SNMP_SYNTAX_INTEGER },
+ { "OctetString", SNMP_SYNTAX_OCTETSTRING },
+ { "OID", SNMP_SYNTAX_OID },
+ { "IpAddress", SNMP_SYNTAX_IPADDRESS },
+ { "Counter32", SNMP_SYNTAX_COUNTER },
+ { "Gauge", SNMP_SYNTAX_GAUGE },
+ { "TimeTicks", SNMP_SYNTAX_TIMETICKS },
+ { "Counter64", SNMP_SYNTAX_COUNTER64 },
+ { "Unknown", SNMP_SYNTAX_UNKNOWN },
+};
+
+int
+snmptool_init(struct snmp_toolinfo *snmptoolctx)
+{
+ char *str;
+ size_t slen;
+
+ memset(snmptoolctx, 0, sizeof(struct snmp_toolinfo));
+ snmptoolctx->objects = 0;
+ snmptoolctx->mappings = NULL;
+ snmptoolctx->flags = SNMP_PDU_GET; /* XXX */
+ SLIST_INIT(&snmptoolctx->filelist);
+ snmp_client_init(&snmp_client);
+
+ if (add_filename(snmptoolctx, bsnmpd_defs, &IsoOrgDod_OID, 0) < 0)
+ warnx("Error adding file %s to list", bsnmpd_defs);
+
+ if (add_filename(snmptoolctx, mibII_defs, &IsoOrgDod_OID, 0) < 0)
+ warnx("Error adding file %s to list", mibII_defs);
+
+ /* Read the environment */
+ if ((str = getenv("SNMPAUTH")) != NULL) {
+ slen = strlen(str);
+ if (slen == strlen("md5") && strcasecmp(str, "md5") == 0)
+ snmp_client.user.auth_proto = SNMP_AUTH_HMAC_MD5;
+ else if (slen == strlen("sha")&& strcasecmp(str, "sha") == 0)
+ snmp_client.user.auth_proto = SNMP_AUTH_HMAC_SHA;
+ else if (slen != 0)
+ warnx("Bad authentication type - %s in SNMPAUTH", str);
+ }
+
+ if ((str = getenv("SNMPPRIV")) != NULL) {
+ slen = strlen(str);
+ if (slen == strlen("des") && strcasecmp(str, "des") == 0)
+ snmp_client.user.priv_proto = SNMP_PRIV_DES;
+ else if (slen == strlen("aes")&& strcasecmp(str, "aes") == 0)
+ snmp_client.user.priv_proto = SNMP_PRIV_AES;
+ else if (slen != 0)
+ warnx("Bad privacy type - %s in SNMPPRIV", str);
+ }
+
+ if ((str = getenv("SNMPUSER")) != NULL) {
+ if ((slen = strlen(str)) > sizeof(snmp_client.user.sec_name)) {
+ warnx("Username too long - %s in SNMPUSER", str);
+ return (-1);
+ }
+ if (slen > 0) {
+ strlcpy(snmp_client.user.sec_name, str,
+ sizeof(snmp_client.user.sec_name));
+ snmp_client.version = SNMP_V3;
+ }
+ }
+
+ if ((str = getenv("SNMPPASSWD")) != NULL) {
+ if ((slen = strlen(str)) > MAXSTR)
+ slen = MAXSTR - 1;
+ if ((snmptoolctx->passwd = malloc(slen + 1)) == NULL) {
+ warnx("malloc() failed - %s", strerror(errno));
+ return (-1);
+ }
+ if (slen > 0)
+ strlcpy(snmptoolctx->passwd, str, slen + 1);
+ }
+
+ return (0);
+}
+
+#define OBJECT_IDX_LIST(o) o->info->table_idx->index_list
+
+/*
+ * Walk through the file list and import string<->oid mappings from each file.
+ */
+int32_t
+snmp_import_all(struct snmp_toolinfo *snmptoolctx)
+{
+ int32_t fc;
+ struct fname *tmp;
+
+ if (snmptoolctx == NULL)
+ return (-1);
+
+ if (ISSET_NUMERIC(snmptoolctx))
+ return (0);
+
+ if ((snmptoolctx->mappings = snmp_mapping_init()) == NULL)
+ return (-1);
+
+ fc = 0;
+ if (SLIST_EMPTY(&snmptoolctx->filelist)) {
+ warnx("No files to read OID <-> string conversions from");
+ return (-1);
+ } else {
+ SLIST_FOREACH(tmp, &snmptoolctx->filelist, link) {
+ if (tmp->done)
+ continue;
+ if (snmp_import_file(snmptoolctx, tmp) < 0) {
+ fc = -1;
+ break;
+ }
+ fc++;
+ }
+ }
+
+ snmp_mapping_dump(snmptoolctx);
+ return (fc);
+}
+
+/*
+ * Add a filename to the file list - the initail idea of keeping a list with all
+ * files to read OIDs from was that an application might want to have loaded in
+ * memory the OIDs from a single file only and when done with them read the OIDs
+ * from another file. This is not used yet but might be a good idea at some
+ * point. Size argument is number of bytes in string including trailing '\0',
+ * not string lenght.
+ */
+int32_t
+add_filename(struct snmp_toolinfo *snmptoolctx, const char *filename,
+ const struct asn_oid *cut, int32_t done)
+{
+ char *fstring;
+ struct fname *entry;
+
+ if (snmptoolctx == NULL)
+ return (-1);
+
+ /* Make sure file was not in list. */
+ SLIST_FOREACH(entry, &snmptoolctx->filelist, link) {
+ if (strncmp(entry->name, filename, strlen(entry->name)) == 0)
+ return (0);
+ }
+
+ if ((fstring = malloc(strlen(filename) + 1)) == NULL) {
+ warnx("malloc() failed - %s", strerror(errno));
+ return (-1);
+ }
+
+ if ((entry = malloc(sizeof(struct fname))) == NULL) {
+ warnx("malloc() failed - %s", strerror(errno));
+ free(fstring);
+ return (-1);
+ }
+
+ memset(entry, 0, sizeof(struct fname));
+
+ if (cut != NULL)
+ asn_append_oid(&(entry->cut), cut);
+ strlcpy(fstring, filename, strlen(filename) + 1);
+ entry->name = fstring;
+ entry->done = done;
+ SLIST_INSERT_HEAD(&snmptoolctx->filelist, entry, link);
+
+ return (1);
+}
+
+void
+free_filelist(struct snmp_toolinfo *snmptoolctx)
+{
+ struct fname *f;
+
+ if (snmptoolctx == NULL)
+ return; /* XXX error handling */
+
+ while ((f = SLIST_FIRST(&snmptoolctx->filelist)) != NULL) {
+ SLIST_REMOVE_HEAD(&snmptoolctx->filelist, link);
+ if (f->name)
+ free(f->name);
+ free(f);
+ }
+}
+
+static char
+isvalid_fchar(char c, int pos)
+{
+ if (isalpha(c)|| c == '/'|| c == '_' || c == '.' || c == '~' ||
+ (pos != 0 && isdigit(c))){
+ return (c);
+ }
+
+ if (c == '\0')
+ return (0);
+
+ if (!isascii(c) || !isprint(c))
+ warnx("Unexpected character %#2x", (u_int) c);
+ else
+ warnx("Illegal character '%c'", c);
+
+ return (-1);
+}
+
+/*
+ * Re-implement getsubopt from scratch, because the second argument is broken
+ * and will not compile with WARNS=5.
+ * Copied from src/contrib/bsnmp/snmpd/main.c.
+ */
+static int
+getsubopt1(char **arg, const char *const *options, char **valp, char **optp)
+{
+ static const char *const delim = ",\t ";
+ u_int i;
+ char *ptr;
+
+ *optp = NULL;
+
+ /* Skip leading junk. */
+ for (ptr = *arg; *ptr != '\0'; ptr++)
+ if (strchr(delim, *ptr) == NULL)
+ break;
+ if (*ptr == '\0') {
+ *arg = ptr;
+ return (-1);
+ }
+ *optp = ptr;
+
+ /* Find the end of the option. */
+ while (*++ptr != '\0')
+ if (strchr(delim, *ptr) != NULL || *ptr == '=')
+ break;
+
+ if (*ptr != '\0') {
+ if (*ptr == '=') {
+ *ptr++ = '\0';
+ *valp = ptr;
+ while (*ptr != '\0' && strchr(delim, *ptr) == NULL)
+ ptr++;
+ if (*ptr != '\0')
+ *ptr++ = '\0';
+ } else
+ *ptr++ = '\0';
+ }
+
+ *arg = ptr;
+
+ for (i = 0; *options != NULL; options++, i++)
+ if (strcmp(*optp, *options) == 0)
+ return (i);
+ return (-1);
+}
+
+static int32_t
+parse_path(char *value)
+{
+ int32_t i, len;
+
+ if (value == NULL)
+ return (-1);
+
+ for (len = 0; len < MAXPATHLEN; len++) {
+ i = isvalid_fchar(*(value + len), len) ;
+
+ if (i == 0)
+ break;
+ else if (i < 0)
+ return (-1);
+ }
+
+ if (len >= MAXPATHLEN || value[len] != '\0') {
+ warnx("Bad pathname - '%s'", value);
+ return (-1);
+ }
+
+ return (len);
+}
+
+static int32_t
+parse_flist(struct snmp_toolinfo *snmptoolctx, char *value, char *path,
+ const struct asn_oid *cut)
+{
+ int32_t namelen;
+ char filename[MAXPATHLEN + 1];
+
+ if (value == NULL)
+ return (-1);
+
+ do {
+ memset(filename, 0, MAXPATHLEN + 1);
+
+ if (isalpha(*value) && (path == NULL || path[0] == '\0')) {
+ strlcpy(filename, SNMP_DEFS_DIR, MAXPATHLEN + 1);
+ namelen = strlen(SNMP_DEFS_DIR);
+ } else if (path != NULL){
+ strlcpy(filename, path, MAXPATHLEN + 1);
+ namelen = strlen(path);
+ } else
+ namelen = 0;
+
+ for ( ; namelen < MAXPATHLEN; value++) {
+ if (isvalid_fchar(*value, namelen) > 0) {
+ filename[namelen++] = *value;
+ continue;
+ }
+
+ if (*value == ',' )
+ value++;
+ else if (*value == '\0')
+ ;
+ else {
+ if (!isascii(*value) || !isprint(*value))
+ warnx("Unexpected character %#2x in"
+ " filename", (u_int) *value);
+ else
+ warnx("Illegal character '%c' in"
+ " filename", *value);
+ return (-1);
+ }
+
+ filename[namelen]='\0';
+ break;
+ }
+
+ if ((namelen == MAXPATHLEN) && (filename[MAXPATHLEN] != '\0')) {
+ warnx("Filename %s too long", filename);
+ return (-1);
+ }
+
+ if (add_filename(snmptoolctx, filename, cut, 0) < 0) {
+ warnx("Error adding file %s to list", filename);
+ return (-1);
+ }
+ } while (*value != '\0');
+
+ return(1);
+}
+
+static int32_t
+parse_ascii(char *ascii, uint8_t *binstr, size_t binlen)
+{
+ int32_t alen, count, saved_errno, i;
+ uint32_t val;
+ char dptr[3];
+
+ /* Filter 0x at the beggining */
+ if ((alen = strlen(ascii)) > 2 && ascii[0] == '0' && ascii[1] == 'x')
+ i = 2;
+ else
+ i = 0;
+
+ saved_errno = errno;
+ errno = 0;
+ for (count = 0; i < alen; i += 2) {
+ /* XXX: consider strlen(ascii) % 2 != 0 */
+ dptr[0] = ascii[i];
+ dptr[1] = ascii[i + 1];
+ dptr[2] = '\0';
+ if ((val = strtoul(dptr, NULL, 16)) > 0xFF || errno != 0) {
+ errno = saved_errno;
+ return (-1);
+ }
+ binstr[count] = (uint8_t) val;
+ if (++count >= binlen) {
+ warnx("Key %s too long - truncating to %zu octest",
+ ascii, binlen);
+ break;
+ }
+ }
+
+ return (count);
+}
+
+/*
+ * Functions to parse common input options for client tools and fill in the
+ * snmp_client structure.
+ */
+int32_t
+parse_authentication(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ int32_t count, subopt;
+ char *val, *option;
+ const char *const subopts[] = {
+ "proto",
+ "key",
+ NULL
+ };
+
+ assert(opt_arg != NULL);
+ count = 1;
+ while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) {
+ switch (subopt) {
+ case 0:
+ if (val == NULL) {
+ warnx("Suboption 'proto' requires an argument");
+ return (-1);
+ }
+ if (strlen(val) != 3) {
+ warnx("Unknown auth protocol - %s", val);
+ return (-1);
+ }
+ if (strncasecmp("md5", val, strlen("md5")) == 0)
+ snmp_client.user.auth_proto =
+ SNMP_AUTH_HMAC_MD5;
+ else if (strncasecmp("sha", val, strlen("sha")) == 0)
+ snmp_client.user.auth_proto =
+ SNMP_AUTH_HMAC_SHA;
+ else {
+ warnx("Unknown auth protocol - %s", val);
+ return (-1);
+ }
+ break;
+ case 1:
+ if (val == NULL) {
+ warnx("Suboption 'key' requires an argument");
+ return (-1);
+ }
+ if (parse_ascii(val, snmp_client.user.auth_key,
+ SNMP_AUTH_KEY_SIZ) < 0) {
+ warnx("Bad authentication key- %s", val);
+ return (-1);
+ }
+ break;
+ default:
+ warnx("Unknown suboption - '%s'", suboptarg);
+ return (-1);
+ }
+ count += 1;
+ }
+ return (2/* count */);
+}
+
+int32_t
+parse_privacy(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ int32_t count, subopt;
+ char *val, *option;
+ const char *const subopts[] = {
+ "proto",
+ "key",
+ NULL
+ };
+
+ assert(opt_arg != NULL);
+ count = 1;
+ while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) {
+ switch (subopt) {
+ case 0:
+ if (val == NULL) {
+ warnx("Suboption 'proto' requires an argument");
+ return (-1);
+ }
+ if (strlen(val) != 3) {
+ warnx("Unknown privacy protocol - %s", val);
+ return (-1);
+ }
+ if (strncasecmp("aes", val, strlen("aes")) == 0)
+ snmp_client.user.priv_proto = SNMP_PRIV_AES;
+ else if (strncasecmp("des", val, strlen("des")) == 0)
+ snmp_client.user.priv_proto = SNMP_PRIV_DES;
+ else {
+ warnx("Unknown privacy protocol - %s", val);
+ return (-1);
+ }
+ break;
+ case 1:
+ if (val == NULL) {
+ warnx("Suboption 'key' requires an argument");
+ return (-1);
+ }
+ if (parse_ascii(val, snmp_client.user.priv_key,
+ SNMP_PRIV_KEY_SIZ) < 0) {
+ warnx("Bad privacy key- %s", val);
+ return (-1);
+ }
+ break;
+ default:
+ warnx("Unknown suboption - '%s'", suboptarg);
+ return (-1);
+ }
+ count += 1;
+ }
+ return (2/* count */);
+}
+
+int32_t
+parse_context(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ int32_t count, subopt;
+ char *val, *option;
+ const char *const subopts[] = {
+ "context",
+ "context-engine",
+ NULL
+ };
+
+ assert(opt_arg != NULL);
+ count = 1;
+ while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) {
+ switch (subopt) {
+ case 0:
+ if (val == NULL) {
+ warnx("Suboption 'context' - no argument");
+ return (-1);
+ }
+ strlcpy(snmp_client.cname, val, SNMP_CONTEXT_NAME_SIZ);
+ break;
+ case 1:
+ if (val == NULL) {
+ warnx("Suboption 'context-engine' - no argument");
+ return (-1);
+ }
+ if ((snmp_client.clen = parse_ascii(val,
+ snmp_client.cengine, SNMP_ENGINE_ID_SIZ)) < 0) {
+ warnx("Bad EngineID - %s", val);
+ return (-1);
+ }
+ break;
+ default:
+ warnx("Unknown suboption - '%s'", suboptarg);
+ return (-1);
+ }
+ count += 1;
+ }
+ return (2/* count */);
+}
+
+int32_t
+parse_user_security(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ int32_t count, subopt, saved_errno;
+ char *val, *option;
+ const char *const subopts[] = {
+ "engine",
+ "engine-boots",
+ "engine-time",
+ "name",
+ NULL
+ };
+
+ assert(opt_arg != NULL);
+ count = 1;
+ while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) {
+ switch (subopt) {
+ case 0:
+ if (val == NULL) {
+ warnx("Suboption 'engine' - no argument");
+ return (-1);
+ }
+ snmp_client.engine.engine_len = parse_ascii(val,
+ snmp_client.engine.engine_id, SNMP_ENGINE_ID_SIZ);
+ if (snmp_client.engine.engine_len < 0) {
+ warnx("Bad EngineID - %s", val);
+ return (-1);
+ }
+ break;
+ case 1:
+ if (val == NULL) {
+ warnx("Suboption 'engine-boots' - no argument");
+ return (-1);
+ }
+ saved_errno = errno;
+ errno = 0;
+ snmp_client.engine.engine_boots = strtoul(val, NULL, 10);
+ if (errno != 0) {
+ warnx("Bad 'engine-boots' value %s - %s", val,
+ strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+ errno = saved_errno;
+ break;
+ case 2:
+ if (val == NULL) {
+ warnx("Suboption 'engine-time' - no argument");
+ return (-1);
+ }
+ saved_errno = errno;
+ errno = 0;
+ snmp_client.engine.engine_time = strtoul(val, NULL, 10);
+ if (errno != 0) {
+ warnx("Bad 'engine-time' value %s - %s", val,
+ strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+ errno = saved_errno;
+ break;
+ case 3:
+ strlcpy(snmp_client.user.sec_name, val,
+ SNMP_ADM_STR32_SIZ);
+ break;
+ default:
+ warnx("Unknown suboption - '%s'", suboptarg);
+ return (-1);
+ }
+ count += 1;
+ }
+ return (2/* count */);
+}
+
+int32_t
+parse_file(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ assert(opt_arg != NULL);
+
+ if (parse_flist(snmptoolctx, opt_arg, NULL, &IsoOrgDod_OID) < 0)
+ return (-1);
+
+ return (2);
+}
+
+int32_t
+parse_include(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ char path[MAXPATHLEN + 1];
+ int32_t cut_dflt, len, subopt;
+ struct asn_oid cut;
+ char *val, *option;
+ const char *const subopts[] = {
+ "cut",
+ "path",
+ "file",
+ NULL
+ };
+
+#define INC_CUT 0
+#define INC_PATH 1
+#define INC_LIST 2
+
+ assert(opt_arg != NULL);
+
+ /* if (opt == 'i')
+ free_filelist(snmptoolctx, ); */
+ /*
+ * This function should be called only after getopt(3) - otherwise if
+ * no previous validation of opt_arg strlen() may not return what is
+ * expected.
+ */
+
+ path[0] = '\0';
+ memset(&cut, 0, sizeof(struct asn_oid));
+ cut_dflt = -1;
+
+ while ((subopt = getsubopt1(&opt_arg, subopts, &val, &option)) != EOF) {
+ switch (subopt) {
+ case INC_CUT:
+ if (val == NULL) {
+ warnx("Suboption 'cut' requires an argument");
+ return (-1);
+ } else {
+ if (snmp_parse_numoid(val, &cut) < 0)
+ return (-1);
+ }
+ cut_dflt = 1;
+ break;
+
+ case INC_PATH:
+ if ((len = parse_path(val)) < 0)
+ return (-1);
+ strlcpy(path, val, len + 1);
+ break;
+
+ case INC_LIST:
+ if (val == NULL)
+ return (-1);
+ if (cut_dflt == -1)
+ len = parse_flist(snmptoolctx, val, path, &IsoOrgDod_OID);
+ else
+ len = parse_flist(snmptoolctx, val, path, &cut);
+ if (len < 0)
+ return (-1);
+ break;
+
+ default:
+ warnx("Unknown suboption - '%s'", suboptarg);
+ return (-1);
+ }
+ }
+
+ /* XXX: Fix me - returning two is wrong here */
+ return (2);
+}
+
+int32_t
+parse_server(char *opt_arg)
+{
+ assert(opt_arg != NULL);
+
+ if (snmp_parse_server(&snmp_client, opt_arg) < 0)
+ return (-1);
+
+ if (snmp_client.trans > SNMP_TRANS_UDP && snmp_client.chost == NULL) {
+ if ((snmp_client.chost = malloc(strlen(SNMP_DEFAULT_LOCAL + 1)))
+ == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+ strcpy(snmp_client.chost, SNMP_DEFAULT_LOCAL);
+ }
+
+ return (2);
+}
+
+int32_t
+parse_timeout(char *opt_arg)
+{
+ int32_t v, saved_errno;
+
+ assert(opt_arg != NULL);
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtol(opt_arg, NULL, 10);
+ if (errno != 0) {
+ warnx( "Error parsing timeout value - %s", strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ snmp_client.timeout.tv_sec = v;
+ errno = saved_errno;
+ return (2);
+}
+
+int32_t
+parse_retry(char *opt_arg)
+{
+ uint32_t v;
+ int32_t saved_errno;
+
+ assert(opt_arg != NULL);
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoul(opt_arg, NULL, 10);
+ if (errno != 0) {
+ warnx("Error parsing retries count - %s", strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ snmp_client.retries = v;
+ errno = saved_errno;
+ return (2);
+}
+
+int32_t
+parse_version(char *opt_arg)
+{
+ uint32_t v;
+ int32_t saved_errno;
+
+ assert(opt_arg != NULL);
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoul(opt_arg, NULL, 10);
+ if (errno != 0) {
+ warnx("Error parsing version - %s", strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ switch (v) {
+ case 1:
+ snmp_client.version = SNMP_V1;
+ break;
+ case 2:
+ snmp_client.version = SNMP_V2c;
+ break;
+ case 3:
+ snmp_client.version = SNMP_V3;
+ break;
+ default:
+ warnx("Unsupported SNMP version - %u", v);
+ errno = saved_errno;
+ return (-1);
+ }
+
+ errno = saved_errno;
+ return (2);
+}
+
+int32_t
+parse_local_path(char *opt_arg)
+{
+ assert(opt_arg != NULL);
+
+ if (sizeof(opt_arg) > sizeof(SNMP_LOCAL_PATH)) {
+ warnx("Filename too long - %s", opt_arg);
+ return (-1);
+ }
+
+ strlcpy(snmp_client.local_path, opt_arg, sizeof(SNMP_LOCAL_PATH));
+ return (2);
+}
+
+int32_t
+parse_buflen(char *opt_arg)
+{
+ uint32_t size;
+ int32_t saved_errno;
+
+ assert(opt_arg != NULL);
+
+ saved_errno = errno;
+ errno = 0;
+
+ size = strtoul(opt_arg, NULL, 10);
+ if (errno != 0) {
+ warnx("Error parsing buffer size - %s", strerror(errno));
+ errno = saved_errno;
+ return (-1);
+ }
+
+ if (size > MAX_BUFF_SIZE) {
+ warnx("Buffer size too big - %d max allowed", MAX_BUFF_SIZE);
+ errno = saved_errno;
+ return (-1);
+ }
+
+ snmp_client.txbuflen = snmp_client.rxbuflen = size;
+ errno = saved_errno;
+ return (2);
+}
+
+int32_t
+parse_debug(void)
+{
+ snmp_client.dump_pdus = 1;
+ return (1);
+}
+
+int32_t
+parse_discovery(struct snmp_toolinfo *snmptoolctx)
+{
+ SET_EDISCOVER(snmptoolctx);
+ snmp_client.version = SNMP_V3;
+ return (1);
+}
+
+int32_t
+parse_local_key(struct snmp_toolinfo *snmptoolctx)
+{
+ SET_LOCALKEY(snmptoolctx);
+ snmp_client.version = SNMP_V3;
+ return (1);
+}
+
+int32_t
+parse_num_oids(struct snmp_toolinfo *snmptoolctx)
+{
+ SET_NUMERIC(snmptoolctx);
+ return (1);
+}
+
+int32_t
+parse_output(struct snmp_toolinfo *snmptoolctx, char *opt_arg)
+{
+ assert(opt_arg != NULL);
+
+ if (strlen(opt_arg) > strlen("verbose")) {
+ warnx( "Invalid output option - %s",opt_arg);
+ return (-1);
+ }
+
+ if (strncasecmp(opt_arg, "short", strlen(opt_arg)) == 0)
+ SET_OUTPUT(snmptoolctx, OUTPUT_SHORT);
+ else if (strncasecmp(opt_arg, "verbose", strlen(opt_arg)) == 0)
+ SET_OUTPUT(snmptoolctx, OUTPUT_VERBOSE);
+ else if (strncasecmp(opt_arg,"tabular", strlen(opt_arg)) == 0)
+ SET_OUTPUT(snmptoolctx, OUTPUT_TABULAR);
+ else if (strncasecmp(opt_arg, "quiet", strlen(opt_arg)) == 0)
+ SET_OUTPUT(snmptoolctx, OUTPUT_QUIET);
+ else {
+ warnx( "Invalid output option - %s", opt_arg);
+ return (-1);
+ }
+
+ return (2);
+}
+
+int32_t
+parse_errors(struct snmp_toolinfo *snmptoolctx)
+{
+ SET_RETRY(snmptoolctx);
+ return (1);
+}
+
+int32_t
+parse_skip_access(struct snmp_toolinfo *snmptoolctx)
+{
+ SET_ERRIGNORE(snmptoolctx);
+ return (1);
+}
+
+char *
+snmp_parse_suboid(char *str, struct asn_oid *oid)
+{
+ char *endptr;
+ asn_subid_t suboid;
+
+ if (*str == '.')
+ str++;
+
+ if (*str < '0' || *str > '9')
+ return (str);
+
+ do {
+ suboid = strtoul(str, &endptr, 10);
+ if ((asn_subid_t) suboid > ASN_MAXID) {
+ warnx("Suboid %u > ASN_MAXID", suboid);
+ return (NULL);
+ }
+ if (snmp_suboid_append(oid, suboid) < 0)
+ return (NULL);
+ str = endptr + 1;
+ } while (*endptr == '.');
+
+ return (endptr);
+}
+
+static char *
+snmp_int2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr;
+ int32_t v, saved_errno;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtol(str, &endptr, 10);
+ if (errno != 0) {
+ warnx("Integer value %s not supported - %s", str,
+ strerror(errno));
+ errno = saved_errno;
+ return (NULL);
+ }
+ errno = saved_errno;
+
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+/* It is a bit weird to have a table indexed by OID but still... */
+static char *
+snmp_oid2asn_oid(struct snmp_toolinfo *snmptoolctx, char *str,
+ struct asn_oid *oid)
+{
+ int32_t i;
+ char string[MAXSTR], *endptr;
+ struct snmp_object obj;
+
+ for (i = 0; i < MAXSTR; i++)
+ if (isalpha (*(str + i)) == 0)
+ break;
+
+ endptr = str + i;
+ memset(&obj, 0, sizeof(struct snmp_object));
+ if (i == 0) {
+ if ((endptr = snmp_parse_suboid(str, &(obj.val.var))) == NULL)
+ return (NULL);
+ if (snmp_suboid_append(oid, (asn_subid_t) obj.val.var.len) < 0)
+ return (NULL);
+ } else {
+ strlcpy(string, str, i + 1);
+ string[i] = '\0';
+ if (snmp_lookup_enumoid(snmptoolctx, &obj, string) < 0) {
+ warnx("Unknown string - %s",string);
+ return (NULL);
+ }
+ free(string);
+ }
+
+ asn_append_oid(oid, &(obj.val.var));
+ return (endptr);
+}
+
+static char *
+snmp_ip2asn_oid(char *str, struct asn_oid *oid)
+{
+ uint32_t v;
+ int32_t i;
+ char *endptr, *ptr;
+
+ ptr = str;
+ for (i = 0; i < 4; i++) {
+ v = strtoul(ptr, &endptr, 10);
+ if (v > 0xff)
+ return (NULL);
+ if (*endptr != '.' && strchr("],\0", *endptr) == NULL && i != 3)
+ return (NULL);
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+ ptr = endptr + 1;
+ }
+
+ return (endptr);
+}
+
+/* 32-bit counter, gauge, timeticks. */
+static char *
+snmp_uint2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr;
+ uint32_t v;
+ int32_t saved_errno;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoul(str, &endptr, 10);
+ if (errno != 0) {
+ warnx("Integer value %s not supported - %s\n", str,
+ strerror(errno));
+ errno = saved_errno;
+ return (NULL);
+ }
+ errno = saved_errno;
+ if (snmp_suboid_append(oid, (asn_subid_t) v) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+static char *
+snmp_cnt64_2asn_oid(char *str, struct asn_oid *oid)
+{
+ char *endptr;
+ uint64_t v;
+ int32_t saved_errno;
+
+ saved_errno = errno;
+ errno = 0;
+
+ v = strtoull(str, &endptr, 10);
+
+ if (errno != 0) {
+ warnx("Integer value %s not supported - %s", str,
+ strerror(errno));
+ errno = saved_errno;
+ return (NULL);
+ }
+ errno = saved_errno;
+ if (snmp_suboid_append(oid, (asn_subid_t) (v & 0xffffffff)) < 0)
+ return (NULL);
+
+ if (snmp_suboid_append(oid, (asn_subid_t) (v >> 32)) < 0)
+ return (NULL);
+
+ return (endptr);
+}
+
+enum snmp_syntax
+parse_syntax(char *str)
+{
+ int32_t i;
+
+ for (i = 0; i < SNMP_SYNTAX_UNKNOWN; i++) {
+ if (strncmp(syntax_strings[i].str, str,
+ strlen(syntax_strings[i].str)) == 0)
+ return (syntax_strings[i].stx);
+ }
+
+ return (SNMP_SYNTAX_NULL);
+}
+
+static char *
+snmp_parse_subindex(struct snmp_toolinfo *snmptoolctx, char *str,
+ struct index *idx, struct snmp_object *object)
+{
+ char *ptr;
+ int32_t i;
+ enum snmp_syntax stx;
+ char syntax[MAX_CMD_SYNTAX_LEN];
+
+ ptr = str;
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE) {
+ for (i = 0; i < MAX_CMD_SYNTAX_LEN ; i++) {
+ if (*(ptr + i) == ':')
+ break;
+ }
+
+ if (i >= MAX_CMD_SYNTAX_LEN) {
+ warnx("Unknown syntax in OID - %s", str);
+ return (NULL);
+ }
+ /* Expect a syntax string here. */
+ if ((stx = parse_syntax(str)) <= SNMP_SYNTAX_NULL) {
+ warnx("Invalid syntax - %s",syntax);
+ return (NULL);
+ }
+
+ if (stx != idx->syntax && !ISSET_ERRIGNORE(snmptoolctx)) {
+ warnx("Syntax mismatch - %d expected, %d given",
+ idx->syntax, stx);
+ return (NULL);
+ }
+ /*
+ * That is where the suboid started + the syntax length + one
+ * character for ':'.
+ */
+ ptr = str + i + 1;
+ } else
+ stx = idx->syntax;
+
+ switch (stx) {
+ case SNMP_SYNTAX_INTEGER:
+ return (snmp_int2asn_oid(ptr, &(object->val.var)));
+ case SNMP_SYNTAX_OID:
+ return (snmp_oid2asn_oid(snmptoolctx, ptr,
+ &(object->val.var)));
+ case SNMP_SYNTAX_IPADDRESS:
+ return (snmp_ip2asn_oid(ptr, &(object->val.var)));
+ case SNMP_SYNTAX_COUNTER:
+ /* FALLTHROUGH */
+ case SNMP_SYNTAX_GAUGE:
+ /* FALLTHROUGH */
+ case SNMP_SYNTAX_TIMETICKS:
+ return (snmp_uint2asn_oid(ptr, &(object->val.var)));
+ case SNMP_SYNTAX_COUNTER64:
+ return (snmp_cnt64_2asn_oid(ptr, &(object->val.var)));
+ case SNMP_SYNTAX_OCTETSTRING:
+ return (snmp_tc2oid(idx->tc, ptr, &(object->val.var)));
+ default:
+ /* NOTREACHED */
+ break;
+ }
+
+ return (NULL);
+}
+
+char *
+snmp_parse_index(struct snmp_toolinfo *snmptoolctx, char *str,
+ struct snmp_object *object)
+{
+ char *ptr;
+ struct index *temp;
+
+ if (object->info->table_idx == NULL)
+ return (NULL);
+
+ ptr = NULL;
+ STAILQ_FOREACH(temp, &(OBJECT_IDX_LIST(object)), link) {
+ if ((ptr = snmp_parse_subindex(snmptoolctx, str, temp, object))
+ == NULL)
+ return (NULL);
+
+ if (*ptr != ',' && *ptr != ']')
+ return (NULL);
+ str = ptr + 1;
+ }
+
+ if (ptr == NULL || *ptr != ']') {
+ warnx("Mismatching index - %s", str);
+ return (NULL);
+ }
+
+ return (ptr + 1);
+}
+
+/*
+ * Fill in the struct asn_oid member of snmp_value with suboids from input.
+ * If an error occurs - print message on stderr and return (-1).
+ * If all is ok - return the length of the oid.
+ */
+int32_t
+snmp_parse_numoid(char *argv, struct asn_oid *var)
+{
+ char *endptr, *str;
+ asn_subid_t suboid;
+
+ str = argv;
+
+ if (*str == '.')
+ str++;
+
+ do {
+ if (var->len == ASN_MAXOIDLEN) {
+ warnx("Oid too long - %u", var->len);
+ return (-1);
+ }
+
+ suboid = strtoul(str, &endptr, 10);
+ if (suboid > ASN_MAXID) {
+ warnx("Oid too long - %u", var->len);
+ return (-1);
+ }
+
+ var->subs[var->len++] = suboid;
+ str = endptr + 1;
+ } while ( *endptr == '.');
+
+ if (*endptr != '\0') {
+ warnx("Invalid oid string - %s", argv);
+ return (-1);
+ }
+
+ return (var->len);
+}
+
+/* Append a length 1 suboid to an asn_oid structure. */
+int32_t
+snmp_suboid_append(struct asn_oid *var, asn_subid_t suboid)
+{
+ if (var == NULL)
+ return (-1);
+
+ if (var->len >= ASN_MAXOIDLEN) {
+ warnx("Oid too long - %u", var->len);
+ return (-1);
+ }
+
+ var->subs[var->len++] = suboid;
+
+ return (1);
+}
+
+/* Pop the last suboid from an asn_oid structure. */
+int32_t
+snmp_suboid_pop(struct asn_oid *var)
+{
+ asn_subid_t suboid;
+
+ if (var == NULL)
+ return (-1);
+
+ if (var->len < 1)
+ return (-1);
+
+ suboid = var->subs[--(var->len)];
+ var->subs[var->len] = 0;
+
+ return (suboid);
+}
+
+/*
+ * Parse the command-line provided string into an OID - alocate memory for a new
+ * snmp object, fill in its fields and insert it in the object list. A
+ * (snmp_verify_inoid_f) function must be provided to validate the input string.
+ */
+int32_t
+snmp_object_add(struct snmp_toolinfo *snmptoolctx, snmp_verify_inoid_f func,
+ char *string)
+{
+ struct snmp_object *obj;
+
+ if (snmptoolctx == NULL)
+ return (-1);
+
+ /* XXX-BZ does that chack make sense? */
+ if (snmptoolctx->objects >= SNMP_MAX_BINDINGS) {
+ warnx("Too many bindings in PDU - %u", snmptoolctx->objects + 1);
+ return (-1);
+ }
+
+ if ((obj = malloc(sizeof(struct snmp_object))) == NULL) {
+ syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ memset(obj, 0, sizeof(struct snmp_object));
+ if (func(snmptoolctx, obj, string) < 0) {
+ warnx("Invalid OID - %s", string);
+ free(obj);
+ return (-1);
+ }
+
+ snmptoolctx->objects++;
+ SLIST_INSERT_HEAD(&snmptoolctx->snmp_objectlist, obj, link);
+
+ return (1);
+}
+
+/* Given an OID, find it in the object list and remove it. */
+int32_t
+snmp_object_remove(struct snmp_toolinfo *snmptoolctx, struct asn_oid *oid)
+{
+ struct snmp_object *temp;
+
+ if (SLIST_EMPTY(&snmptoolctx->snmp_objectlist)) {
+ warnx("Object list already empty");
+ return (-1);
+ }
+
+
+ SLIST_FOREACH(temp, &snmptoolctx->snmp_objectlist, link)
+ if (asn_compare_oid(&(temp->val.var), oid) == 0)
+ break;
+
+ if (temp == NULL) {
+ warnx("No such object in list");
+ return (-1);
+ }
+
+ SLIST_REMOVE(&snmptoolctx->snmp_objectlist, temp, snmp_object, link);
+ if (temp->val.syntax == SNMP_SYNTAX_OCTETSTRING &&
+ temp->val.v.octetstring.octets != NULL)
+ free(temp->val.v.octetstring.octets);
+ free(temp);
+
+ return (1);
+}
+
+static void
+snmp_object_freeall(struct snmp_toolinfo *snmptoolctx)
+{
+ struct snmp_object *o;
+
+ while ((o = SLIST_FIRST(&snmptoolctx->snmp_objectlist)) != NULL) {
+ SLIST_REMOVE_HEAD(&snmptoolctx->snmp_objectlist, link);
+
+ if (o->val.syntax == SNMP_SYNTAX_OCTETSTRING &&
+ o->val.v.octetstring.octets != NULL)
+ free(o->val.v.octetstring.octets);
+ free(o);
+ }
+}
+
+/* Do all possible memory release before exit. */
+void
+snmp_tool_freeall(struct snmp_toolinfo *snmptoolctx)
+{
+ if (snmp_client.chost != NULL) {
+ free(snmp_client.chost);
+ snmp_client.chost = NULL;
+ }
+
+ if (snmp_client.cport != NULL) {
+ free(snmp_client.cport);
+ snmp_client.cport = NULL;
+ }
+
+ snmp_mapping_free(snmptoolctx);
+ free_filelist(snmptoolctx);
+ snmp_object_freeall(snmptoolctx);
+
+ if (snmptoolctx->passwd != NULL) {
+ free(snmptoolctx->passwd);
+ snmptoolctx->passwd = NULL;
+ }
+}
+
+/*
+ * Fill all variables from the object list into a PDU. (snmp_verify_vbind_f)
+ * function should check whether the variable is consistent in this PDU
+ * (e.g do not add non-leaf OIDs to a GET PDU, or OIDs with read access only to
+ * a SET PDU) - might be NULL though. (snmp_add_vbind_f) function is the
+ * function actually adds the variable to the PDU and must not be NULL.
+ */
+int32_t
+snmp_pdu_add_bindings(struct snmp_toolinfo *snmptoolctx,
+ snmp_verify_vbind_f vfunc, snmp_add_vbind_f afunc,
+ struct snmp_pdu *pdu, int32_t maxcount)
+{
+ int32_t nbindings, abind;
+ struct snmp_object *obj;
+
+ if (pdu == NULL || afunc == NULL)
+ return (-1);
+
+ /* Return 0 in case of no more work todo. */
+ if (SLIST_EMPTY(&snmptoolctx->snmp_objectlist))
+ return (0);
+
+ if (maxcount < 0 || maxcount > SNMP_MAX_BINDINGS) {
+ warnx("maxcount out of range: <0 || >SNMP_MAX_BINDINGS");
+ return (-1);
+ }
+
+ nbindings = 0;
+ SLIST_FOREACH(obj, &snmptoolctx->snmp_objectlist, link) {
+ if ((vfunc != NULL) && (vfunc(snmptoolctx, pdu, obj) < 0)) {
+ nbindings = -1;
+ break;
+ }
+ if ((abind = afunc(pdu, obj)) < 0) {
+ nbindings = -1;
+ break;
+ }
+
+ if (abind > 0) {
+ /* Do not put more varbindings than requested. */
+ if (++nbindings >= maxcount)
+ break;
+ }
+ }
+
+ return (nbindings);
+}
+
+/*
+ * Locate an object in the object list and set a corresponding error status.
+ */
+int32_t
+snmp_object_seterror(struct snmp_toolinfo *snmptoolctx,
+ struct snmp_value *err_value, int32_t error_status)
+{
+ struct snmp_object *obj;
+
+ if (SLIST_EMPTY(&snmptoolctx->snmp_objectlist) || err_value == NULL)
+ return (-1);
+
+ SLIST_FOREACH(obj, &snmptoolctx->snmp_objectlist, link)
+ if (asn_compare_oid(&(err_value->var), &(obj->val.var)) == 0) {
+ obj->error = error_status;
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * Check a PDU received in responce to a SNMP_PDU_GET/SNMP_PDU_GETBULK request
+ * but don't compare syntaxes - when sending a request PDU they must be null.
+ * This is a (almost) complete copy of snmp_pdu_check() - with matching syntaxes
+ * checks and some other checks skiped.
+ */
+int32_t
+snmp_parse_get_resp(struct snmp_pdu *resp, struct snmp_pdu *req)
+{
+ uint32_t i;
+
+ for (i = 0; i < req->nbindings; i++) {
+ if (asn_compare_oid(&req->bindings[i].var,
+ &resp->bindings[i].var) != 0) {
+ warnx("Bad OID in response");
+ return (-1);
+ }
+
+ if (snmp_client.version != SNMP_V1 && (resp->bindings[i].syntax
+ == SNMP_SYNTAX_NOSUCHOBJECT || resp->bindings[i].syntax ==
+ SNMP_SYNTAX_NOSUCHINSTANCE))
+ return (0);
+ }
+
+ return (1);
+}
+
+int32_t
+snmp_parse_getbulk_resp(struct snmp_pdu *resp, struct snmp_pdu *req)
+{
+ int32_t N, R, M, r;
+
+ if (req->error_status > (int32_t) resp->nbindings) {
+ warnx("Bad number of bindings in response");
+ return (-1);
+ }
+
+ for (N = 0; N < req->error_status; N++) {
+ if (asn_is_suboid(&req->bindings[N].var,
+ &resp->bindings[N].var) == 0)
+ return (0);
+ if (resp->bindings[N].syntax == SNMP_SYNTAX_ENDOFMIBVIEW)
+ return (0);
+ }
+
+ for (R = N , r = N; R < (int32_t) req->nbindings; R++) {
+ for (M = 0; M < req->error_index && (r + M) <
+ (int32_t) resp->nbindings; M++) {
+ if (asn_is_suboid(&req->bindings[R].var,
+ &resp->bindings[r + M].var) == 0)
+ return (0);
+
+ if (resp->bindings[r + M].syntax ==
+ SNMP_SYNTAX_ENDOFMIBVIEW) {
+ M++;
+ break;
+ }
+ }
+ r += M;
+ }
+
+ return (0);
+}
+
+int32_t
+snmp_parse_getnext_resp(struct snmp_pdu *resp, struct snmp_pdu *req)
+{
+ uint32_t i;
+
+ for (i = 0; i < req->nbindings; i++) {
+ if (asn_is_suboid(&req->bindings[i].var, &resp->bindings[i].var)
+ == 0)
+ return (0);
+
+ if (resp->version != SNMP_V1 && resp->bindings[i].syntax ==
+ SNMP_SYNTAX_ENDOFMIBVIEW)
+ return (0);
+ }
+
+ return (1);
+}
+
+/*
+ * Should be called to check a responce to get/getnext/getbulk.
+ */
+int32_t
+snmp_parse_resp(struct snmp_pdu *resp, struct snmp_pdu *req)
+{
+ if (resp == NULL || req == NULL)
+ return (-2);
+
+ if (resp->version != req->version) {
+ warnx("Response has wrong version");
+ return (-1);
+ }
+
+ if (resp->error_status == SNMP_ERR_NOSUCHNAME) {
+ warnx("Error - No Such Name");
+ return (0);
+ }
+
+ if (resp->error_status != SNMP_ERR_NOERROR) {
+ warnx("Error %d in responce", resp->error_status);
+ return (-1);
+ }
+
+ if (resp->nbindings != req->nbindings && req->type != SNMP_PDU_GETBULK){
+ warnx("Bad number of bindings in response");
+ return (-1);
+ }
+
+ switch (req->type) {
+ case SNMP_PDU_GET:
+ return (snmp_parse_get_resp(resp,req));
+ case SNMP_PDU_GETBULK:
+ return (snmp_parse_getbulk_resp(resp,req));
+ case SNMP_PDU_GETNEXT:
+ return (snmp_parse_getnext_resp(resp,req));
+ default:
+ /* NOTREACHED */
+ break;
+ }
+
+ return (-2);
+}
+
+static void
+snmp_output_octetstring(struct snmp_toolinfo *snmptoolctx, enum snmp_tc tc,
+ uint32_t len, uint8_t *octets)
+{
+ char *buf;
+
+ if (len == 0 || octets == NULL)
+ return;
+
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_OCTETSTRING].str);
+
+ if ((buf = snmp_oct2tc(tc, len, (char *) octets)) != NULL) {
+ fprintf(stdout, "%s", buf);
+ free(buf);
+ }
+}
+
+static void
+snmp_output_octetindex(struct snmp_toolinfo *snmptoolctx, enum snmp_tc tc,
+ struct asn_oid *oid)
+{
+ uint32_t i;
+ uint8_t *s;
+
+ if ((s = malloc(oid->subs[0] + 1)) == NULL)
+ syslog(LOG_ERR, "malloc failed - %s", strerror(errno));
+ else {
+ for (i = 0; i < oid->subs[0]; i++)
+ s[i] = (u_char) (oid->subs[i + 1]);
+
+ snmp_output_octetstring(snmptoolctx, tc, oid->subs[0], s);
+ free(s);
+ }
+}
+
+/*
+ * Check and output syntax type and value.
+ */
+static void
+snmp_output_oid_value(struct snmp_toolinfo *snmptoolctx, struct asn_oid *oid)
+{
+ char oid_string[ASN_OIDSTRLEN];
+ struct snmp_object obj;
+
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ", syntax_strings[SNMP_SYNTAX_OID].str);
+
+ if(!ISSET_NUMERIC(snmptoolctx)) {
+ memset(&obj, 0, sizeof(struct snmp_object));
+ asn_append_oid(&(obj.val.var), oid);
+
+ if (snmp_lookup_enumstring(snmptoolctx, &obj) > 0)
+ fprintf(stdout, "%s" , obj.info->string);
+ else if (snmp_lookup_oidstring(snmptoolctx, &obj) > 0)
+ fprintf(stdout, "%s" , obj.info->string);
+ else if (snmp_lookup_nodestring(snmptoolctx, &obj) > 0)
+ fprintf(stdout, "%s" , obj.info->string);
+ else {
+ (void) asn_oid2str_r(oid, oid_string);
+ fprintf(stdout, "%s", oid_string);
+ }
+ } else {
+ (void) asn_oid2str_r(oid, oid_string);
+ fprintf(stdout, "%s", oid_string);
+ }
+}
+
+static void
+snmp_output_int(struct snmp_toolinfo *snmptoolctx, struct enum_pairs *enums,
+ int32_t int_val)
+{
+ char *string;
+
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_INTEGER].str);
+
+ if (enums != NULL && (string = enum_string_lookup(enums, int_val))
+ != NULL)
+ fprintf(stdout, "%s", string);
+ else
+ fprintf(stdout, "%d", int_val);
+}
+
+static void
+snmp_output_ipaddress(struct snmp_toolinfo *snmptoolctx, uint8_t *ip)
+{
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_IPADDRESS].str);
+
+ fprintf(stdout, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
+}
+
+static void
+snmp_output_counter(struct snmp_toolinfo *snmptoolctx, uint32_t counter)
+{
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_COUNTER].str);
+
+ fprintf(stdout, "%u", counter);
+}
+
+static void
+snmp_output_gauge(struct snmp_toolinfo *snmptoolctx, uint32_t gauge)
+{
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ", syntax_strings[SNMP_SYNTAX_GAUGE].str);
+
+ fprintf(stdout, "%u", gauge);
+}
+
+static void
+snmp_output_ticks(struct snmp_toolinfo *snmptoolctx, uint32_t ticks)
+{
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_TIMETICKS].str);
+
+ fprintf(stdout, "%u", ticks);
+}
+
+static void
+snmp_output_counter64(struct snmp_toolinfo *snmptoolctx, uint64_t counter64)
+{
+ if (GET_OUTPUT(snmptoolctx) == OUTPUT_VERBOSE)
+ fprintf(stdout, "%s : ",
+ syntax_strings[SNMP_SYNTAX_COUNTER64].str);
+
+ fprintf(stdout,"%ju", counter64);
+}
+
+int32_t
+snmp_output_numval(struct snmp_toolinfo *snmptoolctx, struct snmp_value *val,
+ struct snmp_oid2str *entry)
+{
+ if (val == NULL)
+ return (-1);
+
+ if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET)
+ fprintf(stdout, " = ");
+
+ switch (val->syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ if (entry != NULL)
+ snmp_output_int(snmptoolctx, entry->snmp_enum,
+ val->v.integer);
+ else
+ snmp_output_int(snmptoolctx, NULL, val->v.integer);
+ break;
+
+ case SNMP_SYNTAX_OCTETSTRING:
+ if (entry != NULL)
+ snmp_output_octetstring(snmptoolctx, entry->tc,
+ val->v.octetstring.len, val->v.octetstring.octets);
+ else
+ snmp_output_octetstring(snmptoolctx, SNMP_STRING,
+ val->v.octetstring.len, val->v.octetstring.octets);
+ break;
+
+ case SNMP_SYNTAX_OID:
+ snmp_output_oid_value(snmptoolctx, &(val->v.oid));
+ break;
+
+ case SNMP_SYNTAX_IPADDRESS:
+ snmp_output_ipaddress(snmptoolctx, val->v.ipaddress);
+ break;
+
+ case SNMP_SYNTAX_COUNTER:
+ snmp_output_counter(snmptoolctx, val->v.uint32);
+ break;
+
+ case SNMP_SYNTAX_GAUGE:
+ snmp_output_gauge(snmptoolctx, val->v.uint32);
+ break;
+
+ case SNMP_SYNTAX_TIMETICKS:
+ snmp_output_ticks(snmptoolctx, val->v.uint32);
+ break;
+
+ case SNMP_SYNTAX_COUNTER64:
+ snmp_output_counter64(snmptoolctx, val->v.counter64);
+ break;
+
+ case SNMP_SYNTAX_NOSUCHOBJECT:
+ fprintf(stdout, "No Such Object\n");
+ return (val->syntax);
+
+ case SNMP_SYNTAX_NOSUCHINSTANCE:
+ fprintf(stdout, "No Such Instance\n");
+ return (val->syntax);
+
+ case SNMP_SYNTAX_ENDOFMIBVIEW:
+ fprintf(stdout, "End of Mib View\n");
+ return (val->syntax);
+
+ case SNMP_SYNTAX_NULL:
+ /* NOTREACHED */
+ fprintf(stdout, "agent returned NULL Syntax\n");
+ return (val->syntax);
+
+ default:
+ /* NOTREACHED - If here - then all went completely wrong. */
+ fprintf(stdout, "agent returned unknown syntax\n");
+ return (-1);
+ }
+
+ fprintf(stdout, "\n");
+
+ return (0);
+}
+
+static int32_t
+snmp_fill_object(struct snmp_toolinfo *snmptoolctx, struct snmp_object *obj,
+ struct snmp_value *val)
+{
+ int32_t rc;
+ asn_subid_t suboid;
+
+ if (obj == NULL || val == NULL)
+ return (-1);
+
+ if ((suboid = snmp_suboid_pop(&(val->var))) > ASN_MAXID)
+ return (-1);
+
+ memset(obj, 0, sizeof(struct snmp_object));
+ asn_append_oid(&(obj->val.var), &(val->var));
+ obj->val.syntax = val->syntax;
+
+ if (obj->val.syntax > 0)
+ rc = snmp_lookup_leafstring(snmptoolctx, obj);
+ else
+ rc = snmp_lookup_nonleaf_string(snmptoolctx, obj);
+
+ (void) snmp_suboid_append(&(val->var), suboid);
+ (void) snmp_suboid_append(&(obj->val.var), suboid);
+
+ return (rc);
+}
+
+static int32_t
+snmp_output_index(struct snmp_toolinfo *snmptoolctx, struct index *stx,
+ struct asn_oid *oid)
+{
+ uint8_t ip[4];
+ uint32_t bytes = 1;
+ uint64_t cnt64;
+ struct asn_oid temp, out;
+
+ if (oid->len < bytes)
+ return (-1);
+
+ memset(&temp, 0, sizeof(struct asn_oid));
+ asn_append_oid(&temp, oid);
+
+ switch (stx->syntax) {
+ case SNMP_SYNTAX_INTEGER:
+ snmp_output_int(snmptoolctx, stx->snmp_enum, temp.subs[0]);
+ break;
+
+ case SNMP_SYNTAX_OCTETSTRING:
+ if ((temp.subs[0] > temp.len -1 ) || (temp.subs[0] >
+ ASN_MAXOCTETSTRING))
+ return (-1);
+ snmp_output_octetindex(snmptoolctx, stx->tc, &temp);
+ bytes += temp.subs[0];
+ break;
+
+ case SNMP_SYNTAX_OID:
+ if ((temp.subs[0] > temp.len -1) || (temp.subs[0] >
+ ASN_MAXOIDLEN))
+ return (-1);
+
+ bytes += temp.subs[0];
+ memset(&out, 0, sizeof(struct asn_oid));
+ asn_slice_oid(&out, &temp, 1, bytes);
+ snmp_output_oid_value(snmptoolctx, &out);
+ break;
+
+ case SNMP_SYNTAX_IPADDRESS:
+ if (temp.len < 4)
+ return (-1);
+ for (bytes = 0; bytes < 4; bytes++)
+ ip[bytes] = temp.subs[bytes];
+
+ snmp_output_ipaddress(snmptoolctx, ip);
+ bytes = 4;
+ break;
+
+ case SNMP_SYNTAX_COUNTER:
+ snmp_output_counter(snmptoolctx, temp.subs[0]);
+ break;
+
+ case SNMP_SYNTAX_GAUGE:
+ snmp_output_gauge(snmptoolctx, temp.subs[0]);
+ break;
+
+ case SNMP_SYNTAX_TIMETICKS:
+ snmp_output_ticks(snmptoolctx, temp.subs[0]);
+ break;
+
+ case SNMP_SYNTAX_COUNTER64:
+ if (oid->len < 2)
+ return (-1);
+ bytes = 2;
+ memcpy(&cnt64, temp.subs, bytes);
+ snmp_output_counter64(snmptoolctx, cnt64);
+ break;
+
+ default:
+ return (-1);
+ }
+
+ return (bytes);
+}
+
+static int32_t
+snmp_output_object(struct snmp_toolinfo *snmptoolctx, struct snmp_object *o)
+{
+ int32_t i, first, len;
+ struct asn_oid oid;
+ struct index *temp;
+
+ if (ISSET_NUMERIC(snmptoolctx))
+ return (-1);
+
+ if (o->info->table_idx == NULL) {
+ fprintf(stdout,"%s.%d", o->info->string,
+ o->val.var.subs[o->val.var.len - 1]);
+ return (1);
+ }
+
+ fprintf(stdout,"%s[", o->info->string);
+ memset(&oid, 0, sizeof(struct asn_oid));
+
+ len = 1;
+ asn_slice_oid(&oid, &(o->val.var), (o->info->table_idx->var.len + len),
+ o->val.var.len);
+
+ first = 1;
+ STAILQ_FOREACH(temp, &(OBJECT_IDX_LIST(o)), link) {
+ if(first)
+ first = 0;
+ else
+ fprintf(stdout, ", ");
+ if ((i = snmp_output_index(snmptoolctx, temp, &oid)) < 0)
+ break;
+ len += i;
+ memset(&oid, 0, sizeof(struct asn_oid));
+ asn_slice_oid(&oid, &(o->val.var),
+ (o->info->table_idx->var.len + len), o->val.var.len + 1);
+ }
+
+ fprintf(stdout,"]");
+ return (1);
+}
+
+void
+snmp_output_err_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu)
+{
+ char buf[ASN_OIDSTRLEN];
+ struct snmp_object object;
+
+ if (pdu == NULL || (pdu->error_index > (int32_t) pdu->nbindings)) {
+ fprintf(stdout,"Invalid error index in PDU\n");
+ return;
+ }
+
+ fprintf(stdout, "Agent %s:%s returned error \n", snmp_client.chost,
+ snmp_client.cport);
+
+ if (!ISSET_NUMERIC(snmptoolctx) && (snmp_fill_object(snmptoolctx, &object,
+ &(pdu->bindings[pdu->error_index - 1])) > 0))
+ snmp_output_object(snmptoolctx, &object);
+ else {
+ asn_oid2str_r(&(pdu->bindings[pdu->error_index - 1].var), buf);
+ fprintf(stdout,"%s", buf);
+ }
+
+ fprintf(stdout," caused error - ");
+ if ((pdu->error_status > 0) && (pdu->error_status <=
+ SNMP_ERR_INCONS_NAME))
+ fprintf(stdout, "%s\n", error_strings[pdu->error_status].str);
+ else
+ fprintf(stdout,"%s\n", error_strings[SNMP_ERR_UNKNOWN].str);
+}
+
+int32_t
+snmp_output_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu)
+{
+ int32_t error;
+ char p[ASN_OIDSTRLEN];
+ uint32_t i;
+ struct snmp_object object;
+
+ for (i = 0, error = 0; i < pdu->nbindings; i++) {
+ if (GET_OUTPUT(snmptoolctx) != OUTPUT_QUIET) {
+ if (!ISSET_NUMERIC(snmptoolctx) &&
+ (snmp_fill_object(snmptoolctx, &object,
+ &(pdu->bindings[i])) > 0))
+ snmp_output_object(snmptoolctx, &object);
+ else {
+ asn_oid2str_r(&(pdu->bindings[i].var), p);
+ fprintf(stdout, "%s", p);
+ }
+ }
+ error |= snmp_output_numval(snmptoolctx, &(pdu->bindings[i]), object.info);
+ }
+
+ return (error);
+}
+
+void
+snmp_output_engine(void)
+{
+ uint32_t i;
+ char *cptr, engine[2 * SNMP_ENGINE_ID_SIZ + 2];
+
+ cptr = engine;
+ for (i = 0; i < snmp_client.engine.engine_len; i++)
+ cptr += sprintf(cptr, "%.2x", snmp_client.engine.engine_id[i]);
+ *cptr++ = '\0';
+
+ fprintf(stdout, "Engine ID 0x%s\n", engine);
+ fprintf(stdout, "Boots : %u\t\tTime : %d\n",
+ snmp_client.engine.engine_boots,
+ snmp_client.engine.engine_time);
+}
+
+void
+snmp_output_keys(void)
+{
+ uint32_t i, keylen = 0;
+ char *cptr, extkey[2 * SNMP_AUTH_KEY_SIZ + 2];
+
+ fprintf(stdout, "Localized keys for %s\n", snmp_client.user.sec_name);
+ if (snmp_client.user.auth_proto == SNMP_AUTH_HMAC_MD5) {
+ fprintf(stdout, "MD5 : 0x");
+ keylen = SNMP_AUTH_HMACMD5_KEY_SIZ;
+ } else if (snmp_client.user.auth_proto == SNMP_AUTH_HMAC_SHA) {
+ fprintf(stdout, "SHA : 0x");
+ keylen = SNMP_AUTH_HMACSHA_KEY_SIZ;
+ }
+ if (snmp_client.user.auth_proto != SNMP_AUTH_NOAUTH) {
+ cptr = extkey;
+ for (i = 0; i < keylen; i++)
+ cptr += sprintf(cptr, "%.2x",
+ snmp_client.user.auth_key[i]);
+ *cptr++ = '\0';
+ fprintf(stdout, "%s\n", extkey);
+ }
+
+ if (snmp_client.user.priv_proto == SNMP_PRIV_DES) {
+ fprintf(stdout, "DES : 0x");
+ keylen = SNMP_PRIV_DES_KEY_SIZ;
+ } else if (snmp_client.user.priv_proto == SNMP_PRIV_AES) {
+ fprintf(stdout, "AES : 0x");
+ keylen = SNMP_PRIV_AES_KEY_SIZ;
+ }
+ if (snmp_client.user.priv_proto != SNMP_PRIV_NOPRIV) {
+ cptr = extkey;
+ for (i = 0; i < keylen; i++)
+ cptr += sprintf(cptr, "%.2x",
+ snmp_client.user.priv_key[i]);
+ *cptr++ = '\0';
+ fprintf(stdout, "%s\n", extkey);
+ }
+}
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
new file mode 100644
index 0000000..6e62186
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.h
@@ -0,0 +1,331 @@
+/*-
+ * Copyright (c) 2005-2006 The FreeBSD Project
+ * All rights reserved.
+ *
+ * Author: Shteryana Shopova <syrinx@FreeBSD.org>
+ *
+ * Redistribution of this software and documentation and use in source and
+ * binary forms, with or without modification, are permitted provided that
+ * the following conditions are met:
+ *
+ * 1. Redistributions of source code or documentation must retain the above
+ * copyright notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Helper functions common for all tools.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BSNMP_TOOLS_H_
+#define _BSNMP_TOOLS_H_
+
+/* From asn1.h + 1 byte for trailing zero. */
+#define MAX_OCTSTRING_LEN ASN_MAXOCTETSTRING + 1
+#define MAX_CMD_SYNTAX_LEN 12
+
+/* Arbitrary upper limit on node names and function names - gensnmptree.c. */
+#define MAXSTR 1000
+
+/* Should be enough to fetch the biggest allowed octet string. */
+#define MAX_BUFF_SIZE (ASN_MAXOCTETSTRING + 50)
+
+#define SNMP_DEFS_DIR "/usr/share/snmp/defs/"
+#define SNMP_DEFAULT_LOCAL "/var/run/snmpd.sock"
+
+enum snmp_access {
+ SNMP_ACCESS_NONE = 0,
+ SNMP_ACCESS_GET,
+ SNMP_ACCESS_SET,
+ SNMP_ACCESS_GETSET,
+};
+
+/* A structure for integer-string enumerations. */
+struct enum_pair {
+ int32_t enum_val;
+ char *enum_str;
+ STAILQ_ENTRY(enum_pair) link;
+};
+
+STAILQ_HEAD(enum_pairs, enum_pair);
+
+struct enum_type {
+ char *name;
+ uint32_t syntax;
+ int32_t is_enum;
+ int32_t is_bits;
+ struct enum_pairs *snmp_enum;
+ SLIST_ENTRY(enum_type) link;
+};
+
+SLIST_HEAD(snmp_enum_tc, enum_type);
+
+struct index {
+ enum snmp_tc tc;
+ enum snmp_syntax syntax;
+ struct enum_pairs *snmp_enum;
+ STAILQ_ENTRY(index) link;
+};
+
+STAILQ_HEAD(snmp_idxlist, index);
+
+struct snmp_index_entry {
+ char *string;
+ uint32_t strlen;
+ struct asn_oid var;
+ struct snmp_idxlist index_list;
+ SLIST_ENTRY(snmp_index_entry) link;
+};
+
+/* Information needed for oid to string conversion. */
+struct snmp_oid2str {
+ char *string;
+ uint32_t strlen;
+ enum snmp_tc tc;
+ enum snmp_syntax syntax;
+ enum snmp_access access;
+ struct asn_oid var;
+ /* A pointer to a entry from the table list - OK if NULL. */
+ struct snmp_index_entry *table_idx;
+ /*
+ * A singly-linked tail queue of all (int, string) pairs -
+ * for INTEGER syntax only.
+ */
+ struct enum_pairs *snmp_enum;
+ SLIST_ENTRY(snmp_oid2str) link;
+};
+
+/* A structure to hold each oid input by user. */
+struct snmp_object {
+ /* Flag - if set, the variable caused error in a previous request. */
+ int32_t error;
+ /*
+ * A pointer in the mapping lists - not used if OIDs are input as
+ * numericals.
+ */
+ struct snmp_oid2str *info;
+ /* A snmp value to hold the actual oid, syntax and value. */
+ struct snmp_value val;
+ SLIST_ENTRY(snmp_object) link;
+};
+
+struct fname {
+ char *name;
+ int32_t done;
+ struct asn_oid cut;
+ SLIST_ENTRY(fname) link;
+};
+
+SLIST_HEAD(snmp_mapping, snmp_oid2str);
+SLIST_HEAD(fname_list, fname);
+SLIST_HEAD(snmp_table_index, snmp_index_entry);
+
+/*
+ * Keep a list for every syntax type.
+ */
+struct snmp_mappings {
+ /* The list containing all non-leaf nodes. */
+ struct snmp_mapping nodelist;
+ /* INTEGER/INTEGER32 types. */
+ struct snmp_mapping intlist;
+ /* OCTETSTRING types. */
+ struct snmp_mapping octlist;
+ /* OID types. */
+ struct snmp_mapping oidlist;
+ /* IPADDRESS types. */
+ struct snmp_mapping iplist;
+ /* TIMETICKS types. */
+ struct snmp_mapping ticklist;
+ /* COUNTER types. */
+ struct snmp_mapping cntlist;
+ /* GAUGE types. */
+ struct snmp_mapping gaugelist;
+ /* COUNTER64 types. */
+ struct snmp_mapping cnt64list;
+ /* ENUM values for oid types. */
+ struct snmp_mapping enumlist;
+ /* Description of all table entry types. */
+ struct snmp_table_index tablelist;
+ /* Defined enumerated textual conventions. */
+ struct snmp_enum_tc tclist;
+};
+
+struct snmp_toolinfo {
+ uint32_t flags;
+ /* Number of initially input OIDs. */
+ int32_t objects;
+ /* List of all input OIDs. */
+ SLIST_HEAD(snmp_objectlist, snmp_object) snmp_objectlist;
+ /* All known OID to string mapping data. */
+ struct snmp_mappings *mappings;
+ /* A list of .defs filenames to search oid<->string mapping. */
+ struct fname_list filelist;
+ /* SNMPv3 USM user credentials */
+ char *passwd;
+};
+
+/* XXX we might want to get away with this and will need to touch
+ * XXX the MACROS then too */
+extern struct snmp_toolinfo snmptool;
+
+/* Definitions for some flags' bits. */
+#define OUTPUT_BITS 0x00000003 /* bits 0-1 for output type */
+#define NUMERIC_BIT 0x00000004 /* bit 2 for numeric oids */
+#define RETRY_BIT 0x00000008 /* bit 3 for retry on error responce */
+#define ERRIGNORE_BIT 0x00000010 /* bit 4 for skip sanity checking */
+#define ERRIGNORE_BIT 0x00000010 /* bit 4 for skip sanity checking */
+#define EDISCOVER_BIT 0x00000020 /* bit 5 for SNMP Engine Discovery */
+#define LOCALKEY_BIT 0x00000040 /* bit 6 for using localized key */
+ /* 0x00000080 */ /* bit 7 reserverd */
+#define PDUTYPE_BITS 0x00000f00 /* bits 8-11 for pdu type */
+ /* 0x0000f000 */ /* bit 12-15 reserverd */
+#define MAXREP_BITS 0x00ff0000 /* bits 16-23 for max-repetit. value */
+#define NONREP_BITS 0xff000000 /* bits 24-31 for non-repeaters value */
+
+#define OUTPUT_SHORT 0x0
+#define OUTPUT_VERBOSE 0x1
+#define OUTPUT_TABULAR 0x2
+#define OUTPUT_QUIET 0x3
+
+/* Macros for playing with flags' bits. */
+#define SET_OUTPUT(ctx, type) ((ctx)->flags |= ((type) & OUTPUT_BITS))
+#define GET_OUTPUT(ctx) ((ctx)->flags & OUTPUT_BITS)
+
+#define SET_NUMERIC(ctx) ((ctx)->flags |= NUMERIC_BIT)
+#define ISSET_NUMERIC(ctx) ((ctx)->flags & NUMERIC_BIT)
+
+#define SET_RETRY(ctx) ((ctx)->flags |= RETRY_BIT)
+#define ISSET_RETRY(ctx) ((ctx)->flags & RETRY_BIT)
+
+#define SET_ERRIGNORE(ctx) ((ctx)->flags |= ERRIGNORE_BIT)
+#define ISSET_ERRIGNORE(ctx) ((ctx)->flags & ERRIGNORE_BIT)
+
+#define SET_EDISCOVER(ctx) ((ctx)->flags |= EDISCOVER_BIT)
+#define ISSET_EDISCOVER(ctx) ((ctx)->flags & EDISCOVER_BIT)
+
+#define SET_LOCALKEY(ctx) ((ctx)->flags |= LOCALKEY_BIT)
+#define ISSET_LOCALKEY(ctx) ((ctx)->flags & LOCALKEY_BIT)
+
+#define SET_PDUTYPE(ctx, type) (((ctx)->flags |= (((type) & 0xf) << 8)))
+#define GET_PDUTYPE(ctx) (((ctx)->flags & PDUTYPE_BITS) >> 8)
+
+#define SET_MAXREP(ctx, i) (((ctx)->flags |= (((i) & 0xff) << 16)))
+#define GET_MAXREP(ctx) (((ctx)->flags & MAXREP_BITS) >> 16)
+
+#define SET_NONREP(ctx, i) (((ctx)->flags |= (((i) & 0xff) << 24)))
+#define GET_NONREP(ctx) (((ctx)->flags & NONREP_BITS) >> 24)
+
+
+extern const struct asn_oid IsoOrgDod_OID;
+
+int snmptool_init(struct snmp_toolinfo *);
+int32_t snmp_import_file(struct snmp_toolinfo *, struct fname *);
+int32_t snmp_import_all(struct snmp_toolinfo *);
+int32_t add_filename(struct snmp_toolinfo *, const char *,
+ const struct asn_oid *, int32_t);
+void free_filelist(struct snmp_toolinfo *);
+void snmp_tool_freeall(struct snmp_toolinfo *);
+void snmp_import_dump(int);
+
+/* bsnmpmap.c */
+struct snmp_mappings *snmp_mapping_init(void);
+int32_t snmp_mapping_free(struct snmp_toolinfo *);
+void snmp_index_listfree(struct snmp_idxlist *);
+void snmp_dump_oid2str(struct snmp_oid2str *);
+int32_t snmp_node_insert(struct snmp_toolinfo *, struct snmp_oid2str *);
+int32_t snmp_leaf_insert(struct snmp_toolinfo *, struct snmp_oid2str *);
+int32_t snmp_enum_insert(struct snmp_toolinfo *, struct snmp_oid2str *);
+struct enum_pairs *enum_pairs_init(void);
+void enum_pairs_free(struct enum_pairs *);
+void snmp_mapping_entryfree(struct snmp_oid2str *);
+int32_t enum_pair_insert(struct enum_pairs *, int32_t, char *);
+char *enum_string_lookup(struct enum_pairs *, int32_t);
+int32_t enum_number_lookup(struct enum_pairs *, char *);
+int32_t snmp_syntax_insert(struct snmp_idxlist *, struct enum_pairs *,
+ enum snmp_syntax, enum snmp_tc);
+int32_t snmp_table_insert(struct snmp_toolinfo *, struct snmp_index_entry *);
+
+struct enum_type *snmp_enumtc_init(char *);
+void snmp_enumtc_free(struct enum_type *);
+void snmp_enumtc_insert(struct snmp_toolinfo *, struct enum_type *);
+struct enum_type *snmp_enumtc_lookup(struct snmp_toolinfo *, char *);
+
+void snmp_mapping_dump(struct snmp_toolinfo *);
+int32_t snmp_lookup_leafstring(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_enumstring(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_oidstring(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_nonleaf_string(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_allstring(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_nodestring(struct snmp_toolinfo *, struct snmp_object *);
+int32_t snmp_lookup_oidall(struct snmp_toolinfo *, struct snmp_object *, char *);
+int32_t snmp_lookup_enumoid(struct snmp_toolinfo *, struct snmp_object *, char *);
+int32_t snmp_lookup_oid(struct snmp_toolinfo *, struct snmp_object *, char *);
+
+/* Functions parsing common options for all tools. */
+int32_t parse_server(char *);
+int32_t parse_timeout(char *);
+int32_t parse_retry(char *);
+int32_t parse_version(char *);
+int32_t parse_local_path(char *);
+int32_t parse_buflen(char *);
+int32_t parse_debug(void);
+int32_t parse_discovery(struct snmp_toolinfo *);
+int32_t parse_local_key(struct snmp_toolinfo *);
+int32_t parse_num_oids(struct snmp_toolinfo *);
+int32_t parse_file(struct snmp_toolinfo *, char *);
+int32_t parse_include(struct snmp_toolinfo *, char *);
+int32_t parse_output(struct snmp_toolinfo *, char *);
+int32_t parse_errors(struct snmp_toolinfo *);
+int32_t parse_skip_access(struct snmp_toolinfo *);
+int32_t parse_authentication(struct snmp_toolinfo *, char *);
+int32_t parse_privacy(struct snmp_toolinfo *, char *);
+int32_t parse_context(struct snmp_toolinfo *, char *);
+int32_t parse_user_security(struct snmp_toolinfo *, char *);
+
+typedef int32_t (*snmp_verify_inoid_f) (struct snmp_toolinfo *,
+ struct snmp_object *, char *);
+int32_t snmp_object_add(struct snmp_toolinfo *, snmp_verify_inoid_f, char *);
+int32_t snmp_object_remove(struct snmp_toolinfo *, struct asn_oid *oid);
+int32_t snmp_object_seterror(struct snmp_toolinfo *, struct snmp_value *,
+ int32_t);
+
+enum snmp_syntax parse_syntax(char *);
+char *snmp_parse_suboid(char *, struct asn_oid *);
+char *snmp_parse_index(struct snmp_toolinfo *, char *, struct snmp_object *);
+int32_t snmp_parse_numoid(char *, struct asn_oid *);
+int32_t snmp_suboid_append(struct asn_oid *, asn_subid_t);
+int32_t snmp_suboid_pop(struct asn_oid *);
+
+typedef int32_t (*snmp_verify_vbind_f) (struct snmp_toolinfo *,
+ struct snmp_pdu *, struct snmp_object *);
+typedef int32_t (*snmp_add_vbind_f) (struct snmp_pdu *, struct snmp_object *);
+int32_t snmp_pdu_add_bindings(struct snmp_toolinfo *, snmp_verify_vbind_f,
+ snmp_add_vbind_f, struct snmp_pdu *, int32_t);
+
+int32_t snmp_parse_get_resp(struct snmp_pdu *, struct snmp_pdu *);
+int32_t snmp_parse_getbulk_resp(struct snmp_pdu *, struct snmp_pdu *);
+int32_t snmp_parse_getnext_resp(struct snmp_pdu *, struct snmp_pdu *);
+int32_t snmp_parse_resp(struct snmp_pdu *, struct snmp_pdu *);
+int32_t snmp_output_numval(struct snmp_toolinfo *, struct snmp_value *,
+ struct snmp_oid2str *);
+void snmp_output_val(struct snmp_value *);
+int32_t snmp_output_resp(struct snmp_toolinfo *, struct snmp_pdu *);
+void snmp_output_err_resp(struct snmp_toolinfo *, struct snmp_pdu *);
+void snmp_output_engine(void);
+void snmp_output_keys(void);
+
+#endif /* _BSNMP_TOOLS_H_ */
diff --git a/usr.sbin/cxgbtool/cxgbtool.c b/usr.sbin/cxgbtool/cxgbtool.c
index b705ff8..f73f1a4 100644
--- a/usr.sbin/cxgbtool/cxgbtool.c
+++ b/usr.sbin/cxgbtool/cxgbtool.c
@@ -1014,6 +1014,8 @@ load_fw(int argc, char *argv[], int start_arg, const char *iff_name)
op.len = len;
if (doit(iff_name, CHELSIO_LOAD_FW, &op) < 0)
err(1, "load firmware");
+
+ close(fd);
return 0;
}
@@ -1048,6 +1050,7 @@ load_boot(int argc, char *argv[], int start_arg, const char *iff_name)
if (doit(iff_name, CHELSIO_LOAD_BOOT, &op) < 0)
err(1, "load boot image");
+ close(fd);
return 0;
}
diff --git a/usr.sbin/extattrctl/extattrctl.c b/usr.sbin/extattrctl/extattrctl.c
index 1929f79..377d3ba 100644
--- a/usr.sbin/extattrctl/extattrctl.c
+++ b/usr.sbin/extattrctl/extattrctl.c
@@ -144,9 +144,11 @@ initattr(int argc, char *argv[])
if (error == -1) {
perror(argv[1]);
unlink(argv[1]);
+ close(i);
return (-1);
}
+ close(i);
return (0);
}
@@ -168,21 +170,25 @@ showattr(int argc, char *argv[])
i = read(fd, &uef, sizeof(uef));
if (i == -1) {
perror(argv[0]);
+ close(fd);
return (-1);
}
if (i != sizeof(uef)) {
fprintf(stderr, "%s: invalid file header\n", argv[0]);
+ close(fd);
return (-1);
}
if (uef.uef_magic != UFS_EXTATTR_MAGIC) {
fprintf(stderr, "%s: bad magic\n", argv[0]);
+ close(fd);
return (-1);
}
printf("%s: version %d, size %d\n", argv[0], uef.uef_version,
uef.uef_size);
+ close(fd);
return (0);
}
diff --git a/usr.sbin/fifolog/lib/fifolog_write.h b/usr.sbin/fifolog/lib/fifolog_write.h
index 06b3233..22a307d 100644
--- a/usr.sbin/fifolog/lib/fifolog_write.h
+++ b/usr.sbin/fifolog/lib/fifolog_write.h
@@ -44,8 +44,6 @@ struct fifolog_writer {
unsigned syncrate;
unsigned compression;
- unsigned writes_since_sync;
-
int cleanup;
intmax_t cnt[FIFOLOG_NPOINT];
@@ -55,9 +53,11 @@ struct fifolog_writer {
int flag;
time_t last;
+ u_int obufsize;
+ u_char *obuf;
+
u_int ibufsize;
u_char *ibuf;
- u_char *iptr;
time_t starttime;
time_t lastwrite;
diff --git a/usr.sbin/fifolog/lib/fifolog_write_poll.c b/usr.sbin/fifolog/lib/fifolog_write_poll.c
index 4fc5204..abb015b 100644
--- a/usr.sbin/fifolog/lib/fifolog_write_poll.c
+++ b/usr.sbin/fifolog/lib/fifolog_write_poll.c
@@ -33,6 +33,9 @@
#include <unistd.h>
#include <time.h>
#include <sys/endian.h>
+#if 0
+#include <sys/uio.h>
+#endif
#include <zlib.h>
@@ -65,9 +68,8 @@ fifolog_write_assert(const struct fifolog_writer *f)
{
CHECK_OBJ_NOTNULL(f, FIFOLOG_WRITER_MAGIC);
- assert(f->iptr == f->ff->zs->next_in + f->ff->zs->avail_in);
assert(f->ff->zs->next_out + f->ff->zs->avail_out == \
- f->ff->recbuf + f->ff->recsize);
+ f->obuf + f->obufsize);
}
struct fifolog_writer *
@@ -75,8 +77,8 @@ fifolog_write_new(void)
{
struct fifolog_writer *f;
- ALLOC(&f, sizeof *f);
- f->magic = FIFOLOG_WRITER_MAGIC;
+ ALLOC_OBJ(f, FIFOLOG_WRITER_MAGIC);
+ assert(f != NULL);
return (f);
}
@@ -94,36 +96,11 @@ fifolog_write_close(struct fifolog_writer *f)
CHECK_OBJ_NOTNULL(f, FIFOLOG_WRITER_MAGIC);
fifolog_int_close(&f->ff);
free(f->ff);
- if (f->ibuf != NULL)
- free(f->ibuf);
+ if (f->obuf != NULL)
+ free(f->obuf);
free(f);
}
-static void
-fifo_prepobuf(struct fifolog_writer *f, time_t now, int flag)
-{
-
- memset(f->ff->recbuf, 0, f->ff->recsize);
- f->ff->zs->next_out = f->ff->recbuf + 5;
- f->ff->zs->avail_out = f->ff->recsize - 5;
- if (f->recno == 0 && f->seq == 0) {
- srandomdev();
- do {
- f->seq = random();
- } while (f->seq == 0);
- }
- be32enc(f->ff->recbuf, f->seq++);
- f->ff->recbuf[4] = f->flag;
- f->flag = 0;
- if (flag) {
- f->ff->recbuf[4] |= FIFOLOG_FLG_SYNC;
- be32enc(f->ff->recbuf + 5, (u_int)now);
- f->ff->zs->next_out += 4;
- f->ff->zs->avail_out -= 4;
- }
- fifolog_write_assert(f);
-}
-
const char *
fifolog_write_open(struct fifolog_writer *f, const char *fn, unsigned writerate, unsigned syncrate, int compression)
{
@@ -164,144 +141,154 @@ fifolog_write_open(struct fifolog_writer *f, const char *fn, unsigned writerate,
f->seq++;
}
- f->ibufsize = 32768;
- ALLOC(&f->ibuf, f->ibufsize);
- f->iptr = f->ibuf;
- f->ff->zs->next_in = f->iptr;
+ f->obufsize = f->ff->recsize;
+ ALLOC(&f->obuf, f->obufsize);
+
i = deflateInit(f->ff->zs, (int)f->compression);
assert(i == Z_OK);
f->flag |= FIFOLOG_FLG_RESTART;
+ f->flag |= FIFOLOG_FLG_SYNC;
+ f->ff->zs->next_out = f->obuf + 9;
+ f->ff->zs->avail_out = f->obufsize - 9;
time(&now);
- fifo_prepobuf(f, now, 1);
f->starttime = now;
+ f->lastsync = now;
+ f->lastwrite = now;
fifolog_write_assert(f);
return (NULL);
}
-static void
-fifo_writerec(struct fifolog_writer *f)
+static int
+fifolog_write_output(struct fifolog_writer *f, int fl, time_t now)
{
- int i;
- time_t t;
+ long h, l = f->ff->zs->next_out - f->obuf;
+ int i, w;
+
+ h = 4; /* seq */
+ be32enc(f->obuf, f->seq);
+ f->obuf[h] = f->flag;
+ h += 1; /* flag */
+ if (f->flag & FIFOLOG_FLG_SYNC) {
+ be32enc(f->obuf + h, now);
+ h += 4; /* timestamp */
+ }
- fifolog_write_assert(f);
- f->writes_since_sync++;
-
- assert(f->recno < f->ff->logsize);
- f->cnt[FIFOLOG_PT_BYTES_POST] += f->ff->recsize - f->ff->zs->avail_out;
- if (f->ff->zs->avail_out == 0) {
- /* nothing */
- } else if (f->ff->zs->avail_out <= 255) {
- f->ff->recbuf[f->ff->recsize - 1] =
- (u_char)f->ff->zs->avail_out;
- f->ff->recbuf[4] |= FIFOLOG_FLG_1BYTE;
- } else {
- be32enc(f->ff->recbuf + f->ff->recsize - 4,
- f->ff->zs->avail_out);
- f->ff->recbuf[4] |= FIFOLOG_FLG_4BYTE;
+ assert(l <= (long)f->ff->recsize);
+ assert(l >= h);
+ if (l == h)
+ return (0);
+
+
+ if (h + l < (long)f->ff->recsize && fl == Z_NO_FLUSH)
+ return (0);
+
+ w = f->ff->recsize - l;
+ if (w > 255) {
+ be32enc(f->obuf + f->ff->recsize - 4, w);
+ f->obuf[4] |= FIFOLOG_FLG_4BYTE;
+ } else if (w > 0) {
+ f->obuf[f->ff->recsize - 1] = w;
+ f->obuf[4] |= FIFOLOG_FLG_1BYTE;
}
- i = pwrite(f->ff->fd, f->ff->recbuf, f->ff->recsize,
- (f->recno + 1) * f->ff->recsize);
- assert (i == (int)f->ff->recsize);
- if (++f->recno == f->ff->logsize)
- f->recno = 0;
+
+ f->cnt[FIFOLOG_PT_BYTES_POST] += w;
+
+#ifdef DBG
+fprintf(stderr, "W: fl=%d h=%ld l=%ld w=%d recno=%jd fx %02x\n",
+ fl, h, l, w, f->recno, f->obuf[4]);
+#endif
+
+ i = pwrite(f->ff->fd, f->obuf, f->ff->recsize,
+ (f->recno + 1) * f->ff->recsize);
+ assert(i == (int)f->ff->recsize);
+
f->cnt[FIFOLOG_PT_WRITES]++;
- time(&t);
- f->cnt[FIFOLOG_PT_RUNTIME] = t - f->starttime; /*lint !e776 */
- fifolog_write_assert(f);
+
+ f->lastwrite = now;
+ f->seq++;
+ f->recno++;
+#ifdef DBG
+if (f->flag)
+fprintf(stderr, "SYNC- %d\n", __LINE__);
+#endif
+ f->flag = 0;
+
+ memset(f->obuf, 0, f->obufsize);
+ f->ff->zs->next_out = f->obuf + 5;
+ f->ff->zs->avail_out = f->obufsize - 5;
+ return (1);
}
-int
-fifolog_write_poll(struct fifolog_writer *f, time_t now)
+static void
+fifolog_write_gzip(struct fifolog_writer *f, const void *p, int len, time_t now, int fin)
{
- int i, fl, bo, bf;
+ int i, fl;
- if (now == 0)
- time(&now);
+ f->cnt[FIFOLOG_PT_BYTES_PRE] += len;
- fifolog_write_assert(f);
- if (f->cleanup || now >= (int)(f->lastsync + f->syncrate)) {
- /*
- * We always check the sync timer, otherwise a flood of data
- * would not get any sync records at all
- */
+ if (fin == 0)
+ fl = Z_NO_FLUSH;
+ else if (f->cleanup || now >= (int)(f->lastsync + f->syncrate)) {
f->cleanup = 0;
fl = Z_FINISH;
- f->lastsync = now;
- f->lastwrite = now;
f->cnt[FIFOLOG_PT_SYNC]++;
- } else if (f->ff->zs->avail_in == 0 &&
- now >= (int)(f->lastwrite + f->writerate)) {
- /*
- * We only check for writerate timeouts when the input
- * buffer is empty. It would be silly to force a write if
- * pending input could cause it to happen on its own.
- */
+ } else if (now >= (int)(f->lastwrite + f->writerate)) {
fl = Z_SYNC_FLUSH;
- f->lastwrite = now;
f->cnt[FIFOLOG_PT_FLUSH]++;
- } else if (f->ff->zs->avail_in == 0)
- return (0); /* nothing to do */
+ } else if (p == NULL)
+ return;
else
fl = Z_NO_FLUSH;
- for (;;) {
- assert(f->ff->zs->avail_out > 0);
-
- bf = f->ff->zs->avail_out;
-
+ f->ff->zs->avail_in = len;
+ f->ff->zs->next_in = (void*)(uintptr_t)p;
+#ifdef DBG
+if (fl != Z_NO_FLUSH)
+fprintf(stderr, "Z len %3d fin %d now %ld fl %d ai %u ao %u\n",
+ len, fin, now, fl,
+ f->ff->zs->avail_in,
+ f->ff->zs->avail_out);
+#endif
+
+ while (1) {
i = deflate(f->ff->zs, fl);
- assert (i == Z_OK || i == Z_BUF_ERROR || i == Z_STREAM_END);
- bo = f->ff->zs->avail_out;
+#ifdef DBG
+if (i || f->ff->zs->avail_in)
+fprintf(stderr, "fl = %d, i = %d ai = %u ao = %u fx=%02x\n", fl, i,
+ f->ff->zs->avail_in,
+ f->ff->zs->avail_out, f->flag);
+#endif
- /* If we have output space and not in a hurry.. */
- if (bo > 0 && fl == Z_NO_FLUSH)
- break;
-
- /* Write output buffer, if anything in it */
- if (bo != bf)
- fifo_writerec(f);
-
- /* If the buffer were full, we need to check again */
- if (bo == 0) {
- fifo_prepobuf(f, now, 0);
- continue;
- }
+ assert(i == Z_OK || i == Z_BUF_ERROR || i == Z_STREAM_END);
+ assert(f->ff->zs->avail_in == 0);
- if (fl == Z_FINISH) {
- /* Make next record a SYNC record */
- fifo_prepobuf(f, now, 1);
- /* And reset the zlib engine */
- i = deflateReset(f->ff->zs);
- assert(i == Z_OK);
- f->writes_since_sync = 0;
- } else {
- fifo_prepobuf(f, now, 0);
- }
- break;
+ if (!fifolog_write_output(f, fl, now))
+ break;
}
-
- if (f->ff->zs->avail_in == 0) {
- /* Reset input buffer when empty */
- f->iptr = f->ibuf;
- f->ff->zs->next_in = f->iptr;
+ assert(f->ff->zs->avail_in == 0);
+ if (fl == Z_FINISH) {
+ f->flag |= FIFOLOG_FLG_SYNC;
+ f->ff->zs->next_out = f->obuf + 9;
+ f->ff->zs->avail_out = f->obufsize - 9;
+ f->lastsync = now;
+#ifdef DBG
+fprintf(stderr, "SYNC %d\n", __LINE__);
+#endif
+ assert(Z_OK == deflateReset(f->ff->zs));
}
-
- fifolog_write_assert(f);
- return (1);
}
-static void
-fifolog_acct(struct fifolog_writer *f, unsigned bytes)
+int
+fifolog_write_poll(struct fifolog_writer *f, time_t now)
{
-
- f->ff->zs->avail_in += bytes;
- f->iptr += bytes;
- f->cnt[FIFOLOG_PT_BYTES_PRE] += bytes;
+ if (now == 0)
+ time(&now);
+ fifolog_write_gzip(f, NULL, 0, now, 1);
+ return (0);
}
/*
@@ -312,8 +299,8 @@ fifolog_acct(struct fifolog_writer *f, unsigned bytes)
int
fifolog_write_bytes(struct fifolog_writer *f, uint32_t id, time_t now, const void *ptr, unsigned len)
{
- u_int l;
const unsigned char *p;
+ uint8_t buf[4];
fifolog_write_assert(f);
assert(!(id & (FIFOLOG_TIMESTAMP|FIFOLOG_LENGTH)));
@@ -322,46 +309,45 @@ fifolog_write_bytes(struct fifolog_writer *f, uint32_t id, time_t now, const voi
p = ptr;
if (len == 0) {
len = strlen(ptr) + 1;
- l = 4 + len; /* id */
} else {
assert(len <= 255);
id |= FIFOLOG_LENGTH;
- l = 5 + len; /* id + len */
}
- l += 4; /* A timestamp may be necessary */
-
/* Now do timestamp, if needed */
if (now == 0)
time(&now);
- assert(l < f->ibufsize);
-
- /* Return if there is not enough space */
- if (f->iptr + l > f->ibuf + f->ibufsize)
- return (0);
-
if (now != f->last) {
id |= FIFOLOG_TIMESTAMP;
f->last = now;
}
- /* Emit instance+flag and length */
- be32enc(f->iptr, id);
- fifolog_acct(f, 4);
+ /* Emit instance+flag */
+ be32enc(buf, id);
+ fifolog_write_gzip(f, buf, 4, now, 0);
if (id & FIFOLOG_TIMESTAMP) {
- be32enc(f->iptr, (uint32_t)f->last);
- fifolog_acct(f, 4);
+ be32enc(buf, (uint32_t)f->last);
+ fifolog_write_gzip(f, buf, 4, now, 0);
}
if (id & FIFOLOG_LENGTH) {
- f->iptr[0] = (u_char)len;
- fifolog_acct(f, 1);
+ buf[0] = (u_char)len;
+ fifolog_write_gzip(f, buf, 1, now, 0);
}
assert (len > 0);
- memcpy(f->iptr, p, len);
- fifolog_acct(f, len);
+#if 1
+ if (len > f->ibufsize) {
+ free(f->ibuf);
+ f->ibufsize = len;
+ ALLOC(&f->ibuf, f->ibufsize);
+ }
+ memcpy(f->ibuf, p, len);
+ fifolog_write_gzip(f, f->ibuf, len, now, 1);
+#else
+ fifolog_write_gzip(f, p, len, now, 1);
+#endif
fifolog_write_assert(f);
return (1);
}
@@ -384,7 +370,6 @@ fifolog_write_bytes_poll(struct fifolog_writer *f, uint32_t id, time_t now, cons
if (len == 0) {
while (!fifolog_write_bytes(f, id, now, ptr, len)) {
- (void)fifolog_write_poll(f, now);
(void)usleep(10000);
}
} else {
@@ -394,7 +379,6 @@ fifolog_write_bytes_poll(struct fifolog_writer *f, uint32_t id, time_t now, cons
if (l > 255)
l = 255;
while (!fifolog_write_bytes(f, id, now, p, l)) {
- (void)fifolog_write_poll(f, now);
(void)usleep(10000);
}
}
diff --git a/usr.sbin/fwcontrol/fwcontrol.c b/usr.sbin/fwcontrol/fwcontrol.c
index 509d25d..6aa365a 100644
--- a/usr.sbin/fwcontrol/fwcontrol.c
+++ b/usr.sbin/fwcontrol/fwcontrol.c
@@ -508,6 +508,7 @@ load_crom(char *filename, u_int32_t *p)
p, p+1, p+2, p+3, p+4, p+5, p+6, p+7);
p += 8;
}
+ fclose(file);
}
static void
diff --git a/usr.sbin/lpr/Makefile b/usr.sbin/lpr/Makefile
index 3cd0eb6..043ed8b 100644
--- a/usr.sbin/lpr/Makefile
+++ b/usr.sbin/lpr/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
SUBDIR= common_source chkprintcap lp lpc lpd lpq lpr lprm lptest pac \
- filters filters.ru SMM.doc
+ filters filters.ru
# Questions/ideas for lpr & friends could also be sent to:
# freebsd-print@bostonradio.org
diff --git a/usr.sbin/rarpd/rarpd.c b/usr.sbin/rarpd/rarpd.c
index a500dd5..66055f3 100644
--- a/usr.sbin/rarpd/rarpd.c
+++ b/usr.sbin/rarpd/rarpd.c
@@ -666,6 +666,7 @@ struct {
static void
update_arptab(u_char *ep, in_addr_t ipaddr)
{
+ struct timespec tp;
int cc;
struct sockaddr_inarp *ar, *ar2;
struct sockaddr_dl *ll, *ll2;
@@ -731,7 +732,8 @@ update_arptab(u_char *ep, in_addr_t ipaddr)
rt->rtm_version = RTM_VERSION;
rt->rtm_addrs = RTA_DST | RTA_GATEWAY;
rt->rtm_inits = RTV_EXPIRE;
- rt->rtm_rmx.rmx_expire = time(0) + ARPSECS;
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ rt->rtm_rmx.rmx_expire = tp.tv_sec + ARPSECS;
rt->rtm_flags = RTF_HOST | RTF_STATIC;
rt->rtm_type = RTM_ADD;
rt->rtm_seq = ++seq;
diff --git a/usr.sbin/sysinstall/dist.c b/usr.sbin/sysinstall/dist.c
index 716a054..8ef8544 100644
--- a/usr.sbin/sysinstall/dist.c
+++ b/usr.sbin/sysinstall/dist.c
@@ -757,6 +757,9 @@ distExtract(char *parent, Distribution *me)
canceled = 1;
status = FALSE;
+ } else {
+ // ignore any failures with DIST_LOCAL
+ status = TRUE;
}
}
break;
@@ -913,7 +916,7 @@ distExtractAll(dialogMenuItem *self)
restorescr(w);
if (extract_status == FALSE)
- status = DITEM_FAILURE;
+ status = FALSE;
return status;
}
diff --git a/usr.sbin/sysinstall/install.c b/usr.sbin/sysinstall/install.c
index db347e2..daacaa6 100644
--- a/usr.sbin/sysinstall/install.c
+++ b/usr.sbin/sysinstall/install.c
@@ -855,7 +855,7 @@ try_media:
i = distExtractAll(self);
if (i == FALSE)
- return FALSE;
+ return DITEM_FAILURE;
/* When running as init, *now* it's safe to grab the rc.foo vars */
installEnvironment();
diff --git a/usr.sbin/timed/SMM.doc/timed/Makefile b/usr.sbin/timed/SMM.doc/timed/Makefile
deleted file mode 100644
index 9afa6c6..0000000
--- a/usr.sbin/timed/SMM.doc/timed/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# @(#)Makefile 8.1 (Berkeley) 6/8/93
-# $FreeBSD$
-
-DIR= smm/12.timed
-SRCS= timed.ms
-MACROS= -ms
-PRINTER=Pdp
-
-paper.${PRINTER}: ${SRCS}
- ${SOELIM} ${SRCS} | ${TBL} | ${ROFF} > ${.TARGET}
-
-.include <bsd.doc.mk>
diff --git a/usr.sbin/timed/SMM.doc/timedop/Makefile b/usr.sbin/timed/SMM.doc/timedop/Makefile
deleted file mode 100644
index 7d52a32..0000000
--- a/usr.sbin/timed/SMM.doc/timedop/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# @(#)Makefile 8.1 (Berkeley) 6/8/93
-# $FreeBSD$
-
-DIR= smm/11.timedop
-SRCS= timed.ms
-MACROS= -ms
-
-.include <bsd.doc.mk>
diff --git a/usr.sbin/traceroute/Makefile b/usr.sbin/traceroute/Makefile
index c77244f..103d206 100644
--- a/usr.sbin/traceroute/Makefile
+++ b/usr.sbin/traceroute/Makefile
@@ -31,7 +31,7 @@ LDADD= -lipsec
CFLAGS+= -I${TRACEROUTE_DISTDIR}
-WARNS?= 0
+WARNS?= 3
version.c: ${TRACEROUTE_DISTDIR}/VERSION
@rm -f ${.TARGET}
diff --git a/usr.sbin/traceroute6/Makefile b/usr.sbin/traceroute6/Makefile
index e0b72a1..4428d5b 100644
--- a/usr.sbin/traceroute6/Makefile
+++ b/usr.sbin/traceroute6/Makefile
@@ -25,7 +25,7 @@ BINMODE= 4555
CFLAGS+= -DIPSEC -DUSE_RFC2292BIS -DHAVE_POLL
CFLAGS+= -I${.CURDIR} -I${TRACEROUTE_DISTDIR} -I.
-WARNS?= 1
+WARNS?= 3
DPADD= ${LIBIPSEC}
LDADD= -lipsec
diff --git a/usr.sbin/traceroute6/traceroute6.c b/usr.sbin/traceroute6/traceroute6.c
index 699af68..1a67173 100644
--- a/usr.sbin/traceroute6/traceroute6.c
+++ b/usr.sbin/traceroute6/traceroute6.c
@@ -66,7 +66,7 @@
*/
#ifndef lint
-static char copyright[] =
+static const char copyright[] =
"@(#) Copyright (c) 1990, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
@@ -322,7 +322,7 @@ void send_probe(int, u_long);
void *get_uphdr(struct ip6_hdr *, u_char *);
int get_hoplim(struct msghdr *);
double deltaT(struct timeval *, struct timeval *);
-char *pr_type(int);
+const char *pr_type(int);
int packet_ok(struct msghdr *, int, int);
void print(struct msghdr *, int);
const char *inetname(struct sockaddr *);
@@ -372,12 +372,12 @@ main(argc, argv)
{
int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
- int ch, i, on = 1, seq, rcvcmsglen, error, minlen;
+ int ch, i, on = 1, seq, rcvcmsglen, error;
struct addrinfo hints, *res;
static u_char *rcvcmsgbuf;
u_long probe, hops, lport;
struct hostent *hp;
- size_t size;
+ size_t size, minlen;
uid_t uid;
/*
@@ -671,11 +671,11 @@ main(argc, argv)
datalen = minlen;
else if (datalen >= MAXPACKET) {
fprintf(stderr,
- "traceroute6: packet size must be %d <= s < %ld.\n",
- minlen, (long)MAXPACKET);
+ "traceroute6: packet size must be %zu <= s < %d.\n",
+ minlen, MAXPACKET);
exit(1);
}
- outpacket = (struct opacket *)malloc((unsigned)datalen);
+ outpacket = malloc(datalen);
if (!outpacket) {
perror("malloc");
exit(1);
@@ -913,7 +913,7 @@ main(argc, argv)
for (hops = first_hop; hops <= max_hops; ++hops) {
struct in6_addr lastaddr;
int got_there = 0;
- int unreachable = 0;
+ unsigned unreachable = 0;
printf("%2lu ", hops);
bzero(&lastaddr, sizeof(lastaddr));
@@ -1089,7 +1089,7 @@ send_probe(seq, hops)
i = sendto(sndsock, (char *)outpacket, datalen, 0,
(struct sockaddr *)&Dst, Dst.sin6_len);
- if (i < 0 || i != datalen) {
+ if (i < 0 || (u_long)i != datalen) {
if (i < 0)
perror("sendto");
printf("traceroute6: wrote %s %lu chars, ret=%d\n",
@@ -1129,12 +1129,11 @@ deltaT(t1p, t2p)
/*
* Convert an ICMP "type" field to a printable string.
*/
-char *
-pr_type(t0)
- int t0;
+const char *
+pr_type(int t0)
{
u_char t = t0 & 0xff;
- char *cp;
+ const char *cp;
switch (t) {
case ICMP6_DST_UNREACH:
@@ -1221,7 +1220,7 @@ packet_ok(mhdr, cc, seq)
cc -= hlen;
icp = (struct icmp6_hdr *)(buf + hlen);
#else
- if (cc < sizeof(struct icmp6_hdr)) {
+ if (cc < (int)sizeof(struct icmp6_hdr)) {
if (verbose) {
if (getnameinfo((struct sockaddr *)from, from->sin6_len,
hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
diff --git a/usr.sbin/usbdevs/Makefile b/usr.sbin/usbdevs/Makefile
deleted file mode 100644
index 3cfc8ef..0000000
--- a/usr.sbin/usbdevs/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $NetBSD: Makefile,v 1.2 1998/07/12 20:40:45 augustss Exp $
-# FreeBSD $FreeBSD$
-
-PROG= usbdevs
-MAN= usbdevs.8
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/usbdevs/usbdevs.8 b/usr.sbin/usbdevs/usbdevs.8
deleted file mode 100644
index dd56fc8..0000000
--- a/usr.sbin/usbdevs/usbdevs.8
+++ /dev/null
@@ -1,70 +0,0 @@
-.\" $NetBSD: usbdevs.8,v 1.5 2000/10/15 12:44:11 bjh21 Exp $
-.\" Copyright (c) 1999 The NetBSD Foundation, Inc.
-.\" All rights reserved.
-.\"
-.\" Author: Lennart Augustsson
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd May 24, 2004
-.Dt USBDEVS 8
-.Os
-.Sh NAME
-.Nm usbdevs
-.Nd show USB devices connected to the system
-.Sh SYNOPSIS
-.Nm
-.Op Fl a Ar addr
-.Op Fl d
-.Op Fl f Ar dev
-.Op Fl o
-.Op Fl v
-.Sh DESCRIPTION
-The
-.Nm
-utility prints a listing of all USB devices connected to the system
-with some information about each device.
-The indentation of each line indicates its distance from the root.
-.Pp
-The options are as follows:
-.Bl -tag -width ".Fl a Ar addr"
-.It Fl a Ar addr
-only print information about the device at the given address.
-.It Fl d
-Show the device drivers associated with each device.
-.It Fl f Ar dev
-only print information for the given USB controller.
-.It Fl o
-One-line output (only useful in combination with
-.Fl d ) .
-.It Fl v
-Be verbose.
-.El
-.Sh SEE ALSO
-.Xr usb 4
-.Sh HISTORY
-The
-.Nm
-utility appeared in
-.Nx 1.4 .
diff --git a/usr.sbin/usbdevs/usbdevs.c b/usr.sbin/usbdevs/usbdevs.c
deleted file mode 100644
index b51e3c5..0000000
--- a/usr.sbin/usbdevs/usbdevs.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/* $NetBSD: usbdevs.c,v 1.22 2003/11/12 13:31:08 grant Exp $ */
-/* $FreeBSD$ */
-
-/*
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (augustss@NetBSD.org).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <err.h>
-#include <errno.h>
-#include <dev/usb/usb.h>
-#if defined(__FreeBSD__)
-#include <sys/ioctl.h>
-#endif
-
-#define USBDEV "/dev/usb"
-
-int verbose = 0;
-int showdevs = 0;
-int oneline = 0;
-
-void usage(void);
-void usbdev(int f, int a, int rec);
-void usbdump(int f);
-void dumpone(char *name, int f, int addr);
-int main(int, char **);
-
-void
-usage()
-{
- fprintf(stderr, "usage: %s [-a addr] [-d] [-f dev] [-o] [-v]\n",
- getprogname());
- exit(1);
-}
-
-char done[USB_MAX_DEVICES];
-int indent;
-
-void
-usbdev(int f, int a, int rec)
-{
- struct usb_device_info di;
- int e, p, i;
-
- di.udi_addr = a;
- e = ioctl(f, USB_DEVICEINFO, &di);
- if (e) {
- if (errno != ENXIO)
- printf("addr %d: I/O error\n", a);
- return;
- }
- printf("addr %d: ", a);
- done[a] = 1;
- if (verbose) {
- switch (di.udi_speed) {
- case USB_SPEED_LOW: printf("low speed, "); break;
- case USB_SPEED_FULL: printf("full speed, "); break;
- case USB_SPEED_HIGH: printf("high speed, "); break;
- default: break;
- }
- if (di.udi_power)
- printf("power %d mA, ", di.udi_power);
- else
- printf("self powered, ");
- if (di.udi_config)
- printf("config %d, ", di.udi_config);
- else
- printf("unconfigured, ");
- }
- if (verbose) {
- printf("%s(0x%04x), %s(0x%04x), rev %s",
- di.udi_product, di.udi_productNo,
- di.udi_vendor, di.udi_vendorNo, di.udi_release);
- } else
- printf("%s, %s", di.udi_product, di.udi_vendor);
- if (!oneline)
- printf("\n");
- if (showdevs) {
- for (i = 0; i < USB_MAX_DEVNAMES; i++) {
- if (di.udi_devnames[i][0]) {
- if (oneline)
- printf(", device %s",
- di.udi_devnames[i]);
- else
- printf("%*s %s\n", indent, "",
- di.udi_devnames[i]);
- }
- }
- }
- if (oneline)
- printf("\n");
- if (!rec)
- return;
- for (p = 0; p < di.udi_nports; p++) {
- int s = di.udi_ports[p];
- if (s >= USB_MAX_DEVICES) {
- if (verbose) {
- printf("%*sport %d %s\n", indent+1, "", p+1,
- s == USB_PORT_ENABLED ? "enabled" :
- s == USB_PORT_SUSPENDED ? "suspended" :
- s == USB_PORT_POWERED ? "powered" :
- s == USB_PORT_DISABLED ? "disabled" :
- "???");
-
- }
- continue;
- }
- indent++;
- printf("%*s", indent, "");
- if (verbose)
- printf("port %d ", p+1);
- if (s == 0)
- printf("addr 0 should never happen!\n");
- else
- usbdev(f, s, 1);
- indent--;
- }
-}
-
-void
-usbdump(int f)
-{
- int a;
-
- for (a = 1; a < USB_MAX_DEVICES; a++) {
- if (!done[a])
- usbdev(f, a, 1);
- }
-}
-
-void
-dumpone(char *name, int f, int addr)
-{
- if (verbose)
- printf("Controller %s:\n", name);
- indent = 0;
- memset(done, 0, sizeof done);
- if (addr)
- usbdev(f, addr, 0);
- else
- usbdump(f);
-}
-
-int
-main(int argc, char **argv)
-{
- int ch, i, f;
- char buf[50];
- char *dev = 0;
- int addr = 0;
- int ncont;
-
- while ((ch = getopt(argc, argv, "a:df:ov?")) != -1) {
- switch(ch) {
- case 'a':
- addr = atoi(optarg);
- break;
- case 'd':
- showdevs++;
- break;
- case 'f':
- dev = optarg;
- break;
- case 'o':
- oneline++;
- break;
- case 'v':
- verbose = 1;
- break;
- case '?':
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- if (dev == 0) {
- for (ncont = 0, i = 0; i < 10; i++) {
- snprintf(buf, sizeof(buf), "%s%d", USBDEV, i);
- f = open(buf, O_RDONLY);
- if (f >= 0) {
- dumpone(buf, f, addr);
- close(f);
- } else {
- if (errno == ENOENT || errno == ENXIO)
- continue;
- warn("%s", buf);
- }
- ncont++;
- }
- if (verbose && ncont == 0)
- printf("%s: no USB controllers found\n",
- getprogname());
- } else {
- f = open(dev, O_RDONLY);
- if (f >= 0)
- dumpone(dev, f, addr);
- else
- err(1, "%s", dev);
- }
- exit(0);
-}
diff --git a/usr.sbin/usbdump/usbdump.c b/usr.sbin/usbdump/usbdump.c
index 93e9f21..c6f9048 100644
--- a/usr.sbin/usbdump/usbdump.c
+++ b/usr.sbin/usbdump/usbdump.c
@@ -247,7 +247,7 @@ print_apacket(const struct bpf_xhdr *hdr, struct usbpf_pkthdr *up,
printf(" usbus%d.%d 0x%02x %s %s", up->up_busunit, up->up_address,
up->up_endpoint,
xfertype_table[up->up_xfertype],
- up->up_type == USBPF_XFERTAP_SUBMIT ? ">" : "<");
+ up->up_type == USBPF_XFERTAP_SUBMIT ? "S" : "D");
printf(" (%d/%d)", up->up_frames, up->up_length);
if (up->up_type == USBPF_XFERTAP_DONE)
printf(" %s", errstr_table[up->up_error]);
OpenPOWER on IntegriCloud