Skip to content

Instantly share code, notes, and snippets.

@jsipprell
Last active May 25, 2022 05:41
Show Gist options
  • Save jsipprell/52df8f8d382d9ca02eda753f7ca8525a to your computer and use it in GitHub Desktop.
Save jsipprell/52df8f8d382d9ca02eda753f7ca8525a to your computer and use it in GitHub Desktop.
Capture 20 ethernet frames from an interface in promiscuous mode (native go, no libpcap)
package main
import (
"fmt"
"github.com/mdlayher/ethernet"
"github.com/mdlayher/raw"
"log"
"net"
"os"
"strings"
)
const EtherTypeAll uint16 = 0x0003
func dumpFrame(f *ethernet.Frame) string {
s := make([]string, 0, 5)
s = append(s, fmt.Sprintf("dst=%v", f.Destination), fmt.Sprintf("src=%v", f.Source))
if f.VLAN != nil && f.VLAN.ID != ethernet.VLANNone && f.VLAN.ID != ethernet.VLANMax {
s = append(s, fmt.Sprintf("vlan=%v", f.VLAN.ID))
}
s = append(s, f.EtherType.String(), fmt.Sprintf("%d octets", len(f.Payload)))
return strings.Join(s, " ")
}
func main() {
var (
c *raw.Conn
n int
frame ethernet.Frame
iface string = "eth0"
)
if len(os.Args) > 1 {
iface = os.Args[1]
}
ifi, err := net.InterfaceByName(iface)
if err != nil {
log.Fatal(err)
}
if c, err = raw.ListenPacket(ifi, EtherTypeAll, nil); err != nil {
log.Fatal(err)
}
if err = c.SetPromiscuous(true); err != nil {
log.Fatal(err)
}
b := make([]byte, 10000)
log.Printf("listening for 20 packets on %s ...\n", iface)
for i := 0; i < 20; i++ {
if n, _, err = c.ReadFrom(b); err != nil {
log.Fatal(err)
}
if err = frame.UnmarshalBinary(b[:n]); err != nil {
log.Println(err)
continue
}
log.Printf(" [%v]\n", dumpFrame(&frame))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment