github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/cmd/examples/icmp_pcap/main.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "embed" 6 "fmt" 7 "os" 8 "syscall" 9 10 "github.com/dylandreimerink/gobpfld" 11 "github.com/dylandreimerink/gobpfld/bpftypes" 12 ) 13 14 //go:embed src/sockfilter 15 var f embed.FS 16 17 func main() { 18 elfFileBytes, err := f.ReadFile("src/sockfilter") 19 if err != nil { 20 fmt.Fprintf(os.Stderr, "error opening ELF file: %s\n", err.Error()) 21 os.Exit(1) 22 } 23 24 elf, err := gobpfld.LoadProgramFromELF(bytes.NewReader(elfFileBytes), gobpfld.ELFParseSettings{}) 25 if err != nil { 26 fmt.Fprintf(os.Stderr, "error while reading ELF file: %s\n", err.Error()) 27 os.Exit(1) 28 } 29 30 program := elf.Programs["sockfilter_prog"].(*gobpfld.ProgramSocketFilter) 31 32 log, err := program.Load(gobpfld.ProgSKFilterLoadOpts{ 33 VerifierLogLevel: bpftypes.BPFLogLevelBasic, 34 VerifierLogSize: 1 << 20, 35 }) 36 fmt.Fprint(os.Stdout, log) 37 if err != nil { 38 fmt.Fprintf(os.Stderr, "program load: %s\n", err.Error()) 39 os.Exit(1) 40 } 41 42 fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(htons(syscall.ETH_P_ALL))) 43 if err != nil { 44 fmt.Fprintf(os.Stderr, "syscall socket: %s", err.Error()) 45 os.Exit(1) 46 } 47 48 err = program.Attach(uintptr(fd)) 49 if err != nil { 50 fmt.Fprintf(os.Stderr, "socket attach: %s", err.Error()) 51 os.Exit(1) 52 } 53 54 // Make a 32KB buffer 55 buf := make([]byte, 1<<16) 56 for { 57 len, _, err := syscall.Recvfrom(fd, buf, 0) 58 if err != nil { 59 fmt.Fprintf(os.Stderr, "syscall recvfrom: %s", err.Error()) 60 os.Exit(1) 61 } 62 63 fmt.Printf("% X\n", buf[:len]) 64 } 65 } 66 67 // htons converts a short (uint16) from host-to-network byte order. 68 func htons(i uint16) uint16 { 69 return (i<<8)&0xff00 | i>>8 70 }