Giter Club home page Giter Club logo

arcus's Introduction

Arcus Arcus

Nuget (with prereleases) Documentation on ReadTheDocs Apache 2.0 license .NetStandard 1.3 Join the chat at https://gitter.im/sandialabs/Arcus

Build Status

Arcus is a C# manipulation library for calculating, parsing, formatting, converting, and comparing both IPv4 and IPv6 addresses and subnets. It accounts for 128-bit numbers on 32-bit platforms.

Getting Started

The latest stable release of Arcus is available on NuGet.

The latest Arcus documentation may be found on ReadTheDocs.

Usage

At its heart Arcus is split amongst five separate interdependent units. Types, Comparers, Converters, Math, and Utilities.

These units each work across Arcus's IPAddressRange, Subnet and .NET's System.Net.IPAddress. Arcus adds extra desired functionality where the standard C# libraries left off.

Types

Subnet

An IPv4 or IPv6 subnetwork representation - the work horse and original reason for the Arcus library. Outside the concept of the Subnet object, most everything else in Arcus is auxiliary and exists only in support of the Subnet object. That’s not to say that the remaining pieces of the Arcus library aren’t useful, on the contrary their utility can benefit a developer greatly.

A Subnet may be instantiated in several ways:

The most common way to create a Subnet object is to construct it via a high and low IPAddress by calling the constructor Subnet(IPAddress primary, IPAddress secondary). This constructs the smallest possible subnet that would contain both IP addresses. Typically the addresses specified are the Network and Broadcast addresses (lower and higher bounds of a subnet) but this is not necessary. Addresses MUST be the same address family (either Internetwork or InternetworkV6).

It is also possible to create a Subnet from an IPAddress and an integer based route prefix. Eg: Subnet(IPAddress ipAddress, int routingPrefix).

Likewise it may be desired to statically parse a subnet string with Subnet.Parse(string input) or it’s safe equivalent of bool Subnet.TryParse(string input, out Subnet subnet)

For example, one could safely parse the string "192.168.1.0/16" via

Subnet subnet;
var success = Subnet.TryParse("192.168.1.0/16", out subnet)

IPAddressRange

IPAddressRange is a basic implementation of IIPAddressRange it is used to represent an inclusive range of arbitrary IP Addresses of the same address family. Unlike Subnet, IPAddressRange is not restricted to a power of two length, nor a valid broadcast address head.

Comparers

The Comparers package contains useful Comparer objects for comparing properties of IP Addresses and IP Address composite objects.

  • DefaultAddressFamilyComparer - A comparer that compares address families. Most frequently Internetwork (IPv4) and InternetworkV6 (IPv6)
  • DefaultIPAddressComparer - A comparer for IPAddress objects
  • DefaultIPAddressRangeComparer - A comparer for IIPAddressRange. Compares such that lower order ranges are less that higher order ranges accounting for size at matching range starts

Converters

The Converters package is a package of static utility classes for converting one type into another type.

IPAddressConverters

Static utility class containing conversion methods for converting IPAddress objects into something else.

Math

The Math package is a package of static utility classes for doing computational mathematics on objects.

IPAddressMath

In some cases the C# IPAddress object doesn't go far enough with what you can do with it mathematically, this static utility class containing mathematical methods to fill in the gaps.

Incrementing and Decrementing

Incrementing and Decrementing an IPAddress is easy.

Incrementing by one is a simple call to the extension method:

var address = IPAddress.Parse("192.168.1.1");
var result = address.Increment(); // result is 192.168.1.2

Decrementing is just as simple:

var address = IPAddress.Parse("192.168.1.1");
var result = address.Increment(-2); // result is 192.168.0.0

Overflow and Underflow conditions will result in an InvalidOperationException.

Equality

Equality may also be tested via a host of equality extension methods:

  • bool IsEqualTo(this IPAddress alpha, IPAddress beta)
  • bool IsGreaterThan(this IPAddress alpha, IPAddress beta)
  • bool IsGreaterThanOrEqualTo(this IPAddress alpha, IPAddress beta)
  • bool IsLessThan(this IPAddress alpha, IPAddress beta)
  • bool IsLessThanOrEqualTo(this IPAddress alpha, IPAddress beta)

Utilities

The Utilities package contains static classes for miscellaneous operations on specific types.

IPAddressUtilities

Static utility class containing miscellaneous operations for IPAddress objects

Address Family Detection

A couple of extension methods were created to quickly determine the address family of an IP Address. To determine if an address is IPv4 use bool IsIPv4(this IPAddress ipAddress), likewise bool IsIPv6(this IPAddress ipAddress) can be used to test for IPv6.

Parsing

It is possible to parse an IPAddress from a hexadecimal string into either an IPv4 of IPv6 address using the IPAddress ParseFromHexString(string input, AddressFamily addressFamily) method. Likewise it can be done safely with bool TryParseFromHexString(string input, AddressFamily addressFamily, out IPAddress address).

Similarly, conversion may be done from an octal string by using bool TryParseIgnoreOctalInIPv4(string input, out IPAddress address) or even a BigInteger by way of bool TryParse(BigInteger input, AddressFamily addressFamily, out IPAddress address).

SubnetUtilities

Static utility class containing miscellaneous operations for Subnet objects that didn't make sense to put on the object itself.

Given two arbitrary IP Addresses of the same family it may be desired to calculate the fewest consecutive subnets that would hold the inclusive range between them. For example

SubnetUtilities.FewestConsecutiveSubnetsFor(IPAddress.Parse("128.64.20.3"), IPAddress.Parse("128.64.20.12"))

would return an Enumerable containing the subnets 128.64.20.3/32, 128.64.20.4/30, 128.64.20.8/30, 128.64.20.12/32.

Built With

  • Gulliver - A self created library that helped us keep our bits and bytes in order
  • NuGet - Dependency Management
  • JetBrains.Annotations - Used to keep developers honest
  • moq - Fake it until you make it!
  • Stackoverflow - Because who really remembers how to code
  • xUnit.net - Testing, testing, 1, 2, 3...

Versioning

We use SemVer for versioning.

Primary Authors and Contributors

  • Robert H. Engelhardt - Primary Developer, Source of Ideas Good and Bad - @rheone
  • Andrew Steele - Review and Suggestions - @ahsteele
  • Nick Bachicha - Git Wrangler and DevOps Extraordinaire - @nicksterx

Copyright

Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. Government retains certain rights in this software.

License

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

arcus's People

Contributors

ahsteele avatar nicksterx avatar rheone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arcus's Issues

Subnet and IPAddressRange should be serializable

Subnet and IPAddressRange should implement ISerializable, be decorated by SerializableAttribute and have custom serialize logic.

Subnet should serialize head address bytes and routing prefix
IPAddressRange should serialize head address bytes and tail address bytes

[TechDebt] rename Git default branch to `main`

Description

"The Internet Engineering Task Force (IETF) points out that "Master-slave is an oppressive metaphor that will and should never become fully detached from history" as well as "In addition to being inappropriate and arcane, the master-slave metaphor is both technically and historically inaccurate." There's lots of more accurate options depending on context and it costs me nothing to change my vocabulary, especially if it is one less little speed bump to getting a new person excited about tech." - Scott Hanselman

Impact

This can/will affect builds and document generation. All external items pointing to master branch should be updated.

Addressing CA1036 for IPAddressRange and Subnet

CA1036 states that IPAddressRange and Subnet should override the comparison operators, specifically op_Equality, op_Inequality, op_LessThan and op_GreaterThan.

Add less than or equal to and greater than or equal to so as not to disappoint

[TechDebt] Clean up csproj file replacing deprecated configuration

Warnings are generated on packing due to deprecated configuration

  • warning NU5125: The 'licenseUrl' element will be deprecated. Consider using the 'license' element instead. [XXXX\Arcus\src\Arcus\Arcus.csproj]
  • warning NU5048: The 'PackageIconUrl'/'iconUrl' element is deprecated. Consider using the 'PackageIcon'/'icon' element instead. Learn more at https://aka.ms/deprecateIconUrl [XXX\Arcus\src\Arcus\Arcus.csproj]

Fix readme

Readme should include the Arcus icon and link to Gulliver. Also the copyright notice is in a code block and looks ugly. License might also be code and need to change too.

[BUG] MAC address regular expression is wrong

Describe the bug

the RegEx

^(?:[0-9A-Fa-f]{2}([-: ]?))(?:[0-9A-Fa-f]{2}\1){4}[0-9A-Fa-f]{2}$|^(?:[0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4}$|^(?:[0-9A-Fa-f]{3}\.){3}[0-9A-Fa-f]{3}$

was (poorly) optimized to

^[\dA-F]{2}([ -:]?)(?:[\dA-F]{2}\1){4}[\dA-F]{2}$|^(?:[\dA-F]{4}\.){2}[\dA-F]{4}$|^(?:[\dA-F]{3}\.){3}[\dA-F]{3}$`

RegEx to Strings
regexp-tree

It is matching things like

48%57%82%1A%3A%E5
DA8698328B383C858
8F+23+1F+7D+C2+D8
7D6426E367C6F163A
65)E9)E0)5C)21)51
A9&4A&8D&E1&6A&48
200F70CB0250260CD
8F36E30A34936732D
C2$06$7C$6C$7F$0B

Expected behavior

It should match (and only match)

I’ve reviewed common formats and standards and I believe the following regex to be correct for the following formats

  • IEEE 802 format for printing MAC-48 addresses in six groups of two hexadecimal digits, separated by hyphens -
  • six groups of two hexadecimal digits separated by colons :
  • six groups of two hexadecimal digits separated by spaces
  • 12 hexadecimal digits with no separation
  • Cisco three groups of four hexadecimal digits separated by dots .
  • Cisco four groups of three hexadecimal digits separated by dots .

Bonus points if it groups the Hexadecimal Digits

More info may be found on Network Engineering Stackexchange What are the various standard and industry practice ways to express a 48-bit MAC address?

Proposed solutions

I'll figure something out

Can you help?

I'll figure something out

NuGet Icon not configured properly do display both on NuGet site and Nuget PackageManager within Visual Studio

After discovering stackoverflow "NuGet Package Icon Not getting Displayed" it appears that the PackageIcon csproj directive is not respected by the Nuget PackageManager within Visual Studio a documented issue that appears to be getting attention.

  • In theory icon and iconUrl are deprecated, but supported by both NuGet site and Nuget PackageManager within Visual Studio
  • Embedded icon, packageIcon is not supported by Nuget PackageManager within Visual Studio, but is supported by the NuGet site.

I would have to assume embedding and iconUrl will conflict, but experimentation is required.

[Feature Request] MacAddress shold be able to map to EUI-64 bytes for legacy support

Description

A legacy use of a MAC Address is to convert it to a EUI-64.

This will allow us to also support the legacy modification of a EUI-64 as the least-significant 64 bits of a unicast network address or link-local address when stateless address autoconfiguration is used.

Eg. MAC Address to IPv6

Proposed solutions

There are several sources that say several things about this mapping; it is unclear which is "most" correct, or what the variants imply.

It seems odd that each of the 3 below mentioned very specifically outlining differing rules for what would seem to be the same operation. While IEEE is the definitive source, I'd like to determine the reasoning of the other implementations before moving forward. The differing schemes may be perfectly valid in the appropriate place.

All this for a known legacy operation 🤷

Networking Engineering StackExchange

(current implementation)
Answer to "What are EUI-48 and EUI-64?"
states that the insertion bytes should be [0xFF, 0xFE] and 7th bit should be inverted.

Wikipedia entry for "Mac Address"

Mac Address. Citation Note 6
states that the insertion bytes should be [0xFF, 0xFE] if the source is a EUI-48
and that the insertion bytes should be [0xFF, 0xFF] if the source is a MAC-48
(no inversion of any bits mentioned)

IEE

IEEE in "Guidelines for Use of Extended Unique Identifier (EUI), Organizationally Unique Identifier (OUI), and Company ID (CID)" section "Mapping an EUI-48 to an EUI-64" (pg 15)
states that the insertion bytes should be [0xFF, 0xFE] or [0xFF, 0xFF]
(no inversion of any bits mentioned)

Can you help?

Maybe? Gotta clear some things up and do some research

Code

What follows is the "StackExchange" implementation. This exists simply because it is what I first encountered before researching further. By no means is it the "correct" solution, it is simply correct as to the implied spec.

/// <summary>Gets a mapping of the Mac Address as a EUI-64</summary>
/// <remarks><para>Note that this mapping is considered deprecated, and is implemented for legacy needs</para></remarks>
/// <remarks><para>The implementation of this method is under question</para></remarks>
/// <returns>an array of bytes representing the EUI-64 of the MAC Address</returns>
[NotNull]
[Obsolete("This method is obsolete until the desired output can be verified")]
public byte[] GetEui64AddressBytes()
{
   // To generate a EUI-64 from the EUI-48
   // - divided EUI-48 int two 3-byte parts; OUI & CID
   // - insert the value 0xFFFE between the two parts (24th bit)
   // - Invert the 7th bit of the result

   var eui64 = new byte[8];
   Array.Copy(this._address, 0, eui64, 0, 3);  // first 3 bytes od address
   eui64[3] = 0xFF;
   eui64[4] = 0xFE;
   Array.Copy(this._address, 3, eui64, 5, 3);  // last 3 bytes of address

   // invert the 7th bit
   if ((eui64[0] & 0b0000_0010) != 0)  // 7th bit (big-endian) is set, it should be cleared
   {
         eui64[0] &= 0b1111_1101;    // clear the 7th bit
   }
   else  // 7th bit (big-endian) is not set, it should be set
   {
         eui64[0] |= 0b0000_0010;    // set the 7th bit
   }

   return eui64;
}

Tests

public static IEnumerable<object[]> GetEui64AddressBytes_Test_Values()
{
   yield return new object[] { new byte[] { 0x02, 0x21, 0x86, 0xFF, 0xFE, 0xB5, 0x6E, 0x10 }, MacAddress.Parse("00:21:86:B5:6E:10") };
   yield return new object[] { new byte[] { 0xFD, 0x21, 0x86, 0xFF, 0xFE, 0xB5, 0x6E, 0x10 }, MacAddress.Parse("FF:21:86:B5:6E:10") };
   yield return new object[] { new byte[] { 0xC2, 0xFF, 0xEE, 0xFF, 0xFE, 0xCA, 0xFE, 0x00 }, MacAddress.Parse("C0:FF:EE:CA:FE:00") };
}

[Theory]
[MemberData(nameof(GetEui64AddressBytes_Test_Values))]
public void GetEui64AddressBytes_Test(byte[] expected, MacAddress input)
{
   // Arrange
   // Act
   var result = input.GetEui64AddressBytes();

   // Assert
   Assert.IsType<byte[]>(result);
   var addressBytes = input.GetAddressBytes();

   Assert.Equal(8, result.Length);
   Assert.NotEqual(expected[0] & 0b10, addressBytes[0] & 0b10);
   Assert.Equal(0xFF, result[3]);
   Assert.Equal(0xFE, result[4]);
   Assert.Equal(0, ByteArrayUtils.CompareUnsignedBigEndian(expected, result));
}

Introduce basic support for IPv4 classful networks

Description

Arcus is missing in-the-box support for Subnets defined by and expressing traits of the accepted IPv4 Classful Network. It is desired that Arcus should provide legacy support for A, B, C, with a possibility for D (multicasting) and E classful networks.

Arcus should:

  • Allow the Subnet object to be constructed, either via constructor or a factory, by issuing an appropriate IP Address and class specifier
  • Subnet should have a property dictating its class if it is IP4 and meets the appropriate class
  • It should be possible to translate between IP Address netmasks and class A, B, and C

[BUG] Readme icon borked

Describe the bug

Iconography PR broke readme:
image

Expected behavior

An icon not a broken image tag

[Doc] Create a style guideline

Description

We're lacking a style guideline both for the C# code and the Sphinx doc generation.

Impact

It will keep the code clean and concise for all devs

Proposed solutions

  • provide a document with the desired guidelines
  • settle upon a .editorconfig for all file types
  • create appropriate resharper code formatter
  • define linter / formatter rules as appropriate
  • run linter as part of build step

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.