| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 | // This code is derived from jcifs smb client library <jcifs at samba dot org>// Ported by J. Arturo <webmaster at komodosoft dot net>//  // This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.// // This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU// Lesser General Public License for more details.// // You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USAusing System.Net;using SharpCifs.Util;using SharpCifs.Util.Sharpen;namespace SharpCifs.Netbios{	internal abstract class NameServicePacket	{		internal const int Query = 0;		internal const int Wack = 7;		internal const int FmtErr = 0x1;		internal const int SrvErr = 0x2;		internal const int ImpErr = 0x4;	    internal const int RfsErr = 0x5;		internal const int ActErr = 0x6;		internal const int CftErr = 0x7;		internal const int NbIn = 0x00200001;		internal const int NbstatIn = 0x00210001;		internal const int Nb = 0x0020;		internal const int Nbstat = 0x0021;		internal const int In = 0x0001;		internal const int A = 0x0001;		internal const int Ns = 0x0002;		internal const int Null = 0x000a;		internal const int HeaderLength = 12;		internal const int OpcodeOffset = 2;		internal const int QuestionOffset = 4;		internal const int AnswerOffset = 6;		internal const int AuthorityOffset = 8;		internal const int AdditionalOffset = 10;		// opcode		// rcode		// type/class		// header field offsets		internal static void WriteInt2(int val, byte[] dst, int dstIndex)		{			dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF)));			dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF)));		}		internal static void WriteInt4(int val, byte[] dst, int dstIndex)		{			dst[dstIndex++] = unchecked((byte)((val >> 24) & unchecked(0xFF)));			dst[dstIndex++] = unchecked((byte)((val >> 16) & unchecked(0xFF)));			dst[dstIndex++] = unchecked((byte)((val >> 8) & unchecked(0xFF)));			dst[dstIndex] = unchecked((byte)(val & unchecked(0xFF)));		}		internal static int ReadInt2(byte[] src, int srcIndex)		{			return ((src[srcIndex] & unchecked(0xFF)) << 8) + (src[srcIndex + 1] & unchecked(				0xFF));		}		internal static int ReadInt4(byte[] src, int srcIndex)		{			return ((src[srcIndex] & unchecked(0xFF)) << 24) + ((src[srcIndex + 1] & unchecked(				0xFF)) << 16) + ((src[srcIndex + 2] & unchecked(0xFF)) << 8) + (src				[srcIndex + 3] & unchecked(0xFF));		}		internal static int ReadNameTrnId(byte[] src, int srcIndex)		{			return ReadInt2(src, srcIndex);		}		internal int AddrIndex;		internal NbtAddress[] AddrEntry;		internal int NameTrnId;		internal int OpCode;		internal int ResultCode;		internal int QuestionCount;		internal int AnswerCount;		internal int AuthorityCount;		internal int AdditionalCount;		internal bool Received;		internal bool IsResponse;		internal bool IsAuthAnswer;		internal bool IsTruncated;		internal bool IsRecurDesired;		internal bool IsRecurAvailable;		internal bool IsBroadcast;		internal Name QuestionName;		internal Name RecordName;		internal int QuestionType;		internal int QuestionClass;		internal int RecordType;		internal int RecordClass;		internal int Ttl;		internal int RDataLength;		internal IPAddress Addr;		public NameServicePacket()		{			IsRecurDesired = true;			IsBroadcast = true;			QuestionCount = 1;			QuestionClass = In;		}		internal virtual int WriteWireFormat(byte[] dst, int dstIndex)		{			int start = dstIndex;			dstIndex += WriteHeaderWireFormat(dst, dstIndex);			dstIndex += WriteBodyWireFormat(dst, dstIndex);			return dstIndex - start;		}		internal virtual int ReadWireFormat(byte[] src, int srcIndex)		{			int start = srcIndex;			srcIndex += ReadHeaderWireFormat(src, srcIndex);			srcIndex += ReadBodyWireFormat(src, srcIndex);			return srcIndex - start;		}		internal virtual int WriteHeaderWireFormat(byte[] dst, int dstIndex)		{			int start = dstIndex;			WriteInt2(NameTrnId, dst, dstIndex);			dst[dstIndex + OpcodeOffset] = unchecked((byte)((IsResponse ? unchecked(0x80) : unchecked(0x00)) + ((OpCode << 3) & unchecked(0x78)) + (IsAuthAnswer				 ? unchecked(0x04) : unchecked(0x00)) + (IsTruncated ? unchecked(0x02) : unchecked(0x00)) + (IsRecurDesired ? unchecked(0x01)				 : unchecked(0x00))));			dst[dstIndex + OpcodeOffset + 1] = unchecked((byte)((IsRecurAvailable ? unchecked(				0x80) : unchecked(0x00)) + (IsBroadcast ? unchecked(0x10) : 				unchecked(0x00)) + (ResultCode & unchecked(0x0F))));			WriteInt2(QuestionCount, dst, start + QuestionOffset);			WriteInt2(AnswerCount, dst, start + AnswerOffset);			WriteInt2(AuthorityCount, dst, start + AuthorityOffset);			WriteInt2(AdditionalCount, dst, start + AdditionalOffset);			return HeaderLength;		}		internal virtual int ReadHeaderWireFormat(byte[] src, int srcIndex)		{			NameTrnId = ReadInt2(src, srcIndex);			IsResponse = ((src[srcIndex + OpcodeOffset] & unchecked(0x80)) == 0) ? false				 : true;			OpCode = (src[srcIndex + OpcodeOffset] & unchecked(0x78)) >> 3;			IsAuthAnswer = ((src[srcIndex + OpcodeOffset] & unchecked(0x04)) == 0) ? 				false : true;			IsTruncated = ((src[srcIndex + OpcodeOffset] & unchecked(0x02)) == 0) ? false				 : true;			IsRecurDesired = ((src[srcIndex + OpcodeOffset] & unchecked(0x01)) == 0) ? 				false : true;			IsRecurAvailable = ((src[srcIndex + OpcodeOffset + 1] & unchecked(0x80)) 				== 0) ? false : true;			IsBroadcast = ((src[srcIndex + OpcodeOffset + 1] & unchecked(0x10)) == 0)				 ? false : true;			ResultCode = src[srcIndex + OpcodeOffset + 1] & unchecked(0x0F);			QuestionCount = ReadInt2(src, srcIndex + QuestionOffset);			AnswerCount = ReadInt2(src, srcIndex + AnswerOffset);			AuthorityCount = ReadInt2(src, srcIndex + AuthorityOffset);			AdditionalCount = ReadInt2(src, srcIndex + AdditionalOffset);			return HeaderLength;		}		internal virtual int WriteQuestionSectionWireFormat(byte[] dst, int dstIndex)		{			int start = dstIndex;			dstIndex += QuestionName.WriteWireFormat(dst, dstIndex);			WriteInt2(QuestionType, dst, dstIndex);			dstIndex += 2;			WriteInt2(QuestionClass, dst, dstIndex);			dstIndex += 2;			return dstIndex - start;		}		internal virtual int ReadQuestionSectionWireFormat(byte[] src, int srcIndex)		{			int start = srcIndex;			srcIndex += QuestionName.ReadWireFormat(src, srcIndex);			QuestionType = ReadInt2(src, srcIndex);			srcIndex += 2;			QuestionClass = ReadInt2(src, srcIndex);			srcIndex += 2;			return srcIndex - start;		}		internal virtual int WriteResourceRecordWireFormat(byte[] dst, int dstIndex)		{			int start = dstIndex;			if (RecordName == QuestionName)			{				dst[dstIndex++] = unchecked(unchecked(0xC0));				// label string pointer to				dst[dstIndex++] = unchecked(unchecked(0x0C));			}			else			{				// questionName (offset 12)				dstIndex += RecordName.WriteWireFormat(dst, dstIndex);			}			WriteInt2(RecordType, dst, dstIndex);			dstIndex += 2;			WriteInt2(RecordClass, dst, dstIndex);			dstIndex += 2;			WriteInt4(Ttl, dst, dstIndex);			dstIndex += 4;			RDataLength = WriteRDataWireFormat(dst, dstIndex + 2);			WriteInt2(RDataLength, dst, dstIndex);			dstIndex += 2 + RDataLength;			return dstIndex - start;		}		internal virtual int ReadResourceRecordWireFormat(byte[] src, int srcIndex)		{			int start = srcIndex;			int end;			if ((src[srcIndex] & unchecked(0xC0)) == unchecked(0xC0))			{				RecordName = QuestionName;				// label string pointer to questionName				srcIndex += 2;			}			else			{				srcIndex += RecordName.ReadWireFormat(src, srcIndex);			}			RecordType = ReadInt2(src, srcIndex);			srcIndex += 2;			RecordClass = ReadInt2(src, srcIndex);			srcIndex += 2;			Ttl = ReadInt4(src, srcIndex);			srcIndex += 4;			RDataLength = ReadInt2(src, srcIndex);			srcIndex += 2;			AddrEntry = new NbtAddress[RDataLength / 6];			end = srcIndex + RDataLength;			for (AddrIndex = 0; srcIndex < end; AddrIndex++)			{				srcIndex += ReadRDataWireFormat(src, srcIndex);			}			return srcIndex - start;		}		internal abstract int WriteBodyWireFormat(byte[] dst, int dstIndex);		internal abstract int ReadBodyWireFormat(byte[] src, int srcIndex);		internal abstract int WriteRDataWireFormat(byte[] dst, int dstIndex);		internal abstract int ReadRDataWireFormat(byte[] src, int srcIndex);		public override string ToString()		{			string opCodeString;			string resultCodeString;			string questionTypeString;			string recordTypeString;			switch (OpCode)			{				case Query:				{					opCodeString = "QUERY";					break;				}				case Wack:				{					opCodeString = "WACK";					break;				}				default:				{					opCodeString = Extensions.ToString(OpCode);					break;				}			}			switch (ResultCode)			{				case FmtErr:				{					resultCodeString = "FMT_ERR";					break;				}				case SrvErr:				{					resultCodeString = "SRV_ERR";					break;				}				case ImpErr:				{					resultCodeString = "IMP_ERR";					break;				}				case RfsErr:				{					resultCodeString = "RFS_ERR";					break;				}				case ActErr:				{					resultCodeString = "ACT_ERR";					break;				}				case CftErr:				{					resultCodeString = "CFT_ERR";					break;				}				default:				{					resultCodeString = "0x" + Hexdump.ToHexString(ResultCode, 1);					break;				}			}			switch (QuestionType)			{				case Nb:				{					questionTypeString = "NB";					break;				}				case Nbstat:				{					questionTypeString = "NBSTAT";					break;				}				default:				{					questionTypeString = "0x" + Hexdump.ToHexString(QuestionType, 4);					break;				}			}			switch (RecordType)			{				case A:				{					recordTypeString = "A";					break;				}				case Ns:				{					recordTypeString = "NS";					break;				}				case Null:				{					recordTypeString = "NULL";					break;				}				case Nb:				{					recordTypeString = "NB";					break;				}				case Nbstat:				{					recordTypeString = "NBSTAT";					break;				}				default:				{					recordTypeString = "0x" + Hexdump.ToHexString(RecordType, 4);					break;				}			}			return "nameTrnId=" + NameTrnId + ",isResponse=" + IsResponse + ",opCode="				 + opCodeString + ",isAuthAnswer=" + IsAuthAnswer + ",isTruncated=" + IsTruncated				 + ",isRecurAvailable=" + IsRecurAvailable + ",isRecurDesired=" + IsRecurDesired				 + ",isBroadcast=" + IsBroadcast + ",resultCode=" + ResultCode + ",questionCount="				 + QuestionCount + ",answerCount=" + AnswerCount + ",authorityCount=" + AuthorityCount				 + ",additionalCount=" + AdditionalCount + ",questionName=" + QuestionName + ",questionType="				 + questionTypeString + ",questionClass=" + (QuestionClass == In ? "IN" : "0x" +				 Hexdump.ToHexString(QuestionClass, 4)) + ",recordName=" + RecordName + ",recordType="				 + recordTypeString + ",recordClass=" + (RecordClass == In ? "IN" : "0x" + Hexdump				.ToHexString(RecordClass, 4)) + ",ttl=" + Ttl + ",rDataLength=" + RDataLength;		}	}}
 |