Git Product home page Git Product logo

eui48's Introduction

Crates.io docs.rs Build Status Build Status Build Status Coverage Status

eui48

A Rust library to represent and parse IEEE EUI-48 also known as MAC-48 media access control addresses. The IEEE claims trademarks on the names EUI-48 and EUI-64, in which EUI is an abbreviation for Extended Unique Identifier.

Usage

Add this to your Cargo.toml:

[dependencies]

eui48 = "1.0.1"

and this to your crate root:

extern crate eui48;

Examples

To create a new MAC address and print it out in canonical form:

extern crate eui48;
use eui48::{MacAddress, Eui48};

fn main() {
	let eui: Eui48 = [ 0x12, 0x34, 0x56, 0xAB, 0xCD, 0xEF ];
	let mac = MacAddress::new( eui );

	println!("{}", mac.to_canonical());
	println!("{}", mac.to_hex_string());
	println!("{}", mac.to_dot_string());
	println!("{}", mac.to_hexadecimal());
	println!("{}", mac.to_interfaceid());
	println!("{}", mac.to_link_local());

	let mac = MacAddress::parse_str( "01-02-03-0A-0b-0f" ).expect("Parse error {}");
	let mac = MacAddress::parse_str( "01:02:03:0A:0b:0f" ).expect("Parse error {}");
	let mac = MacAddress::parse_str( "0102.030A.0b0f" ).expect("Parse error {}");
	let mac = MacAddress::parse_str( "0x1234567890ab" ).expect("Parse error {}");
}

Notes

  • The default display format is cannonical form 01-02-03-04-05-06 unless a compile time feature disp_hexstring is enabled, then the default format is of the form 01:02:03:04:05:06.

Version 1.0.0 and above allows a more flexible parsing of MAC address strings, compliments of Stan Drozd:

  • Enables the library's caller to parse the MACs that don't follow fixed-length MAC address convention (I'm looking at you, ebtables!). In general, the parsing function tries harder to interpret a given string than before.
  • Rewrite parse_str to use a regex and be more lenient (now it permits one-off string chopping errors and mixed delimiters are accepted as long as we manage to read 6 bytes)
  • Exchange the InvalidCharacter error enum value for InvalidByteCount - InvalidCharacter is no longer supported. See versions >=0.5.0 and < 1.0.0 if you need legacy behavior.

Serialization

When using serde to serialize a MAC address the address is stored as a formatted string. This fits well for text-based protocols like JSON but creates overhead for binary serialization. The overhead gets even bigger when the string is deserialized again, as a full-grown parser is needed instead of reading raw bytes. To reduce this overhead use the serde_bytes feature when serializing and deserializing MAC addresses to binary protocols.

NOTE: serde_bytes and serde_json are mutually exclusive!

References

Wikipedia: MAC address

Authors

  • 0.1 Andrew Baumhauer - Initial design
  • 0.2 rlcomstock3 - Added support for btree keys
  • 0.3 Michal 'vorner' Vaner [email protected] - Serde 1.0 support
  • 0.3.1 Michal 'vorner' Vaner [email protected] - Derive useful traits
  • 0.4.0 Rainer Stademann - Define ABI as repr(C)
  • 0.4.1 Andrew Baumhauer - Add IPv6 Interface ID and Link Local conversions
  • 0.4.2 Andrew Baumhauer / Eric Clone - Bug fix in is_local() and is_unicast() functions
  • 0.4.3 Andrew Baumhauer - Update travis-ci, appveyor, codecov
  • 0.4.4 Andrew Baumhauer - Update documentation
  • 0.4.5 Andrew Baumhauer - Improve code coverage and tests
  • 0.4.6 Jiwoong Lee - Add to_array() for compatibility, add feature disp_hexstring
  • 0.4.7 Adam Reichold - WASM updates
  • 0.4.8 @kamek-pf - respect disp_hexstring flag
  • 0.4.9 Sebastian Dietze - New const added
  • 0.5.0 Andrew Baumhauer - cleanup, update versions, fmt, merge PRs, update unit tests
  • 0.5.1 jrb0001 - Fixed incorrect IPv6 to_link_local for Link-Scoped Unicast
  • 1.0.0 Stan Drozd, @rlcomstock3, and Andrew Baumhauer - merged all forks and improvements back to this repo
  • 1.0.1 jrb0001 - Fixed incorrect IPv6 to_link_local for Link-Scoped Unicast
  • 1.1.0 Felix Schreiner - binary serialization optimization

eui48's People

Contributors

abaumhauer avatar drozdziak1 avatar ericclone avatar felix-rhebo avatar jtremback avatar kamek-pf avatar nicholasbishop avatar porcevader avatar rstade avatar spanfile avatar vorner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

eui48's Issues

Feature Request std::cmp::Ord trait

Could the eui48::MacAddress implement std::cap::Ord? I am happy to try to help if needed. I am just learning rust, so I may not be a lot of help. But am happy to try.

Use is_human_readable methods with serde

Currently, a cargo feature controls whether a MAC is (de)serialized as a formatted string or in binary. Since cargo features are resolved once for every dependency tree, it is impossible to use this crate for both formats in the same application, even through different crates (no direct dependency). serde has a helper method for determining whether the format should use a text or binary representation where both are possible, you should probably use that instead:

Big binary size

I have this code:

fn main() {
    eui48::MacAddress::parse_str("00:11:22:33:44:55").unwrap();
}

When I compile with eui48's master branch and release profile, I get a binary of 1.4mb:

oblique@dystopia /~tmp/eui48-example
% cargo build --release
   Compiling memchr v2.4.1
   Compiling regex-syntax v0.6.25
   Compiling rustc-serialize v0.3.24
   Compiling aho-corasick v0.7.18
   Compiling regex v1.5.4
   Compiling eui48 v1.1.0 (/home/oblique/git/eui48)
   Compiling eui48-example v0.1.0 (/tmp/eui48-example)
    Finished release [optimized] target(s) in 17.78s

oblique@dystopia /tmp/eui48-example
% strip target/release/eui48-example

oblique@dystopia /tmp/eui48-example
% du -h target/release/eui48-example
1.4M	target/release/eui48-example

I noticed that you do not use any unicode features of regex, so I changed regex dependency of eui48's Cargo.toml to:

regex = { version = "1.3.9", default-features = false, features=["std"], optional = false }

and then I got a binary of 604kb:

oblique@dystopia /tmp/eui48-example
% cargo build --release
   Compiling regex-syntax v0.6.25
   Compiling regex v1.5.4
   Compiling eui48 v1.1.0 (/home/oblique/git/eui48)
   Compiling eui48-example v0.1.0 (/tmp/eui48-example)
    Finished release [optimized] target(s) in 8.42s

oblique@dystopia /tmp/eui48-example
% strip target/release/eui48-example

oblique@dystopia /tmp/eui48-example
% du -h target/release/eui48-example
604K	target/release/eui48-example

I decided to write the parsing manually and I got a binary of 264kb:

oblique@dystopia /tmp/eui48-example
% cargo build --release
   Compiling eui48 v1.1.0 (/home/oblique/git/eui48)
   Compiling eui48-example v0.1.0 (/tmp/eui48-example)
    Finished release [optimized] target(s) in 0.55s

oblique@dystopia /tmp/eui48-example
% strip target/release/eui48-example

oblique@dystopia /tmp/eui48-example
% du -h target/release/eui48-example
264K	target/release/eui48-example

Also in the latest case, compilation time is under a second.

Maintenance status ?

Hey there,
First, thanks for this library, we use it at work in a bunch of places!

I noticed several PRs are pending and the crate hasn't been updated in a while.

Would you be interested in introducing additional maintainers ? I'd be glad to help!

Compile time feature to use MacAddressFormat::HexString

A canonical display format of MacAddress, which uses '-' separator, is losing its popular adoption in industry uses. Instead HexString format, which uses ':' separator is more widely used.

This issue is to propose to add a conditional compiler feature, "disp_hexstring". This feature enforces the Display format to use HexString, as used in Debug, and eliminates a burden to explicitly specify the format type in every display case.

Export to Eui48 array

Some existing modules have been already written to use [u8; 6] as a storage type to store an EUI48 style Mac addresses, and their APIs are defined to be so.

Importing their data to eui48::MacAddress is feasible via MacAddress::new(), but exporting eui48::MacAddress to [u8; 6] is not directly feasible, but would require separate implementation.

This issue is to propose to implement pub fn MacAddress::to_array(&self) -> Eui48 {}, which works as an inverse function of ::new().

Index out of range panic when displaying ParseError::InvalidByteCount

The following code panics:

fn main() {
    println!("{}", eui48::MacAddress::parse_str("123456ABCDEF1").unwrap_err());
}
ohazi@avocado:~/source/eui48_index_out_of_range$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/eui48_index_out_of_range`
thread 'main' panicked at /home/ohazi/.cargo/registry/src/index.crates.io-6f17d22bba15001f/eui48-1.1.0/src/lib.rs:300:21:
range end index 7 out of range for slice of length 6
stack backtrace:
   0: rust_begin_unwind
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:645:5
   1: core::panicking::panic_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panicking.rs:72:14
   2: core::slice::index::slice_end_index_len_fail_rt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/slice/index.rs:76:5
   3: core::slice::index::slice_end_index_len_fail
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/slice/index.rs:68:9
   4: <core::ops::range::Range<usize> as core::slice::index::SliceIndex<[T]>>::index
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/slice/index.rs:408:13
   5: <core::ops::range::RangeTo<usize> as core::slice::index::SliceIndex<[T]>>::index
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/slice/index.rs:455:9
   6: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/slice/index.rs:18:9
   7: core::array::<impl core::ops::index::Index<I> for [T; N]>::index
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/array/mod.rs:348:9
   8: <eui48::ParseError as core::fmt::Display>::fmt
             at /home/ohazi/.cargo/registry/src/index.crates.io-6f17d22bba15001f/eui48-1.1.0/src/lib.rs:300:21
   9: core::fmt::rt::Argument::fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/fmt/rt.rs:142:9
  10: core::fmt::write
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/fmt/mod.rs:1120:17
  11: std::io::Write::write_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/io/mod.rs:1762:15
  12: <&std::io::stdio::Stdout as std::io::Write>::write_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/io/stdio.rs:727:9
  13: <std::io::stdio::Stdout as std::io::Write>::write_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/io/stdio.rs:701:9
  14: std::io::stdio::print_to
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/io/stdio.rs:1020:21
  15: std::io::stdio::_print
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/io/stdio.rs:1097:5
  16: eui48_index_out_of_range::main
             at ./src/main.rs:2:5
  17: core::ops::function::FnOnce::call_once
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
ohazi@avocado:~/source/eui48_index_out_of_range$ 

The culprit is this line: https://github.com/abaumhauer/eui48/blob/master/src/lib.rs#L300

In ParseError::InvalidByteCount(found, eui), found is the number of bytes encountered (in this case seven bytes, more than the expected six bytes), and eui is the eui48 that was created out of the first six bytes. You cannot index into eui beyond six, which is what &eui[..found] on line 300 appears to be trying to do.

eui48 into the standard library for rust?

Hi @abaumhauer,

Have you considered creating an RFC (I could assist) to get this work merged into the rust standard library? I find it surprising that std::net only caters for IP addresses, even though anyone doing anything remotely serious with networking would probably also be interested in Mac addresses?

For example, diesel recently added support for Postgres' MAC address data type, but they implemented it as a simple [u8; 6]. Having interoperability between crates by using a standardised type might be quite awesome.

Cheers,

The address parser doesn't do any usefull validation

The mac address parser is way to lenient. It will accept any character as delimiter. It accepts these as input:
c9L3AsB7q12N34r56 => c9:3a:b7:12:34:56
effect affect => ef:fe:0c:af:fe:0c

It is ok to cope with some odd input, but this is like no validation is done at all.

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.