org.filesys.netbios.NetBIOSName Maven / Gradle / Ivy
Show all versions of jfileserver Show documentation
/*
* Copyright (C) 2006-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see .
*/
package org.filesys.netbios;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.filesys.debug.Debug;
import org.filesys.util.IPAddress;
/**
* NetBIOS Name Class
*
*
* Contains the details of a NetBIOS name, which is a 16 byte value containing the name in the first
* 15 bytes with a 16th byte indicating the name type.
*
*
* Contains NetBIOS name type constants.
*
* @author gkspencer
*/
public class NetBIOSName {
// NetBIOS name length
public static final int NameLength = 16;
// NetBIOS name types - + type
public static final char WorkStation = 0x00;
public static final char Messenger = 0x01;
public static final char RemoteMessenger = 0x03;
public static final char RASServer = 0x06;
public static final char FileServer = 0x20;
public static final char RASClientService = 0x21;
public static final char MSExchangeInterchange = 0x22;
public static final char MSExchangeStore = 0x23;
public static final char MSExchangeDirectory = 0x24;
public static final char LotusNotesServerService = 0x2B;
public static final char ModemSharingService = 0x30;
public static final char ModemSharingClient = 0x31;
public static final char McCaffeeAntiVirus = 0x42;
public static final char SMSClientRemoteControl = 0x43;
public static final char SMSAdminRemoteControl = 0x44;
public static final char SMSClientRemoteChat = 0x45;
public static final char SMSClientRemoteTransfer = 0x46;
public static final char DECPathworksService = 0x4C;
public static final char MSExchangeIMC = 0x6A;
public static final char MSExchangeMTA = 0x87;
public static final char NetworkMonitorAgent = 0xBE;
public static final char NetworkMonitorApp = 0xBF;
// + type
public static final char Domain = 0x00; // Group
public static final char DomainMasterBrowser = 0x1B;
public static final char DomainControllers = 0x1C; // Group
public static final char MasterBrowser = 0x1D;
public static final char DomainAnnounce = 0x1E;
// Browse master - __MSBROWSE__ + type
public static final char BrowseMasterGroup = 0x01;
// Browse master NetBIOS name
public static final String BrowseMasterName = "\u0001\u0002__MSBROWSE__\u0002";
// NetBIOS names
public static final String SMBServer = "*SMBSERVER";
public static final String SMBServer2 = "*SMBSERV";
// Adapter status request name
public static final String AdapterStatusName = "*";
// Default time to live for name registrations
public static final int DefaultTTL = 28800; // 8 hours
// Name conversion string
private static final String EncodeConversion = "ABCDEFGHIJKLMNOP";
// Character set to use when converting the NetBIOS name string to a byte array
private static String _nameConversionCharset = null;
// Name string and type
private String m_name;
private char m_type;
// Name scope
private String m_scope;
// Group name flag
private boolean m_group = false;
// Local name flag
private boolean m_local = true;
// IP address(es) of the owner of this name
private List m_addrList;
// Time that the name expires and time to live
private long m_expiry;
private int m_ttl; // seconds
// Name number/id, for Win32NetBIOS registered names
private int m_nameNum = -1;
/**
* Create a unique NetBIOS name.
*
* @param name java.lang.String
* @param typ char
* @param group boolean
*/
public NetBIOSName(String name, char typ, boolean group) {
setName(name);
setType(typ);
setGroup(group);
}
/**
* Copy constructor
*
* @param nbName NetBIOSName
*/
public NetBIOSName(NetBIOSName nbName) {
setName(nbName.getName());
setType(nbName.getType());
setGroup(nbName.isGroupName());
}
/**
* Create a unique NetBIOS name.
*
* @param name java.lang.String
* @param typ char
* @param group boolean
* @param ipaddr byte[]
*/
public NetBIOSName(String name, char typ, boolean group, byte[] ipaddr) {
setName(name);
setType(typ);
setGroup(group);
addIPAddress(ipaddr);
}
/**
* Create a unique NetBIOS name.
*
* @param name String
* @param typ char
* @param group boolean
* @param ipList List of byte arrays
*/
public NetBIOSName(String name, char typ, boolean group, List ipList) {
setName(name);
setType(typ);
setGroup(group);
addIPAddresses(ipList);
}
/**
* Create a unique NetBIOS name.
*
* @param name java.lang.String
* @param typ char
* @param group boolean
* @param ipaddr byte[]
* @param ttl int
*/
public NetBIOSName(String name, char typ, boolean group, byte[] ipaddr, int ttl) {
setName(name);
setType(typ);
setGroup(group);
addIPAddress(ipaddr);
setTimeToLive(ttl);
}
/**
* Create a unique NetBIOS name.
*
* @param name java.lang.String
* @param typ char
* @param group boolean
* @param ipList List of byte arrays
* @param ttl int
*/
public NetBIOSName(String name, char typ, boolean group, List ipList, int ttl) {
setName(name);
setType(typ);
setGroup(group);
addIPAddresses(ipList);
setTimeToLive(ttl);
}
/**
* Create a NetBIOS name from a byte array
*
* @param buf byte[]
* @param off int
*/
public NetBIOSName(byte[] buf, int off) {
setName(new String(buf, off, NameLength - 1));
setType((char) buf[off + (NameLength - 1)]);
}
/**
* Create a NetBIOS name from an encoded name string
*
* @param name String
*/
public NetBIOSName(String name) {
setName(name.substring(0, NameLength - 1).trim());
setType(name.charAt(NameLength - 1));
}
/**
* Create a NetBIOS name from the specified name and scope
*
* @param name String
* @param scope String
*/
protected NetBIOSName(String name, String scope) {
setName(name.substring(0, NameLength - 1).trim());
setType(name.charAt(NameLength - 1));
if (scope != null && scope.length() > 0)
setNameScope(scope);
}
/**
* Compare objects for equality.
*
* @param obj java.lang.Object
* @return boolean
*/
public boolean equals(Object obj) {
// Check if the object is a NetBIOSName type object
if (obj instanceof NetBIOSName) {
// Check if the NetBIOS name, name type and local/remote flags are equal
NetBIOSName nbn = (NetBIOSName) obj;
if (nbn.getName().equals(getName()) && nbn.getType() == getType() && nbn.isLocalName() == isLocalName())
return true;
}
// Objects are not equal
return false;
}
/**
* Return the system time that the NetBIOS name expires.
*
* @return long
*/
public final long getExpiryTime() {
return m_expiry;
}
/**
* Get the names time to live value, in seconds
*
* @return int
*/
public final int getTimeToLive() {
return m_ttl;
}
/**
* Get the name number/id
*
* @return int
*/
public final int getNameNumber() {
return m_nameNum;
}
/**
* Return the number of addresses for this NetBIOS name
*
* @return int
*/
public final int numberOfAddresses() {
return m_addrList != null ? m_addrList.size() : 0;
}
/**
* Return the specified IP address that owns the NetBIOS name.
*
* @param idx int
* @return byte[]
*/
public final byte[] getIPAddress(int idx) {
if (m_addrList == null || idx < 0 || idx >= m_addrList.size())
return null;
return m_addrList.get(idx);
}
/**
* Return the specified IP address that owns the NetBIOS name, as a string.
*
* @param idx int
* @return String
*/
public final String getIPAddressString(int idx) {
if (m_addrList == null || idx < 0 || idx >= m_addrList.size())
return null;
// Get the raw IP address and build the address string
return IPAddress.asString(m_addrList.get(idx));
}
/**
* Return the NetBIOS name.
*
* @return java.lang.String
*/
public final String getName() {
return m_name;
}
/**
* Return the full name including any name scope
*
* @return String
*/
public final String getFullName() {
if (hasNameScope() == false)
return getName();
return getName() + "." + getNameScope();
}
/**
* Return the NetBIOS name as a 16 character string with the name and type
*
* @return byte[]
*/
public final byte[] getNetBIOSName() {
// Allocate a buffer to build the full name
byte[] nameBuf = new byte[NameLength];
// Get the name string bytes
byte[] nameBytes = null;
try {
if (hasNameConversionCharacterSet())
nameBytes = getName().getBytes(getNameConversionCharacterSet());
else
nameBytes = getName().getBytes();
}
catch (Exception ex) {
Debug.println(ex);
}
System.arraycopy(nameBytes, 0, nameBuf, 0, nameBytes.length);
for (int i = nameBytes.length; i < NameLength; i++)
nameBuf[i] = ' ';
nameBuf[NameLength - 1] = (byte) (m_type & 0xFF);
return nameBuf;
}
/**
* Determine if the name has a name scope
*
* @return boolean
*/
public final boolean hasNameScope() {
return m_scope != null ? true : false;
}
/**
* Return the name scope
*
* @return String
*/
public final String getNameScope() {
return m_scope;
}
/**
* Return the NetBIOS name type.
*
* @return char
*/
public final char getType() {
return m_type;
}
/**
* Return a hash code for this object.
*
* @return int
*/
public int hashCode() {
return getName().hashCode() + (int) getType();
}
/**
* Returns true if this is a group type NetBIOS name.
*
* @return boolean
*/
public final boolean isGroupName() {
return m_group;
}
/**
* Determine if this is a local or remote NetBIOS name.
*
* @return boolean
*/
public final boolean isLocalName() {
return m_local;
}
/**
* Returns true if the NetBIOS name is a unique type name.
*
* @return boolean
*/
public final boolean isUniqueName() {
return m_group ? false : true;
}
/**
* Remove all TCP/IP addresses from the NetBIOS name
*/
public final void removeAllAddresses() {
m_addrList.clear();
}
/**
* Set the system time that this NetBIOS name expires at.
*
* @param expires long
*/
public final void setExpiryTime(long expires) {
m_expiry = expires;
}
/**
* Set the names time to live, in seconds
*
* @param ttl int
*/
public final void setTimeToLive(int ttl) {
m_ttl = ttl;
}
/**
* Set/clear the group name flag.
*
* @param flag boolean
*/
public final void setGroup(boolean flag) {
m_group = flag;
}
/**
* Set the name scope
*
* @param scope String
*/
public final void setNameScope(String scope) {
if (scope == null)
m_scope = null;
else if (scope.length() > 0 && scope.startsWith("."))
m_scope = scope.substring(1);
else
m_scope = scope;
}
/**
* Add an IP address to the list of addresses for this NetBIOS name
*
* @param ipaddr byte[]
*/
public final void addIPAddress(byte[] ipaddr) {
if (m_addrList == null)
m_addrList = new ArrayList();
m_addrList.add(ipaddr);
}
/**
* Add a list of IP addresses to the list of addresses for this NetBIOS name
*
* @param addrList Vector (of byte[])
*/
public final void addIPAddresses(List addrList) {
if (m_addrList == null)
m_addrList = new ArrayList();
// Add the addresses
for (int i = 0; i < addrList.size(); i++) {
byte[] addr = addrList.get(i);
m_addrList.add(addr);
}
}
/**
* Set the local/remote NetBIOS name flag.
*
* @param local boolean
*/
public final void setLocalName(boolean local) {
m_local = local;
}
/**
* Set the NetBIOS name.
*
* @param name java.lang.String
*/
public final void setName(String name) {
// Check if the name contains a name scope, if so then split the name and scope id
int pos = name.indexOf(".");
if (pos != -1) {
// Split the name and scope id
setNameScope(name.substring(pos + 1));
m_name = toUpperCaseName(name.substring(0, pos));
} else {
// Set the name
m_name = toUpperCaseName(name);
}
}
/**
* Set the NetBIOS name type.
*
* @param typ char
*/
public final void setType(char typ) {
m_type = typ;
}
/**
* Set the name number
*
* @param nameNum int
*/
public final void setNameNumber(int nameNum) {
m_nameNum = nameNum;
}
/**
* Convert a name to uppercase
*
* @param name String
* @return String
*/
public static String toUpperCaseName(String name) {
// Trim the name, unless it looks like a special name
if (name.length() > 2 && name.charAt(0) != 0x01 && name.charAt(1) != 0x02)
name = name.trim();
// Convert the string to uppercase
if (name != null && name.length() > 0) {
StringBuffer upperName = new StringBuffer(name.length());
for (int i = 0; i < name.length(); i++) {
char ch = name.charAt(i);
if (ch >= 'a' && ch <= 'z')
upperName.append(Character.toUpperCase(ch));
else
upperName.append(ch);
}
// Return the uppercased name
return upperName.toString();
}
// Invalid or empty name
return "";
}
/**
* Determine if the name conversion character set has been configured
*
* @return boolean
*/
public final static boolean hasNameConversionCharacterSet() {
return _nameConversionCharset != null ? true : false;
}
/**
* Return the name conversion character set name
*
* @return String
*/
public final static String getNameConversionCharacterSet() {
return _nameConversionCharset;
}
/**
* Set the name conversion character set
*
* @param charSet String
*/
public final static void setNameConversionCharacterSet(String charSet) {
_nameConversionCharset = charSet;
}
/**
* Return the NetBIOS name as a string.
*
* @return String
*/
public String toString() {
StringBuffer str = new StringBuffer();
str.append("[");
str.append(m_name);
if (hasNameScope()) {
str.append(".");
str.append(m_scope);
}
str.append(":");
str.append(TypeAsString(m_type));
str.append(",");
if (m_group == true)
str.append("Group,");
else
str.append("Unique,");
if (getNameNumber() != -1) {
str.append(",Num=");
str.append(getNameNumber());
}
if (numberOfAddresses() > 0) {
str.append(",Addrs=");
for (int i = 0; i < numberOfAddresses(); i++) {
str.append(getIPAddressString(i));
str.append("|");
}
}
str.append("]");
return str.toString();
}
/**
* Convert a the NetBIOS name into RFC NetBIOS format.
*
* @return byte[]
*/
public byte[] encodeName() {
// Build the name string with the name type, make sure that the host
// name is uppercase.
StringBuffer nbName = new StringBuffer(getName().toUpperCase());
if (nbName.length() > (NameLength - 1))
nbName.setLength(NameLength - 1);
// Space pad the name then add the NetBIOS name type
while (nbName.length() < NameLength - 1)
nbName.append(' ');
nbName.append(getType());
// Allocate the return buffer.
//
// Length byte + encoded NetBIOS name length + name scope length + name scope
int len = 34;
if (hasNameScope())
len += getNameScope().length() + 1;
byte[] encBuf = new byte[len];
// Convert the NetBIOS name string to the RFC NetBIOS name format
int pos = 0;
encBuf[pos++] = (byte) 32;
int idx = 0;
while (idx < nbName.length()) {
// Get the current character from the host name string
char ch = nbName.charAt(idx++);
if (ch == ' ') {
// Append an encoded character
encBuf[pos++] = (byte) 'C';
encBuf[pos++] = (byte) 'A';
} else {
// Append octet for the current character
encBuf[pos++] = (byte) EncodeConversion.charAt((int) ch / 16);
encBuf[pos++] = (byte) EncodeConversion.charAt((int) ch % 16);
}
}
// Check if there is a NetBIOS name scope to be appended to the encoded name string
if (hasNameScope()) {
// Get the name scope and uppercase
StringTokenizer tokens = new StringTokenizer(getNameScope(), ".");
while (tokens.hasMoreTokens()) {
// Get the current token
String token = tokens.nextToken();
// Append the name to the encoded NetBIOS name
encBuf[pos++] = (byte) token.length();
for (int i = 0; i < token.length(); i++)
encBuf[pos++] = (byte) token.charAt(i);
}
}
// Terminate the encoded name string with a null section length
encBuf[pos++] = (byte) 0;
// Return the encoded NetBIOS name
return encBuf;
}
/**
* Find the best match address that the NetBIOS name is registered on that matches one of the
* local TCP/IP addresses
*
* @param addrList InetAddress[]
* @return int
*/
public final int findBestMatchAddress(InetAddress[] addrList) {
// Check if the address list is valid
if (addrList == null || addrList.length == 0 || numberOfAddresses() == 0)
return -1;
// If the NetBIOS name only has one address then just return the index
if (numberOfAddresses() == 1)
return 0;
// Search for a matching subnet
int topAddrIdx = -1;
int topIpIdx = -1;
for (int localIdx = 0; localIdx < addrList.length; localIdx++) {
// Get the address bytes for the current local address
byte[] localAddr = addrList[localIdx].getAddress();
// Match against the addresses that the NetBIOS name is registered against
for (int addrIdx = 0; addrIdx < numberOfAddresses(); addrIdx++) {
// Get the current remote address bytes
byte[] remoteAddr = (byte[]) m_addrList.get(addrIdx);
int ipIdx = 0;
while (ipIdx < 4 && remoteAddr[ipIdx] == localAddr[ipIdx])
ipIdx++;
// Check if the current address is the best match so far
if (ipIdx > topIpIdx) {
// Update the best match address
topIpIdx = addrIdx;
topAddrIdx = addrIdx;
}
}
}
// Return the best match index, or -1 if no match found
return topAddrIdx;
}
/**
* Decode a NetBIOS name string and create a new NetBIOSName object
*
* @param buf byte[]
* @param off int
* @return NetBIOSName
*/
public static NetBIOSName decodeNetBIOSName(byte[] buf, int off) {
// Convert the RFC NetBIOS name string to a normal NetBIOS name string
StringBuffer nameBuf = new StringBuffer(NameLength);
int nameLen = (int) buf[off++];
int idx = 0;
char ch1, ch2;
while (idx < nameLen) {
// Get the current encoded character pair from the encoded name string
ch1 = (char) buf[off++];
ch2 = (char) buf[off++];
if (ch1 == 'C' && ch2 == 'A') {
// Append a character
nameBuf.append(' ');
} else {
// Convert back to a character code
int val = EncodeConversion.indexOf(ch1) << 4;
val += EncodeConversion.indexOf(ch2);
// Append the current character to the decoded name
nameBuf.append((char) (val & 0xFF));
}
// Update the encoded string index
idx += 2;
}
// Decode the NetBIOS name scope, if specified
StringBuffer scopeBuf = new StringBuffer(128);
nameLen = (int) buf[off++];
while (nameLen > 0) {
// Append a name seperator if not the first name section
if (scopeBuf.length() > 0)
scopeBuf.append(".");
// Copy the name scope section to the scope name buffer
for (int i = 0; i < nameLen; i++)
scopeBuf.append((char) buf[off++]);
// Get the next name section length
nameLen = (int) buf[off++];
}
// Create a NetBIOS name
return new NetBIOSName(nameBuf.toString(), scopeBuf.toString());
}
/**
* Decode a NetBIOS name string length
*
* @param buf byte[]
* @param off int
* @return int
*/
public static int decodeNetBIOSNameLength(byte[] buf, int off) {
// Calculate the encoded NetBIOS name string length
int totLen = 1;
int nameLen = (int) buf[off++];
while (nameLen > 0) {
// Update the total encoded name length
totLen += nameLen;
off += nameLen;
// Get the next name section length
nameLen = (int) buf[off++];
totLen++;
}
// Return the encoded NetBIOS name length
return totLen;
}
/**
* Return the NetBIOS name type as a string.
*
* @param typ char
* @return String
*/
public final static String TypeAsString(char typ) {
// Return the NetBIOS name type string
String nameTyp = "";
switch (typ) {
case WorkStation:
nameTyp = "WorkStation";
break;
case Messenger:
nameTyp = "Messenger";
break;
case RemoteMessenger:
nameTyp = "RemoteMessenger";
break;
case RASServer:
nameTyp = "RASServer";
break;
case FileServer:
nameTyp = "FileServer";
break;
case RASClientService:
nameTyp = "RASClientService";
break;
case MSExchangeInterchange:
nameTyp = "MSExchangeInterchange";
break;
case MSExchangeStore:
nameTyp = "MSExchangeStore";
break;
case MSExchangeDirectory:
nameTyp = "MSExchangeDirectory";
break;
case LotusNotesServerService:
nameTyp = "LotusNotesServerService";
break;
case ModemSharingService:
nameTyp = "ModemSharingService";
break;
case ModemSharingClient:
nameTyp = "ModemSharingClient";
break;
case McCaffeeAntiVirus:
nameTyp = "McCaffeeAntiVirus";
break;
case SMSClientRemoteControl:
nameTyp = "SMSClientRemoteControl";
break;
case SMSAdminRemoteControl:
nameTyp = "SMSAdminRemoteControl";
break;
case SMSClientRemoteChat:
nameTyp = "SMSClientRemoteChat";
break;
case SMSClientRemoteTransfer:
nameTyp = "SMSClientRemoteTransfer";
break;
case DECPathworksService:
nameTyp = "DECPathworksService";
break;
case MSExchangeIMC:
nameTyp = "MSExchangeIMC";
break;
case MSExchangeMTA:
nameTyp = "MSExchangeMTA";
break;
case NetworkMonitorAgent:
nameTyp = "NetworkMonitorAgent";
break;
case NetworkMonitorApp:
nameTyp = "NetworkMonitorApp";
break;
case DomainMasterBrowser:
nameTyp = "DomainMasterBrowser";
break;
case MasterBrowser:
nameTyp = "MasterBrowser";
break;
case DomainAnnounce:
nameTyp = "DomainAnnounce";
break;
case DomainControllers:
nameTyp = "DomainControllers";
break;
default:
nameTyp = "0x" + Integer.toHexString((int) typ);
break;
}
return nameTyp;
}
}