KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > filesys > netbios > win32 > Win32NetBIOS


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.filesys.netbios.win32;
18
19 import java.net.InetAddress JavaDoc;
20 import java.net.NetworkInterface JavaDoc;
21 import java.net.SocketException JavaDoc;
22 import java.util.Enumeration JavaDoc;
23 import java.util.Hashtable JavaDoc;
24
25 import org.alfresco.filesys.netbios.NetBIOSName;
26 import org.alfresco.filesys.util.DataBuffer;
27 import org.alfresco.filesys.util.IPAddress;
28
29 /**
30  * Win32 NetBIOS Native Call Wrapper Class
31  */

32 public class Win32NetBIOS
33 {
34
35     // Constants
36
//
37
// FIND_NAME_BUFFER structure length
38

39     protected final static int FindNameBufferLen = 33;
40
41     // Exception if the native code DLL load failed
42

43     private static Throwable JavaDoc m_loadDLLException;
44
45     /**
46      * Check if the native code was loaded successfully
47      *
48      * @return boolean
49      */

50     public static final boolean isInitialized()
51     {
52         return m_loadDLLException == null ? true : false;
53     }
54
55     /**
56      * Return the native code load exception
57      *
58      * @return Throwable
59      */

60     public static final Throwable JavaDoc getInitializationException()
61     {
62         return m_loadDLLException;
63     }
64
65     /**
66      * Check if NetBIOS is enabled on any network adapters
67      *
68      * @return boolean
69      */

70     public static final boolean isAvailable() {
71         
72         // Check if the DLL was loaded successfully
73

74         if ( isInitialized() == false)
75             return false;
76         
77         // Check if there are any valid LANAs, if not then NetBIOS is not enabled or network
78
// adapters that have NetBIOS enabled are not currently enabled
79

80         int[] lanas = LanaEnum();
81         if ( lanas != null && lanas.length > 0)
82             return true;
83         return false;
84     }
85     
86     /**
87      * Add a NetBIOS name to the local name table
88      *
89      * @param lana int
90      * @param name byte[]
91      * @return int
92      */

93     public static native int AddName(int lana, byte[] name);
94
95     /**
96      * Add a group NetBIOS name to the local name table
97      *
98      * @param lana int
99      * @param name byte[]
100      * @return int
101      */

102     public static native int AddGroupName(int lana, byte[] name);
103
104     /**
105      * Find a NetBIOS name, return the name buffer
106      *
107      * @param lana int
108      * @param name byte[]
109      * @param nameBuf byte[]
110      * @param bufLen int
111      * @return int
112      */

113     public static native int FindNameRaw(int lana, byte[] name, byte[] nameBuf, int bufLen);
114
115     /**
116      * Find a NetBIOS name
117      *
118      * @param lana int
119      * @param name NetBIOSName
120      * @return int
121      */

122     public static int FindName(int lana, NetBIOSName nbName)
123     {
124
125         // Allocate a buffer to receive the name details
126

127         byte[] nameBuf = new byte[nbName.isGroupName() ? 65535 : 4096];
128
129         // Get the raw NetBIOS name data
130

131         int sts = FindNameRaw(lana, nbName.getNetBIOSName(), nameBuf, nameBuf.length);
132
133         if (sts != NetBIOS.NRC_GoodRet)
134             return -sts;
135
136         // Unpack the FIND_NAME_HEADER structure
137

138         DataBuffer buf = new DataBuffer(nameBuf, 0, nameBuf.length);
139
140         int nodeCount = buf.getShort();
141         buf.skipBytes(1);
142         boolean isGroupName = buf.getByte() == 0 ? false : true;
143
144         // Unpack the FIND_NAME_BUFFER structures
145

146         int curPos = buf.getPosition();
147
148         for (int i = 0; i < nodeCount; i++)
149         {
150
151             // FIND_NAME_BUFFER:
152
// UCHAR length
153
// UCHAR access_control
154
// UCHAR frame_control
155
// UCHAR destination_addr[6]
156
// UCHAR source_addr[6]
157
// UCHAR routing_info[18]
158

159             // Skip to the source_addr field
160

161             buf.skipBytes(9);
162
163             // Source address field format should be 0.0.n.n.n.n for TCP/IP address
164

165             if (buf.getByte() == 0 && buf.getByte() == 0)
166             {
167
168                 // Looks like a TCP/IP format address, unpack it
169

170                 byte[] ipAddr = new byte[4];
171
172                 ipAddr[0] = (byte) buf.getByte();
173                 ipAddr[1] = (byte) buf.getByte();
174                 ipAddr[2] = (byte) buf.getByte();
175                 ipAddr[3] = (byte) buf.getByte();
176
177                 // Add the address to the list of TCP/IP addresses for the NetBIOS name
178

179                 nbName.addIPAddress(ipAddr);
180
181                 // Skip to the start of the next FIND_NAME_BUFFER structure
182

183                 curPos += FindNameBufferLen;
184                 buf.setPosition(curPos);
185             }
186         }
187
188         // Return the node count
189

190         return nodeCount;
191     }
192
193     /**
194      * Delete a NetBIOS name from the local name table
195      *
196      * @param lana int
197      * @param name byte[]
198      * @return int
199      */

200     public static native int DeleteName(int lana, byte[] name);
201
202     /**
203      * Enumerate the available LANAs
204      *
205      * @return int[]
206      */

207     public static int[] LanaEnumerate()
208     {
209         // Make sure that there is an active network adapter as making calls to the LanaEnum native call
210
// causes problems when there are no active network adapters.
211

212         boolean adapterAvail = false;
213         
214         try
215         {
216             // Enumerate the available network adapters and check for an active adapter, not including
217
// the loopback adapter
218

219             Enumeration JavaDoc<NetworkInterface JavaDoc> nis = NetworkInterface.getNetworkInterfaces();
220             
221             while ( nis.hasMoreElements() && adapterAvail == false)
222             {
223                 NetworkInterface JavaDoc ni = nis.nextElement();
224                 if ( ni.getName().equals("lo") == false)
225                 {
226                     // Make sure the adapter has a valid IP address
227

228                     Enumeration JavaDoc<InetAddress JavaDoc> addrs = ni.getInetAddresses();
229                     if ( addrs.hasMoreElements())
230                         adapterAvail = true;
231                 }
232             }
233             
234         }
235         catch ( SocketException JavaDoc ex)
236         {
237         }
238         
239         // Check if there are network adapter(s) available
240

241         if ( adapterAvail == false)
242             return null;
243         
244         // Call the native code to return the available LANA list
245

246         return LanaEnum();
247     }
248     
249     /**
250      * Enumerate the available LANAs
251      *
252      * @return int[]
253      */

254     private static native int[] LanaEnum();
255
256     /**
257      * Reset the NetBIOS environment
258      *
259      * @param lana int
260      * @return int
261      */

262     public static native int Reset(int lana);
263
264     /**
265      * Listen for an incoming session request
266      *
267      * @param lana int
268      * @param toName byte[]
269      * @param fromName byte[]
270      * @param callerName byte[]
271      * @return int
272      */

273     public static native int Listen(int lana, byte[] toName, byte[] fromName, byte[] callerName);
274
275     /**
276      * Receive a data packet on a session
277      *
278      * @param lana int
279      * @param lsn int
280      * @param buf byte[]
281      * @param off int
282      * @param maxLen int
283      * @return int
284      */

285     public static native int Receive(int lana, int lsn, byte[] buf, int off, int maxLen);
286
287     /**
288      * Send a data packet on a session
289      *
290      * @param lana int
291      * @param lsn int
292      * @param buf byte[]
293      * @param off int
294      * @param len int
295      * @return int
296      */

297     public static native int Send(int lana, int lsn, byte[] buf, int off, int len);
298
299     /**
300      * Send a datagram to a specified name
301      *
302      * @param lana int
303      * @param srcNum int
304      * @param destName byte[]
305      * @param buf byte[]
306      * @param off int
307      * @param len int
308      * @return int
309      */

310     public static native int SendDatagram(int lana, int srcNum, byte[] destName, byte[] buf, int off, int len);
311
312     /**
313      * Send a broadcast datagram
314      *
315      * @param lana
316      * @param buf byte[]
317      * @param off int
318      * @param len int
319      * @return int
320      */

321     public static native int SendBroadcastDatagram(int lana, byte[] buf, int off, int len);
322
323     /**
324      * Receive a datagram on a specified name
325      *
326      * @param lana int
327      * @param nameNum int
328      * @param buf byte[]
329      * @param off int
330      * @param maxLen int
331      * @return int
332      */

333     public static native int ReceiveDatagram(int lana, int nameNum, byte[] buf, int off, int maxLen);
334
335     /**
336      * Receive a broadcast datagram
337      *
338      * @param lana int
339      * @param nameNum int
340      * @param buf byte[]
341      * @param off int
342      * @param maxLen int
343      * @return int
344      */

345     public static native int ReceiveBroadcastDatagram(int lana, int nameNum, byte[] buf, int off, int maxLen);
346
347     /**
348      * Hangup a session
349      *
350      * @param lsn int
351      * @return int
352      */

353     public static native int Hangup(int lana, int lsn);
354
355     /**
356      * Return the local computers NetBIOS name
357      *
358      * @return String
359      */

360     public static native String JavaDoc GetLocalNetBIOSName();
361
362     /**
363      * Return the local domain name
364      *
365      * @return String
366      */

367     public static native String JavaDoc GetLocalDomainName();
368
369     /**
370      * Return a comma delimeted list of WINS server TCP/IP addresses, or null if no WINS servers are
371      * configured.
372      *
373      * @return String
374      */

375     public static native String JavaDoc getWINSServerList();
376
377     /**
378      * Find the TCP/IP address for a LANA
379      *
380      * @param lana int
381      * @return String
382      */

383     public static final String JavaDoc getIPAddressForLANA(int lana)
384     {
385
386         // Get the local NetBIOS name
387

388         String JavaDoc localName = GetLocalNetBIOSName();
389         if (localName == null)
390             return null;
391
392         // Create a NetBIOS name for the local name
393

394         NetBIOSName nbName = new NetBIOSName(localName, NetBIOSName.WorkStation, false);
395
396         // Get the local NetBIOS name details
397

398         int sts = FindName(lana, nbName);
399
400         if (sts == -NetBIOS.NRC_EnvNotDef)
401         {
402
403             // Reset the LANA then try the name lookup again
404

405             Reset(lana);
406             sts = FindName(lana, nbName);
407         }
408
409         // Check if the name lookup was successful
410

411         String JavaDoc ipAddr = null;
412
413         if (sts >= 0)
414         {
415
416             // Get the first IP address from the list
417

418             ipAddr = nbName.getIPAddressString(0);
419         }
420
421         // Return the TCP/IP address for the LANA
422

423         return ipAddr;
424     }
425
426     /**
427      * Find the adapter name for a LANA
428      *
429      * @param lana int
430      * @return String
431      */

432     public static final String JavaDoc getAdapterNameForLANA(int lana)
433     {
434
435         // Get the TCP/IP address for a LANA
436

437         String JavaDoc ipAddr = getIPAddressForLANA(lana);
438         if (ipAddr == null)
439             return null;
440
441         // Get the list of available network adapters
442

443         Hashtable JavaDoc<String JavaDoc, NetworkInterface JavaDoc> adapters = getNetworkAdapterList();
444         String JavaDoc adapterName = null;
445
446         if (adapters != null)
447         {
448
449             // Find the network adapter for the TCP/IP address
450

451             NetworkInterface JavaDoc ni = adapters.get(ipAddr);
452             if (ni != null)
453                 adapterName = ni.getDisplayName();
454         }
455
456         // Return the adapter name for the LANA
457

458         return adapterName;
459     }
460
461     /**
462      * Find the LANA for a TCP/IP address
463      *
464      * @param addr String
465      * @return int
466      */

467     public static final int getLANAForIPAddress(String JavaDoc addr)
468     {
469
470         // Check if the address is a numeric TCP/IP address
471

472         if (IPAddress.isNumericAddress(addr) == false)
473             return -1;
474
475         // Get a list of the available NetBIOS LANAs
476

477         int[] lanas = LanaEnum();
478         if (lanas == null || lanas.length == 0)
479             return -1;
480
481         // Search for the LANA with the matching TCP/IP address
482

483         for (int i = 0; i < lanas.length; i++)
484         {
485
486             // Get the current LANAs TCP/IP address
487

488             String JavaDoc curAddr = getIPAddressForLANA(lanas[i]);
489             if (curAddr != null && curAddr.equals(addr))
490                 return lanas[i];
491         }
492
493         // Failed to find the LANA for the specified TCP/IP address
494

495         return -1;
496     }
497
498     /**
499      * Find the LANA for a network adapter
500      *
501      * @param name String
502      * @return int
503      */

504     public static final int getLANAForAdapterName(String JavaDoc name)
505     {
506
507         // Get the list of available network adapters
508

509         Hashtable JavaDoc<String JavaDoc, NetworkInterface JavaDoc> niList = getNetworkAdapterList();
510
511         // Search for the address of the specified network adapter
512

513         Enumeration JavaDoc<String JavaDoc> niEnum = niList.keys();
514
515         while (niEnum.hasMoreElements())
516         {
517
518             // Get the current TCP/IP address
519

520             String JavaDoc ipAddr = niEnum.nextElement();
521             NetworkInterface JavaDoc ni = niList.get(ipAddr);
522
523             if (ni.getDisplayName().equalsIgnoreCase(name))
524             {
525
526                 // Return the LANA for the network adapters TCP/IP address
527

528                 return getLANAForIPAddress(ipAddr);
529             }
530         }
531
532         // Failed to find matching network adapter
533

534         return -1;
535     }
536
537     /**
538      * Return a hashtable of NetworkInterfaces indexed by TCP/IP address
539      *
540      * @return Hashtable<String,NetworkInterface>
541      */

542     private static final Hashtable JavaDoc<String JavaDoc, NetworkInterface JavaDoc> getNetworkAdapterList()
543     {
544
545         // Get a list of the local network adapters
546

547         Hashtable JavaDoc<String JavaDoc, NetworkInterface JavaDoc> niList = new Hashtable JavaDoc<String JavaDoc, NetworkInterface JavaDoc>();
548
549         try
550         {
551
552             // Enumerate the available network adapters
553

554             Enumeration JavaDoc<NetworkInterface JavaDoc> niEnum = NetworkInterface.getNetworkInterfaces();
555
556             while (niEnum.hasMoreElements())
557             {
558
559                 // Get the current network interface details
560

561                 NetworkInterface JavaDoc ni = niEnum.nextElement();
562                 Enumeration JavaDoc<InetAddress JavaDoc> addrEnum = ni.getInetAddresses();
563
564                 while (addrEnum.hasMoreElements())
565                 {
566
567                     // Get the address and add the adapter to the list indexed via the numeric IP
568
// address string
569

570                     InetAddress JavaDoc addr = addrEnum.nextElement();
571                     niList.put(addr.getHostAddress(), ni);
572                 }
573             }
574         }
575         catch (Exception JavaDoc ex)
576         {
577         }
578
579         // Return the network adapter list
580

581         return niList;
582     }
583
584     //---------- Winsock based NetBIOS interface ----------//
585

586     /**
587      * Initialize the NetBIOS socket interface
588      *
589      * @exception WinsockNetBIOSException If a Winsock error occurs
590      */

591     protected static native void InitializeSockets()
592         throws WinsockNetBIOSException;
593     
594     /**
595      * Shutdown the NetBIOS socket interface
596      */

597     protected static native void ShutdownSockets();
598     
599     /**
600      * Create a NetBIOS socket
601      *
602      * @param lana int
603      * @return int
604      * @exception WinsockNetBIOSException If a Winsock error occurs
605      */

606     protected static native int CreateSocket(int lana)
607         throws WinsockNetBIOSException;
608     
609     /**
610      * Create a NetBIOS datagram socket
611      *
612      * @param lana int
613      * @return int
614      * @exception WinsockNetBIOSException If a Winsock error occurs
615      */

616     protected static native int CreateDatagramSocket(int lana)
617         throws WinsockNetBIOSException;
618     
619     /**
620      * Bind a NetBIOS socket to a name to listen for incoming sessions
621      *
622      * @param sockPtr int
623      * @param name byte[]
624      * @exception WinsockNetBIOSException If a Winsock error occurs
625      */

626     protected static native int BindSocket(int sockPtr, byte[] name)
627         throws WinsockNetBIOSException;
628     
629     /**
630      * Listen for an incoming connection
631      *
632      * @param sockPtr int
633      * @param callerName byte[]
634      * @return int
635      * @exception WinsockNetBIOSException If a Winsock error occurs
636      */

637     protected static native int ListenSocket(int sockPtr, byte[] callerName)
638         throws WinsockNetBIOSException;
639
640     /**
641      * Close a NetBIOS socket
642      *
643      * @param sockPtr int
644      */

645     protected static native void CloseSocket(int sockPtr);
646     
647     /**
648      * Send data on a session socket
649      *
650      * @param sockPtr int
651      * @param buf byte[]
652      * @param off int
653      * @param len int
654      * @return int
655      * @exception WinsockNetBIOSException If a Winsock error occurs
656      */

657     protected static native int SendSocket(int sockPtr, byte[] buf, int off, int len)
658         throws WinsockNetBIOSException;
659
660     /**
661      * Receive data on a session socket
662      *
663      * @param sockPtr int
664      * @param toName byte[]
665      * @param buf byte[]
666      * @param off int
667      * @param maxLen int
668      * @return int
669      * @exception WinsockNetBIOSException If a Winsock error occurs
670      */

671     protected static native int ReceiveSocket(int sockPtr, byte[] buf, int off, int maxLen)
672         throws WinsockNetBIOSException;
673
674     /**
675      * Send data on a datagram socket
676      *
677      * @param sockPtr int
678      * @param toName byte[]
679      * @param buf byte[]
680      * @param off int
681      * @param len int
682      * @return int
683      * @exception WinsockNetBIOSException If a Winsock error occurs
684      */

685     protected static native int SendSocketDatagram(int sockPtr, byte[] toName, byte[] buf, int off, int len)
686         throws WinsockNetBIOSException;
687     
688     /**
689      * Wait for a network address change event, block until a change occurs or the Winsock NetBIOS
690      * interface is shut down
691      */

692     public static native void waitForNetworkAddressChange();
693     
694     /**
695      * Static initializer used to load the native code library
696      */

697     static
698     {
699
700         // Load the Win32 NetBIOS interface library
701

702         try
703         {
704             System.loadLibrary("Win32NetBIOS");
705         }
706         catch (Throwable JavaDoc ex)
707         {
708             // Save the native code load exception
709

710             m_loadDLLException = ex;
711         }
712     }
713 }
714
Popular Tags