C# / .NET library
macadress.com for C#.
A typed .NET client for the MAC address and OUI vendor lookup API: vendor name, IEEE block, country, address type, EUI-64 / IPv6 derivation, randomization confidence and a device guess. CancellationToken on every call, targets netstandard2.0.
netstandard2.0 (.NET Framework 4.6.1+, .NET Core 2+, .NET 5+), MIT licensed, one dependency (System.Text.Json). Source at github.com/sapisos/macadress-csharp.
Install
dotnet add package Macadress
Look up a vendor
The name-only lookup needs no API key:
using Macadress;
var mac = new MacadressClient(); // keyless
await mac.VendorAsync("00:03:93:AB:12:34"); // "Apple, Inc."
await mac.VendorAsync("02:1a:2b:3c:4d:5e"); // "" (unregistered, private, or randomized)
Full analysis
Everything else needs a free API key:
var mac = new MacadressClient("mk_live_xxx");
var r = await mac.LookupAsync("3C:22:FB:12:34:56");
r.Organization; // string?
r.Country; // "US"
r.BlockType; // BlockType.MAL
r.PotentiallyRandomized; // bool
r.RandomizationConfidence; // RandomizationConfidence.None | Possible | Likely
r.Eui64; // "3E:22:FB:FF:FE:12:34:56"
r.Device.Category; // DeviceCategory.Unknown (usually)
r.Explanation; // plain-English summary
// anything not covered by a property is still reachable
r.TryGet("vendor_location.city", out var city); // (bool, JsonElement)
r.Raw; // JsonElement
Batch and directory search
var items = await mac.BatchAsync(new[] { "00:03:93:00:00:00", "3C:22:FB:00:00:00", "bad" });
foreach (var it in items)
{
Console.WriteLine(it.Failed ? $"{it.Input} -> {it.Error}" : $"{it.Input} -> {it.Organization}");
}
var hits = await mac.SearchVendorsAsync("Cisco", country: "US", limit: 20);
foreach (var b in hits.Blocks)
{
Console.WriteLine($"{b.Organization} ({b.Country})");
}
BatchAsync throws ArgumentException without making a request if the list is empty or longer than MacadressClient.MaxBatchSize (100).
Errors
API error responses come back as ApiException (with StatusCode, Message, RequestId, RetryAfter and the decoded Body); a failure to reach the API at all is a MacadressTransportException. The common cases are distinguished by ApiException.Kind: ApiErrorKind.InvalidMac (400), ApiErrorKind.Auth (401), ApiErrorKind.RateLimited (429), ApiErrorKind.Quota (429).
try
{
var r = await mac.LookupAsync(input);
}
catch (ApiException ex) when (ex.Kind == ApiErrorKind.RateLimited)
{
await Task.Delay(ex.RetryAfter ?? TimeSpan.FromSeconds(1));
}
catch (ApiException ex) when (ex.Kind == ApiErrorKind.InvalidMac)
{
// caller mistake, never billed
}
Concurrency and configuration
A MacadressClient is safe for concurrent use. Configure it with MacadressClientOptions: BaseUrl (for a self-hosted deployment), HttpClient, Timeout, UserAgent. Cancellation flows through the CancellationToken you pass to each call.
Quota
Each LookupAsync, BatchAsync address, and SearchVendorsAsync call is one API call against your plan, the same as a direct REST call: see pricing. The keyless VendorAsync endpoint is free for 1,000 lookups a day per IP; passing a key lifts that to your plan quota.
Links
- NuGet package: nuget.org/packages/Macadress
- Source and issues: github.com/sapisos/macadress-csharp
- API reference: macadress.com/docs