KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > filesys > netbios > NetBIOSDatagram


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;
18
19 import java.io.IOException JavaDoc;
20 import java.net.DatagramPacket JavaDoc;
21 import java.net.DatagramSocket JavaDoc;
22 import java.net.InetAddress JavaDoc;
23 import java.net.UnknownHostException JavaDoc;
24
25 import org.alfresco.filesys.util.DataPacker;
26
27 /**
28  * NetBIOS datagram class.
29  */

30 public class NetBIOSDatagram
31 {
32     // Datagram types
33

34     public static final int DIRECT_UNIQUE = 0x10;
35     public static final int DIRECT_GROUP = 0x11;
36     public static final int BROADCAST = 0x12;
37     public static final int DATAGRAM_ERROR = 0x13;
38     public static final int DATAGRAM_QUERY = 0x14;
39     public static final int POSITIVE_RESP = 0x15;
40     public static final int NEGATIVE_RESP = 0x16;
41
42     // Datagram flags
43

44     public static final int FLG_MOREFRAGMENTS = 0x01;
45     public static final int FLG_FIRSTPKT = 0x02;
46
47     // Default NetBIOS packet buffer size to allocate
48

49     public static final int DEFBUFSIZE = 4096;
50
51     // NetBIOS datagram offsets
52

53     public static final int NB_MSGTYPE = 0;
54     public static final int NB_FLAGS = 1;
55     public static final int NB_DATAGRAMID = 2;
56     public static final int NB_SOURCEIP = 4;
57     public static final int NB_SOURCEPORT = 8;
58     public static final int NB_DATAGRAMLEN = 10;
59     public static final int NB_PKTOFFSET = 12;
60     public static final int NB_FROMNAME = 14;
61     public static final int NB_TONAME = 48;
62     public static final int NB_USERDATA = 82;
63
64     public static final int NB_MINLENGTH = 82;
65     public static final int NB_MINSMBLEN = 100;
66
67     // NetBIOS packet buffer
68

69     protected byte[] m_buf;
70
71     // Next available datagram id
72

73     private static int m_nextId;
74
75     /**
76      * NetBIOS Datagram constructor
77      */

78
79     public NetBIOSDatagram()
80     {
81
82         // Allocaet a NetBIOS packet buffer
83

84         m_buf = new byte[DEFBUFSIZE];
85     }
86
87     /**
88      * Create a new NetBIOS datagram using the specified packet buffer.
89      *
90      * @param pkt byte[]
91      */

92     public NetBIOSDatagram(byte[] pkt)
93     {
94         m_buf = pkt;
95     }
96
97     /**
98      * Create a new NetBIOS datagram with the specified buffer size.
99      *
100      * @param bufSize int
101      */

102     public NetBIOSDatagram(int bufSize)
103     {
104         m_buf = new byte[bufSize];
105     }
106
107     /**
108      * Return the next available datagram id.
109      */

110     public final static synchronized int getNextDatagramId()
111     {
112
113         // Update and return the next available datagram id
114

115         return m_nextId++;
116     }
117
118     /**
119      * Return the NetBIOS buffer.
120      *
121      * @return byte[]
122      */

123     public final byte[] getBuffer()
124     {
125         return m_buf;
126     }
127
128     /**
129      * Get the datagram id.
130      *
131      * @return int
132      */

133     public final int getDatagramId()
134     {
135         return DataPacker.getIntelShort(m_buf, NB_DATAGRAMID);
136     }
137
138     /**
139      * Get the datagram destination name.
140      *
141      * @return NetBIOSName
142      */

143     public final NetBIOSName getDestinationName()
144     {
145
146         // Decode the NetBIOS name to a string
147

148         String JavaDoc name = NetBIOSSession.DecodeName(m_buf, NB_TONAME + 1);
149         if (name != null)
150         {
151
152             // Convert the name string to a NetBIOS name
153

154             NetBIOSName nbName = new NetBIOSName(name.substring(0, 14), name.charAt(15), false);
155             if (getMessageType() == DIRECT_GROUP)
156                 nbName.setGroup(true);
157             return nbName;
158         }
159         return null;
160     }
161
162     /**
163      * Return the datagram flags value.
164      *
165      * @return int
166      */

167     public final int getFlags()
168     {
169         return m_buf[NB_FLAGS] & 0xFF;
170     }
171
172     /**
173      * Return the datagram length.
174      *
175      * @return int
176      */

177     public final int getLength()
178     {
179         return DataPacker.getShort(m_buf, NB_DATAGRAMLEN);
180     }
181
182     /**
183      * Return the user data length
184      *
185      * @return int
186      */

187     public final int getDataLength()
188     {
189         return getLength() - NB_USERDATA;
190     }
191
192     /**
193      * Get the NetBIOS datagram message type.
194      *
195      * @return int
196      */

197     public final int getMessageType()
198     {
199         return m_buf[NB_MSGTYPE] & 0xFF;
200     }
201
202     /**
203      * Return the datagram source IP address.
204      *
205      * @return byte[]
206      */

207     public final byte[] getSourceIPAddress()
208     {
209
210         // Allocate a 4 byte array for the IP address
211

212         byte[] ipaddr = new byte[4];
213
214         // Copy the IP address bytes from the datagram
215

216         for (int i = 0; i < 4; i++)
217             ipaddr[i] = m_buf[NB_SOURCEIP + i];
218
219         // Return the IP address bytes
220

221         return ipaddr;
222     }
223
224     /**
225      * Return the datagram source IP address, as a string
226      *
227      * @return String
228      */

229     public final String JavaDoc getSourceAddress()
230     {
231
232         // Get the IP address
233

234         byte[] addr = getSourceIPAddress();
235
236         // Build the IP address string
237

238         StringBuffer JavaDoc addrStr = new StringBuffer JavaDoc();
239
240         addrStr.append(addr[0]);
241         addrStr.append(".");
242         addrStr.append(addr[1]);
243         addrStr.append(".");
244         addrStr.append(addr[2]);
245         addrStr.append(".");
246         addrStr.append(addr[3]);
247
248         return addrStr.toString();
249     }
250
251     /**
252      * Get the source NetBIOS name.
253      *
254      * @return java.lang.String
255      */

256     public final NetBIOSName getSourceName()
257     {
258
259         // Decode the NetBIOS name string
260

261         String JavaDoc name = NetBIOSSession.DecodeName(m_buf, NB_FROMNAME + 1);
262
263         // Convert the name to a NetBIOS name
264

265         if (name != null)
266         {
267
268             // Convert the name string to a NetBIOS name
269

270             NetBIOSName nbName = new NetBIOSName(name.substring(0, 14), name.charAt(15), false);
271             return nbName;
272         }
273         return null;
274     }
275
276     /**
277      * Get the source port/socket for the datagram.
278      *
279      * @return int
280      */

281     public final int getSourcePort()
282     {
283         return DataPacker.getIntelShort(m_buf, NB_SOURCEPORT);
284     }
285
286     /**
287      * Check if the user data is an SMB packet
288      *
289      * @return boolean
290      */

291     public final boolean isSMBData()
292     {
293         if (m_buf[NB_USERDATA] == (byte) 0xFF && m_buf[NB_USERDATA + 1] == (byte) 'S'
294                 && m_buf[NB_USERDATA + 2] == (byte) 'M' && m_buf[NB_USERDATA + 3] == (byte) 'B'
295                 && getLength() >= NB_MINSMBLEN)
296             return true;
297         return false;
298     }
299
300     /**
301      * Return the message type as a string
302      *
303      * @return String
304      */

305
306     public final String JavaDoc getMessageTypeString()
307     {
308
309         // Determine the message type
310

311         String JavaDoc typ = null;
312
313         switch (getMessageType())
314         {
315         case DIRECT_GROUP:
316             typ = "DIRECT GROUP";
317             break;
318         case DIRECT_UNIQUE:
319             typ = "DIRECT UNIQUE";
320             break;
321         case DATAGRAM_ERROR:
322             typ = "DATAGRAM ERROR";
323             break;
324         case DATAGRAM_QUERY:
325             typ = "DATAGRAM QUERY";
326             break;
327         case BROADCAST:
328             typ = "BROADCAST";
329             break;
330         case POSITIVE_RESP:
331             typ = "POSITIVE RESP";
332             break;
333         case NEGATIVE_RESP:
334             typ = "NEGATIVE RESP";
335             break;
336         default:
337             typ = "UNKNOWN";
338             break;
339         }
340
341         // Return the message type string
342

343         return typ;
344     }
345
346     /**
347      * Send a datagram to the specified NetBIOS name using the global NetBIOS datagram socket
348      *
349      * @param dgramTyp Datagram type
350      * @param fromName From NetBIOS name
351      * @param fromNameTyp From NetBIOS name type.
352      * @param toName To NetBIOS name
353      * @param toNameType To NetBIOS name type.
354      * @param userData User data buffer
355      * @param userLen User data length.
356      * @param userOff Offset of data within user buffer.
357      * @param addr Address to send to
358      * @param port Port to send to
359      * @exception java.io.IOException Error occurred sending datagram
360      * @exception UnknownHostException Failed to generate the broadcast mask for the network
361      */

362     public final void SendDatagram(int dgramTyp, String JavaDoc fromName, char fromNameType, String JavaDoc toName, char toNameType,
363             byte[] userData, int userLen, int userOff, InetAddress JavaDoc addr, int port) throws IOException JavaDoc,
364             UnknownHostException JavaDoc
365     {
366
367         // Set the datagram header values
368

369         setMessageType(dgramTyp);
370         setSourceName(fromName, fromNameType);
371         setDestinationName(toName, toNameType);
372         setSourcePort(RFCNetBIOSProtocol.DATAGRAM);
373         setSourceIPAddress(InetAddress.getLocalHost().getAddress());
374         setFlags(FLG_FIRSTPKT);
375
376         if (m_nextId == 0)
377             m_nextId = (int) (System.currentTimeMillis() & 0x7FFF);
378         setDatagramId(m_nextId++);
379
380         // Set the user data and length
381

382         setLength(userLen + NB_USERDATA);
383         setUserData(userData, userLen, userOff);
384
385         // Use the global NetBIOS datagram socket to sent the broadcast datagram
386

387         NetBIOSDatagramSocket nbSocket = NetBIOSDatagramSocket.getInstance();
388         nbSocket.sendDatagram(this, addr, port);
389     }
390
391     /**
392      * Send a datagram to the specified NetBIOS name using the global NetBIOS datagram socket
393      *
394      * @param dgramTyp Datagram type
395      * @param fromName From NetBIOS name
396      * @param fromNameTyp From NetBIOS name type.
397      * @param toName To NetBIOS name
398      * @param toNameType To NetBIOS name type.
399      * @param userData User data buffer
400      * @param userLen User data length.
401      * @param userOff Offset of data within user buffer.
402      * @exception java.io.IOException Error occurred sending datagram
403      * @exception UnknownHostException Failed to generate the broadcast mask for the network
404      */

405     public final void SendDatagram(int dgramTyp, String JavaDoc fromName, char fromNameType, String JavaDoc toName, char toNameType,
406             byte[] userData, int userLen, int userOff) throws IOException JavaDoc, UnknownHostException JavaDoc
407     {
408
409         // Set the datagram header values
410

411         setMessageType(dgramTyp);
412         setSourceName(fromName, fromNameType);
413         setDestinationName(toName, toNameType);
414         setSourcePort(RFCNetBIOSProtocol.DATAGRAM);
415         setSourceIPAddress(InetAddress.getLocalHost().getAddress());
416         setFlags(FLG_FIRSTPKT);
417
418         if (m_nextId == 0)
419             m_nextId = (int) (System.currentTimeMillis() & 0x7FFF);
420         setDatagramId(m_nextId++);
421
422         // Set the user data and length
423

424         setLength(userLen + NB_USERDATA);
425         setUserData(userData, userLen, userOff);
426
427         // Use the global NetBIOS datagram socket to sent the broadcast datagram
428

429         NetBIOSDatagramSocket nbSocket = NetBIOSDatagramSocket.getInstance();
430         nbSocket.sendBroadcastDatagram(this);
431     }
432
433     /**
434      * Send a datagram to the specified NetBIOS name using the global NetBIOS datagram socket
435      *
436      * @param dgramTyp Datagram type
437      * @param fromName From NetBIOS name
438      * @param fromNameTyp From NetBIOS name type.
439      * @param toName To NetBIOS name
440      * @param toNameType To NetBIOS name type.
441      * @param userData User data buffer
442      * @param userLen User data length.
443      * @exception java.io.IOException Error occurred sending datagram
444      * @exception UnknownHostException Failed to generate the broadcast mask for the network
445      */

446     public final void SendDatagram(int dgramTyp, String JavaDoc fromName, String JavaDoc toName, byte[] userData, int userLen)
447             throws IOException JavaDoc, UnknownHostException JavaDoc
448     {
449
450         // Send the datagram from the standard port
451

452         SendDatagram(dgramTyp, fromName, NetBIOSName.FileServer, toName, NetBIOSName.FileServer, userData, userLen, 0);
453     }
454
455     /**
456      * Send a datagram to the specified NetBIOS name using the supplised datagram socket.
457      *
458      * @param dgramTyp Datagram type
459      * @param sock Datagram socket to use to send the datagram packet.
460      * @param fromName From NetBIOS name
461      * @param fromNameTyp From NetBIOS name type.
462      * @param toName To NetBIOS name
463      * @param toNameType To NetBIOS name type.
464      * @param userData User data buffer
465      * @param userLen User data length.
466      * @param userOff Offset of data within user buffer.
467      * @exception java.io.IOException The exception description.
468      */

469     public final void SendDatagram(int dgramTyp, DatagramSocket JavaDoc sock, String JavaDoc fromName, char fromNameType,
470             String JavaDoc toName, char toNameType, byte[] userData, int userLen, int userOff) throws IOException JavaDoc
471     {
472
473         // Set the datagram header values
474

475         setMessageType(dgramTyp);
476         setSourceName(fromName, fromNameType);
477         setDestinationName(toName, toNameType);
478         setSourcePort(RFCNetBIOSProtocol.DATAGRAM);
479         setSourceIPAddress(InetAddress.getLocalHost().getAddress());
480         setFlags(FLG_FIRSTPKT);
481
482         if (m_nextId == 0)
483             m_nextId = (int) (System.currentTimeMillis() & 0x7FFF);
484         setDatagramId(m_nextId++);
485
486         // Set the user data and length
487

488         setLength(userLen + NB_USERDATA);
489         setUserData(userData, userLen, userOff);
490
491         // Build a broadcast destination address
492

493         InetAddress JavaDoc destAddr = InetAddress.getByName(NetworkSettings.GenerateBroadcastMask(null));
494         DatagramPacket JavaDoc dgram = new DatagramPacket JavaDoc(m_buf, userLen + NB_USERDATA, destAddr, RFCNetBIOSProtocol.DATAGRAM);
495
496         // Debug
497

498         // HexDump.Dump( m_buf, userLen + NB_USERDATA, 0);
499

500         // Send the datagram
501

502         sock.send(dgram);
503     }
504
505     /**
506      * Send a datagram to the specified NetBIOS name using the supplied datagram socket.
507      *
508      * @param fromName java.lang.String
509      * @param toName java.lang.String
510      * @param userData byte[]
511      * @param userLen int
512      * @exception java.io.IOException The exception description.
513      */

514     public final void SendDatagram(int dgramTyp, DatagramSocket JavaDoc sock, String JavaDoc fromName, String JavaDoc toName, byte[] userData,
515             int userLen) throws IOException JavaDoc
516     {
517
518         // Send the datagram from the standard port
519

520         SendDatagram(dgramTyp, sock, fromName, NetBIOSName.FileServer, toName, NetBIOSName.FileServer, userData,
521                 userLen, 0);
522     }
523
524     /**
525      * Set the datagram id.
526      *
527      * @param id int
528      */

529     public final void setDatagramId(int id)
530     {
531         DataPacker.putIntelShort(id, m_buf, NB_DATAGRAMID);
532     }
533
534     /**
535      * Set the datagram destination name.
536      *
537      * @param name java.lang.String
538      */

539     public final void setDestinationName(String JavaDoc name)
540     {
541         setDestinationName(name, NetBIOSName.FileServer);
542     }
543
544     /**
545      * Set the datagram destination name.
546      *
547      * @param name java.lang.String
548      */

549     public final void setDestinationName(String JavaDoc name, char typ)
550     {
551
552         // Convert the name to NetBIOS RFC encoded name
553

554         NetBIOSSession.EncodeName(name, typ, m_buf, NB_TONAME);
555     }
556
557     /**
558      * Set the datagram flags value.
559      *
560      * @param flg int
561      */

562     public final void setFlags(int flg)
563     {
564         m_buf[NB_FLAGS] = (byte) (flg & 0xFF);
565     }
566
567     /**
568      * Set the datagram length.
569      *
570      * @param len int
571      */

572     public final void setLength(int len)
573     {
574         DataPacker.putShort((short) len, m_buf, NB_DATAGRAMLEN);
575     }
576
577     /**
578      * Set the NetBIOS datagram message type.
579      *
580      * @param msg int
581      */

582     public final void setMessageType(int msg)
583     {
584         m_buf[NB_MSGTYPE] = (byte) (msg & 0xFF);
585     }
586
587     /**
588      * Set the source IP address for the datagram.
589      *
590      * @param ipaddr byte[]
591      */

592     public final void setSourceIPAddress(byte[] ipaddr)
593     {
594
595         // Pack the IP address into the datagram buffer
596

597         for (int i = 0; i < 4; i++)
598             m_buf[NB_SOURCEIP + i] = ipaddr[i];
599     }
600
601     /**
602      * Set the datagram source NetBIOS name.
603      *
604      * @param name java.lang.String
605      */

606     public final void setSourceName(String JavaDoc name)
607     {
608
609         // Convert the name to NetBIOS RFC encoded name
610

611         NetBIOSSession.EncodeName(name, NetBIOSName.FileServer, m_buf, NB_FROMNAME);
612     }
613
614     /**
615      * Set the datagram source NetBIOS name.
616      *
617      * @param name java.lang.String
618      */

619     public final void setSourceName(String JavaDoc name, char typ)
620     {
621
622         // Convert the name to NetBIOS RFC encoded name
623

624         NetBIOSSession.EncodeName(name, typ, m_buf, NB_FROMNAME);
625     }
626
627     /**
628      * Set the source port/socket for the datagram.
629      *
630      * @param port int
631      */

632     public final void setSourcePort(int port)
633     {
634         DataPacker.putShort((short) port, m_buf, NB_SOURCEPORT);
635     }
636
637     /**
638      * Set the user data portion of the datagram.
639      *
640      * @param buf byte[]
641      * @param len int
642      */

643     public final void setUserData(byte[] buf, int len)
644     {
645
646         // Copy the user data
647

648         System.arraycopy(buf, 0, m_buf, NB_USERDATA, len);
649     }
650
651     /**
652      * Set the user data portion of the datagram.
653      *
654      * @param buf User data buffer
655      * @param len Length of user data
656      * @param off Offset to start of data within buffer.
657      */

658     public final void setUserData(byte[] buf, int len, int off)
659     {
660
661         // Copy the user data
662

663         System.arraycopy(buf, off, m_buf, NB_USERDATA, len);
664     }
665
666     /**
667      * Common constructor initialization code.
668      */

669     protected final void CommonInit()
670     {
671     }
672 }
Popular Tags