iproute-mac
March 19, 2026 · View on GitHub
A native Go implementation of Linux iproute2 (ip, bridge, ss) for macOS.
Linux-compatible command syntax backed by native macOS system calls — PF_ROUTE socket, ioctl, sysctl, CoreWLAN. No shelling out, no fake behavior.
Features
ip — network configuration
| Command | Description |
|---|---|
ip link show/set | Interfaces — flags, MTU, MAC, up/down, stats |
ip addr show/add/del | IPv4 and IPv6 addresses |
ip route show/add/del/get/replace | Routing table |
ip neigh show/add/del/flush | ARP/NDP neighbor table |
ip tunnel show | Tunnel interfaces — utun, gif, stf |
ip maddr show | Multicast group memberships |
ip monitor | Real-time network events (link, addr, route) |
ip wifi show | Wi-Fi details — channel, RSSI, noise, tx-rate, security |
bridge — bridge configuration
| Command | Description |
|---|---|
bridge link show | Bridge member ports with STP state |
bridge fdb show | Forwarding database entries |
ss — socket statistics
| Command | Description |
|---|---|
ss -t/-u/-x | TCP, UDP, Unix sockets |
ss -l/-a | Listening / all sockets |
ss -p | Show process info |
ss -s | Summary statistics |
ss -n | Numeric (don't resolve service names) |
Output modes
- Linux-compatible text (default) — matches
ipoutput format - macOS native (
--native) —ifconfig/netstat -nrstyle - JSON (
-j) — structured output for scripting - Color (
-c) — Linux iproute2 color palette - Resolve (
-r) — reverse DNS on IPs
Requirements
- macOS (darwin/arm64 or darwin/amd64)
- Go 1.24+
- Root privileges for mutating operations (
link set,addr add/del,route add/del,neigh add/del/flush) - Location Services for Wi-Fi SSID/BSSID (channel, RSSI, tx-rate work without it)
Install
From source
git clone https://github.com/rgcr/iproute-mac.git
cd iproute-mac
make build # → bin/ip, bin/bridge, bin/ss
make install # go install to $GOPATH/bin
Homebrew
brew install rgcr/formulae/iproute-mac
Usage
Commands follow Linux iproute2 syntax. Subcommands can be abbreviated: ip l = ip link, ip r = ip route, ip a = ip addr.
ip link show # list interfaces
ip -s link show en0 # with statistics
ip addr show dev en0 # addresses on en0
ip route show # routing table
ip route get 8.8.8.8 # lookup route
ip neigh show # ARP/NDP table
ip tunnel show # utun, gif, stf
ip maddr show dev en0 # multicast groups
ip monitor route # real-time route events
ip wifi show # Wi-Fi details
bridge link show # bridge member ports
bridge fdb show # forwarding database
ss -tl # TCP listening sockets
ss -u # UDP sockets
ss -p # with process info
ss -s # summary
Output formats
ip -j -p link show # pretty JSON
ip -c link show # colorized
ip --native route show # macOS netstat -nr style
ip -r route get 127.0.0.1 # reverse DNS
Mutating operations (require sudo)
sudo ip link set en0 down
sudo ip addr add 10.0.0.1/24 dev en0
sudo ip route add 10.0.0.0/24 via 192.168.1.1 dev en0
sudo ip neigh add 10.0.0.1 lladdr aa:bb:cc:dd:ee:ff dev en0
Shell completions
# Completions are installed automatically via homebrew
ip completion bash > /etc/bash_completion.d/ip
ip completion zsh > "${fpath[1]}/_ip"
ip completion fish > ~/.config/fish/completions/ip.fish
Go Library
Use pkg/net as a Go library — the CLI is a thin wrapper around it.
import pkgnet "github.com/rgcr/iproute-mac/pkg/net"
client, _ := pkgnet.New()
// Interfaces
links, _ := client.LinkList()
link, _ := client.LinkGet("en0")
// Addresses
addrs, _ := client.AddrList(pkgnet.AddrFilterOptions{
Interface: "en0",
Family: pkgnet.FamilyIPv4,
})
// Routes
routes, _ := client.RouteList(pkgnet.RouteFilterOptions{DefaultOnly: true})
route, _ := client.RouteGet(net.ParseIP("8.8.8.8"))
// Neighbors
neighs, _ := client.NeighList(pkgnet.NeighFilterOptions{Interface: "en0"})
// Sockets
sockets, _ := client.SocketList(pkgnet.SocketFilterOptions{
TCP: true,
Listening: true,
})
// Bridge
ports, _ := client.BridgeLinkList("bridge0")
fdb, _ := client.BridgeFDBList("bridge0")
// Multicast
maddrs, _ := client.McastList("en0")
// Tunnels
tunnels, _ := client.TunnelList()
// Wi-Fi
wifi, _ := client.WiFiStatus("en0")
// Monitor (blocks until stopCh closed)
stopCh := make(chan struct{})
client.Monitor(pkgnet.MonitorAll, func(ev pkgnet.Event) {
fmt.Println(ev.Message)
}, stopCh)
Linux Compatibility
| Command | Status | Notes |
|---|---|---|
ip link show/set | ✅ | |
ip addr show/add/del | ✅ | |
ip route show/add/del/get/replace | ✅ | |
ip neigh show/add/del/flush | ✅ | |
ip tunnel show | ✅ | utun, gif, stf |
ip maddr show | ✅ | |
ip monitor | ✅ | link, addr, route |
ip wifi show | ✅ | macOS extension |
ip rule | ⛔ | macOS uses scoped routing (RTF_IFSCOPE) |
ip netns | ⛔ | No network namespaces on macOS |
ip xfrm/vrf/mptcp/l2tp | ⛔ | Not supported on macOS |
ss -t/-u/-x/-l/-a/-p/-s/-n | ✅ | |
bridge link show | ✅ | |
bridge fdb show | ✅ |
Contributing
We ❤️ contributions!
- Fork the repo
- Create your feature branch:
git checkout -b my-new-feature - Commit your changes:
git commit -m 'Add some feature' - Push the branch:
git push origin my-new-feature - Open a Pull Request 🚀
© Rogelio Cedillo – Licensed under the MIT License