aboutsummaryrefslogtreecommitdiff
path: root/Inveigh/Protocols
diff options
context:
space:
mode:
authorKevin Robertson <Kevin-Robertson@users.noreply.github.com>2021-06-15 11:04:15 -0400
committerKevin Robertson <Kevin-Robertson@users.noreply.github.com>2021-06-15 11:04:15 -0400
commit4cbf2642b024daaa5e771c7c0593bb8819f5fe93 (patch)
tree4bfc9d2fd71e111763fa5988e8bd264b67958bf4 /Inveigh/Protocols
parent670edaef3054e1b3216ff7c8942a04195e3055b8 (diff)
downloadInveigh-4cbf2642b024daaa5e771c7c0593bb8819f5fe93.tar.gz
Inveigh-4cbf2642b024daaa5e771c7c0593bb8819f5fe93.zip
Inveigh 2.02.0
Rebuilt Cross-platform (Windows, Linux, macOS) New listeners (SMB, LDAP, WebDAV, HTTPS) Improved interactive console (tab complete, real time stats)
Diffstat (limited to 'Inveigh/Protocols')
-rw-r--r--Inveigh/Protocols/LICENSE29
-rw-r--r--Inveigh/Protocols/Quiddity/Listeners/DHCPv6Listener.cs177
-rw-r--r--Inveigh/Protocols/Quiddity/Listeners/DNSListener.cs151
-rw-r--r--Inveigh/Protocols/Quiddity/Listeners/LLMNRListener.cs101
-rw-r--r--Inveigh/Protocols/Quiddity/Listeners/MDNSListener.cs117
-rw-r--r--Inveigh/Protocols/Quiddity/Listeners/NetBIOSNSListener.cs95
-rw-r--r--Inveigh/Protocols/Quiddity/Listeners/TCPListener.cs48
-rw-r--r--Inveigh/Protocols/Quiddity/Listeners/UDPListener.cs58
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DCERPC/SCMR/SCMRROpenSCManagerW.cs15
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Checker.cs150
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Message.cs86
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Packet.cs222
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option.cs39
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option1.cs88
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option14.cs86
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option16.cs90
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option2.cs95
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option23.cs97
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option24.cs95
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option3.cs107
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option39.cs128
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option5.cs77
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option6.cs87
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option8.cs88
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/Values/DHCPv6DUIDLL.cs72
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/Values/DHCPv6DUIDLLT.cs57
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DNS/DNSChecker.cs329
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DNS/DNSHeader.cs169
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DNS/DNSPacket.cs185
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DNS/DNSQuestion.cs193
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DNS/DNSResource.cs122
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordA.cs33
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordAAAA.cs34
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordSOA.cs85
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordSRV.cs42
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/GSSAPI/GSSAPIInitSecContext.cs49
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/HTTP/HTTPRequest.cs159
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/HTTP/HTTPResponse.cs166
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/ICMPv6/ICMPv6RouterAdvertisement.cs107
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/ICMPv6/Options/ICMPv6DNSSearchList.cs43
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/ICMPv6/Options/ICMPv6RecursiveDNS.cs73
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/IP/IPHeader.cs81
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/LDAPMessage.cs182
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPBindRequest.cs23
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPBindResponse.cs18
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPPartialAttributeList.cs13
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchRequest.cs46
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchResDone.cs22
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchResEntry.cs25
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPResult.cs46
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSaslCredentials.cs52
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSupportedCapabilities.cs55
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSupportedSASLMechanisms.cs56
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRChecker.cs41
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRHeader.cs130
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRPacket.cs98
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRQuestion.cs53
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRResource.cs74
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSChecker.cs84
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSHeader.cs124
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSPacket.cs99
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSQuestion.cs63
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSResource.cs39
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMChallenge.cs275
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMHelper.cs94
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMNegotiate.cs120
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMResponse.cs220
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMAVPair.cs128
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv1Response.cs39
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv2ClientChallenge.cs39
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv2Response.cs39
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSChecker.cs76
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSHeader.cs135
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSPacket.cs93
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSQuestion.cs162
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSResource.cs68
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSSessionService.cs82
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/PacketReader.cs74
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/PacketWriter.cs76
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB/Commands/SMBCOMSessionSetupAndXRequest.cs92
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB/Commands/SMBCOMSessionSetupAndXResponse.cs91
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB/SMBHeader.cs93
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB/SMBHelper.cs70
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CloseRequest.cs47
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CloseResponse.cs54
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CreateRequest.cs120
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CreateResponse.cs45
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ErrorResponse.cs48
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2FlushRequest.cs47
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2FlushResponse.cs45
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2LogoffRequest.cs45
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2LogoffResponse.cs45
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2NegotiateResponse.cs164
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2NegotiatelRequest.cs118
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2QueryDirectoryRequest.cs70
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2QueryDirectoryResponse.cs47
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ReadRequest.cs54
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ReadResponse.cs42
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2SessionSetupRequest.cs89
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2SessionSetupResponse.cs114
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeConnectRequest.cs50
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeConnectResponse.cs88
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeDisconnectRequest.cs45
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeDisconnectResponse.cs45
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2WriteRequest.cs68
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2WriteResponse.cs49
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Header.cs133
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Helper.cs124
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Packet.cs42
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SMB2/Structures/SMB2NegotiateContext.cs108
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SPNEGO/SPNEGONegTokenInit.cs64
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/SPNEGO/SPNEGONegTokenResp.cs55
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/TCP/TCPHeader.cs124
-rw-r--r--Inveigh/Protocols/Quiddity/Protocols/UDP/UDPHeader.cs130
-rw-r--r--Inveigh/Protocols/Quiddity/Support/ASN1.cs284
-rw-r--r--Inveigh/Protocols/Quiddity/Support/Utilities.cs126
-rw-r--r--Inveigh/Protocols/README.md17
117 files changed, 10480 insertions, 0 deletions
diff --git a/Inveigh/Protocols/LICENSE b/Inveigh/Protocols/LICENSE
new file mode 100644
index 0000000..cea2f49
--- /dev/null
+++ b/Inveigh/Protocols/LICENSE
@@ -0,0 +1,29 @@
+BSD 3-Clause License
+
+Copyright (c) 2021, Kevin Robertson
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Inveigh/Protocols/Quiddity/Listeners/DHCPv6Listener.cs b/Inveigh/Protocols/Quiddity/Listeners/DHCPv6Listener.cs
new file mode 100644
index 0000000..04cf106
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Listeners/DHCPv6Listener.cs
@@ -0,0 +1,177 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DHCPv6;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+
+namespace Quiddity
+{
+ public class DHCPv6Listener
+ {
+ public string DNSSuffix { get; set; }
+ public uint Lifetime { get; set; }
+ public int Prefix { get; set; }
+ public int Index { get; set; }
+
+ public DHCPv6Listener()
+ {
+ this.Index = 1;
+ this.DNSSuffix = "";
+ this.Lifetime = 300;
+ this.Prefix = (new Random()).Next(1, 9999);
+ }
+
+ public DHCPv6Listener(uint lifetime, string dnsSuffix)
+ {
+ this.Index = 1;
+ this.DNSSuffix = dnsSuffix;
+ this.Lifetime = lifetime;
+ this.Prefix = (new Random()).Next(1, 9999);
+ }
+
+ public void Start(IPAddress ipAddress, string mac, string dnsIPv6)
+ {
+ UDPListener listener = new UDPListener(AddressFamily.InterNetworkV6);
+ IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 547);
+ listener.JoinMulticastGroup(IPAddress.Parse("ff02::1:2"));
+ listener.Client.Bind(ipEndPoint);
+
+ while (true)
+ {
+
+ try
+ {
+ byte[] receiveBuffer = listener.Receive(ref ipEndPoint);
+ ProcessRequest(receiveBuffer, listener, ipEndPoint, mac, dnsIPv6);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex);
+ }
+
+ }
+
+ }
+
+ protected virtual void ProcessRequest(byte[] data, UDPListener udpListener, IPEndPoint ipEndPoint, string listenerMAC, string dnsIPv6)
+ {
+ string clientIP = ipEndPoint.Address.ToString();
+ DHCPv6Packet packet = new DHCPv6Packet(data);
+
+ if (packet.Message?.MsgType == 1 || packet.Message?.MsgType == 3 || packet.Message?.MsgType == 5)
+ {
+ bool isMicrosoft = false;
+
+ if (packet.Option16?.EnterpriseNumber == 311)
+ {
+ isMicrosoft = true;
+ }
+
+ byte msgType = 0;
+ string leaseIP = "";
+
+ switch (packet.Message.MsgType)
+ {
+ case 1:
+ msgType = 2;
+
+ break;
+
+ case 3:
+ {
+ byte[] renewIP = new DHCPv6Option5(packet.Option3.IANAOptions).IPv6Address;
+ leaseIP = new IPAddress(renewIP).ToString();
+ msgType = 7;
+ }
+ break;
+
+ case 5:
+ {
+ byte[] renewIP = new DHCPv6Option5(packet.Option3.IANAOptions).IPv6Address;
+ leaseIP = new IPAddress(renewIP).ToString();
+ msgType = 7;
+ }
+ break;
+ }
+
+ byte[] clientMACData = new DHCPv6DUIDLLT(packet.Option1.DUID).LinkLayerAddress;
+ string clientMAC = BitConverter.ToString(clientMACData).Replace("-", ":");
+ string clientHostName = "";
+
+ if (!String.IsNullOrEmpty(packet.Option39?.DomainName))
+ {
+ clientHostName = packet.Option39.DomainName;
+ }
+
+ if (Check(clientMAC, clientHostName, listenerMAC, isMicrosoft, out string message))
+ {
+
+ if (msgType == 2)
+ {
+ leaseIP = "fe80::" + this.Prefix + ":" + this.Index;
+ this.Index++;
+ }
+
+ byte[] buffer = new DHCPv6Packet().GetBytes(msgType, leaseIP, listenerMAC, dnsIPv6, this.DNSSuffix, this.Lifetime, packet);
+ SendTo(buffer, udpListener, ipEndPoint);
+ }
+
+ Output(packet.Message.MsgType, leaseIP, clientIP, clientMAC, clientHostName, message);
+ }
+
+ }
+
+ public virtual bool Check(string clientMAC, string clientHostName, string listenerMAC, bool isMicrosoft, out string message)
+ {
+ message = "response sent";
+ return true;
+ }
+
+ protected virtual void SendTo(byte[] data, UDPListener udpListener, IPEndPoint ipEndPoint)
+ {
+ udpListener.Client.SendTo(data, ipEndPoint);
+ }
+
+ protected virtual void Output(int msgType, string leaseIP, string clientIP, string clientMAC, string clientHostName, string message)
+ {
+ }
+
+ protected virtual void OutputError(string message)
+ {
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Listeners/DNSListener.cs b/Inveigh/Protocols/Quiddity/Listeners/DNSListener.cs
new file mode 100644
index 0000000..dea3004
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Listeners/DNSListener.cs
@@ -0,0 +1,151 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DNS;
+using System;
+using System.Net;
+using System.Net.Sockets;
+
+namespace Quiddity
+{
+ public class DNSListener
+ {
+ public uint Serial { get; set; }
+ public uint TTL { get; set; }
+ public string Host { get; set; }
+ public ushort Priority { get; set; }
+ public ushort Weight { get; set; }
+
+ public DNSListener()
+ {
+ this.TTL = 30;
+ }
+
+ public DNSListener(uint ttl)
+ {
+ this.TTL = ttl;
+ }
+
+ public DNSListener(uint ttl, string host)
+ {
+ this.TTL = ttl;
+ this.Host = host;
+ this.Priority = 0;
+ this.Weight = 100;
+ }
+
+ public void Start(IPAddress ipAddress, string replyIP, string replyIPv6)
+ {
+ UDPListener listener = new UDPListener(AddressFamily.InterNetwork);
+ IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 53);
+
+ if (String.Equals(ipAddress.AddressFamily.ToString(), "InterNetworkV6"))
+ {
+ listener = new UDPListener(AddressFamily.InterNetworkV6);
+ }
+
+ listener.Client.Bind(ipEndPoint);
+
+ while (true)
+ {
+
+ try
+ {
+ byte[] receiveBuffer = listener.Receive(ref ipEndPoint);
+ ProcessRequest(receiveBuffer, listener, ipEndPoint, replyIP, replyIPv6);
+ }
+ catch (Exception ex)
+ {
+ OutputError(ex);
+ }
+
+ }
+
+ }
+
+ protected virtual void ProcessRequest(byte[] data, UDPListener udpListener, IPEndPoint ipEndPoint, string replyIP, string replyIPv6)
+ {
+ string clientIP = ipEndPoint.Address.ToString();
+
+ DNSPacket packet = new DNSPacket(data)
+ {
+ Host = this.Host,
+ TTL = this.TTL
+ };
+
+ if (packet.Header.IsQuery())
+ {
+
+ if (Check(packet.Question.Name, packet.Question.Type, clientIP, out string message))
+ {
+ byte[] buffer;
+ buffer = packet.GetBytes(this.TTL, this.Serial, replyIP, replyIPv6);
+ SendTo(buffer, udpListener, ipEndPoint);
+ }
+
+ Output("DNS", clientIP, packet.Question.Name, packet.Question.Type, message);
+ }
+
+ }
+
+ public virtual bool Check(string name, string type, string clientIP, out string message)
+ {
+ message = "response sent";
+ return true;
+ }
+
+ public virtual bool Check(string name, string question, string type, string clientIP, out string message)
+ {
+ message = "response sent";
+ return true;
+ }
+
+ protected virtual void SendTo(byte[] data, UDPListener udpListener, IPEndPoint ipEndPoint)
+ {
+ udpListener.Client.SendTo(data, ipEndPoint);
+ }
+
+ protected virtual void Output(string protocol, string clientIP, string name, string type, string message)
+ {
+
+ }
+
+ protected virtual void Output(string protocol, string clientIP, string name, string question, string type, string message)
+ {
+
+ }
+
+ protected virtual void OutputError(Exception ex)
+ {
+
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Listeners/LLMNRListener.cs b/Inveigh/Protocols/Quiddity/Listeners/LLMNRListener.cs
new file mode 100644
index 0000000..a16d513
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Listeners/LLMNRListener.cs
@@ -0,0 +1,101 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.LLMNR;
+using System;
+using System.Net;
+using System.Net.Sockets;
+
+namespace Quiddity
+{
+ public class LLMNRListener : DNSListener
+ {
+
+ public LLMNRListener()
+ {
+ this.TTL = 300;
+ }
+
+ public new void Start(IPAddress ipAddress, string replyIP, string replyIPv6)
+ {
+ UDPListener listener = new UDPListener(AddressFamily.InterNetwork);
+ IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 5355);
+
+ if (String.Equals(ipAddress.AddressFamily.ToString(), "InterNetwork"))
+ {
+ listener.JoinMulticastGroup(IPAddress.Parse("224.0.0.252"));
+ }
+ else
+ {
+ listener = new UDPListener(AddressFamily.InterNetworkV6);
+ listener.JoinMulticastGroup(IPAddress.Parse("ff02::1:3"));
+ }
+
+ listener.Client.Bind(ipEndPoint);
+
+ while (true)
+ {
+
+ try
+ {
+ byte[] receiveBuffer = listener.Receive(ref ipEndPoint);
+ ProcessRequest(receiveBuffer, listener, ipEndPoint, replyIP, replyIPv6);
+ }
+ catch (Exception ex)
+ {
+ OutputError(ex);
+ }
+
+ }
+
+ }
+
+ protected override void ProcessRequest(byte[] data, UDPListener udpListener, IPEndPoint ipEndPoint, string replyIP, string replyIPv6)
+ {
+ string clientIP = ipEndPoint.Address.ToString();
+ LLMNRPacket packet = new LLMNRPacket(data);
+
+ if (packet.Header.IsQuery())
+ {
+
+ if (Check(packet.Question.Name, packet.Question.Type, clientIP, out string message))
+ {
+ byte[] buffer = packet.GetBytes(this.TTL, replyIP, replyIPv6);
+ SendTo(buffer, udpListener, ipEndPoint);
+ }
+
+ Output("LLMNR", clientIP, packet.Question.Name, packet.Question.Type, message);
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Listeners/MDNSListener.cs b/Inveigh/Protocols/Quiddity/Listeners/MDNSListener.cs
new file mode 100644
index 0000000..973329b
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Listeners/MDNSListener.cs
@@ -0,0 +1,117 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.MDNS;
+using System;
+using System.Net;
+using System.Net.Sockets;
+
+namespace Quiddity
+{
+ public class MDNSListener : DNSListener
+ {
+ public bool UnicastOnly { get; set; }
+
+ public MDNSListener()
+ {
+ this.TTL = 120;
+ }
+
+ public MDNSListener(uint ttl, bool unicastOnly)
+ {
+ this.TTL = ttl;
+ this.UnicastOnly = unicastOnly;
+ }
+
+ public new void Start(IPAddress ipAddress, string replyIP, string replyIPv6)
+ {
+ UDPListener listener = new UDPListener(AddressFamily.InterNetwork);
+ IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 5353);
+
+ if (string.Equals(ipAddress.AddressFamily.ToString(), "InterNetwork"))
+ {
+ listener.JoinMulticastGroup(IPAddress.Parse("224.0.0.251"), ipAddress);
+ }
+ else
+ {
+ listener = new UDPListener(AddressFamily.InterNetworkV6);
+ listener.JoinMulticastGroup(IPAddress.Parse("ff02::fb"));
+ }
+
+ listener.Client.Bind(ipEndPoint);
+
+ while (true)
+ {
+
+ try
+ {
+ byte[] receiveBuffer = listener.Receive(ref ipEndPoint);
+ ProcessRequest(receiveBuffer, listener, ipEndPoint, replyIP, replyIPv6);
+ }
+ catch (Exception ex)
+ {
+ OutputError(ex);
+ }
+
+ }
+
+ }
+
+ protected override void ProcessRequest(byte[] data, UDPListener udpListener, IPEndPoint ipEndPoint, string replyIP, string replyIPv6)
+ {
+ string clientIP = ipEndPoint.Address.ToString();
+ MDNSPacket packet = new MDNSPacket(data);
+
+ if (packet.Header.IsQuery())
+ {
+
+ if (Check(packet.Question.Name, packet.Question.QuestionType, packet.Question.Type, clientIP, out string message))
+ {
+
+ if (packet.Question.QuestionType.Equals("QM") && !this.UnicastOnly && string.Equals(ipEndPoint.Address.AddressFamily.ToString(), "InterNetwork"))
+ {
+ ipEndPoint.Address = IPAddress.Parse("224.0.0.251");
+ }
+ else if (packet.Question.QuestionType.Equals("QM") && !this.UnicastOnly && string.Equals(ipEndPoint.Address.AddressFamily.ToString(), "InterNetworkV6"))
+ {
+ ipEndPoint.Address = IPAddress.Parse("ff02::fb");
+ }
+
+ byte[] buffer = packet.GetBytes(this.TTL, replyIP, replyIPv6);
+ SendTo(buffer, udpListener, ipEndPoint);
+ }
+
+ Output("mDNS", clientIP, packet.Question.Name, packet.Question.QuestionType, packet.Question.Type, message);
+ }
+
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Listeners/NetBIOSNSListener.cs b/Inveigh/Protocols/Quiddity/Listeners/NetBIOSNSListener.cs
new file mode 100644
index 0000000..f2754d6
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Listeners/NetBIOSNSListener.cs
@@ -0,0 +1,95 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.NetBIOS;
+using System;
+using System.Net;
+using System.Net.Sockets;
+
+namespace Quiddity
+{
+ public class NetBIOSNSListener : DNSListener
+ {
+ public NetBIOSNSListener()
+ {
+ this.TTL = 165;
+ }
+
+ public NetBIOSNSListener(uint ttl)
+ {
+ this.TTL = ttl;
+ }
+
+ public void Start(IPAddress ipAddress, string replyIP)
+ {
+ UDPListener listener = new UDPListener(AddressFamily.InterNetwork);
+ IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 137);
+
+ listener.Client.Bind(ipEndPoint);
+
+ while (true)
+ {
+
+ try
+ {
+ byte[] receiveBuffer = listener.Receive(ref ipEndPoint);
+ ProcessRequest(receiveBuffer, listener, ipEndPoint, replyIP);
+ }
+ catch (Exception ex)
+ {
+ OutputError(ex);
+ }
+
+ }
+
+ }
+
+ protected void ProcessRequest(byte[] data, UDPListener udpListener, IPEndPoint ipEndPoint, string replyIP)
+ {
+ string clientIP = ipEndPoint.Address.ToString();
+ NetBIOSNSPacket packet = new NetBIOSNSPacket(data);
+
+ if (packet.Header.IsQuery())
+ {
+
+ if (Check(packet.Question.Name, packet.Question.Type, clientIP, out string message))
+ {
+ byte[] buffer = packet.GetBytes(this.TTL, replyIP);
+ SendTo(buffer, udpListener, ipEndPoint);
+ }
+
+ Output("NBNS", clientIP, packet.Question.Name, packet.Question.Type, message);
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Listeners/TCPListener.cs b/Inveigh/Protocols/Quiddity/Listeners/TCPListener.cs
new file mode 100644
index 0000000..44af085
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Listeners/TCPListener.cs
@@ -0,0 +1,48 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System.Net;
+using System.Net.Sockets;
+
+namespace Quiddity
+{
+ public class TCPListener : TcpListener
+ {
+ public TCPListener(IPAddress ipAddress, int port) : base(ipAddress, port)
+ {
+ this.Server.ExclusiveAddressUse = false;
+ this.ExclusiveAddressUse = false;
+ this.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Listeners/UDPListener.cs b/Inveigh/Protocols/Quiddity/Listeners/UDPListener.cs
new file mode 100644
index 0000000..d0a2f49
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Listeners/UDPListener.cs
@@ -0,0 +1,58 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System.Net;
+using System.Net.Sockets;
+
+namespace Quiddity
+{
+ public class UDPListener : UdpClient
+ {
+
+ public UDPListener(AddressFamily addressFamily) : base(addressFamily)
+ {
+ this.ExclusiveAddressUse = false;
+ this.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+ const int SIO_UDP_CONNRESET = -1744830452;
+
+#if NETFRAMEWORK
+ this.Client.IOControl((IOControlCode)SIO_UDP_CONNRESET, new byte[] { 0, 0, 0, 0 }, null);
+#else
+ if (System.OperatingSystem.IsWindows())
+ {
+ this.Client.IOControl((IOControlCode)SIO_UDP_CONNRESET, new byte[] { 0, 0, 0, 0 }, null);
+ }
+#endif
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DCERPC/SCMR/SCMRROpenSCManagerW.cs b/Inveigh/Protocols/Quiddity/Protocols/DCERPC/SCMR/SCMRROpenSCManagerW.cs
new file mode 100644
index 0000000..2337915
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DCERPC/SCMR/SCMRROpenSCManagerW.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SCMR
+{
+ public class SCMRROpenSCManagerW
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-scmr/dc84adb3-d51d-48eb-820d-ba1c6ca5faf2
+ public byte[] LpMachineName { get; set; }
+ public byte[] LpDatabaseName { get; set; }
+ public byte[] DwDesiredAccess { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Checker.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Checker.cs
new file mode 100644
index 0000000..568a892
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Checker.cs
@@ -0,0 +1,150 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Checker
+ {
+ public string[] IgnoreMACs { get; set; }
+ public string[] ReplyToMACs { get; set; }
+ public IList<string> HostCaptures { get; set; }
+ public bool Enabled { get; set; }
+ public bool Inspect { get; set; }
+ public bool Repeat { get; set; }
+ public bool Microsoft { get; set; }
+ public bool Local { get; set; }
+ public string OutputReplyAllowed { get; set; }
+ public string OutputMessage { get; set; }
+ public string OutputInspect { get; set; }
+ public string OutputDisabled { get; set; }
+ public string OutputLocal { get; set; }
+ public string OutputHostDenied { get; set; }
+ public string OutputMACDenied { get; set; }
+ public string OutputVendorDenied { get; set; }
+ public string OutputIPDenied { get; set; }
+ public string OutputRepeat { get; set; }
+
+ public bool Check(string clientMAC, string clientHost, string listenerMAC, bool isMicrosoft)
+ {
+
+ if (this.Inspect)
+ {
+ this.OutputMessage = this.OutputInspect;
+ return false;
+ }
+ else if (!this.Enabled)
+ {
+ this.OutputMessage = this.OutputDisabled;
+ return false;
+ }
+ else if (!isMicrosoft)
+ {
+ this.OutputMessage = this.OutputVendorDenied;
+ return false;
+ }
+ else if (IsLocal(clientMAC, listenerMAC))
+ {
+ this.OutputMessage = this.OutputLocal;
+ return false;
+ }
+ else if (IsRepeat(clientHost))
+ {
+ this.OutputMessage = this.OutputRepeat;
+ return false;
+ }
+ else if (MACIsDenied(clientMAC))
+ {
+ this.OutputMessage = this.OutputMACDenied;
+ return false;
+ }
+ else if (!MACIsAllowed(clientMAC))
+ {
+ this.OutputMessage = this.OutputMACDenied;
+ return false;
+ }
+
+ this.OutputMessage = this.OutputReplyAllowed;
+ return true;
+ }
+
+ public bool IsRepeat(string host)
+ {
+ host = host.Split('.')[0].ToUpper();
+
+ if (!this.Repeat && this.HostCaptures.Contains(host))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool IsLocal(string clientMAC, string listenerMAC)
+ {
+
+ if (!this.Local && string.Equals(clientMAC, listenerMAC))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool MACIsDenied(string mac)
+ {
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.IgnoreMACs) && (Array.Exists(this.IgnoreMACs, element => element == mac.Replace(":", "").ToUpper())))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool MACIsAllowed(string mac)
+ {
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.ReplyToMACs) && (!Array.Exists(this.ReplyToMACs, element => element == mac.Replace(":","").ToUpper())))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Message.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Message.cs
new file mode 100644
index 0000000..3412b0d
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Message.cs
@@ -0,0 +1,86 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Message
+ {
+ // https://datatracker.ietf.org/doc/html/rfc3315#section-17.1.1
+ public byte MsgType { get; set; }
+ public byte[] TransactionID { get; set; } // 3 bytes
+ public byte[] Options { get; set; }
+
+ public DHCPv6Message()
+ {
+
+ }
+
+ public DHCPv6Message(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.MsgType = packetReader.ReadByte();
+ this.TransactionID = packetReader.ReadBytes(3);
+ this.Options = packetReader.ReadBytes(data.Length - 4);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.MsgType);
+ packetWriter.Write(this.TransactionID);
+ packetWriter.Write(this.Options);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Packet.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Packet.cs
new file mode 100644
index 0000000..b3bd457
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/DHCPv6Packet.cs
@@ -0,0 +1,222 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Packet
+ {
+ public DHCPv6Message Message { get; set; }
+ public DHCPv6Option1 Option1 { get; set; }
+ public DHCPv6Option2 Option2 { get; set; }
+ public DHCPv6Option3 Option3 { get; set; }
+ public DHCPv6Option6 Option6 { get; set; }
+ public DHCPv6Option8 Option8 { get; set; }
+ public DHCPv6Option14 Option14 { get; set; }
+ public DHCPv6Option16 Option16 { get; set; }
+ public DHCPv6Option23 Option23 { get; set; }
+ public DHCPv6Option24 Option24 { get; set; }
+ public DHCPv6Option39 Option39 { get; set; }
+
+ public DHCPv6Packet()
+ {
+
+ }
+
+ public DHCPv6Packet(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Packet(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+ this.Message = new DHCPv6Message(data);
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.Message.Options))
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(this.Message.Options))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ DHCPv6Option option = new DHCPv6Option();
+ option.ReadBytes(this.Message.Options, 0);
+
+ while (option.OptionCode != 0 && memoryStream.Length - memoryStream.Position >= 4)
+ {
+ option.ReadBytes(this.Message.Options, (int)memoryStream.Position);
+
+ switch (option.OptionCode)
+ {
+ case 1:
+ this.Option1 = new DHCPv6Option1(this.Message.Options, (int)memoryStream.Position);
+ break;
+
+ case 2:
+ this.Option2 = new DHCPv6Option2(this.Message.Options, (int)memoryStream.Position);
+ break;
+
+ case 3:
+ this.Option3 = new DHCPv6Option3(this.Message.Options, (int)memoryStream.Position);
+ break;
+
+ case 6:
+ this.Option6 = new DHCPv6Option6(this.Message.Options, (int)memoryStream.Position);
+ break;
+
+ case 8:
+ this.Option8 = new DHCPv6Option8(this.Message.Options, (int)memoryStream.Position);
+ break;
+
+ case 14:
+ this.Option14 = new DHCPv6Option14(this.Message.Options, (int)memoryStream.Position);
+ break;
+
+ case 16:
+ this.Option16 = new DHCPv6Option16(this.Message.Options, (int)memoryStream.Position);
+ break;
+
+ case 23:
+ this.Option23 = new DHCPv6Option23(this.Message.Options, (int)memoryStream.Position);
+ break;
+
+ case 24:
+ this.Option24 = new DHCPv6Option24(this.Message.Options, (int)memoryStream.Position);
+ break;
+
+ case 39:
+ this.Option39 = new DHCPv6Option39(this.Message.Options, (int)memoryStream.Position);
+ break;
+ }
+
+ memoryStream.Position += option.OptionLen + 4;
+ }
+
+ }
+
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.Message.MsgType);
+ packetWriter.Write(this.Message.TransactionID);
+
+ if (this.Option8 != null)
+ {
+ packetWriter.Write(this.Option8.GetBytes());
+ }
+
+ if (this.Option1 != null)
+ {
+ packetWriter.Write(this.Option1.GetBytes());
+ }
+
+ if (this.Option2 != null)
+ {
+ packetWriter.Write(this.Option2.GetBytes());
+ }
+
+ if (this.Option3 != null)
+ {
+ packetWriter.Write(this.Option3.GetBytes());
+ }
+
+ if (this.Option23 != null)
+ {
+ packetWriter.Write(this.Option23.GetBytes());
+ }
+
+ if (this.Option24 != null)
+ {
+ packetWriter.Write(this.Option24.GetBytes());
+ }
+
+ if (this.Option39 != null)
+ {
+ packetWriter.Write(this.Option39.GetBytes());
+ }
+
+ if (this.Option16 != null)
+ {
+ packetWriter.Write(this.Option16.GetBytes());
+ }
+
+ if (this.Option6 != null)
+ {
+ packetWriter.Write(this.Option6.GetBytes());
+ }
+
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ public byte[] GetBytes(byte msgType, string leaseAddress, string listenerMAC, string dnsServer, string dnsSuffix, uint lifetime, DHCPv6Packet dhcpv6Packet)
+ {
+
+ this.Message = new DHCPv6Message
+ {
+ MsgType = msgType,
+ TransactionID = dhcpv6Packet.Message.TransactionID
+ };
+
+ this.Option1 = dhcpv6Packet.Option1;
+ this.Option2 = new DHCPv6Option2(listenerMAC);
+ this.Option3 = new DHCPv6Option3(leaseAddress, lifetime, dhcpv6Packet.Option3.IAID);
+ this.Option23 = new DHCPv6Option23(dnsServer);
+
+ if (!String.IsNullOrEmpty(dnsSuffix))
+ {
+ this.Option24 = new DHCPv6Option24(dnsSuffix);
+ }
+
+ return GetBytes();
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option.cs
new file mode 100644
index 0000000..6e630d1
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option
+ {
+ public ushort OptionCode { get; set; }
+ public ushort OptionLen { get; set; }
+
+ public DHCPv6Option()
+ {
+
+ }
+
+ public DHCPv6Option(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option1.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option1.cs
new file mode 100644
index 0000000..cf34acc
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option1.cs
@@ -0,0 +1,88 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option1 : DHCPv6Option
+ {
+ public byte[] DUID { get; set; }
+
+ public DHCPv6Option1()
+ {
+
+ }
+
+ public DHCPv6Option1(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option1(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ this.DUID = packetReader.ReadBytes(this.OptionLen);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.OptionCode);
+ packetWriter.BigEndianWrite(this.OptionLen);
+ packetWriter.Write(this.DUID);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option14.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option14.cs
new file mode 100644
index 0000000..6c50e47
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option14.cs
@@ -0,0 +1,86 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option14 : DHCPv6Option
+ {
+
+ public DHCPv6Option14()
+ {
+ this.OptionCode = 14;
+ this.OptionLen = 0;
+ }
+
+ public DHCPv6Option14(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option14(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.OptionCode);
+ packetWriter.Write(this.OptionLen);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option16.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option16.cs
new file mode 100644
index 0000000..606ee13
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option16.cs
@@ -0,0 +1,90 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option16 : DHCPv6Option
+ {
+ public uint EnterpriseNumber { get; set; }
+ public byte[] VendorClassData { get; set; }
+
+ public DHCPv6Option16()
+ {
+
+ }
+
+ public DHCPv6Option16(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option16(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ this.EnterpriseNumber = packetReader.BigEndianReadUInt32();
+ this.VendorClassData = packetReader.ReadBytes(this.OptionLen - 8);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.OptionCode);
+ packetWriter.Write(this.OptionLen);
+ packetWriter.Write(this.EnterpriseNumber);
+ packetWriter.Write(this.VendorClassData);
+ return memoryStream.ToArray();
+ }
+
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option2.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option2.cs
new file mode 100644
index 0000000..6abb125
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option2.cs
@@ -0,0 +1,95 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option2 : DHCPv6Option
+ {
+ public byte[] DUID { get; set; }
+
+ public DHCPv6Option2()
+ {
+
+ }
+
+ public DHCPv6Option2(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option2(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public DHCPv6Option2(string mac)
+ {
+ DHCPv6DUIDLL duid = new DHCPv6DUIDLL(mac);
+ this.OptionCode = 2;
+ this.DUID = duid.GetBytes();
+ this.OptionLen = (ushort)this.DUID.Length;
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ this.DUID = packetReader.ReadBytes(this.OptionLen);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.OptionCode);
+ packetWriter.BigEndianWrite(this.OptionLen);
+ packetWriter.Write(this.DUID);
+ return memoryStream.ToArray();
+ }
+
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option23.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option23.cs
new file mode 100644
index 0000000..250bcef
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option23.cs
@@ -0,0 +1,97 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option23 : DHCPv6Option
+ {
+ // https://datatracker.ietf.org/doc/html/rfc3646
+ public byte[] DNSRecursiveNameServers { get; set; }
+ public DHCPv6Option23()
+ {
+
+ }
+
+ public DHCPv6Option23(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option23(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public DHCPv6Option23(string dnsRecursiveNameServer)
+ {
+ this.OptionCode = 23;
+ this.OptionLen = 16;
+ this.DNSRecursiveNameServers = IPAddress.Parse(dnsRecursiveNameServer).GetAddressBytes();
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ this.DNSRecursiveNameServers = packetReader.ReadBytes(this.OptionLen);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.OptionCode);
+ packetWriter.BigEndianWrite(this.OptionLen);
+ packetWriter.Write(this.DNSRecursiveNameServers);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option24.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option24.cs
new file mode 100644
index 0000000..5abbecb
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option24.cs
@@ -0,0 +1,95 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option24 : DHCPv6Option
+ {
+ public byte[] SearchList { get; set; }
+
+ public DHCPv6Option24()
+ {
+
+ }
+
+ public DHCPv6Option24(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option24(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public DHCPv6Option24(string dnsSuffix)
+ {
+ this.OptionCode = 24;
+ this.SearchList = Utilities.GetDNSNameBytes(dnsSuffix, true);
+ this.OptionLen = (ushort)this.SearchList.Length;
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ this.SearchList = packetReader.ReadBytes(this.OptionLen);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.OptionCode);
+ packetWriter.BigEndianWrite(this.OptionLen);
+ packetWriter.Write(this.SearchList);
+ return memoryStream.ToArray();
+ }
+
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option3.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option3.cs
new file mode 100644
index 0000000..7641a32
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option3.cs
@@ -0,0 +1,107 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option3 : DHCPv6Option
+ {
+ public byte[] IAID { get; set; }
+ public uint T1 { get; set; }
+ public uint T2 { get; set; }
+ public byte[] IANAOptions { get; set; }
+
+ public DHCPv6Option3()
+ {
+
+ }
+
+ public DHCPv6Option3(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option3(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public DHCPv6Option3(string clientIPv6Address, uint lifetime, byte[] iaid)
+ {
+ this.OptionCode = 3;
+ this.T1 = 200;
+ this.T2 = 250;
+ this.IAID = iaid;
+ this.IANAOptions = new DHCPv6Option5().GetBytes(clientIPv6Address, lifetime);
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ this.IAID = packetReader.ReadBytes(4);
+ this.T1 = packetReader.BigEndianReadUInt32();
+ this.T2 = packetReader.BigEndianReadUInt32();
+ this.IANAOptions = packetReader.ReadBytes(this.OptionLen - 12);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+ this.OptionLen = 40;
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.OptionCode);
+ packetWriter.BigEndianWrite(this.OptionLen);
+ packetWriter.Write(this.IAID);
+ packetWriter.BigEndianWrite(this.T1);
+ packetWriter.BigEndianWrite(this.T2);
+ packetWriter.Write(this.IANAOptions);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option39.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option39.cs
new file mode 100644
index 0000000..b7b4a76
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option39.cs
@@ -0,0 +1,128 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option39 : DHCPv6Option
+ {
+ // https://datatracker.ietf.org/doc/html/rfc4704
+
+ public byte Flags { get; set; }
+ public string DomainName { get; set; }
+
+ public DHCPv6Option39()
+ {
+
+ }
+
+ public DHCPv6Option39(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option39(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ this.Flags = packetReader.ReadByte();
+ this.DomainName = ConvertName(packetReader.ReadBytes(this.OptionLen - 1));
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.OptionCode);
+ packetWriter.Write(this.OptionLen);
+ packetWriter.Write(this.Flags);
+ packetWriter.Write(this.DomainName);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ protected virtual string ConvertName(byte[]data)
+ {
+ string hostname = "";
+ int hostnameLength = data[0];
+ int index = 0;
+ int i = 0;
+
+ do
+ {
+ int hostnameSegmentLength = hostnameLength;
+ byte[] hostnameSegment = new byte[hostnameSegmentLength];
+ Buffer.BlockCopy(data, (index + 1), hostnameSegment, 0, hostnameSegmentLength);
+ hostname += Encoding.UTF8.GetString(hostnameSegment);
+
+ if (hostnameLength + 1 == data.Length)
+ {
+ return hostname;
+ }
+
+ index += hostnameLength + 1;
+ hostnameLength = data[index];
+ i++;
+
+ if (hostnameLength > 0)
+ {
+ hostname += ".";
+ }
+
+ }
+ while (hostnameLength != 0 && i <= 127);
+
+ return hostname;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option5.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option5.cs
new file mode 100644
index 0000000..7ed7a2b
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option5.cs
@@ -0,0 +1,77 @@
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option5 : DHCPv6Option
+ {
+ // https://datatracker.ietf.org/doc/html/rfc3315#section-22.6
+
+ public byte[] IPv6Address { get; set; }
+ public uint PreferredLifetime { get; set; }
+ public uint ValidLifetime { get; set; }
+ public byte[] IAAddrOptions { get; set; }
+
+ public DHCPv6Option5()
+ {
+ }
+
+ public DHCPv6Option5(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option5(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ this.IPv6Address = packetReader.ReadBytes(16);
+ this.PreferredLifetime = packetReader.BigEndianReadUInt32();
+ this.ValidLifetime = packetReader.BigEndianReadUInt32();
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.OptionCode);
+ packetWriter.BigEndianWrite(this.OptionLen);
+ packetWriter.Write(this.IPv6Address);
+ packetWriter.BigEndianWrite(this.PreferredLifetime);
+ packetWriter.BigEndianWrite(this.ValidLifetime);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ public byte[] GetBytes(string ipv6Address, uint lifeTime)
+ {
+ this.OptionCode = 5;
+ this.OptionLen = 24;
+ this.IPv6Address = IPAddress.Parse(ipv6Address).GetAddressBytes();
+ this.PreferredLifetime = lifeTime;
+ this.ValidLifetime = lifeTime;
+ return GetBytes();
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option6.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option6.cs
new file mode 100644
index 0000000..557e089
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option6.cs
@@ -0,0 +1,87 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option6 : DHCPv6Option
+ {
+ public byte[] RequestedOptionCodes { get; set; }
+
+ public DHCPv6Option6()
+ {
+
+ }
+
+ public DHCPv6Option6(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option6(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ this.RequestedOptionCodes = packetReader.ReadBytes(this.OptionLen);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.OptionCode);
+ packetWriter.Write(this.OptionLen);
+ packetWriter.Write(this.RequestedOptionCodes);
+ return memoryStream.ToArray();
+ }
+
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option8.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option8.cs
new file mode 100644
index 0000000..b6d522c
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/DHCPv6Option8.cs
@@ -0,0 +1,88 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ class DHCPv6Option8 : DHCPv6Option
+ {
+ public ushort ElapsedTime { get; set; }
+
+ public DHCPv6Option8()
+ {
+
+ }
+
+ public DHCPv6Option8(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6Option8(byte[] data, int index)
+ {
+ ReadBytes(data, index);
+ }
+
+ public new void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.OptionCode = packetReader.BigEndianReadUInt16();
+ this.OptionLen = packetReader.BigEndianReadUInt16();
+ this.ElapsedTime = packetReader.BigEndianReadUInt16();
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.OptionCode);
+ packetWriter.Write(this.OptionLen);
+ packetWriter.Write(this.ElapsedTime);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/Values/DHCPv6DUIDLL.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/Values/DHCPv6DUIDLL.cs
new file mode 100644
index 0000000..a24dd45
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/Values/DHCPv6DUIDLL.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ public class DHCPv6DUIDLL
+ {
+ // https://datatracker.ietf.org/doc/html/rfc3315#section-9
+ public ushort DUIDType { get; set; }
+ public ushort HardwareType { get; set; }
+ public byte[] LinkLayerAddress { get; set; }
+
+ public DHCPv6DUIDLL()
+ {
+
+ }
+
+ public DHCPv6DUIDLL(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public DHCPv6DUIDLL(string linkLayerAddress)
+ {
+ byte[] linkLayerAddressData = new byte[6];
+ int i = 0;
+
+ foreach (string character in linkLayerAddress.Split(':'))
+ {
+ linkLayerAddressData[i] = Convert.ToByte(Convert.ToInt16(character, 16));
+ i++;
+ }
+
+ this.DUIDType = 3;
+ this.HardwareType = 1;
+ this.LinkLayerAddress = linkLayerAddressData;
+ }
+
+ public void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.DUIDType = packetReader.BigEndianReadUInt16();
+ this.HardwareType = packetReader.BigEndianReadUInt16();
+ this.LinkLayerAddress = packetReader.ReadBytes(6);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.DUIDType);
+ packetWriter.BigEndianWrite(this.HardwareType);
+ packetWriter.Write(this.LinkLayerAddress);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/Values/DHCPv6DUIDLLT.cs b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/Values/DHCPv6DUIDLLT.cs
new file mode 100644
index 0000000..45408bd
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DHCPv6/Options/Values/DHCPv6DUIDLLT.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DHCPv6
+{
+ public class DHCPv6DUIDLLT
+ {
+ // https://datatracker.ietf.org/doc/html/rfc3315#section-9
+ public ushort DUIDType { get; set; }
+ public ushort HardwareType { get; set; }
+ public uint Time { get; set; }
+ public byte[] LinkLayerAddress { get; set; }
+
+ public DHCPv6DUIDLLT()
+ {
+
+ }
+
+ public DHCPv6DUIDLLT(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public void ReadBytes(byte[] data, int index)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = index;
+ this.DUIDType = packetReader.BigEndianReadUInt16();
+ this.HardwareType = packetReader.BigEndianReadUInt16();
+ this.Time = packetReader.BigEndianReadUInt32();
+ this.LinkLayerAddress = packetReader.ReadBytes(6);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.DUIDType);
+ packetWriter.BigEndianWrite(this.HardwareType);
+ packetWriter.Write(this.LinkLayerAddress);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSChecker.cs b/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSChecker.cs
new file mode 100644
index 0000000..5a23ffd
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSChecker.cs
@@ -0,0 +1,329 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+
+namespace Quiddity.DNS
+{
+ class DNSChecker
+ {
+ public string[] IgnoreHosts { get; set; }
+ public string[] ReplyToHosts { get; set; }
+ public string[] IgnoreIPs { get; set; }
+ public string[] ReplyToIPs { get; set; }
+ public string[] IgnoreDomains { get; set; }
+ public string[] ReplyToDomains { get; set; }
+ public string[] Types { get; set; }
+ public string[] Services { get; set; }
+ public IList<string> IPCaptures { get; set; }
+ public bool Enabled { get; set; }
+ public bool Inspect { get; set; }
+ public bool IPv6 { get; set; }
+ public bool Local { get; set; }
+ public bool Repeat { get; set; }
+ public string OutputReplyAllowed { get; set; }
+ public string OutputMessage { get; set; }
+ public string OutputInspect { get; set; }
+ public string OutputDisabled { get; set; }
+ public string OutputTypeDenied { get; set; }
+ public string OutputServiceDenied { get; set; }
+ public string OutputHostDenied { get; set; }
+ public string OutputIPDenied { get; set; }
+ public string OutputDomainDenied { get; set; }
+ public string OutputRepeat { get; set; }
+
+ public DNSChecker()
+ {
+ this.OutputReplyAllowed = "response sent";
+ this.OutputInspect = "inspect only";
+ this.OutputDisabled = "disabled";
+ this.OutputHostDenied = "host ignored";
+ this.OutputIPDenied = "IP ignored";
+ this.OutputDomainDenied = "domain ignored";
+ this.OutputTypeDenied = "type ignored";
+ this.OutputServiceDenied = "service ignored";
+ this.OutputRepeat = "previous capture";
+ }
+
+ public bool Check(string name, string type, string clientIP)
+ {
+ if (this.Inspect)
+ {
+ this.OutputMessage = this.OutputInspect;
+ return false;
+ }
+ else if (!this.Enabled)
+ {
+ this.OutputMessage = this.OutputDisabled;
+ return false;
+ }
+ else if (IsRepeat(clientIP))
+ {
+ this.OutputMessage = this.OutputRepeat;
+ return false;
+ }
+ else if (!TypeIsAllowed(type))
+ {
+ this.OutputMessage = this.OutputTypeDenied;
+ return false;
+ }
+ else if (!ServiceIsAllowed(name, type))
+ {
+ this.OutputMessage = this.OutputServiceDenied;
+ return false;
+ }
+ else if (HostIsDenied(name))
+ {
+ this.OutputMessage = this.OutputHostDenied;
+ return false;
+ }
+ else if (!HostIsAllowed(name))
+ {
+ this.OutputMessage = this.OutputIPDenied;
+ return false;
+ }
+ else if (FQDNIsDenied(name))
+ {
+ this.OutputMessage = this.OutputHostDenied;
+ return false;
+ }
+ else if (!FQDNIsAllowed(name))
+ {
+ this.OutputMessage = this.OutputIPDenied;
+ return false;
+ }
+ else if (IPIsDenied(clientIP))
+ {
+ this.OutputMessage = this.OutputIPDenied;
+ return false;
+ }
+ else if (!IPIsAllowed(clientIP))
+ {
+ this.OutputMessage = this.OutputIPDenied;
+ return false;
+ }
+ else if (DomainIsDenied(name))
+ {
+ this.OutputMessage = this.OutputDomainDenied;
+ return false;
+ }
+ else if (!DomainIsAllowed(name))
+ {
+ this.OutputMessage = this.OutputDomainDenied;
+ return false;
+ }
+
+ this.OutputMessage = this.OutputReplyAllowed;
+ return true;
+ }
+
+ public bool IsRepeat(string clientIP)
+ {
+
+ if (!this.Repeat && this.IPCaptures.Contains(clientIP))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool TypeIsAllowed(string type)
+ {
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.Types) && (!Array.Exists(this.Types, element => element == type.ToUpper())))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool ServiceIsAllowed(string name, string type)
+ {
+
+ if (type.Equals("SRV") && TypeIsAllowed("SRV"))
+ {
+ string service = "";
+
+ if (name.StartsWith("_ldap."))
+ {
+ service = "LDAP";
+ }
+ else if (name.StartsWith("_kerberos."))
+ {
+ service = "Kerberos";
+ }
+ else if (name.StartsWith("_kpassword."))
+ {
+ service = "KPassword";
+ }
+ else if (name.StartsWith("_gc."))
+ {
+ service = "GC";
+ }
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.Services) && (!Array.Exists(this.Services, element => element == service.ToUpper())))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public bool HostIsDenied(string name)
+ {
+ string host = (name.Split('.'))[0];
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.IgnoreHosts) && Array.Exists(this.IgnoreHosts, element => element == host.ToUpper()))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool HostIsAllowed(string name)
+ {
+ string host = (name.Split('.'))[0];
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.ReplyToHosts) && !Array.Exists(this.ReplyToHosts, element => element == host.ToUpper()))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool FQDNIsDenied(string name)
+ {
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.IgnoreHosts) && Array.Exists(this.IgnoreHosts, element => element == name.ToUpper()))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool FQDNIsAllowed(string name)
+ {
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.ReplyToHosts) && !Array.Exists(this.ReplyToHosts, element => element == name.ToUpper()))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool IPIsDenied(string clientIP)
+ {
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.IgnoreIPs) && Array.Exists(this.IgnoreIPs, element => element == clientIP.ToUpper()))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool IPIsAllowed(string clientIP)
+ {
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.ReplyToIPs) && !Array.Exists(this.ReplyToIPs, element => element == clientIP.ToUpper()))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool DomainIsDenied(string domain)
+ {
+ int index = domain.IndexOf(".");
+
+ while (index > -1)
+ {
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.IgnoreDomains) && Array.Exists(this.IgnoreDomains, element => element == domain.ToUpper()))
+ {
+ return true;
+ }
+
+
+ index = domain.IndexOf(".");
+
+ if (index > -1)
+ {
+ domain = domain.Substring(index).TrimStart('.');
+ }
+
+ }
+
+ return false;
+ }
+
+ public bool DomainIsAllowed(string domain)
+ {
+ int index = domain.IndexOf(".");
+
+ if (index == -1 || Utilities.ArrayIsNullOrEmpty(this.ReplyToDomains))
+ {
+ return true;
+ }
+
+ while (index > -1)
+ {
+
+ if (Array.Exists(this.ReplyToDomains, element => element == domain.ToUpper()))
+ {
+ return true;
+ }
+
+ index = domain.IndexOf(".");
+
+ if (index > -1)
+ {
+ domain = domain.Substring(index).TrimStart('.');
+ }
+
+ }
+
+ return false;
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSHeader.cs b/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSHeader.cs
new file mode 100644
index 0000000..fbdde7b
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSHeader.cs
@@ -0,0 +1,169 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.IO;
+
+namespace Quiddity.DNS
+{
+ public class DNSHeader
+ {
+ // https://tools.ietf.org/html/rfc1035
+ public byte[] ID { get; set; }
+ public bool QR { get; set; } // 1 bit
+ public string Opcode { get; set; } // 4 bit
+ public bool AA { get; set; } // 1 bit
+ public bool TC { get; set; } // 1 bit
+ public bool RD { get; set; } // 1 bit
+ public bool RA { get; set; } // 1 bit
+ public string Z { get; set; } // reserved
+ public string RCode { get; set; } // 4 bit
+ public ushort QDCount { get; set; }
+ public ushort ANCount { get; set; }
+ public ushort NSCount { get; set; }
+ public ushort ARCount { get; set; }
+
+ // custom
+ public byte[] Flags { get; set; }
+
+ public DNSHeader()
+ {
+
+ }
+
+ public DNSHeader(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.ID = packetReader.ReadBytes(2);
+ this.Flags = packetReader.BigEndianReadBytes(2);
+ this.QDCount = packetReader.BigEndianReadUInt16();
+ this.ANCount = packetReader.BigEndianReadUInt16();
+ this.NSCount = packetReader.BigEndianReadUInt16();
+ this.ARCount = packetReader.BigEndianReadUInt16();
+ }
+
+ ReadFlags();
+ }
+
+ public byte[] GetBytes()
+ {
+ WriteFlags();
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.ID);
+ packetWriter.Write(this.Flags);
+ packetWriter.BigEndianWrite(this.QDCount);
+ packetWriter.BigEndianWrite(this.ANCount);
+ packetWriter.BigEndianWrite(this.NSCount);
+ packetWriter.BigEndianWrite(this.ARCount);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ protected virtual void ReadFlags()
+ {
+ string flags = Convert.ToString(BitConverter.ToUInt16(this.Flags, 0), 2).PadLeft(16, '0');
+
+ if (String.Equals(flags.Substring(0, 1), "1"))
+ {
+ this.QR = true;
+ }
+
+ this.Opcode = flags.Substring(1, 4);
+
+ if (String.Equals(flags.Substring(5, 1), "1"))
+ {
+ this.AA = true;
+ }
+
+ if (String.Equals(flags.Substring(6, 1), "1"))
+ {
+ this.TC = true;
+ }
+
+ if (String.Equals(flags.Substring(7, 1), "1"))
+ {
+ this.RD = true;
+ }
+
+ if (String.Equals(flags.Substring(7, 1), "1"))
+ {
+ this.RA = true;
+ }
+
+ this.Z = flags.Substring(8, 3);
+ this.RCode = flags.Substring(12, 4);
+ }
+
+ protected virtual void WriteFlags()
+ {
+ string flags = this.QR ? "1" : "0";
+ flags += this.Opcode;
+ flags += this.AA ? "1" : "0";
+ flags += this.TC ? "1" : "0";
+ flags += this.RD ? "1" : "0";
+ flags += this.RA ? "1" : "0";
+ flags += this.Z;
+ flags += this.RCode;
+ byte[] bytes = new byte[2];
+
+ for (int i = 0; i < 2; ++i)
+ {
+ bytes[i] = Convert.ToByte(flags.Substring(8 * i, 8), 2);
+ }
+
+ this.Flags = bytes;
+ }
+
+ public bool IsQuery()
+ {
+ if (!this.QR && this.QDCount == 1)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSPacket.cs b/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSPacket.cs
new file mode 100644
index 0000000..b18b50b
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSPacket.cs
@@ -0,0 +1,185 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Quiddity.DNS
+{
+ class DNSPacket
+ {
+ public DNSHeader Header { get; set; }
+ public DNSQuestion Question { get; set; }
+ public DNSResource Resource { get; set; }
+ public DNSResource Additional { get; set; }
+
+ public uint TTL { get; set; }
+ public string Host { get; set; }
+
+ enum ServicePort : ushort
+ {
+ Kerberos = 88,
+ LDAP = 389,
+ KPassword = 464,
+ GC = 3268
+ }
+
+ public DNSPacket()
+ {
+ }
+
+ public DNSPacket(byte[] data)
+ {
+ ReadBytes(data);
+ }
+
+ public DNSPacket ReadBytes(byte[] data)
+ {
+ this.Header = new DNSHeader(data);
+ this.Question = new DNSQuestion(data);
+ return this;
+ }
+
+ public byte[] GetBytes(uint ttl, uint serial, string replyIP, string replyIPv6)
+ {
+ byte[] rdata = new byte[0];
+ ushort arCount = 0;
+ ushort index = 12;
+ index |= (1 << 15); // set first 2 bits to 1 to indicate compression is being used
+ index |= (1 << 14);
+ byte[] indexData = BitConverter.GetBytes(index);
+ Array.Reverse(indexData);
+ byte[] nameData = this.Question.QName;
+
+ switch (this.Question.Type)
+ {
+ case "A":
+ arCount = 0;
+ rdata = new DNSRecordA(replyIP).GetBytes();
+ break;
+
+ case "AAAA":
+ arCount = 0;
+
+ if (!String.IsNullOrEmpty(replyIPv6))
+ {
+ rdata = new DNSRecordAAAA(replyIPv6).GetBytes();
+ }
+
+ break;
+
+ case "SRV":
+ arCount = 1;
+ nameData = indexData;
+ index += (ushort)(this.Question.QName.Length + 14);
+ ushort port = 0;
+
+ if (this.Question.Name.StartsWith("_ldap."))
+ {
+ port = (ushort)ServicePort.LDAP;
+ }
+ else if (this.Question.Name.StartsWith("_kerberos."))
+ {
+ port = (ushort)ServicePort.Kerberos;
+ }
+ else if (this.Question.Name.StartsWith("_kpassword."))
+ {
+ port = (ushort)ServicePort.KPassword;
+ }
+ else if (this.Question.Name.StartsWith("_gc."))
+ {
+ port = (ushort)ServicePort.GC;
+ }
+
+ rdata = new DNSRecordSRV().GetBytes(this.Host, port);
+ break;
+
+ case "SOA":
+ arCount = 1;
+ rdata = new DNSRecordSOA(serial).GetBytes(this.Host, 12);
+ index += (ushort)(this.Question.QName.Length + 14);
+ break;
+ }
+
+ this.Header = new DNSHeader
+ {
+ ID = this.Header.ID,
+ QR = true,
+ Opcode = "0000",
+ AA = false,
+ TC = false,
+ RD = false,
+ RA = false,
+ Z = "000",
+ RCode = "0000",
+ QDCount = 1,
+ ANCount = 1,
+ ARCount = arCount
+ };
+
+ this.Resource = new DNSResource
+ {
+ Name = nameData,
+ Type = this.Question.QType,
+ Class = this.Question.QClass,
+ TTL = ttl,
+ RDLength = (ushort)rdata.Length,
+ RData = rdata
+ };
+
+ if (arCount == 1)
+ {
+ this.Resource.Name = indexData;
+ indexData = BitConverter.GetBytes(index);
+ Array.Reverse(indexData);
+
+ this.Additional = new DNSResource
+ {
+ Name = indexData,
+ Type = new byte[] { 0x00, 0x01 },
+ Class = this.Question.QClass,
+ TTL = ttl,
+ RDLength = 4,
+ RData = new DNSRecordA(replyIP).GetBytes()
+ };
+
+ return Utilities.BlockCopy(this.Header.GetBytes(), this.Question.GetBytes(), this.Resource.GetBytes(), this.Additional.GetBytes());
+ }
+
+ return Utilities.BlockCopy(this.Header.GetBytes(), this.Question.GetBytes(), this.Resource.GetBytes());
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSQuestion.cs b/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSQuestion.cs
new file mode 100644
index 0000000..34e2fcb
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSQuestion.cs
@@ -0,0 +1,193 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.IO;
+using System.Text;
+
+namespace Quiddity.DNS
+{
+ class DNSQuestion
+ {
+
+ // https://tools.ietf.org/html/rfc1035
+ public byte[] QName { get; set; }
+ public byte[] QType { get; set; }
+ public byte[] QClass { get; set; }
+
+ // Custom
+ public string Name { get; set; }
+ public string Type { get; set; }
+
+ public DNSQuestion()
+ {
+ this.QName = new byte[0];
+ this.QType = new byte[0];
+ this.QClass = new byte[0];
+ }
+
+ public DNSQuestion(byte[] data)
+ {
+ ReadBytes(data, 12);
+ }
+
+ public DNSQuestion(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+ int segmentLength = data[offset];
+ int lengthIndex = offset;
+ int length = segmentLength + 1;
+
+ do
+ {
+ lengthIndex += segmentLength + 1;
+ segmentLength = data[lengthIndex];
+ length += segmentLength + 1;
+ }
+ while (segmentLength != 0);
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.QName = packetReader.ReadBytes(length);
+ this.QType = packetReader.ReadBytes(2);
+ this.QClass = packetReader.ReadBytes(2);
+ }
+
+ this.Name = ConvertName();
+ this.Type = GetType();
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.QName);
+ packetWriter.Write(this.QType);
+ packetWriter.Write(this.QClass);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ protected virtual string ConvertName()
+ {
+ string hostname = "";
+ int hostnameLength = this.QName[0];
+ int index = 0;
+ int i = 0;
+
+ do
+ {
+ int hostnameSegmentLength = hostnameLength;
+ byte[] hostnameSegment = new byte[hostnameSegmentLength];
+ Buffer.BlockCopy(this.QName, (index + 1), hostnameSegment, 0, hostnameSegmentLength);
+ hostname += Encoding.UTF8.GetString(hostnameSegment);
+ index += hostnameLength + 1;
+ hostnameLength = this.QName[index];
+ i++;
+
+ if (hostnameLength > 0)
+ {
+ hostname += ".";
+ }
+
+ }
+ while (hostnameLength != 0 && i <= 127);
+
+ return hostname;
+ }
+
+ protected new virtual string GetType()
+ {
+ string type = "";
+
+ switch (BitConverter.ToString(this.QType))
+ {
+
+ case "00-01":
+ type = "A";
+ break;
+
+ case "00-1C":
+ type = "AAAA";
+ break;
+
+ case "00-05":
+ type = "CNAME";
+ break;
+
+ case "00-27":
+ type = "DNAME";
+ break;
+
+ case "00-0F":
+ type = "MX";
+ break;
+
+ case "00-02":
+ type = "NS";
+ break;
+
+ case "00-0C":
+ type = "PTR";
+ break;
+
+ case "00-06":
+ type = "SOA";
+ break;
+
+ case "00-21":
+ type = "SRV";
+ break;
+
+ case "00-10":
+ type = "TXT";
+ break;
+
+ case "00-FF":
+ type = "ANY";
+ break;
+
+ }
+
+ return type;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSResource.cs b/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSResource.cs
new file mode 100644
index 0000000..258a08c
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DNS/DNSResource.cs
@@ -0,0 +1,122 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System.IO;
+using System.Net;
+
+namespace Quiddity.DNS
+{
+
+ class DNSResource
+ {
+
+ // https://tools.ietf.org/html/rfc1035
+ public byte[] Name { get; set; }
+ public byte[] Type { get; set; }
+ public byte[] Class { get; set; }
+ public uint TTL { get; set; }
+ public ushort RDLength{ get; set; }
+ public byte[] RData { get; set; }
+
+ //custom
+ public string Host { get; set; }
+
+ public DNSResource()
+ {
+
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.Name = packetReader.ReadBytes(2);
+ this.Type = packetReader.ReadBytes(2);
+ this.Class = packetReader.ReadBytes(2);
+ this.TTL = packetReader.ReadUInt32();
+ this.RDLength = packetReader.ReadUInt16();
+ this.RData = packetReader.ReadBytes(this.RDLength);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.Name);
+ packetWriter.Write(this.Type);
+ packetWriter.Write(this.Class);
+ packetWriter.BigEndianWrite(this.TTL);
+ packetWriter.BigEndianWrite(this.RDLength);
+ packetWriter.Write(this.RData);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ public byte[] GetBytes(DNSQuestion RequestQuestion, uint ttl, string data, byte[] id)
+ {
+ byte[] rdata = IPAddress.Parse(data).GetAddressBytes();
+
+ DNSHeader responseHeader = new DNSHeader
+ {
+ ID = id,
+ QR = true,
+ Opcode = "0000",
+ AA = false,
+ TC = false,
+ RD = false,
+ RA = false,
+ Z = "000",
+ RCode = "0000",
+ QDCount = 1,
+ ANCount = 1
+ };
+
+ this.Name = RequestQuestion.QName;
+ this.Type = RequestQuestion.QType;
+ this.Class = RequestQuestion.QClass;
+ this.TTL = ttl;
+ this.RDLength = (ushort)rdata.Length;
+ this.RData = rdata;
+
+ return Utilities.BlockCopy(responseHeader.GetBytes(), RequestQuestion.GetBytes(), this.GetBytes());
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordA.cs b/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordA.cs
new file mode 100644
index 0000000..7d15405
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordA.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Quiddity.DNS
+{
+ class DNSRecordA
+ {
+ public byte[] Address { get; set; }
+
+ public DNSRecordA()
+ {
+
+ }
+
+ public DNSRecordA(string address)
+ {
+ this.Address = IPAddress.Parse(address).GetAddressBytes();
+ }
+ public byte[] GetBytes()
+ {
+ return this.Address;
+ }
+
+ public byte[] GetBytes(string address)
+ {
+ return IPAddress.Parse(address).GetAddressBytes();
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordAAAA.cs b/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordAAAA.cs
new file mode 100644
index 0000000..ca63c6b
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordAAAA.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Quiddity.DNS
+{
+ class DNSRecordAAAA
+ {
+
+ public byte[] Address { get; set; }
+
+ public DNSRecordAAAA()
+ {
+
+ }
+
+ public DNSRecordAAAA(string address)
+ {
+ this.Address = IPAddress.Parse(address).GetAddressBytes();
+ }
+ public byte[] GetBytes()
+ {
+ return this.Address;
+ }
+
+ public byte[] GetBytes(string address)
+ {
+ return IPAddress.Parse(address).GetAddressBytes();
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordSOA.cs b/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordSOA.cs
new file mode 100644
index 0000000..23fcfe7
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordSOA.cs
@@ -0,0 +1,85 @@
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DNS
+{
+ class DNSRecordSOA
+ {
+ // https://tools.ietf.org/html/rfc1035
+ public byte[] MName { get; set; }
+ public byte[] RName { get; set; }
+ public uint Serial { get; set; }
+ public uint Refresh { get; set; }
+ public uint Retry { get; set; }
+ public uint Expire { get; set; }
+ public uint Minium { get; set; }
+
+ public DNSRecordSOA()
+ {
+ this.Refresh = 900;
+ this.Retry = 600;
+ this.Expire = 86400;
+ this.Minium = 3600;
+ }
+
+ public DNSRecordSOA(uint serial)
+ {
+ this.Serial = serial;
+ this.Refresh = 900;
+ this.Retry = 600;
+ this.Expire = 86400;
+ this.Minium = 3600;
+ }
+
+ public byte[] GetBytes()
+ {
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.MName);
+ packetWriter.Write(this.RName);
+ packetWriter.BigEndianWrite(this.Serial);
+ packetWriter.BigEndianWrite(this.Refresh);
+ packetWriter.BigEndianWrite(this.Retry);
+ packetWriter.BigEndianWrite(this.Expire);
+ packetWriter.BigEndianWrite(this.Minium);
+ return memoryStream.ToArray();
+ }
+ }
+
+ public byte[] GetBytes(string host, ushort index)
+ {
+ index |= (1 << 15);
+ index |= (1 << 14);
+ byte[] indexData = BitConverter.GetBytes(index);
+ Array.Reverse(indexData);
+
+ byte[] hostData = Utilities.GetDNSNameBytes(host, false);
+ byte[] hostCompressed = new byte[hostData[0] + 3];
+ Buffer.BlockCopy(hostData, 0, hostCompressed, 0, hostData[0] + 1);
+ Buffer.BlockCopy(indexData, 0, hostCompressed, hostCompressed.Length - 2, 2);
+ byte[] authoritytData = Utilities.GetDNSNameBytes("hostmaster", false);
+ byte[] authorityCompressed = new byte[authoritytData[0] + 3];
+ Buffer.BlockCopy(authoritytData, 0, authorityCompressed, 0, authoritytData[0] + 1);
+ Buffer.BlockCopy(indexData, 0, authorityCompressed, authorityCompressed.Length - 2, 2);
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(hostCompressed);
+ packetWriter.Write(authorityCompressed);
+ packetWriter.BigEndianWrite(this.Serial);
+ packetWriter.BigEndianWrite(this.Refresh);
+ packetWriter.BigEndianWrite(this.Retry);
+ packetWriter.BigEndianWrite(this.Expire);
+ packetWriter.BigEndianWrite(this.Minium);
+ return memoryStream.ToArray();
+ }
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordSRV.cs b/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordSRV.cs
new file mode 100644
index 0000000..391b671
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/DNS/RDATA/DNSRecordSRV.cs
@@ -0,0 +1,42 @@
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.DNS
+{
+ class DNSRecordSRV : DNSResource
+ {
+ // https://datatracker.ietf.org/doc/html/rfc2782
+ public byte[] Service { get; set; }
+ public byte[] Proto { get; set; }
+ public ushort Priority { get; set; }
+ public ushort Weight { get; set; }
+ public ushort Port { get; set; }
+ public byte[] Target { get; set; }
+
+ public DNSRecordSRV()
+ {
+ this.Priority = 0;
+ this.Weight = 100;
+ }
+
+ public byte[] GetBytes(string target, ushort port)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.Priority);
+ packetWriter.BigEndianWrite(this.Weight);
+ packetWriter.BigEndianWrite(port);
+ packetWriter.Write(Utilities.GetDNSNameBytes(target, true));
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/GSSAPI/GSSAPIInitSecContext.cs b/Inveigh/Protocols/Quiddity/Protocols/GSSAPI/GSSAPIInitSecContext.cs
new file mode 100644
index 0000000..34c70cb
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/GSSAPI/GSSAPIInitSecContext.cs
@@ -0,0 +1,49 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace Quiddity.GSSAPI
+{
+ class GSSAPIInitSecContext
+ {
+
+ /*
+ https://tools.ietf.org/html/rfc4178#appendix-A
+ */
+ public byte[] OID { get; set; }
+
+ public GSSAPIInitSecContext()
+ {
+ this.OID = new byte[8] { 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 } ;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/HTTP/HTTPRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/HTTP/HTTPRequest.cs
new file mode 100644
index 0000000..7423081
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/HTTP/HTTPRequest.cs
@@ -0,0 +1,159 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.HTTP
+{
+ class HTTPRequest
+ {
+ public string Method { get; set; }
+ public string URI { get; set; }
+ public string Version { get; set; }
+ public string Host { get; set; }
+ public string Connection { get; set; }
+ public string UserAgent { get; set; }
+ public string Accept { get; set; }
+ public string AcceptEncoding { get; set; }
+ public string AcceptLanguage { get; set; }
+ public string Authorization { get; set; }
+ public string ProxyAuthorization { get; set; }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ int index = Array.IndexOf<byte>(data, 0x20, 0);
+
+ if (index > -1)
+ {
+ this.Method = Encoding.UTF8.GetString(packetReader.ReadBytes(index));
+ memoryStream.Position++;
+ index = Array.IndexOf<byte>(data, 0x20, (int)memoryStream.Position);
+
+ if (index > -1)
+ {
+ index -= (int)memoryStream.Position;
+ this.URI = Encoding.UTF8.GetString(packetReader.ReadBytes(index));
+ memoryStream.Position++;
+ index = Array.IndexOf<byte>(data, 0x0d, (int)memoryStream.Position);
+
+ if (index > -1)
+ {
+ index -= (int)memoryStream.Position;
+ this.Version = Encoding.UTF8.GetString(packetReader.ReadBytes(index));
+ memoryStream.Position += 2;
+ }
+
+ }
+
+ }
+
+ while (index > -1)
+ {
+ index = Array.IndexOf<byte>(data, 0x20, (int)memoryStream.Position);
+
+ if (index > -1)
+ {
+ index -= (int)memoryStream.Position;
+ string field = Encoding.UTF8.GetString(packetReader.ReadBytes(index));
+ memoryStream.Position++;
+ index = Array.IndexOf<byte>(data, 0x0d, (int)memoryStream.Position);
+ index -= (int)memoryStream.Position;
+
+ if (index > -1)
+ {
+ string value = Encoding.UTF8.GetString(packetReader.ReadBytes(index));
+ GetField(field, value);
+ }
+
+ memoryStream.Position += 2;
+ }
+
+ }
+
+ }
+
+ }
+
+ public void GetField(string field, string value)
+ {
+
+ switch (field.ToUpper())
+ {
+
+ case "HOST:":
+ this.Host = value;
+ break;
+
+ case "CONNECTION:":
+ this.Connection = value;
+ break;
+
+ case "USER-AGENT:":
+ this.UserAgent = value;
+ break;
+
+ case "ACCEPT:":
+ this.Accept = value;
+ break;
+
+ case "ACCEPT-ENCODING:":
+ this.AcceptEncoding = value;
+ break;
+
+ case "ACCEPT-LANGUAGE:":
+ this.AcceptLanguage = value;
+ break;
+
+ case "AUTHORIZATION:":
+ this.Authorization = value;
+ break;
+
+ case "PROXY-AUTHORIZATION:":
+ this.ProxyAuthorization = value;
+ break;
+
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/HTTP/HTTPResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/HTTP/HTTPResponse.cs
new file mode 100644
index 0000000..4ac632d
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/HTTP/HTTPResponse.cs
@@ -0,0 +1,166 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.HTTP
+{
+ class HTTPResponse
+ {
+ public string Version { get; set; }
+ public string StatusCode { get; set; }
+ public string ReasonPhrase { get; set; }
+ public string Server { get; set; }
+ public string Date { get; set; }
+ public string ContentType { get; set; }
+ public string ContentLength { get; set; }
+ public string Connection { get; set; }
+ public string CacheControl { get; set; }
+ public string Allow { get; set; }
+ public string Public { get; set; }
+ public string DAV { get; set; }
+ public string Author { get; set; }
+ public string ProxyAuthenticate { get; set; }
+ public string WWWAuthenticate { get; set; }
+ public byte[] Message { get; set; }
+
+ public byte[] GetBytes()
+ {
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.Message))
+ {
+ this.ContentLength = Convert.ToString(this.Message.Length);
+ }
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.StringWrite(this.Version);
+ packetWriter.Write(new byte[1] { 0x20 });
+ packetWriter.StringWrite(this.StatusCode);
+ packetWriter.Write(new byte[1] { 0x20 });
+ packetWriter.StringWrite(this.ReasonPhrase);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+
+ if (!String.IsNullOrEmpty(this.Connection))
+ {
+ packetWriter.StringWrite("Connection: ");
+ packetWriter.StringWrite(this.Connection);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+ }
+
+ if (!String.IsNullOrEmpty(this.Allow))
+ {
+ packetWriter.StringWrite("Allow: ");
+ packetWriter.StringWrite(this.Allow);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+ }
+
+ if (!String.IsNullOrEmpty(this.Public))
+ {
+ packetWriter.StringWrite("Public: ");
+ packetWriter.StringWrite(this.Public);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+ }
+
+ if (!String.IsNullOrEmpty(this.DAV))
+ {
+ packetWriter.StringWrite("DAV: ");
+ packetWriter.StringWrite(this.DAV);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+ }
+
+ if (!String.IsNullOrEmpty(this.Author))
+ {
+ packetWriter.StringWrite("MS-Author-via: ");
+ packetWriter.StringWrite(this.Author);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+ }
+
+ if (!String.IsNullOrEmpty(this.Server))
+ {
+ packetWriter.StringWrite("Server: ");
+ packetWriter.StringWrite(this.Server);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+ }
+
+ if (!String.IsNullOrEmpty(this.Date))
+ {
+ packetWriter.StringWrite("Date: ");
+ packetWriter.StringWrite(this.Date);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+ }
+
+ packetWriter.StringWrite("Content-Length: ");
+ packetWriter.StringWrite(this.ContentLength);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+
+ if (!String.IsNullOrEmpty(this.ProxyAuthenticate))
+ {
+ packetWriter.StringWrite("Proxy-Authenticate: ");
+ packetWriter.StringWrite(this.ProxyAuthenticate);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+ }
+
+ if (!String.IsNullOrEmpty(this.WWWAuthenticate))
+ {
+ packetWriter.StringWrite("WWW-Authenticate: ");
+ packetWriter.StringWrite(this.WWWAuthenticate);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+ }
+
+ if (!String.IsNullOrEmpty(this.ContentType))
+ {
+ packetWriter.StringWrite("Content-Type: ");
+ packetWriter.StringWrite(this.ContentType);
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+ }
+
+ packetWriter.Write(new byte[2] { 0x0d, 0x0a });
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.Message))
+ {
+ packetWriter.Write(this.Message);
+ }
+
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/ICMPv6/ICMPv6RouterAdvertisement.cs b/Inveigh/Protocols/Quiddity/Protocols/ICMPv6/ICMPv6RouterAdvertisement.cs
new file mode 100644
index 0000000..fec13c4
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/ICMPv6/ICMPv6RouterAdvertisement.cs
@@ -0,0 +1,107 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.ICMPv6
+{
+ class ICMPv6RouterAdvertisement
+ {
+ // https://datatracker.ietf.org/doc/html/rfc4861#section-4.2
+ public byte Type { get; set; }
+ public byte Code { get; set; }
+ public ushort Checksum { get; set; }
+ public byte CurHopLimit { get; set; }
+ public bool M{ get; set; } // 1 bit
+ public bool O { get; set; } // 1 bit
+ public string Reserved { get; set; } // 6 bits
+ public ushort RouterLifeTime { get; set; }
+ public uint ReachableTime { get; set; }
+ public uint RetransTimer { get; set; }
+ public byte[] Options { get; set; }
+
+ // custom fields
+ public byte Flags { get; set; }
+
+ public ICMPv6RouterAdvertisement()
+ {
+ this.Type = 134;
+ this.Code = 0;
+ this.Checksum = 0;
+ this.Flags = 0;
+ this.RouterLifeTime = 0;
+ this.ReachableTime = 0;
+ this.RetransTimer = 0;
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.Type);
+ packetWriter.Write(this.Code);
+ packetWriter.Write(this.Checksum);
+ packetWriter.Write(this.CurHopLimit);
+ packetWriter.Write(this.Flags);
+ packetWriter.BigEndianWrite(this.RouterLifeTime);
+ packetWriter.BigEndianWrite(this.ReachableTime);
+ packetWriter.BigEndianWrite(this.RetransTimer);
+
+ if (!Utilities.ArrayIsNullOrEmpty(Options))
+ {
+ packetWriter.Write(this.Options);
+ }
+
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ protected virtual void WriteFlags()
+ {
+ string flags = this.M ? "1" : "0";
+ flags += this.O ? "1" : "0";
+ flags += this.Reserved;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ this.Flags = Convert.ToByte(flags.Substring(8 * i, 8), 1); ;
+ }
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/ICMPv6/Options/ICMPv6DNSSearchList.cs b/Inveigh/Protocols/Quiddity/Protocols/ICMPv6/Options/ICMPv6DNSSearchList.cs
new file mode 100644
index 0000000..7eef831
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/ICMPv6/Options/ICMPv6DNSSearchList.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.ICMPv6
+{
+ class ICMPv6DNSSearchList
+ {
+ // https://datatracker.ietf.org/doc/html/rfc8106
+ public byte Type { get; set; }
+ public byte Length { get; set; }
+ public ushort Reserved { get; set; }
+ public uint Lifetime { get; set; }
+ public byte[] DomainNames { get; set; }
+
+ public ICMPv6DNSSearchList()
+ {
+ this.Type = 31;
+ this.Length = 0;
+ this.Reserved = 0;
+ this.Lifetime = 0;
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.Type);
+ packetWriter.Write(this.Length);
+ packetWriter.Write(this.Reserved);
+ packetWriter.BigEndianWrite(this.Lifetime);
+ packetWriter.Write(this.DomainNames);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/ICMPv6/Options/ICMPv6RecursiveDNS.cs b/Inveigh/Protocols/Quiddity/Protocols/ICMPv6/Options/ICMPv6RecursiveDNS.cs
new file mode 100644
index 0000000..2fa9f31
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/ICMPv6/Options/ICMPv6RecursiveDNS.cs
@@ -0,0 +1,73 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.ICMPv6
+{
+ class ICMPv6RecursiveDNS
+ {
+ // https://datatracker.ietf.org/doc/html/rfc5006#section-5.1
+ public byte Type { get; set; }
+ public byte Length { get; set; }
+ public ushort Reserved { get; set; }
+ public uint Lifetime { get; set; }
+ public byte[] RecursiveDNSServers { get; set; }
+
+ public ICMPv6RecursiveDNS()
+ {
+ this.Type = 25;
+ this.Length = 0;
+ this.Reserved = 0;
+ this.Lifetime = 0;
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.Type);
+ packetWriter.Write(this.Length);
+ packetWriter.Write(this.Reserved);
+ packetWriter.BigEndianWrite(this.Lifetime);
+ packetWriter.Write(this.RecursiveDNSServers);
+ return memoryStream.ToArray();
+ }
+
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/IP/IPHeader.cs b/Inveigh/Protocols/Quiddity/Protocols/IP/IPHeader.cs
new file mode 100644
index 0000000..80194ab
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/IP/IPHeader.cs
@@ -0,0 +1,81 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.IO;
+using System.Net;
+
+namespace Quiddity.IP
+{
+ class IPHeader
+ {
+ // https://datatracker.ietf.org/doc/html/rfc791#section-3.1
+ public int Version { get; set; }
+ public int IHL { get; set; }
+ public byte TypeOfService { get; set; }
+ public ushort TotalLength { get; set; }
+ public ushort Identification { get; set; }
+ public string Flags { get; set; }
+ public int FragmentOffset { get; set; }
+ public byte TimeToLive { get; set; }
+ public byte Protocol { get; set; }
+ public ushort HeaderChecksum { get; set; }
+ public IPAddress SourceAddress { get; set; }
+ public IPAddress DestinationAddress { get; set; }
+ public byte[] Options { get; set; }
+ public byte[] Padding { get; set; }
+
+ public void ReadBytes(byte[] data, int position)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = position;
+ string versionIHL = packetReader.ReadBinary(1);
+ this.Version = Convert.ToInt32(versionIHL.Substring(0, 4), 2);
+ this.IHL = Convert.ToInt32(versionIHL.Substring(4, 4), 2) * 4;
+ this.TypeOfService = packetReader.ReadByte();
+ this.TotalLength = packetReader.BigEndianReadUInt16();
+ this.Identification = packetReader.BigEndianReadUInt16();
+ string flagsFragmentOffset = packetReader.ReadBinary(2);
+ this.Flags = flagsFragmentOffset.Substring(0, 3);
+ this.FragmentOffset = Convert.ToInt32(flagsFragmentOffset.Substring(3, 13), 2);
+ this.TimeToLive = packetReader.ReadByte();
+ this.Protocol = packetReader.ReadByte();
+ this.HeaderChecksum = packetReader.BigEndianReadUInt16();
+ this.SourceAddress = new IPAddress(packetReader.ReadBytes(4));
+ this.DestinationAddress = new IPAddress(packetReader.ReadBytes(4));
+ }
+
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/LDAPMessage.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/LDAPMessage.cs
new file mode 100644
index 0000000..18445ba
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/LDAPMessage.cs
@@ -0,0 +1,182 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.DirectoryServices.Protocols;
+using Quiddity.Support;
+
+namespace Quiddity.LDAP
+{
+ // https://datatracker.ietf.org/doc/html/rfc2251#section-4.2
+ class LDAPMessage
+ {
+ public int MessageID { get; set; }
+ public object ProtocolOp { get; set; }
+ public byte[] Controls { get; set; }
+
+ //custom
+
+ public int Tag { get; set; }
+
+ public byte[] Encode()
+ {
+ return BerConverter.Encode("{iX}", this.MessageID, this.ProtocolOp);
+ }
+
+ public byte[] Encode(int type)
+ {
+
+ switch (type)
+ {
+
+ case 3:
+ {
+ LDAPBindResponse protocolOp = (LDAPBindResponse)this.ProtocolOp;
+ return BerConverter.Encode("{it{eooto}}", this.MessageID, 0x61, protocolOp.ResultCode, protocolOp.MatchedDN, protocolOp.DiagnosticMessage, 0x87, protocolOp.ServerSaslCreds);
+ }
+
+ case 4:
+ {
+ LDAPSearchResEntry protocolOp = (LDAPSearchResEntry)this.ProtocolOp;
+ return BerConverter.Encode("{it{sto}}", this.MessageID, 0x64, protocolOp.ObjectDN, 0x30, protocolOp.Attributes);
+ }
+
+ case 5:
+ {
+ LDAPSearchResDone protocolOp = (LDAPSearchResDone)this.ProtocolOp;
+ return BerConverter.Encode("{it{eoo}}", this.MessageID, 0x65, protocolOp.ResultCode, protocolOp.MatchedDN, protocolOp.ErrorMessage);
+ }
+
+ }
+
+ return null;
+ }
+
+ public byte[] Encode(LDAPSearchResDone resdone)
+ {
+ return BerConverter.Encode("{it{eoo}}", this.MessageID, 0x65, resdone.ResultCode, resdone.MatchedDN, resdone.ErrorMessage);
+ }
+
+ public byte[] Encode(LDAPSearchResEntry search)
+ {
+ return BerConverter.Encode("{it{stX}}", this.MessageID, 0x64, search.ObjectDN, 0x30, search.Attributes);
+ }
+
+ public void Decode(byte[] data)
+ {
+ this.Tag = GetMessageType(data);
+ object[] message = BerConverter.Decode("{iV}", data);
+ this.MessageID = (int)message[0];
+ this.ProtocolOp = message[1];
+ }
+
+ public static int GetLength(int index, byte[] data)
+ {
+ int length = 0;
+
+ switch (data[index])
+ {
+
+ case 0x84:
+ {
+ index++;
+ byte[] valueLength = new byte[4];
+ Buffer.BlockCopy(data, index, valueLength, 0, 4);
+ Array.Reverse(valueLength);
+ length = BitConverter.ToInt32(valueLength, 0);
+ length += 4;
+ }
+ break;
+
+ }
+
+ return length;
+ }
+
+ public static int GetMessageType(byte[]data)
+ {
+ int type = -1;
+ int index = 1;
+ byte tag;
+ int valueLength = data[index++];
+
+ if ((valueLength & 0x80) == 0x80)
+ {
+ int length = valueLength & 0x7f;
+ valueLength = 0;
+
+ for (int i = 0; i < length; i++)
+ {
+ valueLength = valueLength * 256 + data[index++];
+ }
+
+ }
+ else
+ {
+ index += valueLength;
+ }
+
+ index++;
+ valueLength = data[index];
+
+ if ((valueLength & 0x80) == 0x80)
+ {
+ int length = valueLength & 0x7f;
+ valueLength = 0;
+
+ for (int i = 0; i < length; i++)
+ {
+ valueLength = valueLength * 256 + data[index++];
+ }
+
+ }
+ else
+ {
+ index += valueLength;
+ }
+
+ index++;
+ tag = data[index];
+
+ if ((tag & 0x60) == 0x60 || (tag & 0x40) == 0x40)
+ {
+ type = tag & 0x1f;
+ }
+
+ return type;
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPBindRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPBindRequest.cs
new file mode 100644
index 0000000..8d10047
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPBindRequest.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.LDAP
+{
+ class LDAPBindRequest
+ {
+ public byte[] Version { get; set; }
+ public byte[] Name { get; set; }
+ public byte[] Authentication { get; set; }
+
+ public void ReadBytes(byte[][] Data)
+ {
+ this.Version = (byte[])Data.GetValue(0);
+ this.Name = (byte[])Data.GetValue(1);
+ this.Authentication = (byte[])Data.GetValue(2);
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPBindResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPBindResponse.cs
new file mode 100644
index 0000000..26720cd
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPBindResponse.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.LDAP
+{
+ class LDAPBindResponse : LDAPResult
+ {
+ public byte[] ServerSaslCreds { get; set; }
+
+ public LDAPBindResponse()
+ {
+ this.ResultCode = 14;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPPartialAttributeList.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPPartialAttributeList.cs
new file mode 100644
index 0000000..43f565b
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPPartialAttributeList.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.LDAP
+{
+ class LDAPPartialAttributeList
+ {
+ public string Type { get; set; }
+ public string[] Vals { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchRequest.cs
new file mode 100644
index 0000000..ee697b7
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchRequest.cs
@@ -0,0 +1,46 @@
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.DirectoryServices.Protocols;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.LDAP
+{
+ class LDAPSearchRequest
+ {
+ public byte[] BaseObject { get; set; }
+ public byte[] Scope { get; set; }
+ public byte[] DerefAliases { get; set; }
+ public byte[] SizeLimit { get; set; }
+ public byte[] TimeLimit { get; set; }
+ public byte[] TypesOnly { get; set; }
+ public byte[] Filter { get; set; }
+ public string[] Attributes { get; set; }
+
+ public void ReadBytes(byte[][] Data)
+ {
+ this.BaseObject = (byte[])Data.GetValue(0);
+ this.Scope = (byte[])Data.GetValue(1);
+ this.DerefAliases = (byte[])Data.GetValue(2);
+ this.SizeLimit = (byte[])Data.GetValue(3);
+ this.TimeLimit = (byte[])Data.GetValue(4);
+ this.TypesOnly = (byte[])Data.GetValue(5);
+ this.Filter = (byte[])Data.GetValue(6);
+ this.Attributes = ASN1.DecodeOctetStringArray((byte[])Data.GetValue(7));
+ }
+
+ public object[] Decode(byte[] Data)
+ {
+ return BerConverter.Decode("{OiiiiiOO}", Data);
+ }
+
+ public object[] Decode2(byte[] Data)
+ {
+ return BerConverter.Decode("{B}", Data);
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchResDone.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchResDone.cs
new file mode 100644
index 0000000..a62f9a5
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchResDone.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.DirectoryServices.Protocols;
+
+namespace Quiddity.LDAP
+{
+ class LDAPSearchResDone
+ {
+ public int ResultCode { get; set; }
+ public byte[] MatchedDN { get; set; }
+ public byte[] ErrorMessage { get; set; }
+
+ public byte[] Encode()
+ {
+ return BerConverter.Encode("t{eoo}", 0x65, this.ResultCode, this.MatchedDN, this.ErrorMessage); ;
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchResEntry.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchResEntry.cs
new file mode 100644
index 0000000..c1a6f1e
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/ProtocolOp/LDAPSearchResEntry.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.DirectoryServices.Protocols;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.LDAP
+{
+ class LDAPSearchResEntry
+ {
+ public string ObjectDN { get; set; }
+ public byte[] Attributes { get; set; }
+
+ public byte[] Encode()
+ {
+ return BerConverter.Encode("t{stX}", new object[] { 0x64, this.ObjectDN, 0x30, this.Attributes } );
+ }
+
+ public byte[] Encode(Object[] Segment)
+ {
+ return BerConverter.Encode("t{s{V}}", 0x64, this.ObjectDN, Segment);
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPResult.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPResult.cs
new file mode 100644
index 0000000..5d53155
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPResult.cs
@@ -0,0 +1,46 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.LDAP
+{
+ class LDAPResult
+ {
+ public int ResultCode { get; set; }
+ public byte[] MatchedDN { get; set; }
+ public byte[] DiagnosticMessage { get; set; }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSaslCredentials.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSaslCredentials.cs
new file mode 100644
index 0000000..a9f9670
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSaslCredentials.cs
@@ -0,0 +1,52 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.LDAP
+{
+ class LDAPSaslCredentials
+ {
+ public string Mechanism { get; set; }
+ public byte[] Credentials { get; set; }
+
+ public void ReadBytes(byte[] Data)
+ {
+ this.Mechanism = Encoding.UTF8.GetString(ASN1.GetTagBytes(4, Data));
+ this.Credentials = ASN1.GetTagBytes(4, Data, ASN1.GetLength(1, Data));
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSupportedCapabilities.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSupportedCapabilities.cs
new file mode 100644
index 0000000..087889b
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSupportedCapabilities.cs
@@ -0,0 +1,55 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.DirectoryServices.Protocols;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.LDAP
+{
+ class LDAPSupportedCapabilities : LDAPPartialAttributeList
+ {
+
+ public LDAPSupportedCapabilities()
+ {
+ this.Type = "supportedCapabilities";
+ this.Vals = new string[] { "1.2.840.113556.1.4.800", "1.2.840.113556.1.4.1670", "1.2.840.113556.1.4.1791", "1.2.840.113556.1.4.1935", "1.2.840.113556.1.4.2080", "1.2.840.113556.1.4.2237" };
+ }
+
+ public byte[] Encode()
+ {
+ return BerConverter.Encode("{st{v}}", this.Type, 0x31, this.Vals);
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSupportedSASLMechanisms.cs b/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSupportedSASLMechanisms.cs
new file mode 100644
index 0000000..3db038e
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LDAP/Values/LDAPSupportedSASLMechanisms.cs
@@ -0,0 +1,56 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.LDAP;
+using System;
+using System.Collections.Generic;
+using System.DirectoryServices.Protocols;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.LDAP
+{
+ class LDAPSupportedSASLMechanisms : LDAPPartialAttributeList
+ {
+
+ public LDAPSupportedSASLMechanisms()
+ {
+ this.Type = "supportedSASLMechanisms";
+ this.Vals = new string[] { "GSSAPI", "GSS-SPNEGO", "EXTERNAL", "DIGESTMD5" };
+ }
+
+ public byte[] Encode()
+ {
+ return BerConverter.Encode("{st{v}}", this.Type, 0x31, this.Vals);
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRChecker.cs b/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRChecker.cs
new file mode 100644
index 0000000..c1ca969
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRChecker.cs
@@ -0,0 +1,41 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DNS;
+
+namespace Quiddity.LLMNR
+{
+ class LLMNRChecker : DNSChecker
+ {
+
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRHeader.cs b/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRHeader.cs
new file mode 100644
index 0000000..8df7faa
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRHeader.cs
@@ -0,0 +1,130 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DNS;
+using System;
+
+namespace Quiddity.LLMNR
+{
+ class LLMNRHeader : DNSHeader
+ {
+ // https://tools.ietf.org/html/rfc4795#section-2.1
+
+ public bool C { get; set; } // 1 bit
+ public bool T { get; set; } // 1 bit
+
+ public LLMNRHeader()
+ {
+
+ }
+
+ public LLMNRHeader (byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public byte[] GetPacket(uint ttl, string ip, string ipv6, byte[] data, out string name, out string type)
+ {
+ this.ReadBytes(data, 0);
+ name = "";
+ type = "A";
+
+ if (!this.QR)
+ {
+ LLMNRQuestion question = new LLMNRQuestion();
+ question.ReadBytes(data, 12);
+
+ if (string.Equals(BitConverter.ToString(question.QType), "00-1C"))
+ {
+ type = "AAAA";
+ ip = ipv6;
+ }
+
+ LLMNRResource response = new LLMNRResource();
+ return response.GetBytes(question, ttl, ip, this.ID);
+ }
+
+ return null;
+ }
+
+
+ protected override void ReadFlags()
+ {
+ string flags = Convert.ToString(BitConverter.ToUInt16(this.Flags, 0), 2).PadLeft(16, '0');
+
+ if (string.Equals(flags.Substring(0, 1), "1"))
+ {
+ this.QR = true;
+ }
+
+ this.Opcode = flags.Substring(1, 4);
+
+ if (string.Equals(flags.Substring(5, 1), "1"))
+ {
+ this.C = true;
+ }
+
+ if (string.Equals(flags.Substring(6, 1), "1"))
+ {
+ this.TC = true;
+ }
+
+ if (string.Equals(flags.Substring(7, 1), "1"))
+ {
+ this.T = true;
+ }
+
+ this.Z = flags.Substring(8, 4);
+ this.RCode = flags.Substring(12, 4);
+ }
+
+ protected override void WriteFlags()
+ {
+ string flags = this.QR ? "1" : "0";
+ flags += this.Opcode;
+ flags += this.C ? "1" : "0";
+ flags += this.TC ? "1" : "0";
+ flags += this.T ? "1" : "0";
+ flags += this.Z;
+ flags += this.RCode;
+ byte[] bytes = new byte[2];
+
+ for (int i = 0; i < 2; ++i)
+ {
+ bytes[i] = Convert.ToByte(flags.Substring(8 * i, 8), 2);
+ }
+
+ this.Flags = bytes;
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRPacket.cs b/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRPacket.cs
new file mode 100644
index 0000000..c424a82
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRPacket.cs
@@ -0,0 +1,98 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.LLMNR;
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Quiddity.LLMNR
+{
+ class LLMNRPacket
+ {
+ public LLMNRHeader Header { get; set; }
+ public LLMNRQuestion Question { get; set; }
+ public LLMNRResource Resource { get; set; }
+
+ public LLMNRPacket(byte[] data)
+ {
+ ReadBytes(data);
+ }
+
+ public LLMNRPacket ReadBytes(byte[] data)
+ {
+ this.Header = new LLMNRHeader(data);
+ this.Question = new LLMNRQuestion(data);
+ return this;
+ }
+
+ public byte[] GetBytes(uint ttl, string replyIP, string replyIPv6)
+ {
+
+ if (string.Equals(this.Question.Type, "AAAA") && !String.IsNullOrEmpty(replyIPv6))
+ {
+ replyIP = replyIPv6;
+ }
+
+ byte[] rdata = IPAddress.Parse(replyIP).GetAddressBytes();
+
+ this.Header = new LLMNRHeader
+ {
+ ID = this.Header.ID,
+ QR = true,
+ Opcode = "0000",
+ C = false,
+ TC = false,
+ T = false,
+ Z = "0000",
+ RCode = "0000",
+ QDCount = 1,
+ ANCount = 1
+ };
+
+ this.Resource = new LLMNRResource
+ {
+ Name = this.Question.QName,
+ Type = this.Question.QType,
+ Class = this.Question.QClass,
+ TTL = ttl,
+ RDLength = (ushort)rdata.Length,
+ RData = rdata
+ };
+
+ return Utilities.BlockCopy(this.Header.GetBytes(), this.Question.GetBytes(), this.Resource.GetBytes());
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRQuestion.cs b/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRQuestion.cs
new file mode 100644
index 0000000..7c8fd9e
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRQuestion.cs
@@ -0,0 +1,53 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Quiddity.DNS;
+
+namespace Quiddity.LLMNR
+{
+ class LLMNRQuestion : DNSQuestion
+ {
+ public LLMNRQuestion()
+ {
+
+ }
+
+ public LLMNRQuestion(byte[] data)
+ {
+ ReadBytes(data, 12);
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRResource.cs b/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRResource.cs
new file mode 100644
index 0000000..e4f090e
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/LLMNR/LLMNRResource.cs
@@ -0,0 +1,74 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using Quiddity.DNS;
+using Quiddity.Support;
+
+namespace Quiddity.LLMNR
+{
+ class LLMNRResource : DNSResource
+ {
+ public byte[] GetBytes(LLMNRQuestion llmnrQuestion, uint TTL, string responseData, byte[] id)
+ {
+ byte[] rdata = IPAddress.Parse(responseData).GetAddressBytes();
+
+ LLMNRHeader responseHeader = new LLMNRHeader
+ {
+ ID = id,
+ QR = true,
+ Opcode = "0000",
+ C = false,
+ TC = false,
+ T = false,
+ Z = "0000",
+ RCode = "0000",
+ QDCount = 1,
+ ANCount = 1
+ };
+
+ this.Name = llmnrQuestion.QName;
+ this.Type = llmnrQuestion.QType;
+ this.Class = llmnrQuestion.QClass;
+ this.TTL = TTL;
+ this.RDLength = (ushort)rdata.Length;
+ this.RData = rdata;
+
+ return Utilities.BlockCopy(responseHeader.GetBytes(), llmnrQuestion.GetBytes(), this.GetBytes());
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSChecker.cs b/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSChecker.cs
new file mode 100644
index 0000000..729adca
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSChecker.cs
@@ -0,0 +1,84 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DNS;
+using Quiddity.Support;
+using System;
+
+namespace Quiddity.MDNS
+{
+ class MDNSChecker : DNSChecker
+ {
+ public string[] Questions { get; set; }
+ public string OutputQuestionDenied { get; set; }
+
+ public MDNSChecker()
+ {
+ this.OutputReplyAllowed = "response sent";
+ this.OutputInspect = "inspect only";
+ this.OutputDisabled = "disabled";
+ this.OutputHostDenied = "host ignored";
+ this.OutputIPDenied = "IP ignored";
+ this.OutputTypeDenied = "type ignored";
+ this.OutputServiceDenied = "service ignored";
+ this.OutputRepeat = "previous capture";
+ this.OutputQuestionDenied = "question type ignored";
+ }
+
+ public virtual bool Check(string name, string question, string type, string clientIP)
+ {
+
+ if (!Check(name, type, clientIP))
+ {
+ return false;
+ }
+ else if (!QuestionIsAllowed(question))
+ {
+ this.OutputMessage = this.OutputQuestionDenied;
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool QuestionIsAllowed(string question)
+ {
+
+ if (!Utilities.ArrayIsNullOrEmpty(this.Questions) && !Array.Exists(this.Questions, element => element == question.ToUpper()))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSHeader.cs b/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSHeader.cs
new file mode 100644
index 0000000..2647e59
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSHeader.cs
@@ -0,0 +1,124 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Quiddity.DNS;
+
+namespace Quiddity.MDNS
+{
+ class MDNSHeader : DNSHeader
+ {
+ public bool AD { get; set; } // 1 bit
+ public bool CD { get; set; } // 1 bit
+
+ public MDNSHeader()
+ {
+
+ }
+
+ public MDNSHeader(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ protected override void ReadFlags()
+ {
+ string flags = Convert.ToString(BitConverter.ToUInt16(this.Flags, 0), 2).PadLeft(16, '0');
+
+ if (string.Equals(flags.Substring(0, 1), "1"))
+ {
+ this.QR = true;
+ }
+
+ this.Opcode = flags.Substring(1, 4);
+
+ if (string.Equals(flags.Substring(5, 1), "1"))
+ {
+ this.AA = true;
+ }
+
+ if (string.Equals(flags.Substring(6, 1), "1"))
+ {
+ this.TC = true;
+ }
+
+ if (string.Equals(flags.Substring(7, 1), "1"))
+ {
+ this.RD = true;
+ }
+
+ if (string.Equals(flags.Substring(8, 1), "1"))
+ {
+ this.RA = true;
+ }
+
+ this.Z = flags.Substring(9, 1);
+
+ if (string.Equals(flags.Substring(10, 1), "1"))
+ {
+ this.AD = true;
+ }
+
+ if (string.Equals(flags.Substring(11, 1), "1"))
+ {
+ this.CD = true;
+ }
+
+ this.RCode = flags.Substring(12, 4);
+ }
+
+ protected override void WriteFlags()
+ {
+ string flags = this.QR ? "1" : "0";
+ flags += this.Opcode;
+ flags += this.AA ? "1" : "0";
+ flags += this.TC ? "1" : "0";
+ flags += this.RD ? "1" : "0";
+ flags += this.RA ? "1" : "0";
+ flags += this.Z;
+ flags += this.AD ? "1" : "0";
+ flags += this.CD ? "1" : "0";
+ flags += this.RCode;
+ byte[] bytes = new byte[2];
+
+ for (int i = 0; i < 2; ++i)
+ {
+ bytes[i] = Convert.ToByte(flags.Substring(8 * i, 8), 2);
+ }
+
+ this.Flags = bytes;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSPacket.cs b/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSPacket.cs
new file mode 100644
index 0000000..003a629
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSPacket.cs
@@ -0,0 +1,99 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Quiddity.MDNS
+{
+ class MDNSPacket
+ {
+ public MDNSHeader Header { get; set; }
+ public MDNSQuestion Question { get; set; }
+ public MDNSResource Resource { get; set; }
+ public MDNSPacket(byte[] data)
+ {
+ ReadBytes(data);
+ }
+
+ public MDNSPacket ReadBytes(byte[] data)
+ {
+ this.Header = new MDNSHeader(data);
+ this.Question = new MDNSQuestion(data);
+ return this;
+ }
+
+ public byte[] GetBytes(uint ttl, string replyIP, string replyIPv6)
+ {
+
+ if (string.Equals(this.Question.Type, "AAAA") && !String.IsNullOrEmpty(replyIPv6))
+ {
+ replyIP = replyIPv6;
+ }
+
+ byte[] rdata = IPAddress.Parse(replyIP).GetAddressBytes();
+
+ this.Header = new MDNSHeader
+ {
+ ID = this.Header.ID,
+ QR = true,
+ Opcode = "0000",
+ AA = true,
+ TC = false,
+ RD = false,
+ RA = false,
+ Z = "0",
+ AD = false,
+ CD = false,
+ RCode = "0000",
+ QDCount = 1,
+ ANCount = 1
+ };
+
+ this.Resource = new MDNSResource
+ {
+ Name = this.Question.QName,
+ Type = this.Question.QType,
+ Class = this.Question.QClass,
+ TTL = ttl,
+ RDLength = (ushort)rdata.Length,
+ RData = rdata
+ };
+
+ return Utilities.BlockCopy(this.Header.GetBytes(), this.Question.GetBytes(), this.Resource.GetBytes());
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSQuestion.cs b/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSQuestion.cs
new file mode 100644
index 0000000..e3b224a
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSQuestion.cs
@@ -0,0 +1,63 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DNS;
+using System;
+
+namespace Quiddity.MDNS
+{
+ class MDNSQuestion : DNSQuestion
+ {
+ public string QuestionType { get; set; }
+
+ public MDNSQuestion()
+ {
+
+ }
+
+ public MDNSQuestion(byte[] data)
+ {
+ ReadBytes(data, 12);
+ string qclass = Convert.ToString(BitConverter.ToUInt16(this.QClass, 0), 2).PadLeft(16, '0');
+
+ if (qclass.StartsWith("1"))
+ {
+ this.QuestionType = "QU";
+ }
+ else
+ {
+ this.QuestionType = "QM";
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSResource.cs b/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSResource.cs
new file mode 100644
index 0000000..c24079a
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/MDNS/MDNSResource.cs
@@ -0,0 +1,39 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DNS;
+
+namespace Quiddity.MDNS
+{
+ class MDNSResource : DNSResource
+ {
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMChallenge.cs b/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMChallenge.cs
new file mode 100644
index 0000000..d0ec6f9
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMChallenge.cs
@@ -0,0 +1,275 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Text;
+using System.IO;
+using Quiddity.Support;
+using Quiddity.SPNEGO;
+
+namespace Quiddity.NTLM
+{
+ class NTLMChallenge
+ {
+ //https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/801a4681-8809-4be9-ab0d-61dcfe762786
+ public byte[] Signature { get; set; }
+ public uint MessageType { get; set; }
+ public ushort TargetNameLen { get; set; }
+ public ushort TargetNameMaxLen { get; set; }
+ public uint TargetNameBufferOffset { get; set; }
+ public byte[] NegotiateFlags { get; set; }
+ public byte[] ServerChallenge { get; set; }
+ public UInt64 Reserved { get; set; }
+ public ushort TargetInfoLen { get; set; }
+ public ushort TargetInfoMaxLen { get; set; }
+ public uint TargetInfoBufferOffset { get; set; }
+ public byte[] Version { get; set; }
+ public byte[] Payload { get; set; }
+
+ public NTLMChallenge()
+ {
+ this.Signature = new byte[8] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 }; // NTLMSSP
+ this.MessageType = 2;
+ this.TargetNameLen = 0;
+ this.TargetNameMaxLen = 0;
+ this.TargetNameBufferOffset = 56;
+ this.NegotiateFlags = new byte[4] { 0x15, 0x82, 0x8a, 0xe2 };
+ this.ServerChallenge = new byte[16];
+ this.Reserved = 0;
+ this.TargetInfoLen = 0;
+ this.TargetInfoMaxLen = 0;
+ this.TargetInfoBufferOffset = 0;
+ this.Version = new byte[8] { 0x0a, 0x00, 0x61, 0x4a, 0x00, 0x00, 0x00, 0x0f };
+ this.Payload = new byte[0];
+ }
+
+ public NTLMChallenge(byte[] data)
+ {
+ string signature = Encoding.UTF8.GetString(data);
+
+ if (signature.StartsWith("NTLMSSP"))
+ {
+ ReadBytes(data, 0);
+ }
+ else
+ {
+ SPNEGONegTokenResp token = this.Decode(data);
+ this.ReadBytes(token.ResponseToken, 0);
+ }
+
+ }
+
+ public NTLMChallenge(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public NTLMChallenge(byte[] data, bool decode)
+ {
+
+ if (decode)
+ {
+ SPNEGONegTokenResp token = this.Decode(data);
+ ReadBytes(token.ResponseToken, 0);
+ }
+ else
+ {
+ ReadBytes(data, 0);
+ }
+
+ }
+
+ public NTLMChallenge(string challenge, string netBIOSDomainName, string netBIOSComputerName, string dnsDomainName, string dnsComputerName, string dnsTreeName)
+ {
+ this.Signature = new byte[8] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 }; // NTLMSSP
+ this.MessageType = 2;
+ this.TargetNameLen = 0;
+ this.TargetNameMaxLen = 0;
+ this.TargetNameBufferOffset = 56;
+ this.NegotiateFlags = new byte[4] { 0x15, 0x82, 0x8a, 0xe2 };
+ this.ServerChallenge = new byte[16];
+ this.Reserved = 0;
+ this.TargetInfoLen = 0;
+ this.TargetInfoMaxLen = 0;
+ this.TargetInfoBufferOffset = 0;
+ this.Version = new byte[8] { 0x0a, 0x00, 0x61, 0x4a, 0x00, 0x00, 0x00, 0x0f };
+ this.Payload = new byte[0];
+ this.ServerChallenge = this.Challenge(challenge);
+ byte[] timestamp = BitConverter.GetBytes(DateTime.Now.ToFileTime());
+ NTLMAVPair ntlmAVPair = new NTLMAVPair();
+ this.Payload = ntlmAVPair.GetBytes(netBIOSDomainName, netBIOSComputerName, dnsDomainName, dnsComputerName, dnsTreeName, timestamp);
+ }
+
+ public NTLMChallenge(string challenge, string netBIOSDomainName, string netBIOSComputerName, string dnsDomainName, string dnsComputerName, string dnsTreeName, byte[] timestamp)
+ {
+ this.Signature = new byte[8] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 }; // NTLMSSP
+ this.MessageType = 2;
+ this.TargetNameLen = 0;
+ this.TargetNameMaxLen = 0;
+ this.TargetNameBufferOffset = 56;
+ this.NegotiateFlags = new byte[4] { 0x15, 0x82, 0x8a, 0xe2 };
+ this.ServerChallenge = new byte[16];
+ this.Reserved = 0;
+ this.TargetInfoLen = 0;
+ this.TargetInfoMaxLen = 0;
+ this.TargetInfoBufferOffset = 0;
+ this.Version = new byte[8] { 0x0a, 0x00, 0x61, 0x4a, 0x00, 0x00, 0x00, 0x0f };
+ this.Payload = new byte[0];
+ this.ServerChallenge = this.Challenge(challenge);
+ NTLMAVPair ntlmAVPair = new NTLMAVPair();
+ this.Payload = ntlmAVPair.GetBytes(netBIOSDomainName, netBIOSComputerName, dnsDomainName, dnsComputerName, dnsTreeName, timestamp);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.Signature = packetReader.ReadBytes(8);
+ this.MessageType = packetReader.ReadUInt32();
+ this.TargetNameLen = packetReader.ReadUInt16();
+ this.TargetNameMaxLen = packetReader.ReadUInt16();
+ this.TargetNameBufferOffset = packetReader.ReadUInt32();
+ this.NegotiateFlags = packetReader.ReadBytes(4);
+ this.ServerChallenge = packetReader.ReadBytes(8);
+ this.Reserved = packetReader.ReadUInt64();
+ this.TargetInfoLen = packetReader.ReadUInt16();
+ this.TargetInfoMaxLen = packetReader.ReadUInt16();
+ this.TargetInfoBufferOffset = packetReader.ReadUInt32();
+ this.Version = packetReader.ReadBytes(8);
+ this.Payload = packetReader.ReadBytes(16);
+ }
+
+ }
+
+ public byte[] GetBytes(string targetName)
+ {
+ byte[] targetNameData = Encoding.Unicode.GetBytes(targetName);
+ this.TargetNameLen = (ushort)targetNameData.Length;
+ this.TargetNameMaxLen = this.TargetNameLen;
+ this.TargetInfoLen = (ushort)this.Payload.Length;
+ this.TargetInfoMaxLen = this.TargetInfoLen;
+ this.TargetInfoBufferOffset = (ushort)(targetNameData.Length + 56);
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.Signature);
+ packetWriter.Write(this.MessageType);
+ packetWriter.Write(this.TargetNameLen);
+ packetWriter.Write(this.TargetNameMaxLen);
+ packetWriter.Write(this.TargetNameBufferOffset);
+ packetWriter.Write(this.NegotiateFlags);
+ packetWriter.Write(this.ServerChallenge);
+ packetWriter.Write(this.Reserved);
+ packetWriter.Write(this.TargetInfoLen);
+ packetWriter.Write(this.TargetInfoMaxLen);
+ packetWriter.Write(this.TargetInfoBufferOffset);
+ packetWriter.Write(this.Version);
+ packetWriter.Write(targetNameData);
+ packetWriter.Write(this.Payload);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ public byte[] Encode(byte[] data)
+ {
+ SPNEGONegTokenResp spnegoNegTokenResp = new SPNEGONegTokenResp();
+ spnegoNegTokenResp.NegState = 1;
+ spnegoNegTokenResp.SupportedMech = new byte[10] { 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a };
+ byte[] segment1 = ASN1.Encode(0x04, data);
+ segment1 = ASN1.Encode(0xa2, segment1);
+ byte[] segment2 = ASN1.Encode(0x06, spnegoNegTokenResp.SupportedMech);
+ segment2 = ASN1.Encode(0xa1, segment2);
+ byte[] segment3 = ASN1.Encode(0x0a, new byte[1] { spnegoNegTokenResp.NegState });
+ segment3 = ASN1.Encode(0xa0, segment3);
+ byte[] asn1Data = Utilities.BlockCopy(segment3, segment2, segment1);
+ asn1Data = ASN1.Encode(0x30, asn1Data);
+ asn1Data = ASN1.Encode(0xa1, asn1Data);
+ return asn1Data;
+ }
+
+ private SPNEGONegTokenResp Decode(byte[] data)
+ {
+
+ SPNEGONegTokenResp spnegoNegTokenResp = new SPNEGONegTokenResp
+ {
+ NegState = ASN1.GetTagBytes(1, data)[0],
+ SupportedMech = ASN1.GetTagBytes(6, data),
+ ResponseToken = ASN1.GetTagBytes(4, data)
+ };
+
+ return spnegoNegTokenResp;
+ }
+
+ public byte[] Challenge(string challenge)
+ {
+ byte[] challengeData = new byte[8];
+ string challengeNew = "";
+
+ if (String.IsNullOrEmpty(challenge))
+ {
+ string challengeCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ char[] challengeCharactersArray = new char[8];
+ Random random = new Random();
+
+ for (int i = 0; i < challengeCharactersArray.Length; i++)
+ {
+ challengeCharactersArray[i] = challengeCharacters[random.Next(challengeCharacters.Length)];
+ }
+
+ string finalString = new String(challengeCharactersArray);
+ challengeData = Encoding.UTF8.GetBytes(finalString);
+ challengeNew = (BitConverter.ToString(challengeData)).Replace("-", "");
+ }
+ else
+ {
+ challengeNew = challenge;
+ string challengeMod = challengeNew.Insert(2, "-").Insert(5, "-").Insert(8, "-").Insert(11, "-").Insert(14, "-").Insert(17, "-").Insert(20, "-");
+ int i = 0;
+
+ foreach (string character in challengeMod.Split('-'))
+ {
+ challengeData[i] = Convert.ToByte(Convert.ToInt16(character, 16));
+ i++;
+ }
+
+ }
+
+ return challengeData;
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMHelper.cs b/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMHelper.cs
new file mode 100644
index 0000000..7f36060
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMHelper.cs
@@ -0,0 +1,94 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.SPNEGO;
+using Quiddity.Support;
+using System.IO;
+using System.Text;
+
+namespace Quiddity.NTLM
+{
+ class NTLMHelper
+ {
+ public string Signature { get; set; }
+ public uint MessageType { get; set; }
+
+ public NTLMHelper()
+ {
+
+ }
+ public NTLMHelper(byte[]data)
+ {
+ string signature = Encoding.UTF8.GetString(data);
+
+ if (signature.StartsWith("NTLMSSP"))
+ {
+ ReadBytes(data, 0);
+ }
+ else
+ {
+ SPNEGONegTokenInit token = this.Decode(data);
+ this.ReadBytes(token.MechToken, 0);
+ }
+ }
+
+ public NTLMHelper(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.Signature = Encoding.UTF8.GetString(packetReader.ReadBytes(8));
+ this.MessageType = packetReader.ReadUInt16();
+ }
+
+ }
+
+ private SPNEGONegTokenInit Decode(byte[] data)
+ {
+ SPNEGONegTokenInit spnegoNegTokenInit = new SPNEGONegTokenInit
+ {
+ MechTypes = ASN1.GetTagBytes(6, data),
+ MechToken = ASN1.GetTagBytes(4, data)
+ };
+
+ return spnegoNegTokenInit;
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMNegotiate.cs b/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMNegotiate.cs
new file mode 100644
index 0000000..f5a9353
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMNegotiate.cs
@@ -0,0 +1,120 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using Quiddity.SPNEGO;
+using Quiddity.Support;
+using System;
+using System.IO;
+
+namespace Quiddity.NTLM
+{
+ class NTLMNegotiate
+ {
+ public byte[] Signature { get; set; }
+ public uint MessageType { get; set; }
+ public byte[] NegotiateFlags { get; set; }
+ public ushort DomainNameLen { get; set; }
+ public ushort DomainNameMaxLen { get; set; }
+ public uint DomainNameBufferOffset { get; set; }
+ public ushort WorkstationLen { get; set; }
+ public ushort WorkstationMaxLen { get; set; }
+ public uint WorkstationBufferOffset { get; set; }
+ public byte[] Version { get; set; }
+ public byte[] Payload { get; set; }
+
+ public NTLMNegotiate()
+ {
+ this.Signature = new byte[8] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 }; // NTLMSSP
+ this.MessageType = 1;
+ this.NegotiateFlags = new byte[4] { 0x97, 0x82, 0x08, 0xe2 };
+ this.DomainNameLen = 0;
+ this.DomainNameMaxLen = 0;
+ this.DomainNameBufferOffset = 0;
+ this.WorkstationLen = 0;
+ this.WorkstationMaxLen = 0;
+ this.WorkstationBufferOffset = 0;
+ this.Version = new byte[8] { 0x0a, 0x00, 0x61, 0x4a, 0x00, 0x00, 0x00, 0x0f };
+ this.Payload = new byte[8];
+ }
+
+ public NTLMNegotiate(byte[] data, bool decode)
+ {
+
+ if (decode)
+ {
+ SPNEGONegTokenInit token = this.Decode(data);
+ this.ReadBytes(token.MechToken, 0);
+ }
+ else
+ {
+ ReadBytes(data, 0);
+ }
+
+ }
+
+ public NTLMNegotiate ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.Signature = packetReader.ReadBytes(8);
+ this.MessageType = packetReader.ReadUInt16();
+ this.DomainNameLen = packetReader.ReadUInt16();
+ this.DomainNameMaxLen = packetReader.ReadUInt16();
+ this.DomainNameBufferOffset = packetReader.ReadUInt16();
+ this.DomainNameLen = packetReader.ReadUInt16();
+ this.DomainNameMaxLen = packetReader.ReadUInt16();
+ this.DomainNameBufferOffset = packetReader.ReadUInt16();
+ this.NegotiateFlags = packetReader.ReadBytes(4);
+ this.Version = packetReader.ReadBytes(8);
+ this.Payload = packetReader.ReadBytes(16);
+ return this;
+ }
+
+ }
+
+ private SPNEGONegTokenInit Decode(byte[] data)
+ {
+ SPNEGONegTokenInit spnegoNegTokenInit = new SPNEGONegTokenInit
+ {
+ MechTypes = ASN1.GetTagBytes(6, data),
+ MechToken = ASN1.GetTagBytes(4, data)
+ };
+
+ return spnegoNegTokenInit;
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMResponse.cs
new file mode 100644
index 0000000..84d49f5
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NTLM/NTLMResponse.cs
@@ -0,0 +1,220 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using Quiddity.SPNEGO;
+using Quiddity.Support;
+using System;
+using System.IO;
+using System.Text;
+
+namespace Quiddity.NTLM
+{
+ class NTLMResponse
+ {
+ //https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/033d32cc-88f9-4483-9bf2-b273055038ce
+ public byte[] Signature { get; set; }
+ public uint MessageType { get; set; }
+ public ushort LmChallengeResponseLen { get; set; }
+ public ushort LmChallengeResponseMaxLen { get; set; }
+ public uint LmChallengeResponseBufferOffset { get; set; }
+ public ushort NtChallengeResponseLen { get; set; }
+ public ushort NtChallengeResponseMaxLen { get; set; }
+ public uint NtChallengeResponseBufferOffset { get; set; }
+ public ushort DomainNameLen { get; set; }
+ public ushort DomainNameMaxLen { get; set; }
+ public uint DomainNameBufferOffset { get; set; }
+ public ushort UserNameLen { get; set; }
+ public ushort UserNameMaxLen { get; set; }
+ public uint UserNameBufferOffset { get; set; }
+ public ushort WorkstationLen { get; set; }
+ public ushort WorkstationMaxLen { get; set; }
+ public uint WorkstationBufferOffset { get; set; }
+ public ushort EncryptedRandomSessionKeyLen { get; set; }
+ public ushort EncryptedRandomSessionKeyMaxLen { get; set; }
+ public uint EncryptedRandomSessionKeyBufferOffset { get; set; }
+ public byte[] NegotiateFlags { get; set; }
+ public byte[] Version { get; set; }
+ public byte[] MIC { get; set; }
+ public byte[] Payload { get; set; }
+
+ // custom properties
+ public byte[] DomainName { get; set; }
+ public byte[] UserName { get; set; }
+ public byte[] Workstation { get; set; }
+ public byte[] EncryptedRandomSessionKey { get; set; }
+ public byte[] NtChallengeResponse { get; set; }
+ public byte[] LmChallengeResponse { get; set; }
+ public byte[] Timestamp { get; set; }
+
+ public NTLMResponse()
+ {
+ this.Signature = new byte[8] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00 }; // NTLMSSP
+ this.MessageType = 3;
+ this.LmChallengeResponseLen = 0;
+ this.LmChallengeResponseMaxLen = 0;
+ this.LmChallengeResponseBufferOffset = 0;
+ this.NtChallengeResponseLen = 0;
+ this.NtChallengeResponseMaxLen = 0;
+ this.NtChallengeResponseBufferOffset = 0;
+ this.DomainNameLen = 0;
+ this.DomainNameMaxLen = 0;
+ this.DomainNameBufferOffset = 0;
+ this.UserNameLen = 0;
+ this.UserNameMaxLen = 0;
+ this.UserNameBufferOffset = 0;
+ this.WorkstationLen = 0;
+ this.WorkstationMaxLen = 0;
+ this.WorkstationBufferOffset = 0;
+ this.EncryptedRandomSessionKeyLen = 0;
+ this.EncryptedRandomSessionKeyMaxLen = 0;
+ this.EncryptedRandomSessionKeyBufferOffset = 0;
+ this.NegotiateFlags = new byte[4] { 0x15, 0x82, 0x8a, 0xe2 };
+ this.Version = new byte[8] { 0x0a, 0x00, 0x61, 0x4a, 0x00, 0x00, 0x00, 0x0f };
+ this.MIC = new byte[16];
+ this.Payload = new byte[0];
+ }
+
+ public NTLMResponse(byte[] data)
+ {
+ string signature = Encoding.UTF8.GetString(data);
+
+ if (signature.StartsWith("NTLMSSP"))
+ {
+ ReadBytes(data);
+ }
+ else
+ {
+ SPNEGONegTokenResp token = this.Decode(data);
+ this.ReadBytes(token.ResponseToken);
+ }
+
+ ParseValues();
+ }
+
+ public NTLMResponse(byte[] data, bool decode)
+ {
+
+ if(decode)
+ {
+ SPNEGONegTokenResp token = this.Decode(data);
+ this.ReadBytes(token.ResponseToken);
+ }
+ else
+ {
+ ReadBytes(data);
+ }
+
+ ParseValues();
+ }
+
+ public void ReadBytes(byte[] data)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ this.Signature = packetReader.ReadBytes(8);
+ this.MessageType = packetReader.ReadUInt32();
+ this.LmChallengeResponseLen = packetReader.ReadUInt16();
+ this.LmChallengeResponseMaxLen = packetReader.ReadUInt16();
+ this.LmChallengeResponseBufferOffset = packetReader.ReadUInt32();
+ this.NtChallengeResponseLen = packetReader.ReadUInt16();
+ this.NtChallengeResponseMaxLen = packetReader.ReadUInt16();
+ this.NtChallengeResponseBufferOffset = packetReader.ReadUInt32();
+ this.DomainNameLen = packetReader.ReadUInt16();
+ this.DomainNameMaxLen = packetReader.ReadUInt16();
+ this.DomainNameBufferOffset = packetReader.ReadUInt32();
+ this.UserNameLen = packetReader.ReadUInt16();
+ this.UserNameMaxLen = packetReader.ReadUInt16();
+ this.UserNameBufferOffset = packetReader.ReadUInt32();
+ this.WorkstationLen = packetReader.ReadUInt16();
+ this.WorkstationMaxLen = packetReader.ReadUInt16();
+ this.WorkstationBufferOffset = packetReader.ReadUInt32();
+ this.EncryptedRandomSessionKeyLen = packetReader.ReadUInt16();
+ this.EncryptedRandomSessionKeyMaxLen = packetReader.ReadUInt16();
+ this.EncryptedRandomSessionKeyBufferOffset = packetReader.ReadUInt32();
+ this.NegotiateFlags = packetReader.ReadBytes(4);
+ this.Version = packetReader.ReadBytes(8);
+ this.MIC = packetReader.ReadBytes(16);
+ this.Payload = packetReader.ReadBytes(data.Length - 88);
+ }
+
+ }
+
+ public string GetFormattedHash(string challenge, string user, string domain)
+ {
+ string hash = "";
+
+ if (this.NtChallengeResponse.Length > 24)
+ {
+ hash = user + "::" + domain + ":" + challenge + ":" + BitConverter.ToString(this.NtChallengeResponse).Replace("-", "").Insert(32, ":");
+ }
+ else if (this.NtChallengeResponse.Length == 24)
+ {
+ hash = user + "::" + domain + ":" + BitConverter.ToString(this.LmChallengeResponse).Replace("-", "") + ":" + BitConverter.ToString(this.NtChallengeResponse).Replace("-", "").Insert(32, ":") + ":" + challenge;
+ }
+
+ return hash;
+ }
+
+ private SPNEGONegTokenResp Decode(byte[] data)
+ {
+ SPNEGONegTokenResp spnegoNegTokenResp = new SPNEGONegTokenResp
+ {
+ NegState = ASN1.GetTagBytes(1, data)[0],
+ SupportedMech = ASN1.GetTagBytes(6, data),
+ ResponseToken = ASN1.GetTagBytes(4, data),
+ MechListMIC = ASN1.GetTagBytes(4, ASN1.GetTagBytes(163, data))
+ };
+
+ return spnegoNegTokenResp;
+ }
+
+ private void ParseValues()
+ {
+ this.DomainName = new byte[this.DomainNameLen];
+ Buffer.BlockCopy(this.Payload, (int)(this.DomainNameBufferOffset - 88), this.DomainName, 0, this.DomainNameLen);
+ this.UserName = new byte[this.UserNameLen];
+ Buffer.BlockCopy(this.Payload, (int)(this.UserNameBufferOffset - 88), this.UserName, 0, this.UserNameLen);
+ this.Workstation = new byte[this.WorkstationLen];
+ Buffer.BlockCopy(this.Payload, (int)(this.WorkstationBufferOffset - 88), this.Workstation, 0, this.WorkstationLen);
+ this.EncryptedRandomSessionKey = new byte[this.EncryptedRandomSessionKeyLen];
+ Buffer.BlockCopy(this.Payload, (int)(this.EncryptedRandomSessionKeyBufferOffset - 88), this.EncryptedRandomSessionKey, 0, this.EncryptedRandomSessionKeyLen);
+ this.LmChallengeResponse = new byte[this.LmChallengeResponseLen];
+ Buffer.BlockCopy(this.Payload, (int)(this.LmChallengeResponseBufferOffset - 88), this.LmChallengeResponse, 0, this.LmChallengeResponseLen);
+ this.NtChallengeResponse = new byte[this.NtChallengeResponseLen];
+ Buffer.BlockCopy(this.Payload, (int)(this.NtChallengeResponseBufferOffset - 88), this.NtChallengeResponse, 0, this.NtChallengeResponseLen);
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMAVPair.cs b/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMAVPair.cs
new file mode 100644
index 0000000..2e9c678
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMAVPair.cs
@@ -0,0 +1,128 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Text;
+using System.IO;
+
+namespace Quiddity.NTLM
+{
+ class NTLMAVPair
+ {
+ //https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/83f5e789-660d-4781-8491-5f8c6641f75e
+ public ushort AvId { get; set; }
+ public ushort AvLen { get; set; }
+ public byte[] Value { get; set; }
+
+ public NTLMAVPair()
+ {
+ this.AvId = 0;
+ this.AvLen = 0;
+ this.Value = new byte[0];
+ }
+
+ public byte[] GetBytes(string netBIOSDomainName, string netBIOSComputerName, string dnsDomainName, string dnsComputerName, string dnsTreeName, byte[] timestamp)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+
+ if (!String.IsNullOrEmpty(netBIOSDomainName))
+ {
+ this.AvId = 2;
+ this.Value = Encoding.Unicode.GetBytes(netBIOSDomainName);
+ this.AvLen = (ushort)this.Value.Length;
+ packetWriter.Write(this.AvId);
+ packetWriter.Write(this.AvLen);
+ packetWriter.Write(this.Value);
+ }
+
+ if (!String.IsNullOrEmpty(netBIOSComputerName))
+ {
+ this.AvId = 1;
+ this.Value = Encoding.Unicode.GetBytes(netBIOSComputerName);
+ this.AvLen = (ushort)this.Value.Length;
+ packetWriter.Write(this.AvId);
+ packetWriter.Write(this.AvLen);
+ packetWriter.Write(this.Value);
+ }
+
+ if (!String.IsNullOrEmpty(dnsDomainName))
+ {
+ this.AvId = 4;
+ this.Value = Encoding.Unicode.GetBytes(dnsDomainName);
+ this.AvLen = (ushort)this.Value.Length;
+ packetWriter.Write(this.AvId);
+ packetWriter.Write(this.AvLen);
+ packetWriter.Write(this.Value);
+ }
+
+ if (!String.IsNullOrEmpty(dnsComputerName))
+ {
+ this.AvId = 3;
+ this.Value = Encoding.Unicode.GetBytes(dnsComputerName);
+ this.AvLen = (ushort)this.Value.Length;
+ packetWriter.Write(this.AvId);
+ packetWriter.Write(this.AvLen);
+ packetWriter.Write(this.Value);
+ }
+
+ if (!String.IsNullOrEmpty(dnsTreeName) && !String.Equals(dnsTreeName, netBIOSComputerName))
+ {
+ this.AvId = 5;
+ this.Value = Encoding.Unicode.GetBytes(dnsTreeName);
+ this.AvLen = (ushort)this.Value.Length;
+ packetWriter.Write(this.AvId);
+ packetWriter.Write(this.AvLen);
+ packetWriter.Write(this.Value);
+ }
+
+ this.AvId = 7;
+ this.Value = timestamp;
+ this.AvLen = 8;
+ packetWriter.Write(this.AvId);
+ packetWriter.Write(this.AvLen);
+ packetWriter.Write(this.Value);
+
+ this.AvId = 0;
+ this.AvLen = 0;
+ packetWriter.Write(this.AvId);
+ packetWriter.Write(this.AvLen);
+
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv1Response.cs b/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv1Response.cs
new file mode 100644
index 0000000..36eba9a
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv1Response.cs
@@ -0,0 +1,39 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace Quiddity.NTLM
+{
+ class NTLMv1Response
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/b88739c6-1266-49f7-9d22-b13923bd8d66
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv2ClientChallenge.cs b/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv2ClientChallenge.cs
new file mode 100644
index 0000000..cbda85b
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv2ClientChallenge.cs
@@ -0,0 +1,39 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace Quiddity.NTLM
+{
+ class NTLMv2ClientChallenge
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/aee311d6-21a7-4470-92a5-c4ecb022a87b
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv2Response.cs b/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv2Response.cs
new file mode 100644
index 0000000..0c26bff
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NTLM/Structures/NTLMv2Response.cs
@@ -0,0 +1,39 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace Quiddity.NTLM
+{
+ class NTLMv2Response
+ {
+ //https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/d43e2224-6fc3-449d-9f37-b90b55a29c80
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSChecker.cs b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSChecker.cs
new file mode 100644
index 0000000..cbb9d2e
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSChecker.cs
@@ -0,0 +1,76 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DNS;
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Quiddity.NetBIOS
+{
+ class NetBIOSNSChecker : DNSChecker
+ {
+ /// <summary>method <c>GetBytes</c> returns reply buffer.</summary>
+ public static byte[] GetBytes(NetBIOSNSHeader header, NetBIOSNSQuestion question, uint ttl, string replyIP)
+ {
+ byte[] rdata = Utilities.BlockCopy(new byte[2], IPAddress.Parse(replyIP).GetAddressBytes());
+
+ NetBIOSNSHeader responseHeader = new NetBIOSNSHeader
+ {
+ ID = header.ID,
+ R = true,
+ Opcode = "0000",
+ AA = true,
+ TC = false,
+ RD = true,
+ RA = false,
+ Z = "00",
+ B = false,
+ RCode = "0000",
+ QDCount = 0,
+ ANCount = 1
+ };
+
+ NetBIOSNSResource resource = new NetBIOSNSResource();
+ resource.Name = question.QName;
+ resource.Type = question.QType;
+ resource.Class = question.QClass;
+ resource.TTL = ttl;
+ resource.RDLength = 6;
+ resource.RData = rdata;
+
+ return Utilities.BlockCopy(responseHeader.GetBytes(), resource.GetBytes());
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSHeader.cs b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSHeader.cs
new file mode 100644
index 0000000..88255a3
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSHeader.cs
@@ -0,0 +1,135 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DNS;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.NetBIOS
+{
+ class NetBIOSNSHeader : DNSHeader
+ {
+ // https://datatracker.ietf.org/doc/html/rfc1002
+ public bool R { get; set; } // 1 bit
+ public bool B { get; set; } // 1 bit
+ public NetBIOSNSHeader()
+ {
+
+ }
+
+ public NetBIOSNSHeader(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ protected override void ReadFlags()
+ {
+ string flags = Convert.ToString(BitConverter.ToUInt16(this.Flags, 0), 2).PadLeft(16, '0');
+
+ if (string.Equals(flags.Substring(0, 1), "1"))
+ {
+ this.R = true;
+ }
+
+ this.Opcode = flags.Substring(1, 4);
+
+ if (string.Equals(flags.Substring(5, 1), "1"))
+ {
+ this.AA = true;
+ }
+
+ if (string.Equals(flags.Substring(6, 1), "1"))
+ {
+ this.TC = true;
+ }
+
+ if (string.Equals(flags.Substring(7, 1), "1"))
+ {
+ this.RD = true;
+ }
+
+ if (string.Equals(flags.Substring(8, 1), "1"))
+ {
+ this.RA = true;
+ }
+
+ this.Z = flags.Substring(9, 2);
+
+ if (string.Equals(flags.Substring(11, 1), "1"))
+ {
+ this.B = true;
+ }
+
+ this.RCode = flags.Substring(12, 4);
+ }
+
+ protected override void WriteFlags()
+ {
+ string flags = this.R ? "1" : "0";
+ flags += this.Opcode;
+ flags += this.AA ? "1" : "0";
+ flags += this.TC ? "1" : "0";
+ flags += this.RD ? "1" : "0";
+ flags += this.RA ? "1" : "0";
+ flags += this.Z;
+ flags += this.B ? "1" : "0";
+ flags += this.RCode;
+ byte[] bytes = new byte[2];
+
+ for (int i = 0; i < 2; ++i)
+ {
+ bytes[i] = Convert.ToByte(flags.Substring(8 * i, 8), 2);
+ }
+
+ this.Flags = bytes;
+ }
+
+ public byte[] Parse(uint ttl, string ip, byte[] data, out string name, out string type)
+ {
+ this.ReadBytes(data, 0);
+ name = "";
+ type = "";
+
+ if (this.QDCount == 1 && this.ANCount == 0)
+ {
+ NetBIOSNSQuestion question = new NetBIOSNSQuestion();
+ question.ReadBytes(data, 12);
+ NetBIOSNSResource response = new NetBIOSNSResource();
+ return response.GetBytes(question, ttl, ip, this.ID);
+ }
+
+ return null;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSPacket.cs b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSPacket.cs
new file mode 100644
index 0000000..84fd653
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSPacket.cs
@@ -0,0 +1,93 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Quiddity.NetBIOS
+{
+ class NetBIOSNSPacket
+ {
+ public NetBIOSNSHeader Header { get; set; }
+ public NetBIOSNSQuestion Question { get; set; }
+ public NetBIOSNSResource Resource { get; set; }
+
+ public NetBIOSNSPacket(byte[] data)
+ {
+ ReadBytes(data);
+ }
+
+ public NetBIOSNSPacket ReadBytes(byte[] data)
+ {
+ this.Header = new NetBIOSNSHeader(data);
+ this.Question = new NetBIOSNSQuestion(data);
+ return this;
+ }
+
+ public byte[] GetBytes(uint ttl, string replyIP)
+ {
+ byte[] rdata = Utilities.BlockCopy(new byte[2], IPAddress.Parse(replyIP).GetAddressBytes());
+
+ this.Header = new NetBIOSNSHeader
+ {
+ ID = this.Header.ID,
+ R = true,
+ Opcode = "0000",
+ AA = true,
+ TC = false,
+ RD = true,
+ RA = false,
+ Z = "00",
+ B = false,
+ RCode = "0000",
+ QDCount = 0,
+ ANCount = 1
+ };
+
+ this.Resource = new NetBIOSNSResource
+ {
+ Name = this.Question.QName,
+ Type = this.Question.QType,
+ Class = this.Question.QClass,
+ TTL = ttl,
+ RDLength = 6,
+ RData = rdata
+ };
+
+ return Utilities.BlockCopy(this.Header.GetBytes(), this.Resource.GetBytes());
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSQuestion.cs b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSQuestion.cs
new file mode 100644
index 0000000..2285b2f
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSQuestion.cs
@@ -0,0 +1,162 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DNS;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Quiddity.NetBIOS
+{
+ class NetBIOSNSQuestion : DNSQuestion
+ {
+ public NetBIOSNSQuestion()
+ {
+
+ }
+
+ public NetBIOSNSQuestion(byte[] data)
+ {
+ ReadBytes(data, 12);
+ }
+
+ protected override string ConvertName()
+ {
+ byte[] nameData = new byte[30];
+ Buffer.BlockCopy(this.QName, 1, nameData, 0, 30);
+ string hex = BitConverter.ToString(nameData);
+ string[] nameArray = hex.Split('-');
+ string characters = "";
+
+ foreach (string character in nameArray)
+ {
+ characters += new string(Convert.ToChar(Convert.ToInt16(character, 16)), 1);
+ }
+
+ if (characters.Contains("CA"))
+ {
+ characters = characters.Substring(0, characters.IndexOf("CA"));
+ }
+
+ int i = 0;
+ string nameSubstring = "";
+
+ do
+ {
+ byte characterByte = (byte)Convert.ToChar(characters.Substring(i, 1));
+ characterByte -= 0x41;
+ nameSubstring += Convert.ToString(characterByte, 16);
+ i++;
+ }
+ while (i < characters.Length);
+
+ i = 0;
+ string name = "";
+
+ do
+ {
+ name += (Convert.ToChar(Convert.ToInt16(nameSubstring.Substring(i, 2), 16)));
+ i += 2;
+ }
+ while (i < nameSubstring.Length - 1);
+
+ if (characters.StartsWith("ABAC") && characters.EndsWith("AC"))
+ {
+ name = name.Substring(2);
+ name = name.Substring(0, name.Length - 1);
+ name = string.Concat("<01><02>", name, "<02>");
+ }
+
+ Regex printable = new Regex("[^\x00-\x7F]+");
+
+ if (printable.IsMatch(name))
+ {
+ return "";
+ }
+
+ return name;
+ }
+
+ protected override string GetType()
+ {
+ byte[] typeData = new byte[2];
+ Buffer.BlockCopy(this.QName, 31, typeData, 0, 2);
+ string nbnsQuery = BitConverter.ToString(typeData);
+ string nbnsQueryType = "";
+
+ switch (nbnsQuery)
+ {
+
+ case "41-41":
+ nbnsQueryType = "00";
+ break;
+
+ case "41-42":
+ nbnsQueryType = "01";
+ break;
+
+ case "41-43":
+ nbnsQueryType = "02";
+ break;
+
+ case "41-44":
+ nbnsQueryType = "03";
+ break;
+
+ case "43-41":
+ nbnsQueryType = "20";
+ break;
+
+ case "42-4C":
+ nbnsQueryType = "1B";
+ break;
+
+ case "42-4D":
+ nbnsQueryType = "1C";
+ break;
+
+ case "42-4E":
+ nbnsQueryType = "1D";
+ break;
+
+ case "42-4F":
+ nbnsQueryType = "1E";
+ break;
+
+ }
+
+ return nbnsQueryType;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSResource.cs b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSResource.cs
new file mode 100644
index 0000000..89d136a
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSNSResource.cs
@@ -0,0 +1,68 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.DNS;
+using Quiddity.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Quiddity.NetBIOS
+{
+ class NetBIOSNSResource : DNSResource
+ {
+
+ public byte[] GetBytes(NetBIOSNSQuestion requestQuestion, uint ttl, string reply, byte[] id)
+ {
+ byte[] rdata = Utilities.BlockCopy(new byte[2], IPAddress.Parse(reply).GetAddressBytes());
+
+ NetBIOSNSHeader responseHeader = new NetBIOSNSHeader
+ {
+ ID = id,
+ QDCount = 0,
+ ANCount = 1
+ };
+
+ this.Name = requestQuestion.QName;
+ this.Type = requestQuestion.QType;
+ this.Class = requestQuestion.QClass;
+ this.TTL = ttl;
+ this.RDLength = 6;
+ this.RData = rdata;
+
+ return Utilities.BlockCopy(responseHeader.GetBytes(), this.GetBytes());
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSSessionService.cs b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSSessionService.cs
new file mode 100644
index 0000000..70e8dbe
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/NetBIOS/NetBIOSSessionService.cs
@@ -0,0 +1,82 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System.IO;
+
+namespace Quiddity.NetBIOS
+{
+ class NetBIOSSessionService
+ {
+ // https://tools.ietf.org/html/rfc1002
+ public byte Type { get; set; }
+ public byte Flags { get; set; }
+ public ushort Length { get; set; }
+
+ public NetBIOSSessionService()
+ {
+ this.Type = 0x00;
+ this.Flags = 0x00;
+ }
+
+ public NetBIOSSessionService(byte[] data)
+ {
+ ReadBytes(data);
+ }
+
+ public void ReadBytes(byte[] data)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ this.Type = packetReader.ReadByte();
+ this.Flags = packetReader.ReadByte();
+ this.Length = packetReader.BigEndianReadUInt16();
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.Type);
+ packetWriter.Write(this.Flags);
+ packetWriter.BigEndianWrite(this.Length);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/PacketReader.cs b/Inveigh/Protocols/Quiddity/Protocols/PacketReader.cs
new file mode 100644
index 0000000..904b994
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/PacketReader.cs
@@ -0,0 +1,74 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.IO;
+
+namespace Quiddity
+{
+ class PacketReader : BinaryReader
+ {
+ public PacketReader(Stream stream) : base(stream) { }
+
+ public ushort BigEndianReadUInt16()
+ {
+ byte[] data = base.ReadBytes(2);
+ Array.Reverse(data);
+ return BitConverter.ToUInt16(data, 0);
+ }
+
+ public uint BigEndianReadUInt32()
+ {
+ byte[] data = base.ReadBytes(4);
+ Array.Reverse(data);
+ return BitConverter.ToUInt32(data, 0);
+ }
+
+ public byte[] BigEndianReadBytes(int count)
+ {
+ byte[] data = base.ReadBytes(count);
+ Array.Reverse(data);
+ return data;
+ }
+
+ public string ReadBinary(int count)
+ {
+
+ if (count == 1)
+ {
+ return Convert.ToString(base.ReadByte(), 2).PadLeft(8, '0');
+ }
+
+ return Convert.ToString(BitConverter.ToUInt16(BigEndianReadBytes(count), 0), 2).PadLeft(count * 8, '0');
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/PacketWriter.cs b/Inveigh/Protocols/Quiddity/Protocols/PacketWriter.cs
new file mode 100644
index 0000000..d5fa611
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/PacketWriter.cs
@@ -0,0 +1,76 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.IO;
+using System.Text;
+
+namespace Quiddity
+{
+ class PacketWriter : BinaryWriter // todo optimize
+ {
+ public PacketWriter(Stream stream) : base(stream) { }
+
+ public void BigEndianWrite(ushort number)
+ {
+ byte[] data = BitConverter.GetBytes(number);
+ Array.Reverse(data);
+ base.Write(data);
+ }
+
+ public void BigEndianWrite(uint number)
+ {
+ byte[] data = BitConverter.GetBytes(number);
+ Array.Reverse(data);
+ base.Write(data);
+ }
+
+ public void BigEndianWrite(int number)
+ {
+ byte[] data = BitConverter.GetBytes(number);
+ Array.Reverse(data);
+ base.Write(data);
+ }
+
+ public void BigEndianWrite(byte[] data)
+ {
+ Array.Reverse(data);
+ base.Write(data);
+ }
+
+ public void StringWrite(string String)
+ {
+ byte[] data = Encoding.UTF8.GetBytes(String);
+ base.Write(data);
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB/Commands/SMBCOMSessionSetupAndXRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB/Commands/SMBCOMSessionSetupAndXRequest.cs
new file mode 100644
index 0000000..7130014
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB/Commands/SMBCOMSessionSetupAndXRequest.cs
@@ -0,0 +1,92 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB
+{
+ class SMBCOMSessionSetupAndXRequest
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb/a00d0361-3544-4845-96ab-309b4bb7705d
+ public byte WordCount { get; set; }
+ public byte AndXCommand { get; set; }
+ public byte AndXReserved { get; set; }
+ public ushort AndXOffset { get; set; }
+ public ushort MaxBufferSize { get; set; }
+ public ushort MaxMpxCount { get; set; }
+ public ushort VcNumber { get; set; }
+ public uint SessionKey { get; set; }
+ public ushort SecurityBlobLength { get; set; }
+ public uint Reserved { get; set; }
+ public uint Capabilities { get; set; }
+ public ushort ByteCount { get; set; }
+ public byte[] SecurityBlob { get; set; }
+
+ public SMBCOMSessionSetupAndXRequest()
+ {
+
+ }
+
+ public SMBCOMSessionSetupAndXRequest(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.WordCount = packetReader.ReadByte();
+ this.AndXCommand = packetReader.ReadByte();
+ this.AndXReserved = packetReader.ReadByte();
+ this.AndXOffset = packetReader.ReadUInt16();
+ this.MaxBufferSize = packetReader.ReadUInt16();
+ this.MaxMpxCount = packetReader.ReadUInt16();
+ this.VcNumber = packetReader.ReadUInt16();
+ this.SessionKey = packetReader.ReadUInt32();
+ this.SecurityBlobLength = packetReader.ReadUInt16();
+ this.Reserved = packetReader.BigEndianReadUInt32();
+ this.Capabilities = packetReader.ReadUInt32();
+ this.ByteCount = packetReader.ReadUInt16();
+ this.SecurityBlob = packetReader.ReadBytes(this.SecurityBlobLength);
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB/Commands/SMBCOMSessionSetupAndXResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB/Commands/SMBCOMSessionSetupAndXResponse.cs
new file mode 100644
index 0000000..216162e
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB/Commands/SMBCOMSessionSetupAndXResponse.cs
@@ -0,0 +1,91 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB
+{
+ class SMBCOMSessionSetupAndXResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb/e5a467bc-cd36-4afa-825e-3f2a7bfd6189
+ public byte WordCount { get; set; }
+ public byte AndXCommand { get; set; }
+ public byte AndXReserved { get; set; }
+ public ushort AndXOffset { get; set; }
+ public ushort Action { get; set; }
+ public ushort SecurityBlobLength { get; set; }
+ public ushort ByteCount { get; set; }
+ public byte[] SecurityBlob { get; set; }
+
+ public SMBCOMSessionSetupAndXResponse()
+ {
+
+ }
+
+ public SMBCOMSessionSetupAndXResponse(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.WordCount = packetReader.ReadByte();
+
+ if (this.WordCount != 0)
+ {
+ this.AndXCommand = packetReader.ReadByte();
+ this.AndXReserved = packetReader.ReadByte();
+ this.AndXOffset = packetReader.ReadUInt16();
+ this.Action = packetReader.ReadUInt16();
+ this.SecurityBlobLength = packetReader.ReadUInt16();
+ }
+
+ this.ByteCount = packetReader.ReadUInt16();
+
+ if (this.WordCount != 0)
+ {
+ this.SecurityBlob = packetReader.ReadBytes(SecurityBlobLength);
+ }
+
+ }
+
+ }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB/SMBHeader.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB/SMBHeader.cs
new file mode 100644
index 0000000..9704220
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB/SMBHeader.cs
@@ -0,0 +1,93 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System.IO;
+
+namespace Quiddity.SMB
+{
+ //https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/69a29f73-de0c-45a6-a1aa-8ceeea42217f
+
+ class SMBHeader
+ {
+ public byte[] Protocol { get; set; }
+ public byte Command { get; set; }
+ public uint Status { get; set; }
+ public byte Flags { get; set; }
+ public ushort Flags2 { get; set; }
+ public ushort PIDHigh { get; set; }
+ public byte[] SecurityFeatures { get; set; }
+ public ushort Reserved { get; set; }
+ public ushort TID { get; set; }
+ public ushort PIDLow { get; set; }
+ public ushort UID { get; set; }
+ public ushort MID { get; set; }
+
+ public SMBHeader()
+ {
+ this.Protocol = new byte[4] { 0xff, 0x53, 0x4d, 0x42 };
+ }
+
+ public SMBHeader(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public SMBHeader (byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.Protocol = packetReader.ReadBytes(4);
+ this.Command = packetReader.ReadByte();
+ this.Status = packetReader.BigEndianReadUInt32();
+ this.Flags = packetReader.ReadByte();
+ this.Flags2 = packetReader.BigEndianReadUInt16();
+ this.PIDHigh = packetReader.BigEndianReadUInt16();
+ this.SecurityFeatures = packetReader.ReadBytes(8);
+ this.Reserved = packetReader.BigEndianReadUInt16();
+ this.TID = packetReader.BigEndianReadUInt16();
+ this.PIDLow = packetReader.BigEndianReadUInt16();
+ this.UID = packetReader.BigEndianReadUInt16();
+ this.MID = packetReader.BigEndianReadUInt16();
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB/SMBHelper.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB/SMBHelper.cs
new file mode 100644
index 0000000..32f4309
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB/SMBHelper.cs
@@ -0,0 +1,70 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System.IO;
+
+namespace Quiddity.SMB
+{
+ class SMBHelper
+ {
+ public byte[] Protocol { get; set; }
+
+ public SMBHelper()
+ {
+ this.Protocol = new byte[4];
+ }
+
+ public SMBHelper(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public SMBHelper(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public SMBHelper ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.Protocol = packetReader.ReadBytes(4);
+ return this;
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CloseRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CloseRequest.cs
new file mode 100644
index 0000000..bbe6926
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CloseRequest.cs
@@ -0,0 +1,47 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2CloseRequest
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/f84053b0-bcb2-4f85-9717-536dae2b02bd
+ public ushort StructureSize { get; set; }
+ public byte[] Flags { get; set; }
+ public byte[] Reserved { get; set; }
+ public byte[] Field { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CloseResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CloseResponse.cs
new file mode 100644
index 0000000..3d9b341
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CloseResponse.cs
@@ -0,0 +1,54 @@
+
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2CloseResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/c0c15c57-3f3e-452b-b51c-9cc650a13f7b
+ public ushort StructureSize { get; set; }
+ public byte[] Flags { get; set; }
+ public byte[] Reserved { get; set; }
+ public byte[] CreationTime { get; set; }
+ public byte[] LastAccessTime { get; set; }
+ public byte[] LastWriteTime { get; set; }
+ public byte[] ChangeTime { get; set; }
+ public byte[] AllocationSize { get; set; }
+ public byte[] EndofFile { get; set; }
+ public byte[] FileAttributes { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CreateRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CreateRequest.cs
new file mode 100644
index 0000000..7fd4d42
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CreateRequest.cs
@@ -0,0 +1,120 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Quiddity.SMB2;
+
+namespace Quiddity.SMB2
+{
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e8fb45c1-a03d-44ca-b7ae-47385cfd7997
+ enum RequestedOplockLevel : byte
+ {
+ SMB2_OPLOCK_LEVEL_NONE = 0x00,
+ SMB2_OPLOCK_LEVEL_II = 0x01,
+ SMB2_OPLOCK_LEVEL_EXCLUSIVE = 0x08,
+ SMB2_OPLOCK_LEVEL_BATCH = 0x09,
+ SMB2_OPLOCK_LEVEL_LEASE = 0xFF
+ }
+
+ enum ImpersonationLevel : uint
+ {
+ Anonymous = 0x00000000,
+ Identification = 0x00000001,
+ Impersonation = 0x00000002,
+ Delegate = 0x00000003
+ }
+
+ enum ShareAccess : uint
+ {
+ FILE_SHARE_READ = 0x00000000,
+ FILE_SHARE_WRITE = 0x0000002,
+ FILE_SHARE_DELETE = 0x00000004
+ }
+
+ enum CreateDisposition : uint
+ {
+ FILE_SUPERSEDE = 0x00000000,
+ FILE_OPEN = 0x0000001,
+ FILE_CREATE = 0x00000002,
+ FILE_OPEN_IF = 0x00000003,
+ FILE_OVERWRITE = 0x00000004,
+ FILE_OVERWRITE_IF = 0x00000005
+ }
+
+ enum CreateOptions : uint
+ {
+ FILE_DIRECTORY_FILE = 0x00000000,
+ FILE_WRITE_THROUGH = 0x0000001,
+ FILE_SEQUENTIAL_ONLY = 0x00000004,
+ FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008,
+ FILE_SYNCHRONOUS_IO_ALERT = 0x00000010,
+ FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020,
+ FILE_NON_DIRECTORY_FILE = 0x00000040,
+ FILE_COMPLETE_IF_OPLOCKED = 0x00000100,
+ FILE_NO_EA_KNOWLEDGE = 0x00000200,
+ FILE_RANDOM_ACCESS = 0x00000800,
+ FILE_DELETE_ON_CLOSE = 0x00001000,
+ FILE_OPEN_BY_FILE_ID = 0x00002000,
+ FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000,
+ FILE_NO_COMPRESSION = 0x00008000,
+ FILE_OPEN_REMOTE_INSTANCE = 0x00000400,
+ FILE_OPEN_REQUIRING_OPLOCK = 0x00010000,
+ FILE_DISALLOW_EXCLUSIVE = 0x00020000,
+ FILE_RESERVE_OPFILTER = 0x00100000,
+ FILE_OPEN_REPARSE_POINT = 0x00200000,
+ FILE_OPEN_NO_RECALL = 0x00400000,
+ FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000
+ }
+
+ class SMB2CreateRequest
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e8fb45c1-a03d-44ca-b7ae-47385cfd7997
+ public ushort StructureSize { get; set; }
+ public byte Flags { get; set; }
+ public byte RequestedOplockLevel { get; set; }
+ public uint ImpersonationLevel { get; set; }
+ public byte[] SmbCreateFlags { get; set; }
+ public byte[] Reserved { get; set; }
+ public byte[] DesiredAccess { get; set; }
+ public byte[] FileAttributes { get; set; }
+ public uint ShareAccess { get; set; }
+ public uint CreateDisposition { get; set; }
+ public uint CreateOptions { get; set; }
+ public ushort NameOffset { get; set; }
+ public ushort NameLength { get; set; }
+ public uint CreateContextsOffset { get; set; }
+ public uint CreateContextsLength { get; set; }
+ public byte[] Buffer { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CreateResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CreateResponse.cs
new file mode 100644
index 0000000..3d63d60
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2CreateResponse.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ enum OplockLevel : uint
+ {
+ SMB2_OPLOCK_LEVEL_NONE = 0x00,
+ SMB2_OPLOCK_LEVEL_II = 0x01,
+ SMB2_OPLOCK_LEVEL_EXCLUSIVE = 0x08,
+ SMB2_OPLOCK_LEVEL_BATCH = 0x09,
+ SMB2_OPLOCK_LEVEL_LEASE = 0xFF
+ }
+
+ enum CreateAction : uint
+ {
+ FILE_SUPERSEDED = 0x00000000,
+ FILE_OPENED = 0x00000001,
+ FILE_CREATED = 0x00000002,
+ FILE_OVERWRITTEN = 0x00000003
+ }
+
+ class SMB2CreateResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/d166aa9e-0b53-410e-b35e-3933d8131927
+ public ushort StructureSize { get; set; }
+ public byte OplockLevel { get; set; }
+ public byte Flags { get; set; }
+ public uint CreateAction { get; set; }
+ public byte[] CreationTime { get; set; }
+ public byte[] LastAccessTime { get; set; }
+ public byte[] LastWriteTime { get; set; }
+ public byte[] ChangeTime { get; set; }
+ public byte[] AllocationSize { get; set; }
+ public byte[] EndofFile { get; set; }
+ public byte[] FileAttributes { get; set; }
+ public byte[] Reserved2 { get; set; }
+ public byte[] Field { get; set; }
+ public uint CreateContextsOffset { get; set; }
+ public uint CreateContextsLength { get; set; }
+ public byte[] Buffer { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ErrorResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ErrorResponse.cs
new file mode 100644
index 0000000..02d66a4
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ErrorResponse.cs
@@ -0,0 +1,48 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2ErrorResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/d4da8b67-c180-47e3-ba7a-d24214ac4aaa
+ public ushort StructureSize { get; set; }
+ public byte ErrorContextCount { get; set; }
+ public byte Reserved { get; set; }
+ public uint ByteCount { get; set; }
+ public byte[] ErrorData { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2FlushRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2FlushRequest.cs
new file mode 100644
index 0000000..ead7b7a
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2FlushRequest.cs
@@ -0,0 +1,47 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2FlushRequest
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e494678b-b1fc-44a0-b86e-8195acf74ad7
+ public ushort StructureSize { get; set; }
+ public ushort Reserved1 { get; set; }
+ public uint Reserved2 { get; set; }
+ public byte[] FileId { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2FlushResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2FlushResponse.cs
new file mode 100644
index 0000000..cf48f1e
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2FlushResponse.cs
@@ -0,0 +1,45 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2flushResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/42f78e6a-e25f-48f5-8f08-b4f1bb4c4fa4
+ public ushort StructureSize { get; set; }
+ public ushort Reserved { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2LogoffRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2LogoffRequest.cs
new file mode 100644
index 0000000..0ab01e9
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2LogoffRequest.cs
@@ -0,0 +1,45 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2LogoffRequest
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/abdc4ea9-52df-480e-9a36-34f104797d2c
+ public ushort StructureSize { get; set; }
+ public byte[] Reserved { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2LogoffResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2LogoffResponse.cs
new file mode 100644
index 0000000..b029745
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2LogoffResponse.cs
@@ -0,0 +1,45 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2LogoffResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/7539feb4-6fbb-4996-81ac-06863bb1a89e
+ public ushort StructureSize { get; set; }
+ public byte[] Reserved { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2NegotiateResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2NegotiateResponse.cs
new file mode 100644
index 0000000..e79210a
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2NegotiateResponse.cs
@@ -0,0 +1,164 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.IO;
+using Quiddity.GSSAPI;
+using Quiddity.SPNEGO;
+using Quiddity.Support;
+
+namespace Quiddity.SMB2
+{
+ class SMB2NegotiateResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/63abf97c-0d09-47e2-88d6-6bfa552949a5
+ public ushort StructureSize { get; set; }
+ public ushort SecurityMode { get; set; }
+ public byte[] DialectRivision { get; set; }
+ public ushort NegotiateContextCount { get; set; }
+ public byte[] ServerGUID { get; set; }
+ public byte[] Capabilities { get; set; }
+ public uint MaxTransactSize { get; set; }
+ public uint MaxReadSize { get; set; }
+ public uint MaxWriteSize { get; set; }
+ public byte[] SystemTime { get; set; } // todo create type
+ public byte[] ServerStartTime { get; set; }
+ public ushort SecurityBufferOffset { get; set; }
+ public ushort SecurityBufferLength { get; set; }
+ public uint NegotiateContextOffset { get; set; }
+ public byte[] Buffer { get; set; }
+ public byte[] Padding { get; set; } // todo check
+ public byte[] NegotiateContextList { get; set; }
+
+ public SMB2NegotiateResponse()
+ {
+ this.StructureSize = 65;
+ this.SecurityMode = 1;
+ this.DialectRivision = new byte[2];
+ this.NegotiateContextCount = 0;
+ this.ServerGUID = new byte[16];
+ this.Capabilities = new byte[4];
+ this.MaxTransactSize = 8388608;
+ this.MaxReadSize = 8388608;
+ this.MaxWriteSize = 8388608;
+ this.SystemTime = BitConverter.GetBytes(DateTime.Now.ToFileTime()); ;
+ this.ServerStartTime = new byte[8];
+ this.SecurityBufferOffset = 128;
+ this.SecurityBufferLength = 320;
+ this.NegotiateContextOffset = 0;
+ this.Buffer = new byte[0];
+ this.Padding = new byte[0]; // todo check
+ this.NegotiateContextList = new byte[0];
+ }
+
+ public SMB2NegotiateResponse(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.StructureSize);
+ packetWriter.Write(this.SecurityMode);
+ packetWriter.Write(this.DialectRivision);
+ packetWriter.Write(this.NegotiateContextCount);
+ packetWriter.Write(this.ServerGUID);
+ packetWriter.Write(this.Capabilities);
+ packetWriter.Write(this.MaxTransactSize);
+ packetWriter.Write(this.MaxReadSize);
+ packetWriter.Write(this.MaxWriteSize);
+ packetWriter.Write(this.SystemTime);
+ packetWriter.Write(this.ServerStartTime);
+ packetWriter.Write(this.SecurityBufferOffset);
+ packetWriter.Write(this.SecurityBufferLength);
+ packetWriter.Write(this.NegotiateContextOffset);
+ packetWriter.Write(this.Buffer);
+
+ if (!Utilities.ArrayIsNullOrEmpty(NegotiateContextList))
+ {
+ packetWriter.Write(this.NegotiateContextList);
+ }
+
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.StructureSize = packetReader.ReadUInt16();
+ this.SecurityMode = packetReader.ReadUInt16();
+ this.DialectRivision = packetReader.ReadBytes(2);
+ this.NegotiateContextCount = packetReader.ReadUInt16();
+ this.ServerGUID = packetReader.ReadBytes(16);
+ this.Capabilities = packetReader.ReadBytes(4);
+ this.MaxTransactSize = packetReader.ReadUInt32();
+ this.MaxReadSize = packetReader.ReadUInt16();
+ this.MaxWriteSize = packetReader.ReadUInt32();
+ this.SystemTime = packetReader.ReadBytes(8);
+ this.ServerStartTime = packetReader.ReadBytes(8);
+ this.SecurityBufferOffset = packetReader.ReadUInt16();
+ this.SecurityBufferLength = packetReader.ReadUInt16();
+ this.NegotiateContextOffset = packetReader.ReadUInt32();
+ this.Buffer = packetReader.ReadBytes(8);
+ }
+
+ }
+
+ public void EncodeBuffer()
+ {
+ GSSAPIInitSecContext gssapi = new GSSAPIInitSecContext();
+ SPNEGONegTokenInit spnego = new SPNEGONegTokenInit();
+ spnego.MechTypes = new byte[24] { 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x1e, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a };
+ spnego.MechToken = new byte[264] { 0x4e, 0x45, 0x47, 0x4f, 0x45, 0x58, 0x54, 0x53, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x45, 0x42, 0x37, 0xe2, 0x9c, 0xec, 0xed, 0x6a, 0x73, 0x8a, 0x3e, 0x19, 0x27, 0xdc, 0xa0, 0xb0, 0x64, 0x56, 0x91, 0x92, 0xb4, 0x5c, 0x3d, 0x8d, 0xba, 0x32, 0xd3, 0xb1, 0x31, 0xbc, 0xab, 0x29, 0xfa, 0x47, 0x3d, 0xeb, 0x87, 0x6e, 0x53, 0xd7, 0x0c, 0x91, 0x91, 0xb1, 0xae, 0x9e, 0x6b, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x33, 0x53, 0x0d, 0xea, 0xf9, 0x0d, 0x4d, 0xb2, 0xec, 0x4a, 0xe3, 0x78, 0x6e, 0xc3, 0x08, 0x4e, 0x45, 0x47, 0x4f, 0x45, 0x58, 0x54, 0x53, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x45, 0x42, 0x37, 0xe2, 0x9c, 0xec, 0xed, 0x6a, 0x73, 0x8a, 0x3e, 0x19, 0x27, 0xdc, 0xa0, 0xb0, 0x5c, 0x33, 0x53, 0x0d, 0xea, 0xf9, 0x0d, 0x4d, 0xb2, 0xec, 0x4a, 0xe3, 0x78, 0x6e, 0xc3, 0x08, 0x40, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x30, 0x56, 0xa0, 0x54, 0x30, 0x52, 0x30, 0x27, 0x80, 0x25, 0x30, 0x23, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x4b, 0x65, 0x79, 0x30, 0x27, 0x80, 0x25, 0x30, 0x23, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x4b, 0x65, 0x79 };
+ byte[] mechTokenSegment = ASN1.Encode(4, spnego.MechToken);
+ mechTokenSegment = ASN1.Encode(162, mechTokenSegment);
+ byte[] mechTypesSegment = ASN1.Encode(48, spnego.MechTypes);
+ mechTypesSegment = ASN1.Encode(160, mechTypesSegment);
+ byte[] negTokenInitSegment = Utilities.BlockCopy(mechTypesSegment, mechTokenSegment);
+ negTokenInitSegment = ASN1.Encode(48, negTokenInitSegment);
+ negTokenInitSegment = ASN1.Encode(160, negTokenInitSegment);
+ byte[] gssapiData = Utilities.BlockCopy(gssapi.OID, negTokenInitSegment);
+ this.Buffer = ASN1.Encode(96, gssapiData);
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2NegotiatelRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2NegotiatelRequest.cs
new file mode 100644
index 0000000..884c3af
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2NegotiatelRequest.cs
@@ -0,0 +1,118 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using Quiddity.Support;
+using System;
+using System.IO;
+
+namespace Quiddity.SMB2
+{
+
+ class SMB2NegotiatelRequest
+ {
+ //https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e14db7ff-763a-4263-8b10-0c3944f52fc5
+ public ushort StructureSize { get; set; }
+ public ushort DialectCount { get; set; }
+ public ushort SecurityMode { get; set; }
+ public byte[] Reserved { get; set; }
+ public byte[] Capabilities { get; set; }
+ public byte[] ClientGUID { get; set; }
+ public uint NegotiateContextOffset { get; set; }
+ public ushort NegotiateContextCount { get; set; }
+ public byte[] Reserved2 { get; set; }
+ public byte[] ClientStartTime { get; set; }
+ public byte[] Dialects { get; set; }
+ public byte[] Padding { get; set; } // todo check
+ public byte[] NegotiateContextList { get; set; }
+
+ public SMB2NegotiatelRequest(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.StructureSize);
+ packetWriter.Write(this.DialectCount);
+ packetWriter.Write(this.SecurityMode);
+ packetWriter.Write(this.Reserved);
+ packetWriter.Write(this.Capabilities);
+ packetWriter.Write(this.ClientGUID);
+ packetWriter.Write(this.NegotiateContextOffset);
+ packetWriter.Write(this.NegotiateContextCount);
+ packetWriter.Write(this.Reserved2);
+ packetWriter.Write(this.ClientStartTime);
+ packetWriter.Write(this.Dialects);
+ packetWriter.Write(this.Padding);
+ packetWriter.Write(this.NegotiateContextList);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ public ushort GetMaxDialect()
+ {
+ byte[] maxDialectData = new byte[2];
+ maxDialectData[0] = this.Dialects[this.Dialects.Length - 2];
+ maxDialectData[1] = this.Dialects[this.Dialects.Length - 1];
+ return Utilities.DataToUInt16(maxDialectData);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.StructureSize = packetReader.ReadUInt16();
+ this.DialectCount = packetReader.ReadUInt16();
+ this.SecurityMode = packetReader.ReadUInt16();
+ this.Reserved = packetReader.ReadBytes(2);
+ this.Capabilities = packetReader.ReadBytes(4);
+ this.ClientGUID = packetReader.ReadBytes(16);
+ this.NegotiateContextOffset = packetReader.ReadUInt32();
+ this.NegotiateContextCount = packetReader.ReadUInt16();
+ this.Reserved2 = packetReader.ReadBytes(2);
+ this.Dialects = packetReader.ReadBytes(this.DialectCount * 2);
+ this.Padding = packetReader.ReadBytes(8);
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2QueryDirectoryRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2QueryDirectoryRequest.cs
new file mode 100644
index 0000000..43c51b2
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2QueryDirectoryRequest.cs
@@ -0,0 +1,70 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ enum FileInformationClass : byte
+ {
+ FileDirectoryInformation = 0x01,
+ FileFullDirectoryInformation = 0x02,
+ FileIdFullDirectoryInformation = 0x26,
+ FileBothDirectoryInformation = 0x03,
+ FileIdBothDirectoryInformation = 0x25,
+ FileNamesInformation = 0x0C
+ }
+
+ enum QueryDirectoryRequestFlags : byte
+ {
+ SMB2_RESTART_SCANS = 0x01,
+ SMB2_RETURN_SINGLE_ENTRY = 0x02,
+ SMB2_INDEX_SPECIFIED = 0x04,
+ SMB2_REOPEN = 0x10
+ }
+
+ class SMB2QueryDirectoryRequest
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/10906442-294c-46d3-8515-c277efe1f752
+ public ushort StructureSize { get; set; }
+ public byte FileInformationClass { get; set; }
+ public byte Flags { get; set; }
+ public uint FileIndex { get; set; }
+ public byte[] FileId { get; set; }
+ public uint FileNameOffset { get; set; }
+ public uint FileNameLength { get; set; }
+ public uint OutputBufferLength { get; set; }
+ public byte[] Buffer { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2QueryDirectoryResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2QueryDirectoryResponse.cs
new file mode 100644
index 0000000..43534ed
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2QueryDirectoryResponse.cs
@@ -0,0 +1,47 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2QueryDirectoryResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/4f75351b-048c-4a0c-9ea3-addd55a71956
+ public ushort StructureSize { get; set; }
+ public ushort OutputBufferOffset { get; set; }
+ public uint OutputBufferLength { get; set; }
+ public byte[] Buffer { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ReadRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ReadRequest.cs
new file mode 100644
index 0000000..1cbb484
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ReadRequest.cs
@@ -0,0 +1,54 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2ReadRequest
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/320f04f3-1b28-45cd-aaa1-9e5aed810dca
+ public ushort StructureSize { get; set; }
+ public byte Padding { get; set; }
+ public byte Flags { get; set; }
+ public uint Length { get; set; }
+ public ulong Offset { get; set; }
+ public byte[] Field { get; set; }
+ public uint MinimumCount { get; set; }
+ public byte[] Channel { get; set; }
+ public uint RemainingBytes { get; set; }
+ public ushort ReadChannelInfoOffset { get; set; }
+ public byte[] Buffer { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ReadResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ReadResponse.cs
new file mode 100644
index 0000000..4d5f52f
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2ReadResponse.cs
@@ -0,0 +1,42 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2ReadResponse
+ {
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2SessionSetupRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2SessionSetupRequest.cs
new file mode 100644
index 0000000..3259da2
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2SessionSetupRequest.cs
@@ -0,0 +1,89 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System.IO;
+
+namespace Quiddity.SMB2
+{
+ class SMB2SessionSetupRequest
+ {
+ //https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5a3c2c28-d6b0-48ed-b917-a86b2ca4575f
+ public ushort StructureSize { get; set; }
+ public byte Flags { get; set; }
+ public byte SecurityMode { get; set; }
+ public byte[] Capabilities { get; set; }
+ public byte[] Channel { get; set; }
+ public ushort SecurityBufferOffset { get; set; }
+ public ushort SecurityBufferLength { get; set; }
+ public byte[] PreviousSessionId { get; set; }
+ public byte[] Buffer { get; set; }
+
+ public SMB2SessionSetupRequest()
+ {
+ this.StructureSize = 19;
+ this.Flags = 0x00;
+ this.SecurityMode = 0x01;
+ this.Capabilities = new byte[4] { 0x01, 0x00, 0x00, 0x00 };
+ this.Channel = new byte[4];
+ this.SecurityBufferOffset = 88;
+ this.SecurityBufferLength = 0;
+ this.PreviousSessionId = new byte[8];
+ this.Buffer = new byte[0];
+ }
+
+ public SMB2SessionSetupRequest(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.StructureSize = packetReader.ReadUInt16();
+ this.Flags = packetReader.ReadByte();
+ this.SecurityMode = packetReader.ReadByte();
+ this.Capabilities = packetReader.ReadBytes(4);
+ this.Channel = packetReader.ReadBytes(4);
+ this.SecurityBufferOffset = packetReader.ReadUInt16();
+ this.SecurityBufferLength = packetReader.ReadUInt16();
+ this.PreviousSessionId = packetReader.ReadBytes(8);
+ this.Buffer = packetReader.ReadBytes(this.SecurityBufferLength);
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2SessionSetupResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2SessionSetupResponse.cs
new file mode 100644
index 0000000..7948a9c
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2SessionSetupResponse.cs
@@ -0,0 +1,114 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.IO;
+using Quiddity.NTLM;
+
+namespace Quiddity.SMB2
+{
+ class SMB2SessionSetupResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/0324190f-a31b-4666-9fa9-5c624273a694
+ public ushort StructureSize { get; set; }
+ public ushort SessionFlags { get; set; }
+ public ushort SecurityBufferOffset { get; set; }
+ public ushort SecurityBufferLength { get; set; }
+ public byte[] Buffer { get; set; }
+
+ public SMB2SessionSetupResponse()
+ {
+ this.StructureSize = 9;
+ this.SessionFlags = 0;
+ this.SecurityBufferOffset = 72;
+ this.SecurityBufferLength = 0;
+ this.Buffer = new byte[0];
+ }
+
+ public SMB2SessionSetupResponse(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.StructureSize = packetReader.ReadUInt16();
+ this.SessionFlags = packetReader.ReadUInt16();
+ this.SecurityBufferOffset = packetReader.ReadUInt16();
+ this.SecurityBufferLength = packetReader.ReadUInt16();
+ this.Buffer = packetReader.ReadBytes(this.SecurityBufferLength);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+ this.SecurityBufferLength = (ushort)Buffer.Length;
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.StructureSize);
+ packetWriter.Write(this.SessionFlags);
+ packetWriter.Write(this.SecurityBufferOffset);
+ packetWriter.Write(this.SecurityBufferLength);
+
+ if (this.SecurityBufferLength > 0)
+ {
+ packetWriter.Write(this.Buffer);
+ }
+
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ public void Pack(string challenge, string netBIOSName, string computerName, string dnsDomain, string dnsComputerName, string dnsTreeName, out byte[] challengeData)
+ {
+ NTLMChallenge ntlmChallenge = new NTLMChallenge();
+ ntlmChallenge.ServerChallenge = ntlmChallenge.Challenge(challenge);
+ challengeData = ntlmChallenge.ServerChallenge;
+ byte[] timestamp = BitConverter.GetBytes(DateTime.Now.ToFileTime());
+ NTLMAVPair ntlmAVPair = new NTLMAVPair();
+ ntlmChallenge.Payload = ntlmAVPair.GetBytes(netBIOSName, computerName, dnsDomain, dnsComputerName, dnsTreeName, timestamp);
+ byte[] ntlmChallengeData = ntlmChallenge.GetBytes(computerName);
+ byte[] gssapiData = ntlmChallenge.Encode(ntlmChallengeData);
+ this.SecurityBufferLength = (ushort)gssapiData.Length;
+ this.Buffer = gssapiData;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeConnectRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeConnectRequest.cs
new file mode 100644
index 0000000..48ad1d4
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeConnectRequest.cs
@@ -0,0 +1,50 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+
+ class SMB2TreeConnectRequest
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/832d2130-22e8-4afb-aafd-b30bb0901798
+ public ushort StructureSize { get; set; }
+ public byte[] Flags { get; set; }
+ public byte[] Reserved { get; set; }
+ public ushort PathOffset { get; set; }
+ public ushort PathLength { get; set; }
+ public byte[] Buffer { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeConnectResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeConnectResponse.cs
new file mode 100644
index 0000000..64214cc
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeConnectResponse.cs
@@ -0,0 +1,88 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+
+ enum ShareType : byte
+ {
+ SMB2_SHARE_TYPE_DISK = 0x01,
+ SMB2_SHARE_TYPE_PIPE = 0x02,
+ SMB2_SHARE_TYPE_PRINT = 0x03
+ }
+
+ enum ShareFlags : uint
+ {
+ SMB2_SHAREFLAG_MANUAL_CACHING = 0x00000000,
+ SMB2_SHAREFLAG_AUTO_CACHING = 0x00000010,
+ SMB2_SHAREFLAG_VDO_CACHING = 0x00000020,
+ SMB2_SHAREFLAG_NO_CACHING = 0x00000030,
+ SMB2_SHAREFLAG_DFS = 0x00000001,
+ SMB2_SHAREFLAG_DFS_ROOT = 0x00000002,
+ SMB2_SHAREFLAG_RESTRICT_EXCLUSIVE_OPENS = 0x00000100,
+ SMB2_SHAREFLAG_FORCE_SHARED_DELETE = 0x00000200,
+ SMB2_SHAREFLAG_ALLOW_NAMESPACE_CACHING = 0x00000400,
+ SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM = 0x00000800,
+ SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK = 0x00001000,
+ SMB2_SHAREFLAG_ENABLE_HASH_V1 = 0x00002000,
+ SMB2_SHAREFLAG_ENABLE_HASH_V2 = 0x00004000,
+ SMB2_SHAREFLAG_ENCRYPT_DATA = 0x00008000,
+ SMB2_SHAREFLAG_IDENTITY_REMOTING = 0x00040000,
+ SMB2_SHAREFLAG_COMPRESS_DATA = 0x00100000
+ }
+
+ enum Capabilities : uint
+ {
+ SMB2_SHARE_CAP_DFS = 0x00000008,
+ SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY = 0x00000010,
+ SMB2_SHARE_CAP_SCALEOUT = 0x00000020,
+ SMB2_SHARE_CAP_CLUSTER = 0x00000040,
+ SMB2_SHARE_CAP_ASYMMETRIC = 0x00000080,
+ SMB2_SHARE_CAP_REDIRECT_TO_OWNER = 0x00000100
+ }
+
+
+ class SMB2TreeConnectResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/dd34e26c-a75e-47fa-aab2-6efc27502e96
+ public ushort StructureSize { get; set; }
+ public byte ShareType { get; set; }
+ public byte Reserved { get; set; }
+ public uint ShareFlags { get; set; }
+ public uint Capabilities { get; set; }
+ public uint MaximalAccess { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeDisconnectRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeDisconnectRequest.cs
new file mode 100644
index 0000000..b14ff67
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeDisconnectRequest.cs
@@ -0,0 +1,45 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2TreeDisconnectRequest
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/8a622ecb-ffee-41b9-b4c4-83ff2d3aba1b
+ public ushort StructureSize { get; set; }
+ public byte[] Reserved { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeDisconnectResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeDisconnectResponse.cs
new file mode 100644
index 0000000..40e2925
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2TreeDisconnectResponse.cs
@@ -0,0 +1,45 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2TreeDisconnectResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/aeac92de-8db3-48f8-a8b7-bfee28b9fd9e
+ public ushort StructureSize { get; set; }
+ public byte[] Reserved { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2WriteRequest.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2WriteRequest.cs
new file mode 100644
index 0000000..daf53e5
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2WriteRequest.cs
@@ -0,0 +1,68 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ enum Channel : uint
+ {
+ SMB2_CHANNEL_NONE = 0x00000001,
+ SMB2_CHANNEL_RDMA_V1 = 0x0000002,
+ SMB2_CHANNEL_RDMA_V1_INVALIDATE = 0x00000003,
+ SMB2_CHANNEL_RDMA_TRANSFORM = 0x0000004
+ }
+
+ enum WriteRequestFlags : uint // Flags
+ {
+ SMB2_WRITEFLAG_WRITE_THROUGH = 0x00000001,
+ SMB2_WRITEFLAG_WRITE_UNBUFFERED = 0x0000002
+ }
+
+ class SMB2WriteRequest
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e7046961-3318-4350-be2a-a8d69bb59ce8
+ public ushort StructureSize { get; set; }
+ public ushort DataOffset { get; set; }
+ public uint Length { get; set; }
+ public ulong Offset { get; set; }
+ public byte[] Field { get; set; }
+ public uint Channel { get; set; }
+ public uint RemainingBytes { get; set; }
+ public ushort WriteChannelInfoOffset { get; set; }
+ public ushort WriteChannelInfoLength { get; set; }
+ public uint Flags { get; set; }
+ public byte[] Buffer { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2WriteResponse.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2WriteResponse.cs
new file mode 100644
index 0000000..4266118
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Commands/SMB2WriteResponse.cs
@@ -0,0 +1,49 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2WriteResponse
+ {
+ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/7b80a339-f4d3-4575-8ce2-70a06f24f133
+ public ushort StructureSize { get; set; }
+ public byte[] Reserved { get; set; }
+ public uint Count { get; set; }
+ public uint Remaining { get; set; }
+ public ushort WriteChannelInfoOffset { get; set; }
+ public ushort WriteChannelInfoLength { get; set; }
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Header.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Header.cs
new file mode 100644
index 0000000..65f595e
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Header.cs
@@ -0,0 +1,133 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System.IO;
+
+namespace Quiddity.SMB2
+{
+ class SMB2Header
+ {
+ /*
+ https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/fb188936-5050-48d3-b350-dc43059638a4
+ */
+ public byte[] Protocol { get; set; }
+ public ushort StructureSize { get; set; }
+ public ushort CreditCharge { get; set; }
+ public byte[] Status { get; set; } // SMB2.x requests and all responses
+ public ushort ChannelSequence { get; set; } // SMB3.x requests
+ public ushort Reserved { get; set; } // SMB3.x requests
+ public ushort Command { get; set; }
+ public ushort Credit { get; set; } // CreditRequest/CreditResponse
+ public byte[] Flags { get; set; }
+ public byte[] NextCommand { get; set; }
+ public ulong MessageId { get; set; }
+ public uint Reserved2 { get; set; } // Process ID?
+ public uint TreeId { get; set; }
+ public byte[] SessionId { get; set; }
+ public byte[] Signature { get; set; }
+
+ public SMB2Header()
+ {
+ this.Protocol = new byte[4] { 0xfe, 0x53, 0x4d, 0x42 };
+ this.StructureSize = 64;
+ this.CreditCharge = 0;
+ this.Status = new byte[4];
+ this.Command = 0;
+ this.Credit = 1;
+ this.Flags = new byte[4] { 0x01, 0x00, 0x00, 0x00 };
+ this.NextCommand = new byte[4];
+ this.MessageId = 0;
+ this.Reserved2 = 0;
+ this.TreeId = 0;
+ this.SessionId = new byte[8];
+ this.Signature = new byte[16];
+ }
+
+ public SMB2Header(byte[] data)
+ {
+ ReadBytes(data, 0);
+ }
+
+ public SMB2Header(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public void ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.Protocol = packetReader.ReadBytes(4);
+ this.StructureSize = packetReader.ReadUInt16();
+ this.CreditCharge = packetReader.ReadUInt16();
+ this.Status = packetReader.ReadBytes(4);
+ this.Command = packetReader.ReadUInt16();
+ this.Credit = packetReader.ReadUInt16();
+ this.Flags = packetReader.ReadBytes(4);
+ this.NextCommand = packetReader.ReadBytes(4);
+ this.MessageId = packetReader.ReadUInt64();
+ this.Reserved2 = packetReader.ReadUInt32();
+ this.TreeId = packetReader.ReadUInt32();
+ this.SessionId = packetReader.ReadBytes(8);
+ this.Signature = packetReader.ReadBytes(16);
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(this.Protocol);
+ packetWriter.Write(this.StructureSize);
+ packetWriter.Write(this.CreditCharge);
+ packetWriter.Write(this.Status);
+ packetWriter.Write(this.Command);
+ packetWriter.Write(this.Credit);
+ packetWriter.Write(this.Flags);
+ packetWriter.Write(this.NextCommand);
+ packetWriter.Write(this.MessageId);
+ packetWriter.Write(this.Reserved2);
+ packetWriter.Write(this.TreeId);
+ packetWriter.Write(this.SessionId);
+ packetWriter.Write(this.Signature);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Helper.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Helper.cs
new file mode 100644
index 0000000..8ef9628
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Helper.cs
@@ -0,0 +1,124 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Net.Sockets;
+using Quiddity.NetBIOS;
+using Quiddity.Support;
+
+namespace Quiddity.SMB2
+{
+ class SMB2Helper
+ {
+ public NetBIOSSessionService NetBIOS = new NetBIOSSessionService();
+ public SMB2Header Header = new SMB2Header();
+ public object Payload = new object();
+
+ public void Write(SMB2Helper Packet, NetworkStream Stream)
+ {
+ byte[] headerData = Packet.Header.GetBytes();
+ byte[] commandData = new byte[0];
+
+ switch (Packet.Header.Command)
+ {
+
+ case 0:
+ {
+ SMB2NegotiateResponse command = (SMB2NegotiateResponse)Packet.Payload;
+ commandData = command.GetBytes();
+ }
+ break;
+
+ case 1:
+ {
+ SMB2SessionSetupResponse command = (SMB2SessionSetupResponse)Packet.Payload;
+ commandData = command.GetBytes();
+ }
+ break;
+
+ }
+
+ Packet.NetBIOS.Length = (ushort)(commandData.Length + 64);
+ byte[] netbiosData = Packet.NetBIOS.GetBytes();
+ byte[] buffer = Utilities.BlockCopy(netbiosData, headerData, commandData);
+ Stream.Write(buffer, 0, buffer.Length);
+ Stream.Flush();
+ }
+
+ public static byte[] GetBytes(object smb2Command)
+ {
+ NetBIOSSessionService netBIOSSessionService = new NetBIOSSessionService();
+ SMB2Header smb2Header = new SMB2Header();
+ return GetBytes(netBIOSSessionService, smb2Header, smb2Command);
+ }
+
+ public static byte[] GetBytes(NetBIOSSessionService netBIOSSessionService, SMB2Header smb2Header, object smb2Command)
+ {
+ byte[] headerData = smb2Header.GetBytes();
+ byte[] commandData = new byte[0];
+
+ switch (smb2Header.Command)
+ {
+
+ case 0:
+ {
+ SMB2NegotiateResponse command = (SMB2NegotiateResponse)smb2Command;
+ commandData = command.GetBytes();
+ }
+ break;
+
+ case 1:
+ {
+ SMB2SessionSetupResponse command = (SMB2SessionSetupResponse)smb2Command;
+ commandData = command.GetBytes();
+ }
+ break;
+
+ }
+
+ netBIOSSessionService.Length = (ushort)(commandData.Length + 64);
+ byte[] netbiosData = netBIOSSessionService.GetBytes();
+ return Utilities.BlockCopy(netbiosData, headerData, commandData);
+ }
+
+ public void NegotiateProtocol()
+ {
+
+ }
+
+ public void SessionSetup()
+ {
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Packet.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Packet.cs
new file mode 100644
index 0000000..945d2f8
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/SMB2Packet.cs
@@ -0,0 +1,42 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.SMB2
+{
+ class SMB2Packet
+ {
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SMB2/Structures/SMB2NegotiateContext.cs b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Structures/SMB2NegotiateContext.cs
new file mode 100644
index 0000000..1b94aa6
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SMB2/Structures/SMB2NegotiateContext.cs
@@ -0,0 +1,108 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Linq;
+using System.IO;
+
+namespace Quiddity.SMB2
+{
+ class SMB2NegotiateContext
+ {
+ //https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/15332256-522e-4a53-8cd7-0bd17678a2f7
+ public ushort ContextType { get; set; }
+ public ushort DataLength { get; set; }
+ public uint Reserved { get; set; }
+ public byte[] Data { get; set; }
+
+ public SMB2NegotiateContext()
+ {
+ this.ContextType = 0;
+ this.DataLength = 0;
+ this.Reserved = 0;
+ this.Data = new byte[0];
+ }
+
+ public byte[] GetBytes(string[] contextTypes)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+
+ if (contextTypes.Contains("1"))
+ {
+ this.ContextType = 1;
+ this.DataLength = 38;
+ byte[] key = new byte[32];
+ Random random = new Random();
+ random.NextBytes(key);
+ this.Data = new byte[38];
+ Buffer.BlockCopy(new byte[6] { 0x01, 0x00, 0x20, 0x00, 0x01, 0x00 }, 0, this.Data, 0, 6);
+ Buffer.BlockCopy(key, 0, this.Data, 6, key.Length);
+ packetWriter.Write(this.ContextType);
+ packetWriter.Write(this.DataLength);
+ packetWriter.Write(this.Reserved);
+ packetWriter.Write(this.Data);
+ packetWriter.Write(new byte[2] { 0x000, 0x00 });
+ }
+
+ if (contextTypes.Contains("2"))
+ {
+ this.ContextType = 2;
+ this.DataLength = 4;
+ this.Data = new byte[4] { 0x01, 0x00, 0x2, 0x00 };
+ packetWriter.Write(this.ContextType);
+ packetWriter.Write(this.DataLength);
+ packetWriter.Write(this.Reserved);
+ packetWriter.Write(this.Data);
+ packetWriter.Write(new byte[4] { 0x000, 0x00, 0x00, 0x00 });
+ }
+
+ if (contextTypes.Contains("3"))
+ {
+ this.ContextType = 3;
+ this.DataLength = 12;
+ this.Data = new byte[12] { 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00 };
+ packetWriter.Write(this.ContextType);
+ packetWriter.Write(this.DataLength);
+ packetWriter.Write(this.Reserved);
+ packetWriter.Write(this.Data);
+ }
+
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SPNEGO/SPNEGONegTokenInit.cs b/Inveigh/Protocols/Quiddity/Protocols/SPNEGO/SPNEGONegTokenInit.cs
new file mode 100644
index 0000000..8e57949
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SPNEGO/SPNEGONegTokenInit.cs
@@ -0,0 +1,64 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using Quiddity.Support;
+
+namespace Quiddity.SPNEGO
+{
+ class SPNEGONegTokenInit
+ {
+ /*
+ https://tools.ietf.org/html/rfc4178#appendix-A
+ */
+ public byte[] MechTypes { get; set; }
+ public byte[] ReqFlags { get; set; }
+ public byte[] MechToken { get; set; }
+ public byte[] MechListMIC { get; set; }
+ public byte[] NegHints { get; set; }
+
+ public SPNEGONegTokenInit()
+ {
+ this.MechTypes = new byte[0];
+ this.ReqFlags = new byte[10];
+ this.MechToken = new byte[0];
+ this.MechListMIC = new byte[0];
+ this.NegHints = new byte[0];
+ }
+
+ public void Decode(byte[] data)
+ {
+ this.MechTypes = ASN1.GetTagBytes(6, data);
+ this.MechToken = ASN1.GetTagBytes(4, data);
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/SPNEGO/SPNEGONegTokenResp.cs b/Inveigh/Protocols/Quiddity/Protocols/SPNEGO/SPNEGONegTokenResp.cs
new file mode 100644
index 0000000..869af63
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/SPNEGO/SPNEGONegTokenResp.cs
@@ -0,0 +1,55 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace Quiddity.SPNEGO
+{
+ class SPNEGONegTokenResp
+ {
+ /*
+ https://tools.ietf.org/html/rfc4178#appendix-A
+ */
+ public byte NegState { get; set; }
+ public byte[] SupportedMech { get; set; }
+ public byte[] ResponseToken { get; set; }
+ public byte[] MechListMIC { get; set; }
+
+ public SPNEGONegTokenResp()
+ {
+ this.NegState = 0;
+ this.SupportedMech = new byte[10];
+ this.ResponseToken = new byte[0];
+ this.MechListMIC = new byte[0];
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/TCP/TCPHeader.cs b/Inveigh/Protocols/Quiddity/Protocols/TCP/TCPHeader.cs
new file mode 100644
index 0000000..28c3ba9
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/TCP/TCPHeader.cs
@@ -0,0 +1,124 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.TCP
+{
+ class TCPHeader
+ {
+ // https://datatracker.ietf.org/doc/html/rfc793#section-3.1
+ public ushort SourcePort { get; set; }
+ public ushort DestinationPort { get; set; }
+ public uint SequenceNumber { get; set; }
+ public uint AcknowledgementNumber { get; set; }
+ public int DataOffset { get; set; }
+ public int Reserved { get; set; }
+ public bool URG { get; set; }
+ public bool ACK { get; set; }
+ public bool PSH { get; set; }
+ public bool RST { get; set; }
+ public bool SYN { get; set; }
+ public bool FIN { get; set; }
+ public ushort Window { get; set; }
+ public ushort Checksum { get; set; }
+ public ushort UrgentPointer { get; set; }
+ public byte[] Options { get; set; }
+ public byte[] Padding { get; set; }
+
+ // custom
+ public string Flags { get; set; }
+
+ public void ReadBytes(byte[] data, int position)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = position;
+ this.SourcePort = packetReader.BigEndianReadUInt16();
+ this.DestinationPort = packetReader.BigEndianReadUInt16();
+ this.SequenceNumber = packetReader.BigEndianReadUInt32();
+ this.AcknowledgementNumber = packetReader.BigEndianReadUInt32();
+ this.Flags = packetReader.ReadBinary(2);
+ ReadFlags();
+ this.Window = packetReader.BigEndianReadUInt16();
+ this.Checksum = packetReader.BigEndianReadUInt16();
+ this.UrgentPointer = packetReader.BigEndianReadUInt16();
+ this.Options = packetReader.BigEndianReadBytes(3);
+ this.Padding = packetReader.BigEndianReadBytes(3);
+ }
+
+ }
+
+ protected virtual void ReadFlags()
+ {
+ this.DataOffset = Convert.ToInt32(this.Flags.Substring(0, 4), 2) * 4;
+ this.Reserved = Convert.ToInt32(this.Flags.Substring(4, 3), 2);
+
+ if (string.Equals(this.Flags.Substring(10, 1), "1"))
+ {
+ this.URG = true;
+ }
+
+ if (string.Equals(this.Flags.Substring(11, 1), "1"))
+ {
+ this.ACK = true;
+ }
+
+ if (string.Equals(this.Flags.Substring(12, 1), "1"))
+ {
+ this.PSH = true;
+ }
+
+ if (string.Equals(this.Flags.Substring(13, 1), "1"))
+ {
+ this.RST = true;
+ }
+
+ if (string.Equals(this.Flags.Substring(14, 1), "1"))
+ {
+ this.SYN = true;
+ }
+
+ if (string.Equals(this.Flags.Substring(15, 1), "1"))
+ {
+ this.FIN = true;
+ }
+
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Protocols/UDP/UDPHeader.cs b/Inveigh/Protocols/Quiddity/Protocols/UDP/UDPHeader.cs
new file mode 100644
index 0000000..f6e8671
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Protocols/UDP/UDPHeader.cs
@@ -0,0 +1,130 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.IO;
+using System.Net;
+
+namespace Quiddity.UDP
+{
+ class UDPHeader
+ {
+ // https://tools.ietf.org/html/rfc768
+ public ushort SourcePort { get; set; }
+ public ushort DestinationPort { get; set; }
+ public ushort Length { get; set; }
+ public ushort Checksum { get; set; }
+
+ public UDPHeader()
+ {
+ this.SourcePort = 0;
+ this.DestinationPort = 0;
+ this.Length = 0;
+ this.Checksum = 0;
+ }
+
+ public UDPHeader(byte[] data, int offset)
+ {
+ ReadBytes(data, offset);
+ }
+
+ public UDPHeader ReadBytes(byte[] data, int offset)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+ memoryStream.Position = offset;
+ this.SourcePort = packetReader.BigEndianReadUInt16();
+ this.DestinationPort = packetReader.BigEndianReadUInt16();
+ this.Length = packetReader.BigEndianReadUInt16();
+ this.Checksum = packetReader.ReadUInt16();
+ return this;
+ }
+
+ }
+
+ public byte[] GetBytes()
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.BigEndianWrite(this.SourcePort);
+ packetWriter.BigEndianWrite(this.DestinationPort);
+ packetWriter.BigEndianWrite(this.Length);
+ packetWriter.Write(this.Checksum);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ public void IPv6Checksum(byte[] data, string clientIP, string sourceIP, int nextHeader)
+ {
+ byte[] pseudoHeader = IPv6PseudoHeader(clientIP, sourceIP, nextHeader, data.Length);
+ int e = 0;
+
+ if ((pseudoHeader.Length + data.Length) % 2 != 0)
+ {
+ e = 1;
+ }
+
+ byte[] packet = new byte[pseudoHeader.Length + data.Length + e];
+ Buffer.BlockCopy(pseudoHeader, 0, packet, 0, pseudoHeader.Length);
+ Buffer.BlockCopy(data, 0, packet, pseudoHeader.Length, data.Length);
+ uint packetChecksum = 0;
+ int index = 0;
+
+ while (index < packet.Length)
+ {
+ packetChecksum += Convert.ToUInt32(BitConverter.ToUInt16(packet, index));
+ index += 2;
+ }
+
+ packetChecksum = (packetChecksum >> 16) + (packetChecksum & 0xffff);
+ packetChecksum += (packetChecksum >> 16);
+ this.Checksum = (ushort)~packetChecksum;
+ }
+
+ private byte[] IPv6PseudoHeader(string clientIP, string sourceIP, int nextHeader, int length)
+ {
+ byte[] lengthData = BitConverter.GetBytes(length);
+ Array.Reverse(lengthData);
+ byte[] pseudoHeader = new byte[40];
+ Buffer.BlockCopy(IPAddress.Parse(sourceIP).GetAddressBytes(), 0, pseudoHeader, 0, 16);
+ Buffer.BlockCopy(IPAddress.Parse(clientIP).GetAddressBytes(), 0, pseudoHeader, 16, 16);
+ Buffer.BlockCopy(lengthData, 0, pseudoHeader, 32, 4);
+ pseudoHeader[39] = (byte)nextHeader;
+ return pseudoHeader;
+ }
+
+ }
+}
diff --git a/Inveigh/Protocols/Quiddity/Support/ASN1.cs b/Inveigh/Protocols/Quiddity/Support/ASN1.cs
new file mode 100644
index 0000000..b1862c7
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Support/ASN1.cs
@@ -0,0 +1,284 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Quiddity.Support
+{
+ // https://github.com/mono/mono/blob/main/mcs/class/Mono.Security/Mono.Security/ASN1.cs
+
+ class ASN1
+ {
+ public byte[] Tag { get; set; }
+ public byte[] Length { get; set; }
+ public byte[] Value { get; set; }
+
+ public ASN1()
+ {
+ this.Tag = new byte[1];
+ this.Length = new byte[1];
+ this.Value = new byte[0];
+ }
+
+ public byte[] GetBytes(ASN1 packet)
+ {
+
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ PacketWriter packetWriter = new PacketWriter(memoryStream);
+ packetWriter.Write(packet.Tag);
+ packetWriter.Write(packet.Length);
+ packetWriter.Write(packet.Value);
+ return memoryStream.ToArray();
+ }
+
+ }
+
+ public byte[] GetTagBytes(byte[] data, ref int index, int length, byte tag, out byte tagDecoded)
+ {
+ tagDecoded = 0x00;
+ byte[] value = new byte[0];
+ int valueLength;
+
+ while (index < length - 1 && tag != tagDecoded)
+ {
+ DecodeTag(data, ref index, out tagDecoded, out valueLength, out value);
+
+ if (tagDecoded == 0 || tag == tagDecoded)
+ {
+ continue;
+ }
+
+ if ((tagDecoded & 0x20) == 0x20)
+ {
+ int decodePosistion = index;
+ value = GetTagBytes(data, ref decodePosistion, (decodePosistion + valueLength), tag, out tagDecoded);
+ }
+
+ index += valueLength;
+ }
+
+ return value;
+ }
+
+ public byte GetTag(byte[] data)
+ {
+ byte tagDecoded;
+ byte[] value;
+ int valueLength;
+ int index = 0;
+
+ DecodeTag(data, ref index, out tagDecoded, out valueLength, out value);
+ return tagDecoded;
+ }
+
+ public static byte[] GetTagBytes(int tag, byte[] data)
+ {
+ byte tagDecoded = 0x00;
+ int index = 0;
+ ASN1 asn1 = new ASN1();
+ return asn1.GetTagBytes(data, ref index, data.Length, (byte)tag, out tagDecoded);
+ }
+
+ public static byte[] GetTagBytes(int tag, byte[] data, int index)
+ {
+ byte tagDecoded = 0x00;
+ ASN1 asn1 = new ASN1();
+ return asn1.GetTagBytes(data, ref index, data.Length, (byte)tag, out tagDecoded);
+ }
+
+ public byte[] Decode(byte[] data, ref int index, int length)
+ {
+ byte tag;
+ byte[] value = new byte[0];
+ int valueLength;
+ int i = 0;
+
+ while (index < length - 1)
+ {
+ DecodeTag(data, ref index, out tag, out valueLength, out value);
+
+ if (tag == 0)
+ {
+ continue;
+ }
+
+ if((tag & 0x20) == 0x20)
+ {
+ int decodePosistion = index;
+ value = Decode(data, ref decodePosistion, (decodePosistion + valueLength));
+ }
+
+ index += valueLength;
+ i++;
+
+ }
+
+ return value;
+ }
+
+ public void DecodeTag(byte[] data, ref int index, out byte tag, out int length, out byte[] value)
+ {
+ tag = data[index++];
+ length = data[index++];
+
+ if ((length & 0x80) == 0x80)
+ {
+ int lengthCount = length & 0x7f;
+ length = 0;
+
+ for (int i = 0; i < lengthCount; i++)
+ {
+ length = length * 256 + data[index++];
+ }
+
+ }
+
+ value = new byte[length];
+ Buffer.BlockCopy(data, index, value, 0, length);
+ }
+
+ public byte[] Encode(byte tag, byte[] data)
+ {
+ int dataLength = data.Length;
+ this.Tag[0] = tag;
+
+ if (dataLength <= 127)
+ {
+ this.Length[0] = (byte)dataLength;
+ }
+ else if (dataLength <= 255)
+ {
+ this.Length = new byte[2];
+ this.Length[0] = 0x81;
+ this.Length[1] = (byte)dataLength;
+ }
+ else if (dataLength > 255)
+ {
+ this.Length = new byte[3];
+ this.Length[0] = 0x82;
+ this.Length[1] = (byte)(dataLength >> 8);
+ this.Length[2] = (byte)(dataLength);
+ }
+
+ return Utilities.BlockCopy(this.Tag, this.Length, data);
+ }
+
+ public static byte[] Encode(int tag, byte[] data)
+ {
+ ASN1 asn1 = new ASN1();
+ return asn1.Encode((byte)tag, data);
+ }
+
+ public static string[] DecodeOctetStringArray (byte[] data)
+ {
+ int index = Array.IndexOf<byte>(data, 0x04, 0);
+ List<string> list = new List<string>();
+
+ using (MemoryStream memoryStream = new MemoryStream(data))
+ {
+ PacketReader packetReader = new PacketReader(memoryStream);
+
+ while (index > -1)
+ {
+ memoryStream.Position += 2;
+ list.Add(Encoding.UTF8.GetString(packetReader.ReadBytes(data[index + 1])));
+ index = Array.IndexOf<byte>(data, 0x04, (int)memoryStream.Position);
+ }
+
+ }
+
+ return list.ToArray();
+ }
+
+ public static int GetLength(int index, byte[] data)
+ {
+ int length = 0;
+
+ switch (data[index])
+ {
+
+ case 0x84:
+ {
+ index++;
+ byte[] lengthData = new byte[4];
+ Buffer.BlockCopy(data, index, lengthData, 0, 4);
+ Array.Reverse(lengthData);
+ length = BitConverter.ToInt32(lengthData, 0);
+ length += 4;
+ }
+ break;
+
+ case 0x83:
+ {
+ index++;
+ byte[] lengthData = new byte[3];
+ Buffer.BlockCopy(data, index, lengthData, 0, 4);
+ Array.Reverse(lengthData);
+ length = BitConverter.ToInt32(lengthData, 0);
+ length += 3;
+ }
+ break;
+
+ case 0x82:
+ {
+ index++;
+ byte[] lengthData = new byte[2];
+ Buffer.BlockCopy(data, index, lengthData, 0, 2);
+ Array.Reverse(lengthData);
+ length = BitConverter.ToInt16(lengthData, 0);
+ length += 2;
+ }
+ break;
+
+ case 0x81:
+ {
+ length = data[index++];
+ length += 3;
+ }
+ break;
+
+ default:
+ length = data[index];
+ length += 2;
+ break;
+
+ }
+
+ return length;
+ }
+
+ }
+
+}
diff --git a/Inveigh/Protocols/Quiddity/Support/Utilities.cs b/Inveigh/Protocols/Quiddity/Support/Utilities.cs
new file mode 100644
index 0000000..51c994a
--- /dev/null
+++ b/Inveigh/Protocols/Quiddity/Support/Utilities.cs
@@ -0,0 +1,126 @@
+/*
+ * BSD 3-Clause License
+ *
+ * Copyright (c) 2021, Kevin Robertson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Quiddity.Support
+{
+ class Utilities
+ {
+
+ public static byte[] BlockCopy(byte[] Data1, byte[] Data2)
+ {
+ byte[] data = new byte[Data1.Length + Data2.Length];
+ Buffer.BlockCopy(Data1, 0, data, 0, Data1.Length);
+ Buffer.BlockCopy(Data2, 0, data, Data1.Length, Data2.Length);
+ return data;
+ }
+
+ public static byte[] BlockCopy(byte[] Data1, byte[] Data2, byte[] Data3)
+ {
+ byte[] data = new byte[Data1.Length + Data2.Length + Data3.Length];
+ Buffer.BlockCopy(Data1, 0, data, 0, Data1.Length);
+ Buffer.BlockCopy(Data2, 0, data, Data1.Length, Data2.Length);
+ Buffer.BlockCopy(Data3, 0, data, (Data1.Length + Data2.Length), Data3.Length);
+ return data;
+ }
+
+ public static byte[] BlockCopy(byte[] Data1, byte[] Data2, byte[] Data3, byte[] Data4)
+ {
+ byte[] data = new byte[Data1.Length + Data2.Length + Data3.Length + Data4.Length];
+ Buffer.BlockCopy(Data1, 0, data, 0, Data1.Length);
+ Buffer.BlockCopy(Data2, 0, data, Data1.Length, Data2.Length);
+ Buffer.BlockCopy(Data3, 0, data, (Data1.Length + Data2.Length), Data3.Length);
+ Buffer.BlockCopy(Data4, 0, data, (Data1.Length + Data2.Length + Data3.Length), Data4.Length);
+ return data;
+ }
+
+ public static bool ArrayIsNullOrEmpty(Array array)
+ {
+ return (array == null || array.Length == 0);
+ }
+
+ public static ushort DataToUInt16(byte[] data)
+ {
+ return BitConverter.ToUInt16(data, 0);
+ }
+
+ public static byte[] GetDNSNameBytes(string name, bool addByte)
+ {
+ var indexList = new List<int>();
+
+ for (int i = name.IndexOf('.'); i > -1; i = name.IndexOf('.', i + 1))
+ {
+ indexList.Add(i);
+ }
+
+ using (MemoryStream nameMemoryStream = new MemoryStream())
+ {
+ string nameSection = "";
+ int nameStart = 0;
+
+ if (indexList.Count > 0)
+ {
+ int nameEnd = 0;
+
+ foreach (int index in indexList)
+ {
+ nameEnd = index - nameStart;
+ nameMemoryStream.Write(BitConverter.GetBytes(nameEnd), 0, 1);
+ nameSection = name.Substring(nameStart, nameEnd);
+ nameMemoryStream.Write(Encoding.UTF8.GetBytes(nameSection), 0, nameSection.Length);
+ nameStart = index + 1;
+ }
+
+ }
+
+ nameSection = name.Substring(nameStart);
+ nameMemoryStream.Write(BitConverter.GetBytes(nameSection.Length), 0, 1);
+ nameMemoryStream.Write(Encoding.UTF8.GetBytes(nameSection), 0, nameSection.Length);
+
+ if (addByte)
+ {
+ nameMemoryStream.Write((new byte[1] { 0x00 }), 0, 1);
+ }
+
+ return nameMemoryStream.ToArray();
+ }
+
+ }
+
+
+ }
+
+}
diff --git a/Inveigh/Protocols/README.md b/Inveigh/Protocols/README.md
new file mode 100644
index 0000000..13f604f
--- /dev/null
+++ b/Inveigh/Protocols/README.md
@@ -0,0 +1,17 @@
+# Quiddity# Quiddity
+
+Quiddity is a work in progress C# miscellaneous protocol library meant for infosec testing/defense. The library contains classes for packet segment structures, protocol functions, and listeners. This library is currently being developed as part of Inveigh and other, unreleased projects. It's likely to go through major changes.
+
+## Example Usage
+
+### LLMNR Listener
+
+```
+LLMNRListener llmnrListener = new LLMNRListener();
+llmnrListener.Start(listenerIP, replyIPv4, replyIPv6);
+```
+### Parse SMB2 Header
+```
+SMB2Header smb2Header = new SMB2Header(byteArray);
+Console.WriteLine(smb2Header.Command); // output SMB2 command type of parsed header
+``` \ No newline at end of file