da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#if defined(_KERNEL) || defined(_FAKE_KERNEL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/types.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/sunddi.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#else
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <string.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#endif
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/string.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/netbios.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Routines than support name compression.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The NetBIOS name representation in all NetBIOS packets (for NAME,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SESSION, and DATAGRAM services) is defined in the Domain Name
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Service RFC 883[3] as "compressed" name messages. This format is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * called "second-level encoding" in the section entitled
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * "Representation of NetBIOS Names" in the Concepts and Methods
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * document.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * For ease of description, the first two paragraphs from page 31,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the section titled "Domain name representation and compression",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * of RFC 883 are replicated here:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Domain names messages are expressed in terms of a sequence
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * of labels. Each label is represented as a one octet length
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * field followed by that number of octets. Since every domain
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * name ends with the null label of the root, a compressed
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * domain name is terminated by a length byte of zero. The
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * high order two bits of the length field must be zero, and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the remaining six bits of the length field limit the label
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to 63 octets or less.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * To simplify implementations, the total length of label
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * octets and label length octets that make up a domain name is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * restricted to 255 octets or less.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The following is the uncompressed representation of the NetBIOS name
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * "FRED ", which is the 4 ASCII characters, F, R, E, D, followed by 12
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * space characters (0x20). This name has the SCOPE_ID: "NETBIOS.COM"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * EGFCEFEECACACACACACACACACACACACA.NETBIOS.COM
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This uncompressed representation of names is called "first-level
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * encoding" in the section entitled "Representation of NetBIOS Names"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * in the Concepts and Methods document.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The following is a pictographic representation of the compressed
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * representation of the previous uncompressed Domain Name
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * representation.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | 0x20 | E (0x45) | G (0x47) | F (0x46) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | C (0x43) | E (0x45) | F (0x46) | E (0x45) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | E (0x45) | C (0x43) | A (0x41) | C (0x43) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | A (0x41) | C (0x43) | A (0x41) | C (0x43) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | A (0x41) | C (0x43) | A (0x41) | C (0x43) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | A (0x41) | C (0x43) | A (0x41) | C (0x43) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | A (0x41) | C (0x43) | A (0x41) | C (0x43) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | A (0x41) | C (0x43) | A (0x41) | C (0x43) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | A (0X41) | 0x07 | N (0x4E) | E (0x45) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | T (0x54) | B (0x42) | I (0x49) | O (0x4F) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | S (0x53) | 0x03 | C (0x43) | O (0x4F) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * | M (0x4D) | 0x00 |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Each section of a domain name is called a label [7 (page 31)]. A
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * label can be a maximum of 63 bytes. The first byte of a label in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * compressed representation is the number of bytes in the label. For
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the above example, the first 0x20 is the number of bytes in the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * left-most label, EGFCEFEECACACACACACACACACACACACA, of the domain
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * name. The bytes following the label length count are the characters
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * of the label. The following labels are in sequence after the first
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * label, which is the encoded NetBIOS name, until a zero (0x00) length
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * count. The zero length count represents the root label, which is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * always null.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * A label length count is actually a 6-bit field in the label length
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * field. The most significant 2 bits of the field, bits 7 and 6, are
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * flags allowing an escape from the above compressed representation.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If bits 7 and 6 are both set (11), the following 14 bits are an
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * offset pointer into the full message to the actual label string from
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * another domain name that belongs in this name. This label pointer
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * allows for a further compression of a domain name in a packet.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * NetBIOS implementations can only use label string pointers in Name
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Service packets. They cannot be used in Session or Datagram Service
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * packets.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The other two possible values for bits 7 and 6 (01 and 10) of a label
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * length field are reserved for future use by RFC 883[2 (page 32)].
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Note that the first octet of a compressed name must contain one of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the following bit patterns. (An "x" indicates a bit whose value may
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * be either 0 or 1.):
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 00100000 - Netbios name, length must be 32 (decimal)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 11xxxxxx - Label string pointer
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 10xxxxxx - Reserved
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 01xxxxxx - Reserved
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * netbios_first_level_name_encode
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Put test description here.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Inputs:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * char * in -> Name to encode
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * char * out -> Buffer to encode into.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * int length -> # of bytes to encode.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Nothing
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetbios_first_level_name_encode(unsigned char *name, unsigned char *scope,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char *out, int max_out)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char ch, len;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char *in;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char *lp;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char *op = out;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (max_out < 0x21)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw in = name;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *op++ = 0x20;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (len = 0; len < NETBIOS_NAME_SZ; len++) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ch = *in++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *op++ = 'A' + ((ch >> 4) & 0xF);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *op++ = 'A' + ((ch) & 0xF);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw max_out -= 0x21;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw in = scope;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw len = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lp = op++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (((ch = *in++) != 0) && (max_out-- > 1)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ch == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((*lp = len) != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *op++ = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ch == '.') {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *lp = len;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lp = op++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw len = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *op++ = ch;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw len++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *lp = len;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (len != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *op = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*LINTED E_PTRDIFF_OVERFLOW*/
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (op - out);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_first_level_name_decode
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The null terminated string "in" is the name to decode. The output
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * is placed in the name_entry structure "name".
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The scope field is a series of length designated labels as described
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * in the "Domain name representation and compression" section of RFC883.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The two high order two bits of the length field must be zero, the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * remaining six bits contain the field length. The total length of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * domain name is restricted to 255 octets but note that the trailing
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * root label and its dot are not printed. When converting the labels,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the length fields are replaced by dots.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns the number of bytes scanned or -1 to indicate an error.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetbios_first_level_name_decode(char *in, char *name, char *scope)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
b3988cf65491efce7a0df7b735c586e4e12714f0Gordon Ross unsigned int length;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char c1, c2;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *cp;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *out;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw cp = in;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((length = *cp++) != 0x20) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw out = name;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (length > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw c1 = *cp++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw c2 = *cp++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ('A' <= c1 && c1 <= 'P' && 'A' <= c2 && c2 <= 'P') {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw c1 -= 'A';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw c2 -= 'A';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *out++ = (c1 << 4) | (c2);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1); /* conversion error */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw length -= 2;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
b3988cf65491efce7a0df7b735c586e4e12714f0Gordon Ross * Don't bother decoding the scope. Not supported.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
b3988cf65491efce7a0df7b735c586e4e12714f0Gordon Ross if ((length = *cp++) != 0)
b3988cf65491efce7a0df7b735c586e4e12714f0Gordon Ross return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw scope[0] = '\0';
b3988cf65491efce7a0df7b735c586e4e12714f0Gordon Ross
b3988cf65491efce7a0df7b735c586e4e12714f0Gordon Ross /*LINTED E_PTRDIFF_OVERFLOW*/
b3988cf65491efce7a0df7b735c586e4e12714f0Gordon Ross return (cp - in);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_netbios_name_isvalid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function is provided to be used by session service
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * which runs in kernel in order to hide name_entry definition.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * It returns the decoded name in the provided buffer as 'out'
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * if it's not null.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns 0 if decode fails, 1 if it succeeds.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwnetbios_name_isvalid(char *in, char *out)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char name[NETBIOS_NAME_SZ];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char scope[NETBIOS_DOMAIN_NAME_MAX];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (netbios_first_level_name_decode(in, name, scope) < 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (out)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strlcpy(out, name, NETBIOS_NAME_SZ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}