1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
// Package raw enables reading and writing data at the device driver level for a
// network interface.
//
// Deprecated: use github.com/mdlayher/packet on Linux instead. This package is
// unmaintained.
//
//
// Unmaintained
//
// This repository was one of my first major Go networking libraries. Although I
// have updated it on Linux to incorporate modern Go best practices
// (asynchronous I/O, runtime network poller integration), the non-Linux
// platform code is effectively unmaintained and does not have the same level of
// functionality.
//
// I encourage all Linux users of this package to migrate to
// https://github.com/mdlayher/packet, which is a modern AF_PACKET library. The
// existing *raw.Conn APIs now call directly into the equivalent *packet.Conn
// APIs, and a level of indirection can be removed by migrating to that package.
package raw
import (
"errors"
"net"
"time"
"golang.org/x/net/bpf"
)
// ErrNotImplemented is returned when certain functionality is not yet
// implemented for the host operating system.
var ErrNotImplemented = errors.New("raw: not implemented")
var _ net.Addr = &Addr{}
// Addr is a network address which can be used to contact other machines, using
// their hardware addresses.
type Addr struct {
HardwareAddr net.HardwareAddr
}
// Network returns the address's network name, "raw".
func (a *Addr) Network() string {
return "raw"
}
// String returns the address's hardware address.
func (a *Addr) String() string {
return a.HardwareAddr.String()
}
var _ net.PacketConn = &Conn{}
// Conn is an implementation of the net.PacketConn interface which can send
// and receive data at the network interface device driver level.
type Conn struct {
// packetConn is the operating system-specific implementation of
// a raw connection.
p *packetConn
}
// ReadFrom implements the net.PacketConn ReadFrom method.
func (c *Conn) ReadFrom(b []byte) (int, net.Addr, error) {
return c.p.ReadFrom(b)
}
// WriteTo implements the net.PacketConn WriteTo method.
func (c *Conn) WriteTo(b []byte, addr net.Addr) (int, error) {
return c.p.WriteTo(b, addr)
}
// Close closes the connection.
func (c *Conn) Close() error {
return c.p.Close()
}
// LocalAddr returns the local network address.
func (c *Conn) LocalAddr() net.Addr {
return c.p.LocalAddr()
}
// SetDeadline implements the net.PacketConn SetDeadline method.
func (c *Conn) SetDeadline(t time.Time) error {
return c.p.SetDeadline(t)
}
// SetReadDeadline implements the net.PacketConn SetReadDeadline method.
func (c *Conn) SetReadDeadline(t time.Time) error {
return c.p.SetReadDeadline(t)
}
// SetWriteDeadline implements the net.PacketConn SetWriteDeadline method.
func (c *Conn) SetWriteDeadline(t time.Time) error {
return c.p.SetWriteDeadline(t)
}
var _ bpf.Setter = &Conn{}
// SetBPF attaches an assembled BPF program to the connection.
func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
return c.p.SetBPF(filter)
}
// SetPromiscuous enables or disables promiscuous mode on the interface, allowing it
// to receive traffic that is not addressed to the interface.
func (c *Conn) SetPromiscuous(b bool) error {
return c.p.SetPromiscuous(b)
}
// Stats contains statistics about a Conn.
type Stats struct {
// The total number of packets received.
Packets uint64
// The number of packets dropped.
Drops uint64
}
// Stats retrieves statistics from the Conn.
//
// Only supported on Linux at this time.
func (c *Conn) Stats() (*Stats, error) {
return c.p.Stats()
}
// ListenPacket creates a net.PacketConn which can be used to send and receive
// data at the network interface device driver level.
//
// ifi specifies the network interface which will be used to send and receive
// data.
//
// proto specifies the protocol (usually the EtherType) which should be
// captured and transmitted. proto, if needed, is automatically converted to
// network byte order (big endian), akin to the htons() function in C.
//
// cfg specifies optional configuration which may be operating system-specific.
// A nil Config is equivalent to the default configuration: send and receive
// data at the network interface device driver level (usually raw Ethernet frames).
func ListenPacket(ifi *net.Interface, proto uint16, cfg *Config) (*Conn, error) {
// A nil config is an empty Config.
if cfg == nil {
cfg = &Config{}
}
p, err := listenPacket(ifi, proto, *cfg)
if err != nil {
return nil, err
}
return &Conn{
p: p,
}, nil
}
// A Config can be used to specify additional options for a Conn.
type Config struct {
// Linux only: call socket(7) with SOCK_DGRAM instead of SOCK_RAW.
// Has no effect on other operating systems.
LinuxSockDGRAM bool
// Linux only: do not accumulate packet socket statistic counters. Packet
// socket statistics are reset on each call to retrieve them via getsockopt,
// but this package's default behavior is to continue accumulating the
// statistics internally per Conn. To use the Linux default behavior of
// resetting statistics on each call to Stats, set this value to true.
NoCumulativeStats bool
// Linux only: initial filter to apply to the connection. This avoids
// capturing random packets before SetBPF is called.
Filter []bpf.RawInstruction
// BSD only: configure the BPF direction flag to allow selection of inbound
// only (0 - default) or bidirectional (1) packet processing.
// Has no effect on other operating systems.
BPFDirection int
}
|