arping_linux.go 853 B

123456789101112131415161718192021222324252627282930313233343536373839
  1. package arping
  2. import (
  3. "net"
  4. "syscall"
  5. "time"
  6. )
  7. var sock int
  8. var toSockaddr syscall.SockaddrLinklayer
  9. func initialize(iface net.Interface) error {
  10. toSockaddr = syscall.SockaddrLinklayer{Ifindex: iface.Index}
  11. // 1544 = htons(ETH_P_ARP)
  12. const proto = 1544
  13. var err error
  14. sock, err = syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, proto)
  15. return err
  16. }
  17. func send(request arpDatagram) (time.Time, error) {
  18. return time.Now(), syscall.Sendto(sock, request.MarshalWithEthernetHeader(), 0, &toSockaddr)
  19. }
  20. func receive() (arpDatagram, time.Time, error) {
  21. buffer := make([]byte, 128)
  22. n, _, err := syscall.Recvfrom(sock, buffer, 0)
  23. if err != nil {
  24. return arpDatagram{}, time.Now(), err
  25. }
  26. // skip 14 bytes ethernet header
  27. return parseArpDatagram(buffer[14:n]), time.Now(), nil
  28. }
  29. func deinitialize() error {
  30. return syscall.Close(sock)
  31. }