Bitvantage.NetworkAddressing 1.0.1

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package Bitvantage.NetworkAddressing --version 1.0.1                
NuGet\Install-Package Bitvantage.NetworkAddressing -Version 1.0.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Bitvantage.NetworkAddressing" Version="1.0.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Bitvantage.NetworkAddressing --version 1.0.1                
#r "nuget: Bitvantage.NetworkAddressing, 1.0.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Bitvantage.NetworkAddressing as a Cake Addin
#addin nuget:?package=Bitvantage.NetworkAddressing&version=1.0.1

// Install Bitvantage.NetworkAddressing as a Cake Tool
#tool nuget:?package=Bitvantage.NetworkAddressing&version=1.0.1                

NetworkAddressing

A library for working with network addresses

Features

  • Network class that represents IPv4 and IPv6 networks
  • Network lookup class for high performance prefix matching using a variable stride trie
  • MAC address class that represents an Ethernet MAC address
  • OUI database to lookup manufacturer information of MAC addresses

License

The NetworkAddressing library is licensed under LGPL v2.1

Installing via NuGet Package Manager

PM> NuGet\Install-Package Bitvantage.NetworkAddressing

Overview

A network object represents either an IPv4 or IPv6 network.

Network

// create new network object
var network = Network.Parse("10.0.0.0/24");

// get the total number of host addresses in a network
var totalHosts = network.TotalHosts;

// get the total number of addresses in a network
var totalAddresses = network.TotalAddresses;

// iterate through each host address
foreach(var address in network.Hosts()
	Console.WriteLine(address);

// determin if a network is contained by a different network
var networkContainsNetwork = network.Contains("10.0.0.0/25");

// determin if a IP address is contained by a network
var networkContainsHost = network.Contains(IPAddress.Parse("10.0.0.100");

Network Lookup

The NetworkLookup class uses a high performance variable stride trie to represent a large number of IPv4 or IPv6 networks in a compact tree structure. This structure allows for longest and full prefix matching in an efficient way.

var networkLookup = new NetworkLookup();
networkLookup.Add("69.0.0.0/8");
networkLookup.Add("9.213.0.0/21");
networkLookup.Add("52.137.186.232/30");
networkLookup.Add("59.168.0.0/13");
networkLookup.Add("59.168.83.0/24");
networkLookup.Add("69.169.125.128/30");
networkLookup.Add("69.15.21.0/25");
networkLookup.Add("69.248.13.0/26");
networkLookup.Add("109.114.42.64/28");
networkLookup.Add("109.195.0.0/17");

Longest Matching Prefix

Routers typically work by finding the best route to the destination address. It does this by searching through its routing table to find the longest, or most specific, route to a particular destination.

networkLookup.GetMatch(IPAddress.Parse("69.248.13.12");

All Matching Prefixes

networkLookup.GetMatchs(IPAddress.Parse("69.248.13.12");

Tree Visualization

A Graphviz DOT diagram can generated, and optionaly rendered. In order to render the DOT diagram into a SVG you must have Graphviz installed.

networkLookup.ToDotSvgTree(@"c:\temp\graph.svg", IPVersion.IPv4);

A text representation of the tree can also be generated.

networkLookup.ToTextTree(IPVersion.IPv4);

Variable Stride Trie

Networks are organizing into a wide, shallow tree structure. The maximum depth of the tree is 33 levels for IPv4 or 129 levels for IPv6. The actual depth largely depends on how closely related the networks are; however for most application the depth is generally in the single digits. The depth of the tree is directly proportional to lookup performance.

Below is a visualization of a small tree that contains 10 networks. The orange node is the root node, green nodes are container nodes, and blue nodes are network objects and their associated values.

Network node have between zero and two children, container nodes have exactly two nodes. The child that is contained in the first half of the parents address space is on the left side, the child that is contained by the last half of the parents address space is on the right side. Container nodes are automatically added and removed to maintain the correct parent child relationship.

Small Network Tree

As more networks are added to the tree, the tree tends to grow in width far more quickly then depth. Since the depth of the tree is directly proportional to the search performance, it is possible to rapidly search a tree with millions of networks while only examining a relatively small number of the nodes.

Wide Network Tree

Performance

Performance will vary based on many factors. On an older AMD Ryzen 5 1600X single thread lookup speed of a tree with one million networks is 1.25 million lookups per second. As a point of reference, a Dictionary used for exact matches is about to do around 10 million lookups per second.

Thread Safety

The standard NetworkLookup class is lock free and thread safe for multiple-readers, and a single writer. A ConcurrentNetworkLookup class is provided that implements locks on write operations and should be used where there are concurrent writers.

MAC Address

A MAC address is a globally unique identifier assigned to Ethernet devices that consists of a bit to indicate if it is locally administrated, a bit to indicate if it is a multicast address, a manufacture identifier, and an extension identifier or serial number.

var macAddress1 = MacAddress.Parse("dead:beef:abcd");
var macAddress2 = MacAddress.Parse("dead.beef.abcd");
var macAddress3 = MacAddress.Parse("de.ad.be.ef.ab.cd");
var macAddress4 = MacAddress.Parse("de:ad:be:ef:ab:cd");
var macAddress5 = MacAddress.Parse("deadbeefabcd");

OUI Database

The first three octets of a MAC address are assigned by the IEEE. The registration data is public and can be looked up for a given MAC address. The manufacture can often give clues as to what the device is.

// Create a new OuiDatabase using the defaults
// The default options will use last downloaded database if it exists, and fallback to an internal database if it does not exist. 
// An asynchronous background update check is triggered upon object creation that will update the database every 30 days.
var ouiDatabase = new OuiDatabase();

var ouiRecord = ouiDatabase["64:D1:A3:01:02:03"];
var organization = ouiRecord.Organization;
var address = ouiRecord.Address;
var prefix = ouiRecord.Prefix;

Options

var options = new OuiDatabaseOptions()
{
    // Automatically preform background updates. Defaults to true
    // UpdateDatabase() can be used to manually trigger a database update.
    AutomaticUpdates = true,

    // Where to store the downloaded database. Defaults to %LOCALAPPDATA%\NetworkAddressing
    CacheDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "NetworkAddressing"),

    // How offten to check if an update should be triggered. Defaults to once an hour.
    CheckInterval = TimeSpan.FromHours(1),

    // Where to download the OUI database from. Defaults to https://standards-oui.ieee.org/
    Location = new("https://standards-oui.ieee.org/"),

    // How old the downloaded database can be before downloading a new version. Defaults to 30 days.
    RefreshInterval = TimeSpan.FromDays(30),

    // If the initial database update that is triggered on object creation should block.  Defaults to false.
    // If set to false the last downloaded database or an internal database is initially used and a background update check is triggered.
    // If set to true the object creation is blocked while an update check is triggered.
    SynchronousUpdate = false,

    // If SynchronousUpdate both ThrowOnUpdateFailure are set to true and the initial database update fails
    // then throw an exception and prevent the object from being created.
    // defaults to false
    ThrowOnUpdateFailure = false,
};

// Events can be generated for update events, which can be logged.
options.DatabaseEvent += OptionsOnDatabaseEvent;

var ouiDatabase = new OuiDatabase(options);

Overhead

There is a fair amount of overhead for each OuiDatabase instance and it is best to reuse a single instance or use the OuiDatabase.Instance property. The OuiDatabase.Instance property returns an instance of OuiDatabase using the default options and is suitable for most purposes.

var ouiDatabase = OuiDatabase.Instance;

var ouiRecord = ouiDatabase["64:D1:A3:01:02:03"];
var organization = ouiRecord.Organization;
var address = ouiRecord.Address;
var prefix = ouiRecord.Prefix;
Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net7.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.3 556 11/30/2023
1.0.2 421 3/5/2023
1.0.1 258 3/3/2023
1.0.0.1 257 2/21/2023
1.0.0 258 2/21/2023