Skip to content

Commit 6641b83

Browse files
committed
Add project files.
1 parent a12573f commit 6641b83

19 files changed

+768
-0
lines changed

.editorconfig

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
[*.cs]
2+
3+
# IDE0090: Use 'new(...)'
4+
dotnet_diagnostic.IDE0090.severity = none
5+
6+
# IDE0066: Convert switch statement to expression
7+
dotnet_diagnostic.IDE0066.severity = none
8+
csharp_indent_labels = one_less_than_current
9+
csharp_using_directive_placement = outside_namespace:silent
10+
csharp_prefer_simple_using_statement = true:suggestion
11+
csharp_prefer_braces = true:silent
12+
csharp_style_namespace_declarations = block_scoped:silent
13+
csharp_style_prefer_method_group_conversion = true:silent
14+
csharp_style_prefer_top_level_statements = true:silent
15+
csharp_style_expression_bodied_methods = false:silent
16+
csharp_style_expression_bodied_constructors = false:silent
17+
csharp_style_expression_bodied_operators = false:silent
18+
csharp_style_expression_bodied_properties = true:silent
19+
csharp_style_expression_bodied_indexers = true:silent
20+
csharp_style_expression_bodied_accessors = true:silent
21+
csharp_style_expression_bodied_lambdas = true:silent
22+
csharp_style_expression_bodied_local_functions = false:silent
23+
24+
[*.{cs,vb}]
25+
#### Naming styles ####
26+
27+
# Naming rules
28+
29+
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
30+
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
31+
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
32+
33+
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
34+
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
35+
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
36+
37+
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
38+
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
39+
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
40+
41+
# Symbol specifications
42+
43+
dotnet_naming_symbols.interface.applicable_kinds = interface
44+
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
45+
dotnet_naming_symbols.interface.required_modifiers =
46+
47+
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
48+
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
49+
dotnet_naming_symbols.types.required_modifiers =
50+
51+
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
52+
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
53+
dotnet_naming_symbols.non_field_members.required_modifiers =
54+
55+
# Naming styles
56+
57+
dotnet_naming_style.begins_with_i.required_prefix = I
58+
dotnet_naming_style.begins_with_i.required_suffix =
59+
dotnet_naming_style.begins_with_i.word_separator =
60+
dotnet_naming_style.begins_with_i.capitalization = pascal_case
61+
62+
dotnet_naming_style.pascal_case.required_prefix =
63+
dotnet_naming_style.pascal_case.required_suffix =
64+
dotnet_naming_style.pascal_case.word_separator =
65+
dotnet_naming_style.pascal_case.capitalization = pascal_case
66+
67+
dotnet_naming_style.pascal_case.required_prefix =
68+
dotnet_naming_style.pascal_case.required_suffix =
69+
dotnet_naming_style.pascal_case.word_separator =
70+
dotnet_naming_style.pascal_case.capitalization = pascal_case
71+
dotnet_style_operator_placement_when_wrapping = beginning_of_line
72+
tab_width = 4
73+
indent_size = 4
74+
end_of_line = crlf
75+
dotnet_style_coalesce_expression = true:suggestion
76+
dotnet_style_null_propagation = true:suggestion
77+
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion

ICMPv6DotNet.sln

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.5.33424.131
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICMPv6DotNet", "ICMPv6Sharp\ICMPv6DotNet.csproj", "{DE576278-124D-4D5E-96A7-D4C0F2ACEC5B}"
7+
EndProject
8+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7F141CE5-ACB3-42FD-B3BD-2F1CC449751C}"
9+
ProjectSection(SolutionItems) = preProject
10+
.editorconfig = .editorconfig
11+
EndProjectSection
12+
EndProject
13+
Global
14+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
15+
Debug|Any CPU = Debug|Any CPU
16+
Release|Any CPU = Release|Any CPU
17+
EndGlobalSection
18+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
19+
{DE576278-124D-4D5E-96A7-D4C0F2ACEC5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20+
{DE576278-124D-4D5E-96A7-D4C0F2ACEC5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
21+
{DE576278-124D-4D5E-96A7-D4C0F2ACEC5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
22+
{DE576278-124D-4D5E-96A7-D4C0F2ACEC5B}.Release|Any CPU.Build.0 = Release|Any CPU
23+
EndGlobalSection
24+
GlobalSection(SolutionProperties) = preSolution
25+
HideSolutionNode = FALSE
26+
EndGlobalSection
27+
GlobalSection(ExtensibilityGlobals) = postSolution
28+
SolutionGuid = {ACDB6221-943A-42FB-BE7E-A30D32FA881F}
29+
EndGlobalSection
30+
EndGlobal

ICMPv6Sharp/ICMPPacket.cs

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using System;
2+
using System.Buffers.Binary;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Net;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using ICMPv6DotNet.Packets;
9+
10+
namespace ICMPv6DotNet
11+
{
12+
public class ICMPPacket
13+
{
14+
protected Memory<byte> buffer;
15+
protected IPAddress source;
16+
protected IPAddress destination;
17+
protected bool valid = false;
18+
protected ICMPV6Payload? payload;
19+
20+
public ICMPPacket(Span<byte> bytes, IPAddress source, IPAddress destination)
21+
{
22+
if (bytes.Length < 4)
23+
buffer = new byte[4];
24+
else
25+
buffer = bytes.ToArray();
26+
this.source = source;
27+
this.destination = destination;
28+
}
29+
30+
public bool IsValid
31+
{
32+
get
33+
{
34+
if (buffer.Span[0] == 0)
35+
return false;
36+
if (!valid)
37+
{
38+
lock (source)
39+
{
40+
valid = Validate();
41+
}
42+
}
43+
return valid;
44+
}
45+
}
46+
47+
private bool Validate()
48+
{
49+
uint checksum = 0;
50+
Span<byte> sourceBytes = source.GetAddressBytes();
51+
Span<byte> destBytes = destination.GetAddressBytes();
52+
Span<byte> lengthBytes = new byte[4];
53+
BinaryPrimitives.WriteUInt32BigEndian(lengthBytes, (uint)buffer.Length);
54+
for (var i = 0; i < 16; i += 2)
55+
{
56+
checksum += BinaryPrimitives.ReadUInt16BigEndian(sourceBytes.Slice(i));
57+
checksum += BinaryPrimitives.ReadUInt16BigEndian(destBytes.Slice(i));
58+
}
59+
checksum += BinaryPrimitives.ReadUInt16BigEndian(lengthBytes.Slice(0));
60+
checksum += BinaryPrimitives.ReadUInt16BigEndian(lengthBytes.Slice(2));
61+
checksum += (ushort)58;
62+
for (var i = 0; i < buffer.Length; i += 2)
63+
checksum += BinaryPrimitives.ReadUInt16BigEndian(buffer.Slice(i).Span);
64+
if (buffer.Length % 2 != 0)
65+
checksum += buffer.Span[buffer.Length - 1];
66+
67+
while (checksum > 0xFFFF)
68+
checksum = (checksum & 0xFFFF) + (checksum >> 16);
69+
return ((checksum & 0xFFFF) == 0xFFFF);
70+
//To Calculate a checksum 0 out checksum field and then
71+
//checksum = (ushort)~checksum;
72+
}
73+
74+
public IPAddress Source { get { return source; } }
75+
public IPAddress Destination { get { return destination; } }
76+
public ICMPType Type { get { return (ICMPType)buffer.Span[0]; } }
77+
public bool IsError { get { return buffer.Span[0] > 0 && buffer.Span[0] < 128; } }
78+
public bool IsInfo { get { return buffer.Span[0] > 127; } }
79+
public ushort Checksum { get { return BitConverter.ToUInt16(buffer.Slice(2, 2).Span); } }
80+
public ICMPV6Payload? Payload
81+
{
82+
get
83+
{
84+
if (!IsValid)
85+
return null;
86+
payload ??= ICMPV6Payload.Create(buffer, Type);
87+
return payload;
88+
}
89+
}
90+
91+
public override string ToString()
92+
{
93+
if (!IsValid)
94+
return $"Invalid Packet [Length: {buffer.Length}]";
95+
if (Payload == null)
96+
return $"{Type} from {Source} to {Destination}";
97+
98+
return $"{Type} from {Source}: {Payload}";
99+
}
100+
}
101+
}

ICMPv6Sharp/ICMPType.cs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace ICMPv6DotNet
2+
{
3+
public enum ICMPType
4+
{
5+
Invalid = 0,
6+
DestinationUnreachable = 1,
7+
PacketTooBig = 2,
8+
TimeExceeded = 3,
9+
ParameterProblem = 4,
10+
PrivateExperimentationError = 100,
11+
PrivateExperimentationError2 = 101,
12+
EchoRequest= 128,
13+
EchoReply = 129,
14+
MLDQuery = 130,
15+
MLDReport = 131,
16+
MLDDone = 132,
17+
RouterSolicitation = 133,
18+
RouterAdvertisement = 134,
19+
NeighborSolicitation = 135,
20+
NeighborAdvertisement = 136,
21+
RedirectMessage = 137,
22+
RouterRenumbering = 138,
23+
NodeInformationQuery = 139,
24+
NodeInformationResponse = 140,
25+
InverseNeighborDiscoverySolicitation = 141,
26+
InverseNeighborDiscoveryAdvertisement = 142,
27+
MLDv2Report = 143,
28+
HomeAgentAddressDiscoveryRequest = 144,
29+
HomeAgentAddressDiscoveryReply = 145,
30+
MobilePrefixSolicitation = 146,
31+
MobilePrefixReply = 147,
32+
CertificationPathSolicitation = 148,
33+
CertificationPathAdvertisement = 149,
34+
MulticastRouterAdvertisement = 151,
35+
MulticastRouterSolicitation = 152,
36+
MulticastRouterTermination = 153,
37+
RPLControl = 155,
38+
PrivateExperimentationInfo = 200,
39+
PrivateExperimentationInfo2 = 201,
40+
}
41+
}

ICMPv6Sharp/ICMPv6DotNet.csproj

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<None Include="..\.editorconfig" Link=".editorconfig" />
12+
</ItemGroup>
13+
14+
</Project>

ICMPv6Sharp/Packets/ErrorReason.cs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace ICMPv6DotNet.Packets
2+
{
3+
public enum ErrorReason
4+
{
5+
NoRouteToDestination = 0x100,
6+
CommunicationWithDestinationAdministrativelyProhibited = 0x101,
7+
BeyondScopeOfSourceAddress = 0x102,
8+
AddressUnreachable = 0x103,
9+
PortUnreachable = 0x104,
10+
SourceAddressFailedIngressEgressPolicy = 0x105,
11+
RejectRouteToDestination = 0x106,
12+
ErrorInSourceRoutingHeader = 0x107,
13+
HopLimitExceededInTransit = 0x300,
14+
FragmentReassemblyTimeExceeded = 0x301,
15+
ErroneousHeaderFieldEncountered = 0x400,
16+
UnrecognizedNextHeaderTypeEncountered = 0x401,
17+
UnrecognizedIPv6OptionEncountered = 0x402
18+
}
19+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Text;
2+
3+
namespace ICMPv6DotNet.Packets
4+
{
5+
public class ICMPBinaryPayload : ICMPV6Payload
6+
{
7+
public ICMPBinaryPayload(Memory<byte> buffer) : base(buffer) { }
8+
public override string ToString()
9+
{
10+
return "Payload: " + Encoding.ASCII.GetString(buffer.Slice(4).Span);
11+
}
12+
}
13+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using ICMPv6DotNet.Packets;
2+
using System.Buffers.Binary;
3+
using System.Text;
4+
5+
namespace ICMPv6DotNet
6+
{
7+
public class ICMPErrorPayload : ICMPV6Payload
8+
{
9+
public ICMPErrorPayload(Memory<byte> buffer, ICMPType type) : base(buffer)
10+
{
11+
if (type == ICMPType.PacketTooBig)
12+
MTU = BinaryPrimitives.ReadUInt32BigEndian(buffer.Slice(4, 4).Span);
13+
else if (type == ICMPType.ParameterProblem)
14+
Pointer = BinaryPrimitives.ReadUInt32BigEndian(buffer.Slice(4, 4).Span);
15+
Reason = (ErrorReason)(((int)type << 8) + Code);
16+
}
17+
public override string ToString()
18+
{
19+
return $"Reason: {Reason}, MTU: {MTU}, Packet: {Encoding.ASCII.GetString(buffer.Slice(8).Span)}";
20+
}
21+
22+
public uint? MTU { get; private set; }
23+
public uint? Pointer { get; private set; }
24+
public ErrorReason Reason { get; private set; }
25+
}
26+
}

ICMPv6Sharp/Packets/ICMPV6Payload.cs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using ICMPv6DotNet.Packets.MLD;
2+
using ICMPv6DotNet.Packets.NDPOptions;
3+
4+
namespace ICMPv6DotNet.Packets
5+
{
6+
public abstract class ICMPV6Payload
7+
{
8+
protected Memory<byte> buffer;
9+
10+
internal ICMPV6Payload(Memory<byte> buffer)
11+
{
12+
this.buffer = buffer;
13+
}
14+
15+
internal static ICMPV6Payload? Create(Memory<byte> buffer, ICMPType type)
16+
{
17+
switch (type)
18+
{
19+
case ICMPType.DestinationUnreachable:
20+
case ICMPType.TimeExceeded:
21+
case ICMPType.PacketTooBig:
22+
case ICMPType.ParameterProblem:
23+
return new ICMPErrorPayload(buffer, type);
24+
case ICMPType.EchoReply:
25+
case ICMPType.EchoRequest:
26+
return new ICMPBinaryPayload(buffer);
27+
case ICMPType.NeighborAdvertisement:
28+
case ICMPType.NeighborSolicitation:
29+
case ICMPType.RouterAdvertisement:
30+
case ICMPType.RouterSolicitation:
31+
case ICMPType.RedirectMessage:
32+
return new NDPPayload(buffer, type);
33+
case ICMPType.MLDv2Report:
34+
return new MLDReportPayload(buffer, type);
35+
default:
36+
return null;
37+
}
38+
}
39+
40+
public byte Code { get { return buffer.Span[1]; } }
41+
public virtual bool IsValid { get { return true; } }
42+
43+
public abstract override string ToString();
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace ICMPv6DotNet.Packets.MLD
2+
{
3+
public enum MLDGroupRecordType
4+
{
5+
Invalid = 0,
6+
ModeIsInclude = 1,
7+
ModeIsExcluse = 2,
8+
ChangeToIncludeMode = 3,
9+
ChangeToExcludeMode = 4,
10+
AllowNewSources = 5,
11+
BlockOldSources = 6
12+
}
13+
}

0 commit comments

Comments
 (0)