KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > filesys > smb > server > SMBSrvPacket


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.smb.server;
18
19 import java.io.DataOutputStream JavaDoc;
20
21 import org.alfresco.filesys.netbios.RFCNetBIOSProtocol;
22 import org.alfresco.filesys.smb.PacketType;
23 import org.alfresco.filesys.smb.SMBErrorText;
24 import org.alfresco.filesys.smb.SMBStatus;
25 import org.alfresco.filesys.util.DataPacker;
26 import org.alfresco.filesys.util.HexDump;
27
28 /**
29  * SMB packet type class
30  */

31 public class SMBSrvPacket
32 {
33
34     // Protocol type, either NetBIOS or TCP/IP native SMB
35
//
36
// All protocols reserve a 4 byte header, header is not used by Win32 NetBIOS
37

38     public static final int PROTOCOL_NETBIOS = 0;
39     public static final int PROTOCOL_TCPIP = 1;
40     public static final int PROTOCOL_WIN32NETBIOS = 2;
41
42     // SMB packet offsets, assuming an RFC NetBIOS transport
43

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

65     public static final int TRANS_HEADERLEN = 66 + RFCNetBIOSProtocol.HEADER_LEN;
66
67     // Minimum receive length for a valid SMB packet
68

69     public static final int MIN_RXLEN = 32;
70
71     // Default buffer size to allocate for SMB packets
72

73     public static final int DEFAULT_BUFSIZE = 4096;
74
75     // Flag bits
76

77     public static final int FLG_SUBDIALECT = 0x01;
78     public static final int FLG_CASELESS = 0x08;
79     public static final int FLG_CANONICAL = 0x10;
80     public static final int FLG_OPLOCK = 0x20;
81     public static final int FLG_NOTIFY = 0x40;
82     public static final int FLG_RESPONSE = 0x80;
83
84     // Flag2 bits
85

86     public static final int FLG2_LONGFILENAMES = 0x0001;
87     public static final int FLG2_EXTENDEDATTRIB = 0x0002;
88     public static final int FLG2_READIFEXE = 0x2000;
89     public static final int FLG2_LONGERRORCODE = 0x4000;
90     public static final int FLG2_UNICODE = 0x8000;
91
92     // Security mode bits
93

94     public static final int SEC_USER = 0x0001;
95     public static final int SEC_ENCRYPT = 0x0002;
96
97     // Raw mode bits
98

99     public static final int RAW_READ = 0x0001;
100     public static final int RAW_WRITE = 0x0002;
101
102     // No chained AndX command indicator
103

104     public static final int NO_ANDX_CMD = 0x00FF;
105
106     // SMB packet buffer
107

108     private byte[] m_smbbuf;
109
110     // Received data length (actual buffer used)
111

112     private int m_rxLen;
113
114     // Packet type
115

116     private int m_pkttype;
117
118     // Current byte area pack/unpack position
119

120     protected int m_pos;
121     protected int m_endpos;
122
123     /**
124      * Default constructor
125      */

126
127     public SMBSrvPacket()
128     {
129         m_smbbuf = new byte[DEFAULT_BUFSIZE];
130         InitializeBuffer();
131     }
132
133     /**
134      * Construct an SMB packet using the specified packet buffer.
135      *
136      * @param buf SMB packet buffer.
137      */

138
139     public SMBSrvPacket(byte[] buf)
140     {
141         m_smbbuf = buf;
142     }
143
144     /**
145      * Construct an SMB packet of the specified size.
146      *
147      * @param siz Size of SMB packet buffer to allocate.
148      */

149
150     public SMBSrvPacket(int siz)
151     {
152         m_smbbuf = new byte[siz];
153         InitializeBuffer();
154     }
155
156     /**
157      * Copy constructor.
158      *
159      * @param buf SMB packet buffer.
160      */

161
162     public SMBSrvPacket(SMBSrvPacket pkt)
163     {
164
165         // Create a packet buffer of the same size
166

167         m_smbbuf = new byte[pkt.getBuffer().length];
168
169         // Copy the data from the specified packet
170

171         System.arraycopy(pkt.getBuffer(), 0, m_smbbuf, 0, m_smbbuf.length);
172     }
173
174     /**
175      * Copy constructor.
176      *
177      * @param buf SMB packet buffer.
178      * @param len Length of packet to be copied
179      */

180
181     public SMBSrvPacket(SMBSrvPacket pkt, int len)
182     {
183
184         // Create a packet buffer of the same size
185

186         m_smbbuf = new byte[pkt.getBuffer().length];
187
188         // Copy the data from the specified packet
189

190         System.arraycopy(pkt.getBuffer(), 0, m_smbbuf, 0, len);
191     }
192
193     /**
194      * Check the SMB AndX command for the required minimum parameter count and byte count.
195      *
196      * @param off Offset to the AndX command within the SMB packet.
197      * @param reqWords Minimum number of parameter words expected.
198      * @param reqBytes Minimum number of bytes expected.
199      * @return boolean True if the packet passes the checks, else false.
200      */

201     public final boolean checkAndXPacketIsValid(int off, int reqWords, int reqBytes)
202     {
203
204         // Check the received parameter word count
205

206         if (getAndXParameterCount(off) < reqWords || getAndXByteCount(off) < reqBytes)
207             return false;
208
209         // Initial SMB packet checks passed
210

211         return true;
212     }
213
214     /**
215      * Check the SMB packet for a valid SMB signature, and the required minimum parameter count and
216      * byte count.
217      *
218      * @param reqWords Minimum number of parameter words expected.
219      * @param reqBytes Minimum number of bytes expected.
220      * @return boolean True if the packet passes the checks, else false.
221      */

222     public final boolean checkPacketIsValid(int reqWords, int reqBytes)
223     {
224
225         // Check for the SMB signature block
226

227         if (m_smbbuf[SIGNATURE] != (byte) 0xFF || m_smbbuf[SIGNATURE + 1] != 'S' || m_smbbuf[SIGNATURE + 2] != 'M'
228                 || m_smbbuf[SIGNATURE + 3] != 'B')
229             return false;
230
231         // Check the received parameter word count
232

233         if (getParameterCount() < reqWords || getByteCount() < reqBytes)
234             return false;
235
236         // Initial SMB packet checks passed
237

238         return true;
239     }
240
241     /**
242      * Check the SMB packet has a valid SMB signature.
243      *
244      * @return boolean True if the SMB signature is valid, else false.
245      */

246     public final boolean checkPacketSignature()
247     {
248
249         // Check for the SMB signature block
250

251         if (m_smbbuf[SIGNATURE] == (byte) 0xFF && m_smbbuf[SIGNATURE + 1] == 'S' && m_smbbuf[SIGNATURE + 2] == 'M'
252                 && m_smbbuf[SIGNATURE + 3] == 'B')
253             return true;
254
255         // Invalid SMB packet format
256

257         return false;
258     }
259
260     /**
261      * Clear the data byte count
262      */

263
264     public final void clearBytes()
265     {
266         int offset = getByteOffset() - 2;
267         DataPacker.putIntelShort((short) 0, m_smbbuf, offset);
268     }
269
270     /**
271      * Dump the SMB packet to the debug stream
272      */

273
274     public final void DumpPacket()
275     {
276         DumpPacket(false);
277     }
278
279     /**
280      * Dump the SMB packet to the debug stream
281      *
282      * @param dumpAll boolean
283      */

284
285     public final void DumpPacket(boolean dumpAll)
286     {
287
288         // Dump the command type
289

290         int pCount = getParameterCount();
291         System.out.print("** SMB Packet Type: " + getPacketTypeString());
292
293         // Check if this is a response packet
294

295         if (isResponse())
296             System.out.println(" [Response]");
297         else
298             System.out.println();
299
300         // Dump flags/secondary flags
301

302         if (true)
303         {
304
305             // Dump the packet length
306

307             System.out.println("** SMB Packet Dump");
308             System.out.println("Packet Length : " + getLength());
309             System.out.println("Byte Offset: " + getByteOffset() + ", Byte Count: " + getByteCount());
310
311             // Dump the flags
312

313             System.out.println("Flags: " + Integer.toBinaryString(getFlags()));
314             System.out.println("Flags2: " + Integer.toBinaryString(getFlags2()));
315
316             // Dump various ids
317

318             System.out.println("TID: " + getTreeId());
319             System.out.println("PID: " + getProcessId());
320             System.out.println("UID: " + getUserId());
321             System.out.println("MID: " + getMultiplexId());
322
323             // Dump parameter words/count
324

325             System.out.println("Parameter Words: " + pCount);
326             StringBuffer JavaDoc str = new StringBuffer JavaDoc();
327
328             for (int i = 0; i < pCount; i++)
329             {
330                 str.setLength(0);
331                 str.append(" P");
332                 str.append(Integer.toString(i + 1));
333                 str.append(" = ");
334                 str.append(Integer.toString(getParameter(i)));
335                 while (str.length() < 16)
336                     str.append(" ");
337                 str.append("0x");
338                 str.append(Integer.toHexString(getParameter(i)));
339                 System.out.println(str.toString());
340             }
341
342             // Response packet fields
343

344             if (isResponse())
345             {
346
347                 // Dump the error code
348

349                 System.out.println("Error: 0x" + Integer.toHexString(getErrorCode()));
350                 System.out.print("Error Class: ");
351
352                 switch (getErrorClass())
353                 {
354                 case SMBStatus.Success:
355                     System.out.println("SUCCESS");
356                     break;
357                 case SMBStatus.ErrDos:
358                     System.out.println("ERRDOS");
359                     break;
360                 case SMBStatus.ErrSrv:
361                     System.out.println("ERRSRV");
362                     break;
363                 case SMBStatus.ErrHrd:
364                     System.out.println("ERRHRD");
365                     break;
366                 case SMBStatus.ErrCmd:
367                     System.out.println("ERRCMD");
368                     break;
369                 default:
370                     System.out.println("0x" + Integer.toHexString(getErrorClass()));
371                     break;
372                 }
373
374                 // Display the SMB error text
375

376                 System.out.print("Error Text: ");
377                 System.out.println(SMBErrorText.ErrorString(getErrorClass(), getErrorCode()));
378             }
379         }
380
381         // Dump the raw data
382

383         if (true)
384         {
385             System.out.println("********** Raw SMB Data Dump **********");
386             if (dumpAll)
387                 HexDump.Dump(m_smbbuf, getLength(), 4);
388             else
389                 HexDump.Dump(m_smbbuf, getLength() < 100 ? getLength() : 100, 4);
390         }
391
392         System.out.println();
393         System.out.flush();
394     }
395
396     /**
397      * Get the data byte count for the SMB AndX command.
398      *
399      * @param off Offset to the AndX command.
400      * @return Data byte count
401      */

402
403     public final int getAndXByteCount(int off)
404     {
405
406         // Calculate the offset of the byte count
407

408         int pos = off + 1 + (2 * getParameterCount());
409         return (int) DataPacker.getIntelShort(m_smbbuf, pos);
410     }
411
412     /**
413      * Get the AndX data byte area offset within the SMB packet
414      *
415      * @param off Offset to the AndX command.
416      * @return Data byte offset within the SMB packet.
417      */

418
419     public final int getAndXByteOffset(int off)
420     {
421
422         // Calculate the offset of the byte buffer
423

424         int pCnt = getAndXParameterCount(off);
425         int pos = off + (2 * pCnt) + 3; // parameter words + paramter count byte + byte data length
426
// word
427
return pos;
428     }
429
430     /**
431      * Get the secondary command code
432      *
433      * @return Secondary command code
434      */

435
436     public final int getAndXCommand()
437     {
438         return (int) (m_smbbuf[ANDXCOMMAND] & 0xFF);
439     }
440
441     /**
442      * Get an AndX parameter word from the SMB packet.
443      *
444      * @param off Offset to the AndX command.
445      * @param idx Parameter index (zero based).
446      * @return Parameter word value.
447      * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range.
448      */

449
450     public final int getAndXParameter(int off, int idx) throws java.lang.IndexOutOfBoundsException JavaDoc
451     {
452
453         // Range check the parameter index
454

455         if (idx > getAndXParameterCount(off))
456             throw new java.lang.IndexOutOfBoundsException JavaDoc();
457
458         // Calculate the parameter word offset
459

460         int pos = off + (2 * idx) + 1;
461         return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF);
462     }
463
464     /**
465      * Get an AndX parameter integer from the SMB packet.
466      *
467      * @param off Offset to the AndX command.
468      * @param idx Parameter index (zero based).
469      * @return Parameter integer value.
470      * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range.
471      */

472
473     public final int getAndXParameterLong(int off, int idx) throws java.lang.IndexOutOfBoundsException JavaDoc
474     {
475
476         // Range check the parameter index
477

478         if (idx > getAndXParameterCount(off))
479             throw new java.lang.IndexOutOfBoundsException JavaDoc();
480
481         // Calculate the parameter word offset
482

483         int pos = off + (2 * idx) + 1;
484         return DataPacker.getIntelInt(m_smbbuf, pos);
485     }
486
487     /**
488      * Get the AndX command parameter count.
489      *
490      * @param off Offset to the AndX command.
491      * @return Parameter word count.
492      */

493
494     public final int getAndXParameterCount(int off)
495     {
496         return (int) m_smbbuf[off];
497     }
498
499     /**
500      * Return the byte array used for the SMB packet
501      *
502      * @return Byte array used for the SMB packet.
503      */

504
505     public final byte[] getBuffer()
506     {
507         return m_smbbuf;
508     }
509
510     /**
511      * Return the total buffer size available to the SMB request
512      *
513      * @return Total SMB buffer length available.
514      */

515
516     public final int getBufferLength()
517     {
518         return m_smbbuf.length - RFCNetBIOSProtocol.HEADER_LEN;
519     }
520
521     /**
522      * Get the data byte count for the SMB packet
523      *
524      * @return Data byte count
525      */

526
527     public final int getByteCount()
528     {
529
530         // Calculate the offset of the byte count
531

532         int pos = PARAMWORDS + (2 * getParameterCount());
533         return (int) DataPacker.getIntelShort(m_smbbuf, pos);
534     }
535
536     /**
537      * Get the data byte area offset within the SMB packet
538      *
539      * @return Data byte offset within the SMB packet.
540      */

541
542     public final int getByteOffset()
543     {
544
545         // Calculate the offset of the byte buffer
546

547         int pCnt = getParameterCount();
548         int pos = WORDCNT + (2 * pCnt) + 3;
549         return pos;
550     }
551
552     /**
553      * Get the SMB command
554      *
555      * @return SMB command code.
556      */

557
558     public final int getCommand()
559     {
560         return (int) (m_smbbuf[COMMAND] & 0xFF);
561     }
562
563     /**
564      * Get the SMB error class
565      *
566      * @return SMB error class.
567      */

568
569     public final int getErrorClass()
570     {
571         return (int) m_smbbuf[ERRORCLASS] & 0xFF;
572     }
573
574     /**
575      * Get the SMB error code
576      *
577      * @return SMB error code.
578      */

579
580     public final int getErrorCode()
581     {
582         return (int) m_smbbuf[ERROR] & 0xFF;
583     }
584
585     /**
586      * Get the SMB flags value.
587      *
588      * @return SMB flags value.
589      */

590
591     public final int getFlags()
592     {
593         return (int) m_smbbuf[FLAGS] & 0xFF;
594     }
595
596     /**
597      * Get the SMB flags2 value.
598      *
599      * @return SMB flags2 value.
600      */

601     public final int getFlags2()
602     {
603         return (int) DataPacker.getIntelShort(m_smbbuf, FLAGS2);
604     }
605
606     /**
607      * Calculate the total used packet length.
608      *
609      * @return Total used packet length.
610      */

611     public final int getLength()
612     {
613
614         // Get the length of the first command in the packet
615

616         return (getByteOffset() + getByteCount()) - SIGNATURE;
617     }
618
619     /**
620      * Calculate the total packet length, including header
621      *
622      * @return Total packet length.
623      */

624     public final int getPacketLength()
625     {
626
627         // Get the length of the first command in the packet
628

629         return getByteOffset() + getByteCount();
630     }
631
632     /**
633      * Return the available buffer space for data bytes
634      *
635      * @return int
636      */

637     public final int getAvailableLength()
638     {
639         return m_smbbuf.length - DataPacker.longwordAlign(getByteOffset());
640     }
641
642     /**
643      * Return the available buffer space for data bytes for the specified buffer length
644      *
645      * @param len int
646      * @return int
647      */

648     public final int getAvailableLength(int len)
649     {
650         return len - DataPacker.longwordAlign(getByteOffset());
651     }
652
653     /**
654      * Get the long SMB error code
655      *
656      * @return Long SMB error code.
657      */

658     public final int getLongErrorCode()
659     {
660         return DataPacker.getIntelInt(m_smbbuf, ERRORCODE);
661     }
662
663     /**
664      * Get the multiplex identifier.
665      *
666      * @return Multiplex identifier.
667      */

668     public final int getMultiplexId()
669     {
670         return DataPacker.getIntelShort(m_smbbuf, MID);
671     }
672
673     /**
674      * Dump the packet type
675      *
676      * @return String
677      */

678     public final String JavaDoc getPacketTypeString()
679     {
680
681         String JavaDoc pktType = "";
682
683         switch (getCommand())
684         {
685         case PacketType.Negotiate:
686             pktType = "NEGOTIATE";
687             break;
688         case PacketType.SessionSetupAndX:
689             pktType = "SESSION_SETUP";
690             break;
691         case PacketType.TreeConnect:
692             pktType = "TREE_CONNECT";
693             break;
694         case PacketType.TreeConnectAndX:
695             pktType = "TREE_CONNECT_ANDX";
696             break;
697         case PacketType.TreeDisconnect:
698             pktType = "TREE_DISCONNECT";
699             break;
700         case PacketType.Search:
701             pktType = "SEARCH";
702             break;
703         case PacketType.OpenFile:
704             pktType = "OPEN_FILE";
705             break;
706         case PacketType.OpenAndX:
707             pktType = "OPEN_ANDX";
708             break;
709         case PacketType.ReadFile:
710             pktType = "READ_FILE";
711             break;
712         case PacketType.WriteFile:
713             pktType = "WRITE_FILE";
714             break;
715         case PacketType.CloseFile:
716             pktType = "CLOSE_FILE";
717             break;
718         case PacketType.CreateFile:
719             pktType = "CREATE_FILE";
720             break;
721         case PacketType.GetFileAttributes:
722             pktType = "GET_FILE_INFO";
723             break;
724         case PacketType.DiskInformation:
725             pktType = "GET_DISK_INFO";
726             break;
727         case PacketType.CheckDirectory:
728             pktType = "CHECK_DIRECTORY";
729             break;
730         case PacketType.RenameFile:
731             pktType = "RENAME_FILE";
732             break;
733         case PacketType.DeleteDirectory:
734             pktType = "DELETE_DIRECTORY";
735             break;
736         case PacketType.GetPrintQueue:
737             pktType = "GET_PRINT_QUEUE";
738             break;
739         case PacketType.Transaction2:
740             pktType = "TRANSACTION2";
741             break;
742         case PacketType.Transaction:
743             pktType = "TRANSACTION";
744             break;
745         case PacketType.Transaction2Second:
746             pktType = "TRANSACTION2_SECONDARY";
747             break;
748         case PacketType.TransactionSecond:
749             pktType = "TRANSACTION_SECONDARY";
750             break;
751         case PacketType.Echo:
752             pktType = "ECHO";
753             break;
754         case PacketType.QueryInformation2:
755             pktType = "QUERY_INFORMATION_2";
756             break;
757         case PacketType.WriteAndClose:
758             pktType = "WRITE_AND_CLOSE";
759             break;
760         case PacketType.SetInformation2:
761             pktType = "SET_INFORMATION_2";
762             break;
763         case PacketType.FindClose2:
764             pktType = "FIND_CLOSE2";
765             break;
766         case PacketType.LogoffAndX:
767             pktType = "LOGOFF_ANDX";
768             break;
769         case PacketType.NTCancel:
770             pktType = "NTCANCEL";
771             break;
772         case PacketType.NTCreateAndX:
773             pktType = "NTCREATE_ANDX";
774             break;
775         case PacketType.NTTransact:
776             pktType = "NTTRANSACT";
777             break;
778         case PacketType.NTTransactSecond:
779             pktType = "NTTRANSACT_SECONDARY";
780             break;
781         case PacketType.ReadAndX:
782             pktType = "READ_ANDX";
783             break;
784         default:
785             pktType = "0x" + Integer.toHexString(getCommand());
786             break;
787         }
788
789         // Return the packet type string
790

791         return pktType;
792     }
793
794     /**
795      * Get a parameter word from the SMB packet.
796      *
797      * @param idx Parameter index (zero based).
798      * @return Parameter word value.
799      * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range.
800      */

801
802     public final int getParameter(int idx) throws java.lang.IndexOutOfBoundsException JavaDoc
803     {
804
805         // Range check the parameter index
806

807         if (idx > getParameterCount())
808             throw new java.lang.IndexOutOfBoundsException JavaDoc();
809
810         // Calculate the parameter word offset
811

812         int pos = WORDCNT + (2 * idx) + 1;
813         return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF);
814     }
815
816     /**
817      * Get the parameter count
818      *
819      * @return Parameter word count.
820      */

821
822     public final int getParameterCount()
823     {
824         return (int) m_smbbuf[WORDCNT];
825     }
826
827     /**
828      * Get the specified parameter words, as an int value.
829      *
830      * @param idx Parameter index (zero based).
831      * @param val Parameter value.
832      */

833
834     public final int getParameterLong(int idx)
835     {
836         int pos = WORDCNT + (2 * idx) + 1;
837         return DataPacker.getIntelInt(m_smbbuf, pos);
838     }
839
840     /**
841      * Get the process indentifier (PID)
842      *
843      * @return Process identifier value.
844      */

845     public final int getProcessId()
846     {
847         return DataPacker.getIntelShort(m_smbbuf, PID);
848     }
849
850     /**
851      * Get the actual received data length.
852      *
853      * @return int
854      */

855     public final int getReceivedLength()
856     {
857         return m_rxLen;
858     }
859
860     /**
861      * Get the session identifier (SID)
862      *
863      * @return Session identifier (SID)
864      */

865
866     public final int getSID()
867     {
868         return DataPacker.getIntelShort(m_smbbuf, SID);
869     }
870
871     /**
872      * Get the tree identifier (TID)
873      *
874      * @return Tree identifier (TID)
875      */

876
877     public final int getTreeId()
878     {
879         return DataPacker.getIntelShort(m_smbbuf, TID);
880     }
881
882     /**
883      * Get the user identifier (UID)
884      *
885      * @return User identifier (UID)
886      */

887
888     public final int getUserId()
889     {
890         return DataPacker.getIntelShort(m_smbbuf, UID);
891     }
892
893     /**
894      * Determine if there is a secondary command in this packet.
895      *
896      * @return Secondary command code
897      */

898
899     public final boolean hasAndXCommand()
900     {
901
902         // Check if there is a secondary command
903

904         int andxCmd = getAndXCommand();
905
906         if (andxCmd != 0xFF && andxCmd != 0)
907             return true;
908         return false;
909     }
910
911     /**
912      * Initialize the SMB packet buffer.
913      */

914
915     private final void InitializeBuffer()
916     {
917
918         // Set the packet signature
919

920         m_smbbuf[SIGNATURE] = (byte) 0xFF;
921         m_smbbuf[SIGNATURE + 1] = (byte) 'S';
922         m_smbbuf[SIGNATURE + 2] = (byte) 'M';
923         m_smbbuf[SIGNATURE + 3] = (byte) 'B';
924     }
925
926     /**
927      * Determine if this packet is an SMB response, or command packet
928      *
929      * @return true if this SMB packet is a response, else false
930      */

931
932     public final boolean isResponse()
933     {
934         int resp = getFlags();
935         if ((resp & FLG_RESPONSE) != 0)
936             return true;
937         return false;
938     }
939
940     /**
941      * Check if the response packet is valid, ie. type and flags
942      *
943      * @return true if the SMB packet is a response packet and the response is valid, else false.
944      */

945
946     public final boolean isValidResponse()
947     {
948
949         // Check if this is a response packet, and the correct type of packet
950

951         if (isResponse() && getCommand() == m_pkttype && this.getErrorClass() == SMBStatus.Success)
952             return true;
953         return false;
954     }
955
956     /**
957      * Check if the packet contains ASCII or Unicode strings
958      *
959      * @return boolean
960      */

961     public final boolean isUnicode()
962     {
963         return (getFlags2() & FLG2_UNICODE) != 0 ? true : false;
964     }
965
966     /**
967      * Check if the packet is using caseless filenames
968      *
969      * @return boolean
970      */

971     public final boolean isCaseless()
972     {
973         return (getFlags() & FLG_CASELESS) != 0 ? true : false;
974     }
975
976     /**
977      * Check if long file names are being used
978      *
979      * @return boolean
980      */

981     public final boolean isLongFileNames()
982     {
983         return (getFlags2() & FLG2_LONGFILENAMES) != 0 ? true : false;
984     }
985
986     /**
987      * Check if long error codes are being used
988      *
989      * @return boolean
990      */

991     public final boolean isLongErrorCode()
992     {
993         return (getFlags2() & FLG2_LONGERRORCODE) != 0 ? true : false;
994     }
995
996     /**
997      * Pack a byte (8 bit) value into the byte area
998      *
999      * @param val byte
1000     */

1001    public final void packByte(byte val)
1002    {
1003        m_smbbuf[m_pos++] = val;
1004    }
1005
1006    /**
1007     * Pack a byte (8 bit) value into the byte area
1008     *
1009     * @param val int
1010     */

1011    public final void packByte(int val)
1012    {
1013        m_smbbuf[m_pos++] = (byte) val;
1014    }
1015
1016    /**
1017     * Pack the specified bytes into the byte area
1018     *
1019     * @param byts byte[]
1020     * @param len int
1021     */

1022    public final void packBytes(byte[] byts, int len)
1023    {
1024        for (int i = 0; i < len; i++)
1025            m_smbbuf[m_pos++] = byts[i];
1026    }
1027
1028    /**
1029     * Pack a string using either ASCII or Unicode into the byte area
1030     *
1031     * @param str String
1032     * @param uni boolean
1033     */

1034    public final void packString(String JavaDoc str, boolean uni)
1035    {
1036
1037        // Check for Unicode or ASCII
1038

1039        if (uni)
1040        {
1041
1042            // Word align the buffer position, pack the Unicode string
1043

1044            m_pos = DataPacker.wordAlign(m_pos);
1045            DataPacker.putUnicodeString(str, m_smbbuf, m_pos, true);
1046            m_pos += (str.length() * 2) + 2;
1047        }
1048        else
1049        {
1050
1051            // Pack the ASCII string
1052

1053            DataPacker.putString(str, m_smbbuf, m_pos, true);
1054            m_pos += str.length() + 1;
1055        }
1056    }
1057
1058    /**
1059     * Pack a string using either ASCII or Unicode into the byte area
1060     *
1061     * @param str String
1062     * @param uni boolean
1063     * @param nul boolean
1064     */

1065    public final void packString(String JavaDoc str, boolean uni, boolean nul)
1066    {
1067
1068        // Check for Unicode or ASCII
1069

1070        if (uni)
1071        {
1072
1073            // Word align the buffer position, pack the Unicode string
1074

1075            m_pos = DataPacker.wordAlign(m_pos);
1076            DataPacker.putUnicodeString(str, m_smbbuf, m_pos, nul);
1077            m_pos += (str.length() * 2);
1078            if (nul == true)
1079                m_pos += 2;
1080        }
1081        else
1082        {
1083
1084            // Pack the ASCII string
1085

1086            DataPacker.putString(str, m_smbbuf, m_pos, true);
1087            m_pos += str.length();
1088            if (nul == true)
1089                m_pos++;
1090        }
1091    }
1092
1093    /**
1094     * Pack a word (16 bit) value into the byte area
1095     *
1096     * @param val int
1097     */

1098    public final void packWord(int val)
1099    {
1100        DataPacker.putIntelShort(val, m_smbbuf, m_pos);
1101        m_pos += 2;
1102    }
1103
1104    /**
1105     * Pack an integer (32 bit) value into the byte area
1106     *
1107     * @param val int
1108     */

1109    public final void packInt(int val)
1110    {
1111        DataPacker.putIntelInt(val, m_smbbuf, m_pos);
1112        m_pos += 4;
1113    }
1114
1115    /**
1116     * Pack a long integer (64 bit) value into the byte area
1117     *
1118     * @param val long
1119     */

1120    public final void packLong(long val)
1121    {
1122        DataPacker.putIntelLong(val, m_smbbuf, m_pos);
1123        m_pos += 8;
1124    }
1125
1126    /**
1127     * Return the current byte area buffer position
1128     *
1129     * @return int
1130     */

1131    public final int getPosition()
1132    {
1133        return m_pos;
1134    }
1135
1136    /**
1137     * Unpack a byte value from the byte area
1138     *
1139     * @return int
1140     */

1141    public final int unpackByte()
1142    {
1143        return (int) m_smbbuf[m_pos++];
1144    }
1145
1146    /**
1147     * Unpack a block of bytes from the byte area
1148     *
1149     * @param len int
1150     * @return byte[]
1151     */

1152    public final byte[] unpackBytes(int len)
1153    {
1154        if (len <= 0)
1155            return null;
1156
1157        byte[] buf = new byte[len];
1158        System.arraycopy(m_smbbuf, m_pos, buf, 0, len);
1159        m_pos += len;
1160        return buf;
1161    }
1162
1163    /**
1164     * Unpack a word (16 bit) value from the byte area
1165     *
1166     * @return int
1167     */

1168    public final int unpackWord()
1169    {
1170        int val = DataPacker.getIntelShort(m_smbbuf, m_pos);
1171        m_pos += 2;
1172        return val;
1173    }
1174
1175    /**
1176     * Unpack an integer (32 bit) value from the byte area
1177     *
1178     * @return int
1179     */

1180    public final int unpackInt()
1181    {
1182        int val = DataPacker.getIntelInt(m_smbbuf, m_pos);
1183        m_pos += 4;
1184        return val;
1185    }
1186
1187    /**
1188     * Unpack a long integer (64 bit) value from the byte area
1189     *
1190     * @return long
1191     */

1192    public final long unpackLong()
1193    {
1194        long val = DataPacker.getIntelLong(m_smbbuf, m_pos);
1195        m_pos += 8;
1196        return val;
1197    }
1198
1199    /**
1200     * Unpack a string from the byte area
1201     *
1202     * @param uni boolean
1203     * @return String
1204     */

1205    public final String JavaDoc unpackString(boolean uni)
1206    {
1207
1208        // Check for Unicode or ASCII
1209

1210        String JavaDoc ret = null;
1211
1212        if (uni)
1213        {
1214
1215            // Word align the current buffer position
1216

1217            m_pos = DataPacker.wordAlign(m_pos);
1218            ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, 255);
1219            if (ret != null)
1220                m_pos += (ret.length() * 2) + 2;
1221        }
1222        else
1223        {
1224
1225            // Unpack the ASCII string
1226

1227            ret = DataPacker.getString(m_smbbuf, m_pos, 255);
1228            if (ret != null)
1229                m_pos += ret.length() + 1;
1230        }
1231
1232        // Return the string
1233

1234        return ret;
1235    }
1236
1237    /**
1238     * Check if there is more data in the byte area
1239     *
1240     * @return boolean
1241     */

1242    public final boolean hasMoreData()
1243    {
1244        if (m_pos < m_endpos)
1245            return true;
1246        return false;
1247    }
1248
1249    /**
1250     * Send the SMB response packet.
1251     *
1252     * @param out Output stream associated with the session socket.
1253     * @param proto Protocol type, either PROTOCOL_NETBIOS or PROTOCOL_TCPIP
1254     * @exception java.io.IOException If an I/O error occurs.
1255     */

1256    public final void SendResponseSMB(DataOutputStream JavaDoc out, int proto) throws java.io.IOException JavaDoc
1257    {
1258
1259        // Use the packet length
1260

1261        int siz = getLength();
1262        SendResponseSMB(out, proto, siz);
1263    }
1264
1265    /**
1266     * Send the SMB response packet.
1267     *
1268     * @param out Output stream associated with the session socket.
1269     * @param proto Protocol type, either PROTOCOL_NETBIOS or PROTOCOL_TCPIP
1270     * @param len Packet length
1271     * @exception java.io.IOException If an I/O error occurs.
1272     */

1273    public final void SendResponseSMB(DataOutputStream JavaDoc out, int proto, int len) throws java.io.IOException JavaDoc
1274    {
1275
1276        // Make sure the response flag is set
1277

1278        int flg = getFlags();
1279        if ((flg & FLG_RESPONSE) == 0)
1280            setFlags(flg + FLG_RESPONSE);
1281
1282        // NetBIOS SMB protocol
1283

1284        if (proto == PROTOCOL_NETBIOS)
1285        {
1286
1287            // Fill in the NetBIOS message header, this is already allocated as
1288
// part of the users buffer.
1289

1290            m_smbbuf[0] = (byte) RFCNetBIOSProtocol.SESSION_MESSAGE;
1291            m_smbbuf[1] = (byte) 0;
1292
1293            DataPacker.putShort((short) len, m_smbbuf, 2);
1294        }
1295        else
1296        {
1297
1298            // TCP/IP native SMB
1299

1300            DataPacker.putInt(len, m_smbbuf, 0);
1301        }
1302
1303        // Output the data packet
1304

1305        len += RFCNetBIOSProtocol.HEADER_LEN;
1306        out.write(m_smbbuf, 0, len);
1307    }
1308
1309    /**
1310     * Send a success SMB response packet.
1311     *
1312     * @param out Output stream associated with the session socket.
1313     * @param proto Protocol type, either PROTOCOL_NETBIOS or PROTOCOL_TCPIP
1314     * @exception java.io.IOException If an I/O error occurs.
1315     */

1316
1317    public final void SendSuccessSMB(DataOutputStream JavaDoc out, int proto) throws java.io.IOException JavaDoc
1318    {
1319
1320        // Clear the parameter and byte counts
1321

1322        setParameterCount(0);
1323        setByteCount(0);
1324
1325        // Send the success response
1326

1327        SendResponseSMB(out, proto);
1328    }
1329
1330    /**
1331     * Set the AndX data byte count for this SMB packet.
1332     *
1333     * @param off AndX command offset.
1334     * @param cnt Data byte count.
1335     */

1336
1337    public final void setAndXByteCount(int off, int cnt)
1338    {
1339        int offset = getAndXByteOffset(off) - 2;
1340        DataPacker.putIntelShort(cnt, m_smbbuf, offset);
1341    }
1342
1343    /**
1344     * Set the AndX data byte area in the SMB packet
1345     *
1346     * @param off Offset to the AndX command.
1347     * @param byts Byte array containing the data to be copied to the SMB packet.
1348     */

1349
1350    public final void setAndXBytes(int off, byte[] byts)
1351    {
1352        int offset = getAndXByteOffset(off) - 2;
1353        DataPacker.putIntelShort(byts.length, m_smbbuf, offset);
1354
1355        offset += 2;
1356
1357        for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++])
1358            ;
1359    }
1360
1361    /**
1362     * Set the secondary SMB command
1363     *
1364     * @param cmd Secondary SMB command code.
1365     */

1366
1367    public final void setAndXCommand(int cmd)
1368    {
1369        m_smbbuf[ANDXCOMMAND] = (byte) cmd;
1370        m_smbbuf[ANDXRESERVED] = (byte) 0;
1371    }
1372
1373    /**
1374     * Set the AndX command for an AndX command block.
1375     *
1376     * @param off Offset to the current AndX command.
1377     * @param cmd Secondary SMB command code.
1378     */

1379
1380    public final void setAndXCommand(int off, int cmd)
1381    {
1382        m_smbbuf[off + 1] = (byte) cmd;
1383        m_smbbuf[off + 2] = (byte) 0;
1384    }
1385
1386    /**
1387     * Set the specified AndX parameter word.
1388     *
1389     * @param off Offset to the AndX command.
1390     * @param idx Parameter index (zero based).
1391     * @param val Parameter value.
1392     */

1393
1394    public final void setAndXParameter(int off, int idx, int val)
1395    {
1396        int pos = off + (2 * idx) + 1;
1397        DataPacker.putIntelShort(val, m_smbbuf, pos);
1398    }
1399
1400    /**
1401     * Set the AndX parameter count
1402     *
1403     * @param off Offset to the AndX command.
1404     * @param cnt Parameter word count.
1405     */

1406
1407    public final void setAndXParameterCount(int off, int cnt)
1408    {
1409        m_smbbuf[off] = (byte) cnt;
1410    }
1411
1412    /**
1413     * Set the data byte count for this SMB packet
1414     *
1415     * @param cnt Data byte count.
1416     */

1417
1418    public final void setByteCount(int cnt)
1419    {
1420        int offset = getByteOffset() - 2;
1421        DataPacker.putIntelShort(cnt, m_smbbuf, offset);
1422    }
1423
1424    /**
1425     * Set the data byte count for this SMB packet
1426     */

1427
1428    public final void setByteCount()
1429    {
1430        int offset = getByteOffset() - 2;
1431        int len = m_pos - getByteOffset();
1432        DataPacker.putIntelShort(len, m_smbbuf, offset);
1433    }
1434
1435    /**
1436     * Set the data byte area in the SMB packet
1437     *
1438     * @param byts Byte array containing the data to be copied to the SMB packet.
1439     */

1440
1441    public final void setBytes(byte[] byts)
1442    {
1443        int offset = getByteOffset() - 2;
1444        DataPacker.putIntelShort(byts.length, m_smbbuf, offset);
1445
1446        offset += 2;
1447
1448        for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++])
1449            ;
1450    }
1451
1452    /**
1453     * Set the SMB command
1454     *
1455     * @param cmd SMB command code
1456     */

1457
1458    public final void setCommand(int cmd)
1459    {
1460        m_pkttype = cmd;
1461        m_smbbuf[COMMAND] = (byte) cmd;
1462    }
1463
1464    /**
1465     * Set the error class and code.
1466     *
1467     * @param errCode int
1468     * @param errClass int
1469     */

1470    public final void setError(int errCode, int errClass)
1471    {
1472
1473        // Set the error class and code
1474

1475        setErrorClass(errClass);
1476        setErrorCode(errCode);
1477    }
1478
1479    /**
1480     * Set the error class/code.
1481     *
1482     * @param longError boolean
1483     * @param ntErr int
1484     * @param errCode int
1485     * @param errClass int
1486     */

1487    public final void setError(boolean longError, int ntErr, int errCode, int errClass)
1488    {
1489
1490        // Check if the error code is a long/NT status code
1491

1492        if (longError)
1493        {
1494
1495            // Set the NT status code
1496

1497            setLongErrorCode(ntErr);
1498
1499            // Set the NT status code flag
1500

1501            if (isLongErrorCode() == false)
1502                setFlags2(getFlags2() + SMBSrvPacket.FLG2_LONGERRORCODE);
1503        }
1504        else
1505        {
1506
1507            // Set the error class and code
1508

1509            setErrorClass(errClass);
1510            setErrorCode(errCode);
1511        }
1512    }
1513
1514    /**
1515     * Set the SMB error class.
1516     *
1517     * @param cl SMB error class.
1518     */

1519
1520    public final void setErrorClass(int cl)
1521    {
1522        m_smbbuf[ERRORCLASS] = (byte) (cl & 0xFF);
1523    }
1524
1525    /**
1526     * Set the SMB error code
1527     *
1528     * @param sts SMB error code.
1529     */

1530
1531    public final void setErrorCode(int sts)
1532    {
1533        m_smbbuf[ERROR] = (byte) (sts & 0xFF);
1534    }
1535
1536    /**
1537     * Set the long SMB error code
1538     *
1539     * @param err Long SMB error code.
1540     */

1541
1542    public final void setLongErrorCode(int err)
1543    {
1544        DataPacker.putIntelInt(err, m_smbbuf, ERRORCODE);
1545    }
1546
1547    /**
1548     * Set the SMB flags value.
1549     *
1550     * @param flg SMB flags value.
1551     */

1552
1553    public final void setFlags(int flg)
1554    {
1555        m_smbbuf[FLAGS] = (byte) flg;
1556    }
1557
1558    /**
1559     * Set the SMB flags2 value.
1560     *
1561     * @param flg SMB flags2 value.
1562     */

1563
1564    public final void setFlags2(int flg)
1565    {
1566        DataPacker.putIntelShort(flg, m_smbbuf, FLAGS2);
1567    }
1568
1569    /**
1570     * Set the multiplex identifier.
1571     *
1572     * @param mid Multiplex identifier
1573     */

1574
1575    public final void setMultiplexId(int mid)
1576    {
1577        DataPacker.putIntelShort(mid, m_smbbuf, MID);
1578    }
1579
1580    /**
1581     * Set the specified parameter word.
1582     *
1583     * @param idx Parameter index (zero based).
1584     * @param val Parameter value.
1585     */

1586
1587    public final void setParameter(int idx, int val)
1588    {
1589        int pos = WORDCNT + (2 * idx) + 1;
1590        DataPacker.putIntelShort(val, m_smbbuf, pos);
1591    }
1592
1593    /**
1594     * Set the parameter count
1595     *
1596     * @param cnt Parameter word count.
1597     */

1598
1599    public final void setParameterCount(int cnt)
1600    {
1601
1602        // Set the parameter count
1603

1604        m_smbbuf[WORDCNT] = (byte) cnt;
1605
1606        // Reset the byte area pointer
1607

1608        resetBytePointer();
1609    }
1610
1611    /**
1612     * Set the specified parameter words.
1613     *
1614     * @param idx Parameter index (zero based).
1615     * @param val Parameter value.
1616     */

1617
1618    public final void setParameterLong(int idx, int val)
1619    {
1620        int pos = WORDCNT + (2 * idx) + 1;
1621        DataPacker.putIntelInt(val, m_smbbuf, pos);
1622    }
1623
1624    /**
1625     * Set the pack/unpack position
1626     *
1627     * @param pos int
1628     */

1629    public final void setPosition(int pos)
1630    {
1631        m_pos = pos;
1632    }
1633
1634    /**
1635     * Set the process identifier value (PID).
1636     *
1637     * @param pid Process identifier value.
1638     */

1639
1640    public final void setProcessId(int pid)
1641    {
1642        DataPacker.putIntelShort(pid, m_smbbuf, PID);
1643    }
1644
1645    /**
1646     * Set the actual received data length.
1647     *
1648     * @param len int
1649     */

1650    public final void setReceivedLength(int len)
1651    {
1652        m_rxLen = len;
1653    }
1654
1655    /**
1656     * Set the packet sequence number, for connectionless commands.
1657     *
1658     * @param seq Sequence number.
1659     */

1660
1661    public final void setSeqNo(int seq)
1662    {
1663        DataPacker.putIntelShort(seq, m_smbbuf, SEQNO);
1664    }
1665
1666    /**
1667     * Set the session id.
1668     *
1669     * @param sid Session id.
1670     */

1671    public final void setSID(int sid)
1672    {
1673        DataPacker.putIntelShort(sid, m_smbbuf, SID);
1674    }
1675
1676    /**
1677     * Set the tree identifier (TID)
1678     *
1679     * @param tid Tree identifier value.
1680     */

1681
1682    public final void setTreeId(int tid)
1683    {
1684        DataPacker.putIntelShort(tid, m_smbbuf, TID);
1685    }
1686
1687    /**
1688     * Set the user identifier (UID)
1689     *
1690     * @param uid User identifier value.
1691     */

1692
1693    public final void setUserId(int uid)
1694    {
1695        DataPacker.putIntelShort(uid, m_smbbuf, UID);
1696    }
1697
1698    /**
1699     * Reset the byte pointer area for packing/unpacking data items from the packet
1700     */

1701    public final void resetBytePointer()
1702    {
1703        m_pos = getByteOffset();
1704        m_endpos = m_pos + getByteCount();
1705    }
1706
1707    /**
1708     * Set the unpack pointer to the specified offset, for AndX processing
1709     *
1710     * @param off int
1711     * @param len int
1712     */

1713    public final void setBytePointer(int off, int len)
1714    {
1715        m_pos = off;
1716        m_endpos = m_pos + len;
1717    }
1718
1719    /**
1720     * Align the byte area pointer on an int (32bit) boundary
1721     */

1722    public final void alignBytePointer()
1723    {
1724        m_pos = DataPacker.longwordAlign(m_pos);
1725    }
1726
1727    /**
1728     * Reset the byte/parameter pointer area for packing/unpacking data items from the packet, and
1729     * align the buffer on an int (32bit) boundary
1730     */

1731    public final void resetBytePointerAlign()
1732    {
1733        m_pos = DataPacker.longwordAlign(getByteOffset());
1734        m_endpos = m_pos + getByteCount();
1735    }
1736
1737    /**
1738     * Skip a number of bytes in the parameter/byte area
1739     *
1740     * @param cnt int
1741     */

1742    public final void skipBytes(int cnt)
1743    {
1744        m_pos += cnt;
1745    }
1746
1747    /**
1748     * Set the data buffer
1749     *
1750     * @param buf byte[]
1751     */

1752    public final void setBuffer(byte[] buf)
1753    {
1754        m_smbbuf = buf;
1755    }
1756}
Popular Tags