github.com/blueinnovationsgroup/can-go@v0.0.0-20230518195432-d0567cda0028/pkg/socketcan/dialraw_linux.go (about)

     1  //go:build linux && go1.12
     2  
     3  package socketcan
     4  
     5  import (
     6  	"fmt"
     7  	"net"
     8  	"os"
     9  
    10  	"golang.org/x/sys/unix"
    11  )
    12  
    13  func dialRaw(device string) (conn net.Conn, err error) {
    14  	defer func() {
    15  		if err != nil {
    16  			err = &net.OpError{Op: "dial", Net: canRawNetwork, Addr: &canRawAddr{device: device}, Err: err}
    17  		}
    18  	}()
    19  	ifi, err := net.InterfaceByName(device)
    20  	if err != nil {
    21  		return nil, fmt.Errorf("interface %s: %w", device, err)
    22  	}
    23  	fd, err := unix.Socket(unix.AF_CAN, unix.SOCK_RAW, unix.CAN_RAW)
    24  	if err != nil {
    25  		return nil, fmt.Errorf("socket: %w", err)
    26  	}
    27  	// put fd in non-blocking mode so the created file will be registered by the runtime poller (Go >= 1.12)
    28  	if err := unix.SetNonblock(fd, true); err != nil {
    29  		return nil, fmt.Errorf("set nonblock: %w", err)
    30  	}
    31  	if err := unix.Bind(fd, &unix.SockaddrCAN{Ifindex: ifi.Index}); err != nil {
    32  		return nil, fmt.Errorf("bind: %w", err)
    33  	}
    34  	return &fileConn{ra: &canRawAddr{device: device}, f: os.NewFile(uintptr(fd), "can")}, nil
    35  }