fix(dhcp): can not renew an ip address
The dhcp server is systemd-networkd, and the dhcp plugin can request an ip but can not renew it. The systemd-networkd just ignore the renew request. ``` 2024/09/14 21:46:00 no DHCP packet received within 10s 2024/09/14 21:46:00 retrying in 31.529038 seconds 2024/09/14 21:46:42 no DHCP packet received within 10s 2024/09/14 21:46:42 retrying in 63.150490 seconds 2024/09/14 21:47:45 98184616c91f15419f5cacd012697f85afaa2daeb5d3233e28b0ec21589fb45a/iot/eth1: no more tries 2024/09/14 21:47:45 98184616c91f15419f5cacd012697f85afaa2daeb5d3233e28b0ec21589fb45a/iot/eth1: renewal time expired, rebinding 2024/09/14 21:47:45 Link "eth1" down. Attempting to set up 2024/09/14 21:47:45 98184616c91f15419f5cacd012697f85afaa2daeb5d3233e28b0ec21589fb45a/iot/eth1: lease rebound, expiration is 2024-09-14 22:47:45.309270751 +0800 CST m=+11730.048516519 ``` Follow the https://datatracker.ietf.org/doc/html/rfc2131#section-4.3.6, following options must not be sent in renew - Requested IP Address - Server Identifier Since the upstream code has been inactive for 6 years, we should switch to another dhcpv4 library. The new selected one is https://github.com/insomniacslk/dhcp. Signed-off-by: Songmin Li <lisongmin@protonmail.com>
This commit is contained in:

committed by
Casey Callendrello

parent
e4950728ce
commit
d61e7e5e1f
1
vendor/github.com/mdlayher/packet/.gitignore
generated
vendored
Normal file
1
vendor/github.com/mdlayher/packet/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
cmd/packet
|
27
vendor/github.com/mdlayher/packet/CHANGELOG.md
generated
vendored
Normal file
27
vendor/github.com/mdlayher/packet/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# CHANGELOG
|
||||
|
||||
# v1.1.2
|
||||
|
||||
- [Improvement]: updated dependencies, test with Go 1.20.
|
||||
|
||||
# v1.1.1
|
||||
|
||||
- [Bug Fix]: fix test compilation on big endian machines.
|
||||
|
||||
# v1.1.0
|
||||
|
||||
**This is the first release of package packet that only supports Go 1.18+. Users
|
||||
on older versions of Go must use v1.0.0.**
|
||||
|
||||
- [Improvement]: drop support for older versions of Go so we can begin using
|
||||
modern versions of `x/sys` and other dependencies.
|
||||
|
||||
## v1.0.0
|
||||
|
||||
**This is the last release of package vsock that supports Go 1.17 and below.**
|
||||
|
||||
- Initial stable commit! The API is mostly a direct translation of the previous
|
||||
`github.com/mdlayher/raw` package APIs, with some updates to make everything
|
||||
focused explicitly on Linux and `AF_PACKET` sockets. Functionally, the two
|
||||
packages are equivalent, and `*raw.Conn` is now backed by `*packet.Conn` in
|
||||
the latest version of the `raw` package.
|
9
vendor/github.com/mdlayher/packet/LICENSE.md
generated
vendored
Normal file
9
vendor/github.com/mdlayher/packet/LICENSE.md
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# MIT License
|
||||
|
||||
Copyright (C) 2022 Matt Layher
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
35
vendor/github.com/mdlayher/packet/README.md
generated
vendored
Normal file
35
vendor/github.com/mdlayher/packet/README.md
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
# packet [](https://github.com/mdlayher/packet/actions) [](https://pkg.go.dev/github.com/mdlayher/packet) [](https://goreportcard.com/report/github.com/mdlayher/packet)
|
||||
|
||||
Package `packet` provides access to Linux packet sockets (`AF_PACKET`). MIT
|
||||
Licensed.
|
||||
|
||||
## Stability
|
||||
|
||||
See the [CHANGELOG](./CHANGELOG.md) file for a description of changes between
|
||||
releases.
|
||||
|
||||
This package has a stable v1 API and any future breaking changes will prompt
|
||||
the release of a new major version. Features and bug fixes will continue to
|
||||
occur in the v1.x.x series.
|
||||
|
||||
This package only supports the two most recent major versions of Go, mirroring
|
||||
Go's own release policy. Older versions of Go may lack critical features and bug
|
||||
fixes which are necessary for this package to function correctly.
|
||||
|
||||
## History
|
||||
|
||||
One of my first major Go networking projects was
|
||||
[`github.com/mdlayher/raw`](https://github.com/mdlayher/raw), which provided
|
||||
access to Linux `AF_PACKET` sockets and *BSD equivalent mechanisms for sending
|
||||
and receiving Ethernet frames. However, the *BSD support languished and I lack
|
||||
the expertise and time to properly maintain code for operating systems I do not
|
||||
use on a daily basis.
|
||||
|
||||
Package `packet` is a successor to package `raw`, but exclusively focused on
|
||||
Linux and `AF_PACKET` sockets. The APIs are nearly identical, but with a few
|
||||
changes which take into account some of the lessons learned while working on
|
||||
`raw`.
|
||||
|
||||
Users are highly encouraged to migrate any existing Linux uses of `raw` to
|
||||
package `packet` instead. This package will be supported for the foreseeable
|
||||
future and will receive continued updates as necessary.
|
2
vendor/github.com/mdlayher/packet/doc.go
generated
vendored
Normal file
2
vendor/github.com/mdlayher/packet/doc.go
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// Package packet provides access to Linux packet sockets (AF_PACKET).
|
||||
package packet
|
241
vendor/github.com/mdlayher/packet/packet.go
generated
vendored
Normal file
241
vendor/github.com/mdlayher/packet/packet.go
generated
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
package packet
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
)
|
||||
|
||||
const (
|
||||
// network is the network reported in net.OpError.
|
||||
network = "packet"
|
||||
|
||||
// Operation names which may be returned in net.OpError.
|
||||
opClose = "close"
|
||||
opGetsockopt = "getsockopt"
|
||||
opListen = "listen"
|
||||
opRawControl = "raw-control"
|
||||
opRawRead = "raw-read"
|
||||
opRawWrite = "raw-write"
|
||||
opRead = "read"
|
||||
opSet = "set"
|
||||
opSetsockopt = "setsockopt"
|
||||
opSyscallConn = "syscall-conn"
|
||||
opWrite = "write"
|
||||
)
|
||||
|
||||
// Config contains options for a Conn.
|
||||
type Config struct {
|
||||
// Filter is an optional assembled BPF filter which can be applied to the
|
||||
// Conn before bind(2) is called.
|
||||
//
|
||||
// The Conn.SetBPF method serves the same purpose once a Conn has already
|
||||
// been opened, but setting Filter applies the BPF filter before the Conn is
|
||||
// bound. This ensures that unexpected packets will not be captured before
|
||||
// the Conn is opened.
|
||||
Filter []bpf.RawInstruction
|
||||
}
|
||||
|
||||
// Type is a socket type used when creating a Conn with Listen.
|
||||
//enumcheck:exhaustive
|
||||
type Type int
|
||||
|
||||
// Possible Type values. Note that the zero value is not valid: callers must
|
||||
// always specify one of Raw or Datagram when calling Listen.
|
||||
const (
|
||||
_ Type = iota
|
||||
Raw
|
||||
Datagram
|
||||
)
|
||||
|
||||
// Listen opens a packet sockets connection on the specified interface, using
|
||||
// the given socket type and protocol values.
|
||||
//
|
||||
// The socket type must be one of the Type constants: Raw or Datagram.
|
||||
//
|
||||
// The Config specifies optional configuration for the Conn. A nil *Config
|
||||
// applies the default configuration.
|
||||
func Listen(ifi *net.Interface, socketType Type, protocol int, cfg *Config) (*Conn, error) {
|
||||
l, err := listen(ifi, socketType, protocol, cfg)
|
||||
if err != nil {
|
||||
return nil, opError(opListen, err, &Addr{HardwareAddr: ifi.HardwareAddr})
|
||||
}
|
||||
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// TODO(mdlayher): we want to support FileConn for advanced use cases, but this
|
||||
// library would also need a big endian protocol value and an interface index.
|
||||
// For now we won't bother, but reconsider in the future.
|
||||
|
||||
var (
|
||||
_ net.PacketConn = &Conn{}
|
||||
_ syscall.Conn = &Conn{}
|
||||
_ bpf.Setter = &Conn{}
|
||||
)
|
||||
|
||||
// A Conn is an Linux packet sockets (AF_PACKET) implementation of a
|
||||
// net.PacketConn.
|
||||
type Conn struct {
|
||||
c *conn
|
||||
|
||||
// Metadata about the local connection.
|
||||
addr *Addr
|
||||
ifIndex int
|
||||
protocol uint16
|
||||
}
|
||||
|
||||
// Close closes the connection.
|
||||
func (c *Conn) Close() error {
|
||||
return c.opError(opClose, c.c.Close())
|
||||
}
|
||||
|
||||
// LocalAddr returns the local network address. The Addr returned is shared by
|
||||
// all invocations of LocalAddr, so do not modify it.
|
||||
func (c *Conn) LocalAddr() net.Addr { return c.addr }
|
||||
|
||||
// ReadFrom implements the net.PacketConn ReadFrom method.
|
||||
func (c *Conn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||
return c.readFrom(b)
|
||||
}
|
||||
|
||||
// WriteTo implements the net.PacketConn WriteTo method.
|
||||
func (c *Conn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||
return c.writeTo(b, addr)
|
||||
}
|
||||
|
||||
// SetDeadline implements the net.PacketConn SetDeadline method.
|
||||
func (c *Conn) SetDeadline(t time.Time) error {
|
||||
return c.opError(opSet, c.c.SetDeadline(t))
|
||||
}
|
||||
|
||||
// SetReadDeadline implements the net.PacketConn SetReadDeadline method.
|
||||
func (c *Conn) SetReadDeadline(t time.Time) error {
|
||||
return c.opError(opSet, c.c.SetReadDeadline(t))
|
||||
}
|
||||
|
||||
// SetWriteDeadline implements the net.PacketConn SetWriteDeadline method.
|
||||
func (c *Conn) SetWriteDeadline(t time.Time) error {
|
||||
return c.opError(opSet, c.c.SetWriteDeadline(t))
|
||||
}
|
||||
|
||||
// SetBPF attaches an assembled BPF program to the Conn.
|
||||
func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
|
||||
return c.opError(opSetsockopt, c.c.SetBPF(filter))
|
||||
}
|
||||
|
||||
// SetPromiscuous enables or disables promiscuous mode on the Conn, allowing it
|
||||
// to receive traffic that is not addressed to the Conn's network interface.
|
||||
func (c *Conn) SetPromiscuous(enable bool) error {
|
||||
return c.setPromiscuous(enable)
|
||||
}
|
||||
|
||||
// Stats contains statistics about a Conn reported by the Linux kernel.
|
||||
type Stats struct {
|
||||
// The total number of packets received.
|
||||
Packets uint32
|
||||
|
||||
// The number of packets dropped.
|
||||
Drops uint32
|
||||
|
||||
// The total number of times that a receive queue is frozen. May be zero if
|
||||
// the Linux kernel is not new enough to support TPACKET_V3 statistics.
|
||||
FreezeQueueCount uint32
|
||||
}
|
||||
|
||||
// Stats retrieves statistics about the Conn from the Linux kernel.
|
||||
//
|
||||
// Note that calling Stats will reset the kernel's internal counters for this
|
||||
// Conn. If you want to maintain cumulative statistics by polling Stats over
|
||||
// time, you must do so in your calling code.
|
||||
func (c *Conn) Stats() (*Stats, error) { return c.stats() }
|
||||
|
||||
// SyscallConn returns a raw network connection. This implements the
|
||||
// syscall.Conn interface.
|
||||
func (c *Conn) SyscallConn() (syscall.RawConn, error) {
|
||||
rc, err := c.c.SyscallConn()
|
||||
if err != nil {
|
||||
return nil, c.opError(opSyscallConn, err)
|
||||
}
|
||||
|
||||
return &rawConn{
|
||||
rc: rc,
|
||||
addr: c.addr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// opError is a convenience for the function opError that also passes the local
|
||||
// and remote addresses of the Conn.
|
||||
func (c *Conn) opError(op string, err error) error {
|
||||
return opError(op, err, c.addr)
|
||||
}
|
||||
|
||||
// TODO(mdlayher): see if we can port smarter net.OpError logic into
|
||||
// socket.Conn's SyscallConn type to avoid the need for this wrapper.
|
||||
|
||||
var _ syscall.RawConn = &rawConn{}
|
||||
|
||||
// A rawConn is a syscall.RawConn that wraps an internal syscall.RawConn in order
|
||||
// to produce net.OpError error values.
|
||||
type rawConn struct {
|
||||
rc syscall.RawConn
|
||||
addr *Addr
|
||||
}
|
||||
|
||||
// Control implements the syscall.RawConn Control method.
|
||||
func (rc *rawConn) Control(fn func(fd uintptr)) error {
|
||||
return rc.opError(opRawControl, rc.rc.Control(fn))
|
||||
}
|
||||
|
||||
// Control implements the syscall.RawConn Read method.
|
||||
func (rc *rawConn) Read(fn func(fd uintptr) (done bool)) error {
|
||||
return rc.opError(opRawRead, rc.rc.Read(fn))
|
||||
}
|
||||
|
||||
// Control implements the syscall.RawConn Write method.
|
||||
func (rc *rawConn) Write(fn func(fd uintptr) (done bool)) error {
|
||||
return rc.opError(opRawWrite, rc.rc.Write(fn))
|
||||
}
|
||||
|
||||
// opError is a convenience for the function opError that also passes the
|
||||
// address of the rawConn.
|
||||
func (rc *rawConn) opError(op string, err error) error {
|
||||
return opError(op, err, rc.addr)
|
||||
}
|
||||
|
||||
var _ net.Addr = &Addr{}
|
||||
|
||||
// TODO(mdlayher): expose sll_hatype and sll_pkttype on receive Addr only.
|
||||
|
||||
// An Addr is a physical-layer address.
|
||||
type Addr struct {
|
||||
HardwareAddr net.HardwareAddr
|
||||
}
|
||||
|
||||
// Network returns the address's network name, "packet".
|
||||
func (a *Addr) Network() string { return network }
|
||||
|
||||
// String returns the string representation of an Addr.
|
||||
func (a *Addr) String() string {
|
||||
return a.HardwareAddr.String()
|
||||
}
|
||||
|
||||
// opError unpacks err if possible, producing a net.OpError with the input
|
||||
// parameters in order to implement net.PacketConn. As a convenience, opError
|
||||
// returns nil if the input error is nil.
|
||||
func opError(op string, err error, local net.Addr) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(mdlayher): try to comply with net.PacketConn as best as we can; land
|
||||
// a nettest.TestPacketConn API upstream.
|
||||
return &net.OpError{
|
||||
Op: op,
|
||||
Net: network,
|
||||
Addr: local,
|
||||
Err: err,
|
||||
}
|
||||
}
|
248
vendor/github.com/mdlayher/packet/packet_linux.go
generated
vendored
Normal file
248
vendor/github.com/mdlayher/packet/packet_linux.go
generated
vendored
Normal file
@ -0,0 +1,248 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package packet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"math"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/josharian/native"
|
||||
"github.com/mdlayher/socket"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// A conn is the net.PacketConn implementation for packet sockets. We can use
|
||||
// socket.Conn directly on Linux to implement most of the necessary methods.
|
||||
type conn = socket.Conn
|
||||
|
||||
// readFrom implements the net.PacketConn ReadFrom method using recvfrom(2).
|
||||
func (c *Conn) readFrom(b []byte) (int, net.Addr, error) {
|
||||
// From net.PacketConn documentation:
|
||||
//
|
||||
// "[ReadFrom] returns the number of bytes read (0 <= n <= len(p)) and any
|
||||
// error encountered. Callers should always process the n > 0 bytes returned
|
||||
// before considering the error err."
|
||||
//
|
||||
// c.opError will return nil if no error, but either way we return all the
|
||||
// information that we have.
|
||||
n, sa, err := c.c.Recvfrom(context.Background(), b, 0)
|
||||
return n, fromSockaddr(sa), c.opError(opRead, err)
|
||||
}
|
||||
|
||||
// writeTo implements the net.PacketConn WriteTo method.
|
||||
func (c *Conn) writeTo(b []byte, addr net.Addr) (int, error) {
|
||||
sa, err := c.toSockaddr("sendto", addr)
|
||||
if err != nil {
|
||||
return 0, c.opError(opWrite, err)
|
||||
}
|
||||
|
||||
// TODO(mdlayher): it's curious that unix.Sendto does not return the number
|
||||
// of bytes actually sent. Fake it for now, but investigate upstream.
|
||||
if err := c.c.Sendto(context.Background(), b, 0, sa); err != nil {
|
||||
return 0, c.opError(opWrite, err)
|
||||
}
|
||||
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// setPromiscuous wraps setsockopt(2) for the unix.PACKET_MR_PROMISC option.
|
||||
func (c *Conn) setPromiscuous(enable bool) error {
|
||||
mreq := unix.PacketMreq{
|
||||
Ifindex: int32(c.ifIndex),
|
||||
Type: unix.PACKET_MR_PROMISC,
|
||||
}
|
||||
|
||||
membership := unix.PACKET_DROP_MEMBERSHIP
|
||||
if enable {
|
||||
membership = unix.PACKET_ADD_MEMBERSHIP
|
||||
}
|
||||
|
||||
return c.opError(
|
||||
opSetsockopt,
|
||||
c.c.SetsockoptPacketMreq(unix.SOL_PACKET, membership, &mreq),
|
||||
)
|
||||
}
|
||||
|
||||
// stats wraps getsockopt(2) for tpacket_stats* types.
|
||||
func (c *Conn) stats() (*Stats, error) {
|
||||
const (
|
||||
level = unix.SOL_PACKET
|
||||
name = unix.PACKET_STATISTICS
|
||||
)
|
||||
|
||||
// Try to fetch V3 statistics first, they contain more detailed information.
|
||||
if stats, err := c.c.GetsockoptTpacketStatsV3(level, name); err == nil {
|
||||
return &Stats{
|
||||
Packets: stats.Packets,
|
||||
Drops: stats.Drops,
|
||||
FreezeQueueCount: stats.Freeze_q_cnt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// There was an error fetching v3 stats, try to fall back.
|
||||
stats, err := c.c.GetsockoptTpacketStats(level, name)
|
||||
if err != nil {
|
||||
return nil, c.opError(opGetsockopt, err)
|
||||
}
|
||||
|
||||
return &Stats{
|
||||
Packets: stats.Packets,
|
||||
Drops: stats.Drops,
|
||||
// FreezeQueueCount is not present.
|
||||
}, nil
|
||||
}
|
||||
|
||||
// listen is the entry point for Listen on Linux.
|
||||
func listen(ifi *net.Interface, socketType Type, protocol int, cfg *Config) (*Conn, error) {
|
||||
if cfg == nil {
|
||||
// Default configuration.
|
||||
cfg = &Config{}
|
||||
}
|
||||
|
||||
// Convert Type to the matching SOCK_* constant.
|
||||
var typ int
|
||||
switch socketType {
|
||||
case Raw:
|
||||
typ = unix.SOCK_RAW
|
||||
case Datagram:
|
||||
typ = unix.SOCK_DGRAM
|
||||
default:
|
||||
return nil, errors.New("packet: invalid Type value")
|
||||
}
|
||||
|
||||
// Protocol is intentionally zero in call to socket(2); we can set it on
|
||||
// bind(2) instead. Package raw notes: "Do not specify a protocol to avoid
|
||||
// capturing packets which to not match cfg.Filter."
|
||||
c, err := socket.Socket(unix.AF_PACKET, typ, 0, network, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conn, err := bind(c, ifi.Index, protocol, cfg)
|
||||
if err != nil {
|
||||
_ = c.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// bind binds the *socket.Conn to finalize *Conn setup.
|
||||
func bind(c *socket.Conn, ifIndex, protocol int, cfg *Config) (*Conn, error) {
|
||||
if len(cfg.Filter) > 0 {
|
||||
// The caller wants to apply a BPF filter before bind(2).
|
||||
if err := c.SetBPF(cfg.Filter); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// packet(7) says we sll_protocol must be in network byte order.
|
||||
pnet, err := htons(protocol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO(mdlayher): investigate the possibility of sll_ifindex = 0 because we
|
||||
// could bind to any interface.
|
||||
err = c.Bind(&unix.SockaddrLinklayer{
|
||||
Protocol: pnet,
|
||||
Ifindex: ifIndex,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lsa, err := c.Getsockname()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Parse the physical layer address; sll_halen tells us how many bytes of
|
||||
// sll_addr we should treat as valid.
|
||||
lsall := lsa.(*unix.SockaddrLinklayer)
|
||||
addr := make(net.HardwareAddr, lsall.Halen)
|
||||
copy(addr, lsall.Addr[:])
|
||||
|
||||
return &Conn{
|
||||
c: c,
|
||||
|
||||
addr: &Addr{HardwareAddr: addr},
|
||||
ifIndex: ifIndex,
|
||||
protocol: pnet,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// fromSockaddr converts an opaque unix.Sockaddr to *Addr. If sa is nil, it
|
||||
// returns nil. It panics if sa is not of type *unix.SockaddrLinklayer.
|
||||
func fromSockaddr(sa unix.Sockaddr) *Addr {
|
||||
if sa == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
sall := sa.(*unix.SockaddrLinklayer)
|
||||
|
||||
return &Addr{
|
||||
// The syscall already allocated sa; just slice into it with the
|
||||
// appropriate length and type conversion rather than making a copy.
|
||||
HardwareAddr: net.HardwareAddr(sall.Addr[:sall.Halen]),
|
||||
}
|
||||
}
|
||||
|
||||
// toSockaddr converts a net.Addr to an opaque unix.Sockaddr. It returns an
|
||||
// error if the fields cannot be packed into a *unix.SockaddrLinklayer.
|
||||
func (c *Conn) toSockaddr(
|
||||
op string,
|
||||
addr net.Addr,
|
||||
) (unix.Sockaddr, error) {
|
||||
// The typical error convention for net.Conn types is
|
||||
// net.OpError(os.SyscallError(syscall.Errno)), so all calls here should
|
||||
// return os.SyscallError(syscall.Errno) so the caller can apply the final
|
||||
// net.OpError wrapper.
|
||||
|
||||
// Ensure the correct Addr type.
|
||||
a, ok := addr.(*Addr)
|
||||
if !ok || a.HardwareAddr == nil {
|
||||
return nil, os.NewSyscallError(op, unix.EINVAL)
|
||||
}
|
||||
|
||||
// Pack Addr and Conn metadata into the appropriate sockaddr fields. From
|
||||
// packet(7):
|
||||
//
|
||||
// "When you send packets it is enough to specify sll_family, sll_addr,
|
||||
// sll_halen, sll_ifindex, and sll_protocol. The other fields should be 0."
|
||||
//
|
||||
// sll_family is set on the conversion to unix.RawSockaddrLinklayer.
|
||||
sa := unix.SockaddrLinklayer{
|
||||
Ifindex: c.ifIndex,
|
||||
Protocol: c.protocol,
|
||||
}
|
||||
|
||||
// Ensure the input address does not exceed the amount of space available;
|
||||
// for example an IPoIB address is 20 bytes.
|
||||
if len(a.HardwareAddr) > len(sa.Addr) {
|
||||
return nil, os.NewSyscallError(op, unix.EINVAL)
|
||||
}
|
||||
|
||||
sa.Halen = uint8(len(a.HardwareAddr))
|
||||
copy(sa.Addr[:], a.HardwareAddr)
|
||||
|
||||
return &sa, nil
|
||||
}
|
||||
|
||||
// htons converts a short (uint16) from host-to-network byte order.
|
||||
func htons(i int) (uint16, error) {
|
||||
if i < 0 || i > math.MaxUint16 {
|
||||
return 0, errors.New("packet: protocol value out of range")
|
||||
}
|
||||
|
||||
// Store as big endian, retrieve as native endian.
|
||||
var b [2]byte
|
||||
binary.BigEndian.PutUint16(b[:], uint16(i))
|
||||
|
||||
return native.Endian.Uint16(b[:]), nil
|
||||
}
|
33
vendor/github.com/mdlayher/packet/packet_others.go
generated
vendored
Normal file
33
vendor/github.com/mdlayher/packet/packet_others.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package packet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
)
|
||||
|
||||
// errUnimplemented is returned by all functions on non-Linux platforms.
|
||||
var errUnimplemented = fmt.Errorf("packet: not implemented on %s", runtime.GOOS)
|
||||
|
||||
func listen(_ *net.Interface, _ Type, _ int, _ *Config) (*Conn, error) { return nil, errUnimplemented }
|
||||
|
||||
func (*Conn) readFrom(_ []byte) (int, net.Addr, error) { return 0, nil, errUnimplemented }
|
||||
func (*Conn) writeTo(_ []byte, _ net.Addr) (int, error) { return 0, errUnimplemented }
|
||||
func (*Conn) setPromiscuous(_ bool) error { return errUnimplemented }
|
||||
func (*Conn) stats() (*Stats, error) { return nil, errUnimplemented }
|
||||
|
||||
type conn struct{}
|
||||
|
||||
func (*conn) Close() error { return errUnimplemented }
|
||||
func (*conn) SetDeadline(_ time.Time) error { return errUnimplemented }
|
||||
func (*conn) SetReadDeadline(_ time.Time) error { return errUnimplemented }
|
||||
func (*conn) SetWriteDeadline(_ time.Time) error { return errUnimplemented }
|
||||
func (*conn) SetBPF(_ []bpf.RawInstruction) error { return errUnimplemented }
|
||||
func (*conn) SyscallConn() (syscall.RawConn, error) { return nil, errUnimplemented }
|
Reference in New Issue
Block a user