When building backend services, API gateways, or DevOps infrastructure tools, you often need to target a specific network adapter by name (such as eth0, wlan0, docker0, or tun0) rather than iterating through every interface on the host.

Go's standard net package provides the net.InterfaceByName() function to query an individual network card directly. In this tutorial, we construct a production-ready CLI utility in Go to fetch MAC addresses, MTU limits, status flags, and bound IP subnets for any given interface name.

Quick Reference: net.InterfaceByName Usage

Here is the direct API call to fetch a network interface by its adapter name in Go:

quick_reference.gogo
package main
 
import (
	"fmt"
	"log"
	"net"
)
 
func main() {
	// Look up specific network interface by name
	iface, err := net.InterfaceByName("wlan0")
	if err != nil {
		log.Fatalf("Failed to find interface: %v", err)
	}
 
	fmt.Printf("Interface Name: %s
", iface.Name)
	fmt.Printf("MAC Address   : %s
", iface.HardwareAddr)
	fmt.Printf("MTU           : %d bytes
", iface.MTU)
}

1. Production Go Interface Inspector (main.go)

This Go program takes an interface name from CLI arguments (or defaults to wlan0), verifies its existence, inspects hardware flags, and formats IPv4/IPv6 addresses:

main.gogo
package main
 
import (
	"fmt"
	"log"
	"net"
	"os"
)
 
func calculateBroadcast(ipNet *net.IPNet) net.IP {
	ip := ipNet.IP.To4()
	if ip == nil {
		return nil
	}
	mask := ipNet.Mask
	broadcast := make(net.IP, len(ip))
	for i := 0; i < len(ip); i++ {
		broadcast[i] = ip[i] | ^mask[i]
	}
	return broadcast
}
 
func inspectInterface(ifaceName string) {
	// 1. Fetch interface by target name
	iface, err := net.InterfaceByName(ifaceName)
	if err != nil {
		log.Fatalf("Error: Network interface '%s' not found: %v", ifaceName, err)
	}
 
	fmt.Println("=========================================================")
	fmt.Printf("          DETAILS FOR INTERFACE: %s                      
", iface.Name)
	fmt.Println("=========================================================")
	fmt.Printf("Index ID        : %d
", iface.Index)
	
	mac := iface.HardwareAddr.String()
	if mac == "" {
		mac = "N/A (Virtual / Loopback)"
	}
	fmt.Printf("MAC Address     : %s
", mac)
	fmt.Printf("MTU Size        : %d bytes
", iface.MTU)
	fmt.Printf("Flags           : %v
", iface.Flags)
 
	// Evaluate status flags
	isUp := (iface.Flags & net.FlagUp) != 0
	isLoopback := (iface.Flags & net.FlagLoopback) != 0
	fmt.Printf("Operational     : Up=%t, Loopback=%t
", isUp, isLoopback)
 
	// 2. Query bound network addresses
	addrs, err := iface.Addrs()
	if err != nil {
		log.Fatalf("Failed to fetch addresses for %s: %v", iface.Name, err)
	}
 
	fmt.Println("
Bound IP Addresses:")
	if len(addrs) == 0 {
		fmt.Println("  (No IP addresses assigned)")
		return
	}
 
	for _, addr := range addrs {
		if ipNet, ok := addr.(*net.IPNet); ok {
			if ip4 := ipNet.IP.To4(); ip4 != nil {
				broadcast := calculateBroadcast(ipNet)
				fmt.Printf("  - IPv4      : %s
", ip4.String())
				fmt.Printf("    Subnet    : %s
", ipNet.Mask.String())
				fmt.Printf("    CIDR      : %s
", ipNet.String())
				if broadcast != nil {
					fmt.Printf("    Broadcast : %s
", broadcast.String())
				}
			} else if ip6 := ipNet.IP.To16(); ip6 != nil {
				fmt.Printf("  - IPv6      : %s
", ip6.String())
			}
		}
	}
}
 
func main() {
	targetIface := "wlan0"
	if len(os.Args) > 1 {
		targetIface = os.Args[1]
	}
	inspectInterface(targetIface)
}

2. Running the Command Line Utility

Pass any active network interface name (wlan0, eth0, lo, docker0) as an argument:

Terminal Executionbash
# Inspect wlan0 interface
$ go run main.go wlan0
 
=========================================================
          DETAILS FOR INTERFACE: wlan0                      
=========================================================
Index ID        : 3
MAC Address     : ac:fd:ce:81:49:b2
MTU Size        : 1500 bytes
Flags           : up|broadcast|multicast
Operational     : Up=true, Loopback=false
 
Bound IP Addresses:
  - IPv4      : 192.168.1.105
    Subnet    : ffffff00
    CIDR      : 192.168.1.105/24
    Broadcast : 192.168.1.255
  - IPv6      : fe80::8802:11fb:12a8:442c

Broadcast Address Calculation Math

  • Bitwise OR with Inverted Mask: The IPv4 broadcast address is calculated by taking the 4-byte IP address slice and applying a bitwise OR (|) with the bitwise NOT (^) of the subnet mask: broadcast[i] = ip[i] | ^mask[i].

  • CIDR Subnet Masking: A /24 subnet has a mask of 255.255.255.0 (0xffffff00). Inverting the mask yields 0.0.0.255, which sets all host bits to 1.