KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > filesys > server > auth > passthru > SMBPacket


1 /*
2  * Copyright (C) 2006 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.server.auth.passthru;
18
19 import java.io.IOException JavaDoc;
20
21 import org.alfresco.filesys.netbios.NetBIOSSession;
22 import org.alfresco.filesys.netbios.RFCNetBIOSProtocol;
23 import org.alfresco.filesys.smb.NetworkSession;
24 import org.alfresco.filesys.smb.PacketType;
25 import org.alfresco.filesys.smb.SMBException;
26 import org.alfresco.filesys.smb.SMBStatus;
27 import org.alfresco.filesys.util.DataPacker;
28
29 /**
30  * SMB packet type class
31  *
32  * @author GKSpencer
33  */

34 public class SMBPacket
35 {
36
37     // SMB packet offsets, assuming an RFC NetBIOS transport
38

39     public static final int SIGNATURE = RFCNetBIOSProtocol.HEADER_LEN;
40     public static final int COMMAND = 4 + RFCNetBIOSProtocol.HEADER_LEN;
41     public static final int ERRORCODE = 5 + RFCNetBIOSProtocol.HEADER_LEN;
42     public static final int ERRORCLASS = 5 + RFCNetBIOSProtocol.HEADER_LEN;
43     public static final int ERROR = 7 + RFCNetBIOSProtocol.HEADER_LEN;
44     public static final int FLAGS = 9 + RFCNetBIOSProtocol.HEADER_LEN;
45     public static final int FLAGS2 = 10 + RFCNetBIOSProtocol.HEADER_LEN;
46     public static final int PIDHIGH = 12 + RFCNetBIOSProtocol.HEADER_LEN;
47     public static final int SID = 18 + RFCNetBIOSProtocol.HEADER_LEN;
48     public static final int SEQNO = 20 + RFCNetBIOSProtocol.HEADER_LEN;
49     public static final int TID = 24 + RFCNetBIOSProtocol.HEADER_LEN;
50     public static final int PID = 26 + RFCNetBIOSProtocol.HEADER_LEN;
51     public static final int UID = 28 + RFCNetBIOSProtocol.HEADER_LEN;
52     public static final int MID = 30 + RFCNetBIOSProtocol.HEADER_LEN;
53     public static final int WORDCNT = 32 + RFCNetBIOSProtocol.HEADER_LEN;
54     public static final int ANDXCOMMAND = 33 + RFCNetBIOSProtocol.HEADER_LEN;
55     public static final int ANDXRESERVED = 34 + RFCNetBIOSProtocol.HEADER_LEN;
56     public static final int PARAMWORDS = 33 + RFCNetBIOSProtocol.HEADER_LEN;
57
58     // SMB packet header length for a transaction type request
59

60     public static final int TRANS_HEADERLEN = 66 + RFCNetBIOSProtocol.HEADER_LEN;
61
62     // Minimum receive length for a valid SMB packet
63

64     public static final int MIN_RXLEN = 32;
65
66     // Default buffer size to allocate for SMB packets
67

68     public static final int DEFAULT_BUFSIZE = 4096;
69
70     // Flag bits
71

72     public static final int FLG_SUBDIALECT = 0x01;
73     public static final int FLG_CASELESS = 0x08;
74     public static final int FLG_CANONICAL = 0x10;
75     public static final int FLG_OPLOCK = 0x20;
76     public static final int FLG_NOTIFY = 0x40;
77     public static final int FLG_RESPONSE = 0x80;
78
79     // Flag2 bits
80

81     public static final int FLG2_LONGFILENAMES = 0x0001;
82     public static final int FLG2_EXTENDEDATTRIB = 0x0002;
83     public static final int FLG2_EXTENDEDSECURITY = 0x0800;
84     public static final int FLG2_READIFEXE = 0x2000;
85     public static final int FLG2_LONGERRORCODE = 0x4000;
86     public static final int FLG2_UNICODE = 0x8000;
87
88     // Security mode bits
89

90     public static final int SEC_USER = 0x0001;
91     public static final int SEC_ENCRYPT = 0x0002;
92
93     // Raw mode bits
94

95     public static final int RAW_READ = 0x0001;
96     public static final int RAW_WRITE = 0x0002;
97
98     // SMB packet buffer
99

100     private byte[] m_smbbuf;
101
102     // Packet type
103

104     private int m_pkttype;
105
106     // Current byte area pack/unpack position
107

108     protected int m_pos;
109     protected int m_endpos;
110
111     // Time of last packet send
112

113     protected long m_lastTxTime;
114
115     /**
116      * Default constructor
117      */

118     public SMBPacket()
119     {
120         m_smbbuf = new byte[DEFAULT_BUFSIZE];
121         InitializeBuffer();
122     }
123
124     /**
125      * Construct an SMB packet using the specified packet buffer.
126      *
127      * @param buf SMB packet buffer.
128      */

129     public SMBPacket(byte[] buf)
130     {
131         m_smbbuf = buf;
132     }
133
134     /**
135      * Construct an SMB packet of the specified size.
136      *
137      * @param siz Size of SMB packet buffer to allocate.
138      */

139     public SMBPacket(int siz)
140     {
141         m_smbbuf = new byte[siz];
142         InitializeBuffer();
143     }
144
145     /**
146      * Check if a received SMB is valid, if not then throw an exception
147      *
148      * @exception SMBException
149      */

150     public final void checkForError() throws SMBException
151     {
152
153         // Check if a valid SMB response has been received
154

155         if (isValidResponse() == false)
156         {
157
158             // Check for NT error codes
159

160             if (isLongErrorCode())
161                 throw new SMBException(SMBStatus.NTErr, getLongErrorCode());
162             else
163                 throw new SMBException(getErrorClass(), getErrorCode());
164         }
165     }
166
167     /**
168      * Clear the data byte count
169      */

170     public final void clearBytes()
171     {
172         int offset = getByteOffset() - 2;
173         DataPacker.putIntelShort(0, m_smbbuf, offset);
174     }
175
176     /**
177      * Check if the error class/code match the specified error/class
178      *
179      * @param errClass int
180      * @param errCode int
181      * @return boolean
182      */

183     public final boolean equalsError(int errClass, int errCode)
184     {
185         if (getErrorClass() == errClass && getErrorCode() == errCode)
186             return true;
187         return false;
188     }
189
190     /**
191      * Send the SMB packet and receive the response packet
192      *
193      * @param sess Network session to send/receive the packet over.
194      * @param rxPkt SMB packet to receive the response into.
195      * @param throwerr If true then throw an I/O error if an invalid response is received.
196      * @exception java.io.IOException If a network error occurs.
197      * @exception SMBException If an SMB level error occurs
198      */

199     protected final synchronized void ExchangeLowLevelSMB(NetworkSession sess, SMBPacket rxPkt, boolean throwerr)
200             throws java.io.IOException JavaDoc, SMBException
201     {
202
203         // Set multiplex id
204

205         if (getMultiplexId() == 0)
206             setMultiplexId(1);
207
208         // Send the SMB request
209

210         sess.Send(m_smbbuf, getLength());
211
212         // Receive a response
213

214         if (sess.Receive(rxPkt.getBuffer(), 0) >= MIN_RXLEN)
215         {
216
217             // Check if the response is for the current request
218

219             if (rxPkt.getCommand() == m_pkttype)
220             {
221
222                 // Check if a valid SMB response has been received
223

224                 if (throwerr == true)
225                     checkForError();
226
227                 // Valid packet received, return to caller
228

229                 return;
230             }
231         }
232
233         // Invalid receive packet
234

235         throw new java.io.IOException JavaDoc("Invalid SMB Receive Packet");
236     }
237
238     /**
239      * Send/receive an SMB protocol packet to the remote server.
240      *
241      * @param sess SMB session to send/receive data on.
242      * @param rxPkt SMB packet to receive the response into.
243      * @exception java.io.IOException If an I/O error occurs.
244      * @exception SMBException If an SMB level error occurs.
245      */

246     public synchronized final void ExchangeSMB(AuthenticateSession sess, SMBPacket rxPkt) throws SMBException,
247             IOException JavaDoc
248     {
249
250         // Call the main SMB exhchange method
251

252         ExchangeSMB(sess, rxPkt, false);
253     }
254
255     /**
256      * Send the SMB packet and receive the response packet
257      *
258      * @param sess SMB session to send/receive the packet over.
259      * @param rxPkt SMB packet to receive the response into.
260      * @param throwerr If true then throw an I/O error if an invalid response is received.
261      * @exception java.io.IOException If an I/O error occurs.
262      * @exception SMBException If an SMB level error occurs.
263      */

264     public synchronized final void ExchangeSMB(AuthenticateSession sess, SMBPacket rxPkt, boolean throwerr)
265             throws SMBException, IOException JavaDoc
266     {
267
268         // Set the process id, user id and multiplex id
269

270         setProcessId(sess.getProcessId());
271         setUserId(sess.getUserId());
272
273         if (getMultiplexId() == 0)
274             setMultiplexId(1);
275
276         // Get the network session
277

278         NetworkSession netSess = sess.getSession();
279
280         // Send the SMB request
281

282         netSess.Send(m_smbbuf, getLength());
283
284         // Receive the response, other asynchronous responses may be received before the response
285
// for this request
286

287         boolean rxValid = false;
288
289         while (rxValid == false)
290         {
291
292             // Receive a response
293

294             if (netSess.Receive(rxPkt.getBuffer(), RFCNetBIOSProtocol.TMO) >= MIN_RXLEN)
295             {
296
297                 // Check if the response is for the current request
298

299                 if (rxPkt.getCommand() == m_pkttype)
300                 {
301
302                     // Check if a valid SMB response has been received
303

304                     if (throwerr == true)
305                         checkForError();
306
307                     // Valid packet received, return to caller
308

309                     return;
310                 }
311             }
312         }
313
314         // Invalid receive packet
315

316         throw new java.io.IOException JavaDoc("Invalid SMB Receive Packet");
317     }
318
319     /**
320      * Get the secondary command code
321      *
322      * @return Secondary command code
323      */

324     public final int getAndXCommand()
325     {
326         return (int) (m_smbbuf[ANDXCOMMAND] & 0xFF);
327     }
328
329     /**
330      * Return the byte array used for the SMB packet
331      *
332      * @return Byte array used for the SMB packet.
333      */

334     public final byte[] getBuffer()
335     {
336         return m_smbbuf;
337     }
338
339     /**
340      * Return the total buffer size available to the SMB request
341      *
342      * @return Total SMB buffer length available.
343      */

344     public final int getBufferLength()
345     {
346         return m_smbbuf.length - RFCNetBIOSProtocol.HEADER_LEN;
347     }
348
349     /**
350      * Return the available buffer space for data bytes
351      *
352      * @return int
353      */

354     public final int getAvailableLength()
355     {
356         return m_smbbuf.length - DataPacker.longwordAlign(getByteOffset());
357     }
358
359     /**
360      * Get the data byte count for the SMB packet
361      *
362      * @return Data byte count
363      */

364     public final int getByteCount()
365     {
366
367         // Calculate the offset of the byte count
368

369         int pos = PARAMWORDS + (2 * getParameterCount());
370         return (int) DataPacker.getIntelShort(m_smbbuf, pos);
371     }
372
373     /**
374      * Get the data byte area offset within the SMB packet
375      *
376      * @return Data byte offset within the SMB packet.
377      */

378     public final int getByteOffset()
379     {
380
381         // Calculate the offset of the byte buffer
382

383         int pCnt = getParameterCount();
384         int pos = WORDCNT + (2 * pCnt) + 3;
385         return pos;
386     }
387
388     /**
389      * Get the SMB command
390      *
391      * @return SMB command code.
392      */

393     public final int getCommand()
394     {
395         return (int) (m_smbbuf[COMMAND] & 0xFF);
396     }
397
398     /**
399      * Determine if normal or long error codes have been returned
400      *
401      * @return boolean
402      */

403     public final boolean hasLongErrorCode()
404     {
405         if ((getFlags2() & FLG2_LONGERRORCODE) == 0)
406             return false;
407         return true;
408     }
409
410     /**
411      * Return the saved packet type
412      *
413      * @return int
414      */

415     public final int isType()
416     {
417         return m_pkttype;
418     }
419
420     /**
421      * Check if the packet contains ASCII or Unicode strings
422      *
423      * @return boolean
424      */

425     public final boolean isUnicode()
426     {
427         return (getFlags2() & FLG2_UNICODE) != 0 ? true : false;
428     }
429
430     /**
431      * Check if the packet is using caseless filenames
432      *
433      * @return boolean
434      */

435     public final boolean isCaseless()
436     {
437         return (getFlags() & FLG_CASELESS) != 0 ? true : false;
438     }
439
440     /**
441      * Check if long file names are being used
442      *
443      * @return boolean
444      */

445     public final boolean isLongFileNames()
446     {
447         return (getFlags2() & FLG2_LONGFILENAMES) != 0 ? true : false;
448     }
449
450     /**
451      * Check if long error codes are being used
452      *
453      * @return boolean
454      */

455     public final boolean isLongErrorCode()
456     {
457         return (getFlags2() & FLG2_LONGERRORCODE) != 0 ? true : false;
458     }
459
460     /**
461      * Get the SMB error class
462      *
463      * @return SMB error class.
464      */

465     public final int getErrorClass()
466     {
467         return (int) m_smbbuf[ERRORCLASS] & 0xFF;
468     }
469
470     /**
471      * Get the SMB error code
472      *
473      * @return SMB error code.
474      */

475     public final int getErrorCode()
476     {
477         return (int) m_smbbuf[ERROR] & 0xFF;
478     }
479
480     /**
481      * Get the SMB flags value.
482      *
483      * @return SMB flags value.
484      */

485     public final int getFlags()
486     {
487         return (int) m_smbbuf[FLAGS] & 0xFF;
488     }
489
490     /**
491      * Get the SMB flags2 value.
492      *
493      * @return SMB flags2 value.
494      */

495     public final int getFlags2()
496     {
497         return (int) DataPacker.getIntelShort(m_smbbuf, FLAGS2);
498     }
499
500     /**
501      * Calculate the total used packet length.
502      *
503      * @return Total used packet length.
504      */

505     public final int getLength()
506     {
507         return (getByteOffset() + getByteCount()) - SIGNATURE;
508     }
509
510     /**
511      * Get the long SMB error code
512      *
513      * @return Long SMB error code.
514      */

515     public final int getLongErrorCode()
516     {
517         return DataPacker.getIntelInt(m_smbbuf, ERRORCODE);
518     }
519
520     /**
521      * Get the multiplex identifier.
522      *
523      * @return Multiplex identifier.
524      */

525     public final int getMultiplexId()
526     {
527         return DataPacker.getIntelShort(m_smbbuf, MID);
528     }
529
530     /**
531      * Get a parameter word from the SMB packet.
532      *
533      * @param idx Parameter index (zero based).
534      * @return Parameter word value.
535      * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range.
536      */

537     public final int getParameter(int idx) throws java.lang.IndexOutOfBoundsException JavaDoc
538     {
539
540         // Range check the parameter index
541

542         if (idx > getParameterCount())
543             throw new java.lang.IndexOutOfBoundsException JavaDoc();
544
545         // Calculate the parameter word offset
546

547         int pos = WORDCNT + (2 * idx) + 1;
548         return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF);
549     }
550
551     /**
552      * Get the specified parameter words, as an int value.
553      *
554      * @param idx Parameter index (zero based).
555      * @param val Parameter value.
556      */

557     public final int getParameterLong(int idx)
558     {
559         int pos = WORDCNT + (2 * idx) + 1;
560         return DataPacker.getIntelInt(m_smbbuf, pos);
561     }
562
563     /**
564      * Get the parameter count
565      *
566      * @return Parameter word count.
567      */

568     public final int getParameterCount()
569     {
570         return (int) m_smbbuf[WORDCNT];
571     }
572
573     /**
574      * Get the process indentifier (PID)
575      *
576      * @return Process identifier value.
577      */

578     public final int getProcessId()
579     {
580         return DataPacker.getIntelShort(m_smbbuf, PID);
581     }
582
583     /**
584      * Get the tree identifier (TID)
585      *
586      * @return Tree identifier (TID)
587      */

588     public final int getTreeId()
589     {
590         return DataPacker.getIntelShort(m_smbbuf, TID);
591     }
592
593     /**
594      * Get the user identifier (UID)
595      *
596      * @return User identifier (UID)
597      */

598     public final int getUserId()
599     {
600         return DataPacker.getIntelShort(m_smbbuf, UID);
601     }
602
603     /**
604      * Return the last sent packet time
605      *
606      * @return long
607      */

608     public final long getLastPacketSendTime()
609     {
610         return m_lastTxTime;
611     }
612
613     /**
614      * Initialize the SMB packet buffer.
615      */

616     private final void InitializeBuffer()
617     {
618
619         // Set the packet signature
620

621         m_smbbuf[SIGNATURE] = (byte) 0xFF;
622         m_smbbuf[SIGNATURE + 1] = (byte) 'S';
623         m_smbbuf[SIGNATURE + 2] = (byte) 'M';
624         m_smbbuf[SIGNATURE + 3] = (byte) 'B';
625     }
626
627     /**
628      * Determine if this packet is an SMB response, or command packet
629      *
630      * @return true if this SMB packet is a response, else false
631      */

632     public final boolean isResponse()
633     {
634         int resp = getFlags();
635         if ((resp & FLG_RESPONSE) != 0)
636             return true;
637         return false;
638     }
639
640     /**
641      * Check if the response packet is valid, ie. type and flags
642      *
643      * @return true if the SMB packet is a response packet and the response is valid, else false.
644      */

645     public final boolean isValidResponse()
646     {
647
648         // Check if this is a response packet, and the correct type of packet
649

650         if (isResponse() && getCommand() == m_pkttype)
651         {
652
653             // Check if standard error codes or NT 32-bit error codes are being used
654

655             if ((getFlags2() & FLG2_LONGERRORCODE) == 0)
656             {
657                 if (getErrorCode() == SMBStatus.Success)
658                     return true;
659             }
660             else if (getLongErrorCode() == SMBStatus.NTSuccess)
661                 return true;
662         }
663         return false;
664     }
665
666     /**
667      * Pack a byte (8 bit) value into the byte area
668      *
669      * @param val byte
670      */

671     public final void packByte(byte val)
672     {
673         m_smbbuf[m_pos++] = val;
674     }
675
676     /**
677      * Pack a byte (8 bit) value into the byte area
678      *
679      * @param val int
680      */

681     public final void packByte(int val)
682     {
683         m_smbbuf[m_pos++] = (byte) val;
684     }
685
686     /**
687      * Pack the specified bytes into the byte area
688      *
689      * @param byts byte[]
690      * @param len int
691      */

692     public final void packBytes(byte[] byts, int len)
693     {
694         System.arraycopy(byts, 0, m_smbbuf, m_pos, len);
695         m_pos += len;
696     }
697
698     /**
699      * Pack a string using either ASCII or Unicode into the byte area
700      *
701      * @param str String
702      * @param uni boolean
703      */

704     public final void packString(String JavaDoc str, boolean uni)
705     {
706
707         // Check for Unicode or ASCII
708

709         if (uni)
710         {
711
712             // Word align the buffer position, pack the Unicode string
713

714             m_pos = DataPacker.wordAlign(m_pos);
715             DataPacker.putUnicodeString(str, m_smbbuf, m_pos, true);
716             m_pos += (str.length() * 2) + 2;
717         }
718         else
719         {
720
721             // Pack the ASCII string
722

723             DataPacker.putString(str, m_smbbuf, m_pos, true);
724             m_pos += str.length() + 1;
725         }
726     }
727
728     /**
729      * Pack a word (16 bit) value into the byte area
730      *
731      * @param val int
732      */

733     public final void packWord(int val)
734     {
735         DataPacker.putIntelShort(val, m_smbbuf, m_pos);
736         m_pos += 2;
737     }
738
739     /**
740      * Pack a 32 bit integer value into the byte area
741      *
742      * @param val int
743      */

744     public final void packInt(int val)
745     {
746         DataPacker.putIntelInt(val, m_smbbuf, m_pos);
747         m_pos += 4;
748     }
749
750     /**
751      * Pack a long integer (64 bit) value into the byte area
752      *
753      * @param val long
754      */

755     public final void packLong(long val)
756     {
757         DataPacker.putIntelLong(val, m_smbbuf, m_pos);
758         m_pos += 8;
759     }
760
761     /**
762      * Return the current byte area buffer position
763      *
764      * @return int
765      */

766     public final int getPosition()
767     {
768         return m_pos;
769     }
770
771     /**
772      * Set the byte area buffer position
773      *
774      * @param pos int
775      */

776     public final void setPosition(int pos)
777     {
778         m_pos = pos;
779     }
780
781     /**
782      * Unpack a byte value from the byte area
783      *
784      * @return int
785      */

786     public final int unpackByte()
787     {
788         return (int) m_smbbuf[m_pos++];
789     }
790
791     /**
792      * Unpack a block of bytes from the byte area
793      *
794      * @param len int
795      * @return byte[]
796      */

797     public final byte[] unpackBytes(int len)
798     {
799         if (len <= 0)
800             return null;
801
802         byte[] buf = new byte[len];
803         System.arraycopy(m_smbbuf, m_pos, buf, 0, len);
804         m_pos += len;
805         return buf;
806     }
807
808     /**
809      * Unpack a word (16 bit) value from the byte area
810      *
811      * @return int
812      */

813     public final int unpackWord()
814     {
815         int val = DataPacker.getIntelShort(m_smbbuf, m_pos);
816         m_pos += 2;
817         return val;
818     }
819
820     /**
821      * Unpack an integer (32 bit) value from the byte/parameter area
822      *
823      * @return int
824      */

825     public final int unpackInt()
826     {
827         int val = DataPacker.getIntelInt(m_smbbuf, m_pos);
828         m_pos += 4;
829         return val;
830     }
831
832     /**
833      * Unpack a long integer (64 bit) value from the byte area
834      *
835      * @return long
836      */

837     public final long unpackLong()
838     {
839         long val = DataPacker.getIntelLong(m_smbbuf, m_pos);
840         m_pos += 8;
841         return val;
842     }
843
844     /**
845      * Unpack a string from the byte area
846      *
847      * @param uni boolean
848      * @return String
849      */

850     public final String JavaDoc unpackString(boolean uni)
851     {
852
853         // Check for Unicode or ASCII
854

855         String JavaDoc ret = null;
856
857         if (uni)
858         {
859
860             // Word align the current buffer position
861

862             m_pos = DataPacker.wordAlign(m_pos);
863             ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, 255);
864             if (ret != null)
865                 m_pos += (ret.length() * 2) + 2;
866         }
867         else
868         {
869
870             // Unpack the ASCII string
871

872             ret = DataPacker.getString(m_smbbuf, m_pos, 255);
873             if (ret != null)
874                 m_pos += ret.length() + 1;
875         }
876
877         // Return the string
878

879         return ret;
880     }
881
882     /**
883      * Unpack a string from the byte area
884      *
885      * @param len int
886      * @param uni boolean
887      * @return String
888      */

889     public final String JavaDoc unpackString(int len, boolean uni)
890     {
891
892         // Check for Unicode or ASCII
893

894         String JavaDoc ret = null;
895
896         if (uni)
897         {
898
899             // Word align the current buffer position
900

901             m_pos = DataPacker.wordAlign(m_pos);
902             ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, len);
903             if (ret != null)
904                 m_pos += (ret.length() * 2);
905         }
906         else
907         {
908
909             // Unpack the ASCII string
910

911             ret = DataPacker.getString(m_smbbuf, m_pos, len);
912             if (ret != null)
913                 m_pos += ret.length();
914         }
915
916         // Return the string
917

918         return ret;
919     }
920
921     /**
922      * Check if there is more data in the byte area
923      *
924      * @return boolean
925      */

926     public final boolean hasMoreData()
927     {
928         if (m_pos < m_endpos)
929             return true;
930         return false;
931     }
932
933     /**
934      * Receive an SMB response packet.
935      *
936      * @param sess NetBIOS session to receive the SMB packet on.
937      * @exception java.io.IOException If an I/O error occurs.
938      */

939     private final void ReceiveSMB(NetBIOSSession sess) throws java.io.IOException JavaDoc
940     {
941
942         if (sess.Receive(m_smbbuf, RFCNetBIOSProtocol.TMO) >= MIN_RXLEN)
943             return;
944
945         // Not enough data received for an SMB header
946

947         throw new java.io.IOException JavaDoc("Short NetBIOS receive");
948     }
949
950     /**
951      * Receive an SMB packet on the spceified SMB session.
952      *
953      * @param sess SMB session to receive the packet on.
954      * @exception java.io.IOException If a network error occurs
955      * @exception SMBException If an SMB level error occurs
956      */

957     protected final void ReceiveSMB(AuthenticateSession sess) throws java.io.IOException JavaDoc, SMBException
958     {
959
960         // Call the main receive method
961

962         ReceiveSMB(sess, true);
963     }
964
965     /**
966      * Receive an SMB packet on the spceified SMB session.
967      *
968      * @param sess SMB session to receive the packet on.
969      * @param throwErr Flag to indicate if an error is thrown if an error response is received
970      * @exception java.io.IOException If a network error occurs
971      * @exception SMBException If an SMB level error occurs
972      */

973     protected final void ReceiveSMB(AuthenticateSession sess, boolean throwErr) throws java.io.IOException JavaDoc,
974             SMBException
975     {
976
977         // Get the network session
978

979         NetworkSession netSess = sess.getSession();
980
981         // Receive the response, other asynchronous responses may be received before the response
982
// for this request
983

984         boolean rxValid = false;
985
986         while (rxValid == false)
987         {
988
989             // Receive a response
990

991             if (netSess.Receive(getBuffer(), RFCNetBIOSProtocol.TMO) >= MIN_RXLEN)
992             {
993
994                 // Check if the response is for the current request
995

996                 if (getCommand() == m_pkttype)
997                 {
998
999                     // Check if a valid SMB response has been received
1000

1001                    if (throwErr == true)
1002                        checkForError();
1003
1004                    // Valid packet received, return to caller
1005

1006                    return;
1007                }
1008            }
1009            else
1010            {
1011
1012                // Not enough data received for an SMB header
1013

1014                throw new java.io.IOException JavaDoc("Short NetBIOS receive");
1015            }
1016        }
1017    }
1018
1019    /**
1020     * Send the SMB packet on the specified SMB session.
1021     *
1022     * @param sess SMB session to send this packet over.
1023     * @exception java.io.IOException If an I/O error occurs.
1024     */

1025    protected final void SendSMB(AuthenticateSession sess) throws java.io.IOException JavaDoc
1026    {
1027
1028        // Update the last send time
1029

1030        m_lastTxTime = System.currentTimeMillis();
1031
1032        // Send the SMB request
1033

1034        sess.getSession().Send(m_smbbuf, getLength());
1035    }
1036
1037    /**
1038     * Set the secondary SMB command
1039     *
1040     * @param cmd Secondary SMB command code.
1041     */

1042    public final void setAndXCommand(int cmd)
1043    {
1044
1045        // Set the chained command packet type
1046

1047        m_smbbuf[ANDXCOMMAND] = (byte) cmd;
1048        m_smbbuf[ANDXRESERVED] = (byte) 0;
1049
1050        // If the AndX command is disabled clear the offset to the chained packet
1051

1052        if (cmd == PacketType.NoChainedCommand)
1053            setParameter(1, 0);
1054    }
1055
1056    /**
1057     * Set the data byte count for this SMB packet
1058     *
1059     * @param cnt Data byte count.
1060     */

1061    public final void setByteCount(int cnt)
1062    {
1063        int offset = getByteOffset() - 2;
1064        DataPacker.putIntelShort(cnt, m_smbbuf, offset);
1065    }
1066
1067    /**
1068     * Set the data byte count for this SMB packet
1069     */

1070
1071    public final void setByteCount()
1072    {
1073        int offset = getByteOffset() - 2;
1074        int len = m_pos - getByteOffset();
1075        DataPacker.putIntelShort(len, m_smbbuf, offset);
1076    }
1077
1078    /**
1079     * Set the data byte area in the SMB packet
1080     *
1081     * @param byts Byte array containing the data to be copied to the SMB packet.
1082     */

1083    public final void setBytes(byte[] byts)
1084    {
1085        int offset = getByteOffset() - 2;
1086        DataPacker.putIntelShort(byts.length, m_smbbuf, offset);
1087
1088        offset += 2;
1089
1090        for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++])
1091            ;
1092    }
1093
1094    /**
1095     * Set the SMB command
1096     *
1097     * @param cmd SMB command code
1098     */

1099    public final void setCommand(int cmd)
1100    {
1101        m_pkttype = cmd;
1102        m_smbbuf[COMMAND] = (byte) cmd;
1103    }
1104
1105    /**
1106     * Set the SMB error class.
1107     *
1108     * @param cl SMB error class.
1109     */

1110    public final void setErrorClass(int cl)
1111    {
1112        m_smbbuf[ERRORCLASS] = (byte) (cl & 0xFF);
1113    }
1114
1115    /**
1116     * Set the SMB error code
1117     *
1118     * @param sts SMB error code.
1119     */

1120    public final void setErrorCode(int sts)
1121    {
1122        m_smbbuf[ERROR] = (byte) (sts & 0xFF);
1123    }
1124
1125    /**
1126     * Set the SMB flags value.
1127     *
1128     * @param flg SMB flags value.
1129     */

1130    public final void setFlags(int flg)
1131    {
1132        m_smbbuf[FLAGS] = (byte) flg;
1133    }
1134
1135    /**
1136     * Set the SMB flags2 value.
1137     *
1138     * @param flg SMB flags2 value.
1139     */

1140    public final void setFlags2(int flg)
1141    {
1142        DataPacker.putIntelShort(flg, m_smbbuf, FLAGS2);
1143    }
1144
1145    /**
1146     * Set the multiplex identifier.
1147     *
1148     * @param mid Multiplex identifier
1149     */

1150    public final void setMultiplexId(int mid)
1151    {
1152        DataPacker.putIntelShort(mid, m_smbbuf, MID);
1153    }
1154
1155    /**
1156     * Set the specified parameter word.
1157     *
1158     * @param idx Parameter index (zero based).
1159     * @param val Parameter value.
1160     */

1161    public final void setParameter(int idx, int val)
1162    {
1163        int pos = WORDCNT + (2 * idx) + 1;
1164        DataPacker.putIntelShort(val, m_smbbuf, pos);
1165    }
1166
1167    /**
1168     * Set the specified parameter words.
1169     *
1170     * @param idx Parameter index (zero based).
1171     * @param val Parameter value.
1172     */

1173
1174    public final void setParameterLong(int idx, int val)
1175    {
1176        int pos = WORDCNT + (2 * idx) + 1;
1177        DataPacker.putIntelInt(val, m_smbbuf, pos);
1178    }
1179
1180    /**
1181     * Set the parameter count
1182     *
1183     * @param cnt Parameter word count.
1184     */

1185    public final void setParameterCount(int cnt)
1186    {
1187        m_smbbuf[WORDCNT] = (byte) cnt;
1188    }
1189
1190    /**
1191     * Set the process identifier value (PID).
1192     *
1193     * @param pid Process identifier value.
1194     */

1195    public final void setProcessId(int pid)
1196    {
1197        DataPacker.putIntelShort(pid, m_smbbuf, PID);
1198    }
1199
1200    /**
1201     * Set the packet sequence number, for connectionless commands.
1202     *
1203     * @param seq Sequence number.
1204     */

1205    public final void setSeqNo(int seq)
1206    {
1207        DataPacker.putIntelShort(seq, m_smbbuf, SEQNO);
1208    }
1209
1210    /**
1211     * Set the session id.
1212     *
1213     * @param sid Session id.
1214     */

1215    public final void setSID(int sid)
1216    {
1217        DataPacker.putIntelShort(sid, m_smbbuf, SID);
1218    }
1219
1220    /**
1221     * Set the tree identifier (TID)
1222     *
1223     * @param tid Tree identifier value.
1224     */

1225    public final void setTreeId(int tid)
1226    {
1227        DataPacker.putIntelShort(tid, m_smbbuf, TID);
1228    }
1229
1230    /**
1231     * Set the user identifier (UID)
1232     *
1233     * @param uid User identifier value.
1234     */

1235    public final void setUserId(int uid)
1236    {
1237        DataPacker.putIntelShort(uid, m_smbbuf, UID);
1238    }
1239
1240    /**
1241     * Align the byte area pointer on an int (32bit) boundary
1242     */

1243    public final void alignBytePointer()
1244    {
1245        m_pos = DataPacker.longwordAlign(m_pos);
1246    }
1247
1248    /**
1249     * Reset the byte/parameter pointer area for packing/unpacking data items from the packet
1250     */

1251    public final void resetBytePointer()
1252    {
1253        m_pos = getByteOffset();
1254        m_endpos = m_pos + getByteCount();
1255    }
1256
1257    /**
1258     * Reset the byte/parameter pointer area for packing/unpacking data items from the packet, and
1259     * align the buffer on an int (32bit) boundary
1260     */

1261    public final void resetBytePointerAlign()
1262    {
1263        m_pos = DataPacker.longwordAlign(getByteOffset());
1264        m_endpos = m_pos + getByteCount();
1265    }
1266
1267    /**
1268     * Reset the byte/parameter pointer area for packing/unpacking paramaters from the packet
1269     */

1270    public final void resetParameterPointer()
1271    {
1272        m_pos = PARAMWORDS;
1273    }
1274
1275    /**
1276     * Set the unpack pointer to the specified offset, for AndX processing
1277     *
1278     * @param off int
1279     * @param len int
1280     */

1281    public final void setBytePointer(int off, int len)
1282    {
1283        m_pos = off;
1284        m_endpos = m_pos + len;
1285    }
1286
1287    /**
1288     * Skip a number of bytes in the parameter/byte area
1289     *
1290     * @param cnt int
1291     */

1292    public final void skipBytes(int cnt)
1293    {
1294        m_pos += cnt;
1295    }
1296
1297    /**
1298     * Return the flags value as a string
1299     *
1300     * @return String
1301     */

1302    protected final String JavaDoc getFlagsAsString()
1303    {
1304
1305        // Get the flags value
1306

1307        int flags = getFlags();
1308        if (flags == 0)
1309            return "<None>";
1310
1311        StringBuffer JavaDoc str = new StringBuffer JavaDoc();
1312        if ((flags & FLG_SUBDIALECT) != 0)
1313            str.append("SubDialect,");
1314
1315        if ((flags & FLG_CASELESS) != 0)
1316            str.append("Caseless,");
1317
1318        if ((flags & FLG_CANONICAL) != 0)
1319            str.append("Canonical,");
1320
1321        if ((flags & FLG_OPLOCK) != 0)
1322            str.append("Oplock,");
1323
1324        if ((flags & FLG_NOTIFY) != 0)
1325            str.append("Notify,");
1326
1327        if ((flags & FLG_RESPONSE) != 0)
1328            str.append("Response,");
1329
1330        str.setLength(str.length() - 1);
1331
1332        return str.toString();
1333    }
1334
1335    /**
1336     * Return the flags2 value as a string
1337     *
1338     * @return String
1339     */

1340    protected final String JavaDoc getFlags2AsString()
1341    {
1342
1343        // Get the flags2 value
1344

1345        int flags2 = getFlags2();
1346
1347        if (flags2 == 0)
1348            return "<None>";
1349
1350        StringBuffer JavaDoc str = new StringBuffer JavaDoc();
1351
1352        if ((flags2 & FLG2_LONGFILENAMES) != 0)
1353            str.append("LongFilenames,");
1354
1355        if ((flags2 & FLG2_EXTENDEDATTRIB) != 0)
1356            str.append("ExtAttributes,");
1357
1358        if ((flags2 & FLG2_READIFEXE) != 0)
1359            str.append("ReadIfEXE,");
1360
1361        if ((flags2 & FLG2_LONGERRORCODE) != 0)
1362            str.append("LongErrorCode,");
1363
1364        if ((flags2 & FLG2_UNICODE) != 0)
1365            str.append("Unicode,");
1366
1367        str.setLength(str.length() - 1);
1368
1369        return str.toString();
1370    }
1371}
Popular Tags