Get Interface Golang Part 2

Wanted to share a few updates and tweaks to the original Get Interface name by hardware address code. The below is broken up in to functions to help with code re-useability .

If also prints all interface names and hardware address when no command line argument are present.

package main

import (
    "net"
    "fmt"
    "os"
    "strings"
)

// Use the net library to return all Interfaces
// and capture any errors.
func getInterfaces() ([]net.Interface) {
    interfaces, err := net.Interfaces()
    if err != nil {
        panic("Unable to get interfaces.")
    }
    return interfaces
}

// Use the net library to get Interface by Index number
// and capture any errors.
func getInterfaceByIndex(index int) (*net.Interface) {
    inter, err := net.InterfaceByIndex(index)
    if err != nil {
        panic("Unable to get interface by index")
    }
    return inter
}

// Use the net library to get Interface by Name
// and capture any errors
func getInterfaceByName(name string) (*net.Interface) {
    inter, err := net.InterfaceByName(name)
    if err != nil {
        panic("Unable to get interface by name")
    }
    return inter
}

// Using the net library we will loop over all interfaces
// looking for the interface with matching mac_address.
func getInterfaceByHardwareAddress(mac string) (net.Interface) {
    interfaces := getInterfaces()
    for _, inter := range interfaces {
        if strings.ToUpper(mac) == strings.ToUpper(inter.HardwareAddr.String()) {
            return inter
        }
    }
    panic("Unable to find interface with Hardware Address.")
}

func main() {

    args := os.Args
    // If we have only 2 arguments we will assume the
    // second is mac_address.
    if len(args) == 2 {
        mac_address := args[1]
        inter := getInterfaceByHardwareAddress(mac_address)
        fmt.Println(inter.Name)

    // If no arguments were passed in lets just return
    // a list of all interface names and hardware addresses.
    } else if len(args) == 1 {
        for _, inter := range getInterfaces() {
            fmt.Println(inter.Name, inter.HardwareAddr)
        }

    // If the number of command line arguments are not expected
    // lets panic and explain why.
    } else {
        panic("We require one (mac_address) or no command line arguments.")
    }

}

Usage looks something like this:

$ go build get_interface.go

$ ./get_interface
lo
en0 12:34:56:68:90:00

$ ./get_interface 12:34:56:68:90:00
en0

Get Interface name by hardware address

At work we have had a need for getting a interface name by mac address and are in a
environment that doesn’t have many common Linux tools (nor would I want to regex it as the
environment will constantly be changing).

My first solution was to to write a C program (about 125 lines) which used the linux/rtnetlink
library. However, now that I’m looking at Golang I figured why not rewrite this (which is only about 40 lines).

Below is the code, hopefully the comments explain the solution.

package main

import (
	"net"
	"fmt"
	"os"
)

func main() {

	// First lets check our command line arguments and be sure we
	// have a single input value which we will assume is mac_address.
	args := os.Args
	if len(args) != 2 {
		panic("This binary takes a single argument of interface name.")
	}

	// Get a list of all interfaces on the machine.
	interfaces, err := net.Interfaces()
	if err != nil {
		panic("Unable to get interfaces.")
	}

	// Loop over all interfaces
	for i := range interfaces {

		// Get the interfaces Index and then load
		// the interface by Index.
		id := interfaces[i].Index
		inter, err := net.InterfaceByIndex(id)

		if err != nil {
			panic("Unable to get interface by id")
		}

		// If our command line input matches our HardwareAddr
		// this is the MAC_ADDRESS you seek.
		if args[1] == inter.HardwareAddr.String() {
			fmt.Println(inter.Name)
		}
	}
}

And the code works something like this:

$ ./get_interface 12:34:56:78:90:00
en4

Zombie Dice

Was able to pull out a victory last night against my two boys in Zombie Dice with some help from a little Homebrew.

zombie_dice

If you don’t know what Zombie Dice is, you should have a look at the Tabletop Video.

It is a very inexpensive travel sized gamed, which is easy for younger players, and very exciting!