1 17 package org.alfresco.filesys.smb.server; 18 19 import org.alfresco.filesys.netbios.NetBIOSSession; 20 import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; 21 import org.alfresco.filesys.smb.PacketType; 22 import org.alfresco.filesys.smb.SMBStatus; 23 import org.alfresco.filesys.util.DataPacker; 24 25 28 public class SMBPacket 29 { 30 31 33 public static final int SIGNATURE = RFCNetBIOSProtocol.HEADER_LEN; 34 public static final int COMMAND = 4 + RFCNetBIOSProtocol.HEADER_LEN; 35 public static final int ERRORCODE = 5 + RFCNetBIOSProtocol.HEADER_LEN; 36 public static final int ERRORCLASS = 5 + RFCNetBIOSProtocol.HEADER_LEN; 37 public static final int ERROR = 7 + RFCNetBIOSProtocol.HEADER_LEN; 38 public static final int FLAGS = 9 + RFCNetBIOSProtocol.HEADER_LEN; 39 public static final int FLAGS2 = 10 + RFCNetBIOSProtocol.HEADER_LEN; 40 public static final int PIDHIGH = 12 + RFCNetBIOSProtocol.HEADER_LEN; 41 public static final int SID = 18 + RFCNetBIOSProtocol.HEADER_LEN; 42 public static final int SEQNO = 20 + RFCNetBIOSProtocol.HEADER_LEN; 43 public static final int TID = 24 + RFCNetBIOSProtocol.HEADER_LEN; 44 public static final int PID = 26 + RFCNetBIOSProtocol.HEADER_LEN; 45 public static final int UID = 28 + RFCNetBIOSProtocol.HEADER_LEN; 46 public static final int MID = 30 + RFCNetBIOSProtocol.HEADER_LEN; 47 public static final int WORDCNT = 32 + RFCNetBIOSProtocol.HEADER_LEN; 48 public static final int ANDXCOMMAND = 33 + RFCNetBIOSProtocol.HEADER_LEN; 49 public static final int ANDXRESERVED = 34 + RFCNetBIOSProtocol.HEADER_LEN; 50 public static final int PARAMWORDS = 33 + RFCNetBIOSProtocol.HEADER_LEN; 51 52 54 public static final int TRANS_HEADERLEN = 66 + RFCNetBIOSProtocol.HEADER_LEN; 55 56 58 public static final int MIN_RXLEN = 32; 59 60 62 public static final int DEFAULT_BUFSIZE = 4096; 63 64 66 public static final int FLG_SUBDIALECT = 0x01; 67 public static final int FLG_CASELESS = 0x08; 68 public static final int FLG_CANONICAL = 0x10; 69 public static final int FLG_OPLOCK = 0x20; 70 public static final int FLG_NOTIFY = 0x40; 71 public static final int FLG_RESPONSE = 0x80; 72 73 75 public static final int FLG2_LONGFILENAMES = 0x0001; 76 public static final int FLG2_EXTENDEDATTRIB = 0x0002; 77 public static final int FLG2_SECURITYSIGS = 0x0004; 78 public static final int FLG2_LONGNAMESUSED = 0x0040; 79 public static final int FLG2_EXTENDNEGOTIATE = 0x0800; 80 public static final int FLG2_DFSRESOLVE = 0x1000; 81 public static final int FLG2_READIFEXE = 0x2000; 82 public static final int FLG2_LONGERRORCODE = 0x4000; 83 public static final int FLG2_UNICODE = 0x8000; 84 85 87 public static final int SEC_USER = 0x0001; 88 public static final int SEC_ENCRYPT = 0x0002; 89 90 92 public static final int RAW_READ = 0x0001; 93 public static final int RAW_WRITE = 0x0002; 94 95 97 private byte[] m_smbbuf; 98 99 101 private int m_pkttype; 102 103 105 protected int m_pos; 106 protected int m_endpos; 107 108 111 public SMBPacket() 112 { 113 m_smbbuf = new byte[DEFAULT_BUFSIZE]; 114 InitializeBuffer(); 115 } 116 117 122 public SMBPacket(byte[] buf) 123 { 124 m_smbbuf = buf; 125 } 126 127 132 public SMBPacket(int siz) 133 { 134 m_smbbuf = new byte[siz]; 135 InitializeBuffer(); 136 } 137 138 143 public SMBPacket(SMBPacket pkt) 144 { 145 146 148 m_smbbuf = new byte[pkt.getBuffer().length]; 149 150 152 System.arraycopy(pkt.getBuffer(), 0, m_smbbuf, 0, pkt.getLength()); 153 } 154 155 158 public final void clearBytes() 159 { 160 int offset = getByteOffset() - 2; 161 DataPacker.putIntelShort(0, m_smbbuf, offset); 162 } 163 164 167 public final void DumpPacket() 168 { 169 } 170 171 178 public final boolean equalsError(int errClass, int errCode) 179 { 180 if (getErrorClass() == errClass && getErrorCode() == errCode) 181 return true; 182 return false; 183 } 184 185 190 public final int getAndXCommand() 191 { 192 return (int) (m_smbbuf[ANDXCOMMAND] & 0xFF); 193 } 194 195 200 public final byte[] getBuffer() 201 { 202 return m_smbbuf; 203 } 204 205 210 public final int getBufferLength() 211 { 212 return m_smbbuf.length - RFCNetBIOSProtocol.HEADER_LEN; 213 } 214 215 220 public final int getByteCount() 221 { 222 223 225 int pos = PARAMWORDS + (2 * getParameterCount()); 226 return (int) DataPacker.getIntelShort(m_smbbuf, pos); 227 } 228 229 234 public final int getByteOffset() 235 { 236 237 239 int pCnt = getParameterCount(); 240 int pos = WORDCNT + (2 * pCnt) + 3; 241 return pos; 242 } 243 244 249 public final int getCommand() 250 { 251 return (int) (m_smbbuf[COMMAND] & 0xFF); 252 } 253 254 259 public final boolean hasLongErrorCode() 260 { 261 if ((getFlags2() & FLG2_LONGERRORCODE) == 0) 262 return false; 263 return true; 264 } 265 266 271 public final boolean isUnicode() 272 { 273 return (getFlags2() & FLG2_UNICODE) != 0 ? true : false; 274 } 275 276 281 public final boolean isCaseless() 282 { 283 return (getFlags() & FLG_CASELESS) != 0 ? true : false; 284 } 285 286 291 public final boolean isLongFileNames() 292 { 293 return (getFlags2() & FLG2_LONGFILENAMES) != 0 ? true : false; 294 } 295 296 301 public final boolean isLongErrorCode() 302 { 303 return (getFlags2() & FLG2_LONGERRORCODE) != 0 ? true : false; 304 } 305 306 311 public final int getErrorClass() 312 { 313 return (int) m_smbbuf[ERRORCLASS] & 0xFF; 314 } 315 316 321 public final int getErrorCode() 322 { 323 return (int) m_smbbuf[ERROR] & 0xFF; 324 } 325 326 331 public final int getFlags() 332 { 333 return (int) m_smbbuf[FLAGS] & 0xFF; 334 } 335 336 341 public final int getFlags2() 342 { 343 return (int) DataPacker.getIntelShort(m_smbbuf, FLAGS2); 344 } 345 346 351 public final int getLength() 352 { 353 return (getByteOffset() + getByteCount()) - SIGNATURE; 354 } 355 356 361 public final int getLongErrorCode() 362 { 363 return DataPacker.getIntelInt(m_smbbuf, ERRORCODE); 364 } 365 366 371 public final int getMultiplexId() 372 { 373 return DataPacker.getIntelShort(m_smbbuf, MID); 374 } 375 376 383 public final int getParameter(int idx) throws java.lang.IndexOutOfBoundsException 384 { 385 386 388 if (idx > getParameterCount()) 389 throw new java.lang.IndexOutOfBoundsException (); 390 391 393 int pos = WORDCNT + (2 * idx) + 1; 394 return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF); 395 } 396 397 403 public final int getParameterLong(int idx) 404 { 405 int pos = WORDCNT + (2 * idx) + 1; 406 return DataPacker.getIntelInt(m_smbbuf, pos); 407 } 408 409 414 public final int getParameterCount() 415 { 416 return (int) m_smbbuf[WORDCNT]; 417 } 418 419 424 public final int getProcessId() 425 { 426 return DataPacker.getIntelShort(m_smbbuf, PID); 427 } 428 429 434 public final int getTreeId() 435 { 436 return DataPacker.getIntelShort(m_smbbuf, TID); 437 } 438 439 444 public final int getUserId() 445 { 446 return DataPacker.getIntelShort(m_smbbuf, UID); 447 } 448 449 452 private final void InitializeBuffer() 453 { 454 455 457 m_smbbuf[SIGNATURE] = (byte) 0xFF; 458 m_smbbuf[SIGNATURE + 1] = (byte) 'S'; 459 m_smbbuf[SIGNATURE + 2] = (byte) 'M'; 460 m_smbbuf[SIGNATURE + 3] = (byte) 'B'; 461 } 462 463 468 public final boolean isResponse() 469 { 470 int resp = getFlags(); 471 if ((resp & FLG_RESPONSE) != 0) 472 return true; 473 return false; 474 } 475 476 481 public final boolean isValidResponse() 482 { 483 484 486 if (isResponse() && getCommand() == m_pkttype) 487 { 488 489 491 if ((getFlags2() & FLG2_LONGERRORCODE) == 0) 492 { 493 if (getErrorClass() == SMBStatus.Success) 494 return true; 495 } 496 else if (getLongErrorCode() == SMBStatus.NTSuccess) 497 return true; 498 } 499 return false; 500 } 501 502 507 public final void packByte(byte val) 508 { 509 m_smbbuf[m_pos++] = val; 510 } 511 512 517 public final void packByte(int val) 518 { 519 m_smbbuf[m_pos++] = (byte) val; 520 } 521 522 528 public final void packBytes(byte[] byts, int len) 529 { 530 for (int i = 0; i < len; i++) 531 m_smbbuf[m_pos++] = byts[i]; 532 } 533 534 540 public final void packString(String str, boolean uni) 541 { 542 543 545 if (uni) 546 { 547 548 550 m_pos = DataPacker.wordAlign(m_pos); 551 DataPacker.putUnicodeString(str, m_smbbuf, m_pos, true); 552 m_pos += (str.length() * 2) + 2; 553 } 554 else 555 { 556 557 559 DataPacker.putString(str, m_smbbuf, m_pos, true); 560 m_pos += str.length() + 1; 561 } 562 } 563 564 569 public final void packWord(int val) 570 { 571 DataPacker.putIntelShort(val, m_smbbuf, m_pos); 572 m_pos += 2; 573 } 574 575 580 public final void packInt(int val) 581 { 582 DataPacker.putIntelInt(val, m_smbbuf, m_pos); 583 m_pos += 4; 584 } 585 586 591 public final void packLong(long val) 592 { 593 DataPacker.putIntelLong(val, m_smbbuf, m_pos); 594 m_pos += 8; 595 } 596 597 602 public final int getPosition() 603 { 604 return m_pos; 605 } 606 607 612 public final int unpackByte() 613 { 614 return (int) m_smbbuf[m_pos++]; 615 } 616 617 623 public final byte[] unpackBytes(int len) 624 { 625 if (len <= 0) 626 return null; 627 628 byte[] buf = new byte[len]; 629 System.arraycopy(m_smbbuf, m_pos, buf, 0, len); 630 m_pos += len; 631 return buf; 632 } 633 634 639 public final int unpackWord() 640 { 641 int val = DataPacker.getIntelShort(m_smbbuf, m_pos); 642 m_pos += 2; 643 return val; 644 } 645 646 651 public final int unpackInt() 652 { 653 int val = DataPacker.getIntelInt(m_smbbuf, m_pos); 654 m_pos += 4; 655 return val; 656 } 657 658 663 public final long unpackLong() 664 { 665 long val = DataPacker.getIntelLong(m_smbbuf, m_pos); 666 m_pos += 8; 667 return val; 668 } 669 670 676 public final String unpackString(boolean uni) 677 { 678 679 681 String ret = null; 682 683 if (uni) 684 { 685 686 688 m_pos = DataPacker.wordAlign(m_pos); 689 ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, 255); 690 if (ret != null) 691 m_pos += (ret.length() * 2) + 2; 692 } 693 else 694 { 695 696 698 ret = DataPacker.getString(m_smbbuf, m_pos, 255); 699 if (ret != null) 700 m_pos += ret.length() + 1; 701 } 702 703 705 return ret; 706 } 707 708 715 public final String unpackString(int len, boolean uni) 716 { 717 718 720 String ret = null; 721 722 if (uni) 723 { 724 725 727 m_pos = DataPacker.wordAlign(m_pos); 728 ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, len); 729 if (ret != null) 730 m_pos += (ret.length() * 2); 731 } 732 else 733 { 734 735 737 ret = DataPacker.getString(m_smbbuf, m_pos, len); 738 if (ret != null) 739 m_pos += ret.length(); 740 } 741 742 744 return ret; 745 } 746 747 752 public final boolean hasMoreData() 753 { 754 if (m_pos < m_endpos) 755 return true; 756 return false; 757 } 758 759 765 private final void ReceiveSMB(NetBIOSSession sess) throws java.io.IOException 766 { 767 768 if (sess.Receive(m_smbbuf, RFCNetBIOSProtocol.TMO) >= MIN_RXLEN) 769 return; 770 771 773 throw new java.io.IOException ("Short NetBIOS receive"); 774 } 775 776 781 public final void setAndXCommand(int cmd) 782 { 783 784 786 m_smbbuf[ANDXCOMMAND] = (byte) cmd; 787 m_smbbuf[ANDXRESERVED] = (byte) 0; 788 789 791 if (cmd == PacketType.NoChainedCommand) 792 setParameter(1, 0); 793 } 794 795 800 public final void setByteCount(int cnt) 801 { 802 int offset = getByteOffset() - 2; 803 DataPacker.putIntelShort(cnt, m_smbbuf, offset); 804 } 805 806 809 810 public final void setByteCount() 811 { 812 int offset = getByteOffset() - 2; 813 int len = m_pos - getByteOffset(); 814 DataPacker.putIntelShort(len, m_smbbuf, offset); 815 } 816 817 822 public final void setBytes(byte[] byts) 823 { 824 int offset = getByteOffset() - 2; 825 DataPacker.putIntelShort(byts.length, m_smbbuf, offset); 826 827 offset += 2; 828 829 for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++]) 830 ; 831 } 832 833 838 public final void setCommand(int cmd) 839 { 840 m_pkttype = cmd; 841 m_smbbuf[COMMAND] = (byte) cmd; 842 } 843 844 849 public final void setErrorClass(int cl) 850 { 851 m_smbbuf[ERRORCLASS] = (byte) (cl & 0xFF); 852 } 853 854 859 public final void setErrorCode(int sts) 860 { 861 m_smbbuf[ERROR] = (byte) (sts & 0xFF); 862 } 863 864 869 public final void setFlags(int flg) 870 { 871 m_smbbuf[FLAGS] = (byte) flg; 872 } 873 874 879 public final void setFlags2(int flg) 880 { 881 DataPacker.putIntelShort(flg, m_smbbuf, FLAGS2); 882 } 883 884 889 public final void setMultiplexId(int mid) 890 { 891 DataPacker.putIntelShort(mid, m_smbbuf, MID); 892 } 893 894 900 public final void setParameter(int idx, int val) 901 { 902 int pos = WORDCNT + (2 * idx) + 1; 903 DataPacker.putIntelShort(val, m_smbbuf, pos); 904 } 905 906 912 913 public final void setParameterLong(int idx, int val) 914 { 915 int pos = WORDCNT + (2 * idx) + 1; 916 DataPacker.putIntelInt(val, m_smbbuf, pos); 917 } 918 919 924 public final void setParameterCount(int cnt) 925 { 926 m_smbbuf[WORDCNT] = (byte) cnt; 927 } 928 929 934 public final void setProcessId(int pid) 935 { 936 DataPacker.putIntelShort(pid, m_smbbuf, PID); 937 } 938 939 944 public final void setSeqNo(int seq) 945 { 946 DataPacker.putIntelShort(seq, m_smbbuf, SEQNO); 947 } 948 949 954 public final void setSID(int sid) 955 { 956 DataPacker.putIntelShort(sid, m_smbbuf, SID); 957 } 958 959 964 public final void setTreeId(int tid) 965 { 966 DataPacker.putIntelShort(tid, m_smbbuf, TID); 967 } 968 969 974 public final void setUserId(int uid) 975 { 976 DataPacker.putIntelShort(uid, m_smbbuf, UID); 977 } 978 979 982 public final void alignBytePointer() 983 { 984 m_pos = DataPacker.longwordAlign(m_pos); 985 } 986 987 990 public final void resetBytePointer() 991 { 992 m_pos = getByteOffset(); 993 m_endpos = m_pos + getByteCount(); 994 } 995 996 1000 public final void resetBytePointerAlign() 1001 { 1002 m_pos = DataPacker.longwordAlign(getByteOffset()); 1003 m_endpos = m_pos + getByteCount(); 1004 } 1005 1006 1009 public final void resetParameterPointer() 1010 { 1011 m_pos = PARAMWORDS; 1012 } 1013 1014 1020 public final void setBytePointer(int off, int len) 1021 { 1022 m_pos = off; 1023 m_endpos = m_pos + len; 1024 } 1025 1026 1031 public final void skipBytes(int cnt) 1032 { 1033 m_pos += cnt; 1034 } 1035} | Popular Tags |