├── .editorconfig ├── .github └── workflows │ └── build.yml ├── .gitignore ├── Enclave.FastPacket.sln ├── GitVersion.yml ├── LICENSE ├── README.md ├── bench └── Enclave.FastPacket.Benchmarks │ ├── Benchmarks.cs │ ├── Enclave.FastPacket.Benchmarks.csproj │ ├── Examples │ └── mongodb-ssh-tcp-packet.bin │ ├── Packets │ └── PacketInspectionBenchmark.cs │ └── Program.cs ├── src ├── Directory.Build.props ├── Enclave.FastPacket.Generator │ ├── AnalyzerReleases.Shipped.md │ ├── AnalyzerReleases.Unshipped.md │ ├── Diagnostics.cs │ ├── Enclave.FastPacket.Generator.csproj │ ├── EnumRenderer.cs │ ├── FileTemplates │ │ ├── PacketFieldAttribute.cs │ │ ├── PacketImplementationAttribute.cs │ │ ├── ReadOnlyRefStruct.cs │ │ └── WriteableRefStruct.cs │ ├── GenerationOptions.cs │ ├── IPacketField.cs │ ├── IParserBuilder.cs │ ├── PacketField.cs │ ├── PacketFieldFactory.cs │ ├── PacketFieldOptions.cs │ ├── PacketParserDefinition.cs │ ├── PacketParserGenerator.cs │ ├── PositionProviders │ │ ├── AutomaticPositionProvider.cs │ │ ├── ExplicitPositionProvider.cs │ │ ├── FunctionPositionAutomaticDefaultProvider.cs │ │ ├── FunctionPositionExplicitDefaultProvider.cs │ │ └── IPositionProvider.cs │ ├── Range.Shim.cs │ ├── SizeProviders │ │ ├── CustomTypeConstantSizeProvider.cs │ │ ├── CustomTypeMethodSizeProvider.cs │ │ ├── ExplicitSizeProvider.cs │ │ ├── FieldSizeProvider.cs │ │ ├── FunctionSizeProvider.cs │ │ ├── IConstantSizeProvider.cs │ │ ├── IPropertyReferencingSizeProvider.cs │ │ ├── ISizeProvider.cs │ │ ├── SizeOfSizeProvider.cs │ │ └── SpanRemainingLengthSizeProvider.cs │ ├── SymbolNameExtensions.cs │ ├── TemplatedParserBuilder.cs │ ├── ValueProviders │ │ ├── BinaryPrimitivesValueProvider.cs │ │ ├── BitmaskHelpers.cs │ │ ├── BitmaskWrapperValueProvider.cs │ │ ├── BoolFromNumberValueProvider.cs │ │ ├── CastingValueProvider.cs │ │ ├── CustomProviderResult.cs │ │ ├── CustomTypeValueProvider.cs │ │ ├── INumericValueProvider.cs │ │ ├── ISpanValueProvider.cs │ │ ├── IValueProvider.cs │ │ ├── SingleByteValueProvider.cs │ │ ├── SpanKnownSizeValueProvider.cs │ │ └── SpanRestOfDataValueProvider.cs │ └── VirtualUnionField.cs └── Enclave.FastPacket │ ├── Arp.cs │ ├── ArpOperation.cs │ ├── Enclave.FastPacket.csproj │ ├── Ethernet.cs │ ├── EthernetType.cs │ ├── FastPacketException.cs │ ├── Generated │ ├── net5.0 │ │ └── Enclave.FastPacket.Generator │ │ │ └── Enclave.FastPacket.Generator.PacketParserGenerator │ │ │ ├── Enclave.FastPacket.ArpPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.EthernetPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4AddressMaskSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4DestinationUnreachableSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4RedirectSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4SourceQuenchSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4TimeExceededSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4TimestampSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4AddressMaskSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4DestinationUnreachableSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4RedirectSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4SourceQuenchSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4TimeExceededSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4TimestampSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmpv4PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Ipv4PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Ipv6PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyArpPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyEthernetPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIcmpv4PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIpv4PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIpv6FragmentExtensionSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIpv6HopByHopAndDestinationExtensionSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIpv6PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIpv6RoutingExtensionSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyTcpPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyUdpPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.TcpPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.UdpPacketSpan_Generated.cs │ │ │ ├── FastPacket_PacketFieldAttribute.cs │ │ │ └── FastPacket_PacketImplementationAttribute.cs │ ├── net6.0 │ │ └── Enclave.FastPacket.Generator │ │ │ └── Enclave.FastPacket.Generator.PacketParserGenerator │ │ │ ├── Enclave.FastPacket.ArpPacketReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ArpPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.EthernetPacketReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.EthernetPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4AddressMaskReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4AddressMaskSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4DestinationUnreachableReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4DestinationUnreachableSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4RedirectReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4RedirectSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4SourceQuenchReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4SourceQuenchSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4TimeExceededReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4TimeExceededSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4TimestampReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.Icmpv4TimestampSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4AddressMaskSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4DestinationUnreachableSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4RedirectSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4SourceQuenchSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4TimeExceededSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4TimestampSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmpv4PacketReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Icmpv4PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Ipv4PacketReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Ipv4PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Ipv6PacketReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.Ipv6PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.MyPacketImplementation_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyArpPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyEthernetPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIcmpv4PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIpv4PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIpv6FragmentExtensionSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIpv6HopByHopAndDestinationExtensionSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIpv6PacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyIpv6RoutingExtensionSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyTcpPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.ReadOnlyUdpPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.TcpPacketReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.TcpPacketSpan_Generated.cs │ │ │ ├── Enclave.FastPacket.UdpPacketReadOnlySpan_Generated.cs │ │ │ ├── Enclave.FastPacket.UdpPacketSpan_Generated.cs │ │ │ ├── FastPacket_PacketFieldAttribute.cs │ │ │ └── FastPacket_PacketImplementationAttribute.cs │ └── netstandard2.1 │ │ └── Enclave.FastPacket.Generator │ │ └── Enclave.FastPacket.Generator.PacketParserGenerator │ │ ├── Enclave.FastPacket.ArpPacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.EthernetPacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.Icmpv4AddressMaskSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.Icmpv4DestinationUnreachableSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.Icmpv4RedirectSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.Icmpv4SourceQuenchSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.Icmpv4TimeExceededSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.Icmpv4TimestampSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4AddressMaskSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4DestinationUnreachableSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4RedirectSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4SourceQuenchSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4TimeExceededSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmp.ReadOnlyIcmpv4TimestampSpan_Generated.cs │ │ ├── Enclave.FastPacket.Icmpv4PacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.Ipv4PacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.Ipv6PacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.ReadOnlyArpPacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.ReadOnlyEthernetPacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.ReadOnlyIcmpv4PacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.ReadOnlyIpv4PacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.ReadOnlyIpv6FragmentExtensionSpan_Generated.cs │ │ ├── Enclave.FastPacket.ReadOnlyIpv6HopByHopAndDestinationExtensionSpan_Generated.cs │ │ ├── Enclave.FastPacket.ReadOnlyIpv6PacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.ReadOnlyIpv6RoutingExtensionSpan_Generated.cs │ │ ├── Enclave.FastPacket.ReadOnlyTcpPacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.ReadOnlyUdpPacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.TcpPacketSpan_Generated.cs │ │ ├── Enclave.FastPacket.UdpPacketSpan_Generated.cs │ │ ├── FastPacket_PacketFieldAttribute.cs │ │ └── FastPacket_PacketImplementationAttribute.cs │ ├── GlobalSuppressions.cs │ ├── HardwareAddress.cs │ ├── Icmp │ ├── Icmpv4AddressMask.cs │ ├── Icmpv4DestinationUnreachable.cs │ ├── Icmpv4Redirect.cs │ ├── Icmpv4SourceQuench.cs │ ├── Icmpv4TimeExceeded.cs │ └── Icmpv4Timestamp.cs │ ├── Icmpv4.cs │ ├── IpPacket.cs │ ├── IpProtocol.cs │ ├── Ipv4.cs │ ├── Ipv6.cs │ ├── Ipv6Extensions │ ├── Ipv6ExtensionHelper.cs │ ├── Ipv6FragmentExtension.cs │ ├── Ipv6HopByHopAndDestinationExtension.cs │ └── Ipv6RoutingExtension.cs │ ├── Tcp.cs │ ├── Udp.cs │ ├── ValueIpAddress.cs │ └── VisitResult.cs └── tests ├── Enclave.FastPacket.Generator.Tests ├── Enclave.FastPacket.Generator.Tests.csproj ├── GeneratorTest.cs ├── Helpers │ ├── FluentVerify.cs │ └── ModuleInitializer.cs ├── SizeFieldTests.cs ├── SizeFunctionTests.cs ├── Snapshots │ ├── .gitignore │ ├── GeneratorTest.CanGenerateDefaultType.verified.cs │ ├── GeneratorTest.CanGenerateTypeCustomToString.verified.cs │ ├── GeneratorTest.CanGenerateTypeWithCustomTypeSizeConstant.verified.cs │ ├── GeneratorTest.CanGenerateTypeWithEnumCustomBackingTypeValue.verified.cs │ ├── GeneratorTest.CanGenerateTypeWithEnumValue.verified.cs │ ├── GeneratorTest.CanGenerateTypeWithExternalSize.verified.cs │ ├── GeneratorTest.CanGenerateTypeWithLongerNamespace.verified.cs │ ├── GeneratorTest.CanGenerateTypeWithPayload.verified.cs │ ├── GeneratorTest.CanGenerateTypeWithPositionFunction.verified.cs │ ├── GeneratorTest.CanGenerateTypeWithPrivateMember.verified.cs │ ├── SizeFieldTests.CanUsePrecedingFieldForSize.verified.cs │ ├── SizeFieldTests.SizeFieldCanBeAfterDataFieldIfExplicitPositionUsed.verified.cs │ ├── SizeFieldTests.SizeFieldCannotBeAfterDataField.00.verified.txt │ ├── SizeFieldTests.SizeFieldCannotBeAfterDataField.01.verified.cs │ ├── SizeFieldTests.SizeFieldMustBeNumeric.00.verified.txt │ ├── SizeFieldTests.SizeFieldMustBeNumeric.01.verified.cs │ ├── SizeFieldTests.SizeFieldMustExist.00.verified.txt │ ├── SizeFieldTests.SizeFieldMustExist.01.verified.cs │ ├── SizeFunctionTests.CanHaveOptionalPosition.verified.cs │ ├── TypeTests.CanGenerateBoolBitFields.verified.cs │ ├── UnionTests.CanGenerateUnion.verified.cs │ ├── UnionTests.CanGenerateUnionWithBitmask.verified.cs │ └── UnionTests.CanGenerateUnionWithLargeBitmask.verified.cs ├── TypeTests.cs └── UnionTests.cs └── Enclave.FastPacket.Tests ├── Enclave.FastPacket.Tests.csproj ├── EthernetTests.cs ├── Fixtures └── mongodb-ssh-tcp-packet.bin ├── Helpers ├── FixtureHelpers.cs └── FluentAssertionExtensions.cs ├── Ipv4Tests.cs ├── Ipv6Tests.cs ├── RealPacketTests.cs └── ValueIpAddressTests.cs /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: FastPacket Build 2 | 3 | on: 4 | push: 5 | branches: [ develop, main ] 6 | pull_request: 7 | branches: [ develop ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | 16 | - uses: actions/checkout@v2 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Install GitVersion 21 | uses: gittools/actions/gitversion/setup@v0.9.7 22 | with: 23 | versionSpec: '5.x' 24 | 25 | - name: Determine Version 26 | id: gitversion 27 | uses: gittools/actions/gitversion/execute@v0.9.7 28 | 29 | - name: Setup .NET 6 (SDK) 30 | uses: actions/setup-dotnet@v1 31 | with: 32 | dotnet-version: 6.0.x 33 | 34 | - name: Unit Tests 35 | run: dotnet test 36 | 37 | - name: Build 38 | working-directory: src/Enclave.FastPacket 39 | run: dotnet build -c Release /p:Version=${{ steps.gitversion.outputs.SemVer }} 40 | 41 | - name: Clean Generator before proper build 42 | working-directory: src/Enclave.FastPacket.Generator 43 | run: dotnet clean 44 | 45 | - name: Build Generator without Local Reference Workaround 46 | working-directory: src/Enclave.FastPacket.Generator 47 | run: dotnet build -c Release /p:Version=${{ steps.gitversion.outputs.SemVer }} /p:RemoveLocalReferenceWorkaround=true 48 | 49 | - uses: actions/upload-artifact@v3 50 | with: 51 | name: generator-package 52 | path: src/Enclave.FastPacket.Generator/bin/Release/Enclave.FastPacket.Generator.${{ steps.gitversion.outputs.SemVer }}.nupkg 53 | 54 | - uses: actions/upload-artifact@v3 55 | with: 56 | name: fastpacket-package 57 | path: src/Enclave.FastPacket/bin/Release/Enclave.FastPacket.${{ steps.gitversion.outputs.SemVer }}.nupkg 58 | 59 | - name: Push Generator 60 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 61 | working-directory: src/Enclave.FastPacket.Generator/bin/Release 62 | run: | 63 | dotnet nuget push *.nupkg -k ${{ secrets.NUGET_KEY }} -s https://api.nuget.org/v3/index.json 64 | 65 | - name: Push FastPacket 66 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 67 | working-directory: src/Enclave.FastPacket/bin/Release 68 | run: | 69 | dotnet nuget push *.nupkg -k ${{ secrets.NUGET_KEY }} -s https://api.nuget.org/v3/index.json 70 | 71 | - name: Create Release 72 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 73 | uses: actions/create-release@v1 74 | env: 75 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 76 | with: 77 | tag_name: v${{ steps.gitversion.outputs.SemVer }} 78 | release_name: Release v${{ steps.gitversion.outputs.SemVer }} 79 | body: Latest Enclave.FastPacket Release -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | lib/ 11 | *.tmp 12 | *.bak 13 | *.swp 14 | *~.nib 15 | local.properties 16 | .classpath 17 | .settings/ 18 | .loadpath 19 | 20 | # External tool builders 21 | .externalToolBuilders/ 22 | 23 | # Locally stored "Eclipse launch configurations" 24 | *.launch 25 | 26 | # CDT-specific 27 | .cproject 28 | 29 | # PDT-specific 30 | .buildpath 31 | 32 | 33 | ################# 34 | ## Visual Studio 35 | ################# 36 | 37 | ## Ignore Visual Studio temporary files, build results, and 38 | ## files generated by popular Visual Studio add-ons. 39 | 40 | # User-specific files 41 | *.suo 42 | *.user 43 | *.sln.docstates 44 | 45 | # Build results 46 | /[Dd]ebug/ 47 | /[Rr]elease/ 48 | /[Rr]elease_x86/ 49 | /[Rr]elease_x64/ 50 | *_i.c 51 | *_p.c 52 | *.ilk 53 | *.meta 54 | *.obj 55 | *.pch 56 | *.pdb 57 | *.pgc 58 | *.pgd 59 | *.rsp 60 | *.sbr 61 | *.tlb 62 | *.tli 63 | *.tlh 64 | *.tmp 65 | *.vspscc 66 | .builds 67 | *.dotCover 68 | .vs/ 69 | 70 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 71 | packages/ 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | 80 | # Visual Studio profiler 81 | *.psess 82 | *.vsp 83 | 84 | # ReSharper is a .NET coding add-in 85 | _ReSharper* 86 | 87 | # Installshield output folder 88 | [Ee]xpress 89 | 90 | # DocProject is a documentation generator add-in 91 | DocProject/buildhelp/ 92 | DocProject/Help/*.HxT 93 | DocProject/Help/*.HxC 94 | DocProject/Help/*.hhc 95 | DocProject/Help/*.hhk 96 | DocProject/Help/*.hhp 97 | DocProject/Help/Html2 98 | DocProject/Help/html 99 | 100 | # Click-Once directory 101 | publish 102 | 103 | # Others 104 | [Bb]in 105 | [Oo]bj 106 | sql 107 | TestResults 108 | *.Cache 109 | ClientBin 110 | stylecop.* 111 | ~$* 112 | *.dbmdl 113 | Generated_Code #added for RIA/Silverlight projects 114 | 115 | # Backup & report files from converting an old project file to a newer 116 | # Visual Studio version. Backup files are not needed, because we have git ;-) 117 | _UpgradeReport_Files/ 118 | Backup*/ 119 | UpgradeLog*.XML 120 | 121 | 122 | 123 | ############ 124 | ## Windows 125 | ############ 126 | 127 | # Windows image file caches 128 | Thumbs.db 129 | 130 | # Folder config file 131 | Desktop.ini 132 | 133 | # Mac 134 | 135 | .DS_Store 136 | 137 | # Enclave 138 | -------------------------------------------------------------------------------- /GitVersion.yml: -------------------------------------------------------------------------------- 1 | assembly-versioning-scheme: None 2 | mode: ContinuousDelivery 3 | next-version: 1.0.0 4 | branches: 5 | main: 6 | mode: ContinuousDelivery 7 | develop: 8 | increment: Patch 9 | ignore: 10 | sha: [] 11 | merge-message-formats: {} 12 | -------------------------------------------------------------------------------- /bench/Enclave.FastPacket.Benchmarks/Benchmarks.cs: -------------------------------------------------------------------------------- 1 | using Enclave.FastPacket.Benchmarks.Packets; 2 | using System; 3 | 4 | namespace Enclave.FastPacket.Benchmarks; 5 | 6 | public static class Benchmarks 7 | { 8 | public static Type[] All => new[] 9 | { 10 | typeof(PacketInspectionBenchmark), 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /bench/Enclave.FastPacket.Benchmarks/Enclave.FastPacket.Benchmarks.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net6.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /bench/Enclave.FastPacket.Benchmarks/Examples/mongodb-ssh-tcp-packet.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enclave-networks/Enclave.FastPacket/7e39fff916b07e0cb55374d18c870987053769fb/bench/Enclave.FastPacket.Benchmarks/Examples/mongodb-ssh-tcp-packet.bin -------------------------------------------------------------------------------- /bench/Enclave.FastPacket.Benchmarks/Program.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Running; 2 | using System; 3 | using System.Threading.Tasks; 4 | 5 | namespace Enclave.FastPacket.Benchmarks; 6 | 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | //var bench = new WindowsTapIocpSingleRxPathBenchmark(); 12 | //bench.Setup(); 13 | 14 | //Console.WriteLine("Starting"); 15 | 16 | //await bench.TapWrite1GB(); 17 | //bench.Cleanup(); 18 | new BenchmarkSwitcher(Benchmarks.All).Run(args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | latest 7 | enable 8 | AllEnabledByDefault 9 | 10 | 11 | 12 | 13 | all 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | 16 | 17 | All 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/AnalyzerReleases.Shipped.md: -------------------------------------------------------------------------------- 1 | ; Shipped analyzer releases 2 | ; https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md 3 | 4 | ## Release 1.0 5 | 6 | ### New Rules 7 | 8 | Rule ID | Category | Severity | Notes 9 | --------|----------|----------|-------------------- 10 | FASTPACKET001 | FastPacket | Error | Diagnostics 11 | FASTPACKET002 | FastPacket | Error | Diagnostics 12 | FASTPACKET003 | FastPacket | Error | Diagnostics 13 | FASTPACKET004 | FastPacket | Error | Diagnostics 14 | FASTPACKET005 | FastPacket | Error | Diagnostics 15 | FASTPACKET006 | FastPacket | Error | Diagnostics 16 | FASTPACKET007 | FastPacket | Error | Diagnostics 17 | FASTPACKET008 | FastPacket | Error | Diagnostics 18 | FASTPACKET009 | FastPacket | Error | Diagnostics 19 | FASTPACKET010 | FastPacket | Error | Diagnostics 20 | FASTPACKET011 | FastPacket | Error | Diagnostics 21 | FASTPACKET012 | FastPacket | Error | Diagnostics 22 | FASTPACKET013 | FastPacket | Error | Diagnostics 23 | FASTPACKET014 | FastPacket | Error | Diagnostics 24 | FASTPACKET015 | FastPacket | Error | Diagnostics 25 | FASTPACKET016 | FastPacket | Error | Diagnostics 26 | FASTPACKET017 | FastPacket | Warning | Diagnostics 27 | FASTPACKET255 | FastPacket | Error | Diagnostics -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/AnalyzerReleases.Unshipped.md: -------------------------------------------------------------------------------- 1 | ; Unshipped analyzer release 2 | ; https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md 3 | 4 | ### New Rules 5 | 6 | Rule ID | Category | Severity | Notes 7 | --------|----------|----------|------- 8 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 1.0.0 6 | 10.0 7 | 8 | true 9 | 10 | false 11 | true 12 | true 13 | true 14 | true 15 | enable 16 | 17 | $(TargetsForTfmSpecificContentInPackage);_AddGeneratorsToOutput 18 | 19 | 20 | 21 | true 22 | Enclave Networks 23 | Generate fast packet decoders from a packet description. 24 | Enclave Networks 2022 25 | MPL-2.0 26 | https://github.com/enclave-networks/Enclave.FastPacket 27 | git 28 | https://github.com/enclave-networks/Enclave.FastPacket 29 | GitHub 30 | generator 31 | README.md 32 | 33 | 34 | 35 | REMOVE_LOCAL_REF_WORKAROUND 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/EnumRenderer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Enclave.FastPacket.Generator; 4 | 5 | internal static class EnumRenderer 6 | { 7 | public static string RenderEnumToSource() 8 | where TEnum : struct 9 | { 10 | var typeInfo = typeof(TEnum); 11 | 12 | if (!typeInfo.IsEnum) 13 | { 14 | throw new ArgumentException("Can only generate source for enum types."); 15 | } 16 | 17 | return @$" 18 | // 19 | namespace Enclave.FastPacket.Generator 20 | {{ 21 | internal enum {typeInfo.Name} 22 | {{ 23 | {string.Join(",\n ", Enum.GetNames(typeInfo))} 24 | }} 25 | }}"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/FileTemplates/PacketImplementationAttribute.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | 5 | namespace Enclave.FastPacket.Generator 6 | { 7 | [AttributeUsage(AttributeTargets.Struct)] 8 | internal sealed class PacketImplementationAttribute : Attribute 9 | { 10 | public PacketImplementationAttribute(Type type) 11 | { 12 | } 13 | 14 | public bool IsReadOnly { get; set; } 15 | 16 | public bool CacheAll { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/FileTemplates/ReadOnlyRefStruct.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace {{Namespace}} 7 | { 8 | readonly ref partial struct {{TypeName}} 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = {{ MinSizeExpression }}; 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public {{TypeName}}(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | {{ for prop in Props }} 31 | {{ for comment in (getPropComments prop) }} 32 | /// {{ comment }}{{ end }} 33 | {{ getPropAccessibility prop }} {{ getTypeReferenceName prop }} {{ getPropName prop }} 34 | { 35 | get => {{ getPropGetExpr prop "_span" }}; 36 | } 37 | {{ end }}{{ if AddToStringMethod }} 38 | /// 39 | /// Get a string representation of this packet. 40 | /// 41 | public override string ToString() 42 | { 43 | return {{ getToStringFormat }}; 44 | } 45 | {{ end }} 46 | /// 47 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 48 | /// 49 | public int GetTotalSize() 50 | { 51 | return {{ getTotalSizeExpression "_span" }}; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/FileTemplates/WriteableRefStruct.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace {{Namespace}} 7 | { 8 | readonly ref partial struct {{TypeName}} 9 | { 10 | private readonly Span _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = {{ MinSizeExpression }}; 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public {{TypeName}}(Span packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public Span GetRawData() => _span; 30 | {{ for prop in Props }} 31 | {{ for comment in (getPropComments prop) }} 32 | /// {{ comment }}{{ end }} 33 | {{ getPropAccessibility prop }} {{ getTypeReferenceName prop }} {{ getPropName prop }} 34 | { 35 | get => {{ getPropGetExpr prop "_span" }};{{ if (canSet prop) }} 36 | set => {{ getPropSetExpr prop "_span" "value" }}; {{ end }} 37 | } 38 | {{ end }}{{ if AddToStringMethod }} 39 | /// 40 | /// Get a string representation of this packet. 41 | /// 42 | public override string ToString() 43 | { 44 | return {{ getToStringFormat }}; 45 | } 46 | {{ end }} 47 | /// 48 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 49 | /// 50 | public int GetTotalSize() 51 | { 52 | return {{ getTotalSizeExpression "_span" }}; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/GenerationOptions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator; 4 | 5 | internal readonly struct GenerationOptions 6 | { 7 | public static bool TryGetFromAttribute(AttributeData attrib, out GenerationOptions opt) 8 | { 9 | INamedTypeSymbol? definitionTypeSymbol = null; 10 | var isReadOnly = false; 11 | var cacheAll = false; 12 | 13 | // Only constructor argument right now is the backing type. 14 | if (attrib.ConstructorArguments.Length > 0) 15 | { 16 | if (attrib.ConstructorArguments[0].Value is INamedTypeSymbol typeSymbol) 17 | { 18 | definitionTypeSymbol = typeSymbol; 19 | } 20 | } 21 | 22 | foreach (var additionalArg in attrib.NamedArguments) 23 | { 24 | if (additionalArg.Key == nameof(PacketImplementationAttribute.IsReadOnly)) 25 | { 26 | if (additionalArg.Value.Value is bool attrIsReadOnly) 27 | { 28 | isReadOnly = attrIsReadOnly; 29 | } 30 | } 31 | else if (additionalArg.Key == nameof(PacketImplementationAttribute.CacheAll)) 32 | { 33 | if (additionalArg.Value.Value is bool attrCacheAll) 34 | { 35 | cacheAll = attrCacheAll; 36 | } 37 | } 38 | } 39 | 40 | if (definitionTypeSymbol is not null) 41 | { 42 | opt = new GenerationOptions(definitionTypeSymbol, isReadOnly); 43 | return true; 44 | } 45 | 46 | opt = default; 47 | return false; 48 | } 49 | 50 | private GenerationOptions(INamedTypeSymbol definitionType, bool isReadOnly) 51 | { 52 | DefinitionType = definitionType; 53 | IsReadOnly = isReadOnly; 54 | } 55 | 56 | public INamedTypeSymbol DefinitionType { get; } 57 | 58 | public bool IsReadOnly { get; } 59 | } 60 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/IPacketField.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Enclave.FastPacket.Generator.PositionProviders; 3 | using Enclave.FastPacket.Generator.SizeProviders; 4 | using Enclave.FastPacket.Generator.ValueProviders; 5 | using Microsoft.CodeAnalysis; 6 | 7 | namespace Enclave.FastPacket.Generator; 8 | 9 | internal interface IPacketField 10 | { 11 | public string Name { get; } 12 | 13 | Location DiagnosticsLocation { get; } 14 | 15 | PacketFieldOptions Options { get; } 16 | 17 | public Accessibility Accessibility { get; } 18 | 19 | public IPositionProvider PositionProvider { get; } 20 | 21 | public ISizeProvider SizeProvider { get; } 22 | 23 | public IValueProvider ValueProvider { get; } 24 | 25 | IEnumerable DocComments { get; } 26 | } 27 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/IParserBuilder.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator; 4 | 5 | internal interface IParserBuilder 6 | { 7 | string Generate(PacketParserDefinition packetDef, GenerationOptions definitionTypeOptions, INamedTypeSymbol structSymbol, PacketFieldFactory packetFieldFactory); 8 | } 9 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/PacketField.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Enclave.FastPacket.Generator.PositionProviders; 3 | using Enclave.FastPacket.Generator.SizeProviders; 4 | using Enclave.FastPacket.Generator.ValueProviders; 5 | using Microsoft.CodeAnalysis; 6 | 7 | namespace Enclave.FastPacket.Generator; 8 | 9 | internal class PacketField : IPacketField 10 | { 11 | public PacketField( 12 | string name, 13 | Accessibility accessibility, 14 | Location diagnosticsLocation, 15 | PacketFieldOptions options, 16 | IPositionProvider positionProvider, 17 | ISizeProvider sizeProvider, 18 | IValueProvider valueProvider, 19 | IEnumerable docComments) 20 | { 21 | Name = name; 22 | Accessibility = accessibility; 23 | DiagnosticsLocation = diagnosticsLocation; 24 | Options = options; 25 | PositionProvider = positionProvider; 26 | SizeProvider = sizeProvider; 27 | ValueProvider = valueProvider; 28 | DocComments = docComments; 29 | } 30 | 31 | public string Name { get; } 32 | 33 | public Accessibility Accessibility { get; } 34 | 35 | public Location DiagnosticsLocation { get; } 36 | 37 | public PacketFieldOptions Options { get; } 38 | 39 | public IPositionProvider PositionProvider { get; } 40 | 41 | public ISizeProvider SizeProvider { get; } 42 | 43 | public IValueProvider ValueProvider { get; } 44 | 45 | public IEnumerable DocComments { get; } 46 | } 47 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/PacketFieldOptions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator; 4 | 5 | public class PacketFieldOptions 6 | { 7 | public int? Size { get; set; } 8 | 9 | public int? Position { get; set; } 10 | 11 | public string? PositionFunction { get; set; } 12 | 13 | public INamedTypeSymbol? EnumBackingType { get; set; } 14 | 15 | public ulong? Bitmask { get; set; } 16 | 17 | public string? SizeFunction { get; set; } 18 | 19 | public string? SizeField { get; set; } 20 | } 21 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/PacketParserDefinition.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Enclave.FastPacket.Generator; 4 | 5 | internal class PacketParserDefinition 6 | { 7 | public PacketParserDefinition(IList propertySet, string minSizeExpression) 8 | { 9 | PropertySet = propertySet; 10 | MinSizeExpression = minSizeExpression; 11 | } 12 | 13 | public IList PropertySet { get; } 14 | 15 | public string MinSizeExpression { get; } 16 | } 17 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/PositionProviders/AutomaticPositionProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Enclave.FastPacket.Generator.PositionProviders; 2 | 3 | internal class AutomaticPositionProvider : IPositionProvider 4 | { 5 | public AutomaticPositionProvider(IPacketField? previousProperty) 6 | { 7 | PreviousProperty = previousProperty; 8 | } 9 | 10 | public IPacketField? PreviousProperty { get; } 11 | 12 | public virtual string GetPositionExpression(string spanName) 13 | { 14 | if (PreviousProperty is null) 15 | { 16 | // No previous property, we're starting from 0. 17 | return "0"; 18 | } 19 | 20 | var previousPropPosition = PreviousProperty.PositionProvider.GetPositionExpression(spanName); 21 | 22 | // Automatic position calculation is just based on the position expression of the previous property, 23 | // plus the size (to take us to the start of this field). 24 | return $"{previousPropPosition} + {PreviousProperty.SizeProvider.GetSizeExpression(spanName, previousPropPosition)}"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/PositionProviders/ExplicitPositionProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | 3 | namespace Enclave.FastPacket.Generator.PositionProviders; 4 | 5 | internal class ExplicitPositionProvider : IConstantPositionProvider 6 | { 7 | private readonly int _explicitPosition; 8 | 9 | public ExplicitPositionProvider(int explicitPosition) 10 | { 11 | _explicitPosition = explicitPosition; 12 | } 13 | 14 | public string GetConstantPositionExpression() 15 | { 16 | return _explicitPosition.ToString(CultureInfo.InvariantCulture); 17 | } 18 | 19 | public string GetPositionExpression(string spanName) 20 | { 21 | return GetConstantPositionExpression(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/PositionProviders/FunctionPositionAutomaticDefaultProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator.PositionProviders; 4 | 5 | internal class FunctionPositionAutomaticDefaultProvider : AutomaticPositionProvider 6 | { 7 | public FunctionPositionAutomaticDefaultProvider(IMethodSymbol positionMethod, IPacketField? previousProperty) 8 | : base(previousProperty) 9 | { 10 | Method = positionMethod; 11 | FullReferenceName = positionMethod.GetFullyQualifiedReference(); 12 | } 13 | 14 | public IMethodSymbol Method { get; } 15 | 16 | public string FullReferenceName { get; } 17 | 18 | public override string GetPositionExpression(string spanName) 19 | { 20 | // Automatic position calculation is just based on the position expression of the previous property, 21 | // plus the size (to take us to the start of this field). 22 | return $"{FullReferenceName}({spanName}, {base.GetPositionExpression(spanName)})"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/PositionProviders/FunctionPositionExplicitDefaultProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator.PositionProviders; 4 | 5 | internal class FunctionPositionExplicitDefaultProvider : IPositionProvider 6 | { 7 | private readonly int _explicitPosition; 8 | 9 | public FunctionPositionExplicitDefaultProvider(IMethodSymbol positionMethod, int explicitPosition) 10 | { 11 | Method = positionMethod; 12 | _explicitPosition = explicitPosition; 13 | FullReferenceName = positionMethod.GetFullyQualifiedReference(); 14 | } 15 | 16 | public IMethodSymbol Method { get; } 17 | 18 | public string FullReferenceName { get; } 19 | 20 | public string GetPositionExpression(string spanName) 21 | { 22 | // Automatic position calculation is just based on the position expression of the previous property, 23 | // plus the size (to take us to the start of this field). 24 | return $"{FullReferenceName}({spanName}, {_explicitPosition})"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/PositionProviders/IPositionProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Enclave.FastPacket.Generator.PositionProviders; 2 | 3 | /// 4 | /// Indicates that the provider uses a constant position. 5 | /// 6 | internal interface IConstantPositionProvider : IPositionProvider 7 | { 8 | string GetConstantPositionExpression(); 9 | } 10 | 11 | internal interface IPositionProvider 12 | { 13 | /// 14 | /// Get an expression that results in the position of a field in a packet. 15 | /// 16 | string GetPositionExpression(string spanName); 17 | } 18 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/Range.Shim.cs: -------------------------------------------------------------------------------- 1 | namespace Enclave.FastPacket.Generator; 2 | 3 | /// 4 | /// Used when System.Range is not available in our ns2.0 generator. 5 | /// 6 | internal struct Range 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SizeProviders/CustomTypeConstantSizeProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.CodeAnalysis; 3 | 4 | namespace Enclave.FastPacket.Generator.SizeProviders; 5 | 6 | internal class CustomTypeConstantSizeProvider : IConstantSizeProvider 7 | { 8 | public CustomTypeConstantSizeProvider(INamedTypeSymbol typeSymbol) 9 | { 10 | TypeReferenceName = typeSymbol.GetFullyQualifiedReference(); 11 | } 12 | 13 | public string TypeReferenceName { get; } 14 | 15 | public string GetConstantSizeExpression() 16 | => $"{TypeReferenceName}.Size"; 17 | 18 | public string GetSizeExpression(string spanName, string positionExpression) 19 | => GetConstantSizeExpression(); 20 | } 21 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SizeProviders/CustomTypeMethodSizeProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.CodeAnalysis; 3 | 4 | namespace Enclave.FastPacket.Generator.SizeProviders; 5 | 6 | internal class CustomTypeMethodSizeProvider : ISizeProvider 7 | { 8 | public CustomTypeMethodSizeProvider(INamedTypeSymbol typeSymbol) 9 | { 10 | TypeReferenceName = typeSymbol.GetFullyQualifiedReference(); 11 | } 12 | 13 | public string TypeReferenceName { get; } 14 | 15 | public string GetSizeExpression(string spanName, string positionExpression) 16 | => $"{TypeReferenceName}.GetSize({spanName}.Slice({positionExpression}))"; 17 | } 18 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SizeProviders/ExplicitSizeProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using Microsoft.CodeAnalysis; 3 | 4 | namespace Enclave.FastPacket.Generator.SizeProviders; 5 | 6 | internal class ExplicitSizeProvider : IConstantSizeProvider 7 | { 8 | private readonly int _explicitSize; 9 | 10 | public ExplicitSizeProvider(int explicitSize) 11 | { 12 | _explicitSize = explicitSize; 13 | } 14 | 15 | public string GetConstantSizeExpression() 16 | => _explicitSize.ToString(CultureInfo.InvariantCulture); 17 | 18 | public string GetSizeExpression(string spanName, string positionExpression) 19 | => GetConstantSizeExpression(); 20 | } 21 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SizeProviders/FieldSizeProvider.cs: -------------------------------------------------------------------------------- 1 | using Enclave.FastPacket.Generator.PositionProviders; 2 | using Enclave.FastPacket.Generator.ValueProviders; 3 | using Microsoft.CodeAnalysis; 4 | 5 | namespace Enclave.FastPacket.Generator.SizeProviders; 6 | 7 | internal class FieldSizeProvider : ILateBoundFieldReferencingProvider, ISizeProvider 8 | { 9 | private bool _bound; 10 | 11 | public FieldSizeProvider(string propertyName) 12 | { 13 | PropertyName = propertyName; 14 | } 15 | 16 | public void BindField( 17 | GeneratorExecutionContext execContext, 18 | IPacketField thisProperty, 19 | int thisPropertyPosition, 20 | IPacketField referencedPacketProperty, 21 | int referencedPropertyPosition) 22 | { 23 | _bound = true; 24 | 25 | if (referencedPacketProperty.ValueProvider is not INumericValueProvider) 26 | { 27 | _bound = false; 28 | execContext.ReportDiagnostic(Diagnostic.Create(Diagnostics.SizeFieldNotValidType, thisProperty.DiagnosticsLocation, referencedPacketProperty.Name)); 29 | } 30 | 31 | if (referencedPropertyPosition > thisPropertyPosition && referencedPacketProperty.PositionProvider is not IConstantPositionProvider) 32 | { 33 | _bound = false; 34 | // The referenced field appears after this property in the property order, and it does not have a fixed position. 35 | // That would likely cause a reference loop. 36 | execContext.ReportDiagnostic(Diagnostic.Create(Diagnostics.SizeFieldAppearsAfter, thisProperty.DiagnosticsLocation, referencedPacketProperty.Name)); 37 | } 38 | } 39 | 40 | public void FieldNotFound(GeneratorExecutionContext execContext, IPacketField thisProperty) 41 | { 42 | execContext.ReportDiagnostic(Diagnostic.Create(Diagnostics.SizeFieldNotFound, thisProperty.DiagnosticsLocation, PropertyName)); 43 | } 44 | 45 | public string PropertyName { get; } 46 | 47 | public string GetSizeExpression(string spanName, string positionExpression) 48 | { 49 | // If we bound OK, then use the property name, else use '0' to prevent compile errors in the generated code. 50 | return _bound ? PropertyName : "0"; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SizeProviders/FunctionSizeProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator.SizeProviders; 4 | 5 | internal class FunctionSizeProvider : ISizeProvider 6 | { 7 | public FunctionSizeProvider(IMethodSymbol positionMethod) 8 | { 9 | Method = positionMethod; 10 | FullReferenceName = positionMethod.GetFullyQualifiedReference(); 11 | } 12 | 13 | public IMethodSymbol Method { get; } 14 | 15 | public string FullReferenceName { get; } 16 | 17 | public string GetSizeExpression(string spanName, string positionExpression) 18 | { 19 | if (Method.Parameters.Length > 1) 20 | { 21 | return $"{FullReferenceName}({spanName}, {positionExpression})"; 22 | } 23 | else 24 | { 25 | return $"{FullReferenceName}({spanName})"; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SizeProviders/IConstantSizeProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Enclave.FastPacket.Generator.SizeProviders; 2 | 3 | /// 4 | /// Indicates that a provider gives a constant size known at compile time, with no evaluation required. 5 | /// 6 | internal interface IConstantSizeProvider : ISizeProvider 7 | { 8 | string GetConstantSizeExpression(); 9 | } 10 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SizeProviders/IPropertyReferencingSizeProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator.SizeProviders; 4 | 5 | /// 6 | /// Indicates a provider that directly references another field on the packet, 7 | /// and performs late bound validation against it. 8 | /// 9 | internal interface ILateBoundFieldReferencingProvider 10 | { 11 | string PropertyName { get; } 12 | 13 | void FieldNotFound(GeneratorExecutionContext execContext, IPacketField thisField); 14 | 15 | void BindField( 16 | GeneratorExecutionContext execContext, 17 | IPacketField thisField, 18 | int thisFieldPosition, 19 | IPacketField referencedFieldProperty, 20 | int referencedFieldPosition); 21 | } 22 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SizeProviders/ISizeProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Enclave.FastPacket.Generator.SizeProviders; 2 | 3 | internal interface ISizeProvider 4 | { 5 | /// 6 | /// Get an expression that results in the size of a field in a packet. 7 | /// 8 | string GetSizeExpression(string spanName, string positionExpression); 9 | } 10 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SizeProviders/SizeOfSizeProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator.SizeProviders; 4 | 5 | internal class SizeOfSizeProvider : IConstantSizeProvider 6 | { 7 | public SizeOfSizeProvider(INamedTypeSymbol typeSymbol) 8 | { 9 | TypeReferenceName = typeSymbol.GetFullyQualifiedReference(); 10 | TypeSymbol = typeSymbol; 11 | } 12 | 13 | public INamedTypeSymbol TypeSymbol { get; } 14 | 15 | public string TypeReferenceName { get; } 16 | 17 | public string GetConstantSizeExpression() => $"sizeof({TypeReferenceName})"; 18 | 19 | public string GetSizeExpression(string spanName, string positionExpression) => GetConstantSizeExpression(); 20 | } 21 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SizeProviders/SpanRemainingLengthSizeProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Enclave.FastPacket.Generator.SizeProviders; 2 | 3 | internal class SpanRemainingLengthSizeProvider : ISizeProvider 4 | { 5 | public static ISizeProvider Instance { get; } = new SpanRemainingLengthSizeProvider(); 6 | 7 | public string GetSizeExpression(string spanName, string positionExpression) 8 | => $"{spanName}.Slice({positionExpression}).Length"; 9 | } 10 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/SymbolNameExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Immutable; 4 | using System.Globalization; 5 | using System.Linq; 6 | using Microsoft.CodeAnalysis; 7 | using Microsoft.CodeAnalysis.CSharp.Syntax; 8 | 9 | namespace Enclave.FastPacket.Generator; 10 | 11 | internal static class SymbolNameExtensions 12 | { 13 | public static string GetFullyQualifiedReference(this ISymbol symbol) 14 | { 15 | var st = ImmutableStack.Empty; 16 | 17 | if (symbol is INamedTypeSymbol) 18 | { 19 | return symbol.ToDisplayString(); 20 | } 21 | 22 | st = st.Push(symbol.Name); 23 | 24 | ISymbol? currentSymbol = symbol.ContainingType ?? (ISymbol?)symbol.ContainingNamespace; 25 | 26 | if (currentSymbol is ISymbol) 27 | { 28 | st = st.Push(currentSymbol.Name); 29 | 30 | while (currentSymbol?.ContainingNamespace is object && currentSymbol.ContainingNamespace.Name.Length > 0) 31 | { 32 | currentSymbol = currentSymbol.ContainingNamespace; 33 | 34 | st = st.Push(currentSymbol.Name); 35 | } 36 | } 37 | 38 | return string.Join(".", st); 39 | } 40 | 41 | public static string GetFullyQualifiedGeneratedFileName(this INamedTypeSymbol symbol) 42 | { 43 | var st = ImmutableStack.Empty; 44 | 45 | st = st.Push(symbol.Name + "_Generated.cs"); 46 | 47 | ISymbol? currentSymbol = symbol.ContainingType ?? (ISymbol?)symbol.ContainingNamespace; 48 | 49 | if (currentSymbol is ISymbol) 50 | { 51 | st = st.Push(currentSymbol.Name); 52 | 53 | while (currentSymbol?.ContainingNamespace is object && currentSymbol.ContainingNamespace.Name.Length > 0) 54 | { 55 | currentSymbol = currentSymbol.ContainingNamespace; 56 | 57 | st = st.Push(currentSymbol.Name); 58 | } 59 | } 60 | 61 | return string.Join(".", st); 62 | } 63 | 64 | public static string GetFullNamespace(this ISymbol symbol) 65 | { 66 | var st = ImmutableStack.Empty; 67 | 68 | ISymbol? currentSymbol = symbol.ContainingType ?? (ISymbol?)symbol.ContainingNamespace; 69 | 70 | if (currentSymbol is ISymbol) 71 | { 72 | st = st.Push(currentSymbol.Name); 73 | 74 | while (currentSymbol?.ContainingNamespace is object && currentSymbol.ContainingNamespace.Name.Length > 0) 75 | { 76 | currentSymbol = currentSymbol.ContainingNamespace; 77 | 78 | st = st.Push(currentSymbol.Name); 79 | } 80 | } 81 | 82 | return string.Join(".", st); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/BinaryPrimitivesValueProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator.ValueProviders; 4 | 5 | internal class BinaryPrimitivesValueProvider : INumericValueProvider 6 | { 7 | public BinaryPrimitivesValueProvider(INamedTypeSymbol typeSymbol) 8 | { 9 | TypeReferenceName = typeSymbol.ToDisplayString(); 10 | TypeSymbol = typeSymbol; 11 | } 12 | 13 | public bool CanSet => true; 14 | 15 | public INamedTypeSymbol TypeSymbol { get; set; } 16 | 17 | public string TypeReferenceName { get; } 18 | 19 | public string GetPropGetExpression(string spanName, string positionExpression) 20 | { 21 | return $"BinaryPrimitives.Read{TypeSymbol.Name}BigEndian({spanName}.Slice({positionExpression}))"; 22 | } 23 | 24 | public string GetPropSetExpression(string spanName, string positionExpression, string valueExpression) 25 | { 26 | return $"BinaryPrimitives.Write{TypeSymbol.Name}BigEndian({spanName}.Slice({positionExpression}), {valueExpression})"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/BoolFromNumberValueProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator.ValueProviders; 4 | 5 | internal class BoolFromNumberValueProvider : IValueProvider 6 | { 7 | private readonly IValueProvider _wrappedValueProvider; 8 | 9 | public BoolFromNumberValueProvider(INamedTypeSymbol boolType, IValueProvider wrappedValueProvider) 10 | { 11 | TypeSymbol = boolType; 12 | TypeReferenceName = boolType.GetFullyQualifiedReference(); 13 | _wrappedValueProvider = wrappedValueProvider; 14 | } 15 | 16 | public INamedTypeSymbol TypeSymbol { get; set; } 17 | 18 | public bool CanSet => _wrappedValueProvider.CanSet; 19 | 20 | public string TypeReferenceName { get; set; } 21 | 22 | public string GetPropGetExpression(string spanName, string positionExpression) 23 | { 24 | return $"({_wrappedValueProvider.GetPropGetExpression(spanName, positionExpression)}) > 0"; 25 | } 26 | 27 | public string GetPropSetExpression(string spanName, string positionExpression, string valueExpression) 28 | { 29 | return _wrappedValueProvider.GetPropSetExpression(spanName, positionExpression, "(value ? 1 : 0)"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/CastingValueProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator.ValueProviders; 4 | 5 | internal class CastingValueProvider : IValueProvider 6 | { 7 | private readonly IValueProvider _wrappedValueProvider; 8 | 9 | public CastingValueProvider(INamedTypeSymbol castingTo, IValueProvider wrappedValueProvider) 10 | { 11 | TypeSymbol = castingTo; 12 | TypeReferenceName = castingTo.GetFullyQualifiedReference(); 13 | _wrappedValueProvider = wrappedValueProvider; 14 | } 15 | 16 | public INamedTypeSymbol TypeSymbol { get; set; } 17 | 18 | public bool CanSet => _wrappedValueProvider.CanSet; 19 | 20 | public string TypeReferenceName { get; set; } 21 | 22 | public string GetPropGetExpression(string spanName, string positionExpression) 23 | { 24 | return $"({TypeReferenceName})({_wrappedValueProvider.GetPropGetExpression(spanName, positionExpression)})"; 25 | } 26 | 27 | public string GetPropSetExpression(string spanName, string positionExpression, string valueExpression) 28 | { 29 | return _wrappedValueProvider.GetPropSetExpression(spanName, positionExpression, $"({_wrappedValueProvider.TypeReferenceName})({valueExpression})"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/CustomProviderResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using Enclave.FastPacket.Generator.SizeProviders; 3 | using Microsoft.CodeAnalysis; 4 | 5 | namespace Enclave.FastPacket.Generator.ValueProviders; 6 | 7 | internal class CustomProviderResult 8 | { 9 | public CustomProviderResult(IValueProvider? valueProvider, ISizeProvider? sizeProvider, ImmutableList diagnostics) 10 | { 11 | Value = valueProvider; 12 | Size = sizeProvider; 13 | Diagnostics = diagnostics; 14 | } 15 | 16 | public IValueProvider? Value { get; } 17 | 18 | public ISizeProvider? Size { get; } 19 | 20 | public ImmutableList Diagnostics { get; } 21 | } 22 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/CustomTypeValueProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Enclave.FastPacket.Generator.SizeProviders; 3 | using Microsoft.CodeAnalysis; 4 | 5 | namespace Enclave.FastPacket.Generator.ValueProviders; 6 | 7 | internal class CustomTypeValueProvider : IValueProvider 8 | { 9 | private readonly ISizeProvider _sizeProvider; 10 | 11 | public CustomTypeValueProvider(INamedTypeSymbol typeSymbol, ISizeProvider sizeProvider) 12 | { 13 | TypeSymbol = typeSymbol; 14 | _sizeProvider = sizeProvider; 15 | TypeReferenceName = typeSymbol.GetFullyQualifiedReference(); 16 | } 17 | 18 | public bool CanSet => true; 19 | 20 | public INamedTypeSymbol TypeSymbol { get; } 21 | 22 | public string TypeReferenceName { get; } 23 | 24 | public string GetPropGetExpression(string spanName, string positionExpression) 25 | { 26 | return $"new {TypeReferenceName}({spanName}.Slice({positionExpression}, {_sizeProvider.GetSizeExpression(spanName, positionExpression)}))"; 27 | } 28 | 29 | public string GetPropSetExpression(string spanName, string positionExpression, string valueExpression) 30 | { 31 | return $"{valueExpression}.CopyTo({spanName}.Slice({positionExpression}, {_sizeProvider.GetSizeExpression(spanName, positionExpression)}))"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/INumericValueProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Enclave.FastPacket.Generator.ValueProviders; 2 | 3 | /// 4 | /// Indicates a value provider exposes a numeric value. 5 | /// 6 | internal interface INumericValueProvider : IValueProvider 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/ISpanValueProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Enclave.FastPacket.Generator.ValueProviders; 2 | 3 | internal interface ISpanValueProvider : IValueProvider 4 | { 5 | } -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/IValueProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator.ValueProviders; 4 | 5 | internal interface IValueProvider 6 | { 7 | INamedTypeSymbol TypeSymbol { get; } 8 | 9 | bool CanSet { get; } 10 | 11 | string TypeReferenceName { get; } 12 | 13 | string GetPropGetExpression(string spanName, string positionExpression); 14 | 15 | string GetPropSetExpression(string spanName, string positionExpression, string valueExpression); 16 | } 17 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/SingleByteValueProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace Enclave.FastPacket.Generator.ValueProviders; 4 | 5 | internal class SingleByteValueProvider : INumericValueProvider 6 | { 7 | public SingleByteValueProvider(INamedTypeSymbol typeSymbol) 8 | { 9 | TypeSymbol = typeSymbol; 10 | } 11 | 12 | public bool CanSet => true; 13 | 14 | public INamedTypeSymbol TypeSymbol { get; set; } 15 | 16 | public string TypeReferenceName => "byte"; 17 | 18 | public string GetPropGetExpression(string spanName, string positionExpression) 19 | { 20 | return $"{spanName}[{positionExpression}]"; 21 | } 22 | 23 | public string GetPropSetExpression(string spanName, string positionExpression, string valueExpression) 24 | { 25 | return $"{spanName}[{positionExpression}] = {valueExpression}"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/SpanKnownSizeValueProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Enclave.FastPacket.Generator.SizeProviders; 3 | using Microsoft.CodeAnalysis; 4 | 5 | namespace Enclave.FastPacket.Generator.ValueProviders; 6 | 7 | internal class SpanKnownSizeValueProvider : ISpanValueProvider 8 | { 9 | private readonly ISizeProvider _sizeProvider; 10 | 11 | public SpanKnownSizeValueProvider(INamedTypeSymbol typeSymbol, ISizeProvider sizeProvider) 12 | { 13 | TypeSymbol = typeSymbol; 14 | _sizeProvider = sizeProvider; 15 | TypeReferenceName = typeSymbol.GetFullyQualifiedReference(); 16 | } 17 | 18 | public bool CanSet => false; 19 | 20 | public INamedTypeSymbol TypeSymbol { get; } 21 | 22 | public string TypeReferenceName { get; } 23 | 24 | public string GetPropGetExpression(string spanName, string positionExpression) 25 | { 26 | return $"{spanName}.Slice({positionExpression}, {_sizeProvider.GetSizeExpression(spanName, positionExpression)})"; 27 | } 28 | 29 | public string GetPropSetExpression(string spanName, string positionExpression, string valueExpression) 30 | { 31 | throw new NotImplementedException("Cannot set on a span"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/ValueProviders/SpanRestOfDataValueProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.CodeAnalysis; 3 | 4 | namespace Enclave.FastPacket.Generator.ValueProviders; 5 | 6 | internal class SpanRestOfDataValueProvider : ISpanValueProvider 7 | { 8 | public SpanRestOfDataValueProvider(INamedTypeSymbol typeSymbol) 9 | { 10 | TypeSymbol = typeSymbol; 11 | TypeReferenceName = typeSymbol.GetFullyQualifiedReference(); 12 | } 13 | 14 | public bool CanSet => false; 15 | 16 | public INamedTypeSymbol TypeSymbol { get; } 17 | 18 | public string TypeReferenceName { get; } 19 | 20 | public string GetPropGetExpression(string spanName, string positionExpression) 21 | { 22 | return $"{spanName}.Slice({positionExpression})"; 23 | } 24 | 25 | public string GetPropSetExpression(string spanName, string positionExpression, string valueExpression) 26 | { 27 | throw new NotImplementedException("Cannot set on a span"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket.Generator/VirtualUnionField.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Enclave.FastPacket.Generator.PositionProviders; 4 | using Enclave.FastPacket.Generator.SizeProviders; 5 | using Enclave.FastPacket.Generator.ValueProviders; 6 | using Microsoft.CodeAnalysis; 7 | 8 | namespace Enclave.FastPacket.Generator; 9 | 10 | internal class VirtualUnionField : IPacketField 11 | { 12 | public VirtualUnionField( 13 | string name, 14 | IPositionProvider positionProvider, 15 | ISizeProvider sizeProvider, 16 | IEnumerable docComments) 17 | { 18 | Name = name; 19 | PositionProvider = positionProvider; 20 | SizeProvider = sizeProvider; 21 | DocComments = docComments; 22 | } 23 | 24 | public string Name { get; } 25 | 26 | public IPositionProvider PositionProvider { get; } 27 | 28 | public ISizeProvider SizeProvider { get; } 29 | 30 | public IValueProvider ValueProvider => throw new InvalidOperationException("Unions cannot have their own value providers"); 31 | 32 | public IEnumerable DocComments { get; } 33 | 34 | public Accessibility Accessibility => throw new InvalidOperationException("Cannot directly access the accessibility of a union"); 35 | 36 | public IPropertySymbol DeclaredProperty => throw new NotImplementedException(); 37 | 38 | public Location DiagnosticsLocation => throw new NotImplementedException(); 39 | 40 | public PacketFieldOptions Options => throw new NotImplementedException(); 41 | } 42 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Arp.cs: -------------------------------------------------------------------------------- 1 | using Enclave.FastPacket.Generator; 2 | 3 | namespace Enclave.FastPacket; 4 | 5 | internal struct ArpPacketDefinition 6 | { 7 | /// 8 | /// Specifes the network link protocol type. 9 | /// 10 | public ushort HardwareType { get; set; } 11 | 12 | /// 13 | /// Specifies the IP protocol for which the ARP request is intended. For IPv4 packets, this will be 0x800. 14 | /// 15 | public ushort ProtocolType { get; set; } 16 | 17 | /// 18 | /// The length of the hardware address segment (will be 6). 19 | /// 20 | public byte HardwareAddressLength { get; set; } 21 | 22 | /// 23 | /// The length of the hardware address segment (will be 4 for IPv4 requests). 24 | /// 25 | public byte ProtocolAddressLength { get; set; } 26 | 27 | /// 28 | /// Specifies the arp operation (request or reply). 29 | /// 30 | public ArpOperation Operation { get; set; } 31 | 32 | /// 33 | /// The hardware address of the sender. 34 | /// 35 | public HardwareAddress SenderHardwareAddress { get; set; } 36 | 37 | /// 38 | /// The protocol address of the sender. 39 | /// 40 | [PacketField(Size = 4)] 41 | public ValueIpAddress SenderProtocolAddress { get; set; } 42 | 43 | /// 44 | /// The hardware address of the target (blank for ARP requests). 45 | /// 46 | public HardwareAddress TargetHardwareAddress { get; set; } 47 | 48 | /// 49 | /// The protocol address of the target. 50 | /// 51 | [PacketField(Size = 4)] 52 | public ValueIpAddress TargetProtocolAddress { get; set; } 53 | } 54 | 55 | /// 56 | /// A read-write decoder for an ARP packet. 57 | /// 58 | [PacketImplementation(typeof(ArpPacketDefinition))] 59 | public readonly ref partial struct ArpPacketSpan 60 | { 61 | } 62 | 63 | /// 64 | /// A read-only decoder for an ARP packet. 65 | /// 66 | [PacketImplementation(typeof(ArpPacketDefinition), IsReadOnly = true)] 67 | public readonly ref partial struct ReadOnlyArpPacketSpan 68 | { 69 | /// 70 | /// Convert to a readonly representation. 71 | /// 72 | public static implicit operator ReadOnlyArpPacketSpan(ArpPacketSpan s) => new ReadOnlyArpPacketSpan(s.GetRawData()); 73 | } 74 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/ArpOperation.cs: -------------------------------------------------------------------------------- 1 | namespace Enclave.FastPacket; 2 | 3 | /// 4 | /// Represents possible ARP operations. 5 | /// 6 | public enum ArpOperation : ushort 7 | { 8 | /// 9 | /// None (not a valid value). 10 | /// 11 | None = 0, 12 | 13 | /// 14 | /// An ARP request. 15 | /// 16 | Request = 1, 17 | 18 | /// 19 | /// An ARP reply. 20 | /// 21 | Reply = 2, 22 | } 23 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Enclave.FastPacket.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1;net6.0 5 | true 6 | Enclave.FastPacket 7 | 1.0.0 8 | 9 | 10 | 11 | true 12 | Enclave Networks 13 | A set of high-performance Ethernet and IP frame decoders. 14 | Enclave Networks 2022 15 | MPL-2.0 16 | https://github.com/enclave-networks/Enclave.FastPacket 17 | git 18 | https://github.com/enclave-networks/Enclave.FastPacket 19 | ethernet, network 20 | README.md 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | true 31 | Generated 32 | $(GeneratedFolder)\$(TargetFramework) 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/FastPacketException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Text; 4 | 5 | namespace Enclave.FastPacket; 6 | 7 | /// 8 | /// A general exception type thrown by the FastPacket library. 9 | /// 10 | public class FastPacketException : Exception 11 | { 12 | /// 13 | /// Create a new instance of . 14 | /// 15 | /// A message. 16 | /// The buffer span that caused the problem. 17 | public FastPacketException(string message, ReadOnlySpan span) 18 | : base(ConstructMessage(message, span)) 19 | { 20 | } 21 | 22 | private static string ConstructMessage(string message, ReadOnlySpan span) 23 | { 24 | if (span.Length > 0) 25 | { 26 | return $"{message} (empty span)"; 27 | } 28 | 29 | var displaySpan = span.Slice(0, Math.Min(4, span.Length)); 30 | 31 | string firstBytes; 32 | 33 | #if NET5_0_OR_GREATER 34 | firstBytes = Convert.ToHexString(displaySpan); 35 | #else 36 | var strBuilder = new StringBuilder(); 37 | 38 | foreach (var b in displaySpan) 39 | { 40 | strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}", b); 41 | } 42 | 43 | firstBytes = strBuilder.ToString(); 44 | #endif 45 | 46 | return $"{message} ({span.Length} bytes remaining - {firstBytes}...)"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.Icmpv4SourceQuenchSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct Icmpv4SourceQuenchSpan 9 | { 10 | private readonly Span _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public Icmpv4SourceQuenchSpan(Span packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public Span GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// Indicates the type of the ICMP packet. 34 | /// 35 | public Enclave.FastPacket.Icmpv4Types Type 36 | { 37 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 38 | set => _span[0] = (byte)(value); 39 | } 40 | 41 | 42 | /// 43 | /// The code. 44 | /// 45 | public byte Code 46 | { 47 | get => _span[0 + sizeof(byte)]; 48 | set => _span[0 + sizeof(byte)] = value; 49 | } 50 | 51 | 52 | /// 53 | /// The checksum. 54 | /// 55 | public ushort Checksum 56 | { 57 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 58 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte)), value); 59 | } 60 | 61 | 62 | private uint Unused 63 | { 64 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort))); 65 | set => BinaryPrimitives.WriteUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort)), value); 66 | } 67 | 68 | 69 | /// 70 | /// The failed IP header and datagram. 71 | /// 72 | public System.Span IpHeaderAndDatagram 73 | { 74 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)); 75 | } 76 | 77 | public override string ToString() 78 | { 79 | return $"Type: {Type}; Code: {Code}; Checksum: {Checksum}; ; IpHeaderAndDatagram: {IpHeaderAndDatagram.Length} bytes"; 80 | } 81 | 82 | public int GetTotalSize() 83 | { 84 | return 0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint) + _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)).Length; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.ReadOnlyIcmpv4RedirectSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct ReadOnlyIcmpv4RedirectSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4; 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIcmpv4RedirectSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// Indicates the type of the ICMP packet. 34 | /// 35 | public Enclave.FastPacket.Icmpv4Types Type 36 | { 37 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 38 | } 39 | 40 | 41 | /// 42 | /// The redirect code. 43 | /// 44 | public Enclave.FastPacket.Icmp.Icmpv4RedirectCodes Code 45 | { 46 | get => (Enclave.FastPacket.Icmp.Icmpv4RedirectCodes)(_span[0 + sizeof(byte)]); 47 | } 48 | 49 | 50 | /// 51 | /// The checksum. 52 | /// 53 | public ushort Checksum 54 | { 55 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 56 | } 57 | 58 | 59 | /// 60 | /// The IPv4 address to redirect to. 61 | /// 62 | public Enclave.FastPacket.ValueIpAddress IpAddress 63 | { 64 | get => new Enclave.FastPacket.ValueIpAddress(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort), 4)); 65 | } 66 | 67 | 68 | /// 69 | /// The original IP Header and datagram. 70 | /// 71 | public System.ReadOnlySpan IpHeaderAndDatagram 72 | { 73 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4); 74 | } 75 | 76 | public override string ToString() 77 | { 78 | return $"Type: {Type}; Code: {Code}; Checksum: {Checksum}; IpAddress: {IpAddress}; IpHeaderAndDatagram: {IpHeaderAndDatagram.Length} bytes"; 79 | } 80 | 81 | public int GetTotalSize() 82 | { 83 | return 0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4 + _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4).Length; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.ReadOnlyIcmpv4SourceQuenchSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct ReadOnlyIcmpv4SourceQuenchSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIcmpv4SourceQuenchSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// Indicates the type of the ICMP packet. 34 | /// 35 | public Enclave.FastPacket.Icmpv4Types Type 36 | { 37 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 38 | } 39 | 40 | 41 | /// 42 | /// The code. 43 | /// 44 | public byte Code 45 | { 46 | get => _span[0 + sizeof(byte)]; 47 | } 48 | 49 | 50 | /// 51 | /// The checksum. 52 | /// 53 | public ushort Checksum 54 | { 55 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 56 | } 57 | 58 | 59 | private uint Unused 60 | { 61 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort))); 62 | } 63 | 64 | 65 | /// 66 | /// The failed IP header and datagram. 67 | /// 68 | public System.ReadOnlySpan IpHeaderAndDatagram 69 | { 70 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)); 71 | } 72 | 73 | public override string ToString() 74 | { 75 | return $"Type: {Type}; Code: {Code}; Checksum: {Checksum}; ; IpHeaderAndDatagram: {IpHeaderAndDatagram.Length} bytes"; 76 | } 77 | 78 | public int GetTotalSize() 79 | { 80 | return 0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint) + _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)).Length; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.ReadOnlyIcmpv4TimeExceededSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct ReadOnlyIcmpv4TimeExceededSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIcmpv4TimeExceededSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// Indicates the type of the ICMP packet. 34 | /// 35 | public Enclave.FastPacket.Icmpv4Types Type 36 | { 37 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 38 | } 39 | 40 | 41 | /// 42 | /// The time-exceeded code. 43 | /// 44 | public Enclave.FastPacket.Icmp.Icmpv4TimeExceededCodes Code 45 | { 46 | get => (Enclave.FastPacket.Icmp.Icmpv4TimeExceededCodes)(_span[0 + sizeof(byte)]); 47 | } 48 | 49 | 50 | /// 51 | /// The checksum. 52 | /// 53 | public ushort Checksum 54 | { 55 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 56 | } 57 | 58 | 59 | private uint Unused 60 | { 61 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort))); 62 | } 63 | 64 | 65 | /// 66 | /// The failed IP header and datagram. 67 | /// 68 | public System.ReadOnlySpan IpHeaderAndDatagram 69 | { 70 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)); 71 | } 72 | 73 | public override string ToString() 74 | { 75 | return $"Type: {Type}; Code: {Code}; Checksum: {Checksum}; ; IpHeaderAndDatagram: {IpHeaderAndDatagram.Length} bytes"; 76 | } 77 | 78 | public int GetTotalSize() 79 | { 80 | return 0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint) + _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)).Length; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmpv4PacketSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct Icmpv4PacketSpan 9 | { 10 | private readonly Span _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4; 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public Icmpv4PacketSpan(Span packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public Span GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// Indicates the type of the ICMP packet. 34 | /// 35 | public Enclave.FastPacket.Icmpv4Types Type 36 | { 37 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 38 | set => _span[0] = (byte)(value); 39 | } 40 | 41 | 42 | /// 43 | /// Defines the ICMP Code value. 44 | /// 45 | public byte Code 46 | { 47 | get => _span[0 + sizeof(byte)]; 48 | set => _span[0 + sizeof(byte)] = value; 49 | } 50 | 51 | 52 | /// 53 | /// The ICMP packet checksum. 54 | /// 55 | public ushort Checksum 56 | { 57 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 58 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte)), value); 59 | } 60 | 61 | 62 | /// 63 | /// The rest of the header. Use the As* methods to get the typed packet. 64 | /// 65 | public System.Span RestOfHeader 66 | { 67 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort), 4); 68 | } 69 | 70 | 71 | /// 72 | /// The 'Data' portion of the ICMP header. 73 | /// 74 | public System.Span Data 75 | { 76 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4); 77 | } 78 | 79 | public override string ToString() 80 | { 81 | return $"Type: {Type}; Code: {Code}; Checksum: {Checksum}; RestOfHeader: {RestOfHeader.Length} bytes; Data: {Data.Length} bytes"; 82 | } 83 | 84 | public int GetTotalSize() 85 | { 86 | return 0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4 + _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4).Length; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.ReadOnlyEthernetPacketSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct ReadOnlyEthernetPacketSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = Enclave.FastPacket.HardwareAddress.Size + Enclave.FastPacket.HardwareAddress.Size + sizeof(ushort); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyEthernetPacketSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// The destination hardware (MAC) address. 34 | /// 35 | public Enclave.FastPacket.HardwareAddress Destination 36 | { 37 | get => new Enclave.FastPacket.HardwareAddress(_span.Slice(0, Enclave.FastPacket.HardwareAddress.Size)); 38 | } 39 | 40 | 41 | /// 42 | /// The source hardware (MAC) address. 43 | /// 44 | public Enclave.FastPacket.HardwareAddress Source 45 | { 46 | get => new Enclave.FastPacket.HardwareAddress(_span.Slice(0 + Enclave.FastPacket.HardwareAddress.Size, Enclave.FastPacket.HardwareAddress.Size)); 47 | } 48 | 49 | 50 | /// 51 | /// The EtherType field. 52 | /// 53 | public Enclave.FastPacket.EthernetType Type 54 | { 55 | get => (Enclave.FastPacket.EthernetType)(BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + Enclave.FastPacket.HardwareAddress.Size + Enclave.FastPacket.HardwareAddress.Size))); 56 | } 57 | 58 | 59 | /// 60 | /// The Ethernet Payload. 61 | /// 62 | public System.ReadOnlySpan Payload 63 | { 64 | get => _span.Slice(0 + Enclave.FastPacket.HardwareAddress.Size + Enclave.FastPacket.HardwareAddress.Size + sizeof(ushort)); 65 | } 66 | 67 | public override string ToString() 68 | { 69 | return $"Destination: {Destination}; Source: {Source}; Type: {Type}; Payload: {Payload.Length} bytes"; 70 | } 71 | 72 | public int GetTotalSize() 73 | { 74 | return 0 + Enclave.FastPacket.HardwareAddress.Size + Enclave.FastPacket.HardwareAddress.Size + sizeof(ushort) + _span.Slice(0 + Enclave.FastPacket.HardwareAddress.Size + Enclave.FastPacket.HardwareAddress.Size + sizeof(ushort)).Length; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.ReadOnlyIcmpv4PacketSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct ReadOnlyIcmpv4PacketSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4; 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIcmpv4PacketSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// Indicates the type of the ICMP packet. 34 | /// 35 | public Enclave.FastPacket.Icmpv4Types Type 36 | { 37 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 38 | } 39 | 40 | 41 | /// 42 | /// Defines the ICMP Code value. 43 | /// 44 | public byte Code 45 | { 46 | get => _span[0 + sizeof(byte)]; 47 | } 48 | 49 | 50 | /// 51 | /// The ICMP packet checksum. 52 | /// 53 | public ushort Checksum 54 | { 55 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 56 | } 57 | 58 | 59 | /// 60 | /// The rest of the header. Use the As* methods to get the typed packet. 61 | /// 62 | public System.ReadOnlySpan RestOfHeader 63 | { 64 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort), 4); 65 | } 66 | 67 | 68 | /// 69 | /// The 'Data' portion of the ICMP header. 70 | /// 71 | public System.ReadOnlySpan Data 72 | { 73 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4); 74 | } 75 | 76 | public override string ToString() 77 | { 78 | return $"Type: {Type}; Code: {Code}; Checksum: {Checksum}; RestOfHeader: {RestOfHeader.Length} bytes; Data: {Data.Length} bytes"; 79 | } 80 | 81 | public int GetTotalSize() 82 | { 83 | return 0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4 + _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4).Length; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.ReadOnlyIpv6FragmentExtensionSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct ReadOnlyIpv6FragmentExtensionSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + 2 + sizeof(uint); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIpv6FragmentExtensionSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | public Enclave.FastPacket.IpProtocol NextHeader 33 | { 34 | get => (Enclave.FastPacket.IpProtocol)(_span[0]); 35 | } 36 | 37 | 38 | private byte Reserved 39 | { 40 | get => _span[0 + sizeof(byte)]; 41 | } 42 | 43 | 44 | public ushort FragmentOffset 45 | { 46 | get => (ushort)((BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))) & 0xFFF8u) >> 3); 47 | } 48 | 49 | 50 | public bool MoreFragments 51 | { 52 | get => ((byte)(_span[0 + sizeof(byte) + sizeof(byte)] & 0x1u)) > 0; 53 | } 54 | 55 | 56 | public uint Identification 57 | { 58 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + 2)); 59 | } 60 | 61 | public override string ToString() 62 | { 63 | return $"NextHeader: {NextHeader}; ; FragmentOffset: {FragmentOffset}; MoreFragments: {MoreFragments}; Identification: {Identification}"; 64 | } 65 | 66 | public int GetTotalSize() 67 | { 68 | return 0 + sizeof(byte) + sizeof(byte) + 2 + sizeof(uint); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.ReadOnlyIpv6HopByHopAndDestinationExtensionSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct ReadOnlyIpv6HopByHopAndDestinationExtensionSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIpv6HopByHopAndDestinationExtensionSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | public Enclave.FastPacket.IpProtocol NextHeader 33 | { 34 | get => (Enclave.FastPacket.IpProtocol)(_span[0]); 35 | } 36 | 37 | 38 | public byte HeaderExtensionLength 39 | { 40 | get => _span[0 + sizeof(byte)]; 41 | } 42 | 43 | 44 | public System.ReadOnlySpan OptionsAndPadding 45 | { 46 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte), Enclave.FastPacket.Ipv6HopByHopAndDestinationExtension.GetOptionsSize(_span)); 47 | } 48 | 49 | public override string ToString() 50 | { 51 | return $"NextHeader: {NextHeader}; HeaderExtensionLength: {HeaderExtensionLength}; OptionsAndPadding: {OptionsAndPadding.Length} bytes"; 52 | } 53 | 54 | public int GetTotalSize() 55 | { 56 | return 0 + sizeof(byte) + sizeof(byte) + Enclave.FastPacket.Ipv6HopByHopAndDestinationExtension.GetOptionsSize(_span); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.ReadOnlyIpv6RoutingExtensionSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct ReadOnlyIpv6RoutingExtensionSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(byte) + sizeof(byte); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIpv6RoutingExtensionSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | public Enclave.FastPacket.IpProtocol NextHeader 33 | { 34 | get => (Enclave.FastPacket.IpProtocol)(_span[0]); 35 | } 36 | 37 | 38 | public byte HeaderExtensionLength 39 | { 40 | get => _span[0 + sizeof(byte)]; 41 | } 42 | 43 | 44 | public byte RoutingType 45 | { 46 | get => _span[0 + sizeof(byte) + sizeof(byte)]; 47 | } 48 | 49 | 50 | public byte SegmentsLeft 51 | { 52 | get => _span[0 + sizeof(byte) + sizeof(byte) + sizeof(byte)]; 53 | } 54 | 55 | 56 | public System.ReadOnlySpan TypeData 57 | { 58 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(byte) + sizeof(byte), Enclave.FastPacket.Ipv6RoutingExtension.GetTypeDataSize(_span)); 59 | } 60 | 61 | public override string ToString() 62 | { 63 | return $"NextHeader: {NextHeader}; HeaderExtensionLength: {HeaderExtensionLength}; RoutingType: {RoutingType}; SegmentsLeft: {SegmentsLeft}; TypeData: {TypeData.Length} bytes"; 64 | } 65 | 66 | public int GetTotalSize() 67 | { 68 | return 0 + sizeof(byte) + sizeof(byte) + sizeof(byte) + sizeof(byte) + Enclave.FastPacket.Ipv6RoutingExtension.GetTypeDataSize(_span); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.ReadOnlyUdpPacketSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct ReadOnlyUdpPacketSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyUdpPacketSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// The source port. 34 | /// 35 | public ushort SourcePort 36 | { 37 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0)); 38 | } 39 | 40 | 41 | /// 42 | /// The destination port. 43 | /// 44 | public ushort DestinationPort 45 | { 46 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort))); 47 | } 48 | 49 | 50 | /// 51 | /// The length in bytes of the header and data. 52 | /// 53 | public ushort Length 54 | { 55 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + sizeof(ushort))); 56 | } 57 | 58 | 59 | /// 60 | /// The checksum. 61 | /// 62 | public ushort Checksum 63 | { 64 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + sizeof(ushort) + sizeof(ushort))); 65 | } 66 | 67 | 68 | /// 69 | /// The payload. 70 | /// 71 | public System.ReadOnlySpan Payload 72 | { 73 | get => _span.Slice(0 + sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort)); 74 | } 75 | 76 | public override string ToString() 77 | { 78 | return $"SourcePort: {SourcePort}; DestinationPort: {DestinationPort}; Length: {Length}; Checksum: {Checksum}; Payload: {Payload.Length} bytes"; 79 | } 80 | 81 | public int GetTotalSize() 82 | { 83 | return 0 + sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + _span.Slice(0 + sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort)).Length; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net5.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/FastPacket_PacketImplementationAttribute.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | 5 | namespace Enclave.FastPacket.Generator 6 | { 7 | [AttributeUsage(AttributeTargets.Struct)] 8 | internal sealed class PacketImplementationAttribute : Attribute 9 | { 10 | public PacketImplementationAttribute(Type type) 11 | { 12 | } 13 | 14 | public bool IsReadOnly { get; set; } 15 | 16 | public bool CacheAll { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.EthernetPacketReadOnlySpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct EthernetPacketReadOnlySpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = Enclave.FastPacket.HardwareAddress.Size + Enclave.FastPacket.HardwareAddress.Size + sizeof(ushort); 17 | 18 | public EthernetPacketReadOnlySpan(ReadOnlySpan packetData) 19 | { 20 | _span = packetData; 21 | } 22 | 23 | public ReadOnlySpan GetRawData() => _span; 24 | 25 | 26 | 27 | /// 28 | /// The destination hardware (MAC) address. 29 | /// 30 | public Enclave.FastPacket.HardwareAddress Destination 31 | { 32 | get => new Enclave.FastPacket.HardwareAddress(_span.Slice(0, Enclave.FastPacket.HardwareAddress.Size)); 33 | } 34 | 35 | 36 | /// 37 | /// The source hardware (MAC) address. 38 | /// 39 | public Enclave.FastPacket.HardwareAddress Source 40 | { 41 | get => new Enclave.FastPacket.HardwareAddress(_span.Slice(0 + Enclave.FastPacket.HardwareAddress.Size, Enclave.FastPacket.HardwareAddress.Size)); 42 | } 43 | 44 | 45 | /// 46 | /// The EtherType field. 47 | /// 48 | public Enclave.FastPacket.EthernetType Type 49 | { 50 | get => (Enclave.FastPacket.EthernetType)(BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + Enclave.FastPacket.HardwareAddress.Size + Enclave.FastPacket.HardwareAddress.Size))); 51 | } 52 | 53 | 54 | /// 55 | /// The Ethernet Payload. 56 | /// 57 | public System.ReadOnlySpan Payload 58 | { 59 | get => _span.Slice(0 + Enclave.FastPacket.HardwareAddress.Size + Enclave.FastPacket.HardwareAddress.Size + sizeof(ushort)); 60 | } 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.Icmpv4AddressMaskReadOnlySpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct Icmpv4AddressMaskReadOnlySpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(uint); 17 | 18 | public Icmpv4AddressMaskReadOnlySpan(ReadOnlySpan packetData) 19 | { 20 | _span = packetData; 21 | } 22 | 23 | public ReadOnlySpan GetRawData() => _span; 24 | 25 | 26 | 27 | public Enclave.FastPacket.Icmpv4Types Type 28 | { 29 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 30 | } 31 | 32 | 33 | public byte Code 34 | { 35 | get => _span[0 + sizeof(byte)]; 36 | } 37 | 38 | 39 | public ushort Checksum 40 | { 41 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 42 | } 43 | 44 | 45 | public ushort Identifier 46 | { 47 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort))); 48 | } 49 | 50 | 51 | public ushort SequenceNumber 52 | { 53 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort))); 54 | } 55 | 56 | 57 | public uint AddressMask 58 | { 59 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort))); 60 | } 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.Icmpv4DestinationUnreachableReadOnlySpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct Icmpv4DestinationUnreachableReadOnlySpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort); 17 | 18 | public Icmpv4DestinationUnreachableReadOnlySpan(ReadOnlySpan packetData) 19 | { 20 | _span = packetData; 21 | } 22 | 23 | public ReadOnlySpan GetRawData() => _span; 24 | 25 | 26 | 27 | public Enclave.FastPacket.Icmpv4Types Type 28 | { 29 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 30 | } 31 | 32 | 33 | public Enclave.FastPacket.Icmp.DestinationUnreachableCode Code 34 | { 35 | get => (Enclave.FastPacket.Icmp.DestinationUnreachableCode)(_span[0 + sizeof(byte)]); 36 | } 37 | 38 | 39 | public ushort Checksum 40 | { 41 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 42 | } 43 | 44 | 45 | public ushort Unused 46 | { 47 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort))); 48 | } 49 | 50 | 51 | public ushort NextHopMtu 52 | { 53 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort))); 54 | } 55 | 56 | 57 | public System.ReadOnlySpan IpHeaderAndDatagram 58 | { 59 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort)); 60 | } 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.Icmpv4RedirectReadOnlySpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct Icmpv4RedirectReadOnlySpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4; 17 | 18 | public Icmpv4RedirectReadOnlySpan(ReadOnlySpan packetData) 19 | { 20 | _span = packetData; 21 | } 22 | 23 | public ReadOnlySpan GetRawData() => _span; 24 | 25 | 26 | 27 | public Enclave.FastPacket.Icmpv4Types Type 28 | { 29 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 30 | } 31 | 32 | 33 | public Enclave.FastPacket.Icmp.Icmpv4RedirectCodes Code 34 | { 35 | get => (Enclave.FastPacket.Icmp.Icmpv4RedirectCodes)(_span[0 + sizeof(byte)]); 36 | } 37 | 38 | 39 | public ushort Checksum 40 | { 41 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 42 | } 43 | 44 | 45 | public Enclave.FastPacket.ValueIpAddress IpAddress 46 | { 47 | get => new Enclave.FastPacket.ValueIpAddress(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort), 4)); 48 | } 49 | 50 | 51 | public System.ReadOnlySpan IpHeaderAndDatagram 52 | { 53 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4); 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.Icmpv4SourceQuenchReadOnlySpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct Icmpv4SourceQuenchReadOnlySpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint); 17 | 18 | public Icmpv4SourceQuenchReadOnlySpan(ReadOnlySpan packetData) 19 | { 20 | _span = packetData; 21 | } 22 | 23 | public ReadOnlySpan GetRawData() => _span; 24 | 25 | 26 | 27 | public Enclave.FastPacket.Icmpv4Types Type 28 | { 29 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 30 | } 31 | 32 | 33 | public byte Code 34 | { 35 | get => _span[0 + sizeof(byte)]; 36 | } 37 | 38 | 39 | public ushort Checksum 40 | { 41 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 42 | } 43 | 44 | 45 | public uint Unused 46 | { 47 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort))); 48 | } 49 | 50 | 51 | public System.ReadOnlySpan IpHeaderAndDatagram 52 | { 53 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)); 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.Icmpv4TimeExceededReadOnlySpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct Icmpv4TimeExceededReadOnlySpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint); 17 | 18 | public Icmpv4TimeExceededReadOnlySpan(ReadOnlySpan packetData) 19 | { 20 | _span = packetData; 21 | } 22 | 23 | public ReadOnlySpan GetRawData() => _span; 24 | 25 | 26 | 27 | public Enclave.FastPacket.Icmpv4Types Type 28 | { 29 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 30 | } 31 | 32 | 33 | public Enclave.FastPacket.Icmp.Icmpv4TimeExceededCodes Code 34 | { 35 | get => (Enclave.FastPacket.Icmp.Icmpv4TimeExceededCodes)(_span[0 + sizeof(byte)]); 36 | } 37 | 38 | 39 | public ushort Checksum 40 | { 41 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 42 | } 43 | 44 | 45 | public uint Unused 46 | { 47 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort))); 48 | } 49 | 50 | 51 | public System.ReadOnlySpan IpHeaderAndDatagram 52 | { 53 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)); 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.Icmpv4TimestampReadOnlySpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct Icmpv4TimestampReadOnlySpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(uint) + sizeof(uint) + sizeof(uint); 17 | 18 | public Icmpv4TimestampReadOnlySpan(ReadOnlySpan packetData) 19 | { 20 | _span = packetData; 21 | } 22 | 23 | public ReadOnlySpan GetRawData() => _span; 24 | 25 | 26 | 27 | public Enclave.FastPacket.Icmpv4Types Type 28 | { 29 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 30 | } 31 | 32 | 33 | public byte Code 34 | { 35 | get => _span[0 + sizeof(byte)]; 36 | } 37 | 38 | 39 | public ushort Checksum 40 | { 41 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 42 | } 43 | 44 | 45 | public ushort Identifier 46 | { 47 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort))); 48 | } 49 | 50 | 51 | public ushort SequenceNumber 52 | { 53 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort))); 54 | } 55 | 56 | 57 | public uint OrginateTimeStamp 58 | { 59 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort))); 60 | } 61 | 62 | 63 | public uint ReceiveTimeStamp 64 | { 65 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(uint))); 66 | } 67 | 68 | 69 | public uint TransmitTimeStamp 70 | { 71 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(uint) + sizeof(uint))); 72 | } 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.ReadOnlyIcmpv4SourceQuenchSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct ReadOnlyIcmpv4SourceQuenchSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIcmpv4SourceQuenchSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// Indicates the type of the ICMP packet. 34 | /// 35 | public Enclave.FastPacket.Icmpv4Types Type 36 | { 37 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 38 | } 39 | 40 | 41 | /// 42 | /// The code. 43 | /// 44 | public byte Code 45 | { 46 | get => _span[0 + sizeof(byte)]; 47 | } 48 | 49 | 50 | /// 51 | /// The checksum. 52 | /// 53 | public ushort Checksum 54 | { 55 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 56 | } 57 | 58 | 59 | private uint Unused 60 | { 61 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort))); 62 | } 63 | 64 | 65 | /// 66 | /// The failed IP header and datagram. 67 | /// 68 | public System.ReadOnlySpan IpHeaderAndDatagram 69 | { 70 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)); 71 | } 72 | 73 | /// 74 | /// Get a string representation of this packet. 75 | /// 76 | public override string ToString() 77 | { 78 | return $"Type: {Type}; Code: {Code}; Checksum: {Checksum}; ; IpHeaderAndDatagram: {IpHeaderAndDatagram.Length} bytes"; 79 | } 80 | 81 | /// 82 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 83 | /// 84 | public int GetTotalSize() 85 | { 86 | return 0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint) + _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)).Length; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmpv4PacketReadOnlySpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct Icmpv4PacketReadOnlySpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4; 17 | 18 | public Icmpv4PacketReadOnlySpan(ReadOnlySpan packetData) 19 | { 20 | _span = packetData; 21 | } 22 | 23 | public ReadOnlySpan GetRawData() => _span; 24 | 25 | 26 | 27 | public Enclave.FastPacket.Icmpv4Types Type 28 | { 29 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 30 | } 31 | 32 | 33 | public byte Code 34 | { 35 | get => _span[0 + sizeof(byte)]; 36 | } 37 | 38 | 39 | public ushort Checksum 40 | { 41 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 42 | } 43 | 44 | 45 | public System.ReadOnlySpan RestOfHeader 46 | { 47 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort), 4); 48 | } 49 | 50 | 51 | public System.ReadOnlySpan Data 52 | { 53 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + 4); 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.MyPacketImplementation_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct MyPacketImplementation 9 | { 10 | private readonly Span _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort); 17 | 18 | public MyPacketImplementation(Span packetData) 19 | { 20 | _span = packetData; 21 | } 22 | 23 | public Span GetRawData() => _span; 24 | 25 | 26 | 27 | public byte Field1 28 | { 29 | get => _span[0]; 30 | set => _span[0] = value; 31 | } 32 | 33 | 34 | public byte Field2 35 | { 36 | get => _span[0 + sizeof(byte)]; 37 | set => _span[0 + sizeof(byte)] = value; 38 | } 39 | 40 | 41 | public ushort Field3 42 | { 43 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 44 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte)), value); 45 | } 46 | 47 | 48 | public System.Span RestOfData 49 | { 50 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort)); 51 | } 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.ReadOnlyIpv6FragmentExtensionSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct ReadOnlyIpv6FragmentExtensionSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + 2 + sizeof(uint); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIpv6FragmentExtensionSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// The next header after this extension. 34 | /// 35 | public Enclave.FastPacket.IpProtocol NextHeader 36 | { 37 | get => (Enclave.FastPacket.IpProtocol)(_span[0]); 38 | } 39 | 40 | 41 | private byte Reserved 42 | { 43 | get => _span[0 + sizeof(byte)]; 44 | } 45 | 46 | 47 | /// 48 | /// The offset position of this fragment. 49 | /// 50 | public ushort FragmentOffset 51 | { 52 | get => (ushort)((BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))) & 0xFFF8u) >> 3); 53 | } 54 | 55 | 56 | /// 57 | /// A flag indicating whether any more fragments are available. 58 | /// 59 | public bool MoreFragments 60 | { 61 | get => ((byte)(_span[0 + sizeof(byte) + sizeof(byte)] & 0x1u)) > 0; 62 | } 63 | 64 | 65 | /// 66 | /// The fragment identification field. 67 | /// 68 | public uint Identification 69 | { 70 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + 2)); 71 | } 72 | 73 | /// 74 | /// Get a string representation of this packet. 75 | /// 76 | public override string ToString() 77 | { 78 | return $"NextHeader: {NextHeader}; ; FragmentOffset: {FragmentOffset}; MoreFragments: {MoreFragments}; Identification: {Identification}"; 79 | } 80 | 81 | /// 82 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 83 | /// 84 | public int GetTotalSize() 85 | { 86 | return 0 + sizeof(byte) + sizeof(byte) + 2 + sizeof(uint); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.ReadOnlyIpv6HopByHopAndDestinationExtensionSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct ReadOnlyIpv6HopByHopAndDestinationExtensionSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIpv6HopByHopAndDestinationExtensionSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// The next header after this extension. 34 | /// 35 | public Enclave.FastPacket.IpProtocol NextHeader 36 | { 37 | get => (Enclave.FastPacket.IpProtocol)(_span[0]); 38 | } 39 | 40 | 41 | /// 42 | /// The length of this extension header, excluding the first 8 bytes. 43 | /// 44 | public byte HeaderExtensionLength 45 | { 46 | get => _span[0 + sizeof(byte)]; 47 | } 48 | 49 | 50 | /// 51 | /// The options and padding included in this header. 52 | /// 53 | public System.ReadOnlySpan OptionsAndPadding 54 | { 55 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte), Enclave.FastPacket.Ipv6HopByHopAndDestinationExtension.GetOptionsSize(_span)); 56 | } 57 | 58 | /// 59 | /// Get a string representation of this packet. 60 | /// 61 | public override string ToString() 62 | { 63 | return $"NextHeader: {NextHeader}; HeaderExtensionLength: {HeaderExtensionLength}; OptionsAndPadding: {OptionsAndPadding.Length} bytes"; 64 | } 65 | 66 | /// 67 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 68 | /// 69 | public int GetTotalSize() 70 | { 71 | return 0 + sizeof(byte) + sizeof(byte) + Enclave.FastPacket.Ipv6HopByHopAndDestinationExtension.GetOptionsSize(_span); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.UdpPacketReadOnlySpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct UdpPacketReadOnlySpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort); 17 | 18 | public UdpPacketReadOnlySpan(ReadOnlySpan packetData) 19 | { 20 | _span = packetData; 21 | } 22 | 23 | public ReadOnlySpan GetRawData() => _span; 24 | 25 | 26 | 27 | public ushort SourcePort 28 | { 29 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0)); 30 | } 31 | 32 | 33 | public ushort DestinationPort 34 | { 35 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort))); 36 | } 37 | 38 | 39 | public ushort Length 40 | { 41 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + sizeof(ushort))); 42 | } 43 | 44 | 45 | public ushort Checksum 46 | { 47 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + sizeof(ushort) + sizeof(ushort))); 48 | } 49 | 50 | 51 | public System.ReadOnlySpan Payload 52 | { 53 | get => _span.Slice(0 + sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(ushort)); 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/net6.0/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/FastPacket_PacketImplementationAttribute.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | 5 | namespace Enclave.FastPacket.Generator 6 | { 7 | [AttributeUsage(AttributeTargets.Struct)] 8 | internal sealed class PacketImplementationAttribute : Attribute 9 | { 10 | public PacketImplementationAttribute(Type type) 11 | { 12 | } 13 | 14 | public bool IsReadOnly { get; set; } 15 | 16 | public bool CacheAll { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/netstandard2.1/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.Icmp.ReadOnlyIcmpv4SourceQuenchSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket.Icmp 7 | { 8 | readonly ref partial struct ReadOnlyIcmpv4SourceQuenchSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIcmpv4SourceQuenchSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// Indicates the type of the ICMP packet. 34 | /// 35 | public Enclave.FastPacket.Icmpv4Types Type 36 | { 37 | get => (Enclave.FastPacket.Icmpv4Types)(_span[0]); 38 | } 39 | 40 | 41 | /// 42 | /// The code. 43 | /// 44 | public byte Code 45 | { 46 | get => _span[0 + sizeof(byte)]; 47 | } 48 | 49 | 50 | /// 51 | /// The checksum. 52 | /// 53 | public ushort Checksum 54 | { 55 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))); 56 | } 57 | 58 | 59 | private uint Unused 60 | { 61 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort))); 62 | } 63 | 64 | 65 | /// 66 | /// The failed IP header and datagram. 67 | /// 68 | public System.ReadOnlySpan IpHeaderAndDatagram 69 | { 70 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)); 71 | } 72 | 73 | /// 74 | /// Get a string representation of this packet. 75 | /// 76 | public override string ToString() 77 | { 78 | return $"Type: {Type}; Code: {Code}; Checksum: {Checksum}; ; IpHeaderAndDatagram: {IpHeaderAndDatagram.Length} bytes"; 79 | } 80 | 81 | /// 82 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 83 | /// 84 | public int GetTotalSize() 85 | { 86 | return 0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint) + _span.Slice(0 + sizeof(byte) + sizeof(byte) + sizeof(ushort) + sizeof(uint)).Length; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/netstandard2.1/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.ReadOnlyIpv6FragmentExtensionSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct ReadOnlyIpv6FragmentExtensionSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte) + 2 + sizeof(uint); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIpv6FragmentExtensionSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// The next header after this extension. 34 | /// 35 | public Enclave.FastPacket.IpProtocol NextHeader 36 | { 37 | get => (Enclave.FastPacket.IpProtocol)(_span[0]); 38 | } 39 | 40 | 41 | private byte Reserved 42 | { 43 | get => _span[0 + sizeof(byte)]; 44 | } 45 | 46 | 47 | /// 48 | /// The offset position of this fragment. 49 | /// 50 | public ushort FragmentOffset 51 | { 52 | get => (ushort)((BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte))) & 0xFFF8u) >> 3); 53 | } 54 | 55 | 56 | /// 57 | /// A flag indicating whether any more fragments are available. 58 | /// 59 | public bool MoreFragments 60 | { 61 | get => ((byte)(_span[0 + sizeof(byte) + sizeof(byte)] & 0x1u)) > 0; 62 | } 63 | 64 | 65 | /// 66 | /// The fragment identification field. 67 | /// 68 | public uint Identification 69 | { 70 | get => BinaryPrimitives.ReadUInt32BigEndian(_span.Slice(0 + sizeof(byte) + sizeof(byte) + 2)); 71 | } 72 | 73 | /// 74 | /// Get a string representation of this packet. 75 | /// 76 | public override string ToString() 77 | { 78 | return $"NextHeader: {NextHeader}; ; FragmentOffset: {FragmentOffset}; MoreFragments: {MoreFragments}; Identification: {Identification}"; 79 | } 80 | 81 | /// 82 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 83 | /// 84 | public int GetTotalSize() 85 | { 86 | return 0 + sizeof(byte) + sizeof(byte) + 2 + sizeof(uint); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/netstandard2.1/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/Enclave.FastPacket.ReadOnlyIpv6HopByHopAndDestinationExtensionSpan_Generated.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | using System.Buffers.Binary; 5 | 6 | namespace Enclave.FastPacket 7 | { 8 | readonly ref partial struct ReadOnlyIpv6HopByHopAndDestinationExtensionSpan 9 | { 10 | private readonly ReadOnlySpan _span; 11 | 12 | /// 13 | /// Defines the minimum possible size of this packet, given all 14 | /// known fixed sizes. 15 | /// 16 | public const int MinimumSize = sizeof(byte) + sizeof(byte); 17 | 18 | /// 19 | /// Create a new instance of . 20 | /// 21 | public ReadOnlyIpv6HopByHopAndDestinationExtensionSpan(ReadOnlySpan packetData) 22 | { 23 | _span = packetData; 24 | } 25 | 26 | /// 27 | /// Gets the raw underlying buffer for this packet. 28 | /// 29 | public ReadOnlySpan GetRawData() => _span; 30 | 31 | 32 | /// 33 | /// The next header after this extension. 34 | /// 35 | public Enclave.FastPacket.IpProtocol NextHeader 36 | { 37 | get => (Enclave.FastPacket.IpProtocol)(_span[0]); 38 | } 39 | 40 | 41 | /// 42 | /// The length of this extension header, excluding the first 8 bytes. 43 | /// 44 | public byte HeaderExtensionLength 45 | { 46 | get => _span[0 + sizeof(byte)]; 47 | } 48 | 49 | 50 | /// 51 | /// The options and padding included in this header. 52 | /// 53 | public System.ReadOnlySpan OptionsAndPadding 54 | { 55 | get => _span.Slice(0 + sizeof(byte) + sizeof(byte), Enclave.FastPacket.Ipv6HopByHopAndDestinationExtension.GetOptionsSize(_span)); 56 | } 57 | 58 | /// 59 | /// Get a string representation of this packet. 60 | /// 61 | public override string ToString() 62 | { 63 | return $"NextHeader: {NextHeader}; HeaderExtensionLength: {HeaderExtensionLength}; OptionsAndPadding: {OptionsAndPadding.Length} bytes"; 64 | } 65 | 66 | /// 67 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 68 | /// 69 | public int GetTotalSize() 70 | { 71 | return 0 + sizeof(byte) + sizeof(byte) + Enclave.FastPacket.Ipv6HopByHopAndDestinationExtension.GetOptionsSize(_span); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Generated/netstandard2.1/Enclave.FastPacket.Generator/Enclave.FastPacket.Generator.PacketParserGenerator/FastPacket_PacketImplementationAttribute.cs: -------------------------------------------------------------------------------- 1 | // 2 | 3 | using System; 4 | 5 | namespace Enclave.FastPacket.Generator 6 | { 7 | [AttributeUsage(AttributeTargets.Struct)] 8 | internal sealed class PacketImplementationAttribute : Attribute 9 | { 10 | public PacketImplementationAttribute(Type type) 11 | { 12 | } 13 | 14 | public bool IsReadOnly { get; set; } 15 | 16 | public bool CacheAll { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations", Justification = "We want to use FastPacketException to indicate something is wrong when accessing properties.")] 9 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Icmp/Icmpv4AddressMask.cs: -------------------------------------------------------------------------------- 1 | using Enclave.FastPacket.Generator; 2 | 3 | namespace Enclave.FastPacket.Icmp; 4 | 5 | internal struct Icmpv4AddressMaskDefinition 6 | { 7 | /// 8 | /// Indicates the type of the ICMP packet. 9 | /// 10 | public Icmpv4Types Type { get; set; } 11 | 12 | /// 13 | /// The ICMP Code. 14 | /// 15 | public byte Code { get; set; } 16 | 17 | /// 18 | /// The checksum. 19 | /// 20 | public ushort Checksum { get; set; } 21 | 22 | /// 23 | /// The identifier. 24 | /// 25 | public ushort Identifier { get; set; } 26 | 27 | /// 28 | /// The sequence number. 29 | /// 30 | public ushort SequenceNumber { get; set; } 31 | 32 | /// 33 | /// The address mask. 34 | /// 35 | public uint AddressMask { get; set; } 36 | } 37 | 38 | /// 39 | /// Provides a read-write decoder for an ICMP Address Mask packet. 40 | /// 41 | [PacketImplementation(typeof(Icmpv4AddressMaskDefinition))] 42 | public readonly ref partial struct Icmpv4AddressMaskSpan 43 | { 44 | } 45 | 46 | /// 47 | /// Provides a read-only decoder for an ICMP Address Mask packet. 48 | /// 49 | [PacketImplementation(typeof(Icmpv4AddressMaskDefinition), IsReadOnly = true)] 50 | public readonly ref partial struct ReadOnlyIcmpv4AddressMaskSpan 51 | { 52 | /// 53 | /// Convert to a readonly representation. 54 | /// 55 | public static implicit operator ReadOnlyIcmpv4AddressMaskSpan(Icmpv4AddressMaskSpan s) 56 | => new ReadOnlyIcmpv4AddressMaskSpan(s.GetRawData()); 57 | } -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Icmp/Icmpv4DestinationUnreachable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Enclave.FastPacket.Generator; 3 | 4 | namespace Enclave.FastPacket.Icmp; 5 | 6 | /// 7 | /// Defines the possible destination unreachable codes. 8 | /// 9 | public enum DestinationUnreachableCode : byte 10 | { 11 | #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member 12 | NetworkUnreachable = 0, 13 | HostUnreachable = 1, 14 | ProtocolUnreachable = 2, 15 | PortUnreachable = 3, 16 | DatagramTooBig = 4, 17 | SourceRouteFailed = 5, 18 | DestinationNetworkUnknown = 6, 19 | DestinationHostUnknown = 7, 20 | SourceHostIsolated = 8, 21 | DestinationNetworkAdminProhibited = 9, 22 | DestinationHostAdminProhibited = 10, 23 | NetworkUnreachableTypeOfService = 11, 24 | HostUnreachableTypeOfService = 12, 25 | CommunicationAdminProhibited = 13, 26 | HostPrecedenceViolation = 14, 27 | PrecedenceCutoff = 15, 28 | #pragma warning restore CS1591 29 | } 30 | 31 | internal ref struct Icmpv4DestinationUnreachableDefinition 32 | { 33 | /// 34 | /// Indicates the type of the ICMP packet. 35 | /// 36 | public Icmpv4Types Type { get; set; } 37 | 38 | /// 39 | /// The destination-unreachable code. 40 | /// 41 | public DestinationUnreachableCode Code { get; set; } 42 | 43 | /// 44 | /// The checksum. 45 | /// 46 | public ushort Checksum { get; set; } 47 | 48 | private ushort Unused { get; set; } 49 | 50 | /// 51 | /// The MTU of the next hop. 52 | /// 53 | public ushort NextHopMtu { get; set; } 54 | 55 | /// 56 | /// The failed IP header and datagram. 57 | /// 58 | public ReadOnlySpan IpHeaderAndDatagram { get; set; } 59 | } 60 | 61 | /// 62 | /// Provides a read-write decoder for an ICMP Destination Unreachable packet. 63 | /// 64 | [PacketImplementation(typeof(Icmpv4DestinationUnreachableDefinition))] 65 | public readonly ref partial struct Icmpv4DestinationUnreachableSpan 66 | { 67 | } 68 | 69 | /// 70 | /// Provides a read-only decoder for an ICMP Destination Unreachable packet. 71 | /// 72 | [PacketImplementation(typeof(Icmpv4DestinationUnreachableDefinition), IsReadOnly = true)] 73 | public readonly ref partial struct ReadOnlyIcmpv4DestinationUnreachableSpan 74 | { 75 | /// 76 | /// Convert to a readonly representation. 77 | /// 78 | public static implicit operator ReadOnlyIcmpv4DestinationUnreachableSpan(Icmpv4DestinationUnreachableSpan s) 79 | => new ReadOnlyIcmpv4DestinationUnreachableSpan(s.GetRawData()); 80 | } -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Icmp/Icmpv4Redirect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Enclave.FastPacket.Generator; 3 | 4 | namespace Enclave.FastPacket.Icmp; 5 | 6 | /// 7 | /// Redirect Codes. 8 | /// 9 | public enum Icmpv4RedirectCodes : byte 10 | { 11 | #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member 12 | RedirectForNetwork = 0, 13 | RedirectForHost = 1, 14 | RedirectForTypeOfServiceAndNetwork = 2, 15 | RedirectForTypeOfServiceAndHost = 3, 16 | #pragma warning restore CS1591 17 | } 18 | 19 | internal ref struct Icmpv4RedirectDefinition 20 | { 21 | /// 22 | /// Indicates the type of the ICMP packet. 23 | /// 24 | public Icmpv4Types Type { get; set; } 25 | 26 | /// 27 | /// The redirect code. 28 | /// 29 | public Icmpv4RedirectCodes Code { get; set; } 30 | 31 | /// 32 | /// The checksum. 33 | /// 34 | public ushort Checksum { get; set; } 35 | 36 | /// 37 | /// The IPv4 address to redirect to. 38 | /// 39 | [PacketField(Size = ValueIpAddress.Ipv4Length)] 40 | public ValueIpAddress IpAddress { get; set; } 41 | 42 | /// 43 | /// The original IP Header and datagram. 44 | /// 45 | public ReadOnlySpan IpHeaderAndDatagram { get; set; } 46 | } 47 | 48 | /// 49 | /// Provides a read-write decoder for an ICMP Redirect packet. 50 | /// 51 | [PacketImplementation(typeof(Icmpv4RedirectDefinition))] 52 | public readonly ref partial struct Icmpv4RedirectSpan 53 | { 54 | } 55 | 56 | /// 57 | /// Provides a read-only decoder for an ICMP Redirect packet. 58 | /// 59 | [PacketImplementation(typeof(Icmpv4RedirectDefinition), IsReadOnly = true)] 60 | public readonly ref partial struct ReadOnlyIcmpv4RedirectSpan 61 | { 62 | /// 63 | /// Convert to a readonly representation. 64 | /// 65 | public static implicit operator ReadOnlyIcmpv4RedirectSpan(Icmpv4RedirectSpan s) 66 | => new ReadOnlyIcmpv4RedirectSpan(s.GetRawData()); 67 | } -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Icmp/Icmpv4SourceQuench.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Enclave.FastPacket.Generator; 3 | 4 | namespace Enclave.FastPacket.Icmp; 5 | 6 | internal ref struct Icmpv4SourceQuenchDefinition 7 | { 8 | /// 9 | /// Indicates the type of the ICMP packet. 10 | /// 11 | public Icmpv4Types Type { get; set; } 12 | 13 | /// 14 | /// The code. 15 | /// 16 | public byte Code { get; set; } 17 | 18 | /// 19 | /// The checksum. 20 | /// 21 | public ushort Checksum { get; set; } 22 | 23 | private uint Unused { get; set; } 24 | 25 | /// 26 | /// The failed IP header and datagram. 27 | /// 28 | public ReadOnlySpan IpHeaderAndDatagram { get; set; } 29 | } 30 | 31 | /// 32 | /// Provides a read-write decoder for an ICMP Source Quench packet. 33 | /// 34 | [PacketImplementation(typeof(Icmpv4SourceQuenchDefinition))] 35 | public readonly ref partial struct Icmpv4SourceQuenchSpan 36 | { 37 | } 38 | 39 | /// 40 | /// Provides a read-only decoder for an ICMP Source Quench packet. 41 | /// 42 | [PacketImplementation(typeof(Icmpv4SourceQuenchDefinition), IsReadOnly = true)] 43 | public readonly ref partial struct ReadOnlyIcmpv4SourceQuenchSpan 44 | { 45 | /// 46 | /// Convert to a readonly representation. 47 | /// 48 | public static implicit operator ReadOnlyIcmpv4SourceQuenchSpan(Icmpv4SourceQuenchSpan s) 49 | => new ReadOnlyIcmpv4SourceQuenchSpan(s.GetRawData()); 50 | } -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Icmp/Icmpv4TimeExceeded.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Enclave.FastPacket.Generator; 3 | 4 | namespace Enclave.FastPacket.Icmp; 5 | 6 | /// 7 | /// Time exceeded codes. 8 | /// 9 | public enum Icmpv4TimeExceededCodes : byte 10 | { 11 | #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member 12 | TimeToLiveExceeded = 0, 13 | FragmentReassemblyTimeExceeded = 1, 14 | #pragma warning restore CS1591 15 | } 16 | 17 | internal ref struct Icmpv4TimeExceededDefinition 18 | { 19 | /// 20 | /// Indicates the type of the ICMP packet. 21 | /// 22 | public Icmpv4Types Type { get; set; } 23 | 24 | /// 25 | /// The time-exceeded code. 26 | /// 27 | public Icmpv4TimeExceededCodes Code { get; set; } 28 | 29 | /// 30 | /// The checksum. 31 | /// 32 | public ushort Checksum { get; set; } 33 | 34 | private uint Unused { get; set; } 35 | 36 | /// 37 | /// The failed IP header and datagram. 38 | /// 39 | public ReadOnlySpan IpHeaderAndDatagram { get; set; } 40 | } 41 | 42 | /// 43 | /// Provides a read-write decoder for an ICMP Time Exceeded packet. 44 | /// 45 | [PacketImplementation(typeof(Icmpv4TimeExceededDefinition))] 46 | public readonly ref partial struct Icmpv4TimeExceededSpan 47 | { 48 | } 49 | 50 | /// 51 | /// Provides a read-only decoder for an ICMP Time Exceeded packet. 52 | /// 53 | [PacketImplementation(typeof(Icmpv4TimeExceededDefinition), IsReadOnly = true)] 54 | public readonly ref partial struct ReadOnlyIcmpv4TimeExceededSpan 55 | { 56 | /// 57 | /// Convert to a readonly representation. 58 | /// 59 | public static implicit operator ReadOnlyIcmpv4TimeExceededSpan(Icmpv4TimeExceededSpan s) 60 | => new ReadOnlyIcmpv4TimeExceededSpan(s.GetRawData()); 61 | } -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Icmp/Icmpv4Timestamp.cs: -------------------------------------------------------------------------------- 1 | using Enclave.FastPacket.Generator; 2 | 3 | namespace Enclave.FastPacket.Icmp; 4 | 5 | internal struct Icmpv4TimestampDefinition 6 | { 7 | /// 8 | /// Indicates the type of the ICMP packet. 9 | /// 10 | public Icmpv4Types Type { get; set; } 11 | 12 | /// 13 | /// The code. 14 | /// 15 | public byte Code { get; set; } 16 | 17 | /// 18 | /// The checksum. 19 | /// 20 | public ushort Checksum { get; set; } 21 | 22 | /// 23 | /// The identifier. 24 | /// 25 | public ushort Identifier { get; set; } 26 | 27 | /// 28 | /// The sequence number. 29 | /// 30 | public ushort SequenceNumber { get; set; } 31 | 32 | /// 33 | /// The originating timestamp. 34 | /// 35 | public uint OrginateTimeStamp { get; set; } 36 | 37 | /// 38 | /// The receive timestamp. 39 | /// 40 | public uint ReceiveTimeStamp { get; set; } 41 | 42 | /// 43 | /// The transmit timestamp. 44 | /// 45 | public uint TransmitTimeStamp { get; set; } 46 | } 47 | 48 | /// 49 | /// Provides a read-write decoder for an ICMP Timestamp packet. 50 | /// 51 | [PacketImplementation(typeof(Icmpv4TimestampDefinition))] 52 | public readonly ref partial struct Icmpv4TimestampSpan 53 | { 54 | } 55 | 56 | /// 57 | /// Provides a read-only decoder for an ICMP Timestamp packet. 58 | /// 59 | [PacketImplementation(typeof(Icmpv4TimestampDefinition), IsReadOnly = true)] 60 | public readonly ref partial struct ReadOnlyIcmpv4TimestampSpan 61 | { 62 | /// 63 | /// Convert to a readonly representation. 64 | /// 65 | public static implicit operator ReadOnlyIcmpv4TimestampSpan(Icmpv4TimestampSpan s) 66 | => new ReadOnlyIcmpv4TimestampSpan(s.GetRawData()); 67 | } -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Ipv6.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Enclave.FastPacket.Generator; 3 | using Enclave.FastPacket.Ipv6Extensions; 4 | 5 | namespace Enclave.FastPacket; 6 | 7 | internal ref struct Ipv6Definition 8 | { 9 | [PacketField(Size = sizeof(uint))] 10 | private struct VersionClassAndFlow 11 | { 12 | /// 13 | /// The IP version (6). 14 | /// 15 | [PacketFieldBits(0, 3)] 16 | public byte Version { get; set; } 17 | 18 | /// 19 | /// The traffic class. 20 | /// 21 | [PacketFieldBits(4, 11)] 22 | public byte TrafficClass { get; set; } 23 | 24 | /// 25 | /// The flow label, identifying a flow of packets between source and destination. 26 | /// 27 | [PacketFieldBits(12, 31)] 28 | public uint FlowLabel { get; set; } 29 | } 30 | 31 | /// 32 | /// The size of the payload in bytes. 33 | /// 34 | public ushort PayloadLength { get; set; } 35 | 36 | /// 37 | /// The 'next header' value. 38 | /// 39 | [PacketField(EnumBackingType = typeof(byte))] 40 | public IpProtocol NextHeader { get; set; } 41 | 42 | /// 43 | /// The hop limit, decremented by every forwarding node. 44 | /// 45 | public byte HopLimit { get; set; } 46 | 47 | /// 48 | /// The source IPv6 address. 49 | /// 50 | [PacketField(Size = ValueIpAddress.Ipv6Length)] 51 | public ValueIpAddress Source { get; set; } 52 | 53 | /// 54 | /// The destination IPv6 address. 55 | /// 56 | [PacketField(Size = ValueIpAddress.Ipv6Length)] 57 | public ValueIpAddress Destination { get; set; } 58 | 59 | /// 60 | /// The payload. 61 | /// 62 | public ReadOnlySpan Payload { get; set; } 63 | } 64 | 65 | /// 66 | /// A readonly decoder for an IPv6 packet. 67 | /// 68 | [PacketImplementation(typeof(Ipv6Definition))] 69 | public readonly ref partial struct Ipv6PacketSpan 70 | { 71 | /// 72 | /// Access a visitor for the IPv6 Extensions. 73 | /// 74 | public Ipv6ExtensionVisitor Extensions => new Ipv6ExtensionVisitor(this); 75 | } 76 | 77 | /// 78 | /// A read-write decoder for an IPv6 packet. 79 | /// 80 | [PacketImplementation(typeof(Ipv6Definition), IsReadOnly = true)] 81 | public readonly ref partial struct ReadOnlyIpv6PacketSpan 82 | { 83 | /// 84 | /// Access a visitor for the IPv6 Extensions. 85 | /// 86 | public Ipv6ExtensionVisitor Extensions => new Ipv6ExtensionVisitor(this); 87 | 88 | /// 89 | /// Convert to a readonly representation. 90 | /// 91 | public static implicit operator ReadOnlyIpv6PacketSpan(Ipv6PacketSpan s) => new ReadOnlyIpv6PacketSpan(s.GetRawData()); 92 | } -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Ipv6Extensions/Ipv6FragmentExtension.cs: -------------------------------------------------------------------------------- 1 | using Enclave.FastPacket.Generator; 2 | 3 | namespace Enclave.FastPacket; 4 | 5 | internal ref struct Ipv6FragmentExtension 6 | { 7 | /// 8 | /// The next header after this extension. 9 | /// 10 | [PacketField(EnumBackingType = typeof(byte))] 11 | public IpProtocol NextHeader { get; set; } 12 | 13 | private byte Reserved { get; set; } 14 | 15 | [PacketField(Size = sizeof(ushort))] 16 | public struct OffsetUnion 17 | { 18 | /// 19 | /// The offset position of this fragment. 20 | /// 21 | [PacketFieldBits(0, 12)] 22 | public ushort FragmentOffset { get; set; } 23 | 24 | /// 25 | /// A flag indicating whether any more fragments are available. 26 | /// 27 | [PacketFieldBits(15)] 28 | public bool MoreFragments { get; set; } 29 | } 30 | 31 | /// 32 | /// The fragment identification field. 33 | /// 34 | public uint Identification { get; set; } 35 | } 36 | 37 | /// 38 | /// A read-write decoder for an IPv6 fragment extension header. 39 | /// 40 | [PacketImplementation(typeof(Ipv6FragmentExtension), IsReadOnly = true)] 41 | public readonly ref partial struct ReadOnlyIpv6FragmentExtensionSpan 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Ipv6Extensions/Ipv6HopByHopAndDestinationExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Enclave.FastPacket.Generator; 3 | 4 | namespace Enclave.FastPacket; 5 | 6 | internal ref struct Ipv6HopByHopAndDestinationExtension 7 | { 8 | /// 9 | /// The next header after this extension. 10 | /// 11 | [PacketField(EnumBackingType = typeof(byte))] 12 | public IpProtocol NextHeader { get; set; } 13 | 14 | /// 15 | /// The length of this extension header, excluding the first 8 bytes. 16 | /// 17 | public byte HeaderExtensionLength { get; set; } 18 | 19 | /// 20 | /// The options and padding included in this header. 21 | /// 22 | [PacketField(SizeFunction = nameof(GetOptionsSize))] 23 | public ReadOnlySpan OptionsAndPadding { get; set; } 24 | 25 | public static int GetOptionsSize(ReadOnlySpan buffer) 26 | { 27 | // HeaderExtensionLength excludes the first 8 bytes. 28 | var totalSize = new ReadOnlyIpv6HopByHopAndDestinationExtensionSpan(buffer).HeaderExtensionLength + 8; 29 | 30 | // Options data is the total size minus the minimum known size. 31 | return totalSize - ReadOnlyIpv6HopByHopAndDestinationExtensionSpan.MinimumSize; 32 | } 33 | } 34 | 35 | /// 36 | /// A read-write decoder for an IPv6 hop-by-hop or destination extension header. 37 | /// 38 | [PacketImplementation(typeof(Ipv6HopByHopAndDestinationExtension), IsReadOnly = true)] 39 | public readonly ref partial struct ReadOnlyIpv6HopByHopAndDestinationExtensionSpan 40 | { 41 | } 42 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Ipv6Extensions/Ipv6RoutingExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Enclave.FastPacket.Generator; 3 | 4 | namespace Enclave.FastPacket; 5 | 6 | internal ref struct Ipv6RoutingExtension 7 | { 8 | /// 9 | /// The next header after this extension. 10 | /// 11 | [PacketField(EnumBackingType = typeof(byte))] 12 | public IpProtocol NextHeader { get; set; } 13 | 14 | /// 15 | /// The length of this extension header, excluding the first 8 bytes. 16 | /// 17 | public byte HeaderExtensionLength { get; set; } 18 | 19 | /// 20 | /// The routing type. 21 | /// 22 | public byte RoutingType { get; set; } 23 | 24 | /// 25 | /// The remaining segments. 26 | /// 27 | public byte SegmentsLeft { get; set; } 28 | 29 | /// 30 | /// Additional type data. 31 | /// 32 | [PacketField(SizeFunction = nameof(GetTypeDataSize))] 33 | public ReadOnlySpan TypeData { get; set; } 34 | 35 | public static int GetTypeDataSize(ReadOnlySpan buffer) 36 | { 37 | // HeaderExtensionLength excludes the first 8 bytes. 38 | var totalSize = new ReadOnlyIpv6RoutingExtensionSpan(buffer).HeaderExtensionLength + 8; 39 | 40 | // Type data size is the total size minus the known preceding segments. 41 | return totalSize - ReadOnlyIpv6RoutingExtensionSpan.MinimumSize; 42 | } 43 | } 44 | 45 | /// 46 | /// A read-write decoder for an IPv6 routing extension header. 47 | /// 48 | [PacketImplementation(typeof(Ipv6RoutingExtension), IsReadOnly = true)] 49 | public readonly ref partial struct ReadOnlyIpv6RoutingExtensionSpan 50 | { 51 | } 52 | -------------------------------------------------------------------------------- /src/Enclave.FastPacket/Udp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Enclave.FastPacket.Generator; 3 | 4 | namespace Enclave.FastPacket; 5 | 6 | internal ref struct UdpPacketDefinition 7 | { 8 | /// 9 | /// The source port. 10 | /// 11 | public ushort SourcePort { get; set; } 12 | 13 | /// 14 | /// The destination port. 15 | /// 16 | public ushort DestinationPort { get; set; } 17 | 18 | /// 19 | /// The length in bytes of the header and data. 20 | /// 21 | public ushort Length { get; set; } 22 | 23 | /// 24 | /// The checksum. 25 | /// 26 | public ushort Checksum { get; set; } 27 | 28 | /// 29 | /// The payload. 30 | /// 31 | public ReadOnlySpan Payload { get; set; } 32 | } 33 | 34 | /// 35 | /// A read-write decoder for a UDP packet. 36 | /// 37 | [PacketImplementation(typeof(UdpPacketDefinition))] 38 | public readonly ref partial struct UdpPacketSpan 39 | { 40 | } 41 | 42 | /// 43 | /// A read-only decoder for a UDP packet. 44 | /// 45 | [PacketImplementation(typeof(UdpPacketDefinition), IsReadOnly = true)] 46 | public readonly ref partial struct ReadOnlyUdpPacketSpan 47 | { 48 | /// 49 | /// Convert to a readonly representation. 50 | /// 51 | public static implicit operator ReadOnlyUdpPacketSpan(UdpPacketSpan s) => new ReadOnlyUdpPacketSpan(s.GetRawData()); 52 | } -------------------------------------------------------------------------------- /src/Enclave.FastPacket/VisitResult.cs: -------------------------------------------------------------------------------- 1 | namespace Enclave.FastPacket; 2 | 3 | /// 4 | /// A visitor result. 5 | /// 6 | /// The state type. 7 | public readonly ref struct VisitResult 8 | { 9 | /// 10 | /// Create a new . 11 | /// 12 | /// The state of the visitor. 13 | /// The number of bytes consumed from the initial payload. 14 | /// The number of bytes remaining in the initial payload. 15 | public VisitResult(in TVisitorState visitorState, int lengthConsumed, int lengthRemaining) 16 | { 17 | VisitorState = visitorState; 18 | LengthConsumed = lengthConsumed; 19 | LengthRemaining = lengthRemaining; 20 | } 21 | 22 | /// 23 | /// The visitor state at the end of the visit process. 24 | /// 25 | public TVisitorState VisitorState { get; } 26 | 27 | /// 28 | /// The number of bytes consumed from the initial payload. 29 | /// 30 | public int LengthConsumed { get; } 31 | 32 | /// 33 | /// The number of bytes remaining in the initial payload. 34 | /// 35 | public int LengthRemaining { get; } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Enclave.FastPacket.Generator.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | enable 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | all 18 | 19 | 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | all 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Helpers/FluentVerify.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp; 4 | using System.Data; 5 | using System.Reflection; 6 | 7 | namespace Enclave.FastPacket.Generator.Tests.Helpers; 8 | 9 | public class FluentVerify 10 | { 11 | private readonly string _source; 12 | private IReadOnlyList> _diagnostics = Array.Empty>(); 13 | 14 | public static FluentVerify ForSource(string source) 15 | { 16 | return new FluentVerify(source); 17 | } 18 | 19 | private FluentVerify(string source) 20 | { 21 | _source = source; 22 | } 23 | 24 | public FluentVerify WithDiagnostics(params Action[] diagnosticAsserts) 25 | { 26 | _diagnostics = diagnosticAsserts; 27 | 28 | return this; 29 | } 30 | 31 | public FluentVerify WithDiagnostics(params DiagnosticDescriptor[] diagnosticDescriptors) 32 | { 33 | static Action AssertDiag(DiagnosticDescriptor expected) 34 | { 35 | return (Diagnostic actual) => Assert.Equal(expected.Id, actual.Id); 36 | } 37 | 38 | _diagnostics = diagnosticDescriptors.Select(AssertDiag).ToArray(); 39 | 40 | return this; 41 | } 42 | 43 | public Task Verify() 44 | { 45 | var compilation = Create(_source); 46 | 47 | var generator = new PacketParserGenerator(); 48 | 49 | GeneratorDriver driver = CSharpGeneratorDriver.Create(generator); 50 | 51 | // Once through for the generated code diagnostics, where we update the compilation. 52 | driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out var newCompilation, out var newDiagnostics); 53 | 54 | Assert.Collection(newDiagnostics, _diagnostics.ToArray()); 55 | 56 | return Verifier.Verify(driver) 57 | .UseDirectory(Path.Combine(AttributeReader.GetProjectDirectory(), "Snapshots")); 58 | } 59 | 60 | private static Compilation Create(string source) 61 | => CSharpCompilation.Create("compilation", 62 | new[] { CSharpSyntaxTree.ParseText(source) }, 63 | new[] { 64 | MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location), 65 | }, 66 | new CSharpCompilationOptions(OutputKind.ConsoleApplication)); 67 | } 68 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Helpers/ModuleInitializer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using System.Runtime.CompilerServices; 3 | using VerifyTests; 4 | 5 | namespace Enclave.FastPacket.Generator.Tests.Helpers; 6 | 7 | public static class ModuleInitializer 8 | { 9 | [ModuleInitializer] 10 | public static void Init() 11 | { 12 | // Override the output converter so we can filter out files we're not interested in. 13 | VerifierSettings.RegisterFileConverter(ConvertRunResult); 14 | VerifierSettings.RegisterFileConverter(ConvertDriver); 15 | 16 | VerifySourceGenerators.Enable(); 17 | } 18 | 19 | static ConversionResult ConvertRunResult(GeneratorDriverRunResult target, IReadOnlyDictionary context) 20 | { 21 | var exceptions = new List(); 22 | var targets = new List(); 23 | foreach (var result in target.Results) 24 | { 25 | if (result.Exception != null) 26 | { 27 | exceptions.Add(result.Exception); 28 | } 29 | 30 | targets.AddRange(result.GeneratedSources.Where(x => x.HintName.EndsWith("_Generated.cs")).Select(SourceToTarget)); 31 | } 32 | 33 | if (exceptions.Count == 1) 34 | { 35 | throw exceptions.First(); 36 | } 37 | 38 | if (exceptions.Count > 1) 39 | { 40 | throw new AggregateException(exceptions); 41 | } 42 | 43 | if (target.Diagnostics.Any()) 44 | { 45 | var info = new 46 | { 47 | target.Diagnostics 48 | }; 49 | return new(info, targets); 50 | } 51 | 52 | return new(null, targets); 53 | } 54 | 55 | static ConversionResult ConvertDriver(GeneratorDriver target, IReadOnlyDictionary context) 56 | { 57 | return ConvertRunResult(target.GetRunResult(), context); 58 | } 59 | 60 | static Target SourceToTarget(GeneratedSourceResult source) 61 | { 62 | var data = $@"//HintName: {source.HintName} 63 | {source.SourceText}"; 64 | return new("cs", data); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/SizeFunctionTests.cs: -------------------------------------------------------------------------------- 1 | using Enclave.FastPacket.Generator.Tests.Helpers; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp; 4 | using System.Reflection; 5 | using System.Threading.Tasks; 6 | using VerifyXunit; 7 | using Xunit; 8 | 9 | namespace Enclave.FastPacket.Generator.Tests; 10 | 11 | [UsesVerify] 12 | public class SizeFunctionTests 13 | { 14 | [Fact] 15 | public Task CanHaveOptionalPosition() 16 | { 17 | return FluentVerify.ForSource(@" 18 | using System; 19 | using Enclave.FastPacket.Generator; 20 | 21 | namespace T 22 | { 23 | internal ref struct PacketDefinition 24 | { 25 | [PacketField(SizeFunction = nameof(ValueFunc))] 26 | public ReadOnlySpan Value { get; set; } 27 | 28 | [PacketField(SizeFunction = nameof(Value2Func))] 29 | public ReadOnlySpan Value2 { get; set; } 30 | 31 | public ReadOnlySpan Remaining { get; set; } 32 | 33 | public static int ValueFunc(ReadOnlySpan span, int position) 34 | { 35 | return position; 36 | } 37 | 38 | public static int Value2Func(ReadOnlySpan span) 39 | { 40 | return 1; 41 | } 42 | } 43 | 44 | [PacketImplementation(typeof(PacketDefinition))] 45 | public readonly ref partial struct ValueItem 46 | { 47 | } 48 | } 49 | ").Verify(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/.gitignore: -------------------------------------------------------------------------------- 1 | *.received.cs 2 | *.received.txt -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/GeneratorTest.CanGenerateDefaultType.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public ushort Value 34 | { 35 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0)); 36 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0), value); 37 | } 38 | 39 | /// 40 | /// Get a string representation of this packet. 41 | /// 42 | public override string ToString() 43 | { 44 | return $"Value: {Value}"; 45 | } 46 | 47 | /// 48 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 49 | /// 50 | public int GetTotalSize() 51 | { 52 | return 0 + sizeof(ushort); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/GeneratorTest.CanGenerateTypeCustomToString.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public ushort Value 34 | { 35 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0)); 36 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0), value); 37 | } 38 | 39 | /// 40 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 41 | /// 42 | public int GetTotalSize() 43 | { 44 | return 0 + sizeof(ushort); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/GeneratorTest.CanGenerateTypeWithCustomTypeSizeConstant.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.PacketParser_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct PacketParser 10 | { 11 | private readonly ReadOnlySpan _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(int) + T.HardwareAddress.Size + T.HardwareAddress.Size + sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public PacketParser(ReadOnlySpan packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public ReadOnlySpan GetRawData() => _span; 31 | 32 | 33 | /// This is value 1 34 | /// 35 | /// Some extra stuff 36 | /// 37 | public int Value1 38 | { 39 | get => BinaryPrimitives.ReadInt32BigEndian(_span.Slice(0)); 40 | } 41 | 42 | 43 | public T.HardwareAddress Source 44 | { 45 | get => new T.HardwareAddress(_span.Slice(0 + sizeof(int), T.HardwareAddress.Size)); 46 | } 47 | 48 | 49 | public T.HardwareAddress Destination 50 | { 51 | get => new T.HardwareAddress(_span.Slice(0 + sizeof(int) + T.HardwareAddress.Size, T.HardwareAddress.Size)); 52 | } 53 | 54 | 55 | public ushort Value2 56 | { 57 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(int) + T.HardwareAddress.Size + T.HardwareAddress.Size)); 58 | } 59 | 60 | /// 61 | /// Get a string representation of this packet. 62 | /// 63 | public override string ToString() 64 | { 65 | return $"Value1: {Value1}; Source: {Source}; Destination: {Destination}; Value2: {Value2}"; 66 | } 67 | 68 | /// 69 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 70 | /// 71 | public int GetTotalSize() 72 | { 73 | return 0 + sizeof(int) + T.HardwareAddress.Size + T.HardwareAddress.Size + sizeof(ushort); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/GeneratorTest.CanGenerateTypeWithEnumCustomBackingTypeValue.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(byte); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public T.TcpFlags Value 34 | { 35 | get => (T.TcpFlags)(_span[0]); 36 | set => _span[0] = (byte)(value); 37 | } 38 | 39 | /// 40 | /// Get a string representation of this packet. 41 | /// 42 | public override string ToString() 43 | { 44 | return $"Value: {Value}"; 45 | } 46 | 47 | /// 48 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 49 | /// 50 | public int GetTotalSize() 51 | { 52 | return 0 + sizeof(byte); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/GeneratorTest.CanGenerateTypeWithEnumValue.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(int); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public T.TcpFlags Value 34 | { 35 | get => (T.TcpFlags)(BinaryPrimitives.ReadInt32BigEndian(_span.Slice(0))); 36 | set => BinaryPrimitives.WriteInt32BigEndian(_span.Slice(0), (int)(value)); 37 | } 38 | 39 | /// 40 | /// Get a string representation of this packet. 41 | /// 42 | public override string ToString() 43 | { 44 | return $"Value: {Value}"; 45 | } 46 | 47 | /// 48 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 49 | /// 50 | public int GetTotalSize() 51 | { 52 | return 0 + sizeof(int); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/GeneratorTest.CanGenerateTypeWithExternalSize.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.PacketParser_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct PacketParser 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(int) + 6 + 6 + sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public PacketParser(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | /// This is value 1 34 | /// 35 | /// Some extra stuff 36 | /// 37 | public int Value1 38 | { 39 | get => BinaryPrimitives.ReadInt32BigEndian(_span.Slice(0)); 40 | set => BinaryPrimitives.WriteInt32BigEndian(_span.Slice(0), value); 41 | } 42 | 43 | 44 | public T.HardwareAddress Source 45 | { 46 | get => new T.HardwareAddress(_span.Slice(0 + sizeof(int), 6)); 47 | set => value.CopyTo(_span.Slice(0 + sizeof(int), 6)); 48 | } 49 | 50 | 51 | public T.HardwareAddress Destination 52 | { 53 | get => new T.HardwareAddress(_span.Slice(0 + sizeof(int) + 6, 6)); 54 | set => value.CopyTo(_span.Slice(0 + sizeof(int) + 6, 6)); 55 | } 56 | 57 | 58 | public ushort Value2 59 | { 60 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(int) + 6 + 6)); 61 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + sizeof(int) + 6 + 6), value); 62 | } 63 | 64 | /// 65 | /// Get a string representation of this packet. 66 | /// 67 | public override string ToString() 68 | { 69 | return $"Value1: {Value1}; Source: {Source}; Destination: {Destination}; Value2: {Value2}"; 70 | } 71 | 72 | /// 73 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 74 | /// 75 | public int GetTotalSize() 76 | { 77 | return 0 + sizeof(int) + 6 + 6 + sizeof(ushort); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/GeneratorTest.CanGenerateTypeWithLongerNamespace.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: Enclave.FastPacket.PacketParser_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace Enclave.FastPacket 8 | { 9 | readonly ref partial struct PacketParser 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(int); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public PacketParser(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public int Value1 34 | { 35 | get => BinaryPrimitives.ReadInt32BigEndian(_span.Slice(0)); 36 | set => BinaryPrimitives.WriteInt32BigEndian(_span.Slice(0), value); 37 | } 38 | 39 | /// 40 | /// Get a string representation of this packet. 41 | /// 42 | public override string ToString() 43 | { 44 | return $"Value1: {Value1}"; 45 | } 46 | 47 | /// 48 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 49 | /// 50 | public int GetTotalSize() 51 | { 52 | return 0 + sizeof(int); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/GeneratorTest.CanGenerateTypeWithPayload.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.PacketParser_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct PacketParser 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(int); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public PacketParser(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public int Value1 34 | { 35 | get => BinaryPrimitives.ReadInt32BigEndian(_span.Slice(0)); 36 | set => BinaryPrimitives.WriteInt32BigEndian(_span.Slice(0), value); 37 | } 38 | 39 | 40 | public System.Span Payload 41 | { 42 | get => _span.Slice(0 + sizeof(int)); 43 | } 44 | 45 | /// 46 | /// Get a string representation of this packet. 47 | /// 48 | public override string ToString() 49 | { 50 | return $"Value1: {Value1}; Payload: {Payload.Length} bytes"; 51 | } 52 | 53 | /// 54 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 55 | /// 56 | public int GetTotalSize() 57 | { 58 | return 0 + sizeof(int) + _span.Slice(0 + sizeof(int)).Length; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/GeneratorTest.CanGenerateTypeWithPositionFunction.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = 6 + sizeof(ushort) + sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public ushort Value 34 | { 35 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(6)); 36 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(6), value); 37 | } 38 | 39 | 40 | public ushort NextValue 41 | { 42 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(T.PacketDefinition.GetNextValuePosition(_span, 6 + sizeof(ushort)))); 43 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(T.PacketDefinition.GetNextValuePosition(_span, 6 + sizeof(ushort))), value); 44 | } 45 | 46 | /// 47 | /// Get a string representation of this packet. 48 | /// 49 | public override string ToString() 50 | { 51 | return $"Value: {Value}; NextValue: {NextValue}"; 52 | } 53 | 54 | /// 55 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 56 | /// 57 | public int GetTotalSize() 58 | { 59 | return T.PacketDefinition.GetNextValuePosition(_span, 6 + sizeof(ushort)) + sizeof(ushort); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/GeneratorTest.CanGenerateTypeWithPrivateMember.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(ushort) + sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | private ushort Value 34 | { 35 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0)); 36 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0), value); 37 | } 38 | 39 | 40 | public ushort NextValue 41 | { 42 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort))); 43 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + sizeof(ushort)), value); 44 | } 45 | 46 | /// 47 | /// Get a string representation of this packet. 48 | /// 49 | public override string ToString() 50 | { 51 | return $"NextValue: {NextValue}"; 52 | } 53 | 54 | /// 55 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 56 | /// 57 | public int GetTotalSize() 58 | { 59 | return 0 + sizeof(ushort) + sizeof(ushort); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/SizeFieldTests.CanUsePrecedingFieldForSize.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public ushort DataSize 34 | { 35 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0)); 36 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0), value); 37 | } 38 | 39 | 40 | public System.Span Value 41 | { 42 | get => _span.Slice(0 + sizeof(ushort), DataSize); 43 | } 44 | 45 | /// 46 | /// Get a string representation of this packet. 47 | /// 48 | public override string ToString() 49 | { 50 | return $"DataSize: {DataSize}; Value: {Value.Length} bytes"; 51 | } 52 | 53 | /// 54 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 55 | /// 56 | public int GetTotalSize() 57 | { 58 | return 0 + sizeof(ushort) + DataSize; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/SizeFieldTests.SizeFieldCanBeAfterDataFieldIfExplicitPositionUsed.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = 20 + sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public System.Span Value 34 | { 35 | get => _span.Slice(0, DataSize); 36 | } 37 | 38 | 39 | public ushort DataSize 40 | { 41 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(20)); 42 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(20), value); 43 | } 44 | 45 | /// 46 | /// Get a string representation of this packet. 47 | /// 48 | public override string ToString() 49 | { 50 | return $"Value: {Value.Length} bytes; DataSize: {DataSize}"; 51 | } 52 | 53 | /// 54 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 55 | /// 56 | public int GetTotalSize() 57 | { 58 | return 20 + sizeof(ushort); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/SizeFieldTests.SizeFieldCannotBeAfterDataField.00.verified.txt: -------------------------------------------------------------------------------- 1 | { 2 | Diagnostics: [ 3 | { 4 | Id: FASTPACKET016, 5 | Title: Specified size field exists after this field, 6 | Severity: Error, 7 | WarningLevel: 0, 8 | Location: : (8,9)-(8,50), 9 | Description: , 10 | HelpLink: , 11 | MessageFormat: The specified size field {0} is read from the byte stream after the field in which it is referenced, and has a dynamic position; this is not allowed, 12 | Message: The specified size field DataSize is read from the byte stream after the field in which it is referenced, and has a dynamic position; this is not allowed, 13 | Category: FastPacket, 14 | CustomTags: [] 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/SizeFieldTests.SizeFieldCannotBeAfterDataField.01.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public System.Span Value 34 | { 35 | get => _span.Slice(0, 0); 36 | } 37 | 38 | 39 | public ushort DataSize 40 | { 41 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + 0)); 42 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + 0), value); 43 | } 44 | 45 | /// 46 | /// Get a string representation of this packet. 47 | /// 48 | public override string ToString() 49 | { 50 | return $"Value: {Value.Length} bytes; DataSize: {DataSize}"; 51 | } 52 | 53 | /// 54 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 55 | /// 56 | public int GetTotalSize() 57 | { 58 | return 0 + 0 + sizeof(ushort); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/SizeFieldTests.SizeFieldMustBeNumeric.00.verified.txt: -------------------------------------------------------------------------------- 1 | { 2 | Diagnostics: [ 3 | { 4 | Id: FASTPACKET015, 5 | Title: Specified size field has the wrong type, 6 | Severity: Error, 7 | WarningLevel: 0, 8 | Location: : (10,9)-(10,50), 9 | Description: , 10 | HelpLink: , 11 | MessageFormat: The specified size field {0} must return a numeric type. Size fields must be numeric fields in the same packet definition., 12 | Message: The specified size field DataSize must return a numeric type. Size fields must be numeric fields in the same packet definition., 13 | Category: FastPacket, 14 | CustomTags: [] 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/SizeFieldTests.SizeFieldMustBeNumeric.01.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(byte); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public bool DataSize 34 | { 35 | get => (_span[0]) > 0; 36 | set => _span[0] = (value ? 1 : 0); 37 | } 38 | 39 | 40 | public System.Span Value 41 | { 42 | get => _span.Slice(0 + sizeof(byte), 0); 43 | } 44 | 45 | /// 46 | /// Get a string representation of this packet. 47 | /// 48 | public override string ToString() 49 | { 50 | return $"DataSize: {DataSize}; Value: {Value.Length} bytes"; 51 | } 52 | 53 | /// 54 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 55 | /// 56 | public int GetTotalSize() 57 | { 58 | return 0 + sizeof(byte) + 0; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/SizeFieldTests.SizeFieldMustExist.00.verified.txt: -------------------------------------------------------------------------------- 1 | { 2 | Diagnostics: [ 3 | { 4 | Id: FASTPACKET014, 5 | Title: Specified size field was not found, 6 | Severity: Error, 7 | WarningLevel: 0, 8 | Location: : (8,9)-(8,50), 9 | Description: , 10 | HelpLink: , 11 | MessageFormat: The specified size field {0} was not found in this type. Size fields must be numeric fields in the same packet definition., 12 | Message: The specified size field DataSize was not found in this type. Size fields must be numeric fields in the same packet definition., 13 | Category: FastPacket, 14 | CustomTags: [] 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/SizeFieldTests.SizeFieldMustExist.01.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = 0; 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public System.Span Value 34 | { 35 | get => _span.Slice(0, 0); 36 | } 37 | 38 | /// 39 | /// Get a string representation of this packet. 40 | /// 41 | public override string ToString() 42 | { 43 | return $"Value: {Value.Length} bytes"; 44 | } 45 | 46 | /// 47 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 48 | /// 49 | public int GetTotalSize() 50 | { 51 | return 0 + 0; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/SizeFunctionTests.CanHaveOptionalPosition.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = 0; 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public System.Span Value 34 | { 35 | get => _span.Slice(0, T.PacketDefinition.ValueFunc(_span, 0)); 36 | } 37 | 38 | 39 | public System.Span Value2 40 | { 41 | get => _span.Slice(0 + T.PacketDefinition.ValueFunc(_span, 0), T.PacketDefinition.Value2Func(_span)); 42 | } 43 | 44 | 45 | public System.Span Remaining 46 | { 47 | get => _span.Slice(0 + T.PacketDefinition.ValueFunc(_span, 0) + T.PacketDefinition.Value2Func(_span)); 48 | } 49 | 50 | /// 51 | /// Get a string representation of this packet. 52 | /// 53 | public override string ToString() 54 | { 55 | return $"Value: {Value.Length} bytes; Value2: {Value2.Length} bytes; Remaining: {Remaining.Length} bytes"; 56 | } 57 | 58 | /// 59 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 60 | /// 61 | public int GetTotalSize() 62 | { 63 | return 0 + T.PacketDefinition.ValueFunc(_span, 0) + T.PacketDefinition.Value2Func(_span) + _span.Slice(0 + T.PacketDefinition.ValueFunc(_span, 0) + T.PacketDefinition.Value2Func(_span)).Length; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/TypeTests.CanGenerateBoolBitFields.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(ushort) + 1 + sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public ushort Value 34 | { 35 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0)); 36 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0), value); 37 | } 38 | 39 | 40 | public bool Value1 41 | { 42 | get => ((byte)((_span[0 + sizeof(ushort)] & 0x80u) >> 7)) > 0; 43 | set => _span[0 + sizeof(ushort)] = (byte)((((value ? 1 : 0) << 7) & 0x80u) | (byte)(_span[0 + sizeof(ushort)] & ~0x80u)); 44 | } 45 | 46 | 47 | public bool UnionVal2 48 | { 49 | get => ((byte)((_span[0 + sizeof(ushort)] & 0x40u) >> 6)) > 0; 50 | set => _span[0 + sizeof(ushort)] = (byte)((((value ? 1 : 0) << 6) & 0x40u) | (byte)(_span[0 + sizeof(ushort)] & ~0x40u)); 51 | } 52 | 53 | 54 | public ushort Value2 55 | { 56 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + 1)); 57 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + 1), value); 58 | } 59 | 60 | /// 61 | /// Get a string representation of this packet. 62 | /// 63 | public override string ToString() 64 | { 65 | return $"Value: {Value}; Value1: {Value1}; UnionVal2: {UnionVal2}; Value2: {Value2}"; 66 | } 67 | 68 | /// 69 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 70 | /// 71 | public int GetTotalSize() 72 | { 73 | return 0 + sizeof(ushort) + 1 + sizeof(ushort); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/UnionTests.CanGenerateUnion.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(ushort) + 1 + sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public ushort Value 34 | { 35 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0)); 36 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0), value); 37 | } 38 | 39 | 40 | public byte UnionVal1 41 | { 42 | get => _span[0 + sizeof(ushort)]; 43 | set => _span[0 + sizeof(ushort)] = value; 44 | } 45 | 46 | 47 | public byte UnionVal2 48 | { 49 | get => _span[0 + sizeof(ushort)]; 50 | set => _span[0 + sizeof(ushort)] = value; 51 | } 52 | 53 | 54 | public ushort Value2 55 | { 56 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + 1)); 57 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + 1), value); 58 | } 59 | 60 | /// 61 | /// Get a string representation of this packet. 62 | /// 63 | public override string ToString() 64 | { 65 | return $"Value: {Value}; UnionVal1: {UnionVal1}; UnionVal2: {UnionVal2}; Value2: {Value2}"; 66 | } 67 | 68 | /// 69 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 70 | /// 71 | public int GetTotalSize() 72 | { 73 | return 0 + sizeof(ushort) + 1 + sizeof(ushort); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/UnionTests.CanGenerateUnionWithBitmask.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(ushort) + 1 + sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public ushort Value 34 | { 35 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0)); 36 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0), value); 37 | } 38 | 39 | 40 | public byte UnionVal1 41 | { 42 | get => (byte)((_span[0 + sizeof(ushort)] & 0xF0u) >> 4); 43 | set => _span[0 + sizeof(ushort)] = (byte)(((value << 4) & 0xF0u) | (byte)(_span[0 + sizeof(ushort)] & ~0xF0u)); 44 | } 45 | 46 | 47 | public byte UnionVal2 48 | { 49 | get => (byte)(_span[0 + sizeof(ushort)] & 0xFu); 50 | set => _span[0 + sizeof(ushort)] = (byte)((value & 0xFu) | (byte)(_span[0 + sizeof(ushort)] & ~0xFu)); 51 | } 52 | 53 | 54 | public ushort Value2 55 | { 56 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + 1)); 57 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + 1), value); 58 | } 59 | 60 | /// 61 | /// Get a string representation of this packet. 62 | /// 63 | public override string ToString() 64 | { 65 | return $"Value: {Value}; UnionVal1: {UnionVal1}; UnionVal2: {UnionVal2}; Value2: {Value2}"; 66 | } 67 | 68 | /// 69 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 70 | /// 71 | public int GetTotalSize() 72 | { 73 | return 0 + sizeof(ushort) + 1 + sizeof(ushort); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/Snapshots/UnionTests.CanGenerateUnionWithLargeBitmask.verified.cs: -------------------------------------------------------------------------------- 1 | //HintName: T.ValueItem_Generated.cs 2 | // 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace T 8 | { 9 | readonly ref partial struct ValueItem 10 | { 11 | private readonly Span _span; 12 | 13 | /// 14 | /// Defines the minimum possible size of this packet, given all 15 | /// known fixed sizes. 16 | /// 17 | public const int MinimumSize = sizeof(ushort) + 2 + sizeof(ushort); 18 | 19 | /// 20 | /// Create a new instance of . 21 | /// 22 | public ValueItem(Span packetData) 23 | { 24 | _span = packetData; 25 | } 26 | 27 | /// 28 | /// Gets the raw underlying buffer for this packet. 29 | /// 30 | public Span GetRawData() => _span; 31 | 32 | 33 | public ushort Value 34 | { 35 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0)); 36 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0), value); 37 | } 38 | 39 | 40 | public T.FragmentFlags Flags 41 | { 42 | get => (T.FragmentFlags)((byte)((_span[0 + sizeof(ushort)] & 0xE0u) >> 5)); 43 | set => _span[0 + sizeof(ushort)] = (byte)((((byte)(value) << 5) & 0xE0u) | (byte)(_span[0 + sizeof(ushort)] & ~0xE0u)); 44 | } 45 | 46 | 47 | public ushort FragmentValue 48 | { 49 | get => (ushort)(BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort))) & 0x1FFFu); 50 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + sizeof(ushort)), (ushort)((value & 0x1FFFu) | (ushort)(BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort))) & ~0x1FFFu))); 51 | } 52 | 53 | 54 | public ushort Value2 55 | { 56 | get => BinaryPrimitives.ReadUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + 2)); 57 | set => BinaryPrimitives.WriteUInt16BigEndian(_span.Slice(0 + sizeof(ushort) + 2), value); 58 | } 59 | 60 | /// 61 | /// Get a string representation of this packet. 62 | /// 63 | public override string ToString() 64 | { 65 | return $"Value: {Value}; Flags: {Flags}; FragmentValue: {FragmentValue}; Value2: {Value2}"; 66 | } 67 | 68 | /// 69 | /// Get the computed total size of this packet, including any dynamically-sized fields and trailing payloads. 70 | /// 71 | public int GetTotalSize() 72 | { 73 | return 0 + sizeof(ushort) + 2 + sizeof(ushort); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/TypeTests.cs: -------------------------------------------------------------------------------- 1 | using Enclave.FastPacket.Generator.Tests.Helpers; 2 | 3 | namespace Enclave.FastPacket.Generator.Tests; 4 | 5 | [UsesVerify] 6 | public class TypeTests 7 | { 8 | public TypeTests() 9 | : base() 10 | { 11 | } 12 | 13 | [Fact] 14 | public Task CanGenerateBoolBitFields() 15 | { 16 | return FluentVerify.ForSource(@" 17 | 18 | using Enclave.FastPacket.Generator; 19 | 20 | namespace T 21 | { 22 | internal class PacketDefinition 23 | { 24 | public ushort Value { get; set; } 25 | 26 | [PacketField(Size = sizeof(byte))] 27 | struct Union1 28 | { 29 | [PacketFieldBits(0)] 30 | public bool Value1 { get; set; } 31 | 32 | [PacketFieldBits(1)] 33 | public bool UnionVal2 { get; set; } 34 | } 35 | 36 | public ushort Value2 { get; set; } 37 | } 38 | 39 | [PacketImplementation(typeof(PacketDefinition))] 40 | public readonly ref partial struct ValueItem 41 | { 42 | } 43 | } 44 | ").Verify(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Generator.Tests/UnionTests.cs: -------------------------------------------------------------------------------- 1 | using Enclave.FastPacket.Generator.Tests.Helpers; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp; 4 | using System.Reflection; 5 | using System.Threading.Tasks; 6 | using VerifyXunit; 7 | using Xunit; 8 | 9 | namespace Enclave.FastPacket.Generator.Tests; 10 | 11 | [UsesVerify] 12 | public class UnionTests 13 | { 14 | public UnionTests() 15 | : base() 16 | { 17 | } 18 | 19 | [Fact] 20 | public Task CanGenerateUnion() 21 | { 22 | return FluentVerify.ForSource(@" 23 | 24 | using Enclave.FastPacket.Generator; 25 | 26 | namespace T 27 | { 28 | internal class PacketDefinition 29 | { 30 | public ushort Value { get; set; } 31 | 32 | [PacketField(Size = sizeof(byte))] 33 | struct Union1 34 | { 35 | public byte UnionVal1 { get; set; } 36 | 37 | public byte UnionVal2 { get; set; } 38 | } 39 | 40 | public ushort Value2 { get; set; } 41 | } 42 | 43 | [PacketImplementation(typeof(PacketDefinition))] 44 | public readonly ref partial struct ValueItem 45 | { 46 | } 47 | } 48 | ").Verify(); 49 | } 50 | 51 | [Fact] 52 | public Task CanGenerateUnionWithBitmask() 53 | { 54 | return FluentVerify.ForSource(@" 55 | 56 | using Enclave.FastPacket.Generator; 57 | 58 | namespace T 59 | { 60 | internal class PacketDefinition 61 | { 62 | public ushort Value { get; set; } 63 | 64 | [PacketField(Size = sizeof(byte))] 65 | struct Union1 66 | { 67 | [PacketFieldBits(0, 3)] 68 | public byte UnionVal1 { get; set; } 69 | 70 | [PacketFieldBits(4, 7)] 71 | public byte UnionVal2 { get; set; } 72 | } 73 | 74 | public ushort Value2 { get; set; } 75 | } 76 | 77 | [PacketImplementation(typeof(PacketDefinition))] 78 | public readonly ref partial struct ValueItem 79 | { 80 | } 81 | } 82 | ").Verify(); 83 | } 84 | 85 | [Fact] 86 | public Task CanGenerateUnionWithLargeBitmask() 87 | { 88 | return FluentVerify.ForSource(@" 89 | 90 | using Enclave.FastPacket.Generator; 91 | 92 | namespace T 93 | { 94 | [Flags] 95 | public enum FragmentFlags 96 | { 97 | Reserved = 0x00, 98 | DontFragment = 0x01, 99 | MoreFragments = 0x02, 100 | } 101 | internal class PacketDefinition 102 | { 103 | public ushort Value { get; set; } 104 | 105 | [PacketField(Size = sizeof(ushort))] 106 | private struct U3 107 | { 108 | [PacketFieldBits(0, 2)] 109 | public FragmentFlags Flags { get; set; } 110 | 111 | [PacketFieldBits(3, 15)] 112 | public ushort FragmentValue { get; set; } 113 | } 114 | 115 | public ushort Value2 { get; set; } 116 | } 117 | 118 | [PacketImplementation(typeof(PacketDefinition))] 119 | public readonly ref partial struct ValueItem 120 | { 121 | } 122 | } 123 | ").Verify(); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Tests/Enclave.FastPacket.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | all 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Tests/EthernetTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using System; 3 | using Xunit; 4 | 5 | namespace Enclave.FastPacket.Tests; 6 | 7 | public class EthernetTests 8 | { 9 | [Fact] 10 | public void CanParseEthernetPacket() 11 | { 12 | var bytes = Convert.FromHexString("01 00 5E 00 00 0D C2 03 3D 80 00 01 08 00 45 C0 00 36 00 A3 00 00 01 67 CD E4 0A 00 00 0D E0 00 00 0D 20 00 B5 2E 00 01 00 02 00 69 00 14 00 04 D7 70 51 AB 00 13 00 04 00 00 00 01 00 15 00 04 01 00 00 00".Replace(" ", "")); 13 | 14 | var ethPacketSpan = new EthernetPacketSpan(bytes); 15 | 16 | var type = ethPacketSpan.Type; 17 | 18 | type.Should().Be(EthernetType.IPv4); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Tests/Fixtures/mongodb-ssh-tcp-packet.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enclave-networks/Enclave.FastPacket/7e39fff916b07e0cb55374d18c870987053769fb/tests/Enclave.FastPacket.Tests/Fixtures/mongodb-ssh-tcp-packet.bin -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Tests/Helpers/FixtureHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Enclave.FastPacket.Tests; 5 | 6 | internal static class FixtureHelpers 7 | { 8 | public static byte[] LoadFixture(string name) 9 | { 10 | return File.ReadAllBytes(Path.Combine(AppContext.BaseDirectory, "Fixtures", name)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Tests/Helpers/FluentAssertionExtensions.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentAssertions.Collections; 3 | using System; 4 | 5 | namespace Enclave.FastPacket.Tests; 6 | 7 | internal static class FluentAssertionExtensions 8 | { 9 | public static GenericCollectionAssertions Should(this ReadOnlySpan span) 10 | { 11 | return span.ToArray().Should(); 12 | } 13 | 14 | public static GenericCollectionAssertions Should(this Span span) 15 | { 16 | return span.ToArray().Should(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/Enclave.FastPacket.Tests/RealPacketTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using Xunit; 3 | 4 | namespace Enclave.FastPacket.Tests; 5 | 6 | public class RealPacketTests 7 | { 8 | /// 9 | /// Packet captured on Linux Ubuntu 20.04; MongoDB response packet that was failing to be routed correctly on older versions. 10 | /// 11 | [Fact] 12 | public void MongoDbSshTcpPacket() 13 | { 14 | var packetContent = FixtureHelpers.LoadFixture("mongodb-ssh-tcp-packet.bin"); 15 | 16 | var ethPacket = new EthernetPacketSpan(packetContent); 17 | 18 | ethPacket.Type.Should().Be(EthernetType.IPv4); 19 | 20 | var ipSpan = new ReadOnlyIpv4PacketSpan(ethPacket.Payload); 21 | 22 | ipSpan.Source.ToString().Should().Be("100.73.154.85"); 23 | ipSpan.Destination.ToString().Should().Be("100.83.102.174"); 24 | ipSpan.Protocol.Should().Be(IpProtocol.Tcp); 25 | 26 | var tcpSpan = new ReadOnlyTcpPacketSpan(ipSpan.Payload); 27 | 28 | tcpSpan.SourcePort.Should().Be(27017); 29 | tcpSpan.DestinationPort.Should().Be(59272); 30 | 31 | tcpSpan.Payload.Should().HaveCount(1922); 32 | } 33 | } 34 | --------------------------------------------------------------------------------