/// <summary> /// Creates a new instance of <see cref="NbName"/> /// </summary> /// <param name="netbiosName">Unencoded Netbios Name label</param> /// <param name="netbiosSuffix">Netbios Suffix</param> /// <param name="netbiosScope">Netbios Scope</param> /// <remarks> /// We only perform length checks of <see cref="netbiosName"/> and <see cref="netbiosScope"/> /// The caller must make sure that the characters in these parameters can be converted into a /// single byte via ISO-8859-1 encoding. If this is not the case, an exception will be thrown later /// when the <see cref="NbName"/> is encoded into a byte array. /// </remarks> public NbName(string netbiosName, KnownNetbiosSuffixes netbiosSuffix, string netbiosScope = null) { // Validity checks for netbiosName if (netbiosName == null) { throw new ArgumentNullException("netbiosName"); } if (netbiosName.Length > MAX_NAME_LENGTH_CLEARTEXT || netbiosName.Length < 1) { throw new ArgumentException("netbiosName"); } _netbiosName = netbiosName; _netbiosSuffix = netbiosSuffix; // Validity checks for netbiosScope if (String.IsNullOrEmpty(netbiosScope)) { _netbiosScope = null; return; } var scopeLabels = netbiosScope.Split(SCOPE_SEPARATOR); if (scopeLabels.Any(label => label.Length > MAX_LABEL_LENGTH)) { throw new ArgumentException("netbiosScope"); } _netbiosScope = netbiosScope; // Max length check for the whole NbName if (GetLength() > MAX_DOMAIN_NAME_LENGHT) { throw new ArgumentException("netbiosScope"); } }
/// <summary> /// Tries to parse a <see cref="NbName"/> from a buffer of bytes /// </summary> /// <param name="buffer">Byte array containing the NbName</param> /// <param name="offset">Zero based offset in the buffer where the NbName starts</param> /// <param name="nbName">Parsed NbName if successful, else null</param> /// <returns><c>true</c> if parsing was successful, else <c>false</c></returns> public static bool TryParse(byte[] buffer, int offset, out NbName nbName) { nbName = null; if (buffer == null) { return(false); } if (offset < 0 || offset >= buffer.Length) { return(false); } if (buffer[offset] == 0x00) { return(false); } string name = null; KnownNetbiosSuffixes suffix = 0; string scope = null; while (buffer[offset] != 0x00) { // If the current byte is a label string pointer (the first two bits are set) if (buffer[offset] >= 192) { // Then the fourteen bits starting at bit three of the current byte represent a pointer to the label in the buffer if (offset + 1 >= buffer.Length) { return(false); } var pointer = BitConverter.ToUInt16(buffer, offset); pointer &= Convert.ToUInt16("0011111111111111", 2); if (pointer >= buffer.Length) { return(false); } offset = pointer; } // If the current byte is not a laber string pointer (the first two bits are not set) else if (buffer[offset] < 64) { // Then the current byte represents the length of the label var length = buffer[offset]; offset++; if (length % 2 != 0 || offset + length >= buffer.Length) { return(false); } if (name == null) { // label must be the netbiosName label var nameAndSuffix = LevelOneDecode(buffer, offset, length); suffix = (KnownNetbiosSuffixes)nameAndSuffix[nameAndSuffix.Length - 1]; name = nameAndSuffix.Substring(0, nameAndSuffix.Length - 1); // Wildcard names are padded with null bytes, other names are padded with spaces name = name.Trim('\0', ' '); } else { // label must be a scope label scope = (scope == null) ? ENCODING.GetString(buffer, offset, length) : scope + "." + ENCODING.GetString(buffer, offset, length); } offset += length; } else { return(false); } } nbName = new NbName(name, suffix, scope); return(true); }