da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Msgbuf buffer management implementation. The smb_msgbuf interface is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * typically used to encode or decode SMB data using sprintf/scanf
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * style operations. It contains special handling for the SMB header.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * It can also be used for general purpose encoding and decoding.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int buf_decode(smb_msgbuf_t *, char *, va_list ap);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int buf_encode(smb_msgbuf_t *, char *, va_list ap);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns the offset or number of bytes used within the buffer.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*LINTED E_PTRDIFF_OVERFLOW*/
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns the actual buffer size.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Ensure that the scan is aligned on a word (16-bit) boundary.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Ensure that the scan is aligned on a dword (32-bit) boundary.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Checks whether or not the buffer has space for the amount of data
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * specified. Returns 1 if there is space, otherwise returns 0.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Set flags the smb_msgbuf.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Clear flags the smb_msgbuf.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_msgbuf_init
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Initialize a smb_msgbuf_t structure based on the buffer and size
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * specified. Both scan and base initially point to the beginning
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * of the buffer and end points to the limit of the buffer. As
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * data is added scan should be incremented to point to the next
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * offset at which data will be written. Max and count are set
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to the actual buffer size.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_msgbuf_init(smb_msgbuf_t *mb, uint8_t *buf, size_t size, uint32_t flags)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_msgbuf_term
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Destruct a smb_msgbuf_t. Free any memory hanging off the mlist.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_msgbuf_decode
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Decode a smb_msgbuf buffer as indicated by the format string into
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the variable arg list. This is similar to a scanf operation.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * On success, returns the number of bytes encoded. Otherwise
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * returns a -ve error code.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*LINTED E_PTRDIFF_OVERFLOW*/
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * buf_decode
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Private decode function, where the real work of decoding the smb_msgbuf
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * is done. This function should only be called via smb_msgbuf_decode to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * ensure correct behaviour and error handling.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while ((c = *fmt++) != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (c == '(') {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (c == '#') {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (repc-- > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_msgbuf_has_space(mb, repc * sizeof (uint16_t));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (repc-- > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (repc-- > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (repc-- > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*FALLTHROUGH*/
12b65585e720714b31036daaa2b30eb76014048eGordon Ross if ((cvalp = smb_msgbuf_malloc(mb, repc * 2)) == 0)
12b65585e720714b31036daaa2b30eb76014048eGordon Ross /* Translate OEM to mbs */
12b65585e720714b31036daaa2b30eb76014048eGordon Ross while (repc > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Unicode strings are always word aligned.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The malloc'd area is larger than the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * original string because the UTF-8 chars
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * may be longer than the wide-chars.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross * Count bytes, including the null.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross * Get space for translated string
12b65585e720714b31036daaa2b30eb76014048eGordon Ross * Allocates worst-case size.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross * Translate unicode to mbs, stopping after
12b65585e720714b31036daaa2b30eb76014048eGordon Ross * null or repc limit.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_msgbuf_encode
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Encode a smb_msgbuf buffer as indicated by the format string using
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the variable arg list. This is similar to a sprintf operation.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * On success, returns the number of bytes encoded. Otherwise
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * returns a -ve error code.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*LINTED E_PTRDIFF_OVERFLOW*/
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * buf_encode
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Private encode function, where the real work of encoding the smb_msgbuf
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * is done. This function should only be called via smb_msgbuf_encode to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * ensure correct behaviour and error handling.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while ((c = *fmt++) != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (c == '(') {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (c == '#') {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (repc-- > 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (repc-- > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_msgbuf_has_space(mb, repc * sizeof (uint16_t));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (repc-- > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (repc-- > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (repc-- > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* FALLTHROUGH */
12b65585e720714b31036daaa2b30eb76014048eGordon Ross while (repc > 0) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross while (repc > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Unicode strings are always word aligned.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross while (repc > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_msgbuf_malloc
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Allocate some memory for use with this smb_msgbuf. We increase the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * requested size to hold the list pointer and return a pointer
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to the area for use by the caller.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The caller gets a pointer to the address
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * immediately after the smb_msgbuf_mlist_t.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_msgbuf_chkerc
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Diagnostic function to write an appropriate message to the system log.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw static struct {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (i = 0; i < sizeof (etable)/sizeof (etable[0]); ++i) {