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  }