Every connected device around the world comes with a unique Media Access Control address, or a   MAC address.

A common task a network administrator may come across is being able to identify a network device's manufacturer when given only a MAC address.



Task

Interface with one (or numerous) APIs that exist on the internet and retrieve the device manufacturer based on a supplied MAC address.

A MAC address that does not return a valid result should return the String "N/A".   An error related to the network connectivity or the API should return a null result.

Many implementations on this page use http://api.macvendors.com/ which, as of 19th September 2021, is throttling requests. After only 2 calls, the following response is returned for all subsequent requests. If you are planning to use the same provider or going to run the examples on this page, consider building in a delay between two calls.

{"errors":{"detail":"Too Many Requests","message":"Please slow down your requests or upgrade your plan at https://macvendors.com"}}

extern crate reqwest;
 
use std::{thread, time};
 
fn get_vendor(mac: &str) -> Option<String> {
    let mut url = String::from("http://api.macvendors.com/");
    url.push_str(mac);
    let url_ref = &url;
    match reqwest::get(url_ref) {
        Ok(mut res) => match res.text() {
            Ok(text) => {
                if text.contains("Not Found") {
                    Some("N/A".to_string())
                } else {
                    Some(text)
                }
            }
            Err(e) => {
                println!("{:?}", e);
                None
            }
        },
        Err(e) => {
            println!("{:?}", e);
            None
        }
    }
}
 
fn main() {
    let duration = time::Duration::from_millis(1000);
    match get_vendor("88:53:2E:67:07:BE") {
        None => println!("Error!"),
        Some(text) => println!("{}", text),
    }
    thread::sleep(duration);
    match get_vendor("FC:FB:FB:01:FA:21") {
        None => println!("Error!"),
        Some(text) => println!("{}", text),
    }
    thread::sleep(duration);
    match get_vendor("FC-A1-3E") {
        None => println!("Error!"),
        Some(text) => println!("{}", text),
    }
    thread::sleep(duration);
    match get_vendor("abcdefg") {
        None => println!("Error!"),
        Some(text) => println!("{}", text),
    }
}
 