SessionPacket.cs 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Utilities;
  11. namespace SMBLibrary.NetBios
  12. {
  13. /// <summary>
  14. /// [RFC 1002] 4.3.1. SESSION PACKET
  15. /// </summary>
  16. public abstract class SessionPacket
  17. {
  18. public const int MaxSessionPacketLength = 131075;
  19. public SessionPacketTypeName Type;
  20. public byte Flags;
  21. public int Length; // 2 bytes + length extension bit
  22. public byte[] Trailer;
  23. public SessionPacket()
  24. {
  25. }
  26. public SessionPacket(byte[] buffer, int offset)
  27. {
  28. Type = (SessionPacketTypeName)ByteReader.ReadByte(buffer, offset + 0);
  29. Flags = ByteReader.ReadByte(buffer, offset + 1);
  30. Length = (Flags & 0x01) << 16 | BigEndianConverter.ToUInt16(buffer, offset + 2);
  31. this.Trailer = ByteReader.ReadBytes(buffer, offset + 4, Length);
  32. }
  33. public virtual byte[] GetBytes()
  34. {
  35. Length = this.Trailer.Length;
  36. if (Length > 0x1FFFF)
  37. {
  38. throw new ArgumentException("Invalid NBT packet length");
  39. }
  40. Flags = Convert.ToByte(Length > 0xFFFF);
  41. byte[] buffer = new byte[4 + Trailer.Length];
  42. ByteWriter.WriteByte(buffer, 0, (byte)this.Type);
  43. ByteWriter.WriteByte(buffer, 1, Flags);
  44. BigEndianWriter.WriteUInt16(buffer, 2, (ushort)(Length & 0xFFFF));
  45. ByteWriter.WriteBytes(buffer, 4, this.Trailer);
  46. return buffer;
  47. }
  48. public static SessionPacket GetSessionPacket(byte[] buffer, int offset)
  49. {
  50. SessionPacketTypeName type = (SessionPacketTypeName)ByteReader.ReadByte(buffer, offset);
  51. switch (type)
  52. {
  53. case SessionPacketTypeName.SessionMessage:
  54. return new SessionMessagePacket(buffer, offset);
  55. case SessionPacketTypeName.SessionRequest:
  56. return new SessionRequestPacket(buffer, offset);
  57. case SessionPacketTypeName.PositiveSessionResponse:
  58. return new PositiveSessionResponsePacket(buffer, offset);
  59. case SessionPacketTypeName.NegativeSessionResponse:
  60. return new NegativeSessionResponsePacket(buffer, offset);
  61. case SessionPacketTypeName.RetargetSessionResponse:
  62. return new SessionRetargetResponsePacket(buffer, offset);
  63. case SessionPacketTypeName.SessionKeepAlive:
  64. return new SessionKeepAlivePacket(buffer, offset);
  65. default:
  66. throw new InvalidRequestException("Invalid NetBIOS session packet type: 0x" + type.ToString("X"));
  67. }
  68. }
  69. }
  70. }