2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-06-27 05:23:13 +00:00

Add project files.

This commit is contained in:
Ahmed Zamil
2017-09-15 23:40:03 +03:00
parent 4c95cb1cc6
commit 7ae722ab51
99 changed files with 14687 additions and 0 deletions

View File

@ -0,0 +1,287 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Misc;
using Esiur.Data;
using System.Net;
namespace Esiur.Net.Packets
{
public class HTTPRequestPacket : Packet
{
public enum HTTPMethod:byte
{
GET,
POST,
HEAD,
PUT,
DELETE,
OPTIONS,
TRACE,
CONNECT,
UNKNOWN
}
public StringKeyList Query;
public HTTPMethod Method;
public StringKeyList Headers;
public bool WSMode;
public string Version;
public StringKeyList Cookies; // String
public string URL; /// With query
public string Filename; /// Without query
//public byte[] PostContents;
public KeyList<string, object> PostForms;
public byte[] Message;
private HTTPMethod getMethod(string method)
{
switch (method.ToLower())
{
case "get":
return HTTPMethod.GET;
case "post":
return HTTPMethod.POST;
case "head":
return HTTPMethod.HEAD;
case "put":
return HTTPMethod.PUT;
case "delete":
return HTTPMethod.DELETE;
case "options":
return HTTPMethod.OPTIONS;
case "trace":
return HTTPMethod.TRACE;
case "connect":
return HTTPMethod.CONNECT;
default:
return HTTPMethod.UNKNOWN;
}
}
public override string ToString()
{
return "HTTPRequestPacket"
+ "\n\tVersion: " + Version
+ "\n\tMethod: " + Method
+ "\n\tURL: " + URL
+ "\n\tMessage: " + (Message != null ? Message.Length.ToString() : "NULL");
}
public override long Parse(byte[] data, uint offset, uint ends)
{
string[] sMethod = null;
string[] sLines = null;
uint headerSize = 0;
for (uint i = offset; i < ends - 3; i++)
{
if (data[i] == '\r' && data[i + 1] == '\n'
&& data[i + 2] == '\r' && data[i + 3] == '\n')
{
sLines = Encoding.ASCII.GetString(data, (int)offset,(int)( i - offset)).Split(new string[] { "\r\n" },
StringSplitOptions.None);
headerSize = i + 4;
break;
}
}
if (headerSize == 0)
return -1;
Cookies = new StringKeyList();
PostForms = new KeyList<string, object>();
Query = new StringKeyList();
Headers = new StringKeyList();
sMethod = sLines[0].Split(' ');
Method = getMethod(sMethod[0].Trim());
if (sMethod.Length == 3)
{
sMethod[1] = WebUtility.UrlDecode(sMethod[1]);
if (sMethod[1].Length >= 7)
{
if (sMethod[1].Substring(0, 7) == "http://")
{
sMethod[1] = sMethod[1].Substring(sMethod[1].IndexOf("/", 7));
}
}
URL = sMethod[1].Trim();
if (URL.IndexOf("?", 0) != -1)
{
Filename = URL.Split(new char[] { '?' }, 2)[0];
}
else
{
Filename = URL;
}
if (Filename.IndexOf("%", 0) != -1)
{
Filename = WebUtility.UrlDecode(Filename);
}
Version = sMethod[2].Trim();
}
// Read all headers
for (int i = 1; i < sLines.Length; i++)
{
if (sLines[i] == String.Empty)
{
// Invalid header
return 0;
}
if (sLines[i].IndexOf(':') == -1)
{
// Invalid header
return 0;
}
string[] header = sLines[i].Split(new char[] { ':' }, 2);
header[0] = header[0].ToLower();
Headers[header[0]] = header[1].Trim();
if (header[0] == "cookie")
{
string[] cookies = header[1].Split(';');
foreach (string cookie in cookies)
{
if (cookie.IndexOf('=') != -1)
{
string[] splitCookie = cookie.Split('=');
splitCookie[0] = splitCookie[0].Trim();
splitCookie[1] = splitCookie[1].Trim();
if (!(Cookies.ContainsKey(splitCookie[0].Trim())))
Cookies.Add(splitCookie[0], splitCookie[1]);
}
else
{
if (!(Cookies.ContainsKey(cookie.Trim())))
{
Cookies.Add(cookie.Trim(), String.Empty);
}
}
}
}
}
// Query String
if (URL.IndexOf("?", 0) != -1)
{
string[] SQ = URL.Split(new char[] { '?' }, 2)[1].Split('&');
foreach (string S in SQ)
{
if (S.IndexOf("=", 0) != -1)
{
string[] qp = S.Split(new char[] { '=' }, 2);
if (!Query.ContainsKey(WebUtility.UrlDecode(qp[0])))
{
Query.Add(WebUtility.UrlDecode(qp[0]), WebUtility.UrlDecode(qp[1]));
}
}
else
{
if (!(Query.ContainsKey(WebUtility.UrlDecode(S))))
{
Query.Add(WebUtility.UrlDecode(S), null);
}
}
}
}
// Post Content-Length
if (Method == HTTPMethod.POST)
{
try
{
uint postSize = uint.Parse((string)Headers["content-length"]);
// check limit
if (postSize > data.Length - headerSize)
return postSize - (data.Length - headerSize);
if (Headers["content-type"] == "application/x-www-form-urlencoded"
|| Headers["content-type"] == ""
|| Headers["content-type"] == null)
{
string[] PostVars = null;
PostVars = Encoding.UTF8.GetString(data, (int)headerSize, (int)postSize).Split('&');
for (int J = 0; J < PostVars.Length; J++)
{
if (PostVars[J].IndexOf("=") != -1)
{
string key = WebUtility.HtmlDecode(
WebUtility.UrlDecode(PostVars[J].Split(new char[] { '=' }, 2)[0]));
if (PostForms.Contains(key))
PostForms[key] = WebUtility.HtmlDecode(
WebUtility.UrlDecode(PostVars[J].Split(new char[] { '=' }, 2)[1]));
else
PostForms.Add(key, WebUtility.HtmlDecode(
WebUtility.UrlDecode(PostVars[J].Split(new char[] { '=' }, 2)[1])));
}
else
if (PostForms.Contains("unknown"))
PostForms["unknown"] = PostForms["unknown"]
+ "&" + WebUtility.HtmlDecode(WebUtility.UrlDecode(PostVars[J]));
else
PostForms.Add("unknown", WebUtility.HtmlDecode(WebUtility.UrlDecode(PostVars[J])));
}
}
else if (Headers["content-type"].StartsWith("multipart/form-data"))
{
int st = 1;
int ed = 0;
string strBoundry = "--" + Headers["content-type"].Substring(
Headers["content-type"].IndexOf("boundary=", 0) + 9);
string[] sc = Encoding.UTF8.GetString(data, (int)headerSize, (int)postSize).Split(
new string[] { strBoundry }, StringSplitOptions.None);
for (int j = 1; j < sc.Length - 1; j++)
{
string[] ps = sc[j].Split(new string[] { "\r\n\r\n" }, 2, StringSplitOptions.None);
ps[1] = ps[1].Substring(0, ps[1].Length - 2); // remove the empty line
st = ps[0].IndexOf("name=", 0) + 6;
ed = ps[0].IndexOf("\"", st);
PostForms.Add(ps[0].Substring(st, ed - st), ps[1]);
}
}
else
{
//PostForms.Add(Headers["content-type"], Encoding.Default.GetString( ));
Message = DC.Clip(data, headerSize, postSize);
}
return headerSize + postSize;
}
catch
{
return 0;
}
}
return headerSize;
}
}
}

View File

@ -0,0 +1,284 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Misc;
using Esiur.Data;
namespace Esiur.Net.Packets
{
public class HTTPResponsePacket : Packet
{
public enum ComposeOptions : int
{
AllCalculateLength,
AllDontCalculateLength,
SpecifiedHeadersOnly,
DataOnly
}
public enum ResponseCode : int
{
HTTP_SWITCHING = 101,
HTTP_OK = 200,
HTTP_NOTFOUND = 404,
HTTP_SERVERERROR = 500,
HTTP_MOVED = 301,
HTTP_NOTMODIFIED = 304,
HTTP_REDIRECT = 307
}
public class HTTPCookie
{
public string Name;
public string Value;
public DateTime Expires;
public string Path;
public bool HttpOnly;
public string Domain;
public HTTPCookie(string Name, string Value)
{
this.Name = Name;
this.Value = Value;
}
public HTTPCookie(string Name, string Value, DateTime Expires)
{
this.Name = Name;
this.Value = Value;
this.Expires = Expires;
}
public override string ToString()
{
//Set-Cookie: ckGeneric=CookieBody; expires=Sun, 30-Dec-2001 21:00:00 GMT; domain=.com.au; path=/
//Set-Cookie: SessionID=another; expires=Fri, 29 Jun 2006 20:47:11 UTC; path=/
string Cookie = Name + "=" + Value;
if (Expires.Ticks != 0)
{
Cookie += "; expires=" + Expires.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss") + " GMT";
}
if (Domain != null)
{
Cookie += "; domain=" + Domain;
}
if (Path != null)
{
Cookie += "; path=" + Path;
}
if (HttpOnly)
{
Cookie += "; HttpOnly";
}
return Cookie;
}
}
public StringKeyList Headers = new StringKeyList(true);
public string Version = "HTTP/1.1";
public byte[] Message;
public ResponseCode Number;
public string Text;
//public DStringDictionary Cookies;
public List<HTTPCookie> Cookies = new List<HTTPCookie>();
public bool Handled;
//public bool ResponseHandled; //flag this as true if you are handling it yourself
//private bool createSession;
//private HTTPServer Server;
//public HTTPSession Session;
public override string ToString()
{
return "HTTPResponsePacket"
+ "\n\tVersion: " + Version
//+ "\n\tMethod: " + Method
//+ "\n\tURL: " + URL
+ "\n\tMessage: " + (Message != null ? Message.Length.ToString() : "NULL");
}
private string MakeHeader(ComposeOptions Options)
{
string header = Version + " " + (int)Number + " " + Text + "\r\n"
+ "Server: Delta Web Server\r\n"
//Fri, 30 Oct 2007 14:19:41 GMT"
+ "Date: " + DateTime.Now.ToUniversalTime().ToString("r") + "\r\n";
if (Options == ComposeOptions.AllCalculateLength && Message != null)
{
Headers["Content-Length"] = Message.Length.ToString();
}
foreach (var kv in Headers)
{
header += kv.Key + ": " + kv.Value + "\r\n";
}
// Set-Cookie: ckGeneric=CookieBody; expires=Sun, 30-Dec-2007 21:00:00 GMT; path=/
// Set-Cookie: ASPSESSIONIDQABBDSQA=IPDPMMMALDGFLMICEJIOCIPM; path=/
foreach (var Cookie in Cookies)
{
header += "Set-Cookie: " + Cookie.ToString() + "\r\n";
}
header += "\r\n";
return header;
}
public bool Compose(ComposeOptions options)
{
List<byte> msg = new List<byte>();
if (options != ComposeOptions.DataOnly)
{
msg.AddRange(Encoding.UTF8.GetBytes(MakeHeader(options)));
}
if (options != ComposeOptions.SpecifiedHeadersOnly)
{
if (Message != null)
msg.AddRange(Message);
}
Data = msg.ToArray();
return true;
}
public override bool Compose()
{
return Compose(ComposeOptions.AllDontCalculateLength);
}
public override long Parse(byte[] data, uint offset, uint ends)
{
string[] sMethod = null;
string[] sLines = null;
uint headerSize = 0;
for (uint i = offset; i < ends - 3; i++)
{
if (data[i] == '\r' && data[i + 1] == '\n'
&& data[i + 2] == '\r' && data[i + 3] == '\n')
{
sLines = Encoding.ASCII.GetString(data, (int)offset, (int)(i - offset)).Split(new string[] { "\r\n" },
StringSplitOptions.None);
headerSize = i + 4;
break;
}
}
if (headerSize == 0)
return -1;
//Cookies = new DStringDictionary();
//Headers = new DStringDictionary(true);
sMethod = sLines[0].Split(' ');
if (sMethod.Length == 3)
{
Version = sMethod[0].Trim();
Number = (ResponseCode)(Convert.ToInt32(sMethod[1].Trim()));
Text = sMethod[2];
}
// Read all headers
for (int i = 1; i < sLines.Length; i++)
{
if (sLines[i] == String.Empty)
{
// Invalid header
return 0;
}
if (sLines[i].IndexOf(':') == -1)
{
// Invalid header
return 0;
}
string[] header = sLines[i].Split(new char[] { ':' }, 2);
header[0] = header[0].ToLower();
Headers[header[0]] = header[1].Trim();
//Set-Cookie: NAME=VALUE; expires=DATE;
if (header[0] == "set-cookie")
{
string[] cookie = header[1].Split(';');
if (cookie.Length >= 1)
{
string[] splitCookie = cookie[0].Split('=');
HTTPCookie c = new HTTPCookie(splitCookie[0], splitCookie[1]);
for (int j = 1; j < cookie.Length; j++)
{
splitCookie = cookie[j].Split('=');
switch (splitCookie[0].ToLower())
{
case "domain":
c.Domain = splitCookie[1];
break;
case "path":
c.Path = splitCookie[1];
break;
case "httponly":
c.HttpOnly = true;
break;
case "expires":
// Wed, 13-Jan-2021 22:23:01 GMT
c.Expires = DateTime.Parse(splitCookie[1]);
break;
}
}
}
}
}
// Content-Length
try
{
uint contentLength = uint.Parse((string)Headers["content-length"]);
// check limit
if (contentLength > data.Length - headerSize)
{
return contentLength - (data.Length - headerSize);
}
Message = DC.Clip(data, offset, contentLength);
return headerSize + contentLength;
}
catch
{
return 0;
}
}
}
}

View File

@ -0,0 +1,382 @@
 using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Net.Packets
{
class IIPAuthPacket : Packet
{
public enum IIPAuthPacketCommand: byte
{
Action = 0,
Declare,
Acknowledge,
Error,
}
public enum IIPAuthPacketAction: byte
{
// Authenticate
AuthenticateHash,
//Challenge,
//CertificateRequest,
//CertificateReply,
//EstablishRequest,
//EstablishReply
NewConnection = 0x20,
ResumeConnection,
ConnectionEstablished = 0x28
}
public enum IIPAuthPacketMethod: byte
{
None,
Certificate,
Credentials,
Token
}
public IIPAuthPacketCommand Command
{
get;
set;
}
public IIPAuthPacketAction Action
{
get;
set;
}
public byte ErrorCode { get; set; }
public string ErrorMessage { get; set; }
public IIPAuthPacketMethod LocalMethod
{
get;
set;
}
public byte[] SourceInfo
{
get;
set;
}
public byte[] Hash
{
get;
set;
}
public byte[] SessionId
{
get;
set;
}
public IIPAuthPacketMethod RemoteMethod
{
get;
set;
}
public string Domain
{
get;
set;
}
public long CertificateId
{
get;set;
}
public string LocalUsername
{
get;
set;
}
public string RemoteUsername
{
get;
set;
}
public byte[] LocalPassword
{
get;
set;
}
public byte[] RemotePassword
{
get;
set;
}
public byte[] LocalToken
{
get;
set;
}
public byte[] RemoteToken
{
get;
set;
}
public byte[] AsymetricEncryptionKey
{
get;
set;
}
public byte[] LocalNonce
{
get;
set;
}
public byte[] RemoteNonce
{
get;
set;
}
private uint dataLengthNeeded;
bool NotEnough(uint offset, uint ends, uint needed)
{
if (offset + needed > ends)
{
dataLengthNeeded = needed - (ends - offset);
return true;
}
else
return false;
}
public override string ToString()
{
return Command.ToString() + " " + Action.ToString();
}
public override long Parse(byte[] data, uint offset, uint ends)
{
var oOffset = offset;
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
Command = (IIPAuthPacketCommand)(data[offset] >> 6);
if (Command == IIPAuthPacketCommand.Action)
{
Action = (IIPAuthPacketAction)(data[offset++] & 0x3f);
if (Action == IIPAuthPacketAction.AuthenticateHash)
{
if (NotEnough(offset, ends, 32))
return -dataLengthNeeded;
Hash = data.Clip(offset, 32);
//var hash = new byte[32];
//Buffer.BlockCopy(data, (int)offset, hash, 0, 32);
//Hash = hash;
offset += 32;
}
else if (Action == IIPAuthPacketAction.NewConnection)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var length = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, length))
return -dataLengthNeeded;
SourceInfo = data.Clip(offset, length);
//var sourceInfo = new byte[length];
//Buffer.BlockCopy(data, (int)offset, sourceInfo, 0, length);
//SourceInfo = sourceInfo;
offset += 32;
}
else if (Action == IIPAuthPacketAction.ResumeConnection
|| Action == IIPAuthPacketAction.ConnectionEstablished)
{
//var sessionId = new byte[32];
if (NotEnough(offset, ends, 32))
return -dataLengthNeeded;
SessionId = data.Clip(offset, 32);
//Buffer.BlockCopy(data, (int)offset, sessionId, 0, 32);
//SessionId = sessionId;
offset += 32;
}
}
else if (Command == IIPAuthPacketCommand.Declare)
{
RemoteMethod = (IIPAuthPacketMethod)((data[offset] >> 4) & 0x3);
LocalMethod = (IIPAuthPacketMethod)((data[offset] >> 2) & 0x3);
var encrypt = ((data[offset++] & 0x2) == 0x2);
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
var domainLength = data[offset++];
if (NotEnough(offset, ends, domainLength))
return -dataLengthNeeded;
var domain = data.GetString(offset, domainLength);
Domain = domain;
offset += domainLength;
if (RemoteMethod == IIPAuthPacketMethod.Credentials)
{
if (LocalMethod == IIPAuthPacketMethod.None)
{
if (NotEnough(offset, ends, 33))
return -dataLengthNeeded;
//var remoteNonce = new byte[32];
//Buffer.BlockCopy(data, (int)offset, remoteNonce, 0, 32);
//RemoteNonce = remoteNonce;
RemoteNonce = data.Clip(offset, 32);
offset += 32;
var length = data[offset++];
if (NotEnough(offset, ends, length))
return -dataLengthNeeded;
RemoteUsername = data.GetString(offset, length);
offset += length;
}
}
if (encrypt)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var keyLength = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, keyLength))
return -dataLengthNeeded;
//var key = new byte[keyLength];
//Buffer.BlockCopy(data, (int)offset, key, 0, keyLength);
//AsymetricEncryptionKey = key;
AsymetricEncryptionKey = data.Clip(offset, keyLength);
offset += keyLength;
}
}
else if (Command == IIPAuthPacketCommand.Acknowledge)
{
RemoteMethod = (IIPAuthPacketMethod)((data[offset] >> 4) & 0x3);
LocalMethod = (IIPAuthPacketMethod)((data[offset] >> 2) & 0x3);
var encrypt = ((data[offset++] & 0x2) == 0x2);
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
if (RemoteMethod == IIPAuthPacketMethod.Credentials)
{
if (LocalMethod == IIPAuthPacketMethod.None)
{
if (NotEnough(offset, ends, 32))
return -dataLengthNeeded;
/*
var remoteNonce = new byte[32];
Buffer.BlockCopy(data, (int)offset, remoteNonce, 0, 32);
RemoteNonce = remoteNonce;
*/
RemoteNonce = data.Clip(offset, 32);
offset += 32;
}
}
if (encrypt)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var keyLength = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, keyLength))
return -dataLengthNeeded;
//var key = new byte[keyLength];
//Buffer.BlockCopy(data, (int)offset, key, 0, keyLength);
//AsymetricEncryptionKey = key;
AsymetricEncryptionKey = data.Clip(offset, keyLength);
offset += keyLength;
}
}
else if (Command == IIPAuthPacketCommand.Error)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
offset++;
ErrorCode = data[offset++];
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ErrorMessage = data.GetString(offset, cl);
offset += cl;
}
return offset - oOffset;
}
}
}

View File

@ -0,0 +1,550 @@
 using Esiur.Data;
using Esiur.Engine;
using Esiur.Misc;
using Esiur.Net.Packets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Net.Packets
{
class IIPPacket : Packet
{
public enum IIPPacketCommand : byte
{
Event = 0,
Request,
Reply,
Error,
}
public enum IIPPacketEvent: byte
{
// Event Manage
ResourceReassigned = 0,
ResourceDestroyed,
// Event Invoke
PropertyUpdated = 0x10,
EventOccured,
}
public enum IIPPacketAction : byte
{
// Request Manage
AttachResource = 0,
ReattachResource,
DetachResource,
CreateResource,
DeleteResource,
// Request Inquire
TemplateFromClassName = 0x8,
TemplateFromClassId,
TemplateFromResourceLink,
TemplateFromResourceId,
ResourceIdFromResourceLink,
// Request Invoke
InvokeFunction = 0x10,
GetProperty,
GetPropertyIfModified,
SetProperty,
}
public IIPPacketCommand Command
{
get;
set;
}
public IIPPacketAction Action
{
get;
set;
}
public IIPPacketEvent Event
{
get;
set;
}
public uint ResourceId { get; set; }
public uint NewResourceId { get; set; }
public uint ResourceAge { get; set; }
public byte[] Content { get; set; }
public byte ErrorCode { get; set; }
public string ErrorMessage { get; set; }
public string ClassName { get; set; }
public string ResourceLink { get; set; }
public Guid ClassId { get; set; }
public byte MethodIndex { get; set; }
public string MethodName { get; set; }
public uint CallbackId { get; set; }
private uint dataLengthNeeded;
public override bool Compose()
{
return base.Compose();
}
bool NotEnough(uint offset, uint ends, uint needed)
{
if (offset + needed > ends)
{
dataLengthNeeded = needed - (ends - offset);
return true;
}
else
return false;
}
public override long Parse(byte[] data, uint offset, uint ends)
{
var oOffset = offset;
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
Command = (IIPPacketCommand)(data[offset] >> 6);
if (Command == IIPPacketCommand.Event)
{
Event = (IIPPacketEvent)(data[offset++] & 0x3f);
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else
{
Action = (IIPPacketAction)(data[offset++] & 0x3f);
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
CallbackId = data.GetUInt32(offset);
offset += 4;
}
if (Command == IIPPacketCommand.Event)
{
if (Event == IIPPacketEvent.ResourceReassigned)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
NewResourceId = data.GetUInt32( offset);
offset += 4;
}
else if (Event == IIPPacketEvent.ResourceDestroyed)
{
// nothing to parse
}
else if (Event == IIPPacketEvent.PropertyUpdated)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
MethodIndex = data[offset++];
var dt = (DataType)data[offset++];
var size = dt.Size();// Codec.SizeOf(dt);
if (size < 0)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32( offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip( offset - 5, cl + 5);
offset += cl;
}
else
{
if (NotEnough(offset, ends, (uint)size))
return -dataLengthNeeded;
Content = data.Clip(offset - 1, (uint)size + 1);
offset += (uint)size;
}
}
else if (Event == IIPPacketEvent.EventOccured)
{
if (NotEnough(offset, ends, 5))
return -dataLengthNeeded;
MethodIndex = data[offset++];
var cl = data.GetUInt32( offset);
offset += 4;
Content = data.Clip( offset, cl);
offset += cl;
}
}
else if (Command == IIPPacketCommand.Request)
{
if (Action == IIPPacketAction.AttachResource)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.ReattachResource)
{
if (NotEnough(offset, ends, 8))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
ResourceAge = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.DetachResource)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.CreateResource)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
var cl = data[offset++];
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ClassName = data.GetString(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.DeleteResource)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.TemplateFromClassName)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
var cl = data[offset++];
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ClassName = data.GetString(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.TemplateFromClassId)
{
if (NotEnough(offset, ends, 16))
return -dataLengthNeeded;
ClassId = data.GetGuid(offset);
offset += 16;
}
else if (Action == IIPPacketAction.TemplateFromResourceLink)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ResourceLink = data.GetString(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.TemplateFromResourceId)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.ResourceIdFromResourceLink)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ResourceLink = data.GetString(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.InvokeFunction)
{
if (NotEnough(offset, ends, 9))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
MethodIndex = data[offset++];
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.GetProperty)
{
if (NotEnough(offset, ends, 5))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
MethodIndex = data[offset++];
}
else if (Action == IIPPacketAction.GetPropertyIfModified)
{
if (NotEnough(offset, ends, 9))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
MethodIndex = data[offset++];
ResourceAge = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.SetProperty)
{
if (NotEnough(offset, ends, 6))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
MethodIndex = data[offset++];
var dt = (DataType)data[offset++];
var size = dt.Size();// Codec.SizeOf(dt);
if (size < 0)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset-5, cl + 5);
offset += cl;
}
else
{
if (NotEnough(offset, ends, (uint)size))
return -dataLengthNeeded;
Content = data.Clip(offset-1, (uint)size + 1);
offset += (uint)size;
}
}
}
else if (Command == IIPPacketCommand.Reply)
{
if (Action == IIPPacketAction.AttachResource
|| Action == IIPPacketAction.ReattachResource)
{
if (NotEnough(offset, ends, 26))
return -dataLengthNeeded;
ClassId = data.GetGuid(offset);
offset += 16;
ResourceAge = data.GetUInt32(offset);
offset += 4;
uint cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ResourceLink = data.GetString(offset, cl);
offset += cl;
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.DetachResource)
{
// nothing to do
}
else if (Action == IIPPacketAction.CreateResource)
{
if (NotEnough(offset, ends, 20))
return -dataLengthNeeded;
ClassId = data.GetGuid(offset);
offset += 16;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.DetachResource)
{
// nothing to do
}
else if (Action == IIPPacketAction.TemplateFromClassName
|| Action == IIPPacketAction.TemplateFromClassId
|| Action == IIPPacketAction.TemplateFromResourceLink
|| Action == IIPPacketAction.TemplateFromResourceId)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.ResourceIdFromResourceLink)
{
if (NotEnough(offset, ends, 24))
return -dataLengthNeeded;
ClassId = data.GetGuid(offset);
offset += 16;
ResourceId = data.GetUInt32(offset);
offset += 4;
ResourceAge = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.InvokeFunction
|| Action == IIPPacketAction.GetProperty
|| Action == IIPPacketAction.GetPropertyIfModified)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
var dt = (DataType)data[offset++];
var size = dt.Size();// Codec.SizeOf(dt);
if (size < 0)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset - 5, cl + 5);
offset += cl;
}
else
{
if (NotEnough(offset, ends, (uint)size))
return -dataLengthNeeded;
Content = data.Clip(offset - 1, (uint)size + 1);
offset += (uint)size;
}
}
else if (Action == IIPPacketAction.SetProperty)
{
// nothing to do
}
}
else if (Command == IIPPacketCommand.Error)
{
// Error
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
CallbackId = data.GetUInt32(offset);
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
ErrorCode = data[offset++];
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ErrorMessage = data.GetString(offset, cl);
offset += cl;
}
return offset - oOffset;
}
}
}

367
Esiur/Net/Packets/Packet.cs Normal file
View File

@ -0,0 +1,367 @@
/******************************************************************************\
* Uruky Sniffer Project *
* *
* Copyright (C) 2006 Ahmed Khalaf - ahmed@uruky.com *
* ahmed_baghdad@yahoo.com *
* http://www.uruky.com *
* http://www.dijlh.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2, or (at your option) *
* any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
* *
* File: Packet.cs *
* Description: Ethernet/ARP/IPv4/TCP/UDP Packet Decoding & Encoding Class *
* Compatibility: .Net Framework 2.0 / Mono 1.1.8 *
* *
\******************************************************************************/
using System;
using System.Text;
using Esiur.Misc;
using Esiur.Net.DataLink;
using System.Net.NetworkInformation;
using Esiur.Data;
namespace Esiur.Net.Packets
{
internal static class Functions
{
public static void AddData(ref byte[] dest, byte[] src)
{
int I = 0;
if (src == null)
{
return;
}
if (dest != null)
{
I = dest.Length;
Array.Resize(ref dest, dest.Length + src.Length);
//dest = (byte[])Resize(dest, dest.Length + src.Length);
}
else
{
dest = new byte[src.Length];
}
Array.Copy(src, 0, dest, I, src.Length);
}
/*
public static Array Resize(Array array, int newSize)
{
Type myType = Type.GetType(array.GetType().FullName.TrimEnd('[', ']'));
Array nA = Array.CreateInstance(myType, newSize);
Array.Copy(array, nA, (newSize > array.Length ? array.Length : newSize));
return nA;
} */
//Computes the checksum used in IP, ARP..., ie the
// "The 16 bit one's complement of the one 's complement sum
//of all 16 bit words" as seen in RFCs
// Returns a 4 characters hex string
// data's lenght must be multiple of 4, else zero padding
public static ushort IP_CRC16(byte[] data)
{
ulong Sum = 0;
bool Padding = false;
/// * Padding if needed
if (data.Length % 2 != 0)
{
Array.Resize(ref data, data.Length + 1);
//data = (byte[])Resize(data, data.Length + 1);
Padding = true;
}
int count = data.Length;
///* add 16-bit words */
while (count > 0) //1)
{
///* this is the inner loop */
Sum += GetInteger(data[count - 2], data[count - 1]);
///* Fold 32-bit sum to 16-bit */
while (Sum >> 16 != 0)
{
Sum = (Sum & 0XFFFF) + (Sum >> 16);
}
count -= 2;
}
/// * reverse padding
if (Padding)
{
Array.Resize(ref data, data.Length - 1);
//data = (byte[])Resize(data, data.Length - 1);
}
///* Return one's compliment of final sum.
//return (ushort)(ushort.MaxValue - (ushort)Sum);
return (ushort)(~Sum);
}
public static ushort GetInteger(byte B1, byte B2)
{
return BitConverter.ToUInt16(new byte[] { B2, B1 }, 0);
//return System.Convert.ToUInt16("&h" + GetHex(B1) + GetHex(B2));
}
public static uint GetLong(byte B1, byte B2, byte B3, byte B4)
{
return BitConverter.ToUInt32(new byte[] { B4, B3, B2, B1 }, 0);
//return System.Convert.ToUInt32("&h" + GetHex(B1) + GetHex(B2) + GetHex(B3) + GetHex(B4));
}
public static string GetHex(byte B)
{
return (((B < 15) ? 0 + System.Convert.ToString(B, 16).ToUpper() : System.Convert.ToString(B, 16).ToUpper()));
}
public static bool GetBit(uint B, byte Pos)
{
//return BitConverter.ToBoolean(BitConverter.GetBytes(B), Pos + 1);
return (B & (uint)(Math.Pow(2, (Pos - 1)))) == (Math.Pow(2, (Pos - 1)));
}
public static ushort RemoveBit(ushort I, byte Pos)
{
return (ushort)RemoveBit((uint)I, Pos);
}
public static uint RemoveBit(uint I, byte Pos)
{
if (GetBit(I, Pos))
{
return I - (uint)(Math.Pow(2, (Pos - 1)));
}
else
{
return I;
}
}
public static void SplitInteger(ushort I, ref byte BLeft, ref byte BRight)
{
byte[] b = BitConverter.GetBytes(I);
BLeft = b[1];
BRight = b[0];
//BLeft = I >> 8;
//BRight = (I << 8) >> 8;
}
public static void SplitLong(uint I, ref byte BLeft, ref byte BLeftMiddle, ref byte BRightMiddle, ref byte BRight)
{
byte[] b = BitConverter.GetBytes(I);
BLeft = b[3];
BLeftMiddle = b[2];
BRightMiddle = b[1];
BRight = b[0];
//BLeft = I >> 24;
//BLeftMiddle = (I << 8) >> 24;
//BRightMiddle = (I << 16) >> 24;
//BRight = (I << 24) >> 24;
}
}
public class PosixTime
{
ulong seconds;
ulong microseconds;
PosixTime(ulong Seconds, ulong Microseconds)
{
seconds = Seconds;
microseconds = Microseconds;
}
public override string ToString()
{
return seconds + "." + microseconds;
}
}
public class Packet
{
//public EtherServer2.EthernetSource Source;
public PacketSource Source;
public DateTime Timestamp;
public enum PPPType : ushort
{
IP = 0x0021, // Internet Protocol version 4 [RFC1332]
SDTP = 0x0049, // Serial Data Transport Protocol (PPP-SDTP) [RFC1963]
IPv6HeaderCompression = 0x004f, // IPv6 Header Compression
IPv6 = 0x0057, // Internet Protocol version 6 [RFC5072]
W8021dHelloPacket = 0x0201, // 802.1d Hello Packets [RFC3518]
IPv6ControlProtocol = 0x8057, // IPv6 Control Protocol [RFC5072]
}
public enum ProtocolType : ushort
{
IP = 0x800, // IPv4
ARP = 0x806, // Address Resolution Protocol
IPv6 = 0x86DD, // IPv6
FrameRelayARP = 0x0808, // Frame Relay ARP [RFC1701]
VINESLoopback = 0x0BAE, // VINES Loopback [RFC1701]
VINESEcho = 0x0BAF, // VINES ECHO [RFC1701]
TransEtherBridging = 0x6558, // TransEther Bridging [RFC1701]
RawFrameRelay = 0x6559, // Raw Frame Relay [RFC1701]
IEE8021QVLAN = 0x8100, // IEEE 802.1Q VLAN-tagged frames (initially Wellfleet)
SNMP = 0x814C, // SNMP [JKR1]
TCPIP_Compression = 0x876B, // TCP/IP Compression [RFC1144]
IPAutonomousSystems = 0x876C, // IP Autonomous Systems [RFC1701]
SecureData = 0x876D, // Secure Data [RFC1701]
PPP = 0x880B, // PPP [IANA]
MPLS = 0x8847, // MPLS [RFC5332]
MPLS_UpstreamAssignedLabel = 0x8848, // MPLS with upstream-assigned label [RFC5332]
PPPoEDiscoveryStage = 0x8863, // PPPoE Discovery Stage [RFC2516]
PPPoESessionStage = 0x8864, // PPPoE Session Stage [RFC2516]
}
/*
public static void GetPacketMACAddresses(Packet packet, out byte[] srcMAC, out byte[] dstMAC)
{
// get the node address
Packet root = packet.RootPacket;
if (root is TZSPPacket)
{
TZSPPacket tp = (TZSPPacket)root;
if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.Ethernet)
{
EthernetPacket ep = (EthernetPacket)tp.SubPacket;
srcMAC = ep.SourceMAC;
dstMAC = ep.DestinationMAC;
}
else if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.IEEE802_11)
{
W802_11Packet wp = (W802_11Packet)tp.SubPacket;
srcMAC = wp.SA;
dstMAC = wp.DA;
}
else
{
srcMAC = null;
dstMAC = null;
}
}
else if (root is EthernetPacket)
{
EthernetPacket ep = (EthernetPacket)root;
srcMAC = ep.SourceMAC;
dstMAC = ep.DestinationMAC;
}
else if (root is W802_11Packet)
{
W802_11Packet wp = (W802_11Packet)root;
srcMAC = wp.SA;
dstMAC = wp.DA;
}
else
{
srcMAC = null;
dstMAC = null;
}
}
public static void GetPacketAddresses(Packet packet, ref string srcMAC, ref string dstMAC, ref string srcIP, ref string dstIP)
{
if (packet is TCPv4Packet)
{
if (packet.ParentPacket is IPv4Packet)
{
IPv4Packet ip = (IPv4Packet)packet.ParentPacket;
srcIP = ip.SourceIP.ToString();
dstIP = ip.DestinationIP.ToString();
}
}
// get the node address
Packet root = packet.RootPacket;
if (root is TZSPPacket)
{
TZSPPacket tp = (TZSPPacket)root;
if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.Ethernet)
{
EthernetPacket ep = (EthernetPacket)tp.SubPacket;
srcMAC = DC.GetPhysicalAddress(ep.SourceMAC, 0).ToString();
dstMAC = DC.GetPhysicalAddress(ep.DestinationMAC, 0).ToString();
}
else if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.IEEE802_11)
{
W802_11Packet wp = (W802_11Packet)tp.SubPacket;
srcMAC = DC.GetPhysicalAddress(wp.SA, 0).ToString();
dstMAC = DC.GetPhysicalAddress(wp.DA, 0).ToString();
}
}
else if (root is EthernetPacket)
{
EthernetPacket ep = (EthernetPacket)root;
srcMAC = DC.GetPhysicalAddress(ep.SourceMAC, 0).ToString();
dstMAC = DC.GetPhysicalAddress(ep.DestinationMAC, 0).ToString();
}
else if (root is W802_11Packet)
{
W802_11Packet wp = (W802_11Packet)root;
srcMAC = DC.GetPhysicalAddress(wp.SA, 0).ToString();
dstMAC = DC.GetPhysicalAddress(wp.DA, 0).ToString();
}
}
*/
PosixTime Timeval;
public byte[] Header;
public byte[] Preamble;
//public byte[] Payload;
public byte[] Data;
public Packet SubPacket;
public Packet ParentPacket;
public virtual long Parse(byte[] data, uint offset, uint ends) { return 0; }
public virtual bool Compose() { return false; }
public Packet RootPacket
{
get
{
Packet root = this;
while (root.ParentPacket != null)
root = root.ParentPacket;
return root;
}
}
public Packet LeafPacket
{
get
{
Packet leaf = this;
while (leaf.SubPacket != null)
leaf = leaf.SubPacket;
return leaf;
}
}
}
}
/************************************ EOF *************************************/

View File

@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Misc;
using Esiur.Data;
namespace Esiur.Net.Packets
{
public class WebsocketPacket : Packet
{
public enum WSOpcode : byte
{
ContinuationFrame = 0x0, // %x0 denotes a continuation frame
TextFrame = 0x1, // %x1 denotes a text frame
BinaryFrame = 0x2, // %x2 denotes a binary frame
// %x3-7 are reserved for further non-control frames
ConnectionClose = 0x8, // %x8 denotes a connection close
Ping = 0x9, // %x9 denotes a ping
Pong = 0xA, // %xA denotes a pong
//* %xB-F are reserved for further control frames
}
public bool FIN;
public bool RSV1;
public bool RSV2;
public bool RSV3;
public WSOpcode Opcode;
public bool Mask;
public long PayloadLength;
// public UInt32 MaskKey;
public byte[] MaskKey;
public byte[] Message;
public override string ToString()
{
return "WebsocketPacket"
+ "\n\tFIN: " + FIN
+ "\n\tOpcode: " + Opcode
+ "\n\tPayload: " + PayloadLength
+ "\n\tMaskKey: " + MaskKey
+ "\n\tMessage: " + (Message != null ? Message.Length.ToString() : "NULL");
}
public override bool Compose()
{
var pkt = new List<byte>();
pkt.Add((byte)((FIN ? 0x80 : 0x0) |
(RSV1 ? 0x40 : 0x0) |
(RSV2 ? 0x20 : 0x0) |
(RSV3 ? 0x10 : 0x0) |
(byte)Opcode));
// calculate length
if (Message.Length > UInt16.MaxValue)
// 4 bytes
{
pkt.Add((byte)((Mask ? 0x80 : 0x0) | 127));
pkt.AddRange(DC.ToBytes((UInt64)Message.LongCount()));
}
else if (Message.Length > 125)
// 2 bytes
{
pkt.Add((byte)((Mask ? 0x80 : 0x0) | 126));
pkt.AddRange(DC.ToBytes((UInt16)Message.Length));
}
else
{
pkt.Add((byte)((Mask ? 0x80 : 0x0) | Message.Length));
}
if (Mask)
{
pkt.AddRange(MaskKey);
}
pkt.AddRange(Message);
Data = pkt.ToArray();
return true;
}
public override long Parse(byte[] data, uint offset, uint ends)
{
try
{
long needed = 2;
var length = (ends - offset);
if (length < needed)
{
//Console.WriteLine("stage 1 " + needed);
return length - needed;
}
uint oOffset = offset;
FIN = ((data[offset] & 0x80) == 0x80);
RSV1 = ((data[offset] & 0x40) == 0x40);
RSV2 = ((data[offset] & 0x20) == 0x20);
RSV3 = ((data[offset] & 0x10) == 0x10);
Opcode = (WSOpcode)(data[offset++] & 0xF);
Mask = ((data[offset] & 0x80) == 0x80);
PayloadLength = (long)(data[offset++] & 0x7F);
if (Mask)
needed += 4;
if (PayloadLength == 126)
{
needed += 2;
if (length < needed)
{
//Console.WriteLine("stage 2 " + needed);
return length - needed;
}
PayloadLength = DC.GetUInt16(data, offset);
offset += 2;
}
else if (PayloadLength == 127)
{
needed += 8;
if (length < needed)
{
//Console.WriteLine("stage 3 " + needed);
return length - needed;
}
PayloadLength = DC.GetInt64(data, offset);
offset += 8;
}
if (Mask)
{
MaskKey = new byte[4];
MaskKey[0] = data[offset++];
MaskKey[1] = data[offset++];
MaskKey[2] = data[offset++];
MaskKey[3] = data[offset++];
//MaskKey = DC.GetUInt32(data, offset);
//offset += 4;
}
needed += PayloadLength;
if (length < needed)
{
//Console.WriteLine("stage 4");
return length - needed;
}
// if ((int)PayloadLength > (ends - offset))
// {
// return -((int)PayloadLength - (ends - offset));
// }
else
{
Message = DC.Clip(data, offset, (uint)PayloadLength);
if (Mask)
{
//var aMask = BitConverter.GetBytes(MaskKey);
for (int i = 0; i < Message.Length; i++)
{
Message[i] = (byte)(Message[i] ^ MaskKey[i % 4]);
}
}
return (offset - oOffset) + (int)PayloadLength;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.WriteLine(offset + "::" + DC.ToHex(data));
throw ex;
}
}
}
}