pkg://jcifs-0.8.2-1jpp.src.rpm:566555/jcifs-0.8.2.tgz
info downloads
jcifs_0.8.2/src/jcifs/netbios/Log.java 100644 0 0 7064 10025170724 14751 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.util.Hashtable;
import java.util.Enumeration;
/**
* Provides logging methods specific to the netbios package. Log class
* members are applied to the Log's mask(set as an arithmetic expression
* from {@link jcifs.util.Log#setMask(int mask)}) to "flip on" logging of
* netbios specific information.
* <p><blockquote><pre>
* Log.setMask( Log.EXCEPTIONS +
* jcifs.netbios.Log.SESSION_SERVICE_PACKET_DATA );
* </pre></blockquote>
* <p>
* See the {@link jcifs.util.Log} parent class for details about this
* logging style.
*
* @see jcifs.util.Log
*/
public class Log extends jcifs.util.Log {
// supress javadoc constructor summary
Log() {}
public static final int NONE = 0xFFFFFF0F;
public static final int ALL = 0x000000F0;
/**
*
* This mask produces limited netbios name service packet information. See
* <a href="http://www.cis.ohio-state.edu/rfc/rfc1002.txt">RFC 1002</a>
* for a detailed description of packet contents and their meaning.
*
* @see jcifs.util.Log#setMask(int mask)
*/
public static final int NAME_SERVICE_PACKET_DATA = 0x00000010;
public static final int SESSION_SERVICE_PACKET_DATA = 0x00000020;
/**
* This mask produces the contents of the netbios address cache.
*
* @see jcifs.util.Log#setMask(int mask)
*/
public static final int ADDRESS_CACHE = 0x00000040;
/**
* reserved for this package
*/
public static final int RESERVED8 = 0x00000080;
static void printPacketData( String desc, SessionServicePacket ssp ) {
try { // why do I have try/catch here?
if(( SESSION_SERVICE_PACKET_DATA & mask ) == 0 ) {
return;
}
out.println( desc, ssp.toString() );
} catch( Exception e ) {
Log.printStackTrace( "jcifs.netbios.Log.printPacketData()", e );
}
}
static void printPacketData( String desc, NameServicePacket nsp ) {
try {
if(( NAME_SERVICE_PACKET_DATA & mask ) == 0 ) {
return;
}
out.println( desc, nsp.toString() );
} catch( Exception e ) {
Log.printStackTrace( "jcifs.netbios.Log.printPacketData()", e );
}
}
static void printAddressCache( String desc, Hashtable addressCache ) {
if(( ADDRESS_CACHE & mask ) == 0 )
return;
StringBuffer sb = new StringBuffer();
NbtAddress.CacheEntry ce;
for( Enumeration e = addressCache.elements(); e.hasMoreElements(); ) {
ce = (NbtAddress.CacheEntry)e.nextElement();
sb.append( ' ' ).append( ce.hostName );
sb.append( ' ' ).append( ce.address ).append( NL );
}
out.println( desc, sb.toString() );
}
}
jcifs_0.8.2/src/jcifs/netbios/NbtException.java 100644 0 0 6346 10025170724 16634 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.io.IOException;
public class NbtException extends IOException {
// error classes
public static final int SUCCESS = 0;
public static final int ERR_NAM_SRVC = 0x01;
public static final int ERR_SSN_SRVC = 0x02;
// name service error codes
public static final int FMT_ERR = 0x1;
public static final int SRV_ERR = 0x2;
public static final int IMP_ERR = 0x4;
public static final int RFS_ERR = 0x5;
public static final int ACT_ERR = 0x6;
public static final int CFT_ERR = 0x7;
// session service error codes
public static final int CONNECTION_REFUSED = -1;
public static final int NOT_LISTENING_CALLED = 0x80;
public static final int NOT_LISTENING_CALLING = 0x81;
public static final int CALLED_NOT_PRESENT = 0x82;
public static final int NO_RESOURCES = 0x83;
public static final int UNSPECIFIED = 0x8F;
public int errorClass;
public int errorCode;
public static String getErrorString( int errorClass, int errorCode ) {
String result = "";
switch( errorClass ) {
case SUCCESS:
result += "SUCCESS";
break;
case ERR_NAM_SRVC:
result += "ERR_NAM_SRVC/";
switch( errorCode ) {
case FMT_ERR:
result += "FMT_ERR: Format Error";
default:
result += "Unknown error code: " + errorCode;
}
break;
case ERR_SSN_SRVC:
result += "ERR_SSN_SRVC/";
switch( errorCode ) {
case CONNECTION_REFUSED:
result += "Connection refused";
break;
case NOT_LISTENING_CALLED:
result += "Not listening on called name";
break;
case NOT_LISTENING_CALLING:
result += "Not listening for calling name";
break;
case CALLED_NOT_PRESENT:
result += "Called name not present";
break;
case NO_RESOURCES:
result += "Called name present, but insufficient resources";
break;
case UNSPECIFIED:
result += "Unspecified error";
break;
default:
result += "Unknown error code: " + errorCode;
}
break;
default:
result += "unknown error class: " + errorClass;
}
return result;
}
public NbtException( int errorClass, int errorCode ) {
super( getErrorString( errorClass, errorCode ));
this.errorClass = errorClass;
this.errorCode = errorCode;
}
public String toString() {
return new String( "errorClass=" + errorClass + ",errorCode=" + errorCode + ",errorString=" + getErrorString( errorClass, errorCode ));
}
}
jcifs_0.8.2/src/jcifs/netbios/NbtAddress.java 100644 0 0 64755 10025170724 16313 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.SocketException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;
import jcifs.Config;
/**
* This class represents a NetBIOS over TCP/IP address. Under normal
* conditions, users of jCIFS need not be concerned with this class as
* name resolution and session services are handled internally by the smb package.
*
* <p> Applications can use the methods <code>getLocalHost</code>,
* <code>getByName</code>, and
* <code>getAllByAddress</code> to create a new NbtAddress instance. This
* class is symmetric with {@link java.net.InetAddress}.
*
* <p><b>About NetBIOS:</b> The NetBIOS name
* service is a dynamic distributed service that allows hosts to resolve
* names by broadcasting a query, directing queries to a server such as
* Samba or WINS. NetBIOS is currently the primary networking layer for
* providing name service, datagram service, and session service to the
* Microsoft Windows platform. A NetBIOS name can be 15 characters long
* and hosts usually registers several names on the network. From a
* Windows command prompt you can see
* what names a host registers with the nbtstat command.
* <p><blockquote><pre>
* C:\>nbtstat -a 192.168.1.15
*
* NetBIOS Remote Machine Name Table
*
* Name Type Status
* ---------------------------------------------
* JMORRIS2 <00> UNIQUE Registered
* BILLING-NY <00> GROUP Registered
* JMORRIS2 <03> UNIQUE Registered
* JMORRIS2 <20> UNIQUE Registered
* BILLING-NY <1E> GROUP Registered
* JMORRIS <03> UNIQUE Registered
*
* MAC Address = 00-B0-34-21-FA-3B
* </blockquote></pre>
* <p> The hostname of this machine is <code>JMORRIS2</code>. It is
* a member of the group(a.k.a workgroup and domain) <code>BILLING-NY</code>. To
* obtain an {@link java.net.InetAddress} for a host one might do:
*
* <pre>
* InetAddress addr = NbtAddress.getByName( "jmorris2" ).getInetAddress();
* </pre>
* <p>From a UNIX platform with Samba installed you can perform similar
* diagnostics using the <code>nmblookup</code> utility.
*
* @author Michael B. Allen
* @see java.net.InetAddress
* @since jcifs-0.1
*/
public final class NbtAddress {
/*
* This is a special name that means all hosts. If you wish to find all hosts
* on a network querying a workgroup group name is the preferred method.
*/
static final String ANY_HOSTS_NAME = "*\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000";
/**
* This is a special name for querying the master browser that serves the
* list of hosts found in "Network Neighborhood".
*/
public static final String MASTER_BROWSER_NAME = "\u0001\u0002__MSBROWSE__\u0002";
/**
* A special generic name specified when connecting to a host for which
* a name is not known. Not all servers respond to this name.
*/
public static final String SMBSERVER_NAME = "*SMBSERVER ";
/**
* A B node only broadcasts name queries. This is the default if a
* nameserver such as WINS or Samba is not specified.
*/
public static final int B_NODE = 0;
/**
* A Point-to-Point node, or P node, unicasts queries to a nameserver
* only. Natrually the <code>jcifs.netbios.nameserver</code> property must
* be set.
*/
public static final int P_NODE = 1;
/**
* Try Broadcast queries first, then try to resolve the name using the
* nameserver.
*/
public static final int M_NODE = 2;
/**
* A Hybrid node tries to resolve a name using the nameserver first. If
* that fails use the broadcast address. This is the default if a nameserver
* is provided. This is the behavior of Microsoft Windows machines.
*/
public static final int H_NODE = 3;
static final int DEFAULT_CACHE_POLICY = 30;
static final int FOREVER = -1;
static int cachePolicy;
static Hashtable addressCache;
static Hashtable lookupTable;
static Name unknownName;
static NbtAddress unknownAddress;
static byte[] unknownMacAddress = new byte[] {
(byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00
};
static final class CacheEntry {
Name hostName;
NbtAddress address;
long expiration;
CacheEntry( Name hostName, NbtAddress address, long expiration ) {
this.hostName = hostName;
this.address = address;
this.expiration = expiration;
}
}
static NameServiceClient client;
static NbtAddress localhost;
static {
InetAddress localInetAddress;
String localHostname;
Name localName;
addressCache = new Hashtable();
lookupTable = new Hashtable();
cachePolicy = Config.getInt( "jcifs.netbios.cachePolicy", DEFAULT_CACHE_POLICY );
/* Construct the shared static client object that will
* conduct all encoding and decoding of NetBIOS name service
* messages as well as socket IO in a synchronized fashon.
*/
client = new NameServiceClient();
/* Create an address to represent failed lookups and cache forever.
*/
unknownName = new Name( "0.0.0.0", 0x00, null );
unknownAddress = new NbtAddress( unknownName, 0, false, B_NODE );
addressCache.put( unknownName,
new CacheEntry( unknownName, unknownAddress, FOREVER ));
/* Determine the InetAddress of the local interface
* if one was not specified.
*/
localInetAddress = client.laddr;
if( localInetAddress == null ) {
try {
localInetAddress = InetAddress.getLocalHost();
} catch( UnknownHostException uhe ) {
}
}
/* If a local hostname was not provided a name like
* JCIFS34_172_A6 will be dynamically generated for the
* client. This is primarily (exclusively?) used as a
* CallingName during session establishment.
*/
localHostname = Config.getProperty( "jcifs.netbios.hostname", null );
if( localHostname == null || localHostname.length() == 0 ) {
byte[] addr = localInetAddress.getAddress();
localHostname = "JCIFS" +
( addr[2] & 0xFF ) + "_" +
( addr[3] & 0xFF ) + "_" +
Name.toHexChars( (int)( Math.random() * (double)0xFF ));
}
/* Create an NbtAddress for the local interface with
* the name deduced above possibly with scope applied and
* cache it forever.
*/
localName = new Name( localHostname, 0x00,
Config.getProperty( "jcifs.netbios.scope", null ));
localhost = new NbtAddress( localName,
localInetAddress.hashCode(),
false,
B_NODE,
false, false, true, false,
unknownMacAddress );
cacheAddress( localName, localhost, FOREVER );
}
static void cacheAddress( Name hostName, NbtAddress addr ) {
if( cachePolicy == 0 ) {
return;
}
long expiration = -1;
if( cachePolicy != FOREVER ) {
expiration = System.currentTimeMillis() + cachePolicy * 1000;
}
cacheAddress( hostName, addr, expiration );
}
static void cacheAddress( Name hostName, NbtAddress addr, long expiration ) {
if( cachePolicy == 0 ) {
return;
}
synchronized( addressCache ) {
CacheEntry entry = (CacheEntry)addressCache.get( hostName );
if( entry == null ) {
entry = new CacheEntry( hostName, addr, expiration );
addressCache.put( hostName, entry );
} else {
entry.address = addr;
entry.expiration = expiration;
}
Log.printAddressCache( "name service address cache", addressCache );
}
}
static void cacheAddressArray( NbtAddress[] addrs ) {
if( cachePolicy == 0 ) {
return;
}
long expiration = -1;
if( cachePolicy != FOREVER ) {
expiration = System.currentTimeMillis() + cachePolicy * 1000;
}
synchronized( addressCache ) {
for( int i = 0; i < addrs.length; i++ ) {
CacheEntry entry = (CacheEntry)addressCache.get( addrs[i].hostName );
if( entry == null ) {
entry = new CacheEntry( addrs[i].hostName, addrs[i], expiration );
addressCache.put( addrs[i].hostName, entry );
} else {
entry.address = addrs[i];
entry.expiration = expiration;
}
}
Log.printAddressCache( "name service address cache", addressCache );
}
}
static NbtAddress getCachedAddress( Name hostName ) {
if( cachePolicy == 0 ) {
return null;
}
synchronized( addressCache ) {
CacheEntry entry = (CacheEntry)addressCache.get( hostName );
if( entry != null && entry.expiration < System.currentTimeMillis() &&
entry.expiration >= 0 ) {
entry = null;
}
return entry != null ? entry.address : null;
}
}
static NbtAddress doNameQuery( Name name, InetAddress svr )
throws UnknownHostException {
NbtAddress addr;
if( name.hexCode == 0x1d && svr == null ) {
svr = client.baddr; // bit of a hack but saves a lookup
}
name.srcHashCode = svr != null ? svr.hashCode() : 0;
addr = getCachedAddress( name );
if( addr == null ) {
/* This was copied amost verbatim from InetAddress.java. See the
* comments there for a description of how the lookupTable prevents
* redundant queries from going out on the wire.
*/
if(( addr = (NbtAddress)checkLookupTable( name )) == null ) {
try {
addr = client.getByName( name, svr );
} catch( UnknownHostException uhe ) {
addr = unknownAddress;
} finally {
cacheAddress( name, addr );
updateLookupTable( name );
}
}
}
if( addr == unknownAddress ) {
throw new UnknownHostException( name.toString() );
}
return addr;
}
private static Object checkLookupTable( Name name ) {
Object obj;
synchronized( lookupTable ) {
if( lookupTable.containsKey( name ) == false ) {
lookupTable.put( name, name );
return null;
}
while( lookupTable.containsKey( name )) {
try {
lookupTable.wait();
} catch( InterruptedException e ) {
}
}
}
obj = getCachedAddress( name );
if( obj == null ) {
synchronized( lookupTable ) {
lookupTable.put( name, name );
}
}
return obj;
}
private static void updateLookupTable( Name name ) {
synchronized( lookupTable ) {
lookupTable.remove( name );
lookupTable.notifyAll();
}
}
/**
* Retrieves the local host address.
*
* @throws UnknownHostException This is not likely as the IP returned
* by <code>InetAddress</code> should be available
*/
public static NbtAddress getLocalHost() throws UnknownHostException {
return localhost;
}
/**
* Determines the address of a host given it's host name. The name can be a NetBIOS name like
* "freto" or an IP address like "192.168.1.15". It cannot be a DNS name;
* the analygous {@link jcifs.UniAddress} or {@link java.net.InetAddress}
* <code>getByName</code> methods can be used for that.
*
* @param host hostname to resolve
* @throws java.net.UnknownHostException if there is an error resolving the name
*/
public static NbtAddress getByName( String host )
throws UnknownHostException {
return getByName( host, 0x00, null );
}
/**
* Determines the address of a host given it's host name. NetBIOS
* names also have a <code>type</code>. Types(aka Hex Codes)
* are used to distiquish the various services on a host. <a
* href="../../../nbtcodes.html">Here</a> is
* a fairly complete list of NetBIOS hex codes. Scope is not used but is
* still functional in other NetBIOS products and so for completeness it has been
* implemented. A <code>scope</code> of <code>null</code> or <code>""</code>
* signifies no scope.
*
* @param host the name to resolve
* @param type the hex code of the name
* @param scope the scope of the name
* @throws java.net.UnknownHostException if there is an error resolving the name
*/
public static NbtAddress getByName( String host,
int type,
String scope )
throws UnknownHostException {
return getByName( host, type, scope, null );
}
/*
* The additional <code>svr</code> parameter specifies the address to
* query. This might be the address of a specific host, a name server,
* or a broadcast address.
*/
public static NbtAddress getByName( String host,
int type,
String scope,
InetAddress svr )
throws UnknownHostException {
if( host == null || host.length() == 0 ) {
return getLocalHost();
}
if( !Character.isDigit( host.charAt(0) )) {
return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr );
} else {
int IP = 0x00;
int hitDots = 0;
char[] data = host.toCharArray();
for( int i = 0; i < data.length; i++ ) {
char c = data[i];
if( c < 48 || c > 57 ) {
return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr );
}
int b = 0x00;
while( c != '.' ) {
if( c < 48 || c > 57 ) {
return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr );
}
b = b * 10 + c - '0';
if( ++i >= data.length )
break;
c = data[i];
}
if( b > 0xFF ) {
return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr );
}
IP = ( IP << 8 ) + b;
hitDots++;
}
if( hitDots != 4 || host.endsWith( "." )) {
return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr );
}
return new NbtAddress( unknownName, IP, false, B_NODE );
}
}
/**
* Retrieve all addresses of a host by it's address. NetBIOS hosts can
* have many names for a given IP address. The name and IP address make the
* NetBIOS address. This provides a way to retrieve the other names for a
* host with the same IP address.
*
* @param host hostname to lookup all addresses for
* @throws java.net.UnknownHostException if there is an error resolving the name
*/
public static NbtAddress[] getAllByAddress( String host )
throws UnknownHostException {
return getAllByAddress( getByName( host, 0x00, null ));
}
/**
* Retrieve all addresses of a host by it's address. NetBIOS hosts can
* have many names for a given IP address. The name and IP address make
* the NetBIOS address. This provides a way to retrieve the other names
* for a host with the same IP address. See {@link #getByName}
* for a description of <code>type</code>
* and <code>scope</code>.
*
* @param host hostname to lookup all addresses for
* @param type the hexcode of the name
* @param scope the scope of the name
* @throws java.net.UnknownHostException if there is an error resolving the name
*/
public static NbtAddress[] getAllByAddress( String host,
int type,
String scope )
throws UnknownHostException {
return getAllByAddress( getByName( host, type, scope ));
}
/**
* Retrieve all addresses of a host by it's address. NetBIOS hosts can
* have many names for a given IP address. The name and IP address make the
* NetBIOS address. This provides a way to retrieve the other names for a
* host with the same IP address.
*
* @param addr the address to query
* @throws UnknownHostException if address cannot be resolved
*/
public static NbtAddress[] getAllByAddress( NbtAddress addr )
throws UnknownHostException {
try {
NbtAddress[] addrs = client.getNodeStatus( addr );
cacheAddressArray( addrs );
return addrs;
} catch( UnknownHostException uhe ) {
throw new UnknownHostException( "no name with type 0x" +
Name.toHexChars( addr.hostName.hexCode ) +
((( addr.hostName.scope == null ) ||
( addr.hostName.scope.length() == 0 )) ?
" with no scope" : " with scope " + addr.hostName.scope ) +
" for host " + addr.getHostAddress() );
}
}
Name hostName;
int address, nodeType;
boolean groupName,
isBeingDeleted,
isInConflict,
isActive,
isPermanent,
isDataFromNodeStatus;
byte[] macAddress;
String calledName;
NbtAddress( Name hostName, int address, boolean groupName, int nodeType ) {
this.hostName = hostName;
this.address = address;
this.groupName = groupName;
this.nodeType = nodeType;
}
NbtAddress( Name hostName,
int address,
boolean groupName,
int nodeType,
boolean isBeingDeleted,
boolean isInConflict,
boolean isActive,
boolean isPermanent,
byte[] macAddress ) {
/* The NodeStatusResponse.readNodeNameArray method may also set this
* information. These two places where node status data is populated should
* be consistent. Be carefull!
*/
this.hostName = hostName;
this.address = address;
this.groupName = groupName;
this.nodeType = nodeType;
this.isBeingDeleted = isBeingDeleted;
this.isInConflict = isInConflict;
this.isActive = isActive;
this.isPermanent = isPermanent;
this.macAddress = macAddress;
isDataFromNodeStatus = true;
}
/* Guess next called name to try for session establishment. These
* methods are used by the smb package.
*/
public String firstCalledName() {
calledName = hostName.name;
if( Character.isDigit( calledName.charAt( 0 ))) {
int i, len, dots;
char[] data;
i = dots = 0; /* quick IP address validation */
len = calledName.length();
data = calledName.toCharArray();
while( i < len && Character.isDigit( data[i++] )) {
if( i == len && dots == 3 ) {
// probably an IP address
calledName = SMBSERVER_NAME;
break;
}
if( i < len && data[i] == '.' ) {
dots++;
i++;
}
}
} else if( hostName.hexCode == 0x1D ) {
calledName = SMBSERVER_NAME;
}
return calledName;
}
public String nextCalledName() {
if( calledName == hostName.name ) {
calledName = SMBSERVER_NAME;
} else if( calledName == SMBSERVER_NAME ) {
NbtAddress[] addrs;
try {
addrs = client.getNodeStatus( this );
if( hostName.hexCode == 0x1D ) {
for( int i = 0; i < addrs.length; i++ ) {
if( addrs[i].hostName.hexCode == 0x20 ) {
return addrs[i].hostName.name;
}
}
return null;
} else if( isDataFromNodeStatus ) {
/* 'this' has been updated and should now
* have a real NetBIOS name
*/
calledName = null;
return hostName.name;
}
} catch( UnknownHostException uhe ) {
calledName = null;
}
} else {
calledName = null;
}
return calledName;
}
/*
* There are three degrees of state that any NbtAddress can have.
*
* 1) IP Address - If a dot-quad IP string is used with getByName (or used
* to create an NbtAddress internal to this netbios package), no query is
* sent on the wire and the only state this object has is it's IP address
* (but that's enough to connect to a host using *SMBSERVER for CallingName).
*
* 2) IP Address, NetBIOS name, nodeType, groupName - If however a
* legal NetBIOS name string is used a name query request will retreive
* the IP, node type, and whether or not this NbtAddress represents a
* group name. This degree of state can be obtained with a Name Query
* Request or Node Status Request.
*
* 3) All - The NbtAddress will be populated with all state such as mac
* address, isPermanent, isBeingDeleted, ...etc. This information can only
* be retrieved with the Node Status request.
*
* The degree of state that an NbtAddress has is dependant on how it was
* created and what is required of it. The second degree of state is the
* most common. This is the state information that would be retrieved from
* WINS for example. Natrually it is not practical for every NbtAddress
* to be populated will all state requiring a Node Status on every host
* encountered. The below methods allow state to be populated when requested
* in a lazy fashon.
*/
void checkData() throws UnknownHostException {
if( hostName == unknownName ) {
getAllByAddress( this );
}
}
void checkNodeStatusData() throws UnknownHostException {
if( isDataFromNodeStatus == false ) {
getAllByAddress( this );
}
}
/**
* Determines if the address is a group address. This is also
* known as a workgroup name or group name.
*
* @throws UnknownHostException if the host cannot be resolved to find out.
*/
public boolean isGroupAddress() throws UnknownHostException {
checkData();
return groupName;
}
/**
* Checks the node type of this address.
* @return {@link jcifs.netbios.NbtAddress#B_NODE},
* {@link jcifs.netbios.NbtAddress#P_NODE}, {@link jcifs.netbios.NbtAddress#M_NODE},
* {@link jcifs.netbios.NbtAddress#H_NODE}
*
* @throws UnknownHostException if the host cannot be resolved to find out.
*/
public int getNodeType() throws UnknownHostException {
checkData();
return nodeType;
}
/**
* Determines if this address in the process of being deleted.
*
* @throws UnknownHostException if the host cannot be resolved to find out.
*/
public boolean isBeingDeleted() throws UnknownHostException {
checkNodeStatusData();
return isBeingDeleted;
}
/**
* Determines if this address in conflict with another address.
*
* @throws UnknownHostException if the host cannot be resolved to find out.
*/
public boolean isInConflict() throws UnknownHostException {
checkNodeStatusData();
return isInConflict;
}
/**
* Determines if this address is active.
*
* @throws UnknownHostException if the host cannot be resolved to find out.
*/
public boolean isActive() throws UnknownHostException {
checkNodeStatusData();
return isActive;
}
/**
* Determines if this address is set to be permanent.
*
* @throws UnknownHostException if the host cannot be resolved to find out.
*/
public boolean isPermanent() throws UnknownHostException {
checkNodeStatusData();
return isPermanent;
}
/**
* Retrieves the MAC address of the remote network interface. Samba returns all zeros.
*
* @return the MAC address as an array of six bytes
* @throws UnknownHostException if the host cannot be resolved to
* determine the MAC address.
*/
public byte[] getMacAddress() throws UnknownHostException {
checkNodeStatusData();
return macAddress;
}
/**
* The hostname of this address. If the hostname is null the local machines
* IP address is returned.
*
* @return the text representation of the hostname associated with this address
*/
public String getHostName() {
try {
checkData();
} catch( UnknownHostException uhe ) {
return getHostAddress();
}
return hostName.name;
}
/**
* Returns the raw IP address of this NbtAddress. The result is in network
* byte order: the highest order byte of the address is in getAddress()[0].
*
* @return a four byte array
*/
public byte[] getAddress() {
byte[] addr = new byte[4];
addr[0] = (byte)(( address >>> 24 ) & 0xFF );
addr[1] = (byte)(( address >>> 16 ) & 0xFF );
addr[2] = (byte)(( address >>> 8 ) & 0xFF );
addr[3] = (byte)( address & 0xFF );
return addr;
}
/**
* To convert this address to an <code>InetAddress</code>.
*
* @return the {@link java.net.InetAddress} representation of this address.
*/
public InetAddress getInetAddress() throws UnknownHostException {
return InetAddress.getByName( getHostAddress() );
}
/**
* Returns this IP adress as a {@link java.lang.String} in the form "%d.%d.%d.%d".
*/
public String getHostAddress() {
return (( address >>> 24 ) & 0xFF ) + "." +
(( address >>> 16 ) & 0xFF ) + "." +
(( address >>> 8 ) & 0xFF ) + "." +
(( address >>> 0 ) & 0xFF );
}
/**
* Returned the hex code associated with this name(e.g. 0x20 is for the file service)
*/
public int getNameType() {
return hostName.hexCode;
}
/**
* Returns a hashcode for this IP address. The hashcode comes from the IP address
* and is not generated from the string representation. So because NetBIOS nodes
* can have many names, all names associated with an IP will have the same
* hashcode.
*/
public int hashCode() {
return address;
}
/**
* Determines if this address is equal two another. Only the IP Addresses
* are compared. Similar to the {@link #hashCode} method, the comparison
* is based on the integer IP address and not the string representation.
*/
public boolean equals( Object obj ) {
return ( obj != null ) && ( obj instanceof NbtAddress ) &&
( ((NbtAddress)obj).address == address );
}
/**
* Returns the {@link java.lang.String} representaion of this address.
*/
public String toString() {
return hostName.toString() + "/" + getHostAddress();
}
}
jcifs_0.8.2/src/jcifs/netbios/SocketOutputStream.java 100644 0 0 5437 10025170724 20057 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.io.FilterOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import jcifs.util.Log;
class SocketOutputStream extends FilterOutputStream {
private static int DEFAULT_BUFR_SIZE = 4400;
private byte[] bufr;
private int count, writeSize;
SocketOutputStream( OutputStream out ) {
this( out, DEFAULT_BUFR_SIZE );
}
SocketOutputStream( OutputStream out, int size ) {
super( out );
writeSize = jcifs.Config.getInt( "jcifs.netbios.client.writeSize", size );
if( writeSize <= 0 ) {
throw new IllegalArgumentException( "buffer size <= 0" );
} else if( writeSize > SessionServicePacket.MAX_MESSAGE_SIZE ) {
throw new IllegalArgumentException( "buffer exceeds max netbios message size" );
}
writeSize += 4;
bufr = new byte[writeSize];
bufr[0] = (byte)SessionServicePacket.SESSION_MESSAGE;
count = 4;
}
public synchronized void write( int b ) throws IOException {
if( count >= bufr.length ) {
flush();
}
bufr[count++] = (byte)b;
}
public synchronized void write( byte[] b, int off, int len ) throws IOException {
if(( len + 4 ) > bufr.length ) {
Log.println( Log.WARNINGS, "session service warning",
"write len exceeds pre-allocated buffer size; performance " +
"will suffer: len=" + len + ",writeSize=" + writeSize );
flush();
byte[] tmp = bufr;
bufr = new byte[len + 4]; /* at least mantain a permainent fixed size buffer */
System.arraycopy( b, off, bufr, count, len ); /* doah! */
count += len;
flush();
bufr = tmp;
return;
}
if( len > bufr.length - count ) {
flush();
}
System.arraycopy( b, off, bufr, count, len );
count += len;
}
public synchronized void flush() throws IOException {
if( count == 4 ) {
return;
}
int n = count - 4;
bufr[1] = (byte)(( n & 0x010000 ) == 0x00 ? 0x00 : 0x01 );
bufr[2] = (byte)(( n >> 8 ) & 0xFF );
bufr[3] = (byte)( n & 0xFF );
out.write( bufr, 0, count );
out.flush();
count = 4;
}
}
jcifs_0.8.2/src/jcifs/netbios/NameQueryRequest.java 100644 0 0 2713 10025170724 17503 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
class NameQueryRequest extends NameServicePacket {
NameQueryRequest( Name name ) {
questionName = name;
questionType = NB;
}
int writeBodyWireFormat( byte[] dst, int dstIndex ) {
return writeQuestionSectionWireFormat( dst, dstIndex );
}
int readBodyWireFormat( byte[] src, int srcIndex ) {
return readQuestionSectionWireFormat( src, srcIndex );
}
int writeRDataWireFormat( byte[] dst, int dstIndex ) {
return 0;
}
int readRDataWireFormat( byte[] src, int srcIndex ) {
return 0;
}
public String toString() {
return new String( "NameQueryRequest[" +
super.toString() + "]" );
}
}
jcifs_0.8.2/src/jcifs/netbios/Name.java 100644 0 0 14444 10025170724 15130 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
* "Christopher R. Hertel" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.io.UnsupportedEncodingException;
import jcifs.Config;
class Name {
static final char[] HEX_DIGITS = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'A' , 'B' ,
'C' , 'D' , 'E' , 'F'
};
static String toHexChars( int val ) {
int len = 2;
char[] tmp = new char[2];
while( len > 0 ) {
tmp[ len - 1 ] = HEX_DIGITS[val & 0x000F];
if( val != 0 ) {
val >>>= 4;
}
len--;
}
return new String( tmp );
}
static final int TYPE_OFFSET = 31;
static final int SCOPE_OFFSET = 33;
static String defaultScope = Config.getProperty( "jcifs.netbios.scope" );
static String encoding = Config.getProperty( "jcifs.netbios.encoding", "ISO8859_1" );
String name, scope;
int hexCode;
int srcHashCode; /* srcHashCode must be set by name resolution
* routines before entry into addressCache
*/
Name() {
}
Name( String name, int hexCode, String scope ) {
if( name.length() > 15 ) {
name = name.substring( 0, 15 );
}
this.name = name.toUpperCase();
this.hexCode = hexCode;
this.scope = scope != null && scope.length() > 0 ? scope : defaultScope;
this.srcHashCode = 0;
}
int writeWireFormat( byte[] dst, int dstIndex ) {
// write 0x20 in first byte
dst[dstIndex] = 0x20;
// write name
try {
byte tmp[] = name.getBytes( Name.encoding );
int i;
for( i = 0; i < tmp.length; i++ ) {
dst[dstIndex + ( 2 * i + 1 )] = (byte)((( tmp[i] & 0xF0 ) >> 4 ) + 0x41 );
dst[dstIndex + ( 2 * i + 2 )] = (byte)(( tmp[i] & 0x0F ) + 0x41 );
}
for( ; i < 15; i++ ) {
dst[dstIndex + ( 2 * i + 1 )] = (byte)0x43;
dst[dstIndex + ( 2 * i + 2 )] = (byte)0x41;
}
dst[dstIndex + TYPE_OFFSET] = (byte)((( hexCode & 0xF0 ) >> 4 ) + 0x41 );
dst[dstIndex + TYPE_OFFSET + 1] = (byte)(( hexCode & 0x0F ) + 0x41 );
} catch( UnsupportedEncodingException uee ) {
}
return SCOPE_OFFSET + writeScopeWireFormat( dst, dstIndex + SCOPE_OFFSET );
}
int readWireFormat( byte[] src, int srcIndex ) {
byte tmp[] = new byte[SCOPE_OFFSET];
int length = 15;
for( int i = 0; i < 15; i++ ) {
tmp[i] = (byte)((( src[srcIndex + ( 2 * i + 1 )] & 0xFF ) - 0x41 ) << 4 );
tmp[i] |= (byte)((( src[srcIndex + ( 2 * i + 2 )] & 0xFF ) - 0x41 ) & 0x0F );
if( tmp[i] != (byte)' ' ) {
length = i + 1;
}
}
try {
name = new String( tmp, 0, length, Name.encoding );
} catch( UnsupportedEncodingException uee ) {
}
hexCode = (( src[srcIndex + TYPE_OFFSET] & 0xFF ) - 0x41 ) << 4;
hexCode |= (( src[srcIndex + TYPE_OFFSET + 1] & 0xFF ) - 0x41 ) & 0x0F;
return SCOPE_OFFSET + readScopeWireFormat( src, srcIndex + SCOPE_OFFSET );
}
int writeScopeWireFormat( byte[] dst, int dstIndex ) {
if( scope == null ) {
dst[dstIndex] = (byte)0x00;
return 1;
}
// copy new scope in
dst[dstIndex++] = (byte)'.';
try {
System.arraycopy( scope.getBytes( encoding ), 0, dst, dstIndex, scope.length() );
} catch( UnsupportedEncodingException uee ) {
}
dstIndex += scope.length();
dst[dstIndex++] = (byte)0x00;
// now go over scope backwards converting '.' to label length
int i = dstIndex - 2;
int e = i - scope.length();
int c = 0;
do {
if( dst[i] == '.' ) {
dst[i] = (byte)c;
c = 0;
} else {
c++;
}
} while( i-- > e );
return scope.length() + 2;
}
int readScopeWireFormat( byte[] src, int srcIndex ) {
int start = srcIndex;
int n;
StringBuffer sb;
if(( n = src[srcIndex++] & 0xFF ) == 0 ) {
scope = null;
return 1;
}
try {
sb = new StringBuffer( new String( src, srcIndex, n, Name.encoding ));
srcIndex += n;
while(( n = src[srcIndex++] & 0xFF ) != 0 ) {
sb.append( '.' ).append( new String( src, srcIndex, n, Name.encoding ));
srcIndex += n;
}
scope = sb.toString();
} catch( UnsupportedEncodingException uee ) {
}
return srcIndex - start;
}
public int hashCode() {
int result;
result = name.hashCode();
result += 65599 * hexCode;
result += 65599 * srcHashCode; /* hashCode is different depending
* on where it came from
*/
if( scope != null && scope.length() != 0 ) {
result += scope.hashCode();
}
return result;
}
public boolean equals( Object obj ) {
Name n;
if( !( obj instanceof Name )) {
return false;
}
n = (Name)obj;
if( scope == null && n.scope == null ) {
return name.equals( n.name ) && hexCode == n.hexCode;
}
return name.equals( n.name ) && hexCode == n.hexCode && scope.equals( n.scope );
}
public String toString() {
StringBuffer sb = new StringBuffer();
String n = name;
// fix MSBROWSE name
if( n == null ) {
n = "null";
} else if( n.charAt( 0 ) == 0x01 ) {
char c[] = n.toCharArray();
c[0] = '.';
c[1] = '.';
c[14] = '.';
n = new String( c );
}
sb.append( n ).append( "<" ).append( toHexChars( hexCode )).append( ">" );
if( scope != null ) {
sb.append( "." ).append( scope );
}
return sb.toString();
}
}
jcifs_0.8.2/src/jcifs/netbios/NodeStatusResponse.java 100644 0 0 13062 10025170724 20053 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.io.UnsupportedEncodingException;
class NodeStatusResponse extends NameServicePacket {
NbtAddress queryAddress;
int numberOfNames;
NbtAddress[] addressArray;
byte[] macAddress;
byte[] stats;
/* It is a little awkward but prudent to pass the quering address
* so that it may be included in the list of results. IOW we do
* not want to create a new NbtAddress object for this particular
* address from which the query is constructed, we want to populate
* the data of the existing address that should be one of several
* returned by the node status.
*/
NodeStatusResponse( NbtAddress queryAddress ) {
this.queryAddress = queryAddress;
recordName = new Name();
macAddress = new byte[6];
}
int writeBodyWireFormat( byte[] dst, int dstIndex ) {
return 0;
}
int readBodyWireFormat( byte[] src, int srcIndex ) {
return readResourceRecordWireFormat( src, srcIndex );
}
int writeRDataWireFormat( byte[] dst, int dstIndex ) {
return 0;
}
int readRDataWireFormat( byte[] src, int srcIndex ) {
int start = srcIndex;
numberOfNames = src[srcIndex] & 0xFF;
int namesLength = numberOfNames * 18;
int statsLength = rDataLength - namesLength - 1;
numberOfNames = src[srcIndex++] & 0xFF;
// gotta read the mac first so we can populate addressArray with it
System.arraycopy( src, srcIndex + namesLength, macAddress, 0, 6 );
srcIndex += readNodeNameArray( src, srcIndex );
stats = new byte[statsLength];
System.arraycopy( src, srcIndex, stats, 0, statsLength );
srcIndex += statsLength;
return srcIndex - start;
}
private int readNodeNameArray( byte[] src, int srcIndex ) {
int start = srcIndex;
addressArray = new NbtAddress[numberOfNames];
String n;
int hexCode;
String scope = queryAddress.hostName.scope;
boolean groupName;
int ownerNodeType;
boolean isBeingDeleted;
boolean isInConflict;
boolean isActive;
boolean isPermanent;
int j;
boolean addrFound = false;
try {
for( int i = 0; i < numberOfNames; srcIndex += 18, i++ ) {
for( j = srcIndex + 14; src[j] == 0x20; j-- )
;
n = new String( src, srcIndex, j - srcIndex + 1, Name.encoding );
hexCode = src[srcIndex + 15] & 0xFF;
groupName = (( src[srcIndex + 16] & 0x80 ) == 0x80 ) ? true : false;
ownerNodeType = ( src[srcIndex + 16] & 0x60 ) >> 5;
isBeingDeleted = (( src[srcIndex + 16] & 0x10 ) == 0x10 ) ? true : false;
isInConflict = (( src[srcIndex + 16] & 0x08 ) == 0x08 ) ? true : false;
isActive = (( src[srcIndex + 16] & 0x04 ) == 0x04 ) ? true : false;
isPermanent = (( src[srcIndex + 16] & 0x02 ) == 0x02 ) ? true : false;
/* The NbtAddress object used to query this node will be in the list
* returned by the Node Status. A new NbtAddress object should not be
* created for it because the original is potentially being actively
* referenced by other objects. We must populate the existing object's
* data explicitly (and carefully).
*/
if( !addrFound && queryAddress.hostName.hexCode == hexCode &&
( queryAddress.hostName == NbtAddress.unknownName ||
queryAddress.hostName.name.equals( n ))) {
if( queryAddress.hostName == NbtAddress.unknownName ) {
queryAddress.hostName = new Name( n, hexCode, scope );
}
queryAddress.groupName = groupName;
queryAddress.nodeType = ownerNodeType;
queryAddress.isBeingDeleted = isBeingDeleted;
queryAddress.isInConflict = isInConflict;
queryAddress.isActive = isActive;
queryAddress.isPermanent = isPermanent;
queryAddress.macAddress = macAddress;
queryAddress.isDataFromNodeStatus = true;
addrFound = true;
addressArray[i] = queryAddress;
} else {
addressArray[i] = new NbtAddress( new Name( n, hexCode, scope ),
queryAddress.address,
groupName,
ownerNodeType,
isBeingDeleted,
isInConflict,
isActive,
isPermanent,
macAddress );
}
}
} catch( UnsupportedEncodingException uee ) {
}
return srcIndex - start;
}
public String toString() {
return new String( "NodeStatusResponse[" +
super.toString() + "]" );
}
}
jcifs_0.8.2/src/jcifs/netbios/SessionServicePacket.java 100644 0 0 7440 10025170724 20322 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.io.IOException;
import java.io.InputStream;
abstract class SessionServicePacket {
// session service packet types
static final int SESSION_MESSAGE = 0x00;
static final int SESSION_REQUEST = 0x81;
static final int POSITIVE_SESSION_RESPONSE = 0x82;
static final int NEGATIVE_SESSION_RESPONSE = 0x83;
static final int SESSION_RETARGET_RESPONSE = 0x84;
static final int SESSION_KEEP_ALIVE = 0x85;
static final int MAX_MESSAGE_SIZE = 0x0001FFFF;
static final int HEADER_LENGTH = 4;
static void writeInt2( int val, byte[] dst, int dstIndex ) {
dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF );
dst[dstIndex] = (byte)( val & 0xFF );
}
static void writeInt4( int val, byte[] dst, int dstIndex ) {
dst[dstIndex++] = (byte)(( val >> 24 ) & 0xFF );
dst[dstIndex++] = (byte)(( val >> 16 ) & 0xFF );
dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF );
dst[dstIndex] = (byte)( val & 0xFF );
}
static int readInt2( byte[] src, int srcIndex ) {
return (( src[srcIndex] & 0xFF ) << 8 ) +
( src[srcIndex + 1] & 0xFF );
}
static int readInt4( byte[] src, int srcIndex ) {
return (( src[srcIndex] & 0xFF ) << 24 ) +
(( src[srcIndex + 1] & 0xFF ) << 16 ) +
(( src[srcIndex + 2] & 0xFF ) << 8 ) +
( src[srcIndex + 3] & 0xFF );
}
static int readLength( byte[] src, int srcIndex ) {
srcIndex++;
return (( src[srcIndex++] & 0x01 ) << 16 ) +
(( src[srcIndex++] & 0xFF ) << 8 ) +
( src[srcIndex++] & 0xFF );
}
static int readPacketType( InputStream in,
byte[] buffer,
int bufferIndex )
throws IOException {
int n;
if(( n = in.read( buffer, bufferIndex, HEADER_LENGTH )) != HEADER_LENGTH ) {
if( n == -1 ) {
return -1;
}
throw new IOException( "unexpected EOF reading netbios session header" );
}
int t = buffer[bufferIndex] & 0xFF;
return t;
}
int type, length;
int writeWireFormat( byte[] dst, int dstIndex ) {
length = writeTrailerWireFormat( dst, dstIndex + HEADER_LENGTH );
writeHeaderWireFormat( dst, dstIndex );
return HEADER_LENGTH + length;
}
int readWireFormat( InputStream in, byte[] buffer, int bufferIndex ) throws IOException {
readHeaderWireFormat( in, buffer, bufferIndex );
return HEADER_LENGTH + readTrailerWireFormat( in, buffer, bufferIndex );
}
int writeHeaderWireFormat( byte[] dst, int dstIndex ) {
dst[dstIndex++] = (byte)type;
if( length > 0x0000FFFF ) {
dst[dstIndex] = (byte)0x01;
}
dstIndex++;
writeInt2( length, dst, dstIndex );
return HEADER_LENGTH;
}
int readHeaderWireFormat( InputStream in,
byte[] buffer,
int bufferIndex )
throws IOException {
type = buffer[bufferIndex++] & 0xFF;
length = (( buffer[bufferIndex] & 0x01 ) << 16 ) + readInt2( buffer, bufferIndex + 1 );
return HEADER_LENGTH;
}
abstract int writeTrailerWireFormat( byte[] dst, int dstIndex );
abstract int readTrailerWireFormat( InputStream in,
byte[] buffer,
int bufferIndex )
throws IOException;
}
jcifs_0.8.2/src/jcifs/netbios/SessionRequestPacket.java 100644 0 0 3623 10025170724 20351 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.io.IOException;
import java.io.InputStream;
class SessionRequestPacket extends SessionServicePacket {
Name calledName, callingName;
SessionRequestPacket() {
calledName = new Name();
callingName = new Name();
}
SessionRequestPacket( Name calledName, Name callingName ) {
type = SESSION_REQUEST;
this.calledName = calledName;
this.callingName = callingName;
}
int writeTrailerWireFormat( byte[] dst, int dstIndex ) {
int start = dstIndex;
dstIndex += calledName.writeWireFormat( dst, dstIndex );
dstIndex += callingName.writeWireFormat( dst, dstIndex );
return dstIndex - start;
}
int readTrailerWireFormat( InputStream in,
byte[] buffer,
int bufferIndex )
throws IOException {
int start = bufferIndex;
if( in.read( buffer, bufferIndex, length ) != length ) {
throw new IOException( "invalid session request wire format" );
}
bufferIndex += calledName.readWireFormat( buffer, bufferIndex );
bufferIndex += callingName.readWireFormat( buffer, bufferIndex );
return bufferIndex - start;
}
}
jcifs_0.8.2/src/jcifs/netbios/NameQueryResponse.java 100644 0 0 3370 10025170725 17652 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
class NameQueryResponse extends NameServicePacket {
NbtAddress addrEntry;
NameQueryResponse() {
recordName = new Name();
}
int writeBodyWireFormat( byte[] dst, int dstIndex ) {
return 0;
}
int readBodyWireFormat( byte[] src, int srcIndex ) {
return readResourceRecordWireFormat( src, srcIndex );
}
int writeRDataWireFormat( byte[] dst, int dstIndex ) {
return 0;
}
int readRDataWireFormat( byte[] src, int srcIndex ) {
if( resultCode != 0 || opCode != QUERY ) {
return 0;
}
boolean groupName = (( src[srcIndex] & 0x80 ) == 0x80 ) ? true : false;
int nodeType = ( src[srcIndex] & 0x60 ) >> 5;
srcIndex += 2;
int address = readInt4( src, srcIndex );
addrEntry = new NbtAddress( recordName, address, groupName, nodeType );
return 6;
}
public String toString() {
return new String( "NameQueryResponse[" +
super.toString() +
",addrEntry=" + addrEntry + "]" );
}
}
jcifs_0.8.2/src/jcifs/netbios/SocketInputStream.java 100644 0 0 5324 10025170725 17652 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.io.InputStream;
import java.io.IOException;
class SocketInputStream extends InputStream {
private static final int TMP_BUFFER_SIZE = 256;
private InputStream in;
private SessionServicePacket ssp;
private int tot, bip, n;
private byte[] header, tmp;
SocketInputStream( InputStream in ) {
this.in = in;
header = new byte[4];
tmp = new byte[TMP_BUFFER_SIZE];
}
public synchronized int read() throws IOException {
if( read( tmp, 0, 1 ) < 0 ) {
return -1;
}
return tmp[0] & 0xFF;
}
public synchronized int read( byte[] b ) throws IOException {
return read( b, 0, b.length );
}
/* This method will not return until len bytes have been read
* or the stream has been closed.
*/
public synchronized int read( byte[] b, int off, int len ) throws IOException {
if( len == 0 ) {
return 0;
}
tot = 0;
while( true ) {
while( bip > 0 ) {
n = in.read( b, off, Math.min( len, bip ));
if( n == -1 ) {
return tot > 0 ? tot : -1;
}
tot += n;
off += n;
len -= n;
bip -= n;
if( len == 0 ) {
return tot;
}
}
switch( SessionServicePacket.readPacketType( in, header, 0 )) {
case SessionServicePacket.SESSION_KEEP_ALIVE:
break;
case SessionServicePacket.SESSION_MESSAGE:
bip = SessionServicePacket.readLength( header, 0 );
break;
case -1:
if( tot > 0 ) {
return tot;
}
return -1;
}
}
}
public synchronized long skip( long numbytes ) throws IOException {
if( numbytes <= 0 ) {
return 0;
}
long n = numbytes;
while( n > 0 ) {
int r = read( tmp, 0, (int)Math.min( (long)TMP_BUFFER_SIZE, n ));
if (r < 0) {
break;
}
n -= r;
}
return numbytes - n;
}
public int available() throws IOException {
if( bip > 0 ) {
return bip;
}
return in.available();
}
public void close() throws IOException {
in.close();
}
}
jcifs_0.8.2/src/jcifs/netbios/SessionRetargetResponsePacket.java 100644 0 0 3236 10025170725 22216 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.io.IOException;
import java.io.InputStream;
class SessionRetargetResponsePacket extends SessionServicePacket {
NbtAddress retargetAddress;
int retargetPort;
SessionRetargetResponsePacket() {
type = SESSION_RETARGET_RESPONSE;
length = 6;
}
int writeTrailerWireFormat( byte[] dst, int dstIndex ) {
return 0;
}
int readTrailerWireFormat( InputStream in,
byte[] buffer,
int bufferIndex )
throws IOException {
if( in.read( buffer, bufferIndex, length ) != length ) {
throw new IOException( "unexpected EOF reading netbios retarget session response" );
}
int addr = readInt4( buffer, bufferIndex );
bufferIndex += 4;
retargetAddress = new NbtAddress( null, addr, false, NbtAddress.B_NODE );
retargetPort = readInt2( buffer, bufferIndex );
return length;
}
}
jcifs_0.8.2/src/jcifs/netbios/NodeStatusRequest.java 100644 0 0 3163 10025170725 17667 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
class NodeStatusRequest extends NameServicePacket {
NodeStatusRequest( Name name ) {
questionName = name;
questionType = NBSTAT;
isRecurDesired = false;
isBroadcast = false;
}
int writeBodyWireFormat( byte[] dst, int dstIndex ) {
int tmp = questionName.hexCode;
questionName.hexCode = 0x00; // type has to be 0x00 for node status
int result = writeQuestionSectionWireFormat( dst, dstIndex );
questionName.hexCode = tmp;
return result;
}
int readBodyWireFormat( byte[] src, int srcIndex ) {
return 0;
}
int writeRDataWireFormat( byte[] dst, int dstIndex ) {
return 0;
}
int readRDataWireFormat( byte[] src, int srcIndex ) {
return 0;
}
public String toString() {
return new String( "NodeStatusRequest[" +
super.toString() + "]" );
}
}
jcifs_0.8.2/src/jcifs/netbios/Lmhosts.java 100644 0 0 10744 10025170725 15701 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import jcifs.Config;
import jcifs.smb.SmbFileInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Hashtable;
import java.net.UnknownHostException;
public class Lmhosts {
static String filename = Config.getProperty( "jcifs.netbios.lmhosts" );
static Hashtable tab = new Hashtable();
static long lastModified = 1L;
static int alt;
/**
* This is really just for {@link jcifs.UniAddress}. It does
* not throw an {@link java.net.UnknownHostException} because this
* is queried frequently and exceptions would be rather costly to
* throw on a regular basis here.
*/
public synchronized static NbtAddress getByName( String host ) {
return getByName( new Name( host, 0x20, null ));
}
synchronized static NbtAddress getByName( Name name ) {
NbtAddress result = null;
try {
if( filename != null ) {
File f = new File( filename );
long lm;
if(( lm = f.lastModified() ) > lastModified ) {
lastModified = lm;
tab.clear();
alt = 0;
populate( new FileReader( f ));
}
result = (NbtAddress)tab.get( name );
}
} catch( FileNotFoundException fnfe ) {
Log.println( Log.WARNINGS, "netbios name service exception",
"lmhosts file not found: " + filename );
} catch( IOException ioe ) {
Log.printStackTrace( "netbios name service exception", ioe );
}
return result;
}
static void populate( Reader r ) throws IOException {
String line;
BufferedReader br = new BufferedReader( r );
while(( line = br.readLine() ) != null ) {
line = line.toUpperCase().trim();
if( line.length() == 0 ) {
continue;
} else if( line.charAt( 0 ) == '#' ) {
if( line.startsWith( "#INCLUDE " )) {
line = line.substring( line.indexOf( '\\' ));
String url = "smb:" + line.replace( '\\', '/' );
if( alt > 0 ) {
try {
populate( new InputStreamReader( new SmbFileInputStream( url )));
} catch( IOException ioe ) {
Log.println( Log.WARNINGS, "netbios name service warning",
"failed to load lmhosts alternate include: " + url );
continue;
}
/* An include was loaded successfully. We can skip
* all other includes up to the #END_ALTERNATE tag.
*/
alt--;
while(( line = br.readLine() ) != null ) {
line = line.toUpperCase().trim();
if( line.startsWith( "#END_ALTERNATE" )) {
break;
}
}
} else {
populate( new InputStreamReader( new SmbFileInputStream( url )));
}
} else if( line.startsWith( "#BEGIN_ALTERNATE" )) {
alt++;
} else if( line.startsWith( "#END_ALTERNATE" ) && alt > 0 ) {
alt--;
throw new IOException( "no lmhosts alternate includes loaded" );
}
} else if( Character.isDigit( line.charAt( 0 ))) {
char[] data = line.toCharArray();
int ip, i, j;
Name name;
NbtAddress addr;
char c;
c = '.';
ip = i = 0;
for( ; i < data.length && c == '.'; i++ ) {
int b = 0x00;
for( ; i < data.length && ( c = data[i] ) >= 48 && c <= 57; i++ ) {
b = b * 10 + c - '0';
}
ip = ( ip << 8 ) + b;
}
while( i < data.length && Character.isWhitespace( data[i] )) {
i++;
}
j = i;
while( j < data.length && Character.isWhitespace( data[j] ) == false ) {
j++;
}
name = new Name( line.substring( i, j ), 0x20, null );
addr = new NbtAddress( name, ip, false, NbtAddress.B_NODE,
false, false, true, true,
NbtAddress.unknownMacAddress );
tab.put( name, addr );
}
}
}
}
jcifs_0.8.2/src/jcifs/netbios/NbtSocket.java 100644 0 0 10244 10025170725 16137 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.net.Socket;
import java.net.InetAddress;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import jcifs.Config;
/**
* This class represents a netbios TCP/IP socket. Under no
* conditions will users of jcifs need not be concerned with this class as
* netbios services are handled internally to the smb package. It is
* only public so the smb package can access it.
*/
public class NbtSocket extends Socket {
private static final int SSN_SRVC_PORT = 139;
private static final int BUFFER_SIZE = 512;
private static final int DEFAULT_SO_TIMEOUT = 5000;
NbtAddress address;
Name calledName;
int soTimeout;
public NbtSocket() {
super();
}
public NbtSocket( NbtAddress address, int port ) throws IOException {
this( address, port, null, 0 );
}
public NbtSocket( NbtAddress address, int port,
InetAddress localAddr, int localPort ) throws IOException {
this( address, null, port, localAddr, localPort );
}
public NbtSocket( NbtAddress address, String calledName, int port,
InetAddress localAddr, int localPort ) throws IOException {
super( address.getInetAddress(), ( port == 0 ? SSN_SRVC_PORT : port ),
localAddr, localPort );
this.address = address;
if( calledName == null ) {
this.calledName = address.hostName;
} else {
this.calledName = new Name( calledName, 0x20, null );
}
soTimeout = Config.getInt( "jcifs.netbios.soTimeout", DEFAULT_SO_TIMEOUT );
connect();
}
public NbtAddress getNbtAddress() {
return address;
}
InputStream getRawInputStream() throws IOException {
return super.getInputStream();
}
OutputStream getRawOutputStream() throws IOException {
return super.getOutputStream();
}
public InputStream getInputStream() throws IOException {
return new SocketInputStream( super.getInputStream() );
}
public OutputStream getOutputStream() throws IOException {
return new SocketOutputStream( super.getOutputStream() );
}
public int getPort() {
return super.getPort();
}
public InetAddress getLocalAddress() {
return super.getLocalAddress();
}
public int getLocalPort() {
return super.getLocalPort();
}
public String toString() {
return "NbtSocket[addr=" + address +
",port=" + super.getPort() +
",localport=" + super.getLocalPort() + "]";
}
private void connect() throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
InputStream in = super.getInputStream();
OutputStream out = super.getOutputStream();
SessionServicePacket ssp0 = new SessionRequestPacket( calledName, NbtAddress.localhost.hostName );
out.write( buffer, 0, ssp0.writeWireFormat( buffer, 0 ));
setSoTimeout( soTimeout );
switch( ssp0.readPacketType( in, buffer, 0 )) {
case SessionServicePacket.POSITIVE_SESSION_RESPONSE:
Log.println( Log.WARNINGS, "session service warning", " session established ok with " + address );
return;
case SessionServicePacket.NEGATIVE_SESSION_RESPONSE:
int errorCode = (int)( in.read() & 0xFF );
throw new NbtException( NbtException.ERR_SSN_SRVC, errorCode );
case -1:
throw new NbtException( NbtException.ERR_SSN_SRVC, NbtException.CONNECTION_REFUSED );
default:
throw new NbtException( NbtException.ERR_SSN_SRVC, 0 );
}
}
public void close() throws IOException {
Log.println( Log.WARNINGS, "netbios socket closed", this );
super.close();
}
}
jcifs_0.8.2/src/jcifs/netbios/NameServicePacket.java 100644 0 0 24044 10025170725 17577 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.net.InetAddress;
abstract class NameServicePacket {
// opcode
static final int QUERY = 0;
static final int WACK = 7;
// rcode
static final int FMT_ERR = 0x1;
static final int SRV_ERR = 0x2;
static final int IMP_ERR = 0x4;
static final int RFS_ERR = 0x5;
static final int ACT_ERR = 0x6;
static final int CFT_ERR = 0x7;
// type/class
static final int NB_IN = 0x00200001;
static final int NBSTAT_IN = 0x00210001;
static final int NB = 0x0020;
static final int NBSTAT = 0x0021;
static final int IN = 0x0001;
static final int A = 0x0001;
static final int NS = 0x0002;
static final int NULL = 0x000a;
static final int HEADER_LENGTH = 12;
// header field offsets
static final int OPCODE_OFFSET = 2;
static final int QUESTION_OFFSET = 4;
static final int ANSWER_OFFSET = 6;
static final int AUTHORITY_OFFSET = 8;
static final int ADDITIONAL_OFFSET = 10;
static final int LOOKUP_RESP_LIMIT = jcifs.Config.getInt( "jcifs.netbios.lookupRespLimit", 5 );
static int addrIndex = 0;
static void writeInt2( int val, byte[] dst, int dstIndex ) {
dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF );
dst[dstIndex] = (byte)( val & 0xFF );
}
static void writeInt4( int val, byte[] dst, int dstIndex ) {
dst[dstIndex++] = (byte)(( val >> 24 ) & 0xFF );
dst[dstIndex++] = (byte)(( val >> 16 ) & 0xFF );
dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF );
dst[dstIndex] = (byte)( val & 0xFF );
}
static int readInt2( byte[] src, int srcIndex ) {
return (( src[srcIndex] & 0xFF ) << 8 ) +
( src[srcIndex + 1] & 0xFF );
}
static int readInt4( byte[] src, int srcIndex ) {
return (( src[srcIndex] & 0xFF ) << 24 ) +
(( src[srcIndex + 1] & 0xFF ) << 16 ) +
(( src[srcIndex + 2] & 0xFF ) << 8 ) +
( src[srcIndex + 3] & 0xFF );
}
static int readNameTrnId( byte[] src, int srcIndex ) {
return readInt2( src, srcIndex );
}
int nameTrnId;
int opCode,
resultCode,
questionCount,
answerCount,
authorityCount,
additionalCount;
boolean received,
isResponse,
isAuthAnswer,
isTruncated,
isRecurDesired,
isRecurAvailable,
isBroadcast;
Name questionName;
Name recordName;
int questionType,
questionClass,
recordType,
recordClass,
ttl,
rDataLength;
InetAddress addr;
NameServicePacket() {
isRecurDesired = true;
isBroadcast = true;
questionCount = 1;
questionClass = IN;
}
int writeWireFormat( byte[] dst, int dstIndex ) {
int start = dstIndex;
dstIndex += writeHeaderWireFormat( dst, dstIndex );
dstIndex += writeBodyWireFormat( dst, dstIndex );
return dstIndex - start;
}
int readWireFormat( byte[] src, int srcIndex ) {
int start = srcIndex;
srcIndex += readHeaderWireFormat( src, srcIndex );
srcIndex += readBodyWireFormat( src, srcIndex );
return srcIndex - start;
}
int writeHeaderWireFormat( byte[] dst, int dstIndex ) {
int start = dstIndex;
writeInt2( nameTrnId, dst, dstIndex );
dst[dstIndex + OPCODE_OFFSET] = (byte)(( isResponse ? 0x80 : 0x00 ) +
(( opCode << 3 ) & 0x78 ) +
( isAuthAnswer ? 0x04 : 0x00 ) +
( isTruncated ? 0x02 : 0x00 ) +
( isRecurDesired ? 0x01 : 0x00 ));
dst[dstIndex + OPCODE_OFFSET + 1] = (byte)(( isRecurAvailable ? 0x80 : 0x00 ) +
( isBroadcast ? 0x10 : 0x00 ) +
( resultCode & 0x0F ));
writeInt2( questionCount, dst, start + QUESTION_OFFSET );
writeInt2( answerCount, dst, start + ANSWER_OFFSET );
writeInt2( authorityCount, dst, start + AUTHORITY_OFFSET );
writeInt2( additionalCount, dst, start + ADDITIONAL_OFFSET );
return HEADER_LENGTH;
}
int readHeaderWireFormat( byte[] src, int srcIndex ) {
nameTrnId = readInt2( src, srcIndex );
isResponse = (( src[srcIndex + OPCODE_OFFSET] & 0x80 ) == 0 ) ? false : true;
opCode = ( src[srcIndex + OPCODE_OFFSET] & 0x78 ) >> 3;
isAuthAnswer = (( src[srcIndex + OPCODE_OFFSET] & 0x04 ) == 0 ) ? false : true;
isTruncated = (( src[srcIndex + OPCODE_OFFSET] & 0x02 ) == 0 ) ? false : true;
isRecurDesired = (( src[srcIndex + OPCODE_OFFSET] & 0x01 ) == 0 ) ? false : true;
isRecurAvailable =
(( src[srcIndex + OPCODE_OFFSET + 1] & 0x80 ) == 0 ) ? false : true;
isBroadcast = (( src[srcIndex + OPCODE_OFFSET + 1] & 0x10 ) == 0 ) ? false : true;
resultCode = src[srcIndex + OPCODE_OFFSET + 1] & 0x0F;
questionCount = readInt2( src, srcIndex + QUESTION_OFFSET );
answerCount = readInt2( src, srcIndex + ANSWER_OFFSET );
authorityCount = readInt2( src, srcIndex + AUTHORITY_OFFSET );
additionalCount = readInt2( src, srcIndex + ADDITIONAL_OFFSET );
return HEADER_LENGTH;
}
int writeQuestionSectionWireFormat( byte[] dst, int dstIndex ) {
int start = dstIndex;
dstIndex += questionName.writeWireFormat( dst, dstIndex );
writeInt2( questionType, dst, dstIndex );
dstIndex += 2;
writeInt2( questionClass, dst, dstIndex );
dstIndex += 2;
return dstIndex - start;
}
int readQuestionSectionWireFormat( byte[] src, int srcIndex ) {
int start = srcIndex;
srcIndex += questionName.readWireFormat( src, srcIndex );
questionType = readInt2( src, srcIndex );
srcIndex += 2;
questionClass = readInt2( src, srcIndex );
srcIndex += 2;
return srcIndex - start;
}
int writeResourceRecordWireFormat( byte[] dst, int dstIndex ) {
int start = dstIndex;
if( recordName == questionName ) {
dst[dstIndex++] = (byte)0xC0; // label string pointer to
dst[dstIndex++] = (byte)0x0C; // questionName (offset 12)
} else {
dstIndex += recordName.writeWireFormat( dst, dstIndex );
}
writeInt2( recordType, dst, dstIndex );
dstIndex += 2;
writeInt2( recordClass, dst, dstIndex );
dstIndex += 2;
writeInt4( ttl, dst, dstIndex );
dstIndex += 4;
rDataLength = writeRDataWireFormat( dst, dstIndex + 2 );
writeInt2( rDataLength, dst, dstIndex );
dstIndex += 2 + rDataLength;
return dstIndex - start;
}
int readResourceRecordWireFormat( byte[] src, int srcIndex ) {
int start = srcIndex;
int end;
if(( src[srcIndex] & 0xC0 ) == 0xC0 ) {
recordName = questionName; // label string pointer to questionName
srcIndex += 2;
} else {
srcIndex += recordName.readWireFormat( src, srcIndex );
}
recordType = readInt2( src, srcIndex );
srcIndex += 2;
recordClass = readInt2( src, srcIndex );
srcIndex += 2;
ttl = readInt4( src, srcIndex );
srcIndex += 4;
rDataLength = readInt2( src, srcIndex );
srcIndex += 2;
end = srcIndex + rDataLength;
for( int i = 0; srcIndex < end; i++ ) {
srcIndex += readRDataWireFormat( src, srcIndex );
if( i == addrIndex ) {
addrIndex++;
if( addrIndex == LOOKUP_RESP_LIMIT ) {
addrIndex = 0;
}
return end - start;
}
}
addrIndex = 0;
return srcIndex - start;
}
abstract int writeBodyWireFormat( byte[] dst, int dstIndex );
abstract int readBodyWireFormat( byte[] src, int srcIndex );
abstract int writeRDataWireFormat( byte[] dst, int dstIndex );
abstract int readRDataWireFormat( byte[] src, int srcIndex );
public String toString() {
String opCodeString,
resultCodeString,
questionTypeString,
questionClassString,
recordTypeString,
recordClassString;
switch( opCode ) {
case QUERY:
opCodeString = "QUERY";
break;
case WACK:
opCodeString = "WACK";
break;
default:
opCodeString = Integer.toString( opCode );
}
switch( resultCode ) {
case FMT_ERR:
resultCodeString = "FMT_ERR";
break;
case SRV_ERR:
resultCodeString = "SRV_ERR";
break;
case IMP_ERR:
resultCodeString = "IMP_ERR";
break;
case RFS_ERR:
resultCodeString = "RFS_ERR";
break;
case ACT_ERR:
resultCodeString = "ACT_ERR";
break;
case CFT_ERR:
resultCodeString = "CFT_ERR";
break;
default:
resultCodeString = "0x" + Log.getHexString( resultCode, 1 );
}
switch( questionType ) {
case NB:
questionTypeString = "NB";
case NBSTAT:
questionTypeString = "NBSTAT";
default:
questionTypeString = "0x" + Log.getHexString( questionType, 4 );
}
switch( recordType ) {
case A:
recordTypeString = "A";
break;
case NS:
recordTypeString = "NS";
break;
case NULL:
recordTypeString = "NULL";
break;
case NB:
recordTypeString = "NB";
case NBSTAT:
recordTypeString = "NBSTAT";
default:
recordTypeString = "0x" + Log.getHexString( recordType, 4 );
}
return new String(
"nameTrnId=" + nameTrnId +
",isResponse=" + isResponse +
",opCode=" + opCodeString +
",isAuthAnswer=" + isAuthAnswer +
",isTruncated=" + isTruncated +
",isRecurAvailable=" + isRecurAvailable +
",isRecurDesired=" + isRecurDesired +
",isBroadcast=" + isBroadcast +
",resultCode=" + resultCode +
",questionCount=" + questionCount +
",answerCount=" + answerCount +
",authorityCount=" + authorityCount +
",additionalCount=" + additionalCount +
",questionName=" + questionName +
",questionType=" + questionTypeString +
",questionClass=" + ( questionClass == IN ? "IN" :
"0x" + Log.getHexString( questionClass, 4 )) +
",recordName=" + recordName +
",recordType=" + recordTypeString +
",recordClass=" + ( recordClass == IN ? "IN" :
"0x" + Log.getHexString( recordClass, 4 )) +
",ttl=" + ttl +
",rDataLength=" + rDataLength );
}
}
jcifs_0.8.2/src/jcifs/netbios/NameServiceClient.java 100644 0 0 27332 10025170725 17611 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.netbios;
import java.net.InetAddress;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.UnknownHostException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.Hashtable;
import java.util.StringTokenizer;
import jcifs.Config;
class NameServiceClient implements Runnable {
static final int DEFAULT_SO_TIMEOUT = 5000;
static final int DEFAULT_RCV_BUF_SIZE = 576;
static final int DEFAULT_SND_BUF_SIZE = 576;
static final int NAME_SERVICE_UDP_PORT = 137;
static final int DEFAULT_RETRY_COUNT = 2;
static final int DEFAULT_RETRY_TIMEOUT = 3000;
static final int RESOLVER_LMHOSTS = 1;
static final int RESOLVER_BCAST = 2;
static final int RESOLVER_WINS = 3;
InetAddress laddr, baddr, nbns;
int port, soTimeout, retryCount, retryTimeout, closeTimeout;
int snd_buf_size, rcv_buf_size;
byte[] snd_buf, rcv_buf;
DatagramSocket socket;
DatagramPacket in, out;
Hashtable responseTable;
Thread thread;
int nextNameTrnId;
Object socketLock;
int[] resolveOrder;
NameServiceClient() {
this( Config.getInt( "jcifs.netbios.lport", 0 ),
Config.getInetAddress( "jcifs.netbios.laddr", null ));
}
NameServiceClient( int port, InetAddress laddr ) {
this.port = port;
this.laddr = laddr;
try {
baddr = Config.getInetAddress( "jcifs.netbios.baddr",
InetAddress.getByName( "255.255.255.255" ));
} catch( UnknownHostException uhe ) {
}
nbns = Config.getInetAddress( "jcifs.netbios.wins", null );
soTimeout = Config.getInt( "jcifs.netbios.soTimeout", DEFAULT_SO_TIMEOUT );
retryCount = Config.getInt( "jcifs.netbios.retryCount", DEFAULT_RETRY_COUNT );
retryTimeout = Config.getInt( "jcifs.netbios.retryTimeout", DEFAULT_RETRY_TIMEOUT);
rcv_buf_size = Config.getInt( "jcifs.netbios.rcv_buf_size", DEFAULT_RCV_BUF_SIZE );
snd_buf_size = Config.getInt( "jcifs.netbios.snd_buf_size", DEFAULT_SND_BUF_SIZE );
rcv_buf = new byte[rcv_buf_size];
snd_buf = new byte[snd_buf_size];
in = new DatagramPacket( rcv_buf, rcv_buf_size );
out = new DatagramPacket( snd_buf, snd_buf_size, baddr, NAME_SERVICE_UDP_PORT );
responseTable = new Hashtable();
nextNameTrnId = 0;
socketLock = new Object();
String ro = Config.getProperty( "jcifs.resolveOrder" );
if( ro == null || ro.length() == 0 ) {
/* No resolveOrder has been specified, use the
* default which is LMHOSTS,WINS,BCAST,DNS or just
* LMHOSTS,BCAST,DNS if jcifs.netbios.wins has not
* been specified.
*/
if( nbns == null ) {
resolveOrder = new int[2];
resolveOrder[0] = RESOLVER_LMHOSTS;
resolveOrder[1] = RESOLVER_BCAST;
} else {
resolveOrder = new int[3];
resolveOrder[0] = RESOLVER_LMHOSTS;
resolveOrder[1] = RESOLVER_WINS;
resolveOrder[2] = RESOLVER_BCAST;
}
} else {
int[] tmp = new int[3];
StringTokenizer st = new StringTokenizer( ro, "," );
int i = 0;
while( st.hasMoreTokens() ) {
String s = st.nextToken().trim();
if( s.equalsIgnoreCase( "LMHOSTS" )) {
tmp[i++] = RESOLVER_LMHOSTS;
} else if( s.equalsIgnoreCase( "WINS" )) {
if( nbns == null ) {
Log.println( Log.WARNINGS, "netbios name service warning",
" resolveOrder specifies WINS however the " +
"jcifs.netbios.wins property has not been set" );
continue;
}
tmp[i++] = RESOLVER_WINS;
} else if( s.equalsIgnoreCase( "BCAST" )) {
tmp[i++] = RESOLVER_BCAST;
} else if( s.equalsIgnoreCase( "DNS" )) {
; // skip
} else {
Log.println( Log.WARNINGS, "netbios name service warning",
"unknown resolver method: " + s );
}
}
resolveOrder = new int[i];
System.arraycopy( tmp, 0, resolveOrder, 0, i );
}
}
int getNextNameTrnId() {
if(( ++nextNameTrnId & 0xFFFF ) == 0 ) {
nextNameTrnId = 1;
}
return nextNameTrnId;
}
void ensureOpen( int timeout ) throws IOException {
closeTimeout = 0;
if( soTimeout != 0 ) {
closeTimeout = Math.max( soTimeout, timeout );
}
// If socket is still good, the new closeTimeout will
// be ignored; see tryClose comment.
if( socket == null ) {
socket = new DatagramSocket( port, laddr );
thread = new Thread( this, "JCIFS-NameServiceClient" );
thread.setDaemon( true );
thread.start();
}
}
void tryClose() {
synchronized( socketLock ) {
/* Yes, there is the potential to drop packets
* because we might close the socket during a
* request. However the chances are slim and the
* retry code should ensure the overall request
* is serviced. The alternative complicates things
* more than I think is worth it.
*/
if( socket != null ) {
socket.close();
socket = null;
}
thread = null;
responseTable.clear();
}
}
public void run() {
int nameTrnId;
NameServicePacket response;
while( thread == Thread.currentThread() ) {
in.setLength( rcv_buf_size );
try {
socket.setSoTimeout( closeTimeout );
socket.receive( in );
} catch( IOException ioe ) {
tryClose();
break;
}
Log.println( Log.DEBUGGING, "nbt name service debugging",
" new data read from socket" );
nameTrnId = NameServicePacket.readNameTrnId( rcv_buf, 0 );
response = (NameServicePacket)responseTable.get( new Integer( nameTrnId ));
if( response == null || response.received ) {
continue;
}
synchronized( response ) {
response.readWireFormat( rcv_buf, 0 );
response.received = true;
Log.printPacketData( "nbt name service packet receviced", response );
Log.printHexDump( "datagram packet received from: " +
in.getAddress().getHostAddress(), rcv_buf, 0, in.getLength() );
response.notify();
}
}
}
void send( NameServicePacket request, NameServicePacket response,
int timeout ) throws IOException {
Integer nid = null;
synchronized( response ) {
try {
synchronized( socketLock ) {
request.nameTrnId = getNextNameTrnId();
nid = new Integer( request.nameTrnId );
out.setAddress( request.addr );
out.setLength( request.writeWireFormat( snd_buf, 0 ));
response.received = false;
responseTable.put( nid, response );
ensureOpen( timeout + 1000 );
socket.send( out );
Log.printPacketData( "nbt name service packet sent", request );
Log.printHexDump( "datagram packet sent to: " +
out.getAddress().getHostAddress(), snd_buf, 0, out.getLength() );
}
response.wait( timeout );
} catch( InterruptedException ie ) {
} finally {
responseTable.remove( nid );
}
}
}
NbtAddress getByName( Name name, InetAddress addr )
throws UnknownHostException {
int n;
NameQueryRequest request = new NameQueryRequest( name );
NameQueryResponse response = new NameQueryResponse();
if( addr != null ) { /* UniAddress calls always use this
* because it specifies addr
*/
request.addr = addr; /* if addr ends with 255 flag it bcast */
request.isBroadcast = (addr.getAddress()[3] == (byte)0xFF);
n = retryCount;
do {
try {
send( request, response, retryTimeout );
} catch( IOException ioe ) {
Log.printStackTrace( "nbt name service send:", ioe );
throw new UnknownHostException( ioe.getMessage() );
}
if( response.received && response.resultCode == 0 ) {
response.addrEntry.hostName.srcHashCode = addr.hashCode();
return response.addrEntry;
}
} while( --n > 0 && request.isBroadcast );
throw new UnknownHostException( name.toString() );
}
/* If a target address to query was not specified explicitly
* with the addr parameter we fall into this resolveOrder routine.
*/
for( int i = 0; i < resolveOrder.length; i++ ) {
try {
switch( resolveOrder[i] ) {
case RESOLVER_LMHOSTS:
NbtAddress ans = Lmhosts.getByName( name );
if( ans != null ) {
ans.hostName.srcHashCode = 0; // just has to be different
// from other methods
return ans;
}
break;
case RESOLVER_WINS:
case RESOLVER_BCAST:
if( resolveOrder[i] == RESOLVER_WINS &&
name.name != NbtAddress.MASTER_BROWSER_NAME &&
name.hexCode != 0x1d ) {
request.addr = nbns;
request.isBroadcast = false;
} else {
request.addr = baddr;
request.isBroadcast = true;
}
n = retryCount;
while( n-- > 0 ) {
try {
send( request, response, retryTimeout );
} catch( IOException ioe ) {
Log.printStackTrace( "nbt name service send:", ioe );
throw new UnknownHostException( ioe.getMessage() );
}
if( response.received && response.resultCode == 0 ) {
/* Before we return, in anticipation of this address being cached we must
* augment the addresses name's hashCode to distinguish those resolved by
* Lmhosts, WINS, or BCAST. Otherwise a failed query from say WINS would
* get pulled out of the cache for a BCAST on the same name.
*/
response.addrEntry.hostName.srcHashCode =
request.addr.hashCode();
return response.addrEntry;
} else if( resolveOrder[i] == RESOLVER_WINS ) {
/* If WINS reports negative, no point in retry
*/
break;
}
}
break;
}
} catch( IOException ioe ) {
}
}
throw new UnknownHostException( name.name );
}
NbtAddress[] getNodeStatus( NbtAddress addr ) throws UnknownHostException {
int n, srcHashCode;
NodeStatusRequest request;
NodeStatusResponse response;
response = new NodeStatusResponse( addr );
request = new NodeStatusRequest(
new Name( NbtAddress.ANY_HOSTS_NAME, 0x00, null));
request.addr = addr.getInetAddress();
n = retryCount;
while( n-- > 0 ) {
try {
send( request, response, retryTimeout );
} catch( IOException ioe ) {
Log.printStackTrace( "nbt name service send:", ioe );
throw new UnknownHostException( ioe.getMessage() );
}
if( response.received && response.resultCode == 0 ) {
/* For name queries resolved by different sources (e.g. WINS,
* BCAST, Node Status) we need to augment the hashcode generated
* for the addresses hostname or failed lookups for one type will
* be cached and cause other types to fail even though they may
* not be the authority for the name. For example, if a WINS lookup
* for FOO fails and caches unknownAddress for FOO, a subsequent
* lookup for FOO using BCAST should not fail because of that
* name cached from WINS.
*
* So, here we apply the source addresses hashCode to each name to
* make them specific to who resolved the name.
*/
srcHashCode = request.addr.hashCode();
for( int i = 0; i < response.addressArray.length; i++ ) {
response.addressArray[i].hostName.srcHashCode = srcHashCode;
}
return response.addressArray;
}
}
throw new UnknownHostException( addr.hostName.name );
}
}
jcifs_0.8.2/src/jcifs/smb/SmbSession.java 100644 0 0 13313 10025170724 15445 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.smb;
import java.util.Vector;
import java.util.Enumeration;
import java.net.InetAddress;
import java.net.UnknownHostException;
import jcifs.UniAddress;
/**
* The class represents a user's session established with an SMB/CIFS
* server. This class is used internally to the jCIFS library however
* applications may wish to authenticate aribrary user credentials
* with the <tt>logon</tt> method. It is noteworthy that jCIFS does not
* support DCE/RPC at this time and therefore does not use the NETLOGON
* procedure. Instead, it simply performs a "tree connect" to IPC$ using
* the supplied credentials. This is only a subset of the NETLOGON procedure
* but is achives the same effect.
*/
public final class SmbSession {
public static byte[] getChallenge( UniAddress dc ) throws SmbException, UnknownHostException {
SmbTransport trans = SmbTransport.getSmbTransport( dc, 0 );
trans.negotiate();
return trans.server.encryptionKey;
}
/**
* Authenticate arbitrary credentials represented by the
* <tt>NtlmPasswordAuthentication</tt> object against the domain controller
* specified by the <tt>UniAddress</tt> parameter. If the credentials are
* not accepted, an <tt>SmbAuthException</tt> will be thrown. If an error
* occurs an <tt>SmbException</tt> will be thrown. If the credentials are
* valid, the method will return without throwing an exception. See the
* last <a href="../../../../FAQ.html">FAQ</a> question.
*/
public static void logon( UniAddress dc,
NtlmPasswordAuthentication auth ) throws SmbException {
SmbTransport.getSmbTransport( dc, 0 ).getSmbSession( auth ).getSmbTree( "IPC$", null ).treeConnect( null, null );
}
int uid;
NtlmPasswordAuthentication auth;
SmbTransport transport;
Vector trees;
boolean sessionSetup;
SmbSession( SmbTransport transport, NtlmPasswordAuthentication auth ) {
this.transport = transport;
this.auth = auth;
trees = new Vector();
}
synchronized SmbTree getSmbTree( String share, String service ) {
SmbTree t;
if( share == null ) {
share = "IPC$";
}
for( Enumeration e = trees.elements(); e.hasMoreElements(); ) {
t = (SmbTree)e.nextElement();
if( t.matches( share, service )) {
return t;
}
}
t = new SmbTree( this, share, service );
trees.addElement( t );
return t;
}
boolean matches( NtlmPasswordAuthentication auth ) {
return this.auth == auth || this.auth.equals( auth );
}
void sendTransaction( SmbComTransaction request,
SmbComTransactionResponse response ) throws SmbException {
// transactions are not batchable
sessionSetup( null, null );
request.uid = uid;
request.auth = auth;
transport.sendTransaction( request, response );
}
void send( ServerMessageBlock request,
ServerMessageBlock response ) throws SmbException {
if( response != null ) {
response.received = false;
}
sessionSetup( request, response );
if( response != null && response.received ) {
return;
}
request.uid = uid;
request.auth = auth;
transport.send( request, response );
}
void sessionSetup( ServerMessageBlock andx,
ServerMessageBlock andxResponse ) throws SmbException {
synchronized( transport ) {
if( sessionSetup ) {
return;
}
transport.negotiate();
if( transport.useSigning && transport.macSigningKey == null &&
NtlmPasswordAuthentication.NULL != auth &&
NtlmPasswordAuthentication.NULL.equals( auth ) == false ) {
// NtlmPasswordAuthentication.GUEST.equals( auth ) == false ) {
/* The first SMB_COM_SESSION_SETUP_ANX with creds other than
* null or guest generates the signing key */
transport.initSigning( auth );
}
Log.println( Log.WARNINGS, "smb session setup warning",
" requesting session with accountName=" + auth.username +
",primaryDomain=" + auth.domain );
/*
* Session Setup And X Request / Response
*/
SmbComSessionSetupAndX request = new SmbComSessionSetupAndX( this, andx );
SmbComSessionSetupAndXResponse response = new SmbComSessionSetupAndXResponse( andxResponse );
request.auth = auth;
transport.send( request, response );
uid = response.uid;
sessionSetup = true;
}
}
void logoff( boolean inError ) {
synchronized( transport ) {
if( sessionSetup == false ) {
return;
}
for( Enumeration e = trees.elements(); e.hasMoreElements(); ) {
SmbTree t = (SmbTree)e.nextElement();
t.treeDisconnect( inError );
}
if( transport.server.security == ServerMessageBlock.SECURITY_SHARE ) {
return;
}
if( !inError ) {
/*
* Logoff And X Request / Response
*/
try {
SmbComLogoffAndX request = new SmbComLogoffAndX( null );
request.uid = uid;
transport.send( request, null );
} catch( SmbException se ) {
}
}
sessionSetup = false;
}
}
public String toString() {
return "SmbSession[accountName=" + auth.username +
",primaryDomain=" + auth.domain +
",uid=" + uid +
",sessionSetup=" + sessionSetup + "]";
}
}
jcifs_0.8.2/src/jcifs/smb/Trans2FindFirst2Response.java 100644 0 0 17136 10025170724 20152 0 ustar 0 0 /* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.smb;
import java.io.UnsupportedEncodingException;
import java.util.Date;
class Trans2FindFirst2Response extends SmbComTransactionResponse {
// information levels
static final int SMB_INFO_STANDARD = 1;
static final int SMB_INFO_QUERY_EA_SIZE = 2;
static final int SMB_INFO_QUERY_EAS_FROM_LIST = 3;
static final int SMB_FIND_FILE_DIRECTORY_INFO = 0x101;
static final int SMB_FIND_FILE_FULL_DIRECTORY_INFO = 0x102;
static final int SMB_FILE_NAMES_INFO = 0x103;
static final int SMB_FILE_BOTH_DIRECTORY_INFO = 0x104;
class SmbFindFileBothDirectoryInfo implements FileEntry {
int nextEntryOffset;
int fileIndex;
long creationTime;
long lastAccessTime;
long lastWriteTime;
long changeTime;
long endOfFile;
long allocationSize;
int extFileAttributes;
int fileNameLength;
int eaSize;
int shortNameLength;
String shortName;
String filename;
public String getName() {
return filename;
}
public int getType() {
return SmbFile.TYPE_FILESYSTEM;
}
public int getAttributes() {
return extFileAttributes;
}
public long createTime() {
return creationTime;
}
public long lastModified() {
return lastWriteTime;
}
public long length() {
return endOfFile;
}
public String toString() {
return new String( "SmbFindFileBothDirectoryInfo[" +
"nextEntryOffset=" + nextEntryOffset +
",fileIndex=" + fileIndex +
",creationTime=" + new Date( creationTime ) +
",lastAccessTime=" + new Date( lastAccessTime ) +
",lastWriteTime=" + new Date( lastWriteTime ) +
",changeTime=" + new Date( changeTime ) +
",endOfFile=" + endOfFile +
",allocationSize=" + allocationSize +
",extFileAttributes=" + extFileAttributes +
",fileNameLength=" + fileNameLength +
",eaSize=" + eaSize +
",shortNameLength=" + shortNameLength +
",shortName=" + shortName +
",filename=" + filename + "]" );
}
}
int sid;
boolean isEndOfSearch;
int eaErrorOffset;
int lastNameOffset, lastNameBufferIndex;
String lastName;
int resumeKey;
Trans2FindFirst2Response() {
command = SMB_COM_TRANSACTION2;
subCommand = SmbComTransaction.TRANS2_FIND_FIRST2;
}
String readString( byte[] src, int srcIndex, int len ) {
String str = null;
try {
if( useUnicode ) {
// should Unicode alignment be corrected for here?
str = new String( src, srcIndex, len, "UnicodeLittle" );
} else {
/* On NT without Unicode the fileNameLength
* includes the '\0' whereas on win98 it doesn't. I
* guess most clients only support non-unicode so
* they don't run into this.
*/
/* UPDATE: Maybe not! Could this be a Unicode alignment issue. I hope
* so. We cannot just comment out this method and use readString of
* ServerMessageBlock.java because the arguments are different, however
* one might be able to reduce this.
*/
if( len > 0 && src[srcIndex + len - 1] == '\0' ) {
len--;
}
str = new String( src, srcIndex, len, ServerMessageBlock.encoding );
}
} catch( UnsupportedEncodingException uee ) {
Log.printStackTrace( "smb exception", uee );
}
return str;
}
int writeSetupWireFormat( byte[] dst, int dstIndex ) {
return 0;
}
int writeParametersWireFormat( byte[] dst, int dstIndex ) {
return 0;
}
int writeDataWireFormat( byte[] dst, int dstIndex ) {
return 0;
}
int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
return 0;
}
int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
int start = bufferIndex;
if( subCommand == SmbComTransaction.TRANS2_FIND_FIRST2 ) {
sid = readInt2( buffer, bufferIndex );
bufferIndex += 2;
}
numEntries = readInt2( buffer, bufferIndex );
bufferIndex += 2;
isEndOfSearch = ( buffer[bufferIndex] & 0x01 ) == 0x01 ? true : false;
bufferIndex += 2;
eaErrorOffset = readInt2( buffer, bufferIndex );
bufferIndex += 2;
lastNameOffset = readInt2( buffer, bufferIndex );
bufferIndex += 2;
return bufferIndex - start;
}
int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
int start = bufferIndex;
SmbFindFileBothDirectoryInfo e;
lastNameBufferIndex = bufferIndex + lastNameOffset;
results = new SmbFindFileBothDirectoryInfo[numEntries];
for( int i = 0; i < numEntries; i++ ) {
results[i] = e = new SmbFindFileBothDirectoryInfo();
e.nextEntryOffset = readInt4( buffer, bufferIndex );
e.fileIndex = readInt4( buffer, bufferIndex + 4 );
e.creationTime = readTime( buffer, bufferIndex + 8 );
// e.lastAccessTime = readTime( buffer, bufferIndex + 16 );
e.lastWriteTime = readTime( buffer, bufferIndex + 24 );
// e.changeTime = readTime( buffer, bufferIndex + 32 );
e.endOfFile = readLong( buffer, bufferIndex + 40 );
// e.allocationSize = readLong( buffer, bufferIndex + 48 );
e.extFileAttributes = readInt4( buffer, bufferIndex + 56 );
e.fileNameLength = readInt4( buffer, bufferIndex + 60 );
// e.eaSize = readInt4( buffer, bufferIndex + 64 );
// e.shortNameLength = buffer[bufferIndex + 68] & 0xFF;
/* With NT, the shortName is in Unicode regardless of what is negotiated.
*/
// e.shortName = readString( buffer, bufferIndex + 70, e.shortNameLength );
e.filename = readString( buffer, bufferIndex + 94, e.fileNameLength );
//Log.println( Log.DEBUGGING, "Trans2FindFirst2/Next2Response debugging", "bufferIndex=" + bufferIndex + ",lastNameBufferIndex=" + lastNameBufferIndex + ",nextEntryOffet=" + ( bufferIndex + e.nextEntryOffset ));
/* lastNameOffset ends up pointing to either to
* the exact location of the filename(e.g. Win98)
* or to the start of the entry containing the
* filename(e.g. NT). Ahhrg! In either case the
* lastNameOffset falls between the start of the
* entry and the next entry.
*/
if( lastNameBufferIndex >= bufferIndex && ( e.nextEntryOffset == 0 ||
lastNameBufferIndex < ( bufferIndex + e.nextEntryOffset ))) {
lastName = e.filename;
resumeKey = e.fileIndex;
}
//Log.println( Log.DEBUGGING, "info entry", e );
bufferIndex += e.nextEntryOffset;
}
if( lastName == null ) {
Log.println( Log.WARNINGS, "Trans2FindFirst2/Next2Response debugging",
"lastName was null" );
}
/* last nextEntryOffset for NT 4(but not 98) is 0 so we must
* use dataCount or our accounting will report an error for NT :~(
*/
//return bufferIndex - start;
return dataCount;
}
public String toString() {
String c;
if( subCommand == SmbComTransaction.TRANS2_FIND_FIRST2 ) {
c = "Trans2FindFirst2Response[";
} else {
c = "Trans2FindNext2Response[";
}
return new String( c + super.toString() +
",sid=" + sid +
",searchCount=" + numEntries +
",isEndOfSearch=" + isEndOfSearch +
",eaErrorOffset=" + eaErrorOffset +
",lastNameOffset=" + lastNameOffset +
",lastName=" + lastName + "]" );
}
}