mirror of
https://github.com/buger/goreplay.git
synced 2024-04-21 12:32:02 +00:00
implements af_packet socket
This commit is contained in:
+97
-41
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -21,13 +22,13 @@ type Handler func(gopacket.Packet)
|
||||
// PcapOptions options that can be set on a pcap capture handle,
|
||||
// these options take effect on inactive pcap handles
|
||||
type PcapOptions struct {
|
||||
BufferTimeout time.Duration `json:"input-raw-buffer-timeout"`
|
||||
TimestampType string `json:"input-raw-timestamp-type"`
|
||||
BPFFilter string `json:"input-raw-bpf-filter"`
|
||||
BufferSize size.Size `json:"input-raw-buffer-size"`
|
||||
Promiscuous bool `json:"input-raw-promisc"`
|
||||
Monitor bool `json:"input-raw-monitor"`
|
||||
Snaplen bool `json:"input-raw-override-snaplen"`
|
||||
BufferTimeout time.Duration `json:"input-raw-buffer-timeout"`
|
||||
TimestampType string `json:"input-raw-timestamp-type"`
|
||||
BufferSize size.Size `json:"input-raw-buffer-size"`
|
||||
BPFFilter string `json:"input-raw-bpf-filter"`
|
||||
}
|
||||
|
||||
// NetInterface represents network interface
|
||||
@@ -39,18 +40,18 @@ type NetInterface struct {
|
||||
// Listener handle traffic capture, this is its representation.
|
||||
type Listener struct {
|
||||
sync.Mutex
|
||||
PcapOptions
|
||||
Engine EngineType
|
||||
Transport string // transport layer default to tcp
|
||||
Activate func() error // function is used to activate the engine. it must be called before reading packets
|
||||
Handles map[string]*pcap.Handle
|
||||
Handles map[string]gopacket.PacketDataSource
|
||||
Interfaces []NetInterface
|
||||
Reading chan bool // this channel is closed when the listener has started reading packets
|
||||
|
||||
host string // pcap file name or interface (name, hardware addr, index or ip address)
|
||||
PcapOptions
|
||||
Engine EngineType
|
||||
port uint16 // src or/and dst port
|
||||
trackResponse bool
|
||||
|
||||
host string // pcap file name or interface (name, hardware addr, index or ip address)
|
||||
|
||||
quit chan bool
|
||||
packets chan gopacket.Packet
|
||||
}
|
||||
@@ -60,8 +61,9 @@ type EngineType uint8
|
||||
|
||||
// Available engines for intercepting traffic
|
||||
const (
|
||||
EnginePcap EngineType = iota
|
||||
EnginePcap EngineType = 1 << iota
|
||||
EnginePcapFile
|
||||
EngineRawSocket
|
||||
)
|
||||
|
||||
// Set is here so that EngineType can implement flag.Var
|
||||
@@ -71,6 +73,8 @@ func (eng *EngineType) Set(v string) error {
|
||||
*eng = EnginePcap
|
||||
case "pcap_file":
|
||||
*eng = EnginePcapFile
|
||||
case "sock_raw", "af_packet":
|
||||
*eng = EngineRawSocket
|
||||
default:
|
||||
return fmt.Errorf("invalid engine %s", v)
|
||||
}
|
||||
@@ -83,6 +87,8 @@ func (eng *EngineType) String() (e string) {
|
||||
e = "pcap_file"
|
||||
case EnginePcap:
|
||||
e = "libpcap"
|
||||
case EngineRawSocket:
|
||||
e = "sock_raw"
|
||||
default:
|
||||
e = ""
|
||||
}
|
||||
@@ -101,16 +107,21 @@ func NewListener(host string, port uint16, transport string, engine EngineType,
|
||||
if transport != "" {
|
||||
l.Transport = transport
|
||||
}
|
||||
l.Handles = make(map[string]*pcap.Handle)
|
||||
l.Handles = make(map[string]gopacket.PacketDataSource)
|
||||
l.trackResponse = trackResponse
|
||||
l.packets = make(chan gopacket.Packet, 1000)
|
||||
l.quit = make(chan bool, 1)
|
||||
l.Reading = make(chan bool, 1)
|
||||
l.Activate = l.activatePcap
|
||||
l.Engine = EnginePcap
|
||||
if engine == EnginePcapFile {
|
||||
l.Activate = l.activatePcapFile
|
||||
switch engine {
|
||||
default:
|
||||
l.Engine = EnginePcap
|
||||
l.Activate = l.activatePcap
|
||||
case EngineRawSocket:
|
||||
l.Engine = EngineRawSocket
|
||||
l.Activate = l.activateRawSocket
|
||||
case EnginePcapFile:
|
||||
l.Engine = EnginePcapFile
|
||||
l.Activate = l.activatePcapFile
|
||||
return
|
||||
}
|
||||
err = l.setInterfaces()
|
||||
@@ -130,9 +141,6 @@ func (l *Listener) SetPcapOptions(opts PcapOptions) {
|
||||
// until the context done signal is sent or EOF on handles.
|
||||
// this function should be called after activating pcap handles
|
||||
func (l *Listener) Listen(ctx context.Context, handler Handler) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.read()
|
||||
done := ctx.Done()
|
||||
var p gopacket.Packet
|
||||
@@ -143,7 +151,7 @@ func (l *Listener) Listen(ctx context.Context, handler Handler) (err error) {
|
||||
l.quit <- true
|
||||
close(l.quit)
|
||||
err = ctx.Err()
|
||||
return
|
||||
done = nil
|
||||
case p, ok = <-l.packets:
|
||||
if !ok {
|
||||
return
|
||||
@@ -182,7 +190,7 @@ func (l *Listener) Filter(ifi NetInterface) (filter string) {
|
||||
dir = " "
|
||||
}
|
||||
filter = fmt.Sprintf("(%s%s%s)", l.Transport, dir, port)
|
||||
if l.host == "" || isDevice(l.host, ifi) {
|
||||
if listenAll(l.host) || isDevice(l.host, ifi) {
|
||||
return
|
||||
}
|
||||
filter = fmt.Sprintf("(%s%s%s and host %s)", l.Transport, dir, port, l.host)
|
||||
@@ -254,7 +262,7 @@ func (l *Listener) PcapHandle(ifi NetInterface) (handle *pcap.Handle, err error)
|
||||
return nil, fmt.Errorf("handle buffer size error: %q, interface: %q", err, ifi.Name)
|
||||
}
|
||||
}
|
||||
if l.BufferTimeout.Nanoseconds() == 0 {
|
||||
if l.BufferTimeout == 0 {
|
||||
l.BufferTimeout = pcap.BlockForever
|
||||
}
|
||||
err = inactive.SetTimeout(l.BufferTimeout)
|
||||
@@ -266,11 +274,8 @@ func (l *Listener) PcapHandle(ifi NetInterface) (handle *pcap.Handle, err error)
|
||||
return nil, fmt.Errorf("PCAP Activate device error: %q, interface: %q", err, ifi.Name)
|
||||
}
|
||||
if l.BPFFilter != "" {
|
||||
if l.BPFFilter[0] != '(' {
|
||||
l.BPFFilter = "(" + l.BPFFilter
|
||||
}
|
||||
if l.BPFFilter[len(l.BPFFilter)-1] != ')' {
|
||||
l.BPFFilter += ")"
|
||||
if l.BPFFilter[0] != '(' || l.BPFFilter[len(l.BPFFilter)-1] != ')' {
|
||||
l.BPFFilter = "(" + l.BPFFilter + ")"
|
||||
}
|
||||
} else {
|
||||
l.BPFFilter = l.Filter(ifi)
|
||||
@@ -283,15 +288,43 @@ func (l *Listener) PcapHandle(ifi NetInterface) (handle *pcap.Handle, err error)
|
||||
return
|
||||
}
|
||||
|
||||
// SocketHandle returns new unix ethernet handle associated with this listener settings
|
||||
func (l *Listener) SocketHandle(ifi NetInterface) (handle *SockRaw, err error) {
|
||||
handle, err = NewSockRaw(ifi.Interface)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sock raw error: %q, interface: %q", err, ifi.Name)
|
||||
}
|
||||
if err = handle.SetPromiscuous(l.Promiscuous || l.Monitor); err != nil {
|
||||
return nil, fmt.Errorf("promiscuous mode error: %q, interface: %q", err, ifi.Name)
|
||||
}
|
||||
if l.BPFFilter != "" {
|
||||
if l.BPFFilter[0] != '(' || l.BPFFilter[len(l.BPFFilter)-1] != ')' {
|
||||
l.BPFFilter = "(" + l.BPFFilter + ")"
|
||||
}
|
||||
} else {
|
||||
l.BPFFilter = l.Filter(ifi)
|
||||
}
|
||||
if err = handle.SetBPFFilter(l.BPFFilter); err != nil {
|
||||
handle.Close()
|
||||
return nil, fmt.Errorf("BPF filter error: %q%s, interface: %q", err, l.BPFFilter, ifi.Name)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Listener) read() {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
for key, handle := range l.Handles {
|
||||
source := gopacket.NewPacketSource(handle, handle.LinkType())
|
||||
var source *gopacket.PacketSource
|
||||
linkType := layers.LinkTypeEthernet
|
||||
if _, ok := handle.(*pcap.Handle); ok {
|
||||
linkType = handle.(*pcap.Handle).LinkType()
|
||||
}
|
||||
source = gopacket.NewPacketSource(handle, linkType)
|
||||
source.Lazy = true
|
||||
source.NoCopy = true
|
||||
ch := source.Packets()
|
||||
go func(handle *pcap.Handle, key string) {
|
||||
go func(key string) {
|
||||
defer l.closeHandles(key)
|
||||
for {
|
||||
select {
|
||||
@@ -304,7 +337,7 @@ func (l *Listener) read() {
|
||||
l.packets <- p
|
||||
}
|
||||
}
|
||||
}(handle, key)
|
||||
}(key)
|
||||
}
|
||||
l.Reading <- true
|
||||
close(l.Reading)
|
||||
@@ -314,7 +347,9 @@ func (l *Listener) closeHandles(key string) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
if handle, ok := l.Handles[key]; ok {
|
||||
handle.Close()
|
||||
if _, ok = handle.(interface{ Close() }); ok {
|
||||
handle.(interface{ Close() }).Close()
|
||||
}
|
||||
delete(l.Handles, key)
|
||||
if len(l.Handles) == 0 {
|
||||
close(l.packets)
|
||||
@@ -322,7 +357,7 @@ func (l *Listener) closeHandles(key string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Listener) activatePcap() (err error) {
|
||||
func (l *Listener) activatePcap() error {
|
||||
var e error
|
||||
var msg string
|
||||
for _, ifi := range l.Interfaces {
|
||||
@@ -337,7 +372,25 @@ func (l *Listener) activatePcap() (err error) {
|
||||
if len(l.Handles) == 0 {
|
||||
return fmt.Errorf("pcap handles error:%s", msg)
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Listener) activateRawSocket() error {
|
||||
if runtime.GOOS != "linux" {
|
||||
return fmt.Errorf("sock_raw is not stabilized on OS other than linux")
|
||||
}
|
||||
var msg string
|
||||
var e error
|
||||
for _, ifi := range l.Interfaces {
|
||||
var handle *SockRaw
|
||||
handle, e = l.SocketHandle(ifi)
|
||||
if e != nil {
|
||||
msg += ("\n" + e.Error())
|
||||
continue
|
||||
}
|
||||
l.Handles[ifi.Name] = handle
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func (l *Listener) activatePcapFile() (err error) {
|
||||
@@ -347,11 +400,8 @@ func (l *Listener) activatePcapFile() (err error) {
|
||||
return fmt.Errorf("open pcap file error: %q", e)
|
||||
}
|
||||
if l.BPFFilter != "" {
|
||||
if l.BPFFilter[0] != '(' {
|
||||
l.BPFFilter = "(" + l.BPFFilter
|
||||
}
|
||||
if l.BPFFilter[len(l.BPFFilter)-1] != ')' {
|
||||
l.BPFFilter += ")"
|
||||
if l.BPFFilter[0] != '(' || l.BPFFilter[len(l.BPFFilter)-1] != ')' {
|
||||
l.BPFFilter = "(" + l.BPFFilter + ")"
|
||||
}
|
||||
} else {
|
||||
addr := l.host
|
||||
@@ -396,15 +446,13 @@ func (l *Listener) setInterfaces() (err error) {
|
||||
Ifis = append(Ifis, ifi)
|
||||
}
|
||||
|
||||
switch l.host {
|
||||
case "", "0.0.0.0", "[::]", "::":
|
||||
if listenAll(l.host) {
|
||||
l.Interfaces = Ifis
|
||||
return
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, ifi := range Ifis {
|
||||
if l.host == ifi.Name || l.host == fmt.Sprintf("%d", ifi.Index) || l.host == ifi.HardwareAddr.String() {
|
||||
if isDevice(l.host, ifi) {
|
||||
found = true
|
||||
}
|
||||
for _, ip := range ifi.IPs {
|
||||
@@ -435,3 +483,11 @@ func cutMask(addr net.Addr) string {
|
||||
func isDevice(addr string, ifi NetInterface) bool {
|
||||
return addr == ifi.Name || addr == fmt.Sprintf("%d", ifi.Index) || addr == ifi.HardwareAddr.String()
|
||||
}
|
||||
|
||||
func listenAll(addr string) bool {
|
||||
switch addr {
|
||||
case "", "0.0.0.0", "[::]", "::":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -193,6 +193,46 @@ func TestPcapHandler(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSocketHandler(t *testing.T) {
|
||||
l, err := NewListener(LoopBack.Name, 8000, "", EngineRawSocket, true)
|
||||
if err != nil {
|
||||
t.Errorf("expected error to be nil, got %v", err)
|
||||
return
|
||||
}
|
||||
err = l.Activate()
|
||||
if err != nil {
|
||||
t.Errorf("expected error to be nil, got %v", err)
|
||||
return
|
||||
}
|
||||
quit := make(chan bool, 1)
|
||||
pckts := 0
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
errCh := l.ListenBackground(ctx, func(packet gopacket.Packet) {
|
||||
pckts++
|
||||
if pckts == 10 {
|
||||
quit <- true
|
||||
}
|
||||
})
|
||||
select {
|
||||
case err = <-errCh:
|
||||
t.Error(err)
|
||||
case <-l.Reading:
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("expected error to be nil, got %v", err)
|
||||
return
|
||||
}
|
||||
for i := 0; i < 5; i++ {
|
||||
_, _ = net.Dial("tcp", "127.0.0.1:8000")
|
||||
}
|
||||
select {
|
||||
case <-time.After(time.Second * 2):
|
||||
t.Error("failed to parse packets in time")
|
||||
case <-quit:
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPcapDump(b *testing.B) {
|
||||
f, err := ioutil.TempFile("", "pcap_file")
|
||||
if err != nil {
|
||||
@@ -224,6 +264,7 @@ func BenchmarkPcapFile(b *testing.B) {
|
||||
}
|
||||
name := f.Name()
|
||||
f.Close()
|
||||
b.ResetTimer()
|
||||
var l *Listener
|
||||
l, err = NewListener(name, 8000, "", EnginePcapFile, true)
|
||||
if err != nil {
|
||||
@@ -288,3 +329,48 @@ func BenchmarkPcap(b *testing.B) {
|
||||
}
|
||||
b.Logf("%d/%d packets in %s", pckts, b.N*2, time.Since(now))
|
||||
}
|
||||
|
||||
func BenchmarkRawSocket(b *testing.B) {
|
||||
now := time.Now()
|
||||
var err error
|
||||
|
||||
l, err := NewListener(LoopBack.Name, 8000, "", EngineRawSocket, true)
|
||||
if err != nil {
|
||||
b.Errorf("expected error to be nil, got %v", err)
|
||||
return
|
||||
}
|
||||
err = l.Activate()
|
||||
if err != nil {
|
||||
b.Errorf("expected error to be nil, got %v", err)
|
||||
return
|
||||
}
|
||||
sock := l.Handles[LoopBack.Name].(*SockRaw)
|
||||
quit := make(chan bool, 1)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
pckts := 0
|
||||
errCh := l.ListenBackground(ctx, func(_ gopacket.Packet) {
|
||||
pckts++
|
||||
if pckts == b.N*2 {
|
||||
quit <- true
|
||||
}
|
||||
})
|
||||
select {
|
||||
case err = <-errCh:
|
||||
b.Error(err)
|
||||
case <-l.Reading:
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
buf := generateHeaders(1, 1<<10)
|
||||
err = sock.WritePacketData(buf[:])
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
select {
|
||||
case <-time.After(time.Second):
|
||||
case <-quit:
|
||||
}
|
||||
sts, _ := l.Handles[LoopBack.Name].(*SockRaw).Stats()
|
||||
b.Logf("%d/%d packets in %s", sts.Packets-sts.Drops, sts.Packets, time.Since(now))
|
||||
}
|
||||
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
package capture
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
"github.com/google/gopacket/pcap"
|
||||
)
|
||||
|
||||
const (
|
||||
// ETHALL htons(ETH_P_ALL)
|
||||
ETHALL uint16 = unix.ETH_P_ALL<<8 | unix.ETH_P_ALL>>8
|
||||
// PAGESIZE represents multiples of 4kb in powers of 2
|
||||
PAGESIZE = 0x1000
|
||||
// BLOCKSIZE ring buffer block_size
|
||||
BLOCKSIZE = PAGESIZE * 36
|
||||
// BLOCKNR ring buffer block_nr
|
||||
BLOCKNR = 4
|
||||
// FRAMESIZE ring buffer frame_size
|
||||
FRAMESIZE = BLOCKSIZE / 2
|
||||
// FRAMENR ring buffer frame_nr
|
||||
FRAMENR = BLOCKNR * BLOCKSIZE / FRAMESIZE
|
||||
)
|
||||
|
||||
var tpacket2hdrlen = tpAlign(int(unsafe.Sizeof(unix.Tpacket2Hdr{})))
|
||||
|
||||
// SockRaw is a linux M'maped af_packet socket
|
||||
type SockRaw struct {
|
||||
mu sync.Mutex
|
||||
fd int
|
||||
ifindex int
|
||||
snaplen int
|
||||
pollTimeout int
|
||||
frame int
|
||||
buf []byte // points to the memory space of the ring buffer shared with the kernel.
|
||||
}
|
||||
|
||||
// NewSockRaw returns new M'maped sock_raw on packet version 2.
|
||||
func NewSockRaw(ifi net.Interface) (*SockRaw, error) {
|
||||
// sock create
|
||||
fd, err := unix.Socket(unix.AF_PACKET, unix.SOCK_RAW, int(ETHALL))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sock := &SockRaw{
|
||||
fd: fd,
|
||||
ifindex: ifi.Index,
|
||||
snaplen: unix.IP_MAXPACKET,
|
||||
pollTimeout: -1,
|
||||
}
|
||||
|
||||
// set packet version
|
||||
err = unix.SetsockoptInt(fd, unix.SOL_PACKET, unix.PACKET_VERSION, unix.TPACKET_V2)
|
||||
if err != nil {
|
||||
unix.Close(fd)
|
||||
return nil, fmt.Errorf("setsockopt packet_version: %v", err)
|
||||
}
|
||||
|
||||
// bind to interface
|
||||
addr := unix.RawSockaddrLinklayer{
|
||||
Family: unix.AF_PACKET,
|
||||
Protocol: ETHALL,
|
||||
Ifindex: int32(ifi.Index),
|
||||
}
|
||||
_, _, e := unix.Syscall(
|
||||
unix.SYS_BIND,
|
||||
uintptr(fd),
|
||||
uintptr(unsafe.Pointer(&addr)),
|
||||
uintptr(unix.SizeofSockaddrLinklayer),
|
||||
)
|
||||
if e != 0 {
|
||||
unix.Close(fd)
|
||||
return nil, e
|
||||
}
|
||||
|
||||
// create shared-memory ring buffer
|
||||
tp := &unix.TpacketReq{
|
||||
Block_size: BLOCKSIZE,
|
||||
Block_nr: BLOCKNR,
|
||||
Frame_size: FRAMESIZE,
|
||||
Frame_nr: FRAMENR,
|
||||
}
|
||||
err = unix.SetsockoptTpacketReq(sock.fd, unix.SOL_PACKET, unix.PACKET_RX_RING, tp)
|
||||
if err != nil {
|
||||
unix.Close(fd)
|
||||
return nil, fmt.Errorf("setsockopt packet_rx_ring: %v", err)
|
||||
}
|
||||
sock.buf, err = unix.Mmap(
|
||||
sock.fd,
|
||||
0,
|
||||
BLOCKSIZE*BLOCKNR,
|
||||
unix.PROT_READ|unix.PROT_WRITE,
|
||||
unix.MAP_SHARED|unix.MAP_LOCKED,
|
||||
)
|
||||
if err != nil {
|
||||
unix.Close(fd)
|
||||
return nil, fmt.Errorf("socket mmap error: %v", err)
|
||||
}
|
||||
return sock, nil
|
||||
}
|
||||
|
||||
// ReadPacketData implements gopacket.PacketDataSource.
|
||||
func (sock *SockRaw) ReadPacketData() (buf []byte, ci gopacket.CaptureInfo, err error) {
|
||||
sock.mu.Lock()
|
||||
defer sock.mu.Unlock()
|
||||
var tpHdr *unix.Tpacket2Hdr
|
||||
poll := &unix.PollFd{
|
||||
Fd: int32(sock.fd),
|
||||
Events: unix.POLLIN,
|
||||
}
|
||||
i := sock.frame * FRAMESIZE
|
||||
tpHdr = (*unix.Tpacket2Hdr)(unsafe.Pointer(&sock.buf[i]))
|
||||
|
||||
for tpHdr.Status&unix.TP_STATUS_USER == 0 {
|
||||
_, _, e := unix.Syscall(unix.SYS_POLL, uintptr(unsafe.Pointer(poll)), 1, uintptr(sock.pollTimeout))
|
||||
if e != 0 && e != unix.EINTR {
|
||||
return buf, ci, e
|
||||
}
|
||||
}
|
||||
tpHdr.Status = unix.TP_STATUS_KERNEL
|
||||
sockAddr := (*unix.RawSockaddrLinklayer)(unsafe.Pointer(&sock.buf[i+tpacket2hdrlen]))
|
||||
ci.Length = int(tpHdr.Len)
|
||||
ci.Timestamp = time.Unix(int64(tpHdr.Sec), int64(tpHdr.Nsec))
|
||||
ci.InterfaceIndex = int(sockAddr.Ifindex)
|
||||
buf = make([]byte, tpHdr.Snaplen)
|
||||
ci.CaptureLength = copy(buf, sock.buf[i+int(tpHdr.Mac):])
|
||||
sock.frame = (sock.frame + 1) % FRAMENR
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Close closes the underlying socket
|
||||
func (sock *SockRaw) Close() (err error) {
|
||||
sock.mu.Lock()
|
||||
defer sock.mu.Unlock()
|
||||
if sock.fd != -1 {
|
||||
unix.Munmap(sock.buf)
|
||||
sock.buf = nil
|
||||
err = unix.Close(sock.fd)
|
||||
sock.fd = -1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetSnapLen sets the maximum capture length to the given value.
|
||||
// for this to take effects on the kernel level SetBPFilter should be called too.
|
||||
func (sock *SockRaw) SetSnapLen(snap int) error {
|
||||
sock.mu.Lock()
|
||||
defer sock.mu.Unlock()
|
||||
if snap < 0 {
|
||||
return fmt.Errorf("expected %d snap length to be at least 0", snap)
|
||||
}
|
||||
if snap > unix.IP_MAXPACKET {
|
||||
snap = unix.IP_MAXPACKET
|
||||
}
|
||||
sock.snaplen = snap
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetTimeout sets poll wait timeout for the socket.
|
||||
// negative value will block forever
|
||||
func (sock *SockRaw) SetTimeout(t time.Duration) error {
|
||||
sock.mu.Lock()
|
||||
defer sock.mu.Unlock()
|
||||
sock.pollTimeout = int(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSnapLen returns the maximum capture length
|
||||
func (sock *SockRaw) GetSnapLen() int {
|
||||
sock.mu.Lock()
|
||||
defer sock.mu.Unlock()
|
||||
return sock.snaplen
|
||||
}
|
||||
|
||||
// SetBPFFilter compiles and sets a BPF filter for the socket handle.
|
||||
func (sock *SockRaw) SetBPFFilter(expr string) error {
|
||||
sock.mu.Lock()
|
||||
defer sock.mu.Unlock()
|
||||
if len(expr) == 0 {
|
||||
return unix.SetsockoptInt(sock.fd, unix.SOL_SOCKET, unix.SO_DETACH_FILTER, 0)
|
||||
}
|
||||
filter, err := pcap.CompileBPFFilter(layers.LinkTypeEthernet, sock.snaplen, expr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(filter) > int(^uint16(0)) {
|
||||
return fmt.Errorf("filters out of range 0-%d", ^uint16(0))
|
||||
}
|
||||
if len(filter) == 0 {
|
||||
return unix.SetsockoptInt(sock.fd, unix.SOL_SOCKET, unix.SO_DETACH_FILTER, 0)
|
||||
}
|
||||
fprog := &unix.SockFprog{
|
||||
Len: uint16(len(filter)),
|
||||
Filter: &(*(*[]unix.SockFilter)(unsafe.Pointer(&filter)))[0],
|
||||
}
|
||||
return unix.SetsockoptSockFprog(sock.fd, unix.SOL_SOCKET, unix.SO_ATTACH_FILTER, fprog)
|
||||
}
|
||||
|
||||
// SetPromiscuous sets promiscous mode to the required value. If it is enabled, traffic not destined for the interface will also be captured.
|
||||
func (sock *SockRaw) SetPromiscuous(b bool) error {
|
||||
sock.mu.Lock()
|
||||
defer sock.mu.Unlock()
|
||||
mreq := unix.PacketMreq{
|
||||
Ifindex: int32(sock.ifindex),
|
||||
Type: unix.PACKET_MR_PROMISC,
|
||||
}
|
||||
|
||||
opt := unix.PACKET_ADD_MEMBERSHIP
|
||||
if !b {
|
||||
opt = unix.PACKET_DROP_MEMBERSHIP
|
||||
}
|
||||
|
||||
return unix.SetsockoptPacketMreq(sock.fd, unix.SOL_PACKET, opt, &mreq)
|
||||
}
|
||||
|
||||
// Stats returns number of packets and dropped packets. This will be the number of packets/dropped packets since the last call to stats (not the cummulative sum!).
|
||||
func (sock *SockRaw) Stats() (*unix.TpacketStats, error) {
|
||||
sock.mu.Lock()
|
||||
defer sock.mu.Unlock()
|
||||
return unix.GetsockoptTpacketStats(sock.fd, unix.SOL_PACKET, unix.PACKET_STATISTICS)
|
||||
}
|
||||
|
||||
// WritePacketData transmits a raw packet.
|
||||
func (sock *SockRaw) WritePacketData(pkt []byte) error {
|
||||
_, err := unix.Write(sock.fd, pkt)
|
||||
return err
|
||||
}
|
||||
|
||||
func tpAlign(x int) int {
|
||||
return int((uint(x) + unix.TPACKET_ALIGNMENT - 1) &^ (unix.TPACKET_ALIGNMENT - 1))
|
||||
}
|
||||
@@ -8,11 +8,12 @@ require (
|
||||
github.com/aws/aws-sdk-go v1.33.2
|
||||
github.com/bitly/go-hostpool v0.1.0 // indirect
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
|
||||
github.com/google/gopacket v1.1.17
|
||||
github.com/google/gopacket v1.1.18
|
||||
github.com/klauspost/compress v1.10.10 // indirect
|
||||
github.com/mattbaird/elastigo v0.0.0-20170123220020-2fe47fd29e4b
|
||||
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
|
||||
)
|
||||
|
||||
@@ -30,8 +30,8 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY=
|
||||
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
|
||||
github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY=
|
||||
github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
||||
|
||||
+2
-3
@@ -18,21 +18,20 @@ type Stats struct {
|
||||
Length int // length of the data
|
||||
Start time.Time // first packet's timestamp
|
||||
End time.Time // last packet's timestamp
|
||||
IPversion byte
|
||||
SrcAddr string
|
||||
DstAddr string
|
||||
IsIncoming bool
|
||||
TimedOut bool // timeout before getting the whole message
|
||||
Truncated bool // last packet truncated due to max message size
|
||||
IPversion byte
|
||||
}
|
||||
|
||||
// Message is the representation of a tcp message
|
||||
type Message struct {
|
||||
Stats
|
||||
|
||||
packets []*Packet
|
||||
done chan bool
|
||||
data []byte
|
||||
Stats
|
||||
}
|
||||
|
||||
// NewMessage ...
|
||||
|
||||
+7
-5
@@ -35,11 +35,13 @@ type Packet struct {
|
||||
// ParsePacket parse raw packets
|
||||
func ParsePacket(packet gopacket.Packet) (pckt *Packet, err error) {
|
||||
// early check of error
|
||||
_ = packet.ApplicationLayer()
|
||||
if e, ok := packet.ErrorLayer().(*gopacket.DecodeFailure); ok {
|
||||
err = e.Error()
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if packet.ErrorLayer() != nil {
|
||||
err = packet.ErrorLayer().Error()
|
||||
println(err.Error())
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
// initialization
|
||||
pckt = new(Packet)
|
||||
|
||||
+6
-4
@@ -2,6 +2,7 @@ language: go
|
||||
go:
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
- master
|
||||
|
||||
addons:
|
||||
@@ -38,10 +39,11 @@ jobs:
|
||||
install: ./.travis.install.sh
|
||||
- os: osx
|
||||
go: 1.x
|
||||
- os: windows
|
||||
go: 1.x
|
||||
# winpcap does not work on travis ci - so install nmap to get libpcap
|
||||
before_install: choco install nmap
|
||||
# windows doesn't work on travis (package installation just hangs and then errors out)
|
||||
# - os: windows
|
||||
# go: 1.x
|
||||
# # We don't need nmap - but that's the only way to get npcap:
|
||||
# before_install: choco install npcap --version 0.86 -y
|
||||
- stage: style
|
||||
name: "fmt/vet/lint"
|
||||
go: 1.x
|
||||
|
||||
+1
@@ -17,6 +17,7 @@ Christian Mäder <christian.maeder@nine.ch>
|
||||
Gernot Vormayr <gvormayr@gmail.com>
|
||||
Vitor Garcia Graveto <victor.graveto@gmail.com>
|
||||
Elias Chavarria Reyes <elchavar@cisco.com>
|
||||
Daniel Rittweiler <ripx80@protonmail.com>
|
||||
|
||||
CONTRIBUTORS:
|
||||
Attila Oláh <attila@attilaolah.eu>
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ See [godoc](https://godoc.org/github.com/google/gopacket) for more details.
|
||||
[](https://travis-ci.org/google/gopacket)
|
||||
[](https://godoc.org/github.com/google/gopacket)
|
||||
|
||||
Minimum Go version required is 1.5 except for pcapgo/EthernetHandle, afpacket, and bsdbpf which need at least 1.7 due to x/sys/unix dependencies.
|
||||
Minimum Go version required is 1.5 except for pcapgo/EthernetHandle, afpacket, and bsdbpf which need at least 1.9 due to x/sys/unix dependencies.
|
||||
|
||||
Originally forked from the gopcap project written by Andreas
|
||||
Krennmair <ak@synflood.at> (http://github.com/akrennmair/gopcap).
|
||||
|
||||
+2
-2
@@ -78,7 +78,7 @@ func (p Payload) SerializeTo(b SerializeBuffer, opts SerializeOptions) error {
|
||||
func decodePayload(data []byte, p PacketBuilder) error {
|
||||
payload := &Payload{}
|
||||
if err := payload.DecodeFromBytes(data, p); err != nil {
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
p.AddLayer(payload)
|
||||
p.SetApplicationLayer(payload)
|
||||
@@ -132,7 +132,7 @@ func (p *Fragment) SerializeTo(b SerializeBuffer, opts SerializeOptions) error {
|
||||
func decodeFragment(data []byte, p PacketBuilder) error {
|
||||
payload := &Fragment{}
|
||||
if err := payload.DecodeFromBytes(data, p); err != nil {
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
p.AddLayer(payload)
|
||||
p.SetApplicationLayer(payload)
|
||||
|
||||
+62
-1
@@ -208,7 +208,7 @@ based on endpoint criteria:
|
||||
}
|
||||
}
|
||||
// Find all packets coming from UDP port 1000 to UDP port 500
|
||||
interestingFlow := gopacket.NewFlow(layers.NewUDPPortEndpoint(1000), layers.NewUDPPortEndpoint(500))
|
||||
interestingFlow := gopacket.FlowFromEndpoints(layers.NewUDPPortEndpoint(1000), layers.NewUDPPortEndpoint(500))
|
||||
if t := packet.NetworkLayer(); t != nil && t.TransportFlow() == interestingFlow {
|
||||
fmt.Println("Found that UDP flow I was looking for!")
|
||||
}
|
||||
@@ -320,6 +320,67 @@ implementing the DecodingLayer interface are usable. Also, it's possible to
|
||||
create DecodingLayers that are not themselves Layers... see
|
||||
layers.IPv6ExtensionSkipper for an example of this.
|
||||
|
||||
Faster And Customized Decoding with DecodingLayerContainer
|
||||
|
||||
By default, DecodingLayerParser uses native map to store and search for a layer
|
||||
to decode. Though being versatile, in some cases this solution may be not so
|
||||
optimal. For example, if you have only few layers faster operations may be
|
||||
provided by sparse array indexing or linear array scan.
|
||||
|
||||
To accomodate these scenarios, DecodingLayerContainer interface is introduced
|
||||
along with its implementations: DecodingLayerSparse, DecodingLayerArray and
|
||||
DecodingLayerMap. You can specify a container implementation to
|
||||
DecodingLayerParser with SetDecodingLayerContainer method. Example:
|
||||
|
||||
dlp := gopacket.NewDecodingLayerParser(LayerTypeEthernet)
|
||||
dlp.SetDecodingLayerContainer(gopacket.DecodingLayerSparse(nil))
|
||||
var eth layers.Ethernet
|
||||
dlp.AddDecodingLayer(ð)
|
||||
// ... add layers and use DecodingLayerParser as usual...
|
||||
|
||||
To skip one level of indirection (though sacrificing some capabilities) you may
|
||||
also use DecodingLayerContainer as a decoding tool as it is. In this case you have to
|
||||
handle unknown layer types and layer panics by yourself. Example:
|
||||
|
||||
func main() {
|
||||
var eth layers.Ethernet
|
||||
var ip4 layers.IPv4
|
||||
var ip6 layers.IPv6
|
||||
var tcp layers.TCP
|
||||
dlc := gopacket.DecodingLayerContainer(gopacket.DecodingLayerArray(nil))
|
||||
dlc = dlc.Put(ð)
|
||||
dlc = dlc.Put(&ip4)
|
||||
dlc = dlc.Put(&ip6)
|
||||
dlc = dlc.Put(&tcp)
|
||||
// you may specify some meaningful DecodeFeedback
|
||||
decoder := dlc.LayersDecoder(LayerTypeEthernet, gopacket.NilDecodeFeedback)
|
||||
decoded := make([]gopacket.LayerType, 0, 20)
|
||||
for packetData := range somehowGetPacketData() {
|
||||
lt, err := decoder(packetData, &decoded)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Could not decode layers: %v\n", err)
|
||||
continue
|
||||
}
|
||||
if lt != gopacket.LayerTypeZero {
|
||||
fmt.Fprintf(os.Stderr, "unknown layer type: %v\n", lt)
|
||||
continue
|
||||
}
|
||||
for _, layerType := range decoded {
|
||||
// examine decoded layertypes just as already shown above
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecodingLayerSparse is the fastest but most effective when LayerType values
|
||||
that layers in use can decode are not large because otherwise that would lead
|
||||
to bigger memory footprint. DecodingLayerArray is very compact and primarily
|
||||
usable if the number of decoding layers is not big (up to ~10-15, but please do
|
||||
your own benchmarks). DecodingLayerMap is the most versatile one and used by
|
||||
DecodingLayerParser by default. Please refer to tests and benchmarks in layers
|
||||
subpackage to further examine usage examples and performance measurements.
|
||||
|
||||
You may also choose to implement your own DecodingLayerContainer if you want to
|
||||
make use of your own internal packet decoding logic.
|
||||
|
||||
Creating Packet Data
|
||||
|
||||
|
||||
+10
-1
@@ -10,6 +10,7 @@ package layers
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
)
|
||||
@@ -39,17 +40,25 @@ func (arp *ARP) LayerType() gopacket.LayerType { return LayerTypeARP }
|
||||
|
||||
// DecodeFromBytes decodes the given bytes into this layer.
|
||||
func (arp *ARP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 8 {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("ARP length %d too short", len(data))
|
||||
}
|
||||
arp.AddrType = LinkType(binary.BigEndian.Uint16(data[0:2]))
|
||||
arp.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))
|
||||
arp.HwAddressSize = data[4]
|
||||
arp.ProtAddressSize = data[5]
|
||||
arp.Operation = binary.BigEndian.Uint16(data[6:8])
|
||||
arpLength := 8 + 2*arp.HwAddressSize + 2*arp.ProtAddressSize
|
||||
if len(data) < int(arpLength) {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("ARP length %d too short, %d expected", len(data), arpLength)
|
||||
}
|
||||
arp.SourceHwAddress = data[8 : 8+arp.HwAddressSize]
|
||||
arp.SourceProtAddress = data[8+arp.HwAddressSize : 8+arp.HwAddressSize+arp.ProtAddressSize]
|
||||
arp.DstHwAddress = data[8+arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+arp.ProtAddressSize]
|
||||
arp.DstProtAddress = data[8+2*arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+2*arp.ProtAddressSize]
|
||||
|
||||
arpLength := 8 + 2*arp.HwAddressSize + 2*arp.ProtAddressSize
|
||||
arp.Contents = data[:arpLength]
|
||||
arp.Payload = data[arpLength:]
|
||||
return nil
|
||||
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
// Copyright 2019 The GoPacket Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license that can be found
|
||||
// in the LICENSE file in the root of the source tree.
|
||||
|
||||
package layers
|
||||
|
||||
// This file implements the ASF RMCP payload specified in section 3.2.2.3 of
|
||||
// https://www.dmtf.org/sites/default/files/standards/documents/DSP0136.pdf
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
)
|
||||
|
||||
const (
|
||||
// ASFRMCPEnterprise is the IANA-assigned Enterprise Number of the ASF-RMCP.
|
||||
ASFRMCPEnterprise uint32 = 4542
|
||||
)
|
||||
|
||||
// ASFDataIdentifier encapsulates fields used to uniquely identify the format of
|
||||
// the data block.
|
||||
//
|
||||
// While the enterprise number is almost always 4542 (ASF-RMCP), we support
|
||||
// registering layers using structs of this type as a key in case any users are
|
||||
// using OEM-extensions.
|
||||
type ASFDataIdentifier struct {
|
||||
|
||||
// Enterprise is the IANA Enterprise Number associated with the entity that
|
||||
// defines the message type. A list can be found at
|
||||
// https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers.
|
||||
// This can be thought of as the namespace for the message type.
|
||||
Enterprise uint32
|
||||
|
||||
// Type is the message type, defined by the entity associated with the
|
||||
// enterprise above. No pressure, but in the context of EN 4542, 1 byte is
|
||||
// the difference between sending a ping and telling a machine to do an
|
||||
// unconditional power down (0x80 and 0x12 respectively).
|
||||
Type uint8
|
||||
}
|
||||
|
||||
// LayerType returns the payload layer type corresponding to an ASF message
|
||||
// type.
|
||||
func (a ASFDataIdentifier) LayerType() gopacket.LayerType {
|
||||
if lt := asfDataLayerTypes[a]; lt != 0 {
|
||||
return lt
|
||||
}
|
||||
|
||||
// some layer types don't have a payload, e.g. ASF-RMCP Presence Ping.
|
||||
return gopacket.LayerTypePayload
|
||||
}
|
||||
|
||||
// RegisterASFLayerType allows specifying that the data block of ASF packets
|
||||
// with a given enterprise number and type should be processed by a given layer
|
||||
// type. This overrides any existing registrations, including defaults.
|
||||
func RegisterASFLayerType(a ASFDataIdentifier, l gopacket.LayerType) {
|
||||
asfDataLayerTypes[a] = l
|
||||
}
|
||||
|
||||
var (
|
||||
// ASFDataIdentifierPresencePong is the message type of the response to a
|
||||
// Presence Ping message. It indicates the sender is ASF-RMCP-aware.
|
||||
ASFDataIdentifierPresencePong = ASFDataIdentifier{
|
||||
Enterprise: ASFRMCPEnterprise,
|
||||
Type: 0x40,
|
||||
}
|
||||
|
||||
// ASFDataIdentifierPresencePing is a message type sent to a managed client
|
||||
// to solicit a Presence Pong response. Clients may ignore this if the RMCP
|
||||
// version is unsupported. Sending this message with a sequence number <255
|
||||
// is the recommended way of finding out whether an implementation sends
|
||||
// RMCP ACKs (e.g. iDRAC does, Super Micro does not).
|
||||
//
|
||||
// Systems implementing IPMI must respond to this ping to conform to the
|
||||
// spec, so it is a good substitute for an ICMP ping.
|
||||
ASFDataIdentifierPresencePing = ASFDataIdentifier{
|
||||
Enterprise: ASFRMCPEnterprise,
|
||||
Type: 0x80,
|
||||
}
|
||||
|
||||
// asfDataLayerTypes is used to find the next layer for a given ASF header.
|
||||
asfDataLayerTypes = map[ASFDataIdentifier]gopacket.LayerType{
|
||||
ASFDataIdentifierPresencePong: LayerTypeASFPresencePong,
|
||||
}
|
||||
)
|
||||
|
||||
// ASF defines ASF's generic RMCP message Data block format. See section
|
||||
// 3.2.2.3.
|
||||
type ASF struct {
|
||||
BaseLayer
|
||||
ASFDataIdentifier
|
||||
|
||||
// Tag is used to match request/response pairs. The tag of a response is set
|
||||
// to that of the message it is responding to. If a message is
|
||||
// unidirectional, i.e. not part of a request/response pair, this is set to
|
||||
// 255.
|
||||
Tag uint8
|
||||
|
||||
// 1 byte reserved, set to 0x00.
|
||||
|
||||
// Length is the length of this layer's payload in bytes.
|
||||
Length uint8
|
||||
}
|
||||
|
||||
// LayerType returns LayerTypeASF. It partially satisfies Layer and
|
||||
// SerializableLayer.
|
||||
func (*ASF) LayerType() gopacket.LayerType {
|
||||
return LayerTypeASF
|
||||
}
|
||||
|
||||
// CanDecode returns LayerTypeASF. It partially satisfies DecodingLayer.
|
||||
func (a *ASF) CanDecode() gopacket.LayerClass {
|
||||
return a.LayerType()
|
||||
}
|
||||
|
||||
// DecodeFromBytes makes the layer represent the provided bytes. It partially
|
||||
// satisfies DecodingLayer.
|
||||
func (a *ASF) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 8 {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("invalid ASF data header, length %v less than 8",
|
||||
len(data))
|
||||
}
|
||||
|
||||
a.BaseLayer.Contents = data[:8]
|
||||
a.BaseLayer.Payload = data[8:]
|
||||
|
||||
a.Enterprise = binary.BigEndian.Uint32(data[:4])
|
||||
a.Type = uint8(data[4])
|
||||
a.Tag = uint8(data[5])
|
||||
// 1 byte reserved
|
||||
a.Length = uint8(data[7])
|
||||
return nil
|
||||
}
|
||||
|
||||
// NextLayerType returns the layer type corresponding to the message type of
|
||||
// this ASF data layer. This partially satisfies DecodingLayer.
|
||||
func (a *ASF) NextLayerType() gopacket.LayerType {
|
||||
return a.ASFDataIdentifier.LayerType()
|
||||
}
|
||||
|
||||
// SerializeTo writes the serialized fom of this layer into the SerializeBuffer,
|
||||
// partially satisfying SerializableLayer.
|
||||
func (a *ASF) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||
payload := b.Bytes()
|
||||
bytes, err := b.PrependBytes(8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
binary.BigEndian.PutUint32(bytes[:4], a.Enterprise)
|
||||
bytes[4] = uint8(a.Type)
|
||||
bytes[5] = a.Tag
|
||||
bytes[6] = 0x00
|
||||
if opts.FixLengths {
|
||||
a.Length = uint8(len(payload))
|
||||
}
|
||||
bytes[7] = a.Length
|
||||
return nil
|
||||
}
|
||||
|
||||
// decodeASF decodes the byte slice into an RMCP-ASF data struct.
|
||||
func decodeASF(data []byte, p gopacket.PacketBuilder) error {
|
||||
return decodingLayerDecoder(&ASF{}, data, p)
|
||||
}
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
// Copyright 2019 The GoPacket Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license that can be found
|
||||
// in the LICENSE file in the root of the source tree.
|
||||
|
||||
package layers
|
||||
|
||||
// This file implements the RMCP ASF Presence Pong message, specified in section
|
||||
// 3.2.4.3 of
|
||||
// https://www.dmtf.org/sites/default/files/standards/documents/DSP0136.pdf. It
|
||||
// also contains non-competing elements from IPMI v2.0, specified in section
|
||||
// 13.2.4 of
|
||||
// https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/ipmi-intelligent-platform-mgt-interface-spec-2nd-gen-v2-0-spec-update.pdf.
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
)
|
||||
|
||||
type (
|
||||
// ASFEntity is the type of individual entities that a Presence Pong
|
||||
// response can indicate support of. The entities currently implemented by
|
||||
// the spec are IPMI and ASFv1.
|
||||
ASFEntity uint8
|
||||
|
||||
// ASFInteraction is the type of individual interactions that a Presence
|
||||
// Pong response can indicate support for. The interactions currently
|
||||
// implemented by the spec are RMCP security extensions. Although not
|
||||
// specified, IPMI uses this field to indicate support for DASH, which is
|
||||
// supported as well.
|
||||
ASFInteraction uint8
|
||||
)
|
||||
|
||||
const (
|
||||
// ASFDCMIEnterprise is the IANA-assigned Enterprise Number of the Data
|
||||
// Center Manageability Interface Forum. The Presence Pong response's
|
||||
// Enterprise field being set to this value indicates support for DCMI. The
|
||||
// DCMI spec regards the OEM field as reserved, so these should be null.
|
||||
ASFDCMIEnterprise uint32 = 36465
|
||||
|
||||
// ASFPresencePongEntityIPMI ANDs with Presence Pong's supported entities
|
||||
// field if the managed system supports IPMI.
|
||||
ASFPresencePongEntityIPMI ASFEntity = 1 << 7
|
||||
|
||||
// ASFPresencePongEntityASFv1 ANDs with Presence Pong's supported entities
|
||||
// field if the managed system supports ASF v1.0.
|
||||
ASFPresencePongEntityASFv1 ASFEntity = 1
|
||||
|
||||
// ASFPresencePongInteractionSecurityExtensions ANDs with Presence Pong's
|
||||
// supported interactions field if the managed system supports RMCP v2.0
|
||||
// security extensions. See section 3.2.3.
|
||||
ASFPresencePongInteractionSecurityExtensions ASFInteraction = 1 << 7
|
||||
|
||||
// ASFPresencePongInteractionDASH ANDs with Presence Pong's supported
|
||||
// interactions field if the managed system supports DMTF DASH. See
|
||||
// https://www.dmtf.org/standards/dash.
|
||||
ASFPresencePongInteractionDASH ASFInteraction = 1 << 5
|
||||
)
|
||||
|
||||
// ASFPresencePong defines the structure of a Presence Pong message's payload.
|
||||
// See section 3.2.4.3.
|
||||
type ASFPresencePong struct {
|
||||
BaseLayer
|
||||
|
||||
// Enterprise is the IANA Enterprise Number of an entity that has defined
|
||||
// OEM-specific capabilities for the managed client. If no such capabilities
|
||||
// exist, this is set to ASF's IANA Enterprise Number.
|
||||
Enterprise uint32
|
||||
|
||||
// OEM identifies OEM-specific capabilities. Its structure is defined by the
|
||||
// OEM. This is set to 0s if no OEM-specific capabilities exist. This
|
||||
// implementation does not change byte order from the wire for this field.
|
||||
OEM [4]byte
|
||||
|
||||
// We break out entities and interactions into separate booleans as
|
||||
// discovery is the entire point of this type of message, so we assume they
|
||||
// are accessed. It also makes gopacket's default layer printing more
|
||||
// useful.
|
||||
|
||||
// IPMI is true if IPMI is supported by the managed system. There is no
|
||||
// explicit version in the specification, however given the dates, this is
|
||||
// assumed to be IPMI v1.0. Support for IPMI is contained in the "supported
|
||||
// entities" field of the presence pong payload.
|
||||
IPMI bool
|
||||
|
||||
// ASFv1 indicates support for ASF v1.0. This seems somewhat redundant as
|
||||
// ASF must be supported in order to receive a response. This is contained
|
||||
// in the "supported entities" field of the presence pong payload.
|
||||
ASFv1 bool
|
||||
|
||||
// SecurityExtensions indicates support for RMCP Security Extensions,
|
||||
// specified in ASF v2.0. This will always be false for v1.x
|
||||
// implementations. This is contained in the "supported interactions" field
|
||||
// of the presence pong payload. This field is defined in ASF v1.0, but has
|
||||
// no useful value.
|
||||
SecurityExtensions bool
|
||||
|
||||
// DASH is true if DMTF DASH is supported. This is not specified in ASF
|
||||
// v2.0, but in IPMI v2.0, however the former does not preclude it, so we
|
||||
// support it.
|
||||
DASH bool
|
||||
|
||||
// 6 bytes reserved after the entities and interactions fields, set to 0s.
|
||||
}
|
||||
|
||||
// SupportsDCMI returns whether the Presence Pong message indicates support for
|
||||
// the Data Center Management Interface, which is an extension of IPMI v2.0.
|
||||
func (a *ASFPresencePong) SupportsDCMI() bool {
|
||||
return a.Enterprise == ASFDCMIEnterprise && a.IPMI && a.ASFv1
|
||||
}
|
||||
|
||||
// LayerType returns LayerTypeASFPresencePong. It partially satisfies Layer and
|
||||
// SerializableLayer.
|
||||
func (*ASFPresencePong) LayerType() gopacket.LayerType {
|
||||
return LayerTypeASFPresencePong
|
||||
}
|
||||
|
||||
// CanDecode returns LayerTypeASFPresencePong. It partially satisfies
|
||||
// DecodingLayer.
|
||||
func (a *ASFPresencePong) CanDecode() gopacket.LayerClass {
|
||||
return a.LayerType()
|
||||
}
|
||||
|
||||
// DecodeFromBytes makes the layer represent the provided bytes. It partially
|
||||
// satisfies DecodingLayer.
|
||||
func (a *ASFPresencePong) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 16 {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("invalid ASF presence pong payload, length %v less than 16",
|
||||
len(data))
|
||||
}
|
||||
|
||||
a.BaseLayer.Contents = data[:16]
|
||||
a.BaseLayer.Payload = data[16:]
|
||||
|
||||
a.Enterprise = binary.BigEndian.Uint32(data[:4])
|
||||
copy(a.OEM[:], data[4:8]) // N.B. no byte order change
|
||||
a.IPMI = data[8]&uint8(ASFPresencePongEntityIPMI) != 0
|
||||
a.ASFv1 = data[8]&uint8(ASFPresencePongEntityASFv1) != 0
|
||||
a.SecurityExtensions = data[9]&uint8(ASFPresencePongInteractionSecurityExtensions) != 0
|
||||
a.DASH = data[9]&uint8(ASFPresencePongInteractionDASH) != 0
|
||||
// ignore remaining 6 bytes; should be set to 0s
|
||||
return nil
|
||||
}
|
||||
|
||||
// NextLayerType returns LayerTypePayload, as there are no further layers to
|
||||
// decode. This partially satisfies DecodingLayer.
|
||||
func (a *ASFPresencePong) NextLayerType() gopacket.LayerType {
|
||||
return gopacket.LayerTypePayload
|
||||
}
|
||||
|
||||
// SerializeTo writes the serialized fom of this layer into the SerializeBuffer,
|
||||
// partially satisfying SerializableLayer.
|
||||
func (a *ASFPresencePong) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
|
||||
bytes, err := b.PrependBytes(16)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
binary.BigEndian.PutUint32(bytes[:4], a.Enterprise)
|
||||
|
||||
copy(bytes[4:8], a.OEM[:])
|
||||
|
||||
bytes[8] = 0
|
||||
if a.IPMI {
|
||||
bytes[8] |= uint8(ASFPresencePongEntityIPMI)
|
||||
}
|
||||
if a.ASFv1 {
|
||||
bytes[8] |= uint8(ASFPresencePongEntityASFv1)
|
||||
}
|
||||
|
||||
bytes[9] = 0
|
||||
if a.SecurityExtensions {
|
||||
bytes[9] |= uint8(ASFPresencePongInteractionSecurityExtensions)
|
||||
}
|
||||
if a.DASH {
|
||||
bytes[9] |= uint8(ASFPresencePongInteractionDASH)
|
||||
}
|
||||
|
||||
// zero-out remaining 6 bytes
|
||||
for i := 10; i < len(bytes); i++ {
|
||||
bytes[i] = 0x00
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// decodeASFPresencePong decodes the byte slice into an RMCP-ASF Presence Pong
|
||||
// struct.
|
||||
func decodeASFPresencePong(data []byte, p gopacket.PacketBuilder) error {
|
||||
return decodingLayerDecoder(&ASFPresencePong{}, data, p)
|
||||
}
|
||||
+7
@@ -124,6 +124,10 @@ func (d *DHCPv4) LayerType() gopacket.LayerType { return LayerTypeDHCPv4 }
|
||||
|
||||
// DecodeFromBytes decodes the given bytes into this layer.
|
||||
func (d *DHCPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 240 {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("DHCPv4 length %d too short", len(data))
|
||||
}
|
||||
d.Options = d.Options[:0]
|
||||
d.Operation = DHCPOp(data[0])
|
||||
d.HardwareType = LinkType(data[1])
|
||||
@@ -168,6 +172,9 @@ func (d *DHCPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error
|
||||
start += int(o.Length) + 2
|
||||
}
|
||||
}
|
||||
|
||||
d.Contents = data
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -88,12 +88,20 @@ func (d *DHCPv6) LayerType() gopacket.LayerType { return LayerTypeDHCPv6 }
|
||||
|
||||
// DecodeFromBytes decodes the given bytes into this layer.
|
||||
func (d *DHCPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 4 {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("DHCPv6 length %d too short", len(data))
|
||||
}
|
||||
d.BaseLayer = BaseLayer{Contents: data}
|
||||
d.Options = d.Options[:0]
|
||||
d.MsgType = DHCPv6MsgType(data[0])
|
||||
|
||||
offset := 0
|
||||
if d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply {
|
||||
if len(data) < 34 {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("DHCPv6 length %d too short for message type %d", len(data), d.MsgType)
|
||||
}
|
||||
d.HopCount = data[1]
|
||||
d.LinkAddr = net.IP(data[2:18])
|
||||
d.PeerAddr = net.IP(data[18:34])
|
||||
|
||||
+68
-38
@@ -52,25 +52,26 @@ type DNSType uint16
|
||||
|
||||
// DNSType known values.
|
||||
const (
|
||||
DNSTypeA DNSType = 1 // a host address
|
||||
DNSTypeNS DNSType = 2 // an authoritative name server
|
||||
DNSTypeMD DNSType = 3 // a mail destination (Obsolete - use MX)
|
||||
DNSTypeMF DNSType = 4 // a mail forwarder (Obsolete - use MX)
|
||||
DNSTypeCNAME DNSType = 5 // the canonical name for an alias
|
||||
DNSTypeSOA DNSType = 6 // marks the start of a zone of authority
|
||||
DNSTypeMB DNSType = 7 // a mailbox domain name (EXPERIMENTAL)
|
||||
DNSTypeMG DNSType = 8 // a mail group member (EXPERIMENTAL)
|
||||
DNSTypeMR DNSType = 9 // a mail rename domain name (EXPERIMENTAL)
|
||||
DNSTypeNULL DNSType = 10 // a null RR (EXPERIMENTAL)
|
||||
DNSTypeWKS DNSType = 11 // a well known service description
|
||||
DNSTypePTR DNSType = 12 // a domain name pointer
|
||||
DNSTypeHINFO DNSType = 13 // host information
|
||||
DNSTypeMINFO DNSType = 14 // mailbox or mail list information
|
||||
DNSTypeMX DNSType = 15 // mail exchange
|
||||
DNSTypeTXT DNSType = 16 // text strings
|
||||
DNSTypeAAAA DNSType = 28 // a IPv6 host address [RFC3596]
|
||||
DNSTypeSRV DNSType = 33 // server discovery [RFC2782] [RFC6195]
|
||||
DNSTypeOPT DNSType = 41 // OPT Pseudo-RR [RFC6891]
|
||||
DNSTypeA DNSType = 1 // a host address
|
||||
DNSTypeNS DNSType = 2 // an authoritative name server
|
||||
DNSTypeMD DNSType = 3 // a mail destination (Obsolete - use MX)
|
||||
DNSTypeMF DNSType = 4 // a mail forwarder (Obsolete - use MX)
|
||||
DNSTypeCNAME DNSType = 5 // the canonical name for an alias
|
||||
DNSTypeSOA DNSType = 6 // marks the start of a zone of authority
|
||||
DNSTypeMB DNSType = 7 // a mailbox domain name (EXPERIMENTAL)
|
||||
DNSTypeMG DNSType = 8 // a mail group member (EXPERIMENTAL)
|
||||
DNSTypeMR DNSType = 9 // a mail rename domain name (EXPERIMENTAL)
|
||||
DNSTypeNULL DNSType = 10 // a null RR (EXPERIMENTAL)
|
||||
DNSTypeWKS DNSType = 11 // a well known service description
|
||||
DNSTypePTR DNSType = 12 // a domain name pointer
|
||||
DNSTypeHINFO DNSType = 13 // host information
|
||||
DNSTypeMINFO DNSType = 14 // mailbox or mail list information
|
||||
DNSTypeMX DNSType = 15 // mail exchange
|
||||
DNSTypeTXT DNSType = 16 // text strings
|
||||
DNSTypeAAAA DNSType = 28 // a IPv6 host address [RFC3596]
|
||||
DNSTypeSRV DNSType = 33 // server discovery [RFC2782] [RFC6195]
|
||||
DNSTypeOPT DNSType = 41 // OPT Pseudo-RR [RFC6891]
|
||||
DNSTypeURI DNSType = 256 // URI RR [RFC7553]
|
||||
)
|
||||
|
||||
func (dt DNSType) String() string {
|
||||
@@ -115,6 +116,8 @@ func (dt DNSType) String() string {
|
||||
return "SRV"
|
||||
case DNSTypeOPT:
|
||||
return "OPT"
|
||||
case DNSTypeURI:
|
||||
return "URI"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,25 +126,26 @@ type DNSResponseCode uint8
|
||||
|
||||
// DNSResponseCode known values.
|
||||
const (
|
||||
DNSResponseCodeNoErr DNSResponseCode = 0 // No error
|
||||
DNSResponseCodeFormErr DNSResponseCode = 1 // Format Error [RFC1035]
|
||||
DNSResponseCodeServFail DNSResponseCode = 2 // Server Failure [RFC1035]
|
||||
DNSResponseCodeNXDomain DNSResponseCode = 3 // Non-Existent Domain [RFC1035]
|
||||
DNSResponseCodeNotImp DNSResponseCode = 4 // Not Implemented [RFC1035]
|
||||
DNSResponseCodeRefused DNSResponseCode = 5 // Query Refused [RFC1035]
|
||||
DNSResponseCodeYXDomain DNSResponseCode = 6 // Name Exists when it should not [RFC2136]
|
||||
DNSResponseCodeYXRRSet DNSResponseCode = 7 // RR Set Exists when it should not [RFC2136]
|
||||
DNSResponseCodeNXRRSet DNSResponseCode = 8 // RR Set that should exist does not [RFC2136]
|
||||
DNSResponseCodeNotAuth DNSResponseCode = 9 // Server Not Authoritative for zone [RFC2136]
|
||||
DNSResponseCodeNotZone DNSResponseCode = 10 // Name not contained in zone [RFC2136]
|
||||
DNSResponseCodeBadVers DNSResponseCode = 16 // Bad OPT Version [RFC2671]
|
||||
DNSResponseCodeBadSig DNSResponseCode = 16 // TSIG Signature Failure [RFC2845]
|
||||
DNSResponseCodeBadKey DNSResponseCode = 17 // Key not recognized [RFC2845]
|
||||
DNSResponseCodeBadTime DNSResponseCode = 18 // Signature out of time window [RFC2845]
|
||||
DNSResponseCodeBadMode DNSResponseCode = 19 // Bad TKEY Mode [RFC2930]
|
||||
DNSResponseCodeBadName DNSResponseCode = 20 // Duplicate key name [RFC2930]
|
||||
DNSResponseCodeBadAlg DNSResponseCode = 21 // Algorithm not supported [RFC2930]
|
||||
DNSResponseCodeBadTruc DNSResponseCode = 22 // Bad Truncation [RFC4635]
|
||||
DNSResponseCodeNoErr DNSResponseCode = 0 // No error
|
||||
DNSResponseCodeFormErr DNSResponseCode = 1 // Format Error [RFC1035]
|
||||
DNSResponseCodeServFail DNSResponseCode = 2 // Server Failure [RFC1035]
|
||||
DNSResponseCodeNXDomain DNSResponseCode = 3 // Non-Existent Domain [RFC1035]
|
||||
DNSResponseCodeNotImp DNSResponseCode = 4 // Not Implemented [RFC1035]
|
||||
DNSResponseCodeRefused DNSResponseCode = 5 // Query Refused [RFC1035]
|
||||
DNSResponseCodeYXDomain DNSResponseCode = 6 // Name Exists when it should not [RFC2136]
|
||||
DNSResponseCodeYXRRSet DNSResponseCode = 7 // RR Set Exists when it should not [RFC2136]
|
||||
DNSResponseCodeNXRRSet DNSResponseCode = 8 // RR Set that should exist does not [RFC2136]
|
||||
DNSResponseCodeNotAuth DNSResponseCode = 9 // Server Not Authoritative for zone [RFC2136]
|
||||
DNSResponseCodeNotZone DNSResponseCode = 10 // Name not contained in zone [RFC2136]
|
||||
DNSResponseCodeBadVers DNSResponseCode = 16 // Bad OPT Version [RFC2671]
|
||||
DNSResponseCodeBadSig DNSResponseCode = 16 // TSIG Signature Failure [RFC2845]
|
||||
DNSResponseCodeBadKey DNSResponseCode = 17 // Key not recognized [RFC2845]
|
||||
DNSResponseCodeBadTime DNSResponseCode = 18 // Signature out of time window [RFC2845]
|
||||
DNSResponseCodeBadMode DNSResponseCode = 19 // Bad TKEY Mode [RFC2930]
|
||||
DNSResponseCodeBadName DNSResponseCode = 20 // Duplicate key name [RFC2930]
|
||||
DNSResponseCodeBadAlg DNSResponseCode = 21 // Algorithm not supported [RFC2930]
|
||||
DNSResponseCodeBadTruc DNSResponseCode = 22 // Bad Truncation [RFC4635]
|
||||
DNSResponseCodeBadCookie DNSResponseCode = 23 // Bad/missing Server Cookie [RFC7873]
|
||||
)
|
||||
|
||||
func (drc DNSResponseCode) String() string {
|
||||
@@ -184,6 +188,8 @@ func (drc DNSResponseCode) String() string {
|
||||
return "Algorithm not supported"
|
||||
case DNSResponseCodeBadTruc:
|
||||
return "Bad Truncation"
|
||||
case DNSResponseCodeBadCookie:
|
||||
return "Bad Cookie"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,6 +373,10 @@ func (d *DNS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
d.Additionals = d.Additionals[:i] // strip off erroneous value
|
||||
return err
|
||||
}
|
||||
// extract extended RCODE from OPT RRs, RFC 6891 section 6.1.3
|
||||
if d.Additionals[i].Type == DNSTypeOPT {
|
||||
d.ResponseCode = DNSResponseCode(uint8(d.ResponseCode) | uint8(d.Additionals[i].TTL>>20&0xF0))
|
||||
}
|
||||
}
|
||||
|
||||
if uint16(len(d.Questions)) != d.QDCount {
|
||||
@@ -427,6 +437,8 @@ func recSize(rr *DNSResourceRecord) int {
|
||||
return l
|
||||
case DNSTypeSRV:
|
||||
return 6 + len(rr.SRV.Name) + 2
|
||||
case DNSTypeURI:
|
||||
return 4 + len(rr.URI.Target)
|
||||
case DNSTypeOPT:
|
||||
l := len(rr.OPT) * 4
|
||||
for _, opt := range rr.OPT {
|
||||
@@ -684,6 +696,7 @@ type DNSResourceRecord struct {
|
||||
SRV DNSSRV
|
||||
MX DNSMX
|
||||
OPT []DNSOPT // See RFC 6891, section 6.1.2
|
||||
URI DNSURI
|
||||
|
||||
// Undecoded TXT for backward compatibility
|
||||
TXT []byte
|
||||
@@ -781,6 +794,10 @@ func (rr *DNSResourceRecord) encode(data []byte, offset int, opts gopacket.Seria
|
||||
binary.BigEndian.PutUint16(data[noff+12:], rr.SRV.Weight)
|
||||
binary.BigEndian.PutUint16(data[noff+14:], rr.SRV.Port)
|
||||
encodeName(rr.SRV.Name, data, noff+16)
|
||||
case DNSTypeURI:
|
||||
binary.BigEndian.PutUint16(data[noff+10:], rr.URI.Priority)
|
||||
binary.BigEndian.PutUint16(data[noff+12:], rr.URI.Weight)
|
||||
copy(data[noff+14:], rr.URI.Target)
|
||||
case DNSTypeOPT:
|
||||
noff2 := noff + 10
|
||||
for _, opt := range rr.OPT {
|
||||
@@ -813,6 +830,9 @@ func (rr *DNSResourceRecord) String() string {
|
||||
}
|
||||
return "OPT " + strings.Join(opts, ",")
|
||||
}
|
||||
if rr.Type == DNSTypeURI {
|
||||
return fmt.Sprintf("URI %d %d %s", rr.URI.Priority, rr.URI.Weight, string(rr.URI.Target))
|
||||
}
|
||||
if rr.Class == DNSClassIN {
|
||||
switch rr.Type {
|
||||
case DNSTypeA, DNSTypeAAAA:
|
||||
@@ -924,6 +944,10 @@ func (rr *DNSResourceRecord) decodeRData(data []byte, offset int, buffer *[]byte
|
||||
return err
|
||||
}
|
||||
rr.MX.Name = name
|
||||
case DNSTypeURI:
|
||||
rr.URI.Priority = binary.BigEndian.Uint16(data[offset : offset+2])
|
||||
rr.URI.Weight = binary.BigEndian.Uint16(data[offset+2 : offset+4])
|
||||
rr.URI.Target = rr.Data[4:]
|
||||
case DNSTypeSRV:
|
||||
rr.SRV.Priority = binary.BigEndian.Uint16(data[offset : offset+2])
|
||||
rr.SRV.Weight = binary.BigEndian.Uint16(data[offset+2 : offset+4])
|
||||
@@ -964,6 +988,12 @@ type DNSMX struct {
|
||||
Name []byte
|
||||
}
|
||||
|
||||
// DNSURI is a URI record, defining a target (URI) of a server/service
|
||||
type DNSURI struct {
|
||||
Priority, Weight uint16
|
||||
Target []byte
|
||||
}
|
||||
|
||||
// DNSOptionCode represents the code of a DNS Option, see RFC6891, section 6.1.2
|
||||
type DNSOptionCode uint16
|
||||
|
||||
|
||||
+1
@@ -922,6 +922,7 @@ func (m *Dot11) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
}
|
||||
m.Type = Dot11Type((data[0])&0xFC) >> 2
|
||||
|
||||
m.DataLayer = nil
|
||||
m.Proto = uint8(data[0]) & 0x0003
|
||||
m.Flags = Dot11Flags(data[1])
|
||||
m.DurationID = binary.LittleEndian.Uint16(data[2:4])
|
||||
|
||||
+4
@@ -27,6 +27,10 @@ func (d *Dot1Q) LayerType() gopacket.LayerType { return LayerTypeDot1Q }
|
||||
|
||||
// DecodeFromBytes decodes the given bytes into this layer.
|
||||
func (d *Dot1Q) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 4 {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("802.1Q tag length %d too short", len(data))
|
||||
}
|
||||
d.Priority = (data[0] & 0xE0) >> 5
|
||||
d.DropEligible = data[0]&0x10 != 0
|
||||
d.VLANIdentifier = binary.BigEndian.Uint16(data[:2]) & 0x0FFF
|
||||
|
||||
+8
@@ -47,9 +47,17 @@ func (e *EAP) LayerType() gopacket.LayerType { return LayerTypeEAP }
|
||||
|
||||
// DecodeFromBytes decodes the given bytes into this layer.
|
||||
func (e *EAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 4 {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("EAP length %d too short", len(data))
|
||||
}
|
||||
e.Code = EAPCode(data[0])
|
||||
e.Id = data[1]
|
||||
e.Length = binary.BigEndian.Uint16(data[2:4])
|
||||
if len(data) < int(e.Length) {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("EAP length %d too short, %d expected", len(data), e.Length)
|
||||
}
|
||||
switch {
|
||||
case e.Length > 4:
|
||||
e.Type = EAPType(data[4])
|
||||
|
||||
+4
@@ -25,6 +25,10 @@ func (e *EAPOL) LayerType() gopacket.LayerType { return LayerTypeEAPOL }
|
||||
|
||||
// DecodeFromBytes decodes the given bytes into this layer.
|
||||
func (e *EAPOL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 4 {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("EAPOL length %d too short", len(data))
|
||||
}
|
||||
e.Version = data[0]
|
||||
e.Type = EAPOLType(data[1])
|
||||
e.Length = binary.BigEndian.Uint16(data[2:4])
|
||||
|
||||
+2
-9
@@ -8,7 +8,6 @@
|
||||
package layers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
@@ -26,14 +25,6 @@ type EnumMetadata struct {
|
||||
LayerType gopacket.LayerType
|
||||
}
|
||||
|
||||
// errorFunc returns a decoder that spits out a specific error message.
|
||||
func errorFunc(msg string) gopacket.Decoder {
|
||||
var e = errors.New(msg)
|
||||
return gopacket.DecodeFunc(func([]byte, gopacket.PacketBuilder) error {
|
||||
return e
|
||||
})
|
||||
}
|
||||
|
||||
// EthernetType is an enumeration of ethernet type values, and acts as a decoder
|
||||
// for any type it supports.
|
||||
type EthernetType uint16
|
||||
@@ -130,6 +121,8 @@ const (
|
||||
LinkTypeLinuxIRDA LinkType = 144
|
||||
LinkTypeLinuxLAPD LinkType = 177
|
||||
LinkTypeLinuxUSB LinkType = 220
|
||||
LinkTypeFC2 LinkType = 224
|
||||
LinkTypeFC2Framed LinkType = 225
|
||||
LinkTypeIPv4 LinkType = 228
|
||||
LinkTypeIPv6 LinkType = 229
|
||||
)
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// Copyright 2019 The GoPacket Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license that can be found
|
||||
// in the LICENSE file in the root of the source tree.
|
||||
|
||||
package layers
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
)
|
||||
|
||||
// FuzzLayer is a fuzz target for the layers package of gopacket
|
||||
// A fuzz target is a function processing a binary blob (byte slice)
|
||||
// The process here is to interpret this data as a packet, and print the layers contents.
|
||||
// The decoding options and the starting layer are encoded in the first bytes.
|
||||
// The function returns 1 if this is a valid packet (no error layer)
|
||||
func FuzzLayer(data []byte) int {
|
||||
if len(data) < 3 {
|
||||
return 0
|
||||
}
|
||||
// use the first two bytes to choose the top level layer
|
||||
startLayer := binary.BigEndian.Uint16(data[:2])
|
||||
var fuzzOpts = gopacket.DecodeOptions{
|
||||
Lazy: data[2]&0x1 != 0,
|
||||
NoCopy: data[2]&0x2 != 0,
|
||||
SkipDecodeRecovery: data[2]&0x4 != 0,
|
||||
DecodeStreamsAsDatagrams: data[2]&0x8 != 0,
|
||||
}
|
||||
p := gopacket.NewPacket(data[3:], gopacket.LayerType(startLayer), fuzzOpts)
|
||||
for _, l := range p.Layers() {
|
||||
gopacket.LayerString(l)
|
||||
}
|
||||
if p.ErrorLayer() != nil {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
+3
@@ -143,6 +143,9 @@ var (
|
||||
LayerTypeMLDv2MulticastListenerQuery = gopacket.RegisterLayerType(139, gopacket.LayerTypeMetadata{Name: "MLDv2MulticastListenerQuery", Decoder: gopacket.DecodeFunc(decodeMLDv2MulticastListenerQuery)})
|
||||
LayerTypeTLS = gopacket.RegisterLayerType(140, gopacket.LayerTypeMetadata{Name: "TLS", Decoder: gopacket.DecodeFunc(decodeTLS)})
|
||||
LayerTypeModbusTCP = gopacket.RegisterLayerType(141, gopacket.LayerTypeMetadata{Name: "ModbusTCP", Decoder: gopacket.DecodeFunc(decodeModbusTCP)})
|
||||
LayerTypeRMCP = gopacket.RegisterLayerType(142, gopacket.LayerTypeMetadata{Name: "RMCP", Decoder: gopacket.DecodeFunc(decodeRMCP)})
|
||||
LayerTypeASF = gopacket.RegisterLayerType(143, gopacket.LayerTypeMetadata{Name: "ASF", Decoder: gopacket.DecodeFunc(decodeASF)})
|
||||
LayerTypeASFPresencePong = gopacket.RegisterLayerType(144, gopacket.LayerTypeMetadata{Name: "ASFPresencePong", Decoder: gopacket.DecodeFunc(decodeASFPresencePong)})
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
+29
@@ -38,6 +38,7 @@ const (
|
||||
ASExternalLSAtypeV2 = 0x5
|
||||
ASExternalLSAtype = 0x4005
|
||||
NSSALSAtype = 0x2007
|
||||
NSSALSAtypeV2 = 0x7
|
||||
LinkLSAtype = 0x0008
|
||||
IntraAreaPrefixLSAtype = 0x2009
|
||||
)
|
||||
@@ -129,6 +130,12 @@ type NetworkLSA struct {
|
||||
AttachedRouter []uint32
|
||||
}
|
||||
|
||||
// NetworkLSAV2 is the struct from RFC 2328 A.4.3.
|
||||
type NetworkLSAV2 struct {
|
||||
NetworkMask uint32
|
||||
AttachedRouter []uint32
|
||||
}
|
||||
|
||||
// RouterV2 extends RouterLSAV2
|
||||
type RouterV2 struct {
|
||||
Type uint8
|
||||
@@ -288,12 +295,24 @@ func extractLSAInformation(lstype, lsalength uint16, data []byte) (interface{},
|
||||
switch lstype {
|
||||
case RouterLSAtypeV2:
|
||||
var routers []RouterV2
|
||||
var j uint32
|
||||
for j = 24; j < uint32(lsalength); j += 12 {
|
||||
router := RouterV2{
|
||||
LinkID: binary.BigEndian.Uint32(data[j : j+4]),
|
||||
LinkData: binary.BigEndian.Uint32(data[j+4 : j+8]),
|
||||
Type: uint8(data[j+8]),
|
||||
Metric: binary.BigEndian.Uint16(data[j+10 : j+12]),
|
||||
}
|
||||
routers = append(routers, router)
|
||||
}
|
||||
links := binary.BigEndian.Uint16(data[22:24])
|
||||
content = RouterLSAV2{
|
||||
Flags: data[20],
|
||||
Links: links,
|
||||
Routers: routers,
|
||||
}
|
||||
case NSSALSAtypeV2:
|
||||
fallthrough
|
||||
case ASExternalLSAtypeV2:
|
||||
content = ASExternalLSAV2{
|
||||
NetworkMask: binary.BigEndian.Uint32(data[20:24]),
|
||||
@@ -302,6 +321,16 @@ func extractLSAInformation(lstype, lsalength uint16, data []byte) (interface{},
|
||||
ForwardingAddress: binary.BigEndian.Uint32(data[28:32]),
|
||||
ExternalRouteTag: binary.BigEndian.Uint32(data[32:36]),
|
||||
}
|
||||
case NetworkLSAtypeV2:
|
||||
var routers []uint32
|
||||
var j uint32
|
||||
for j = 24; j < uint32(lsalength); j += 4 {
|
||||
routers = append(routers, binary.BigEndian.Uint32(data[j:j+4]))
|
||||
}
|
||||
content = NetworkLSAV2{
|
||||
NetworkMask: binary.BigEndian.Uint32(data[20:24]),
|
||||
AttachedRouter: routers,
|
||||
}
|
||||
case RouterLSAtype:
|
||||
var routers []Router
|
||||
var j uint32
|
||||
|
||||
+1
@@ -115,6 +115,7 @@ var udpPortLayerType = [65536]gopacket.LayerType{
|
||||
6081: LayerTypeGeneve,
|
||||
3784: LayerTypeBFD,
|
||||
2152: LayerTypeGTPv1U,
|
||||
623: LayerTypeRMCP,
|
||||
}
|
||||
|
||||
// RegisterUDPPortLayerType creates a new mapping between a UDPPort
|
||||
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
// Copyright 2019 The GoPacket Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license that can be found
|
||||
// in the LICENSE file in the root of the source tree.
|
||||
|
||||
package layers
|
||||
|
||||
// This file implements the ASF-RMCP header specified in section 3.2.2.2 of
|
||||
// https://www.dmtf.org/sites/default/files/standards/documents/DSP0136.pdf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
)
|
||||
|
||||
// RMCPClass is the class of a RMCP layer's payload, e.g. ASF or IPMI. This is a
|
||||
// 4-bit unsigned int on the wire; all but 6 (ASF), 7 (IPMI) and 8 (OEM-defined)
|
||||
// are currently reserved.
|
||||
type RMCPClass uint8
|
||||
|
||||
// LayerType returns the payload layer type corresponding to a RMCP class.
|
||||
func (c RMCPClass) LayerType() gopacket.LayerType {
|
||||
if lt := rmcpClassLayerTypes[uint8(c)]; lt != 0 {
|
||||
return lt
|
||||
}
|
||||
return gopacket.LayerTypePayload
|
||||
}
|
||||
|
||||
func (c RMCPClass) String() string {
|
||||
return fmt.Sprintf("%v(%v)", uint8(c), c.LayerType())
|
||||
}
|
||||
|
||||
const (
|
||||
// RMCPVersion1 identifies RMCP v1.0 in the Version header field. Lower
|
||||
// values are considered legacy, while higher values are reserved by the
|
||||
// specification.
|
||||
RMCPVersion1 uint8 = 0x06
|
||||
|
||||
// RMCPNormal indicates a "normal" message, i.e. not an acknowledgement.
|
||||
RMCPNormal uint8 = 0
|
||||
|
||||
// RMCPAck indicates a message is acknowledging a received normal message.
|
||||
RMCPAck uint8 = 1 << 7
|
||||
|
||||
// RMCPClassASF identifies an RMCP message as containing an ASF-RMCP
|
||||
// payload.
|
||||
RMCPClassASF RMCPClass = 0x06
|
||||
|
||||
// RMCPClassIPMI identifies an RMCP message as containing an IPMI payload.
|
||||
RMCPClassIPMI RMCPClass = 0x07
|
||||
|
||||
// RMCPClassOEM identifies an RMCP message as containing an OEM-defined
|
||||
// payload.
|
||||
RMCPClassOEM RMCPClass = 0x08
|
||||
)
|
||||
|
||||
var (
|
||||
rmcpClassLayerTypes = [16]gopacket.LayerType{
|
||||
RMCPClassASF: LayerTypeASF,
|
||||
// RMCPClassIPMI is to implement; RMCPClassOEM is deliberately not
|
||||
// implemented, so we return LayerTypePayload
|
||||
}
|
||||
)
|
||||
|
||||
// RegisterRMCPLayerType allows specifying that the payload of a RMCP packet of
|
||||
// a certain class should processed by the provided layer type. This overrides
|
||||
// any existing registrations, including defaults.
|
||||
func RegisterRMCPLayerType(c RMCPClass, l gopacket.LayerType) {
|
||||
rmcpClassLayerTypes[c] = l
|
||||
}
|
||||
|
||||
// RMCP describes the format of an RMCP header, which forms a UDP payload. See
|
||||
// section 3.2.2.2.
|
||||
type RMCP struct {
|
||||
BaseLayer
|
||||
|
||||
// Version identifies the version of the RMCP header. 0x06 indicates RMCP
|
||||
// v1.0; lower values are legacy, higher values are reserved.
|
||||
Version uint8
|
||||
|
||||
// Sequence is the sequence number assicated with the message. Note that
|
||||
// this rolls over to 0 after 254, not 255. Seq num 255 indicates the
|
||||
// receiver must not send an ACK.
|
||||
Sequence uint8
|
||||
|
||||
// Ack indicates whether this packet is an acknowledgement. If it is, the
|
||||
// payload will be empty.
|
||||
Ack bool
|
||||
|
||||
// Class idicates the structure of the payload. There are only 2^4 valid
|
||||
// values, however there is no uint4 data type. N.B. the Ack bit has been
|
||||
// split off into another field. The most significant 4 bits of this field
|
||||
// will always be 0.
|
||||
Class RMCPClass
|
||||
}
|
||||
|
||||
// LayerType returns LayerTypeRMCP. It partially satisfies Layer and
|
||||
// SerializableLayer.
|
||||
func (*RMCP) LayerType() gopacket.LayerType {
|
||||
return LayerTypeRMCP
|
||||
}
|
||||
|
||||
// CanDecode returns LayerTypeRMCP. It partially satisfies DecodingLayer.
|
||||
func (r *RMCP) CanDecode() gopacket.LayerClass {
|
||||
return r.LayerType()
|
||||
}
|
||||
|
||||
// DecodeFromBytes makes the layer represent the provided bytes. It partially
|
||||
// satisfies DecodingLayer.
|
||||
func (r *RMCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 4 {
|
||||
df.SetTruncated()
|
||||
return fmt.Errorf("invalid RMCP header, length %v less than 4",
|
||||
len(data))
|
||||
}
|
||||
|
||||
r.BaseLayer.Contents = data[:4]
|
||||
r.BaseLayer.Payload = data[4:]
|
||||
|
||||
r.Version = uint8(data[0])
|
||||
// 1 byte reserved
|
||||
r.Sequence = uint8(data[2])
|
||||
r.Ack = data[3]&RMCPAck != 0
|
||||
r.Class = RMCPClass(data[3] & 0xF)
|
||||
return nil
|
||||
}
|
||||
|
||||
// NextLayerType returns the data layer of this RMCP layer. This partially
|
||||
// satisfies DecodingLayer.
|
||||
func (r *RMCP) NextLayerType() gopacket.LayerType {
|
||||
return r.Class.LayerType()
|
||||
}
|
||||
|
||||
// Payload returns the data layer. It partially satisfies ApplicationLayer.
|
||||
func (r *RMCP) Payload() []byte {
|
||||
return r.BaseLayer.Payload
|
||||
}
|
||||
|
||||
// SerializeTo writes the serialized fom of this layer into the SerializeBuffer,
|
||||
// partially satisfying SerializableLayer.
|
||||
func (r *RMCP) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
|
||||
// The IPMI v1.5 spec contains a pad byte for frame sizes of certain lengths
|
||||
// to work around issues in LAN chips. This is no longer necessary as of
|
||||
// IPMI v2.0 (renamed to "legacy pad") so we do not attempt to add it. The
|
||||
// same approach is taken by FreeIPMI:
|
||||
// http://git.savannah.gnu.org/cgit/freeipmi.git/tree/libfreeipmi/interface/ipmi-lan-interface.c?id=b5ffcd38317daf42074458879f4c55ba6804a595#n836
|
||||
bytes, err := b.PrependBytes(4)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bytes[0] = r.Version
|
||||
bytes[1] = 0x00
|
||||
bytes[2] = r.Sequence
|
||||
bytes[3] = bool2uint8(r.Ack)<<7 | uint8(r.Class) // thanks, BFD layer
|
||||
return nil
|
||||
}
|
||||
|
||||
// decodeRMCP decodes the byte slice into an RMCP type, and sets the application
|
||||
// layer to it.
|
||||
func decodeRMCP(data []byte, p gopacket.PacketBuilder) error {
|
||||
rmcp := &RMCP{}
|
||||
err := rmcp.DecodeFromBytes(data, p)
|
||||
p.AddLayer(rmcp)
|
||||
p.SetApplicationLayer(rmcp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return p.NextDecoder(rmcp.NextLayerType())
|
||||
}
|
||||
+1
-1
@@ -25,7 +25,7 @@ Specification has this to say:
|
||||
be used for all interfaces.
|
||||
|
||||
This decoder only supports the compact form, because that is the only
|
||||
one for which data was avaialble.
|
||||
one for which data was available.
|
||||
|
||||
The datagram is composed of one or more samples of type flow or counter,
|
||||
and each sample is composed of one or more records describing the sample.
|
||||
|
||||
+6
-6
@@ -245,14 +245,11 @@ func (s *SIP) NextLayerType() gopacket.LayerType {
|
||||
|
||||
// DecodeFromBytes decodes the slice into the SIP struct.
|
||||
func (s *SIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
|
||||
// Init some vars for parsing follow-up
|
||||
var countLines int
|
||||
var line []byte
|
||||
var err error
|
||||
|
||||
// Clean leading new line
|
||||
data = bytes.Trim(data, "\n")
|
||||
var offset int
|
||||
|
||||
// Iterate on all lines of the SIP Headers
|
||||
// and stop when we reach the SDP (aka when the new line
|
||||
@@ -265,19 +262,21 @@ func (s *SIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
line, err = buffer.ReadBytes(byte('\n'))
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
if len(bytes.Trim(line, "\r\n")) > 0 {
|
||||
df.SetTruncated()
|
||||
}
|
||||
break
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
offset += len(line)
|
||||
|
||||
// Trim the new line delimiters
|
||||
line = bytes.Trim(line, "\r\n")
|
||||
|
||||
// Empty line, we hit Body
|
||||
// Putting packet remain in Paypload
|
||||
if len(line) == 0 {
|
||||
s.BaseLayer.Payload = buffer.Bytes()
|
||||
break
|
||||
}
|
||||
|
||||
@@ -298,6 +297,7 @@ func (s *SIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
|
||||
countLines++
|
||||
}
|
||||
s.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+2
-1
@@ -268,6 +268,7 @@ func (tcp *TCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
tcp.Payload = data[dataStart:]
|
||||
// From here on, data points just to the header options.
|
||||
data = data[20:dataStart]
|
||||
OPTIONS:
|
||||
for len(data) > 0 {
|
||||
tcp.Options = append(tcp.Options, TCPOption{OptionType: TCPOptionKind(data[0])})
|
||||
opt := &tcp.Options[len(tcp.Options)-1]
|
||||
@@ -275,7 +276,7 @@ func (tcp *TCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
case TCPOptionKindEndList: // End of options
|
||||
opt.OptionLength = 1
|
||||
tcp.Padding = data[1:]
|
||||
break
|
||||
break OPTIONS
|
||||
case TCPOptionKindNop: // 1 byte padding
|
||||
opt.OptionLength = 1
|
||||
default:
|
||||
|
||||
+27
-2
@@ -8,7 +8,9 @@ package layers
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
)
|
||||
|
||||
@@ -37,9 +39,21 @@ type VXLAN struct {
|
||||
// LayerType returns LayerTypeVXLAN
|
||||
func (vx *VXLAN) LayerType() gopacket.LayerType { return LayerTypeVXLAN }
|
||||
|
||||
func decodeVXLAN(data []byte, p gopacket.PacketBuilder) error {
|
||||
vx := &VXLAN{}
|
||||
// CanDecode returns the layer type this DecodingLayer can decode
|
||||
func (vx *VXLAN) CanDecode() gopacket.LayerClass {
|
||||
return LayerTypeVXLAN
|
||||
}
|
||||
|
||||
// NextLayerType retuns the next layer we should see after vxlan
|
||||
func (vx *VXLAN) NextLayerType() gopacket.LayerType {
|
||||
return LayerTypeEthernet
|
||||
}
|
||||
|
||||
// DecodeFromBytes takes a byte buffer and decodes
|
||||
func (vx *VXLAN) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
if len(data) < 8 {
|
||||
return errors.New("vxlan packet too small")
|
||||
}
|
||||
// VNI is a 24bit number, Uint32 requires 32 bits
|
||||
var buf [4]byte
|
||||
copy(buf[1:], data[4:7])
|
||||
@@ -59,6 +73,17 @@ func decodeVXLAN(data []byte, p gopacket.PacketBuilder) error {
|
||||
vx.Contents = data[:vxlanLength]
|
||||
vx.Payload = data[vxlanLength:]
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func decodeVXLAN(data []byte, p gopacket.PacketBuilder) error {
|
||||
vx := &VXLAN{}
|
||||
err := vx.DecodeFromBytes(data, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.AddLayer(vx)
|
||||
return p.NextDecoder(LinkTypeEthernet)
|
||||
}
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
// Copyright 2019 The GoPacket Authors. All rights reserved.
|
||||
|
||||
package gopacket
|
||||
|
||||
// Created by gen.go, don't edit manually
|
||||
// Generated at 2019-06-18 11:37:31.308731293 +0600 +06 m=+0.000842599
|
||||
|
||||
// LayersDecoder returns DecodingLayerFunc for specified
|
||||
// DecodingLayerContainer, LayerType value to start decoding with and
|
||||
// some DecodeFeedback.
|
||||
func LayersDecoder(dl DecodingLayerContainer, first LayerType, df DecodeFeedback) DecodingLayerFunc {
|
||||
firstDec, ok := dl.Decoder(first)
|
||||
if !ok {
|
||||
return func([]byte, *[]LayerType) (LayerType, error) {
|
||||
return first, nil
|
||||
}
|
||||
}
|
||||
if dlc, ok := dl.(DecodingLayerSparse); ok {
|
||||
return func(data []byte, decoded *[]LayerType) (LayerType, error) {
|
||||
*decoded = (*decoded)[:0] // Truncated decoded layers.
|
||||
typ := first
|
||||
decoder := firstDec
|
||||
for {
|
||||
if err := decoder.DecodeFromBytes(data, df); err != nil {
|
||||
return LayerTypeZero, err
|
||||
}
|
||||
*decoded = append(*decoded, typ)
|
||||
typ = decoder.NextLayerType()
|
||||
if data = decoder.LayerPayload(); len(data) == 0 {
|
||||
break
|
||||
}
|
||||
if decoder, ok = dlc.Decoder(typ); !ok {
|
||||
return typ, nil
|
||||
}
|
||||
}
|
||||
return LayerTypeZero, nil
|
||||
}
|
||||
}
|
||||
if dlc, ok := dl.(DecodingLayerArray); ok {
|
||||
return func(data []byte, decoded *[]LayerType) (LayerType, error) {
|
||||
*decoded = (*decoded)[:0] // Truncated decoded layers.
|
||||
typ := first
|
||||
decoder := firstDec
|
||||
for {
|
||||
if err := decoder.DecodeFromBytes(data, df); err != nil {
|
||||
return LayerTypeZero, err
|
||||
}
|
||||
*decoded = append(*decoded, typ)
|
||||
typ = decoder.NextLayerType()
|
||||
if data = decoder.LayerPayload(); len(data) == 0 {
|
||||
break
|
||||
}
|
||||
if decoder, ok = dlc.Decoder(typ); !ok {
|
||||
return typ, nil
|
||||
}
|
||||
}
|
||||
return LayerTypeZero, nil
|
||||
}
|
||||
}
|
||||
if dlc, ok := dl.(DecodingLayerMap); ok {
|
||||
return func(data []byte, decoded *[]LayerType) (LayerType, error) {
|
||||
*decoded = (*decoded)[:0] // Truncated decoded layers.
|
||||
typ := first
|
||||
decoder := firstDec
|
||||
for {
|
||||
if err := decoder.DecodeFromBytes(data, df); err != nil {
|
||||
return LayerTypeZero, err
|
||||
}
|
||||
*decoded = append(*decoded, typ)
|
||||
typ = decoder.NextLayerType()
|
||||
if data = decoder.LayerPayload(); len(data) == 0 {
|
||||
break
|
||||
}
|
||||
if decoder, ok = dlc.Decoder(typ); !ok {
|
||||
return typ, nil
|
||||
}
|
||||
}
|
||||
return LayerTypeZero, nil
|
||||
}
|
||||
}
|
||||
dlc := dl
|
||||
return func(data []byte, decoded *[]LayerType) (LayerType, error) {
|
||||
*decoded = (*decoded)[:0] // Truncated decoded layers.
|
||||
typ := first
|
||||
decoder := firstDec
|
||||
for {
|
||||
if err := decoder.DecodeFromBytes(data, df); err != nil {
|
||||
return LayerTypeZero, err
|
||||
}
|
||||
*decoded = append(*decoded, typ)
|
||||
typ = decoder.NextLayerType()
|
||||
if data = decoder.LayerPayload(); len(data) == 0 {
|
||||
break
|
||||
}
|
||||
if decoder, ok = dlc.Decoder(typ); !ok {
|
||||
return typ, nil
|
||||
}
|
||||
}
|
||||
return LayerTypeZero, nil
|
||||
}
|
||||
}
|
||||
+169
-26
@@ -10,6 +10,12 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// A container for single LayerType->DecodingLayer mapping.
|
||||
type decodingLayerElem struct {
|
||||
typ LayerType
|
||||
dec DecodingLayer
|
||||
}
|
||||
|
||||
// DecodingLayer is an interface for packet layers that can decode themselves.
|
||||
//
|
||||
// The important part of DecodingLayer is that they decode themselves in-place.
|
||||
@@ -39,15 +45,150 @@ type DecodingLayer interface {
|
||||
LayerPayload() []byte
|
||||
}
|
||||
|
||||
// DecodingLayerFunc decodes given packet and stores decoded LayerType
|
||||
// values into specified slice. Returns either first encountered
|
||||
// unsupported LayerType value or decoding error. In case of success,
|
||||
// returns (LayerTypeZero, nil).
|
||||
type DecodingLayerFunc func([]byte, *[]LayerType) (LayerType, error)
|
||||
|
||||
// DecodingLayerContainer stores all DecodingLayer-s and serves as a
|
||||
// searching tool for DecodingLayerParser.
|
||||
type DecodingLayerContainer interface {
|
||||
// Put adds new DecodingLayer to container. The new instance of
|
||||
// the same DecodingLayerContainer is returned so it may be
|
||||
// implemented as a value receiver.
|
||||
Put(DecodingLayer) DecodingLayerContainer
|
||||
// Decoder returns DecodingLayer to decode given LayerType and
|
||||
// true if it was found. If no decoder found, return false.
|
||||
Decoder(LayerType) (DecodingLayer, bool)
|
||||
// LayersDecoder returns DecodingLayerFunc which decodes given
|
||||
// packet, starting with specified LayerType and DecodeFeedback.
|
||||
LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc
|
||||
}
|
||||
|
||||
// DecodingLayerSparse is a sparse array-based implementation of
|
||||
// DecodingLayerContainer. Each DecodingLayer is addressed in an
|
||||
// allocated slice by LayerType value itself. Though this is the
|
||||
// fastest container it may be memory-consuming if used with big
|
||||
// LayerType values.
|
||||
type DecodingLayerSparse []DecodingLayer
|
||||
|
||||
// Put implements DecodingLayerContainer interface.
|
||||
func (dl DecodingLayerSparse) Put(d DecodingLayer) DecodingLayerContainer {
|
||||
maxLayerType := LayerType(len(dl) - 1)
|
||||
for _, typ := range d.CanDecode().LayerTypes() {
|
||||
if typ > maxLayerType {
|
||||
maxLayerType = typ
|
||||
}
|
||||
}
|
||||
|
||||
if extra := maxLayerType - LayerType(len(dl)) + 1; extra > 0 {
|
||||
dl = append(dl, make([]DecodingLayer, extra)...)
|
||||
}
|
||||
|
||||
for _, typ := range d.CanDecode().LayerTypes() {
|
||||
dl[typ] = d
|
||||
}
|
||||
return dl
|
||||
}
|
||||
|
||||
// LayersDecoder implements DecodingLayerContainer interface.
|
||||
func (dl DecodingLayerSparse) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc {
|
||||
return LayersDecoder(dl, first, df)
|
||||
}
|
||||
|
||||
// Decoder implements DecodingLayerContainer interface.
|
||||
func (dl DecodingLayerSparse) Decoder(typ LayerType) (DecodingLayer, bool) {
|
||||
if int64(typ) < int64(len(dl)) {
|
||||
decoder := dl[typ]
|
||||
return decoder, decoder != nil
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// DecodingLayerArray is an array-based implementation of
|
||||
// DecodingLayerContainer. Each DecodingLayer is searched linearly in
|
||||
// an allocated slice in one-by-one fashion.
|
||||
type DecodingLayerArray []decodingLayerElem
|
||||
|
||||
// Put implements DecodingLayerContainer interface.
|
||||
func (dl DecodingLayerArray) Put(d DecodingLayer) DecodingLayerContainer {
|
||||
TYPES:
|
||||
for _, typ := range d.CanDecode().LayerTypes() {
|
||||
for i := range dl {
|
||||
if dl[i].typ == typ {
|
||||
dl[i].dec = d
|
||||
continue TYPES
|
||||
}
|
||||
}
|
||||
dl = append(dl, decodingLayerElem{typ, d})
|
||||
}
|
||||
return dl
|
||||
}
|
||||
|
||||
// Decoder implements DecodingLayerContainer interface.
|
||||
func (dl DecodingLayerArray) Decoder(typ LayerType) (DecodingLayer, bool) {
|
||||
for i := range dl {
|
||||
if dl[i].typ == typ {
|
||||
return dl[i].dec, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// LayersDecoder implements DecodingLayerContainer interface.
|
||||
func (dl DecodingLayerArray) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc {
|
||||
return LayersDecoder(dl, first, df)
|
||||
}
|
||||
|
||||
// DecodingLayerMap is an map-based implementation of
|
||||
// DecodingLayerContainer. Each DecodingLayer is searched in a map
|
||||
// hashed by LayerType value.
|
||||
type DecodingLayerMap map[LayerType]DecodingLayer
|
||||
|
||||
// Put implements DecodingLayerContainer interface.
|
||||
func (dl DecodingLayerMap) Put(d DecodingLayer) DecodingLayerContainer {
|
||||
for _, typ := range d.CanDecode().LayerTypes() {
|
||||
if dl == nil {
|
||||
dl = make(map[LayerType]DecodingLayer)
|
||||
}
|
||||
dl[typ] = d
|
||||
}
|
||||
return dl
|
||||
}
|
||||
|
||||
// Decoder implements DecodingLayerContainer interface.
|
||||
func (dl DecodingLayerMap) Decoder(typ LayerType) (DecodingLayer, bool) {
|
||||
d, ok := dl[typ]
|
||||
return d, ok
|
||||
}
|
||||
|
||||
// LayersDecoder implements DecodingLayerContainer interface.
|
||||
func (dl DecodingLayerMap) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc {
|
||||
return LayersDecoder(dl, first, df)
|
||||
}
|
||||
|
||||
// Static code check.
|
||||
var (
|
||||
_ = []DecodingLayerContainer{
|
||||
DecodingLayerSparse(nil),
|
||||
DecodingLayerMap(nil),
|
||||
DecodingLayerArray(nil),
|
||||
}
|
||||
)
|
||||
|
||||
// DecodingLayerParser parses a given set of layer types. See DecodeLayers for
|
||||
// more information on how DecodingLayerParser should be used.
|
||||
type DecodingLayerParser struct {
|
||||
// DecodingLayerParserOptions is the set of options available to the
|
||||
// user to define the parser's behavior.
|
||||
DecodingLayerParserOptions
|
||||
first LayerType
|
||||
decoders map[LayerType]DecodingLayer
|
||||
df DecodeFeedback
|
||||
dlc DecodingLayerContainer
|
||||
first LayerType
|
||||
df DecodeFeedback
|
||||
|
||||
decodeFunc DecodingLayerFunc
|
||||
|
||||
// Truncated is set when a decode layer detects that the packet has been
|
||||
// truncated.
|
||||
Truncated bool
|
||||
@@ -57,9 +198,7 @@ type DecodingLayerParser struct {
|
||||
// the decoding layer's CanDecode layers to the parser... should they be
|
||||
// encountered, they'll be parsed.
|
||||
func (l *DecodingLayerParser) AddDecodingLayer(d DecodingLayer) {
|
||||
for _, typ := range d.CanDecode().LayerTypes() {
|
||||
l.decoders[typ] = d
|
||||
}
|
||||
l.SetDecodingLayerContainer(l.dlc.Put(d))
|
||||
}
|
||||
|
||||
// SetTruncated is used by DecodingLayers to set the Truncated boolean in the
|
||||
@@ -77,18 +216,30 @@ func (l *DecodingLayerParser) SetTruncated() {
|
||||
// subsequently decoded layers to find the next relevant decoder. Should a
|
||||
// deoder not be available for the layer type returned by NextLayerType,
|
||||
// decoding will stop.
|
||||
//
|
||||
// NewDecodingLayerParser uses DecodingLayerMap container by
|
||||
// default.
|
||||
func NewDecodingLayerParser(first LayerType, decoders ...DecodingLayer) *DecodingLayerParser {
|
||||
dlp := &DecodingLayerParser{
|
||||
decoders: make(map[LayerType]DecodingLayer),
|
||||
first: first,
|
||||
}
|
||||
dlp := &DecodingLayerParser{first: first}
|
||||
dlp.df = dlp // Cast this once to the interface
|
||||
// default container
|
||||
dlc := DecodingLayerContainer(DecodingLayerMap(make(map[LayerType]DecodingLayer)))
|
||||
for _, d := range decoders {
|
||||
dlp.AddDecodingLayer(d)
|
||||
dlc = dlc.Put(d)
|
||||
}
|
||||
|
||||
dlp.SetDecodingLayerContainer(dlc)
|
||||
return dlp
|
||||
}
|
||||
|
||||
// SetDecodingLayerContainer specifies container with decoders. This
|
||||
// call replaces all decoders already registered in given instance of
|
||||
// DecodingLayerParser.
|
||||
func (l *DecodingLayerParser) SetDecodingLayerContainer(dlc DecodingLayerContainer) {
|
||||
l.dlc = dlc
|
||||
l.decodeFunc = l.dlc.LayersDecoder(l.first, l.df)
|
||||
}
|
||||
|
||||
// DecodeLayers decodes as many layers as possible from the given data. It
|
||||
// initially treats the data as layer type 'typ', then uses NextLayerType on
|
||||
// each subsequent decoded layer until it gets to a layer type it doesn't know
|
||||
@@ -153,23 +304,15 @@ func (l *DecodingLayerParser) DecodeLayers(data []byte, decoded *[]LayerType) (e
|
||||
if !l.IgnorePanic {
|
||||
defer panicToError(&err)
|
||||
}
|
||||
typ := l.first
|
||||
*decoded = (*decoded)[:0] // Truncated decoded layers.
|
||||
for len(data) > 0 {
|
||||
decoder, ok := l.decoders[typ]
|
||||
if !ok {
|
||||
if l.IgnoreUnsupported {
|
||||
return nil
|
||||
}
|
||||
return UnsupportedLayerType(typ)
|
||||
} else if err = decoder.DecodeFromBytes(data, l.df); err != nil {
|
||||
return err
|
||||
typ, err := l.decodeFunc(data, decoded)
|
||||
if typ != LayerTypeZero {
|
||||
// no decoder
|
||||
if l.IgnoreUnsupported {
|
||||
return nil
|
||||
}
|
||||
*decoded = append(*decoded, typ)
|
||||
typ = decoder.NextLayerType()
|
||||
data = decoder.LayerPayload()
|
||||
return UnsupportedLayerType(typ)
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// UnsupportedLayerType is returned by DecodingLayerParser if DecodeLayers
|
||||
|
||||
+18
-8
@@ -96,11 +96,18 @@ type InterfaceAddress struct {
|
||||
P2P net.IP // P2P destination address for this IP may be nil
|
||||
}
|
||||
|
||||
// bpfFilter keeps C.struct_bpf_program separate from BPF.orig which might be a pointer to go memory.
|
||||
// This is a workaround for https://github.com/golang/go/issues/32970 which will be fixed in go1.14.
|
||||
// (type conversion is in pcap_unix.go pcapOfflineFilter)
|
||||
type bpfFilter struct {
|
||||
bpf pcapBpfProgram // takes a finalizer, not overriden by outsiders
|
||||
}
|
||||
|
||||
// BPF is a compiled filter program, useful for offline packet matching.
|
||||
type BPF struct {
|
||||
orig string
|
||||
bpf pcapBpfProgram // takes a finalizer, not overriden by outsiders
|
||||
hdr pcapPkthdr // allocate on the heap to enable optimizations
|
||||
bpf *bpfFilter
|
||||
hdr pcapPkthdr // allocate on the heap to enable optimizations
|
||||
}
|
||||
|
||||
// BPFInstruction is a byte encoded structure holding a BPF instruction
|
||||
@@ -264,6 +271,7 @@ const (
|
||||
aeDenied = activateError(pcapErrorDenied)
|
||||
aeNotUp = activateError(pcapErrorNotUp)
|
||||
aeWarning = activateError(pcapWarning)
|
||||
aeError = activateError(pcapError)
|
||||
)
|
||||
|
||||
func (a activateError) Error() string {
|
||||
@@ -282,6 +290,8 @@ func (a activateError) Error() string {
|
||||
return "Interface Not Up"
|
||||
case aeWarning:
|
||||
return fmt.Sprintf("Warning: %v", activateErrMsg.Error())
|
||||
case aeError:
|
||||
return fmt.Sprintf("Error: %v", activateErrMsg.Error())
|
||||
default:
|
||||
return fmt.Sprintf("unknown activated error: %d", a)
|
||||
}
|
||||
@@ -508,10 +518,10 @@ func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf pcapBpfProgram,
|
||||
// BPF filters need to be created from activated handles, because they need to
|
||||
// know the underlying link type to correctly compile their offsets.
|
||||
func (p *Handle) NewBPF(expr string) (*BPF, error) {
|
||||
bpf := &BPF{orig: expr}
|
||||
bpf := &BPF{orig: expr, bpf: new(bpfFilter)}
|
||||
|
||||
var err error
|
||||
bpf.bpf, err = p.pcapCompile(expr, pcapNetmaskUnknown)
|
||||
bpf.bpf.bpf, err = p.pcapCompile(expr, pcapNetmaskUnknown)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -548,9 +558,9 @@ func NewBPF(linkType layers.LinkType, captureLength int, expr string) (*BPF, err
|
||||
// know the underlying link type to correctly compile their offsets.
|
||||
func (p *Handle) NewBPFInstructionFilter(bpfInstructions []BPFInstruction) (*BPF, error) {
|
||||
var err error
|
||||
bpf := &BPF{orig: "BPF Instruction Filter"}
|
||||
bpf := &BPF{orig: "BPF Instruction Filter", bpf: new(bpfFilter)}
|
||||
|
||||
bpf.bpf, err = bpfInstructionFilter(bpfInstructions)
|
||||
bpf.bpf.bpf, err = bpfInstructionFilter(bpfInstructions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -559,7 +569,7 @@ func (p *Handle) NewBPFInstructionFilter(bpfInstructions []BPFInstruction) (*BPF
|
||||
return bpf, nil
|
||||
}
|
||||
func destroyBPF(bpf *BPF) {
|
||||
bpf.bpf.free()
|
||||
bpf.bpf.bpf.free()
|
||||
}
|
||||
|
||||
// String returns the original string this BPF filter was compiled from.
|
||||
@@ -756,7 +766,7 @@ func (p *InactiveHandle) Activate() (*Handle, error) {
|
||||
pcapSetTstampPrecision(p.cptr, pcapTstampPrecisionNano)
|
||||
handle, err := p.pcapActivate()
|
||||
if err != aeNoError {
|
||||
if err == aeWarning {
|
||||
if err == aeWarning || err == aeError {
|
||||
activateErrMsg = p.Error()
|
||||
}
|
||||
return nil, err
|
||||
|
||||
+17
-19
@@ -33,6 +33,7 @@ import (
|
||||
#include <stdlib.h>
|
||||
#include <pcap.h>
|
||||
#include <stdint.h>
|
||||
#include <poll.h>
|
||||
|
||||
// Some old versions of pcap don't define this constant.
|
||||
#ifndef PCAP_NETMASK_UNKNOWN
|
||||
@@ -142,28 +143,24 @@ int pcap_offline_filter_escaping(struct bpf_program *fp, uintptr_t pkt_hdr, uint
|
||||
|
||||
// pcap_wait returns when the next packet is available or the timeout expires.
|
||||
// Since it uses pcap_get_selectable_fd, it will not work in Windows.
|
||||
int pcap_wait(pcap_t *p, int usec) {
|
||||
fd_set fds;
|
||||
int pcap_wait(pcap_t *p, int msec) {
|
||||
struct pollfd fds[1];
|
||||
int fd;
|
||||
struct timeval tv;
|
||||
|
||||
fd = pcap_get_selectable_fd(p);
|
||||
if(fd < 0) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
fds[0].fd = fd;
|
||||
fds[0].events = POLLIN;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = usec;
|
||||
|
||||
if(usec != 0) {
|
||||
return select(fd+1, &fds, NULL, NULL, &tv);
|
||||
if(msec != 0) {
|
||||
return poll(fds, 1, msec);
|
||||
}
|
||||
|
||||
// block indefinitely if no timeout provided
|
||||
return select(fd+1, &fds, NULL, NULL, NULL);
|
||||
return poll(fds, 1, -1);
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -179,6 +176,7 @@ const (
|
||||
pcapErrorDenied = C.PCAP_ERROR_PERM_DENIED
|
||||
pcapErrorNotUp = C.PCAP_ERROR_IFACE_NOT_UP
|
||||
pcapWarning = C.PCAP_WARNING
|
||||
pcapError = C.PCAP_ERROR
|
||||
pcapDIN = C.PCAP_D_IN
|
||||
pcapDOUT = C.PCAP_D_OUT
|
||||
pcapDINOUT = C.PCAP_D_INOUT
|
||||
@@ -348,7 +346,7 @@ func (b *BPF) pcapOfflineFilter(ci gopacket.CaptureInfo, data []byte) bool {
|
||||
hdr.caplen = C.bpf_u_int32(len(data)) // Trust actual length over ci.Length.
|
||||
hdr.len = C.bpf_u_int32(ci.Length)
|
||||
dataptr := (*C.u_char)(unsafe.Pointer(&data[0]))
|
||||
return C.pcap_offline_filter_escaping((*C.struct_bpf_program)(&b.bpf),
|
||||
return C.pcap_offline_filter_escaping((*C.struct_bpf_program)(&b.bpf.bpf),
|
||||
C.uintptr_t(uintptr(unsafe.Pointer(hdr))),
|
||||
C.uintptr_t(uintptr(unsafe.Pointer(dataptr)))) != 0
|
||||
}
|
||||
@@ -684,13 +682,13 @@ func (p *Handle) setNonBlocking() error {
|
||||
|
||||
// waitForPacket waits for a packet or for the timeout to expire.
|
||||
func (p *Handle) waitForPacket() {
|
||||
// need to wait less than the read timeout according to pcap documentation.
|
||||
// timeoutMillis rounds up to at least one millisecond so we can safely
|
||||
// subtract up to a millisecond.
|
||||
usec := timeoutMillis(p.timeout) * 1000
|
||||
usec -= 100
|
||||
|
||||
C.pcap_wait(p.cptr, C.int(usec))
|
||||
// According to pcap_get_selectable_fd() man page, there are some cases where it will
|
||||
// return a file descriptor, but a simple call of select() or poll() will not indicate
|
||||
// that the descriptor is readable until a full buffer's worth of packets is received,
|
||||
// so the call must have a timeout less than *or equal* to the packet buffer timeout.
|
||||
// The packet buffer timeout is set to timeoutMillis(p.timeout) in pcapOpenLive(),
|
||||
// so we should be fine to use it here too.
|
||||
C.pcap_wait(p.cptr, C.int(timeoutMillis(p.timeout)))
|
||||
}
|
||||
|
||||
// openOfflineFile returns contents of input file as a *Handle.
|
||||
|
||||
+20
-7
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var pcapLoaded = false
|
||||
@@ -66,7 +67,7 @@ func initLoadedDllPath(kernel32 syscall.Handle) {
|
||||
}
|
||||
|
||||
func mustLoad(fun string) uintptr {
|
||||
addr, err := syscall.GetProcAddress(wpcapHandle, fun)
|
||||
addr, err := windows.GetProcAddress(wpcapHandle, fun)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Couldn't load function %s from %s", fun, loadedDllPath))
|
||||
}
|
||||
@@ -74,7 +75,7 @@ func mustLoad(fun string) uintptr {
|
||||
}
|
||||
|
||||
func mightLoad(fun string) uintptr {
|
||||
addr, err := syscall.GetProcAddress(wpcapHandle, fun)
|
||||
addr, err := windows.GetProcAddress(wpcapHandle, fun)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
@@ -101,7 +102,7 @@ func bytePtrToString(r uintptr) string {
|
||||
return byteSliceToString(bval[:])
|
||||
}
|
||||
|
||||
var wpcapHandle syscall.Handle
|
||||
var wpcapHandle windows.Handle
|
||||
var msvcrtHandle syscall.Handle
|
||||
var (
|
||||
callocPtr,
|
||||
@@ -171,9 +172,21 @@ func LoadWinPCAP() error {
|
||||
|
||||
initDllPath(kernel32)
|
||||
|
||||
wpcapHandle, err = syscall.LoadLibrary("wpcap.dll")
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't load wpcap.dll")
|
||||
if haveSearch, _ := syscall.GetProcAddress(kernel32, "AddDllDirectory"); haveSearch != 0 {
|
||||
// if AddDllDirectory is present, we can use LOAD_LIBRARY_* stuff with LoadLibraryEx to avoid wpcap.dll hijacking
|
||||
// see: https://msdn.microsoft.com/en-us/library/ff919712%28VS.85%29.aspx
|
||||
const LOAD_LIBRARY_SEARCH_USER_DIRS = 0x00000400
|
||||
const LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
|
||||
wpcapHandle, err = windows.LoadLibraryEx("wpcap.dll", 0, LOAD_LIBRARY_SEARCH_USER_DIRS|LOAD_LIBRARY_SEARCH_SYSTEM32)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't load wpcap.dll")
|
||||
}
|
||||
} else {
|
||||
// otherwise fall back to load it with the unsafe search cause by SetDllDirectory
|
||||
wpcapHandle, err = windows.LoadLibrary("wpcap.dll")
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't load wpcap.dll")
|
||||
}
|
||||
}
|
||||
initLoadedDllPath(kernel32)
|
||||
msvcrtHandle, err = syscall.LoadLibrary("msvcrt.dll")
|
||||
@@ -432,7 +445,7 @@ func (b *BPF) pcapOfflineFilter(ci gopacket.CaptureInfo, data []byte) bool {
|
||||
hdr.Ts.Usec = int32(ci.Timestamp.Nanosecond() / 1000)
|
||||
hdr.Caplen = uint32(len(data)) // Trust actual length over ci.Length.
|
||||
hdr.Len = uint32(ci.Length)
|
||||
e, _, _ := syscall.Syscall(pcapOfflineFilterPtr, 3, uintptr(unsafe.Pointer(&b.bpf)), uintptr(unsafe.Pointer(&hdr)), uintptr(unsafe.Pointer(&data[0])))
|
||||
e, _, _ := syscall.Syscall(pcapOfflineFilterPtr, 3, uintptr(unsafe.Pointer(&b.bpf.bpf)), uintptr(unsafe.Pointer(&hdr)), uintptr(unsafe.Pointer(&data[0])))
|
||||
return e != 0
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/AUTHORS.
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
||||
Generated
+2
@@ -0,0 +1,2 @@
|
||||
_obj/
|
||||
unix.test
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
# Building `sys/unix`
|
||||
|
||||
The sys/unix package provides access to the raw system call interface of the
|
||||
underlying operating system. See: https://godoc.org/golang.org/x/sys/unix
|
||||
|
||||
Porting Go to a new architecture/OS combination or adding syscalls, types, or
|
||||
constants to an existing architecture/OS pair requires some manual effort;
|
||||
however, there are tools that automate much of the process.
|
||||
|
||||
## Build Systems
|
||||
|
||||
There are currently two ways we generate the necessary files. We are currently
|
||||
migrating the build system to use containers so the builds are reproducible.
|
||||
This is being done on an OS-by-OS basis. Please update this documentation as
|
||||
components of the build system change.
|
||||
|
||||
### Old Build System (currently for `GOOS != "linux"`)
|
||||
|
||||
The old build system generates the Go files based on the C header files
|
||||
present on your system. This means that files
|
||||
for a given GOOS/GOARCH pair must be generated on a system with that OS and
|
||||
architecture. This also means that the generated code can differ from system
|
||||
to system, based on differences in the header files.
|
||||
|
||||
To avoid this, if you are using the old build system, only generate the Go
|
||||
files on an installation with unmodified header files. It is also important to
|
||||
keep track of which version of the OS the files were generated from (ex.
|
||||
Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
|
||||
and have each OS upgrade correspond to a single change.
|
||||
|
||||
To build the files for your current OS and architecture, make sure GOOS and
|
||||
GOARCH are set correctly and run `mkall.sh`. This will generate the files for
|
||||
your specific system. Running `mkall.sh -n` shows the commands that will be run.
|
||||
|
||||
Requirements: bash, go
|
||||
|
||||
### New Build System (currently for `GOOS == "linux"`)
|
||||
|
||||
The new build system uses a Docker container to generate the go files directly
|
||||
from source checkouts of the kernel and various system libraries. This means
|
||||
that on any platform that supports Docker, all the files using the new build
|
||||
system can be generated at once, and generated files will not change based on
|
||||
what the person running the scripts has installed on their computer.
|
||||
|
||||
The OS specific files for the new build system are located in the `${GOOS}`
|
||||
directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
|
||||
the kernel or system library updates, modify the Dockerfile at
|
||||
`${GOOS}/Dockerfile` to checkout the new release of the source.
|
||||
|
||||
To build all the files under the new build system, you must be on an amd64/Linux
|
||||
system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will
|
||||
then generate all of the files for all of the GOOS/GOARCH pairs in the new build
|
||||
system. Running `mkall.sh -n` shows the commands that will be run.
|
||||
|
||||
Requirements: bash, go, docker
|
||||
|
||||
## Component files
|
||||
|
||||
This section describes the various files used in the code generation process.
|
||||
It also contains instructions on how to modify these files to add a new
|
||||
architecture/OS or to add additional syscalls, types, or constants. Note that
|
||||
if you are using the new build system, the scripts/programs cannot be called normally.
|
||||
They must be called from within the docker container.
|
||||
|
||||
### asm files
|
||||
|
||||
The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
|
||||
call dispatch. There are three entry points:
|
||||
```
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
```
|
||||
The first and second are the standard ones; they differ only in how many
|
||||
arguments can be passed to the kernel. The third is for low-level use by the
|
||||
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
|
||||
let it know that a system call is running.
|
||||
|
||||
When porting Go to an new architecture/OS, this file must be implemented for
|
||||
each GOOS/GOARCH pair.
|
||||
|
||||
### mksysnum
|
||||
|
||||
Mksysnum is a Go program located at `${GOOS}/mksysnum.go` (or `mksysnum_${GOOS}.go`
|
||||
for the old system). This program takes in a list of header files containing the
|
||||
syscall number declarations and parses them to produce the corresponding list of
|
||||
Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
|
||||
constants.
|
||||
|
||||
Adding new syscall numbers is mostly done by running the build on a sufficiently
|
||||
new installation of the target OS (or updating the source checkouts for the
|
||||
new build system). However, depending on the OS, you make need to update the
|
||||
parsing in mksysnum.
|
||||
|
||||
### mksyscall.go
|
||||
|
||||
The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
|
||||
hand-written Go files which implement system calls (for unix, the specific OS,
|
||||
or the specific OS/Architecture pair respectively) that need special handling
|
||||
and list `//sys` comments giving prototypes for ones that can be generated.
|
||||
|
||||
The mksyscall.go program takes the `//sys` and `//sysnb` comments and converts
|
||||
them into syscalls. This requires the name of the prototype in the comment to
|
||||
match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
|
||||
prototype can be exported (capitalized) or not.
|
||||
|
||||
Adding a new syscall often just requires adding a new `//sys` function prototype
|
||||
with the desired arguments and a capitalized name so it is exported. However, if
|
||||
you want the interface to the syscall to be different, often one will make an
|
||||
unexported `//sys` prototype, an then write a custom wrapper in
|
||||
`syscall_${GOOS}.go`.
|
||||
|
||||
### types files
|
||||
|
||||
For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
|
||||
`types_${GOOS}.go` on the old system). This file includes standard C headers and
|
||||
creates Go type aliases to the corresponding C types. The file is then fed
|
||||
through godef to get the Go compatible definitions. Finally, the generated code
|
||||
is fed though mkpost.go to format the code correctly and remove any hidden or
|
||||
private identifiers. This cleaned-up code is written to
|
||||
`ztypes_${GOOS}_${GOARCH}.go`.
|
||||
|
||||
The hardest part about preparing this file is figuring out which headers to
|
||||
include and which symbols need to be `#define`d to get the actual data
|
||||
structures that pass through to the kernel system calls. Some C libraries
|
||||
preset alternate versions for binary compatibility and translate them on the
|
||||
way in and out of system calls, but there is almost always a `#define` that can
|
||||
get the real ones.
|
||||
See `types_darwin.go` and `linux/types.go` for examples.
|
||||
|
||||
To add a new type, add in the necessary include statement at the top of the
|
||||
file (if it is not already there) and add in a type alias line. Note that if
|
||||
your type is significantly different on different architectures, you may need
|
||||
some `#if/#elif` macros in your include statements.
|
||||
|
||||
### mkerrors.sh
|
||||
|
||||
This script is used to generate the system's various constants. This doesn't
|
||||
just include the error numbers and error strings, but also the signal numbers
|
||||
an a wide variety of miscellaneous constants. The constants come from the list
|
||||
of include files in the `includes_${uname}` variable. A regex then picks out
|
||||
the desired `#define` statements, and generates the corresponding Go constants.
|
||||
The error numbers and strings are generated from `#include <errno.h>`, and the
|
||||
signal numbers and strings are generated from `#include <signal.h>`. All of
|
||||
these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
|
||||
`_errors.c`, which prints out all the constants.
|
||||
|
||||
To add a constant, add the header that includes it to the appropriate variable.
|
||||
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
||||
the regex too broad to avoid matching unintended constants.
|
||||
|
||||
### mkmerge.go
|
||||
|
||||
This program is used to extract duplicate const, func, and type declarations
|
||||
from the generated architecture-specific files listed below, and merge these
|
||||
into a common file for each OS.
|
||||
|
||||
The merge is performed in the following steps:
|
||||
1. Construct the set of common code that is idential in all architecture-specific files.
|
||||
2. Write this common code to the merged file.
|
||||
3. Remove the common code from all architecture-specific files.
|
||||
|
||||
|
||||
## Generated files
|
||||
|
||||
### `zerror_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing all of the system's generated error numbers, error strings,
|
||||
signal numbers, and constants. Generated by `mkerrors.sh` (see above).
|
||||
|
||||
### `zsyscall_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing all the generated syscalls for a specific GOOS and GOARCH.
|
||||
Generated by `mksyscall.go` (see above).
|
||||
|
||||
### `zsysnum_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A list of numeric constants for all the syscall number of the specific GOOS
|
||||
and GOARCH. Generated by mksysnum (see above).
|
||||
|
||||
### `ztypes_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing Go types for passing into (or returning from) syscalls.
|
||||
Generated by godefs and the types file (see above).
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// CPU affinity functions
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"math/bits"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const cpuSetSize = _CPU_SETSIZE / _NCPUBITS
|
||||
|
||||
// CPUSet represents a CPU affinity mask.
|
||||
type CPUSet [cpuSetSize]cpuMask
|
||||
|
||||
func schedAffinity(trap uintptr, pid int, set *CPUSet) error {
|
||||
_, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))
|
||||
if e != 0 {
|
||||
return errnoErr(e)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SchedGetaffinity gets the CPU affinity mask of the thread specified by pid.
|
||||
// If pid is 0 the calling thread is used.
|
||||
func SchedGetaffinity(pid int, set *CPUSet) error {
|
||||
return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)
|
||||
}
|
||||
|
||||
// SchedSetaffinity sets the CPU affinity mask of the thread specified by pid.
|
||||
// If pid is 0 the calling thread is used.
|
||||
func SchedSetaffinity(pid int, set *CPUSet) error {
|
||||
return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)
|
||||
}
|
||||
|
||||
// Zero clears the set s, so that it contains no CPUs.
|
||||
func (s *CPUSet) Zero() {
|
||||
for i := range s {
|
||||
s[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
func cpuBitsIndex(cpu int) int {
|
||||
return cpu / _NCPUBITS
|
||||
}
|
||||
|
||||
func cpuBitsMask(cpu int) cpuMask {
|
||||
return cpuMask(1 << (uint(cpu) % _NCPUBITS))
|
||||
}
|
||||
|
||||
// Set adds cpu to the set s.
|
||||
func (s *CPUSet) Set(cpu int) {
|
||||
i := cpuBitsIndex(cpu)
|
||||
if i < len(s) {
|
||||
s[i] |= cpuBitsMask(cpu)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear removes cpu from the set s.
|
||||
func (s *CPUSet) Clear(cpu int) {
|
||||
i := cpuBitsIndex(cpu)
|
||||
if i < len(s) {
|
||||
s[i] &^= cpuBitsMask(cpu)
|
||||
}
|
||||
}
|
||||
|
||||
// IsSet reports whether cpu is in the set s.
|
||||
func (s *CPUSet) IsSet(cpu int) bool {
|
||||
i := cpuBitsIndex(cpu)
|
||||
if i < len(s) {
|
||||
return s[i]&cpuBitsMask(cpu) != 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Count returns the number of CPUs in the set s.
|
||||
func (s *CPUSet) Count() int {
|
||||
c := 0
|
||||
for _, b := range s {
|
||||
c += bits.OnesCount64(uint64(b))
|
||||
}
|
||||
return c
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
// +build go1.9
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
type Signal = syscall.Signal
|
||||
type Errno = syscall.Errno
|
||||
type SysProcAttr = syscall.SysProcAttr
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
|
||||
//
|
||||
|
||||
TEXT ·syscall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·syscall6(SB)
|
||||
|
||||
TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·rawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for 386, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
// +build arm,darwin
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
// +build arm64,darwin
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
B syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, DragonFly
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for 386, FreeBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, FreeBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM, FreeBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM64, FreeBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for 386, Linux
|
||||
//
|
||||
|
||||
// See ../runtime/sys_linux_386.s for the reason why we always use int 0x80
|
||||
// instead of the glibc-specific "CALL 0x10(GS)".
|
||||
#define INVOKE_SYSCALL INT $0x80
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
||||
CALL runtime·entersyscall(SB)
|
||||
MOVL trap+0(FP), AX // syscall entry
|
||||
MOVL a1+4(FP), BX
|
||||
MOVL a2+8(FP), CX
|
||||
MOVL a3+12(FP), DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, r1+16(FP)
|
||||
MOVL DX, r2+20(FP)
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
||||
MOVL trap+0(FP), AX // syscall entry
|
||||
MOVL a1+4(FP), BX
|
||||
MOVL a2+8(FP), CX
|
||||
MOVL a3+12(FP), DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, r1+16(FP)
|
||||
MOVL DX, r2+20(FP)
|
||||
RET
|
||||
|
||||
TEXT ·socketcall(SB),NOSPLIT,$0-36
|
||||
JMP syscall·socketcall(SB)
|
||||
|
||||
TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
|
||||
JMP syscall·rawsocketcall(SB)
|
||||
|
||||
TEXT ·seek(SB),NOSPLIT,$0-28
|
||||
JMP syscall·seek(SB)
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for AMD64, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
CALL runtime·entersyscall(SB)
|
||||
MOVQ a1+8(FP), DI
|
||||
MOVQ a2+16(FP), SI
|
||||
MOVQ a3+24(FP), DX
|
||||
MOVQ $0, R10
|
||||
MOVQ $0, R8
|
||||
MOVQ $0, R9
|
||||
MOVQ trap+0(FP), AX // syscall entry
|
||||
SYSCALL
|
||||
MOVQ AX, r1+32(FP)
|
||||
MOVQ DX, r2+40(FP)
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVQ a1+8(FP), DI
|
||||
MOVQ a2+16(FP), SI
|
||||
MOVQ a3+24(FP), DX
|
||||
MOVQ $0, R10
|
||||
MOVQ $0, R8
|
||||
MOVQ $0, R9
|
||||
MOVQ trap+0(FP), AX // syscall entry
|
||||
SYSCALL
|
||||
MOVQ AX, r1+32(FP)
|
||||
MOVQ DX, r2+40(FP)
|
||||
RET
|
||||
|
||||
TEXT ·gettimeofday(SB),NOSPLIT,$0-16
|
||||
JMP syscall·gettimeofday(SB)
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for arm, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVW trap+0(FP), R7
|
||||
MOVW a1+4(FP), R0
|
||||
MOVW a2+8(FP), R1
|
||||
MOVW a3+12(FP), R2
|
||||
MOVW $0, R3
|
||||
MOVW $0, R4
|
||||
MOVW $0, R5
|
||||
SWI $0
|
||||
MOVW R0, r1+16(FP)
|
||||
MOVW $0, R0
|
||||
MOVW R0, r2+20(FP)
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
||||
MOVW trap+0(FP), R7 // syscall entry
|
||||
MOVW a1+4(FP), R0
|
||||
MOVW a2+8(FP), R1
|
||||
MOVW a3+12(FP), R2
|
||||
SWI $0
|
||||
MOVW R0, r1+16(FP)
|
||||
MOVW $0, R0
|
||||
MOVW R0, r2+20(FP)
|
||||
RET
|
||||
|
||||
TEXT ·seek(SB),NOSPLIT,$0-28
|
||||
B syscall·seek(SB)
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux
|
||||
// +build arm64
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD $0, R3
|
||||
MOVD $0, R4
|
||||
MOVD $0, R5
|
||||
MOVD trap+0(FP), R8 // syscall entry
|
||||
SVC
|
||||
MOVD R0, r1+32(FP) // r1
|
||||
MOVD R1, r2+40(FP) // r2
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
B syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD $0, R3
|
||||
MOVD $0, R4
|
||||
MOVD $0, R5
|
||||
MOVD trap+0(FP), R8 // syscall entry
|
||||
SVC
|
||||
MOVD R0, r1+32(FP)
|
||||
MOVD R1, r2+40(FP)
|
||||
RET
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux
|
||||
// +build mips64 mips64le
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for mips64, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
JAL runtime·entersyscall(SB)
|
||||
MOVV a1+8(FP), R4
|
||||
MOVV a2+16(FP), R5
|
||||
MOVV a3+24(FP), R6
|
||||
MOVV R0, R7
|
||||
MOVV R0, R8
|
||||
MOVV R0, R9
|
||||
MOVV trap+0(FP), R2 // syscall entry
|
||||
SYSCALL
|
||||
MOVV R2, r1+32(FP)
|
||||
MOVV R3, r2+40(FP)
|
||||
JAL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVV a1+8(FP), R4
|
||||
MOVV a2+16(FP), R5
|
||||
MOVV a3+24(FP), R6
|
||||
MOVV R0, R7
|
||||
MOVV R0, R8
|
||||
MOVV R0, R9
|
||||
MOVV trap+0(FP), R2 // syscall entry
|
||||
SYSCALL
|
||||
MOVV R2, r1+32(FP)
|
||||
MOVV R3, r2+40(FP)
|
||||
RET
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux
|
||||
// +build mips mipsle
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for mips, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
||||
JAL runtime·entersyscall(SB)
|
||||
MOVW a1+4(FP), R4
|
||||
MOVW a2+8(FP), R5
|
||||
MOVW a3+12(FP), R6
|
||||
MOVW R0, R7
|
||||
MOVW trap+0(FP), R2 // syscall entry
|
||||
SYSCALL
|
||||
MOVW R2, r1+16(FP) // r1
|
||||
MOVW R3, r2+20(FP) // r2
|
||||
JAL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
||||
MOVW a1+4(FP), R4
|
||||
MOVW a2+8(FP), R5
|
||||
MOVW a3+12(FP), R6
|
||||
MOVW trap+0(FP), R2 // syscall entry
|
||||
SYSCALL
|
||||
MOVW R2, r1+16(FP)
|
||||
MOVW R3, r2+20(FP)
|
||||
RET
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux
|
||||
// +build ppc64 ppc64le
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for ppc64, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R3
|
||||
MOVD a2+16(FP), R4
|
||||
MOVD a3+24(FP), R5
|
||||
MOVD R0, R6
|
||||
MOVD R0, R7
|
||||
MOVD R0, R8
|
||||
MOVD trap+0(FP), R9 // syscall entry
|
||||
SYSCALL R9
|
||||
MOVD R3, r1+32(FP)
|
||||
MOVD R4, r2+40(FP)
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVD a1+8(FP), R3
|
||||
MOVD a2+16(FP), R4
|
||||
MOVD a3+24(FP), R5
|
||||
MOVD R0, R6
|
||||
MOVD R0, R7
|
||||
MOVD R0, R8
|
||||
MOVD trap+0(FP), R9 // syscall entry
|
||||
SYSCALL R9
|
||||
MOVD R3, r1+32(FP)
|
||||
MOVD R4, r2+40(FP)
|
||||
RET
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build riscv64,!gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for linux/riscv64.
|
||||
//
|
||||
// Where available, just jump to package syscall's implementation of
|
||||
// these functions.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
CALL runtime·entersyscall(SB)
|
||||
MOV a1+8(FP), A0
|
||||
MOV a2+16(FP), A1
|
||||
MOV a3+24(FP), A2
|
||||
MOV trap+0(FP), A7 // syscall entry
|
||||
ECALL
|
||||
MOV A0, r1+32(FP) // r1
|
||||
MOV A1, r2+40(FP) // r2
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOV a1+8(FP), A0
|
||||
MOV a2+16(FP), A1
|
||||
MOV a3+24(FP), A2
|
||||
MOV trap+0(FP), A7 // syscall entry
|
||||
ECALL
|
||||
MOV A0, r1+32(FP)
|
||||
MOV A1, r2+40(FP)
|
||||
RET
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build s390x
|
||||
// +build linux
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for s390x, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
BR syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
BR syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R2
|
||||
MOVD a2+16(FP), R3
|
||||
MOVD a3+24(FP), R4
|
||||
MOVD $0, R5
|
||||
MOVD $0, R6
|
||||
MOVD $0, R7
|
||||
MOVD trap+0(FP), R1 // syscall entry
|
||||
SYSCALL
|
||||
MOVD R2, r1+32(FP)
|
||||
MOVD R3, r2+40(FP)
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
BR syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
BR syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVD a1+8(FP), R2
|
||||
MOVD a2+16(FP), R3
|
||||
MOVD a3+24(FP), R4
|
||||
MOVD $0, R5
|
||||
MOVD $0, R6
|
||||
MOVD $0, R7
|
||||
MOVD trap+0(FP), R1 // syscall entry
|
||||
SYSCALL
|
||||
MOVD R2, r1+32(FP)
|
||||
MOVD R3, r2+40(FP)
|
||||
RET
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for 386, NetBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, NetBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM, NetBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM64, NetBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
B syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for 386, OpenBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, OpenBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM, OpenBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for arm64, OpenBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
|
||||
//
|
||||
|
||||
TEXT ·sysvicall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·sysvicall6(SB)
|
||||
|
||||
TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·rawSysvicall6(SB)
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Bluetooth sockets and messages
|
||||
|
||||
package unix
|
||||
|
||||
// Bluetooth Protocols
|
||||
const (
|
||||
BTPROTO_L2CAP = 0
|
||||
BTPROTO_HCI = 1
|
||||
BTPROTO_SCO = 2
|
||||
BTPROTO_RFCOMM = 3
|
||||
BTPROTO_BNEP = 4
|
||||
BTPROTO_CMTP = 5
|
||||
BTPROTO_HIDP = 6
|
||||
BTPROTO_AVDTP = 7
|
||||
)
|
||||
|
||||
const (
|
||||
HCI_CHANNEL_RAW = 0
|
||||
HCI_CHANNEL_USER = 1
|
||||
HCI_CHANNEL_MONITOR = 2
|
||||
HCI_CHANNEL_CONTROL = 3
|
||||
HCI_CHANNEL_LOGGING = 4
|
||||
)
|
||||
|
||||
// Socketoption Level
|
||||
const (
|
||||
SOL_BLUETOOTH = 0x112
|
||||
SOL_HCI = 0x0
|
||||
SOL_L2CAP = 0x6
|
||||
SOL_RFCOMM = 0x12
|
||||
SOL_SCO = 0x11
|
||||
)
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build freebsd
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c
|
||||
|
||||
const (
|
||||
// This is the version of CapRights this package understands. See C implementation for parallels.
|
||||
capRightsGoVersion = CAP_RIGHTS_VERSION_00
|
||||
capArSizeMin = CAP_RIGHTS_VERSION_00 + 2
|
||||
capArSizeMax = capRightsGoVersion + 2
|
||||
)
|
||||
|
||||
var (
|
||||
bit2idx = []int{
|
||||
-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
|
||||
4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
}
|
||||
)
|
||||
|
||||
func capidxbit(right uint64) int {
|
||||
return int((right >> 57) & 0x1f)
|
||||
}
|
||||
|
||||
func rightToIndex(right uint64) (int, error) {
|
||||
idx := capidxbit(right)
|
||||
if idx < 0 || idx >= len(bit2idx) {
|
||||
return -2, fmt.Errorf("index for right 0x%x out of range", right)
|
||||
}
|
||||
return bit2idx[idx], nil
|
||||
}
|
||||
|
||||
func caprver(right uint64) int {
|
||||
return int(right >> 62)
|
||||
}
|
||||
|
||||
func capver(rights *CapRights) int {
|
||||
return caprver(rights.Rights[0])
|
||||
}
|
||||
|
||||
func caparsize(rights *CapRights) int {
|
||||
return capver(rights) + 2
|
||||
}
|
||||
|
||||
// CapRightsSet sets the permissions in setrights in rights.
|
||||
func CapRightsSet(rights *CapRights, setrights []uint64) error {
|
||||
// This is essentially a copy of cap_rights_vset()
|
||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
||||
return fmt.Errorf("bad rights version %d", capver(rights))
|
||||
}
|
||||
|
||||
n := caparsize(rights)
|
||||
if n < capArSizeMin || n > capArSizeMax {
|
||||
return errors.New("bad rights size")
|
||||
}
|
||||
|
||||
for _, right := range setrights {
|
||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
||||
return errors.New("bad right version")
|
||||
}
|
||||
i, err := rightToIndex(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i >= n {
|
||||
return errors.New("index overflow")
|
||||
}
|
||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
||||
return errors.New("index mismatch")
|
||||
}
|
||||
rights.Rights[i] |= right
|
||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
||||
return errors.New("index mismatch (after assign)")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CapRightsClear clears the permissions in clearrights from rights.
|
||||
func CapRightsClear(rights *CapRights, clearrights []uint64) error {
|
||||
// This is essentially a copy of cap_rights_vclear()
|
||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
||||
return fmt.Errorf("bad rights version %d", capver(rights))
|
||||
}
|
||||
|
||||
n := caparsize(rights)
|
||||
if n < capArSizeMin || n > capArSizeMax {
|
||||
return errors.New("bad rights size")
|
||||
}
|
||||
|
||||
for _, right := range clearrights {
|
||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
||||
return errors.New("bad right version")
|
||||
}
|
||||
i, err := rightToIndex(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i >= n {
|
||||
return errors.New("index overflow")
|
||||
}
|
||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
||||
return errors.New("index mismatch")
|
||||
}
|
||||
rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
|
||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
||||
return errors.New("index mismatch (after assign)")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CapRightsIsSet checks whether all the permissions in setrights are present in rights.
|
||||
func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
|
||||
// This is essentially a copy of cap_rights_is_vset()
|
||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
||||
return false, fmt.Errorf("bad rights version %d", capver(rights))
|
||||
}
|
||||
|
||||
n := caparsize(rights)
|
||||
if n < capArSizeMin || n > capArSizeMax {
|
||||
return false, errors.New("bad rights size")
|
||||
}
|
||||
|
||||
for _, right := range setrights {
|
||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
||||
return false, errors.New("bad right version")
|
||||
}
|
||||
i, err := rightToIndex(right)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if i >= n {
|
||||
return false, errors.New("index overflow")
|
||||
}
|
||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
||||
return false, errors.New("index mismatch")
|
||||
}
|
||||
if (rights.Rights[i] & right) != right {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func capright(idx uint64, bit uint64) uint64 {
|
||||
return ((1 << (57 + idx)) | bit)
|
||||
}
|
||||
|
||||
// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.
|
||||
// See man cap_rights_init(3) and rights(4).
|
||||
func CapRightsInit(rights []uint64) (*CapRights, error) {
|
||||
var r CapRights
|
||||
r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)
|
||||
r.Rights[1] = capright(1, 0)
|
||||
|
||||
err := CapRightsSet(&r, rights)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.
|
||||
// The capability rights on fd can never be increased by CapRightsLimit.
|
||||
// See man cap_rights_limit(2) and rights(4).
|
||||
func CapRightsLimit(fd uintptr, rights *CapRights) error {
|
||||
return capRightsLimit(int(fd), rights)
|
||||
}
|
||||
|
||||
// CapRightsGet returns a CapRights structure containing the operations permitted on fd.
|
||||
// See man cap_rights_get(3) and rights(4).
|
||||
func CapRightsGet(fd uintptr) (*CapRights, error) {
|
||||
r, err := CapRightsInit(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = capRightsGet(capRightsGoVersion, int(fd), r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
R_OK = 0x4
|
||||
W_OK = 0x2
|
||||
X_OK = 0x1
|
||||
)
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix
|
||||
// +build ppc
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used by AIX.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a Linux device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev >> 16) & 0xffff)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a Linux device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32(dev & 0xffff)
|
||||
}
|
||||
|
||||
// Mkdev returns a Linux device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
return uint64(((major) << 16) | (minor))
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix
|
||||
// +build ppc64
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used AIX.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a Linux device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev & 0x3fffffff00000000) >> 32)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a Linux device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32((dev & 0x00000000ffffffff) >> 0)
|
||||
}
|
||||
|
||||
// Mkdev returns a Linux device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
var DEVNO64 uint64
|
||||
DEVNO64 = 0x8000000000000000
|
||||
return ((uint64(major) << 32) | (uint64(minor) & 0x00000000FFFFFFFF) | DEVNO64)
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in Darwin's sys/types.h header.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a Darwin device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev >> 24) & 0xff)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a Darwin device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32(dev & 0xffffff)
|
||||
}
|
||||
|
||||
// Mkdev returns a Darwin device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
return (uint64(major) << 24) | uint64(minor)
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in Dragonfly's sys/types.h header.
|
||||
//
|
||||
// The information below is extracted and adapted from sys/types.h:
|
||||
//
|
||||
// Minor gives a cookie instead of an index since in order to avoid changing the
|
||||
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
|
||||
// devices that don't use them.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a DragonFlyBSD device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev >> 8) & 0xff)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a DragonFlyBSD device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32(dev & 0xffff00ff)
|
||||
}
|
||||
|
||||
// Mkdev returns a DragonFlyBSD device number generated from the given major and
|
||||
// minor components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
return (uint64(major) << 8) | uint64(minor)
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in FreeBSD's sys/types.h header.
|
||||
//
|
||||
// The information below is extracted and adapted from sys/types.h:
|
||||
//
|
||||
// Minor gives a cookie instead of an index since in order to avoid changing the
|
||||
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
|
||||
// devices that don't use them.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a FreeBSD device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev >> 8) & 0xff)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a FreeBSD device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32(dev & 0xffff00ff)
|
||||
}
|
||||
|
||||
// Mkdev returns a FreeBSD device number generated from the given major and
|
||||
// minor components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
return (uint64(major) << 8) | uint64(minor)
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used by the Linux kernel and glibc.
|
||||
//
|
||||
// The information below is extracted and adapted from bits/sysmacros.h in the
|
||||
// glibc sources:
|
||||
//
|
||||
// dev_t in glibc is 64-bit, with 32-bit major and minor numbers. glibc's
|
||||
// default encoding is MMMM Mmmm mmmM MMmm, where M is a hex digit of the major
|
||||
// number and m is a hex digit of the minor number. This is backward compatible
|
||||
// with legacy systems where dev_t is 16 bits wide, encoded as MMmm. It is also
|
||||
// backward compatible with the Linux kernel, which for some architectures uses
|
||||
// 32-bit dev_t, encoded as mmmM MMmm.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a Linux device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
major := uint32((dev & 0x00000000000fff00) >> 8)
|
||||
major |= uint32((dev & 0xfffff00000000000) >> 32)
|
||||
return major
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a Linux device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
minor := uint32((dev & 0x00000000000000ff) >> 0)
|
||||
minor |= uint32((dev & 0x00000ffffff00000) >> 12)
|
||||
return minor
|
||||
}
|
||||
|
||||
// Mkdev returns a Linux device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
dev := (uint64(major) & 0x00000fff) << 8
|
||||
dev |= (uint64(major) & 0xfffff000) << 32
|
||||
dev |= (uint64(minor) & 0x000000ff) << 0
|
||||
dev |= (uint64(minor) & 0xffffff00) << 12
|
||||
return dev
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in NetBSD's sys/types.h header.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a NetBSD device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev & 0x000fff00) >> 8)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a NetBSD device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
minor := uint32((dev & 0x000000ff) >> 0)
|
||||
minor |= uint32((dev & 0xfff00000) >> 12)
|
||||
return minor
|
||||
}
|
||||
|
||||
// Mkdev returns a NetBSD device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
dev := (uint64(major) << 8) & 0x000fff00
|
||||
dev |= (uint64(minor) << 12) & 0xfff00000
|
||||
dev |= (uint64(minor) << 0) & 0x000000ff
|
||||
return dev
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in OpenBSD's sys/types.h header.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of an OpenBSD device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev & 0x0000ff00) >> 8)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of an OpenBSD device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
minor := uint32((dev & 0x000000ff) >> 0)
|
||||
minor |= uint32((dev & 0xffff0000) >> 8)
|
||||
return minor
|
||||
}
|
||||
|
||||
// Mkdev returns an OpenBSD device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
dev := (uint64(major) << 8) & 0x0000ff00
|
||||
dev |= (uint64(minor) << 8) & 0xffff0000
|
||||
dev |= (uint64(minor) << 0) & 0x000000ff
|
||||
return dev
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// readInt returns the size-bytes unsigned integer in native byte order at offset off.
|
||||
func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
|
||||
if len(b) < int(off+size) {
|
||||
return 0, false
|
||||
}
|
||||
if isBigEndian {
|
||||
return readIntBE(b[off:], size), true
|
||||
}
|
||||
return readIntLE(b[off:], size), true
|
||||
}
|
||||
|
||||
func readIntBE(b []byte, size uintptr) uint64 {
|
||||
switch size {
|
||||
case 1:
|
||||
return uint64(b[0])
|
||||
case 2:
|
||||
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint64(b[1]) | uint64(b[0])<<8
|
||||
case 4:
|
||||
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
|
||||
case 8:
|
||||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
|
||||
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
|
||||
default:
|
||||
panic("syscall: readInt with unsupported size")
|
||||
}
|
||||
}
|
||||
|
||||
func readIntLE(b []byte, size uintptr) uint64 {
|
||||
switch size {
|
||||
case 1:
|
||||
return uint64(b[0])
|
||||
case 2:
|
||||
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint64(b[0]) | uint64(b[1])<<8
|
||||
case 4:
|
||||
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
|
||||
case 8:
|
||||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||
default:
|
||||
panic("syscall: readInt with unsupported size")
|
||||
}
|
||||
}
|
||||
|
||||
// ParseDirent parses up to max directory entries in buf,
|
||||
// appending the names to names. It returns the number of
|
||||
// bytes consumed from buf, the number of entries added
|
||||
// to names, and the new names slice.
|
||||
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
|
||||
origlen := len(buf)
|
||||
count = 0
|
||||
for max != 0 && len(buf) > 0 {
|
||||
reclen, ok := direntReclen(buf)
|
||||
if !ok || reclen > uint64(len(buf)) {
|
||||
return origlen, count, names
|
||||
}
|
||||
rec := buf[:reclen]
|
||||
buf = buf[reclen:]
|
||||
ino, ok := direntIno(rec)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
if ino == 0 { // File absent in directory.
|
||||
continue
|
||||
}
|
||||
const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
|
||||
namlen, ok := direntNamlen(rec)
|
||||
if !ok || namoff+namlen > uint64(len(rec)) {
|
||||
break
|
||||
}
|
||||
name := rec[namoff : namoff+namlen]
|
||||
for i, c := range name {
|
||||
if c == 0 {
|
||||
name = name[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
// Check for useless names before allocating a string.
|
||||
if string(name) == "." || string(name) == ".." {
|
||||
continue
|
||||
}
|
||||
max--
|
||||
count++
|
||||
names = append(names, string(name))
|
||||
}
|
||||
return origlen - len(buf), count, names
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
// +build ppc64 s390x mips mips64
|
||||
|
||||
package unix
|
||||
|
||||
const isBigEndian = true
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
// +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le riscv64
|
||||
|
||||
package unix
|
||||
|
||||
const isBigEndian = false
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
// Unix environment variables.
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
func Getenv(key string) (value string, found bool) {
|
||||
return syscall.Getenv(key)
|
||||
}
|
||||
|
||||
func Setenv(key, value string) error {
|
||||
return syscall.Setenv(key, value)
|
||||
}
|
||||
|
||||
func Clearenv() {
|
||||
syscall.Clearenv()
|
||||
}
|
||||
|
||||
func Environ() []string {
|
||||
return syscall.Environ()
|
||||
}
|
||||
|
||||
func Unsetenv(key string) error {
|
||||
return syscall.Unsetenv(key)
|
||||
}
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
||||
// them here for backwards compatibility.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
DLT_HHDLC = 0x79
|
||||
IFF_SMART = 0x20
|
||||
IFT_1822 = 0x2
|
||||
IFT_A12MPPSWITCH = 0x82
|
||||
IFT_AAL2 = 0xbb
|
||||
IFT_AAL5 = 0x31
|
||||
IFT_ADSL = 0x5e
|
||||
IFT_AFLANE8023 = 0x3b
|
||||
IFT_AFLANE8025 = 0x3c
|
||||
IFT_ARAP = 0x58
|
||||
IFT_ARCNET = 0x23
|
||||
IFT_ARCNETPLUS = 0x24
|
||||
IFT_ASYNC = 0x54
|
||||
IFT_ATM = 0x25
|
||||
IFT_ATMDXI = 0x69
|
||||
IFT_ATMFUNI = 0x6a
|
||||
IFT_ATMIMA = 0x6b
|
||||
IFT_ATMLOGICAL = 0x50
|
||||
IFT_ATMRADIO = 0xbd
|
||||
IFT_ATMSUBINTERFACE = 0x86
|
||||
IFT_ATMVCIENDPT = 0xc2
|
||||
IFT_ATMVIRTUAL = 0x95
|
||||
IFT_BGPPOLICYACCOUNTING = 0xa2
|
||||
IFT_BSC = 0x53
|
||||
IFT_CCTEMUL = 0x3d
|
||||
IFT_CEPT = 0x13
|
||||
IFT_CES = 0x85
|
||||
IFT_CHANNEL = 0x46
|
||||
IFT_CNR = 0x55
|
||||
IFT_COFFEE = 0x84
|
||||
IFT_COMPOSITELINK = 0x9b
|
||||
IFT_DCN = 0x8d
|
||||
IFT_DIGITALPOWERLINE = 0x8a
|
||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
|
||||
IFT_DLSW = 0x4a
|
||||
IFT_DOCSCABLEDOWNSTREAM = 0x80
|
||||
IFT_DOCSCABLEMACLAYER = 0x7f
|
||||
IFT_DOCSCABLEUPSTREAM = 0x81
|
||||
IFT_DS0 = 0x51
|
||||
IFT_DS0BUNDLE = 0x52
|
||||
IFT_DS1FDL = 0xaa
|
||||
IFT_DS3 = 0x1e
|
||||
IFT_DTM = 0x8c
|
||||
IFT_DVBASILN = 0xac
|
||||
IFT_DVBASIOUT = 0xad
|
||||
IFT_DVBRCCDOWNSTREAM = 0x93
|
||||
IFT_DVBRCCMACLAYER = 0x92
|
||||
IFT_DVBRCCUPSTREAM = 0x94
|
||||
IFT_ENC = 0xf4
|
||||
IFT_EON = 0x19
|
||||
IFT_EPLRS = 0x57
|
||||
IFT_ESCON = 0x49
|
||||
IFT_ETHER = 0x6
|
||||
IFT_FAITH = 0xf2
|
||||
IFT_FAST = 0x7d
|
||||
IFT_FASTETHER = 0x3e
|
||||
IFT_FASTETHERFX = 0x45
|
||||
IFT_FDDI = 0xf
|
||||
IFT_FIBRECHANNEL = 0x38
|
||||
IFT_FRAMERELAYINTERCONNECT = 0x3a
|
||||
IFT_FRAMERELAYMPI = 0x5c
|
||||
IFT_FRDLCIENDPT = 0xc1
|
||||
IFT_FRELAY = 0x20
|
||||
IFT_FRELAYDCE = 0x2c
|
||||
IFT_FRF16MFRBUNDLE = 0xa3
|
||||
IFT_FRFORWARD = 0x9e
|
||||
IFT_G703AT2MB = 0x43
|
||||
IFT_G703AT64K = 0x42
|
||||
IFT_GIF = 0xf0
|
||||
IFT_GIGABITETHERNET = 0x75
|
||||
IFT_GR303IDT = 0xb2
|
||||
IFT_GR303RDT = 0xb1
|
||||
IFT_H323GATEKEEPER = 0xa4
|
||||
IFT_H323PROXY = 0xa5
|
||||
IFT_HDH1822 = 0x3
|
||||
IFT_HDLC = 0x76
|
||||
IFT_HDSL2 = 0xa8
|
||||
IFT_HIPERLAN2 = 0xb7
|
||||
IFT_HIPPI = 0x2f
|
||||
IFT_HIPPIINTERFACE = 0x39
|
||||
IFT_HOSTPAD = 0x5a
|
||||
IFT_HSSI = 0x2e
|
||||
IFT_HY = 0xe
|
||||
IFT_IBM370PARCHAN = 0x48
|
||||
IFT_IDSL = 0x9a
|
||||
IFT_IEEE80211 = 0x47
|
||||
IFT_IEEE80212 = 0x37
|
||||
IFT_IEEE8023ADLAG = 0xa1
|
||||
IFT_IFGSN = 0x91
|
||||
IFT_IMT = 0xbe
|
||||
IFT_INTERLEAVE = 0x7c
|
||||
IFT_IP = 0x7e
|
||||
IFT_IPFORWARD = 0x8e
|
||||
IFT_IPOVERATM = 0x72
|
||||
IFT_IPOVERCDLC = 0x6d
|
||||
IFT_IPOVERCLAW = 0x6e
|
||||
IFT_IPSWITCH = 0x4e
|
||||
IFT_IPXIP = 0xf9
|
||||
IFT_ISDN = 0x3f
|
||||
IFT_ISDNBASIC = 0x14
|
||||
IFT_ISDNPRIMARY = 0x15
|
||||
IFT_ISDNS = 0x4b
|
||||
IFT_ISDNU = 0x4c
|
||||
IFT_ISO88022LLC = 0x29
|
||||
IFT_ISO88023 = 0x7
|
||||
IFT_ISO88024 = 0x8
|
||||
IFT_ISO88025 = 0x9
|
||||
IFT_ISO88025CRFPINT = 0x62
|
||||
IFT_ISO88025DTR = 0x56
|
||||
IFT_ISO88025FIBER = 0x73
|
||||
IFT_ISO88026 = 0xa
|
||||
IFT_ISUP = 0xb3
|
||||
IFT_L3IPXVLAN = 0x89
|
||||
IFT_LAPB = 0x10
|
||||
IFT_LAPD = 0x4d
|
||||
IFT_LAPF = 0x77
|
||||
IFT_LOCALTALK = 0x2a
|
||||
IFT_LOOP = 0x18
|
||||
IFT_MEDIAMAILOVERIP = 0x8b
|
||||
IFT_MFSIGLINK = 0xa7
|
||||
IFT_MIOX25 = 0x26
|
||||
IFT_MODEM = 0x30
|
||||
IFT_MPC = 0x71
|
||||
IFT_MPLS = 0xa6
|
||||
IFT_MPLSTUNNEL = 0x96
|
||||
IFT_MSDSL = 0x8f
|
||||
IFT_MVL = 0xbf
|
||||
IFT_MYRINET = 0x63
|
||||
IFT_NFAS = 0xaf
|
||||
IFT_NSIP = 0x1b
|
||||
IFT_OPTICALCHANNEL = 0xc3
|
||||
IFT_OPTICALTRANSPORT = 0xc4
|
||||
IFT_OTHER = 0x1
|
||||
IFT_P10 = 0xc
|
||||
IFT_P80 = 0xd
|
||||
IFT_PARA = 0x22
|
||||
IFT_PFLOG = 0xf6
|
||||
IFT_PFSYNC = 0xf7
|
||||
IFT_PLC = 0xae
|
||||
IFT_POS = 0xab
|
||||
IFT_PPPMULTILINKBUNDLE = 0x6c
|
||||
IFT_PROPBWAP2MP = 0xb8
|
||||
IFT_PROPCNLS = 0x59
|
||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
|
||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
|
||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
|
||||
IFT_PROPMUX = 0x36
|
||||
IFT_PROPWIRELESSP2P = 0x9d
|
||||
IFT_PTPSERIAL = 0x16
|
||||
IFT_PVC = 0xf1
|
||||
IFT_QLLC = 0x44
|
||||
IFT_RADIOMAC = 0xbc
|
||||
IFT_RADSL = 0x5f
|
||||
IFT_REACHDSL = 0xc0
|
||||
IFT_RFC1483 = 0x9f
|
||||
IFT_RS232 = 0x21
|
||||
IFT_RSRB = 0x4f
|
||||
IFT_SDLC = 0x11
|
||||
IFT_SDSL = 0x60
|
||||
IFT_SHDSL = 0xa9
|
||||
IFT_SIP = 0x1f
|
||||
IFT_SLIP = 0x1c
|
||||
IFT_SMDSDXI = 0x2b
|
||||
IFT_SMDSICIP = 0x34
|
||||
IFT_SONET = 0x27
|
||||
IFT_SONETOVERHEADCHANNEL = 0xb9
|
||||
IFT_SONETPATH = 0x32
|
||||
IFT_SONETVT = 0x33
|
||||
IFT_SRP = 0x97
|
||||
IFT_SS7SIGLINK = 0x9c
|
||||
IFT_STACKTOSTACK = 0x6f
|
||||
IFT_STARLAN = 0xb
|
||||
IFT_STF = 0xd7
|
||||
IFT_T1 = 0x12
|
||||
IFT_TDLC = 0x74
|
||||
IFT_TERMPAD = 0x5b
|
||||
IFT_TR008 = 0xb0
|
||||
IFT_TRANSPHDLC = 0x7b
|
||||
IFT_TUNNEL = 0x83
|
||||
IFT_ULTRA = 0x1d
|
||||
IFT_USB = 0xa0
|
||||
IFT_V11 = 0x40
|
||||
IFT_V35 = 0x2d
|
||||
IFT_V36 = 0x41
|
||||
IFT_V37 = 0x78
|
||||
IFT_VDSL = 0x61
|
||||
IFT_VIRTUALIPADDRESS = 0x70
|
||||
IFT_VOICEEM = 0x64
|
||||
IFT_VOICEENCAP = 0x67
|
||||
IFT_VOICEFXO = 0x65
|
||||
IFT_VOICEFXS = 0x66
|
||||
IFT_VOICEOVERATM = 0x98
|
||||
IFT_VOICEOVERFRAMERELAY = 0x99
|
||||
IFT_VOICEOVERIP = 0x68
|
||||
IFT_X213 = 0x5d
|
||||
IFT_X25 = 0x5
|
||||
IFT_X25DDN = 0x4
|
||||
IFT_X25HUNTGROUP = 0x7a
|
||||
IFT_X25MLP = 0x79
|
||||
IFT_X25PLE = 0x28
|
||||
IFT_XETHER = 0x1a
|
||||
IPPROTO_MAXID = 0x34
|
||||
IPV6_FAITH = 0x1d
|
||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||
IP_FAITH = 0x16
|
||||
IP_MAX_SOURCE_FILTER = 0x400
|
||||
IP_MIN_MEMBERSHIPS = 0x1f
|
||||
MAP_NORESERVE = 0x40
|
||||
MAP_RENAME = 0x20
|
||||
NET_RT_MAXID = 0x6
|
||||
RTF_PRCLONING = 0x10000
|
||||
RTM_OLDADD = 0x9
|
||||
RTM_OLDDEL = 0xa
|
||||
RT_CACHING_CONTEXT = 0x1
|
||||
RT_NORTREF = 0x2
|
||||
SIOCADDRT = 0x8030720a
|
||||
SIOCALIFADDR = 0x8118691b
|
||||
SIOCDELRT = 0x8030720b
|
||||
SIOCDLIFADDR = 0x8118691d
|
||||
SIOCGLIFADDR = 0xc118691c
|
||||
SIOCGLIFPHYADDR = 0xc118694b
|
||||
SIOCSLIFPHYADDR = 0x8118694a
|
||||
)
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
||||
// them here for backwards compatibility.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
DLT_HHDLC = 0x79
|
||||
IFF_SMART = 0x20
|
||||
IFT_1822 = 0x2
|
||||
IFT_A12MPPSWITCH = 0x82
|
||||
IFT_AAL2 = 0xbb
|
||||
IFT_AAL5 = 0x31
|
||||
IFT_ADSL = 0x5e
|
||||
IFT_AFLANE8023 = 0x3b
|
||||
IFT_AFLANE8025 = 0x3c
|
||||
IFT_ARAP = 0x58
|
||||
IFT_ARCNET = 0x23
|
||||
IFT_ARCNETPLUS = 0x24
|
||||
IFT_ASYNC = 0x54
|
||||
IFT_ATM = 0x25
|
||||
IFT_ATMDXI = 0x69
|
||||
IFT_ATMFUNI = 0x6a
|
||||
IFT_ATMIMA = 0x6b
|
||||
IFT_ATMLOGICAL = 0x50
|
||||
IFT_ATMRADIO = 0xbd
|
||||
IFT_ATMSUBINTERFACE = 0x86
|
||||
IFT_ATMVCIENDPT = 0xc2
|
||||
IFT_ATMVIRTUAL = 0x95
|
||||
IFT_BGPPOLICYACCOUNTING = 0xa2
|
||||
IFT_BSC = 0x53
|
||||
IFT_CCTEMUL = 0x3d
|
||||
IFT_CEPT = 0x13
|
||||
IFT_CES = 0x85
|
||||
IFT_CHANNEL = 0x46
|
||||
IFT_CNR = 0x55
|
||||
IFT_COFFEE = 0x84
|
||||
IFT_COMPOSITELINK = 0x9b
|
||||
IFT_DCN = 0x8d
|
||||
IFT_DIGITALPOWERLINE = 0x8a
|
||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
|
||||
IFT_DLSW = 0x4a
|
||||
IFT_DOCSCABLEDOWNSTREAM = 0x80
|
||||
IFT_DOCSCABLEMACLAYER = 0x7f
|
||||
IFT_DOCSCABLEUPSTREAM = 0x81
|
||||
IFT_DS0 = 0x51
|
||||
IFT_DS0BUNDLE = 0x52
|
||||
IFT_DS1FDL = 0xaa
|
||||
IFT_DS3 = 0x1e
|
||||
IFT_DTM = 0x8c
|
||||
IFT_DVBASILN = 0xac
|
||||
IFT_DVBASIOUT = 0xad
|
||||
IFT_DVBRCCDOWNSTREAM = 0x93
|
||||
IFT_DVBRCCMACLAYER = 0x92
|
||||
IFT_DVBRCCUPSTREAM = 0x94
|
||||
IFT_ENC = 0xf4
|
||||
IFT_EON = 0x19
|
||||
IFT_EPLRS = 0x57
|
||||
IFT_ESCON = 0x49
|
||||
IFT_ETHER = 0x6
|
||||
IFT_FAITH = 0xf2
|
||||
IFT_FAST = 0x7d
|
||||
IFT_FASTETHER = 0x3e
|
||||
IFT_FASTETHERFX = 0x45
|
||||
IFT_FDDI = 0xf
|
||||
IFT_FIBRECHANNEL = 0x38
|
||||
IFT_FRAMERELAYINTERCONNECT = 0x3a
|
||||
IFT_FRAMERELAYMPI = 0x5c
|
||||
IFT_FRDLCIENDPT = 0xc1
|
||||
IFT_FRELAY = 0x20
|
||||
IFT_FRELAYDCE = 0x2c
|
||||
IFT_FRF16MFRBUNDLE = 0xa3
|
||||
IFT_FRFORWARD = 0x9e
|
||||
IFT_G703AT2MB = 0x43
|
||||
IFT_G703AT64K = 0x42
|
||||
IFT_GIF = 0xf0
|
||||
IFT_GIGABITETHERNET = 0x75
|
||||
IFT_GR303IDT = 0xb2
|
||||
IFT_GR303RDT = 0xb1
|
||||
IFT_H323GATEKEEPER = 0xa4
|
||||
IFT_H323PROXY = 0xa5
|
||||
IFT_HDH1822 = 0x3
|
||||
IFT_HDLC = 0x76
|
||||
IFT_HDSL2 = 0xa8
|
||||
IFT_HIPERLAN2 = 0xb7
|
||||
IFT_HIPPI = 0x2f
|
||||
IFT_HIPPIINTERFACE = 0x39
|
||||
IFT_HOSTPAD = 0x5a
|
||||
IFT_HSSI = 0x2e
|
||||
IFT_HY = 0xe
|
||||
IFT_IBM370PARCHAN = 0x48
|
||||
IFT_IDSL = 0x9a
|
||||
IFT_IEEE80211 = 0x47
|
||||
IFT_IEEE80212 = 0x37
|
||||
IFT_IEEE8023ADLAG = 0xa1
|
||||
IFT_IFGSN = 0x91
|
||||
IFT_IMT = 0xbe
|
||||
IFT_INTERLEAVE = 0x7c
|
||||
IFT_IP = 0x7e
|
||||
IFT_IPFORWARD = 0x8e
|
||||
IFT_IPOVERATM = 0x72
|
||||
IFT_IPOVERCDLC = 0x6d
|
||||
IFT_IPOVERCLAW = 0x6e
|
||||
IFT_IPSWITCH = 0x4e
|
||||
IFT_IPXIP = 0xf9
|
||||
IFT_ISDN = 0x3f
|
||||
IFT_ISDNBASIC = 0x14
|
||||
IFT_ISDNPRIMARY = 0x15
|
||||
IFT_ISDNS = 0x4b
|
||||
IFT_ISDNU = 0x4c
|
||||
IFT_ISO88022LLC = 0x29
|
||||
IFT_ISO88023 = 0x7
|
||||
IFT_ISO88024 = 0x8
|
||||
IFT_ISO88025 = 0x9
|
||||
IFT_ISO88025CRFPINT = 0x62
|
||||
IFT_ISO88025DTR = 0x56
|
||||
IFT_ISO88025FIBER = 0x73
|
||||
IFT_ISO88026 = 0xa
|
||||
IFT_ISUP = 0xb3
|
||||
IFT_L3IPXVLAN = 0x89
|
||||
IFT_LAPB = 0x10
|
||||
IFT_LAPD = 0x4d
|
||||
IFT_LAPF = 0x77
|
||||
IFT_LOCALTALK = 0x2a
|
||||
IFT_LOOP = 0x18
|
||||
IFT_MEDIAMAILOVERIP = 0x8b
|
||||
IFT_MFSIGLINK = 0xa7
|
||||
IFT_MIOX25 = 0x26
|
||||
IFT_MODEM = 0x30
|
||||
IFT_MPC = 0x71
|
||||
IFT_MPLS = 0xa6
|
||||
IFT_MPLSTUNNEL = 0x96
|
||||
IFT_MSDSL = 0x8f
|
||||
IFT_MVL = 0xbf
|
||||
IFT_MYRINET = 0x63
|
||||
IFT_NFAS = 0xaf
|
||||
IFT_NSIP = 0x1b
|
||||
IFT_OPTICALCHANNEL = 0xc3
|
||||
IFT_OPTICALTRANSPORT = 0xc4
|
||||
IFT_OTHER = 0x1
|
||||
IFT_P10 = 0xc
|
||||
IFT_P80 = 0xd
|
||||
IFT_PARA = 0x22
|
||||
IFT_PFLOG = 0xf6
|
||||
IFT_PFSYNC = 0xf7
|
||||
IFT_PLC = 0xae
|
||||
IFT_POS = 0xab
|
||||
IFT_PPPMULTILINKBUNDLE = 0x6c
|
||||
IFT_PROPBWAP2MP = 0xb8
|
||||
IFT_PROPCNLS = 0x59
|
||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
|
||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
|
||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
|
||||
IFT_PROPMUX = 0x36
|
||||
IFT_PROPWIRELESSP2P = 0x9d
|
||||
IFT_PTPSERIAL = 0x16
|
||||
IFT_PVC = 0xf1
|
||||
IFT_QLLC = 0x44
|
||||
IFT_RADIOMAC = 0xbc
|
||||
IFT_RADSL = 0x5f
|
||||
IFT_REACHDSL = 0xc0
|
||||
IFT_RFC1483 = 0x9f
|
||||
IFT_RS232 = 0x21
|
||||
IFT_RSRB = 0x4f
|
||||
IFT_SDLC = 0x11
|
||||
IFT_SDSL = 0x60
|
||||
IFT_SHDSL = 0xa9
|
||||
IFT_SIP = 0x1f
|
||||
IFT_SLIP = 0x1c
|
||||
IFT_SMDSDXI = 0x2b
|
||||
IFT_SMDSICIP = 0x34
|
||||
IFT_SONET = 0x27
|
||||
IFT_SONETOVERHEADCHANNEL = 0xb9
|
||||
IFT_SONETPATH = 0x32
|
||||
IFT_SONETVT = 0x33
|
||||
IFT_SRP = 0x97
|
||||
IFT_SS7SIGLINK = 0x9c
|
||||
IFT_STACKTOSTACK = 0x6f
|
||||
IFT_STARLAN = 0xb
|
||||
IFT_STF = 0xd7
|
||||
IFT_T1 = 0x12
|
||||
IFT_TDLC = 0x74
|
||||
IFT_TERMPAD = 0x5b
|
||||
IFT_TR008 = 0xb0
|
||||
IFT_TRANSPHDLC = 0x7b
|
||||
IFT_TUNNEL = 0x83
|
||||
IFT_ULTRA = 0x1d
|
||||
IFT_USB = 0xa0
|
||||
IFT_V11 = 0x40
|
||||
IFT_V35 = 0x2d
|
||||
IFT_V36 = 0x41
|
||||
IFT_V37 = 0x78
|
||||
IFT_VDSL = 0x61
|
||||
IFT_VIRTUALIPADDRESS = 0x70
|
||||
IFT_VOICEEM = 0x64
|
||||
IFT_VOICEENCAP = 0x67
|
||||
IFT_VOICEFXO = 0x65
|
||||
IFT_VOICEFXS = 0x66
|
||||
IFT_VOICEOVERATM = 0x98
|
||||
IFT_VOICEOVERFRAMERELAY = 0x99
|
||||
IFT_VOICEOVERIP = 0x68
|
||||
IFT_X213 = 0x5d
|
||||
IFT_X25 = 0x5
|
||||
IFT_X25DDN = 0x4
|
||||
IFT_X25HUNTGROUP = 0x7a
|
||||
IFT_X25MLP = 0x79
|
||||
IFT_X25PLE = 0x28
|
||||
IFT_XETHER = 0x1a
|
||||
IPPROTO_MAXID = 0x34
|
||||
IPV6_FAITH = 0x1d
|
||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||
IP_FAITH = 0x16
|
||||
IP_MAX_SOURCE_FILTER = 0x400
|
||||
IP_MIN_MEMBERSHIPS = 0x1f
|
||||
MAP_NORESERVE = 0x40
|
||||
MAP_RENAME = 0x20
|
||||
NET_RT_MAXID = 0x6
|
||||
RTF_PRCLONING = 0x10000
|
||||
RTM_OLDADD = 0x9
|
||||
RTM_OLDDEL = 0xa
|
||||
RT_CACHING_CONTEXT = 0x1
|
||||
RT_NORTREF = 0x2
|
||||
SIOCADDRT = 0x8040720a
|
||||
SIOCALIFADDR = 0x8118691b
|
||||
SIOCDELRT = 0x8040720b
|
||||
SIOCDLIFADDR = 0x8118691d
|
||||
SIOCGLIFADDR = 0xc118691c
|
||||
SIOCGLIFPHYADDR = 0xc118694b
|
||||
SIOCSLIFPHYADDR = 0x8118694a
|
||||
)
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
IFT_1822 = 0x2
|
||||
IFT_A12MPPSWITCH = 0x82
|
||||
IFT_AAL2 = 0xbb
|
||||
IFT_AAL5 = 0x31
|
||||
IFT_ADSL = 0x5e
|
||||
IFT_AFLANE8023 = 0x3b
|
||||
IFT_AFLANE8025 = 0x3c
|
||||
IFT_ARAP = 0x58
|
||||
IFT_ARCNET = 0x23
|
||||
IFT_ARCNETPLUS = 0x24
|
||||
IFT_ASYNC = 0x54
|
||||
IFT_ATM = 0x25
|
||||
IFT_ATMDXI = 0x69
|
||||
IFT_ATMFUNI = 0x6a
|
||||
IFT_ATMIMA = 0x6b
|
||||
IFT_ATMLOGICAL = 0x50
|
||||
IFT_ATMRADIO = 0xbd
|
||||
IFT_ATMSUBINTERFACE = 0x86
|
||||
IFT_ATMVCIENDPT = 0xc2
|
||||
IFT_ATMVIRTUAL = 0x95
|
||||
IFT_BGPPOLICYACCOUNTING = 0xa2
|
||||
IFT_BSC = 0x53
|
||||
IFT_CCTEMUL = 0x3d
|
||||
IFT_CEPT = 0x13
|
||||
IFT_CES = 0x85
|
||||
IFT_CHANNEL = 0x46
|
||||
IFT_CNR = 0x55
|
||||
IFT_COFFEE = 0x84
|
||||
IFT_COMPOSITELINK = 0x9b
|
||||
IFT_DCN = 0x8d
|
||||
IFT_DIGITALPOWERLINE = 0x8a
|
||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
|
||||
IFT_DLSW = 0x4a
|
||||
IFT_DOCSCABLEDOWNSTREAM = 0x80
|
||||
IFT_DOCSCABLEMACLAYER = 0x7f
|
||||
IFT_DOCSCABLEUPSTREAM = 0x81
|
||||
IFT_DS0 = 0x51
|
||||
IFT_DS0BUNDLE = 0x52
|
||||
IFT_DS1FDL = 0xaa
|
||||
IFT_DS3 = 0x1e
|
||||
IFT_DTM = 0x8c
|
||||
IFT_DVBASILN = 0xac
|
||||
IFT_DVBASIOUT = 0xad
|
||||
IFT_DVBRCCDOWNSTREAM = 0x93
|
||||
IFT_DVBRCCMACLAYER = 0x92
|
||||
IFT_DVBRCCUPSTREAM = 0x94
|
||||
IFT_ENC = 0xf4
|
||||
IFT_EON = 0x19
|
||||
IFT_EPLRS = 0x57
|
||||
IFT_ESCON = 0x49
|
||||
IFT_ETHER = 0x6
|
||||
IFT_FAST = 0x7d
|
||||
IFT_FASTETHER = 0x3e
|
||||
IFT_FASTETHERFX = 0x45
|
||||
IFT_FDDI = 0xf
|
||||
IFT_FIBRECHANNEL = 0x38
|
||||
IFT_FRAMERELAYINTERCONNECT = 0x3a
|
||||
IFT_FRAMERELAYMPI = 0x5c
|
||||
IFT_FRDLCIENDPT = 0xc1
|
||||
IFT_FRELAY = 0x20
|
||||
IFT_FRELAYDCE = 0x2c
|
||||
IFT_FRF16MFRBUNDLE = 0xa3
|
||||
IFT_FRFORWARD = 0x9e
|
||||
IFT_G703AT2MB = 0x43
|
||||
IFT_G703AT64K = 0x42
|
||||
IFT_GIF = 0xf0
|
||||
IFT_GIGABITETHERNET = 0x75
|
||||
IFT_GR303IDT = 0xb2
|
||||
IFT_GR303RDT = 0xb1
|
||||
IFT_H323GATEKEEPER = 0xa4
|
||||
IFT_H323PROXY = 0xa5
|
||||
IFT_HDH1822 = 0x3
|
||||
IFT_HDLC = 0x76
|
||||
IFT_HDSL2 = 0xa8
|
||||
IFT_HIPERLAN2 = 0xb7
|
||||
IFT_HIPPI = 0x2f
|
||||
IFT_HIPPIINTERFACE = 0x39
|
||||
IFT_HOSTPAD = 0x5a
|
||||
IFT_HSSI = 0x2e
|
||||
IFT_HY = 0xe
|
||||
IFT_IBM370PARCHAN = 0x48
|
||||
IFT_IDSL = 0x9a
|
||||
IFT_IEEE80211 = 0x47
|
||||
IFT_IEEE80212 = 0x37
|
||||
IFT_IEEE8023ADLAG = 0xa1
|
||||
IFT_IFGSN = 0x91
|
||||
IFT_IMT = 0xbe
|
||||
IFT_INTERLEAVE = 0x7c
|
||||
IFT_IP = 0x7e
|
||||
IFT_IPFORWARD = 0x8e
|
||||
IFT_IPOVERATM = 0x72
|
||||
IFT_IPOVERCDLC = 0x6d
|
||||
IFT_IPOVERCLAW = 0x6e
|
||||
IFT_IPSWITCH = 0x4e
|
||||
IFT_ISDN = 0x3f
|
||||
IFT_ISDNBASIC = 0x14
|
||||
IFT_ISDNPRIMARY = 0x15
|
||||
IFT_ISDNS = 0x4b
|
||||
IFT_ISDNU = 0x4c
|
||||
IFT_ISO88022LLC = 0x29
|
||||
IFT_ISO88023 = 0x7
|
||||
IFT_ISO88024 = 0x8
|
||||
IFT_ISO88025 = 0x9
|
||||
IFT_ISO88025CRFPINT = 0x62
|
||||
IFT_ISO88025DTR = 0x56
|
||||
IFT_ISO88025FIBER = 0x73
|
||||
IFT_ISO88026 = 0xa
|
||||
IFT_ISUP = 0xb3
|
||||
IFT_L3IPXVLAN = 0x89
|
||||
IFT_LAPB = 0x10
|
||||
IFT_LAPD = 0x4d
|
||||
IFT_LAPF = 0x77
|
||||
IFT_LOCALTALK = 0x2a
|
||||
IFT_LOOP = 0x18
|
||||
IFT_MEDIAMAILOVERIP = 0x8b
|
||||
IFT_MFSIGLINK = 0xa7
|
||||
IFT_MIOX25 = 0x26
|
||||
IFT_MODEM = 0x30
|
||||
IFT_MPC = 0x71
|
||||
IFT_MPLS = 0xa6
|
||||
IFT_MPLSTUNNEL = 0x96
|
||||
IFT_MSDSL = 0x8f
|
||||
IFT_MVL = 0xbf
|
||||
IFT_MYRINET = 0x63
|
||||
IFT_NFAS = 0xaf
|
||||
IFT_NSIP = 0x1b
|
||||
IFT_OPTICALCHANNEL = 0xc3
|
||||
IFT_OPTICALTRANSPORT = 0xc4
|
||||
IFT_OTHER = 0x1
|
||||
IFT_P10 = 0xc
|
||||
IFT_P80 = 0xd
|
||||
IFT_PARA = 0x22
|
||||
IFT_PFLOG = 0xf6
|
||||
IFT_PFSYNC = 0xf7
|
||||
IFT_PLC = 0xae
|
||||
IFT_POS = 0xab
|
||||
IFT_PPPMULTILINKBUNDLE = 0x6c
|
||||
IFT_PROPBWAP2MP = 0xb8
|
||||
IFT_PROPCNLS = 0x59
|
||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
|
||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
|
||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
|
||||
IFT_PROPMUX = 0x36
|
||||
IFT_PROPWIRELESSP2P = 0x9d
|
||||
IFT_PTPSERIAL = 0x16
|
||||
IFT_PVC = 0xf1
|
||||
IFT_QLLC = 0x44
|
||||
IFT_RADIOMAC = 0xbc
|
||||
IFT_RADSL = 0x5f
|
||||
IFT_REACHDSL = 0xc0
|
||||
IFT_RFC1483 = 0x9f
|
||||
IFT_RS232 = 0x21
|
||||
IFT_RSRB = 0x4f
|
||||
IFT_SDLC = 0x11
|
||||
IFT_SDSL = 0x60
|
||||
IFT_SHDSL = 0xa9
|
||||
IFT_SIP = 0x1f
|
||||
IFT_SLIP = 0x1c
|
||||
IFT_SMDSDXI = 0x2b
|
||||
IFT_SMDSICIP = 0x34
|
||||
IFT_SONET = 0x27
|
||||
IFT_SONETOVERHEADCHANNEL = 0xb9
|
||||
IFT_SONETPATH = 0x32
|
||||
IFT_SONETVT = 0x33
|
||||
IFT_SRP = 0x97
|
||||
IFT_SS7SIGLINK = 0x9c
|
||||
IFT_STACKTOSTACK = 0x6f
|
||||
IFT_STARLAN = 0xb
|
||||
IFT_STF = 0xd7
|
||||
IFT_T1 = 0x12
|
||||
IFT_TDLC = 0x74
|
||||
IFT_TERMPAD = 0x5b
|
||||
IFT_TR008 = 0xb0
|
||||
IFT_TRANSPHDLC = 0x7b
|
||||
IFT_TUNNEL = 0x83
|
||||
IFT_ULTRA = 0x1d
|
||||
IFT_USB = 0xa0
|
||||
IFT_V11 = 0x40
|
||||
IFT_V35 = 0x2d
|
||||
IFT_V36 = 0x41
|
||||
IFT_V37 = 0x78
|
||||
IFT_VDSL = 0x61
|
||||
IFT_VIRTUALIPADDRESS = 0x70
|
||||
IFT_VOICEEM = 0x64
|
||||
IFT_VOICEENCAP = 0x67
|
||||
IFT_VOICEFXO = 0x65
|
||||
IFT_VOICEFXS = 0x66
|
||||
IFT_VOICEOVERATM = 0x98
|
||||
IFT_VOICEOVERFRAMERELAY = 0x99
|
||||
IFT_VOICEOVERIP = 0x68
|
||||
IFT_X213 = 0x5d
|
||||
IFT_X25 = 0x5
|
||||
IFT_X25DDN = 0x4
|
||||
IFT_X25HUNTGROUP = 0x7a
|
||||
IFT_X25MLP = 0x79
|
||||
IFT_X25PLE = 0x28
|
||||
IFT_XETHER = 0x1a
|
||||
|
||||
// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
|
||||
IFF_SMART = 0x20
|
||||
IFT_FAITH = 0xf2
|
||||
IFT_IPXIP = 0xf9
|
||||
IPPROTO_MAXID = 0x34
|
||||
IPV6_FAITH = 0x1d
|
||||
IP_FAITH = 0x16
|
||||
MAP_NORESERVE = 0x40
|
||||
MAP_RENAME = 0x20
|
||||
NET_RT_MAXID = 0x6
|
||||
RTF_PRCLONING = 0x10000
|
||||
RTM_OLDADD = 0x9
|
||||
RTM_OLDDEL = 0xa
|
||||
SIOCADDRT = 0x8030720a
|
||||
SIOCALIFADDR = 0x8118691b
|
||||
SIOCDELRT = 0x8030720b
|
||||
SIOCDLIFADDR = 0x8118691d
|
||||
SIOCGLIFADDR = 0xc118691c
|
||||
SIOCGLIFPHYADDR = 0xc118694b
|
||||
SIOCSLIFPHYADDR = 0x8118694a
|
||||
)
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
||||
// them here for backwards compatibility.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
DLT_HHDLC = 0x79
|
||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||
IP_MAX_SOURCE_FILTER = 0x400
|
||||
IP_MIN_MEMBERSHIPS = 0x1f
|
||||
RT_CACHING_CONTEXT = 0x1
|
||||
RT_NORTREF = 0x2
|
||||
)
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly freebsd linux netbsd openbsd
|
||||
|
||||
package unix
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux
|
||||
// systems by fcntl_linux_32bit.go to be SYS_FCNTL64.
|
||||
var fcntl64Syscall uintptr = SYS_FCNTL
|
||||
|
||||
func fcntl(fd int, cmd, arg int) (int, error) {
|
||||
valptr, _, errno := Syscall(fcntl64Syscall, uintptr(fd), uintptr(cmd), uintptr(arg))
|
||||
var err error
|
||||
if errno != 0 {
|
||||
err = errno
|
||||
}
|
||||
return int(valptr), err
|
||||
}
|
||||
|
||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
return fcntl(int(fd), cmd, arg)
|
||||
}
|
||||
|
||||
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
|
||||
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
|
||||
_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))
|
||||
if errno == 0 {
|
||||
return nil
|
||||
}
|
||||
return errno
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package unix
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
return fcntl(int(fd), cmd, arg)
|
||||
}
|
||||
|
||||
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
|
||||
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
|
||||
_, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(lk))))
|
||||
return err
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// +build linux,386 linux,arm linux,mips linux,mipsle
|
||||
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package unix
|
||||
|
||||
func init() {
|
||||
// On 32-bit Linux systems, the fcntl syscall that matches Go's
|
||||
// Flock_t type is SYS_FCNTL64, not SYS_FCNTL.
|
||||
fcntl64Syscall = SYS_FCNTL64
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
// Set adds fd to the set fds.
|
||||
func (fds *FdSet) Set(fd int) {
|
||||
fds.Bits[fd/NFDBITS] |= (1 << (uintptr(fd) % NFDBITS))
|
||||
}
|
||||
|
||||
// Clear removes fd from the set fds.
|
||||
func (fds *FdSet) Clear(fd int) {
|
||||
fds.Bits[fd/NFDBITS] &^= (1 << (uintptr(fd) % NFDBITS))
|
||||
}
|
||||
|
||||
// IsSet returns whether fd is in the set fds.
|
||||
func (fds *FdSet) IsSet(fd int) bool {
|
||||
return fds.Bits[fd/NFDBITS]&(1<<(uintptr(fd)%NFDBITS)) != 0
|
||||
}
|
||||
|
||||
// Zero clears the set fds.
|
||||
func (fds *FdSet) Zero() {
|
||||
for i := range fds.Bits {
|
||||
fds.Bits[i] = 0
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build gccgo
|
||||
// +build !aix
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
// We can't use the gc-syntax .s files for gccgo. On the plus side
|
||||
// much of the functionality can be written directly in Go.
|
||||
|
||||
//extern gccgoRealSyscallNoError
|
||||
func realSyscallNoError(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r uintptr)
|
||||
|
||||
//extern gccgoRealSyscall
|
||||
func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr)
|
||||
|
||||
func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {
|
||||
syscall.Entersyscall()
|
||||
r := realSyscallNoError(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
||||
syscall.Exitsyscall()
|
||||
return r, 0
|
||||
}
|
||||
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
syscall.Entersyscall()
|
||||
r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
||||
syscall.Exitsyscall()
|
||||
return r, 0, syscall.Errno(errno)
|
||||
}
|
||||
|
||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
syscall.Entersyscall()
|
||||
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
|
||||
syscall.Exitsyscall()
|
||||
return r, 0, syscall.Errno(errno)
|
||||
}
|
||||
|
||||
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
syscall.Entersyscall()
|
||||
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
syscall.Exitsyscall()
|
||||
return r, 0, syscall.Errno(errno)
|
||||
}
|
||||
|
||||
func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {
|
||||
r := realSyscallNoError(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
||||
return r, 0
|
||||
}
|
||||
|
||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
||||
return r, 0, syscall.Errno(errno)
|
||||
}
|
||||
|
||||
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
|
||||
return r, 0, syscall.Errno(errno)
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build gccgo
|
||||
// +build !aix
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define _STRINGIFY2_(x) #x
|
||||
#define _STRINGIFY_(x) _STRINGIFY2_(x)
|
||||
#define GOSYM_PREFIX _STRINGIFY_(__USER_LABEL_PREFIX__)
|
||||
|
||||
// Call syscall from C code because the gccgo support for calling from
|
||||
// Go to C does not support varargs functions.
|
||||
|
||||
struct ret {
|
||||
uintptr_t r;
|
||||
uintptr_t err;
|
||||
};
|
||||
|
||||
struct ret
|
||||
gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)
|
||||
{
|
||||
struct ret r;
|
||||
|
||||
errno = 0;
|
||||
r.r = syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||
r.err = errno;
|
||||
return r;
|
||||
}
|
||||
|
||||
uintptr_t
|
||||
gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)
|
||||
{
|
||||
return syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build gccgo,linux,amd64
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
//extern gettimeofday
|
||||
func realGettimeofday(*Timeval, *byte) int32
|
||||
|
||||
func gettimeofday(tv *Timeval) (err syscall.Errno) {
|
||||
r := realGettimeofday(tv, nil)
|
||||
if r < 0 {
|
||||
return syscall.GetErrno()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// ioctl itself should not be exposed directly, but additional get/set
|
||||
// functions for specific types are permissible.
|
||||
|
||||
// IoctlSetInt performs an ioctl operation which sets an integer value
|
||||
// on fd, using the specified request number.
|
||||
func IoctlSetInt(fd int, req uint, value int) error {
|
||||
return ioctl(fd, req, uintptr(value))
|
||||
}
|
||||
|
||||
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
|
||||
//
|
||||
// To change fd's window size, the req argument should be TIOCSWINSZ.
|
||||
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
|
||||
// TODO: if we get the chance, remove the req parameter and
|
||||
// hardcode TIOCSWINSZ.
|
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
|
||||
runtime.KeepAlive(value)
|
||||
return err
|
||||
}
|
||||
|
||||
// IoctlSetTermios performs an ioctl on fd with a *Termios.
|
||||
//
|
||||
// The req value will usually be TCSETA or TIOCSETA.
|
||||
func IoctlSetTermios(fd int, req uint, value *Termios) error {
|
||||
// TODO: if we get the chance, remove the req parameter.
|
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
|
||||
runtime.KeepAlive(value)
|
||||
return err
|
||||
}
|
||||
|
||||
// IoctlGetInt performs an ioctl operation which gets an integer value
|
||||
// from fd, using the specified request number.
|
||||
//
|
||||
// A few ioctl requests use the return value as an output parameter;
|
||||
// for those, IoctlRetInt should be used instead of this function.
|
||||
func IoctlGetInt(fd int, req uint) (int, error) {
|
||||
var value int
|
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
|
||||
return value, err
|
||||
}
|
||||
|
||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
|
||||
var value Winsize
|
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
|
||||
return &value, err
|
||||
}
|
||||
|
||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
|
||||
var value Termios
|
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
|
||||
return &value, err
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user