Package arp implements the ARP protocol, as described in RFC 826. MIT Licensed.

Related tags

Network arp
Overview

arp Build Status GoDoc Go Report Card

Package arp implements the ARP protocol, as described in RFC 826. MIT Licensed.

Portions of this code are taken from the Go standard library. The Go standard library is Copyright (c) 2012 The Go Authors. All rights reserved. The Go license can be found at https://golang.org/LICENSE.

Issues
  • How is SetDeadline supposed to work?

    How is SetDeadline supposed to work?

    My code:

    	arpInterface, err := net.InterfaceByName("en0"); if err != nil {
    		panic("Cannot open en0")
    	}
    	arpClient, err := arp.Dial(arpInterface); if err != nil {
    		panic("sendArp: Cannot bind client to interface")
    	}
    
    	fmt.Println("ip = ", ip)
    	timeout := time.Now().Add(3*time.Second)
    	fmt.Println("timeout set to ", timeout )
    	arpClient.SetDeadline(timeout)
    	macaddr, err := arpClient.Resolve(ip); if err != nil {
    		fmt.Println("Request error is ", err)
    	} else {
    		fmt.Println("Resolved ", ip, " to ", macaddr)
    	}
    

    When I try to resolve a nonexistent IP, arpClient.Resolve() hangs indefinitely. I'd like to specify a timeout, and I thought that SetDeadline or SetReadDeadline would work. Obviously I'm doing something wrong. Advice appreciated.

    opened by sbromberger 8
  • Windows Support?

    Windows Support?

    Currently I need to listen for arp requests sent, and the raw depend fails to work on windows.

    Possible to implement?

    opened by JamieSinn 5
  • *: restructure API

    *: restructure API

    This change completely overhauls the API.

    It gets rid of the server and client distinction. From a traditional networking standpoint, there are no ARP clients and servers. Each device will send requests, and it will answer to requests. From a Go perspective, having the distinction made some sense – many users will probably only ever send requests, not answer them. However, the distinction made it harder for people who do have to do both. It also lacked a way for sending many requests at once with a single client. While this could've been fixed by adding more APIs, it seemed a lot more straightforward to unify the client and server responsibilities. This gets rid of the server, the muxer and the request type.

    Instead, we provide the 2 basic building blocks (reading packets and writing packets) and some high level functions:

    • Read, which reads a single packet. The packet may be a request, or it may be a response. The user can determine this based on the Operation and act accordingly. This allows to work as a server, or as a client dealing with many responses, or a mixture of both.
    • Write, which will send a packet.
    • Request, which sends a single request. It does not wait for a response. The response will be read via Read.
    • Respond, which will send a response to a request.
    • Resolve, which will send a single request, then wait for a response. This provides a high-level way for resolving an IP to a MAC address, without having to deal with individual packets or filtering out other noise. On the other hand, it cannot be used concurrently with Read, as the two would conflict with each other. It's an either-or choice.

    Additionally, the following helpers were added:

    • IsReply, to check if a packet is a response to a request.
    • IsReplyFrom, like IsReply but also check for a specific IP.
    opened by dominikh 3
  • go generate produces error

    go generate produces error

    Hi thanks for this package.

    I was looking through the source and seeing that string.go and packet.go are generated (this comes from the go std lib I assume) as such 'go generate' does not work:

    packet.go:26: running "stringer": exec: "stringer": executable file not found in $PATH
    

    string.go also has some lint issues; I don't know if you want to keep this "this is generated code" in these files or clean them up?

    opened by miekg 2
  • Operation not permitted

    Operation not permitted

    Hi, I'm trying to use this library for sending some ARP requests, and I get an

    operation not permitted

    error when I try to create a client. I'm getting the interfacing, passing it's pointer to the NewClient method. like so:

    ifaces, _ := net.Interfaces()
    // The third for me is the relevant one.
    client, err := arp.NewClient(&ifaces[2])
    if err != nil {
        fmt.Println(err)
    }
    
    target := net.ParseIP("10.0.18.70")
    err = client.Request(target)
    if err != nil {
        fmt.Println(err)
    }
    

    So I then get a nil error when I call client.Request, because the original client is not permitted. Is this the correct way to proceed? Should I be using sudo? When I do that it complains that the GOPATH isn't set, and things get tricky.

    opened by fenimore 2
  • Allow the user to create a Client from a PacketConn

    Allow the user to create a Client from a PacketConn

    In particular, on Linux, this will allow the user to create an arp.Client in promiscious mode, by having raw.ListenPacket call socket(2) with htons(ETH_P_ALL) by passing syscall.ETH_P_ALL into it.

    An example replacement of an existing call site would look something like:

    dev, err := net.InterfaceByName("name0")
    if err != nil {
        return err
    }
    packetConn, err := raw.ListenPacket(dev, syscall.ETH_P_ALL)
    if err != nil {
        return err
    }
    arpClient, err := arp.NewClientPacketConn(dev, packetConn)
    ...
    
    opened by paultag 2
  • Linux (docker and raspberry pi): Resolve() not returning

    Linux (docker and raspberry pi): Resolve() not returning

    I have the following code:

    func sendArp(ip net.IP, arpClient *arp.Client, config chirpdconfig) (net.HardwareAddr, error) {
    
    	l.Println("sendArp: in sendarp for ", ip)
    	timeout := time.Now().Add(config.arpResponseTimeout)
    	l.Println("sendArp: timeout = ", timeout)
    	err := arpClient.SetDeadline(timeout)
    	if  err != nil {
    		panic(fmt.Sprintln("sendArp: cannot set deadline: ", err))
    	}
    
    	l.Println("sendArp: post SetDeadline")
    	macaddr, err := arpClient.Resolve(ip)
    	l.Println("sendArp: post Resolve")
    	if err != nil {
    		l.Println("sendArp: err = ", err)
    	}
    	l.Println("macaddr = ", macaddr)
    	return macaddr, err
    }
    

    I get the following output:

    2017/10/12 sendArp: in sendarp for  10.0.1.222
    2017/10/12 sendArp: timeout =  2017-10-12 21:19:36.879028782 -0700 PDT m=+7.533864643
    2017/10/12 sendArp: post SetDeadline
    

    and then things just hang.

    I understand from #12 that SetDeadline doesn't work on MacOS, so that might explain the linux/docker failure, but I tried this on a raspberry pi running raspbian and it's not working either. What am I doing wrong?

    opened by sbromberger 2
  • client: make WriteTo use addr argument for the Ethernet frame

    client: make WriteTo use addr argument for the Ethernet frame

    According to RFC 826, the target hardware address in the ARP packet isn't important (in one place even marked as "don't care"), and it specifically says that the address lacks meaning in the request form. Nevertheless, hardware exists that (regardless of whether or not it's compliant) imposes requirements on the target address.

    Previously, the WriteTo function in this library has disregarded its addr parameter and instead used the target MAC address from inside the ARP packet for the Ethernet destination address. This made it impossible to communicate with hardware that has expectations on the target MAC address field as you couldn't use an ARP target MAC address that's distinct from the Ethernet frame's destination address.

    Example

    package main
    
    import (
    	"net"
    
    	"github.com/mdlayher/arp"
    	"github.com/mdlayher/ethernet"
    )
    
    func main() {
    	sourceMAC := net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}
    	sourceIP := net.IPv4(10, 1, 2, 3)
    	targetMAC := net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
    	targetIP := net.IPv4(10, 1, 2, 4)
    	packet, _ := arp.NewPacket(arp.OperationRequest, sourceMAC, sourceIP, targetMAC, targetIP)
    
    	iface, _ := net.InterfaceByName("wlp3s0")
    	client, _ := arp.Dial(iface)
    	destinationMAC := ethernet.Broadcast // this one's ignored and replaced with zeroes
    	client.WriteTo(packet, destinationMAC)
    }
    

    Before

    15:55:02.410404 ARP, Request who-has 10.1.2.4 tell 10.1.2.3, length 46
    	0x0000:  0000 0000 0000 1234 5678 9abc 0806 0001  .......4Vx......
    	0x0010:  0800 0604 0001 1234 5678 9abc 0a01 0203  .......4Vx......
    	0x0020:  0000 0000 0000 0a01 0204 0000 0000 0000  ................
    	0x0030:  0000 0000 0000 0000 0000 0000            ............
    

    After

    15:57:30.886322 ARP, Request who-has 10.1.2.4 tell 10.1.2.3, length 46
    	0x0000:  ffff ffff ffff 1234 5678 9abc 0806 0001  .......4Vx......
    	0x0010:  0800 0604 0001 1234 5678 9abc 0a01 0203  .......4Vx......
    	0x0020:  0000 0000 0000 0a01 0204 0000 0000 0000  ................
    	0x0030:  0000 0000 0000 0000 0000 0000            ............
    
    opened by sjoqvist 1
  • Indirect dependency library `golang.org/x/textv0.3.0` has a security issue

    Indirect dependency library `golang.org/x/textv0.3.0` has a security issue

    Indirect dependency golang.org/x/textv0.3.0 has a security issue, please found this dependency library at: https://github.com/mdlayher/arp/blob/master/go.sum#L13
    CVE link: https://nvd.nist.gov/vuln/detail/CVE-2020-14040
    Could you consider to upgrade this library to version v0.3.7?

    opened by fool-derek 0
  • Suggestion: provide a New...() for mock/fake client

    Suggestion: provide a New...() for mock/fake client

    Hey @mdlayher, thanks for this package and the others you've provided. They've been very helpful.

    I want to be able to unit test code that is using arp.Client and see the packets that I'm sending by providing a mock PacketConn. The code in client_test.go is pretty close to what I want to do, but users of this package cannot set the PacketConn on the client without using New(), which requires a net.Interface. I believe creating a net.Interface for my tests would require NET_ADMIN capabilities.

    I could mock out the Client as an interface, but then I cannot see the packets that go on the wire.

    Is it possible that another New...() function could be created that allows you to set the net.IP, net.HardwareAddr and net.PacketConn directly for use in testing?

    This might require adjustments to the Client struct. I believe you only use the net.Interface to get Addrs() during initialization and for getting the HardwareAddr during various functions.

    My suggestion would look something like this and I can submit a PR if you're willing to accept it :) I'm iffy on the name, love to hear your suggestions if you don't like it.

    type Client struct {
            addr net.HardwareAddr
    	ip  net.IP
    	p   net.PacketConn
    }
    
    func NewForTesting(addr net.HardwareAddr, ip net.IP, p net.PacketConn) *Client { ... }
    
    opened by nathanperkins 0
  • Suggestion: Continuous Fuzzing

    Suggestion: Continuous Fuzzing

    Hi, I'm Yevgeny Pats Founder of Fuzzit - Continuous fuzzing as a service platform.

    I saw that you implemented Fuzz targets but they are currently not running as part of the CI.

    We have a free plan for OSS and I would be happy to contribute a PR if that's interesting. The PR will include the following

    • Continuous Fuzzing of master branch which will generate new corpus and look for new crashes
    • Regression on every PR that will run the fuzzers through all the generated corpus and fixed crashes from previous step. This will prevent new or old bugs from crippling into master.

    You can see our basic example here and you can see an example of "in the wild" integration here.

    Let me know if this is something worth working on.

    Cheers, Yevgeny

    opened by yevgenypats 0
  • Support infiniband device

    Support infiniband device

    Trying to use a downsteam package that references this repo. I ran into an issue using IP over Infiniband device type in a mix ethernet/infiniband environment.

     ib0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 4092 qdisc mq state UP mode DEFAULT group default qlen 256
        link/infiniband 20:00:00:67:fe:80:00:00:00:00:00:00:e0:07:1b:ff:ff:7d:e2:e8 brd 00:ff:ff:ff:ff:12:40:1b:ff:ff:00:00:00:00:00:00:ff:ff:ff:ff
    

    Infiniband devices use 12 digit mac addresses and this probably unnecessary sanity check in packet.go causes error. Lines 90-92:

    	if len(srcHW) != len(dstHW) {
    		return nil, ErrInvalidHardwareAddr
    	}
    

    It assumes all MAC addresses are 6 character. Removing the check and recompiling allowed downstream Metallb to work on my IP over Infiniband interconnects.

    opened by jcatana 8
Owner
Matt Layher
Software Engineer. Go, Linux, and open source software enthusiast. On and ever upward.
Matt Layher
Package ethernet implements marshaling and unmarshaling of IEEE 802.3 Ethernet II frames and IEEE 802.1Q VLAN tags. MIT Licensed.

ethernet Package ethernet implements marshaling and unmarshaling of IEEE 802.3 Ethernet II frames and IEEE 802.1Q VLAN tags. MIT Licensed. For more in

Matt Layher 235 Dec 20, 2021
Package raw enables reading and writing data at the device driver level for a network interface. MIT Licensed.

raw Package raw enables reading and writing data at the device driver level for a network interface. MIT Licensed. For more information about using ra

Matt Layher 412 Dec 15, 2021
Package socket provides a low-level network connection type which integrates with Go's runtime network poller to provide asynchronous I/O and deadline support. MIT Licensed.

socket Package socket provides a low-level network connection type which integrates with Go's runtime network poller to provide asynchronous I/O and d

Matt Layher 30 Dec 23, 2021
A go implementation of the STUN client (RFC 3489 and RFC 5389)

go-stun go-stun is a STUN (RFC 3489, 5389) client implementation in golang (a.k.a. UDP hole punching). RFC 3489: STUN - Simple Traversal of User Datag

Cong Ding 464 Jan 4, 2022
Diameter stack and Base Protocol (RFC 6733) for the Go programming language

Diameter Base Protocol Package go-diameter is an implementation of the Diameter Base Protocol RFC 6733 and a stack for the Go programming language. St

Alexandre Fiori 186 Jan 5, 2022
Gmqtt is a flexible, high-performance MQTT broker library that fully implements the MQTT protocol V3.1.1 and V5 in golang

中文文档 Gmqtt News: MQTT V5 is now supported. But due to those new features in v5, there area lots of breaking changes. If you have any migration problem

null 554 Jan 14, 2022
CoAP Client/Server implementing RFC 7252 for the Go Language

Canopus Canopus is a client/server implementation of the Constrained Application Protocol (CoAP) Updates 25.11.2016 I've added basic dTLS Support base

Zubair Hamed 147 Nov 16, 2021
Fast RFC 5389 STUN implementation in go

STUN Package stun implements Session Traversal Utilities for NAT (STUN) [RFC5389] protocol and client with no external dependencies and zero allocatio

null 476 Dec 30, 2021
URI Templates (RFC 6570) implemented in Go

uritemplates -- import "github.com/jtacoma/uritemplates" Package uritemplates is a level 4 implementation of RFC 6570 (URI Template, http://tools.ietf

Joshua Tacoma 72 Aug 31, 2021
Fast RFC 5389 STUN implementation in go

STUN Package stun implements Session Traversal Utilities for NAT (STUN) [RFC5389] protocol and client with no external dependencies and zero allocatio

null 476 Dec 30, 2021
RFC 1413 compliant fake identd

RFC 1413 compliant fake identd. It is an implementation of the Ident Protocol, but it lies to the clients and always returns fake identities of queried users.

Hyeon Kim (김지현) 2 Nov 21, 2021
wire protocol for multiplexing connections or streams into a single connection, based on a subset of the SSH Connection Protocol

qmux qmux is a wire protocol for multiplexing connections or streams into a single connection. It is based on the SSH Connection Protocol, which is th

Jeff Lindsay 164 Jan 1, 2022
A simple tool to convert socket5 proxy protocol to http proxy protocol

Socket5 to HTTP 这是一个超简单的 Socket5 代理转换成 HTTP 代理的小工具。 如何安装? Golang 用户 # Required Go 1.17+ go install github.com/mritd/s2[email protected] Docker 用户 docker pull m

mritd 3 Nov 2, 2021
Inspired by go-socks5,This package provides full functionality of socks5 protocol.

The protocol described here is designed to provide a framework for client-server applications in both the TCP and UDP domains to conveniently and securely use the services of a network firewall.

Zhangliu 64 Jan 8, 2022
A little ping pong service that implements rate limiting with golang

Fred the Guardian Introduction Writing a little ping pong service that implements rate limiting with the programming language golang. Requirements Web

null 0 Jan 2, 2022
P2PDistributedHashTable - A golang Kademlia/Bittorrent DHT library that implements BEP5

This is a golang Kademlia/Bittorrent DHT library that implements BEP 5. It's typ

Suhas Aggarwal 1 Jan 5, 2022
A TCP Server Framework with graceful shutdown, custom protocol.

xtcp A TCP Server Framework with graceful shutdown,custom protocol. Usage Define your protocol format: Before create server and client, you need defin

xfx 128 Jan 10, 2022
Go library for writing standalone Map/Reduce jobs or for use with Hadoop's streaming protocol

dmrgo is a Go library for writing map/reduce jobs. It can be used with Hadoop's streaming protocol, but also includes a standalone map/reduce impleme

Damian Gryski 105 Nov 26, 2021