KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > knowgate > jcifs > netbios > NbtAddress


1 /* jcifs smb client library in Java
2  * Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package com.knowgate.jcifs.netbios;
20
21 import java.net.InetAddress JavaDoc;
22 import java.net.UnknownHostException JavaDoc;
23 import java.net.SocketException JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.UnsupportedEncodingException JavaDoc;
26 import java.util.HashMap JavaDoc;
27
28 import com.knowgate.jcifs.Config;
29
30 import com.knowgate.misc.Gadgets;
31
32 /**
33  * This class represents a NetBIOS over TCP/IP address. Under normal
34  * conditions, users of jCIFS need not be concerned with this class as
35  * name resolution and session services are handled internally by the smb package.
36  *
37  * <p> Applications can use the methods <code>getLocalHost</code>,
38  * <code>getByName</code>, and
39  * <code>getAllByAddress</code> to create a new NbtAddress instance. This
40  * class is symmetric with {@link java.net.InetAddress}.
41  *
42  * <p><b>About NetBIOS:</b> The NetBIOS name
43  * service is a dynamic distributed service that allows hosts to resolve
44  * names by broadcasting a query, directing queries to a server such as
45  * Samba or WINS. NetBIOS is currently the primary networking layer for
46  * providing name service, datagram service, and session service to the
47  * Microsoft Windows platform. A NetBIOS name can be 15 characters long
48  * and hosts usually registers several names on the network. From a
49  * Windows command prompt you can see
50  * what names a host registers with the nbtstat command.
51  * <p><blockquote><pre>
52  * C:\>nbtstat -a 192.168.1.15
53  *
54  * NetBIOS Remote Machine Name Table
55  *
56  * Name Type Status
57  * ---------------------------------------------
58  * JMORRIS2 <00> UNIQUE Registered
59  * BILLING-NY <00> GROUP Registered
60  * JMORRIS2 <03> UNIQUE Registered
61  * JMORRIS2 <20> UNIQUE Registered
62  * BILLING-NY <1E> GROUP Registered
63  * JMORRIS <03> UNIQUE Registered
64  *
65  * MAC Address = 00-B0-34-21-FA-3B
66  * </blockquote></pre>
67  * <p> The hostname of this machine is <code>JMORRIS2</code>. It is
68  * a member of the group(a.k.a workgroup and domain) <code>BILLING-NY</code>. To
69  * obtain an {@link java.net.InetAddress} for a host one might do:
70  *
71  * <pre>
72  * InetAddress addr = NbtAddress.getByName( "jmorris2" ).getInetAddress();
73  * </pre>
74  * <p>From a UNIX platform with Samba installed you can perform similar
75  * diagnostics using the <code>nmblookup</code> utility.
76  *
77  * @author Michael B. Allen
78  * @see java.net.InetAddress
79  * @since jcifs-0.1
80  */

81
82 public final class NbtAddress {
83
84 /*
85  * This is a special name that means all hosts. If you wish to find all hosts
86  * on a network querying a workgroup group name is the preferred method.
87  */

88
89     static final String JavaDoc ANY_HOSTS_NAME = "*\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000";
90
91 /**
92  * This is a special name for querying the master browser that serves the
93  * list of hosts found in "Network Neighborhood".
94  */

95
96     public static final String JavaDoc MASTER_BROWSER_NAME = "\u0001\u0002__MSBROWSE__\u0002";
97
98 /**
99  * A special generic name specified when connecting to a host for which
100  * a name is not known. Not all servers respond to this name.
101  */

102
103     public static final String JavaDoc SMBSERVER_NAME = "*SMBSERVER ";
104
105 /**
106  * A B node only broadcasts name queries. This is the default if a
107  * nameserver such as WINS or Samba is not specified.
108  */

109
110     public static final int B_NODE = 0;
111
112 /**
113  * A Point-to-Point node, or P node, unicasts queries to a nameserver
114  * only. Natrually the <code>jcifs.netbios.nameserver</code> property must
115  * be set.
116  */

117
118     public static final int P_NODE = 1;
119
120 /**
121  * Try Broadcast queries first, then try to resolve the name using the
122  * nameserver.
123  */

124
125     public static final int M_NODE = 2;
126
127 /**
128  * A Hybrid node tries to resolve a name using the nameserver first. If
129  * that fails use the broadcast address. This is the default if a nameserver
130  * is provided. This is the behavior of Microsoft Windows machines.
131  */

132
133     public static final int H_NODE = 3;
134
135     static final InetAddress JavaDoc[] NBNS = Config.getInetAddressArray( "jcifs.netbios.wins", ",", new InetAddress JavaDoc[0] );
136
137     /* Construct the shared static client object that will
138      * conduct all encoding and decoding of NetBIOS name service
139      * messages as well as socket IO in a synchronized fashon.
140      */

141
142     private static final NameServiceClient CLIENT = new NameServiceClient();
143
144     private static final int DEFAULT_CACHE_POLICY = 30;
145     private static final int CACHE_POLICY = Config.getInt( "jcifs.netbios.cachePolicy", DEFAULT_CACHE_POLICY );
146     private static final int FOREVER = -1;
147     private static int nbnsIndex = 0;
148
149     private static final HashMap JavaDoc ADDRESS_CACHE = new HashMap JavaDoc();
150     private static final HashMap JavaDoc LOOKUP_TABLE = new HashMap JavaDoc();
151
152     static final Name UNKNOWN_NAME = new Name( "0.0.0.0", 0x00, null );
153     static final NbtAddress UNKNOWN_ADDRESS = new NbtAddress( UNKNOWN_NAME, 0, false, B_NODE );
154     static final byte[] UNKNOWN_MAC_ADDRESS = new byte[] {
155         (byte)0x00, (byte)0x00, (byte)0x00,
156         (byte)0x00, (byte)0x00, (byte)0x00
157     };
158
159     static final class CacheEntry {
160         Name hostName;
161         NbtAddress address;
162         long expiration;
163
164         CacheEntry( Name hostName, NbtAddress address, long expiration ) {
165             this.hostName = hostName;
166             this.address = address;
167             this.expiration = expiration;
168         }
169     }
170
171     static NbtAddress localhost;
172
173     static {
174         InetAddress JavaDoc localInetAddress;
175         String JavaDoc localHostname;
176         Name localName;
177
178         /* Create an address to represent failed lookups and cache forever.
179          */

180
181         ADDRESS_CACHE.put( UNKNOWN_NAME, new CacheEntry( UNKNOWN_NAME, UNKNOWN_ADDRESS, FOREVER ));
182
183         /* Determine the InetAddress of the local interface
184          * if one was not specified.
185          */

186         localInetAddress = CLIENT.laddr;
187         if( localInetAddress == null ) {
188             try {
189                 localInetAddress = InetAddress.getLocalHost();
190             } catch( UnknownHostException JavaDoc uhe ) {
191             }
192         }
193
194         /* If a local hostname was not provided a name like
195          * JCIFS34_172_A6 will be dynamically generated for the
196          * client. This is primarily (exclusively?) used as a
197          * CallingName during session establishment.
198          */

199         localHostname = Config.getProperty( "jcifs.netbios.hostname", null );
200         if( localHostname == null || localHostname.length() == 0 ) {
201             byte[] addr = localInetAddress.getAddress();
202             localHostname = "JCIFS" +
203                     ( addr[2] & 0xFF ) + "_" +
204                     ( addr[3] & 0xFF ) + "_" +
205                     Gadgets.toHexString( (int)( Math.random() * (double)0xFF ), 2 );
206         }
207
208         /* Create an NbtAddress for the local interface with
209          * the name deduced above possibly with scope applied and
210          * cache it forever.
211          */

212         localName = new Name( localHostname, 0x00,
213                             Config.getProperty( "jcifs.netbios.scope", null ));
214         localhost = new NbtAddress( localName,
215                                     localInetAddress.hashCode(),
216                                     false,
217                                     B_NODE,
218                                     false, false, true, false,
219                                     UNKNOWN_MAC_ADDRESS );
220         cacheAddress( localName, localhost, FOREVER );
221     }
222
223     static void cacheAddress( Name hostName, NbtAddress addr ) {
224         if( CACHE_POLICY == 0 ) {
225             return;
226         }
227         long expiration = -1;
228         if( CACHE_POLICY != FOREVER ) {
229             expiration = System.currentTimeMillis() + CACHE_POLICY * 1000;
230         }
231         cacheAddress( hostName, addr, expiration );
232     }
233     static void cacheAddress( Name hostName, NbtAddress addr, long expiration ) {
234         if( CACHE_POLICY == 0 ) {
235             return;
236         }
237         synchronized( ADDRESS_CACHE ) {
238             CacheEntry entry = (CacheEntry)ADDRESS_CACHE.get( hostName );
239             if( entry == null ) {
240                 entry = new CacheEntry( hostName, addr, expiration );
241                 ADDRESS_CACHE.put( hostName, entry );
242             } else {
243                 entry.address = addr;
244                 entry.expiration = expiration;
245             }
246         }
247     }
248     static void cacheAddressArray( NbtAddress[] addrs ) {
249         if( CACHE_POLICY == 0 ) {
250             return;
251         }
252         long expiration = -1;
253         if( CACHE_POLICY != FOREVER ) {
254             expiration = System.currentTimeMillis() + CACHE_POLICY * 1000;
255         }
256         synchronized( ADDRESS_CACHE ) {
257             for( int i = 0; i < addrs.length; i++ ) {
258                 CacheEntry entry = (CacheEntry)ADDRESS_CACHE.get( addrs[i].hostName );
259                 if( entry == null ) {
260                     entry = new CacheEntry( addrs[i].hostName, addrs[i], expiration );
261                     ADDRESS_CACHE.put( addrs[i].hostName, entry );
262                 } else {
263                     entry.address = addrs[i];
264                     entry.expiration = expiration;
265                 }
266             }
267         }
268     }
269     static NbtAddress getCachedAddress( Name hostName ) {
270         if( CACHE_POLICY == 0 ) {
271             return null;
272         }
273         synchronized( ADDRESS_CACHE ) {
274             CacheEntry entry = (CacheEntry)ADDRESS_CACHE.get( hostName );
275             if( entry != null && entry.expiration < System.currentTimeMillis() &&
276                                                 entry.expiration >= 0 ) {
277                 entry = null;
278             }
279             return entry != null ? entry.address : null;
280         }
281     }
282
283     static NbtAddress doNameQuery( Name name, InetAddress JavaDoc svr )
284                                                     throws UnknownHostException JavaDoc {
285         NbtAddress addr;
286
287         if( name.hexCode == 0x1d && svr == null ) {
288             svr = CLIENT.baddr; // bit of a hack but saves a lookup
289
}
290         name.srcHashCode = svr != null ? svr.hashCode() : 0;
291         addr = getCachedAddress( name );
292
293         if( addr == null ) {
294             /* This was copied amost verbatim from InetAddress.java. See the
295              * comments there for a description of how the LOOKUP_TABLE prevents
296              * redundant queries from going out on the wire.
297              */

298             if(( addr = (NbtAddress)checkLookupTable( name )) == null ) {
299                 try {
300                     addr = CLIENT.getByName( name, svr );
301                 } catch( UnknownHostException JavaDoc uhe ) {
302                     addr = UNKNOWN_ADDRESS;
303                 } finally {
304                     cacheAddress( name, addr );
305                     updateLookupTable( name );
306                 }
307             }
308         }
309         if( addr == UNKNOWN_ADDRESS ) {
310             throw new UnknownHostException JavaDoc( name.toString() );
311         }
312         return addr;
313     }
314
315     private static Object JavaDoc checkLookupTable( Name name ) {
316         Object JavaDoc obj;
317
318         synchronized( LOOKUP_TABLE ) {
319             if( LOOKUP_TABLE.containsKey( name ) == false ) {
320                 LOOKUP_TABLE.put( name, name );
321                 return null;
322             }
323             while( LOOKUP_TABLE.containsKey( name )) {
324                 try {
325                     LOOKUP_TABLE.wait();
326                 } catch( InterruptedException JavaDoc e ) {
327                 }
328             }
329         }
330         obj = getCachedAddress( name );
331         if( obj == null ) {
332             synchronized( LOOKUP_TABLE ) {
333                 LOOKUP_TABLE.put( name, name );
334             }
335         }
336
337         return obj;
338     }
339     private static void updateLookupTable( Name name ) {
340         synchronized( LOOKUP_TABLE ) {
341             LOOKUP_TABLE.remove( name );
342             LOOKUP_TABLE.notifyAll();
343         }
344     }
345
346 /**
347  * Retrieves the local host address.
348  *
349  * @throws UnknownHostException This is not likely as the IP returned
350  * by <code>InetAddress</code> should be available
351  */

352
353     public static NbtAddress getLocalHost() throws UnknownHostException JavaDoc {
354         return localhost;
355     }
356
357 /**
358  * Determines the address of a host given it's host name. The name can be a NetBIOS name like
359  * "freto" or an IP address like "192.168.1.15". It cannot be a DNS name;
360  * the analygous {@link jcifs.UniAddress} or {@link java.net.InetAddress}
361  * <code>getByName</code> methods can be used for that.
362  *
363  * @param host hostname to resolve
364  * @throws java.net.UnknownHostException if there is an error resolving the name
365  */

366
367     public static NbtAddress getByName( String JavaDoc host )
368                                         throws UnknownHostException JavaDoc {
369         return getByName( host, 0x00, null );
370     }
371
372 /**
373  * Determines the address of a host given it's host name. NetBIOS
374  * names also have a <code>type</code>. Types(aka Hex Codes)
375  * are used to distiquish the various services on a host. <a
376  * HREF="../../../nbtcodes.html">Here</a> is
377  * a fairly complete list of NetBIOS hex codes. Scope is not used but is
378  * still functional in other NetBIOS products and so for completeness it has been
379  * implemented. A <code>scope</code> of <code>null</code> or <code>""</code>
380  * signifies no scope.
381  *
382  * @param host the name to resolve
383  * @param type the hex code of the name
384  * @param scope the scope of the name
385  * @throws java.net.UnknownHostException if there is an error resolving the name
386  */

387
388     public static NbtAddress getByName( String JavaDoc host,
389                                         int type,
390                                         String JavaDoc scope )
391                                         throws UnknownHostException JavaDoc {
392
393         return getByName( host, type, scope, null );
394     }
395
396 /*
397  * The additional <code>svr</code> parameter specifies the address to
398  * query. This might be the address of a specific host, a name server,
399  * or a broadcast address.
400  */

401
402     public static NbtAddress getByName( String JavaDoc host,
403                                         int type,
404                                         String JavaDoc scope,
405                                         InetAddress JavaDoc svr )
406                                         throws UnknownHostException JavaDoc {
407
408         if( host == null || host.length() == 0 ) {
409             return getLocalHost();
410         }
411         if( !Character.isDigit( host.charAt(0) )) {
412             return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr );
413         } else {
414             int IP = 0x00;
415             int hitDots = 0;
416             char[] data = host.toCharArray();
417
418             for( int i = 0; i < data.length; i++ ) {
419                 char c = data[i];
420                 if( c < 48 || c > 57 ) {
421                     return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr );
422                 }
423                 int b = 0x00;
424                 while( c != '.' ) {
425                     if( c < 48 || c > 57 ) {
426                         return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr );
427                     }
428                     b = b * 10 + c - '0';
429
430                     if( ++i >= data.length )
431                         break;
432
433                     c = data[i];
434                 }
435                 if( b > 0xFF ) {
436                     return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr );
437                 }
438                 IP = ( IP << 8 ) + b;
439                 hitDots++;
440             }
441             if( hitDots != 4 || host.endsWith( "." )) {
442                 return (NbtAddress)doNameQuery( new Name( host, type, scope ), svr );
443             }
444             return new NbtAddress( UNKNOWN_NAME, IP, false, B_NODE );
445         }
446     }
447
448 /**
449  * Retrieve all addresses of a host by it's address. NetBIOS hosts can
450  * have many names for a given IP address. The name and IP address make the
451  * NetBIOS address. This provides a way to retrieve the other names for a
452  * host with the same IP address.
453  *
454  * @param host hostname to lookup all addresses for
455  * @throws java.net.UnknownHostException if there is an error resolving the name
456  */

457
458
459     public static NbtAddress[] getAllByAddress( String JavaDoc host )
460                                                 throws UnknownHostException JavaDoc {
461         return getAllByAddress( getByName( host, 0x00, null ));
462     }
463
464
465 /**
466  * Retrieve all addresses of a host by it's address. NetBIOS hosts can
467  * have many names for a given IP address. The name and IP address make
468  * the NetBIOS address. This provides a way to retrieve the other names
469  * for a host with the same IP address. See {@link #getByName}
470  * for a description of <code>type</code>
471  * and <code>scope</code>.
472  *
473  * @param host hostname to lookup all addresses for
474  * @param type the hexcode of the name
475  * @param scope the scope of the name
476  * @throws java.net.UnknownHostException if there is an error resolving the name
477  */

478
479
480     public static NbtAddress[] getAllByAddress( String JavaDoc host,
481                                         int type,
482                                         String JavaDoc scope )
483                                         throws UnknownHostException JavaDoc {
484         return getAllByAddress( getByName( host, type, scope ));
485     }
486
487
488 /**
489  * Retrieve all addresses of a host by it's address. NetBIOS hosts can
490  * have many names for a given IP address. The name and IP address make the
491  * NetBIOS address. This provides a way to retrieve the other names for a
492  * host with the same IP address.
493  *
494  * @param addr the address to query
495  * @throws UnknownHostException if address cannot be resolved
496  */

497
498     public static NbtAddress[] getAllByAddress( NbtAddress addr )
499                                                 throws UnknownHostException JavaDoc {
500         try {
501             NbtAddress[] addrs = CLIENT.getNodeStatus( addr );
502             cacheAddressArray( addrs );
503             return addrs;
504         } catch( UnknownHostException JavaDoc uhe ) {
505             throw new UnknownHostException JavaDoc( "no name with type 0x" +
506                             Gadgets.toHexString( addr.hostName.hexCode, 2 ) +
507                             ((( addr.hostName.scope == null ) ||
508                             ( addr.hostName.scope.length() == 0 )) ?
509                             " with no scope" : " with scope " + addr.hostName.scope ) +
510                             " for host " + addr.getHostAddress() );
511         }
512     }
513
514     public static InetAddress JavaDoc getWINSAddress() {
515         return NBNS.length == 0 ? null : NBNS[nbnsIndex];
516     }
517     public static boolean isWINS( InetAddress JavaDoc svr ) {
518         for( int i = 0; svr != null && i < NBNS.length; i++ ) {
519             if( svr.hashCode() == NBNS[i].hashCode() ) {
520                 return true;
521             }
522         }
523         return false;
524     }
525     static InetAddress JavaDoc switchWINS() {
526         nbnsIndex = (nbnsIndex + 1) < NBNS.length ? nbnsIndex + 1 : 0;
527         return NBNS.length == 0 ? null : NBNS[nbnsIndex];
528     }
529
530     Name hostName;
531     int address, nodeType;
532     boolean groupName,
533         isBeingDeleted,
534         isInConflict,
535         isActive,
536         isPermanent,
537         isDataFromNodeStatus;
538     byte[] macAddress;
539     String JavaDoc calledName;
540
541     NbtAddress( Name hostName, int address, boolean groupName, int nodeType ) {
542         this.hostName = hostName;
543         this.address = address;
544         this.groupName = groupName;
545         this.nodeType = nodeType;
546     }
547
548     NbtAddress( Name hostName,
549                 int address,
550                 boolean groupName,
551                 int nodeType,
552                 boolean isBeingDeleted,
553                 boolean isInConflict,
554                 boolean isActive,
555                 boolean isPermanent,
556                 byte[] macAddress ) {
557
558 /* The NodeStatusResponse.readNodeNameArray method may also set this
559  * information. These two places where node status data is populated should
560  * be consistent. Be carefull!
561  */

562         this.hostName = hostName;
563         this.address = address;
564         this.groupName = groupName;
565         this.nodeType = nodeType;
566         this.isBeingDeleted = isBeingDeleted;
567         this.isInConflict = isInConflict;
568         this.isActive = isActive;
569         this.isPermanent = isPermanent;
570         this.macAddress = macAddress;
571         isDataFromNodeStatus = true;
572     }
573
574 /* Guess next called name to try for session establishment. These
575  * methods are used by the smb package.
576  */

577
578     public String JavaDoc firstCalledName() {
579
580         calledName = hostName.name;
581
582         if( Character.isDigit( calledName.charAt( 0 ))) {
583             int i, len, dots;
584             char[] data;
585
586             i = dots = 0; /* quick IP address validation */
587             len = calledName.length();
588             data = calledName.toCharArray();
589             while( i < len && Character.isDigit( data[i++] )) {
590                 if( i == len && dots == 3 ) {
591                     // probably an IP address
592
calledName = SMBSERVER_NAME;
593                     break;
594                 }
595                 if( i < len && data[i] == '.' ) {
596                     dots++;
597                     i++;
598                 }
599             }
600         } else if( hostName.hexCode == 0x1D ) {
601             calledName = SMBSERVER_NAME;
602         }
603
604         return calledName;
605     }
606     public String JavaDoc nextCalledName() {
607
608         if( calledName == hostName.name ) {
609             calledName = SMBSERVER_NAME;
610         } else if( calledName == SMBSERVER_NAME ) {
611             NbtAddress[] addrs;
612
613             try {
614                 addrs = CLIENT.getNodeStatus( this );
615                 if( hostName.hexCode == 0x1D ) {
616                     for( int i = 0; i < addrs.length; i++ ) {
617                         if( addrs[i].hostName.hexCode == 0x20 ) {
618                             return addrs[i].hostName.name;
619                         }
620                     }
621                     return null;
622                 } else if( isDataFromNodeStatus ) {
623                     /* 'this' has been updated and should now
624                      * have a real NetBIOS name
625                      */

626                     calledName = null;
627                     return hostName.name;
628                 }
629             } catch( UnknownHostException JavaDoc uhe ) {
630                 calledName = null;
631             }
632         } else {
633             calledName = null;
634         }
635
636         return calledName;
637     }
638
639 /*
640  * There are three degrees of state that any NbtAddress can have.
641  *
642  * 1) IP Address - If a dot-quad IP string is used with getByName (or used
643  * to create an NbtAddress internal to this netbios package), no query is
644  * sent on the wire and the only state this object has is it's IP address
645  * (but that's enough to connect to a host using *SMBSERVER for CallingName).
646  *
647  * 2) IP Address, NetBIOS name, nodeType, groupName - If however a
648  * legal NetBIOS name string is used a name query request will retreive
649  * the IP, node type, and whether or not this NbtAddress represents a
650  * group name. This degree of state can be obtained with a Name Query
651  * Request or Node Status Request.
652  *
653  * 3) All - The NbtAddress will be populated with all state such as mac
654  * address, isPermanent, isBeingDeleted, ...etc. This information can only
655  * be retrieved with the Node Status request.
656  *
657  * The degree of state that an NbtAddress has is dependant on how it was
658  * created and what is required of it. The second degree of state is the
659  * most common. This is the state information that would be retrieved from
660  * WINS for example. Natrually it is not practical for every NbtAddress
661  * to be populated will all state requiring a Node Status on every host
662  * encountered. The below methods allow state to be populated when requested
663  * in a lazy fashon.
664  */

665
666     void checkData() throws UnknownHostException JavaDoc {
667         if( hostName == UNKNOWN_NAME ) {
668             getAllByAddress( this );
669         }
670     }
671     void checkNodeStatusData() throws UnknownHostException JavaDoc {
672         if( isDataFromNodeStatus == false ) {
673             getAllByAddress( this );
674         }
675     }
676
677 /**
678  * Determines if the address is a group address. This is also
679  * known as a workgroup name or group name.
680  *
681  * @throws UnknownHostException if the host cannot be resolved to find out.
682  */

683
684     public boolean isGroupAddress() throws UnknownHostException JavaDoc {
685         checkData();
686         return groupName;
687     }
688
689 /**
690  * Checks the node type of this address.
691  * @return {@link jcifs.netbios.NbtAddress#B_NODE},
692  * {@link jcifs.netbios.NbtAddress#P_NODE}, {@link jcifs.netbios.NbtAddress#M_NODE},
693  * {@link jcifs.netbios.NbtAddress#H_NODE}
694  *
695  * @throws UnknownHostException if the host cannot be resolved to find out.
696  */

697
698     public int getNodeType() throws UnknownHostException JavaDoc {
699         checkData();
700         return nodeType;
701     }
702
703 /**
704  * Determines if this address in the process of being deleted.
705  *
706  * @throws UnknownHostException if the host cannot be resolved to find out.
707  */

708
709     public boolean isBeingDeleted() throws UnknownHostException JavaDoc {
710         checkNodeStatusData();
711         return isBeingDeleted;
712     }
713
714 /**
715  * Determines if this address in conflict with another address.
716  *
717  * @throws UnknownHostException if the host cannot be resolved to find out.
718  */

719
720     public boolean isInConflict() throws UnknownHostException JavaDoc {
721         checkNodeStatusData();
722         return isInConflict;
723     }
724
725 /**
726  * Determines if this address is active.
727  *
728  * @throws UnknownHostException if the host cannot be resolved to find out.
729  */

730
731     public boolean isActive() throws UnknownHostException JavaDoc {
732         checkNodeStatusData();
733         return isActive;
734     }
735
736 /**
737  * Determines if this address is set to be permanent.
738  *
739  * @throws UnknownHostException if the host cannot be resolved to find out.
740  */

741
742     public boolean isPermanent() throws UnknownHostException JavaDoc {
743         checkNodeStatusData();
744         return isPermanent;
745     }
746
747 /**
748  * Retrieves the MAC address of the remote network interface. Samba returns all zeros.
749  *
750  * @return the MAC address as an array of six bytes
751  * @throws UnknownHostException if the host cannot be resolved to
752  * determine the MAC address.
753  */

754
755     public byte[] getMacAddress() throws UnknownHostException JavaDoc {
756         checkNodeStatusData();
757         return macAddress;
758     }
759
760 /**
761  * The hostname of this address. If the hostname is null the local machines
762  * IP address is returned.
763  *
764  * @return the text representation of the hostname associated with this address
765  */

766
767     public String JavaDoc getHostName() {
768         try {
769             checkData();
770         } catch( UnknownHostException JavaDoc uhe ) {
771             return getHostAddress();
772         }
773         return hostName.name;
774     }
775
776
777 /**
778  * Returns the raw IP address of this NbtAddress. The result is in network
779  * byte order: the highest order byte of the address is in getAddress()[0].
780  *
781  * @return a four byte array
782  */

783
784     public byte[] getAddress() {
785         byte[] addr = new byte[4];
786
787         addr[0] = (byte)(( address >>> 24 ) & 0xFF );
788         addr[1] = (byte)(( address >>> 16 ) & 0xFF );
789         addr[2] = (byte)(( address >>> 8 ) & 0xFF );
790         addr[3] = (byte)( address & 0xFF );
791         return addr;
792     }
793
794 /**
795  * To convert this address to an <code>InetAddress</code>.
796  *
797  * @return the {@link java.net.InetAddress} representation of this address.
798  */

799
800     public InetAddress JavaDoc getInetAddress() throws UnknownHostException JavaDoc {
801         return InetAddress.getByName( getHostAddress() );
802     }
803
804 /**
805  * Returns this IP adress as a {@link java.lang.String} in the form "%d.%d.%d.%d".
806  */

807
808     public String JavaDoc getHostAddress() {
809         return (( address >>> 24 ) & 0xFF ) + "." +
810             (( address >>> 16 ) & 0xFF ) + "." +
811             (( address >>> 8 ) & 0xFF ) + "." +
812             (( address >>> 0 ) & 0xFF );
813     }
814
815 /**
816  * Returned the hex code associated with this name(e.g. 0x20 is for the file service)
817  */

818
819     public int getNameType() {
820         return hostName.hexCode;
821     }
822
823 /**
824  * Returns a hashcode for this IP address. The hashcode comes from the IP address
825  * and is not generated from the string representation. So because NetBIOS nodes
826  * can have many names, all names associated with an IP will have the same
827  * hashcode.
828  */

829
830     public int hashCode() {
831         return address;
832     }
833
834 /**
835  * Determines if this address is equal two another. Only the IP Addresses
836  * are compared. Similar to the {@link #hashCode} method, the comparison
837  * is based on the integer IP address and not the string representation.
838  */

839
840     public boolean equals( Object JavaDoc obj ) {
841         return ( obj != null ) && ( obj instanceof NbtAddress ) &&
842                                         ( ((NbtAddress)obj).address == address );
843     }
844
845 /**
846  * Returns the {@link java.lang.String} representaion of this address.
847  */

848
849     public String JavaDoc toString() {
850         return hostName.toString() + "/" + getHostAddress();
851     }
852 }
853
Popular Tags