MAC Vendor Lookup

From Rosetta Code
Task
MAC Vendor Lookup
You are encouraged to solve this task according to the task description, using any language you may know.

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.

Basic Task

The task is to 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". A error related to the network connectivity or the API should return a null result.

AutoHotkey[edit]

macLookup(MAC){
WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WebRequest.Open("GET", "http://api.macvendors.com/" MAC)
WebRequest.Send()
return WebRequest.ResponseText
}
Examples:
MsgBox % macLookup("00-14-22-01-23-45")
Outputs:
Dell Inc.

C#[edit]

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
 
class Program
{
static async Task<string> LookupMac(string MacAddress)
{
var uri = new Uri("http://api.macvendors.com/" + WebUtility.UrlEncode(MacAddress));
using (var wc = new HttpClient())
return await wc.GetStringAsync(uri);
}
static void Main(string[] args)
{
foreach (var mac in new string[] { "88:53:2E:67:07:BE", "FC:FB:FB:01:FA:21", "D4:F4:6F:C9:EF:8D" })
Console.WriteLine(mac + "\t" + LookupMac(mac).Result);
Console.ReadLine();
}
}
Output:
88:53:2E:67:07:BE       Intel Corporate
FC:FB:FB:01:FA:21       Cisco Systems, Inc
D4:F4:6F:C9:EF:8D       Apple, Inc.

Go[edit]

package main
 
import (
"net/http"
"fmt"
"io/ioutil"
)
 
func macLookUp(mac string) (res string){
resp, _ := http.Get("http://api.macvendors.com/" + mac)
body, _ := ioutil.ReadAll(resp.Body)
res = string(body)
return
}
 
func main() {
fmt.Println(macLookUp("FC-A1-3E"))
fmt.Println(macLookUp("FC:FB:FB:01:FA:21"))
fmt.Println(macLookUp("BC:5F:F4"))
}
 
Output:
Samsung Electronics Co.,Ltd
Cisco Systems, Inc
ASRock Incorporation


J[edit]

Solution

require 'web/gethttp'
lookupMACvendor=: [: gethttp 'http://api.macvendors.com/'&,

Example Usage

   addr=: '88:53:2E:67:07:BE';'FC:FB:FB:01:FA:21';'D4:F4:6F:C9:EF:8D';'23:45:67'
(,&' ' , lookupMACvendor)&> addr
88:53:2E:67:07:BE Intel Corporate
FC:FB:FB:01:FA:21 Cisco Systems, Inc
D4:F4:6F:C9:EF:8D Apple, Inc.
23:45:67 Vendor not found

Java[edit]

package com.jamesdonnell.MACVendor;
 
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
 
/** MAC Vendor Lookup class.
* www.JamesDonnell.com
* @author James A. Donnell Jr. */

public class Lookup {
/** Base URL for API. The API from www.macvendors.com was chosen. */
private static final String baseURL = "http://api.macvendors.com/";
 
/** Performs lookup on MAC address(es) supplied in arguments.
* @param args MAC address(es) to lookup. */

public static void main(String[] args) {
for (String arguments : args)
System.out.println(arguments + ": " + get(arguments));
}
 
/** Performs lookup on supplied MAC address.
* @param macAddress MAC address to lookup.
* @return Manufacturer of MAC address. */

private static String get(String macAddress) {
try {
StringBuilder result = new StringBuilder();
URL url = new URL(baseURL + macAddress);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
return result.toString();
} catch (FileNotFoundException e) {
// MAC not found
return "N/A";
} catch (IOException e) {
// Error during lookup, either network or API.
return null;
}
}
}

Kotlin[edit]

// version 1.1.2
 
import java.net.URL
 
fun lookupVendor(mac: String) = URL("http://api.macvendors.com/" + mac).readText()
 
fun main(args: Array<String>) {
val macs = arrayOf("FC-A1-3E", "FC:FB:FB:01:FA:21", "88:53:2E:67:07:BE", "D4:F4:6F:C9:EF:8D")
for (mac in macs) println(lookupVendor(mac))
}
Output:
Samsung Electronics Co.,Ltd
Cisco Systems, Inc
Intel Corporate
Apple, Inc.

Lua[edit]

-- Requires LuaSocket extension by Lua
-- Created by James A. Donnell Jr.
-- www.JamesDonnell.com
 
local baseURL = "http://api.macvendors.com/"
 
local function lookup(macAddress)
http = require "socket.http"
result, statuscode, content = http.request(baseURL .. macAddress)
return result
end
 
local macAddress = "FC-A1-3E-2A-1C-33"
print(lookup(macAddress))


Nim[edit]

import httpclient
 
proc maclookup(mac: string): string =
var client = newHttpClient()
var site = "http://api.macvendors.com/"
site.add(mac)
return client.getContent(site)
 
echo maclookup("FC-A1-3E")
echo maclookup("FC:FB:FB:01:FA:21")
echo maclookup("BC:5F:F4")
Output:
Samsung Electronics Co.,Ltd
Cisco Systems, Inc
ASRock Incorporation

Perl[edit]

#!/usr/bin/env perl -T
use 5.018_002;
use warnings;
use LWP;
 
our $VERSION = 1.000_000;
 
my $ua = LWP::UserAgent->new;
 
my @macs = (
'FC-A1-3EFC:FB:FB:01:FA:21', '00,0d,4b',
'Rhubarb', '00-14-22-01-23-45',
'10:dd:b1', 'D4:F4:6F:C9:EF:8D',
'FC-A1-3E', '88:53:2E:67:07:BE',
'23:45:67', 'FC:FB:FB:01:FA:21',
'BC:5F:F4',
);
 
for my $mac (@macs) {
my $vendor = get_mac_vendor($mac);
if ($vendor) {
say "$mac = $vendor";
}
}
 
sub get_mac_vendor {
my $s = shift;
 
my $req = HTTP::Request->new( GET => "http://api.macvendors.com/$s" );
my $res = $ua->request($req);
 
# A error related to the network connectivity or the API should
# return a null result.
if ( $res->is_error ) {
return;
}
 
# A MAC address that does not return a valid result should
# return the String "N/A".
if ( !$res->content
or $res->content eq 'Vendor not found' )
{
return 'N/A';
}
 
return $res->content;
}
 
# IEEE 802:
# Six groups of two hexadecimal digits separated by hyphens or colons,
# like 01-23-45-67-89-ab or 01:23:45:67:89:ab
# Three groups of four hexadecimal digits separated by dots (.),
# like 0123.4567.89ab
#sub validmac {
# my $s = shift;
#
# my $hex = qr{ [A-Fa-f[:digit:]] }xms;
# my $hex2ws = qr{ [-:] $hex{2} }xms;
#
# if ( $s =~ m{\A $hex{2} $hex2ws{5} \z}xms
# or $s =~ m{\A $hex{4} [.] $hex{4} [.] $hex{4} \z}xms )
# {
# return 'true';
# }
# return;
#}
Output:
FC-A1-3EFC:FB:FB:01:FA:21 = Samsung Electronics Co.,Ltd
00,0d,4b = Roku, Inc.
00-14-22-01-23-45 = Dell Inc.
10:dd:b1 = Apple, Inc.
D4:F4:6F:C9:EF:8D = Apple, Inc.
FC-A1-3E = Samsung Electronics Co.,Ltd
88:53:2E:67:07:BE = Intel Corporate
FC:FB:FB:01:FA:21 = Cisco Systems, Inc
BC:5F:F4 = ASRock Incorporation

Perl 6[edit]

Works with: Rakudo version 2016.12
use HTTP::UserAgent;
 
my $ua = HTTP::UserAgent.new;
 
$ua.timeout = 10; # seconds
 
my $server = 'http://api.macvendors.com/';
 
sub lookup ($mac) {
my $response = $ua.get: "$server+$mac";
 
return $response.is-success ?? $response.content !! 'N/A';
 
CATCH { # Normally you would report some information about what
default { Nil } # went wrong, but the task specifies to ignore errors.
}
}
 
for <
BC:5F:F4
FC-A1-3E
10:dd:b1
00,0d,4b
23:45:67
> -> $mac { say lookup $mac }
Output:
ASRock Incorporation
Samsung Electronics Co.,Ltd
Apple, Inc.
Roku, Inc.
N/A

PicoLisp[edit]

(load "@lib/http.l")
 
(de maclookup (M)
(client "api.macvendors.com" 80
M
(while (line))
(line T) ) )
(test
"Intel Corporate"
(maclookup "88:53:2E:67:07:BE") )
(test
"Apple, Inc."
(maclookup "D4:F4:6F:C9:EF:8D") )

Python[edit]

import requests
 
for addr in ['88:53:2E:67:07:BE', 'FC:FB:FB:01:FA:21',
'D4:F4:6F:C9:EF:8D', '23:45:67']:
vendor = requests.get('http://api.macvendors.com/' + addr).text
print(addr, vendor)
Output:
88:53:2E:67:07:BE Intel Corporate
FC:FB:FB:01:FA:21 Cisco Systems, Inc
D4:F4:6F:C9:EF:8D Apple, Inc.
23:45:67 Vendor not found

Racket[edit]

#lang racket
 
(require net/url)
 
(define (lookup-MAC-address addr)
(port->string
(get-pure-port
(url "http" #f "api.macvendors.com" #f #t (list (path/param addr null)) null #f))))
 
(module+ test
(for ((i (in-list '("88:53:2E:67:07:BE"
"FC:FB:FB:01:FA:21"
"D4:F4:6F:C9:EF:8D"))))
(printf "~a\t~a~%" i (lookup-MAC-address i))))
Output:
88:53:2E:67:07:BE	Intel Corporate
FC:FB:FB:01:FA:21	Cisco Systems, Inc
D4:F4:6F:C9:EF:8D	Apple, Inc.

Ruby[edit]

require 'net/http'
 
arr = ['88:53:2E:67:07:BE', 'FC:FB:FB:01:FA:21', 'D4:F4:6F:C9:EF:8D', '23:45:67']
 
arr.each do |addr|
vendor = Net::HTTP.get('api.macvendors.com', "/#{addr}/") rescue nil
puts "#{addr} #{vendor}"
end
Output:
88:53:2E:67:07:BE  Intel Corporate
FC:FB:FB:01:FA:21  Cisco Systems, Inc
D4:F4:6F:C9:EF:8D  Apple, Inc.
23:45:67  Vendor not found

Tcl[edit]

package require http
 
# finally is a bit like go's defer
proc finally args {
tailcall trace add variable :#finally#: unset [list apply [list args $args]]
}
 
# basic wrapper for http::geturl
proc geturl {url} {
set tok [::http::geturl $url]
finally ::http::cleanup $tok
 ::http::data $tok
}
proc maclookup {mac} {
geturl http://api.macvendors.com/$mac
}
 
foreach mac {00-14-22-01-23-45 88:53:2E:67:07:BE} {
puts "$mac\t[maclookup $mac]"
}
Output:
00-14-22-01-23-45       Dell Inc.
88:53:2E:67:07:BE       Intel Corporate

zkl[edit]

Translation of: Lua

Uses libcurl (the multiprotocol file transfer library) to do the web query

var [const] CURL=Import("zklCurl");   // libcurl
const MAC_VENDORS="http://api.macvendors.com/";
 
fcn lookUp(macAddress){
httpAddr:=MAC_VENDORS + macAddress;
vender:=CURL().get(httpAddr); //-->(Data,bytes of header,bytes of trailer)
vender=vender[0].del(0,vender[1]); // remove HTTP header
vender.text; // Data --> String (Data is a byte bucket)
}
lookUp("FC-A1-3E-2A-1C-33").println();
lookUp("4c:72:b9:56:fe:bc").println();
lookUp("foobar").println();
Output:
Samsung Electronics Co.,Ltd
PEGATRON CORPORATION
Vendor not found