mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
HLS: Ignore empty NALU to avoid error. v6.0.65 (#3750)
For the DJI M30, there is a bug where empty NALU packets with a size of zero are causing issues with HLS streaming. This bug leads to random unpublish events due to the SRS disconnecting the connection for the HLS module when it fails to handle empty NALU packets. To address this bug, we have patched the system to ignore any empty NALU packets with a size of zero. Additionally, we have created a tool in the srs-bench to replay pcapng files captured by tcpdump or Wireshark. We have also added utest using mprotect and asan to detect any memory corruption. It is important to note that this bug has been fixed in versions 4.0.2716477f31004
and 5.0.170939f6b484b
. This patch specifically addresses the issue in SRS 6.0. Please be aware that there is another commit related to this bug that partially fixes the issue but still leaves a small problem for asan to detect memory corruption. This commit,577cd299e1
, only ignores empty NALU packets but still reads beyond the memory. --------- Co-authored-by: chundonglinlin <chundonglinlin@163.com>
This commit is contained in:
parent
e19efe0bcd
commit
73dd8af4c9
182 changed files with 46111 additions and 3914 deletions
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
|
@ -419,7 +419,7 @@ jobs:
|
||||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
|
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
|
||||||
# Create release.
|
# Create release.
|
||||||
# TODO: FIXME: Refine the release when 6.0 released
|
# TODO: FIXME: Refine the release when 6.0 released
|
||||||
# TODO: FIXME: Change prerelease to false when 6.0 released
|
# TODO: FIXME: Change prerelease to false and makeLatest to true when 6.0 released
|
||||||
- name: Update release
|
- name: Update release
|
||||||
id: update_release
|
id: update_release
|
||||||
uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0
|
uses: ncipollo/release-action@a2e71bdd4e7dab70ca26a852f29600c98b33153e # v1.12.0
|
||||||
|
@ -466,6 +466,7 @@ jobs:
|
||||||
* [中文FAQ](https://ossrs.net/lts/zh-cn/faq), [功能列表](https://github.com/ossrs/srs/blob/${{ github.sha }}/trunk/doc/Features.md#features) 或 [修订历史](https://github.com/ossrs/srs/blob/${{ github.sha }}/trunk/doc/CHANGELOG.md#changelog)
|
* [中文FAQ](https://ossrs.net/lts/zh-cn/faq), [功能列表](https://github.com/ossrs/srs/blob/${{ github.sha }}/trunk/doc/Features.md#features) 或 [修订历史](https://github.com/ossrs/srs/blob/${{ github.sha }}/trunk/doc/CHANGELOG.md#changelog)
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
makeLatest: false
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
release-done:
|
release-done:
|
||||||
|
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
|
@ -81,7 +81,7 @@ jobs:
|
||||||
WORKDIR=$(cygpath -u $SRS_WORKSPACE) && export PATH=/usr/bin:/usr/local/bin && cd ${WORKDIR} &&
|
WORKDIR=$(cygpath -u $SRS_WORKSPACE) && export PATH=/usr/bin:/usr/local/bin && cd ${WORKDIR} &&
|
||||||
pwd && rm -rf /usr/local/srs-cache && mkdir -p /usr/local/srs-cache/srs/trunk && ls -lh &&
|
pwd && rm -rf /usr/local/srs-cache && mkdir -p /usr/local/srs-cache/srs/trunk && ls -lh &&
|
||||||
tar xf objs.tar.bz2 -C /usr/local/srs-cache/srs/trunk/ && du -sh /usr/local/srs-cache/srs/trunk/* &&
|
tar xf objs.tar.bz2 -C /usr/local/srs-cache/srs/trunk/ && du -sh /usr/local/srs-cache/srs/trunk/* &&
|
||||||
cd ${WORKDIR}/trunk && ./configure --gb28181=on --utest=on && ls -lh && du -sh * && du -sh objs/* &&
|
cd ${WORKDIR}/trunk && ./configure --h265=on --gb28181=on --utest=on && ls -lh && du -sh * && du -sh objs/* &&
|
||||||
cd ${WORKDIR}/trunk && make utest && ./objs/srs_utest
|
cd ${WORKDIR}/trunk && make utest && ./objs/srs_utest
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
|
1
trunk/3rdparty/srs-bench/.gitignore
vendored
1
trunk/3rdparty/srs-bench/.gitignore
vendored
|
@ -8,3 +8,4 @@ objs
|
||||||
.format.txt
|
.format.txt
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.log
|
*.log
|
||||||
|
*.pcapng
|
11
trunk/3rdparty/srs-bench/Makefile
vendored
11
trunk/3rdparty/srs-bench/Makefile
vendored
|
@ -11,7 +11,7 @@ clean:
|
||||||
gofmt -w *.go janus
|
gofmt -w *.go janus
|
||||||
mkdir -p objs && echo "done" > ./objs/.format.bench.txt
|
mkdir -p objs && echo "done" > ./objs/.format.bench.txt
|
||||||
|
|
||||||
bench: ./objs/srs_bench
|
bench: ./objs/srs_bench ./objs/pcap_simulator
|
||||||
|
|
||||||
./objs/srs_bench: ./objs/.format.bench.txt *.go janus/*.go srs/*.go vnet/*.go gb28181/*.go Makefile
|
./objs/srs_bench: ./objs/.format.bench.txt *.go janus/*.go srs/*.go vnet/*.go gb28181/*.go Makefile
|
||||||
go build -mod=vendor -o objs/srs_bench .
|
go build -mod=vendor -o objs/srs_bench .
|
||||||
|
@ -29,6 +29,15 @@ test: ./objs/srs_test ./objs/srs_gb28181_test ./objs/srs_blackbox_test
|
||||||
./objs/srs_test: ./objs/.format.srs.txt *.go srs/*.go vnet/*.go Makefile
|
./objs/srs_test: ./objs/.format.srs.txt *.go srs/*.go vnet/*.go Makefile
|
||||||
go test ./srs -mod=vendor -c -o ./objs/srs_test
|
go test ./srs -mod=vendor -c -o ./objs/srs_test
|
||||||
|
|
||||||
|
#########################################################################################################
|
||||||
|
# For pcap simulator test.
|
||||||
|
./objs/.format.pcap.txt: pcap/*.go
|
||||||
|
gofmt -w pcap
|
||||||
|
mkdir -p objs && echo "done" > ./objs/.format.pcap.txt
|
||||||
|
|
||||||
|
./objs/pcap_simulator: ./objs/.format.pcap.txt pcap/*.go Makefile
|
||||||
|
go build -mod=vendor -o ./objs/pcap_simulator ./pcap
|
||||||
|
|
||||||
#########################################################################################################
|
#########################################################################################################
|
||||||
# For gb28181 test.
|
# For gb28181 test.
|
||||||
./objs/.format.gb28181.txt: gb28181/*.go
|
./objs/.format.gb28181.txt: gb28181/*.go
|
||||||
|
|
1
trunk/3rdparty/srs-bench/go.mod
vendored
1
trunk/3rdparty/srs-bench/go.mod
vendored
|
@ -4,6 +4,7 @@ go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ghettovoice/gosip v0.0.0-20220929080231-de8ba881be83
|
github.com/ghettovoice/gosip v0.0.0-20220929080231-de8ba881be83
|
||||||
|
github.com/google/gopacket v1.1.19
|
||||||
github.com/ossrs/go-oryx-lib v0.0.9
|
github.com/ossrs/go-oryx-lib v0.0.9
|
||||||
github.com/pion/ice/v2 v2.3.6
|
github.com/pion/ice/v2 v2.3.6
|
||||||
github.com/pion/interceptor v0.1.17
|
github.com/pion/interceptor v0.1.17
|
||||||
|
|
5
trunk/3rdparty/srs-bench/go.sum
vendored
5
trunk/3rdparty/srs-bench/go.sum
vendored
|
@ -27,6 +27,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||||
|
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
@ -140,6 +142,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||||
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
@ -213,6 +217,7 @@ golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
|
128
trunk/3rdparty/srs-bench/pcap/main.go
vendored
Normal file
128
trunk/3rdparty/srs-bench/pcap/main.go
vendored
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
"github.com/google/gopacket/layers"
|
||||||
|
"github.com/google/gopacket/pcapgo"
|
||||||
|
"github.com/ossrs/go-oryx-lib/errors"
|
||||||
|
"github.com/ossrs/go-oryx-lib/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ctx := logger.WithContext(context.Background())
|
||||||
|
if err := doMain(ctx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func trace(format string, args ...interface{}) {
|
||||||
|
fmt.Println(fmt.Sprintf(format, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func doMain(ctx context.Context) error {
|
||||||
|
var doRE, doTrace, help bool
|
||||||
|
var pauseNumber, abortNumber uint64
|
||||||
|
var filename string
|
||||||
|
var server string
|
||||||
|
flag.BoolVar(&help, "h", false, "whether show this help")
|
||||||
|
flag.BoolVar(&help, "help", false, "whether show this help")
|
||||||
|
flag.BoolVar(&doRE, "re", true, "whether do real-time emulation")
|
||||||
|
flag.BoolVar(&doTrace, "trace", true, "whether trace the packet")
|
||||||
|
flag.Uint64Var(&pauseNumber, "pause", 0, "the packet number to pause")
|
||||||
|
flag.Uint64Var(&abortNumber, "abort", 0, "the packet number to abort")
|
||||||
|
flag.StringVar(&filename, "f", "", "the pcap filename, like ./t.pcapng")
|
||||||
|
flag.StringVar(&server, "s", "", "the server address, like 127.0.0.1:1935")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if help {
|
||||||
|
flag.Usage()
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if filename == "" || server == "" {
|
||||||
|
flag.Usage()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Tf(ctx, "Forward pcap %v to %v, re=%v, trace=%v, pause=%v, abort=%v",
|
||||||
|
filename, server, doRE, doTrace, pauseNumber, abortNumber)
|
||||||
|
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "open pcap %v", filename)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
r, err := pcapgo.NewNgReader(f, pcapgo.DefaultNgReaderOptions)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "new reader")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: FIXME: Should start a goroutine to consume bytes from conn.
|
||||||
|
conn, err := net.Dial("tcp", server)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "dial %v", server)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
var packetNumber uint64
|
||||||
|
var previousTime *time.Time
|
||||||
|
source := gopacket.NewPacketSource(r, r.LinkType())
|
||||||
|
for packet := range source.Packets() {
|
||||||
|
packetNumber++
|
||||||
|
|
||||||
|
if packet.Layer(layers.LayerTypeTCP) == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ci := packet.Metadata().CaptureInfo
|
||||||
|
tcp, _ := packet.Layer(layers.LayerTypeTCP).(*layers.TCP)
|
||||||
|
payload := tcp.Payload
|
||||||
|
if len(payload) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if tcp.DstPort != 1935 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if pauseNumber > 0 && packetNumber == pauseNumber {
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
trace("#%v Press Enter to continue...", packetNumber)
|
||||||
|
_, _ = reader.ReadString('\n')
|
||||||
|
}
|
||||||
|
if abortNumber > 0 && packetNumber > abortNumber {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := conn.Write(payload); err != nil {
|
||||||
|
return errors.Wrapf(err, "write to %v", server)
|
||||||
|
}
|
||||||
|
|
||||||
|
if doRE {
|
||||||
|
if previousTime != nil {
|
||||||
|
if diff := ci.Timestamp.Sub(*previousTime); diff > 0 {
|
||||||
|
time.Sleep(diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previousTime = &ci.Timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
if doTrace {
|
||||||
|
trace("#%v TCP %v=>%v %v Len:%v",
|
||||||
|
packetNumber, uint16(tcp.SrcPort), uint16(tcp.DstPort),
|
||||||
|
ci.Timestamp.Format("15:04:05.000"),
|
||||||
|
len(payload))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
1
trunk/3rdparty/srs-bench/vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
1
trunk/3rdparty/srs-bench/vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
|
@ -18,7 +18,6 @@
|
||||||
// tag is deprecated and thus should not be used.
|
// tag is deprecated and thus should not be used.
|
||||||
// Go versions prior to 1.4 are disabled because they use a different layout
|
// Go versions prior to 1.4 are disabled because they use a different layout
|
||||||
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
||||||
//go:build !js && !appengine && !safe && !disableunsafe && go1.4
|
|
||||||
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
||||||
|
|
||||||
package spew
|
package spew
|
||||||
|
|
1
trunk/3rdparty/srs-bench/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
1
trunk/3rdparty/srs-bench/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
|
@ -16,7 +16,6 @@
|
||||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
// when the code is running on Google App Engine, compiled by GopherJS, or
|
||||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
||||||
// tag is deprecated and thus should not be used.
|
// tag is deprecated and thus should not be used.
|
||||||
//go:build js || appengine || safe || disableunsafe || !go1.4
|
|
||||||
// +build js appengine safe disableunsafe !go1.4
|
// +build js appengine safe disableunsafe !go1.4
|
||||||
|
|
||||||
package spew
|
package spew
|
||||||
|
|
4
trunk/3rdparty/srs-bench/vendor/github.com/ghettovoice/gosip/sip/parser/error.go
generated
vendored
4
trunk/3rdparty/srs-bench/vendor/github.com/ghettovoice/gosip/sip/parser/error.go
generated
vendored
|
@ -11,9 +11,7 @@ type InvalidStartLineError string
|
||||||
func (err InvalidStartLineError) Syntax() bool { return true }
|
func (err InvalidStartLineError) Syntax() bool { return true }
|
||||||
func (err InvalidStartLineError) Malformed() bool { return false }
|
func (err InvalidStartLineError) Malformed() bool { return false }
|
||||||
func (err InvalidStartLineError) Broken() bool { return true }
|
func (err InvalidStartLineError) Broken() bool { return true }
|
||||||
func (err InvalidStartLineError) Error() string {
|
func (err InvalidStartLineError) Error() string { return "parser.InvalidStartLineError: " + string(err) }
|
||||||
return "parser.InvalidStartLineError: " + string(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
type InvalidMessageFormat string
|
type InvalidMessageFormat string
|
||||||
|
|
||||||
|
|
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbufio/pbufio_go110.go
generated
vendored
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbufio/pbufio_go110.go
generated
vendored
|
@ -1,4 +1,3 @@
|
||||||
//go:build go1.10
|
|
||||||
// +build go1.10
|
// +build go1.10
|
||||||
|
|
||||||
package pbufio
|
package pbufio
|
||||||
|
|
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbufio/pbufio_go19.go
generated
vendored
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbufio/pbufio_go19.go
generated
vendored
|
@ -1,4 +1,3 @@
|
||||||
//go:build !go1.10
|
|
||||||
// +build !go1.10
|
// +build !go1.10
|
||||||
|
|
||||||
package pbufio
|
package pbufio
|
||||||
|
|
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbytes/pool.go
generated
vendored
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbytes/pool.go
generated
vendored
|
@ -1,4 +1,3 @@
|
||||||
//go:build !pool_sanitize
|
|
||||||
// +build !pool_sanitize
|
// +build !pool_sanitize
|
||||||
|
|
||||||
package pbytes
|
package pbytes
|
||||||
|
|
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbytes/pool_sanitize.go
generated
vendored
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbytes/pool_sanitize.go
generated
vendored
|
@ -1,4 +1,3 @@
|
||||||
//go:build pool_sanitize
|
|
||||||
// +build pool_sanitize
|
// +build pool_sanitize
|
||||||
|
|
||||||
package pbytes
|
package pbytes
|
||||||
|
|
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/ws/dialer_tls_go17.go
generated
vendored
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/ws/dialer_tls_go17.go
generated
vendored
|
@ -1,4 +1,3 @@
|
||||||
//go:build !go1.8
|
|
||||||
// +build !go1.8
|
// +build !go1.8
|
||||||
|
|
||||||
package ws
|
package ws
|
||||||
|
|
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/ws/dialer_tls_go18.go
generated
vendored
1
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/ws/dialer_tls_go18.go
generated
vendored
|
@ -1,4 +1,3 @@
|
||||||
//go:build go1.8
|
|
||||||
// +build go1.8
|
// +build go1.8
|
||||||
|
|
||||||
package ws
|
package ws
|
||||||
|
|
38
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.gitignore
generated
vendored
Normal file
38
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
#*
|
||||||
|
*~
|
||||||
|
|
||||||
|
# examples binaries
|
||||||
|
examples/synscan/synscan
|
||||||
|
examples/pfdump/pfdump
|
||||||
|
examples/pcapdump/pcapdump
|
||||||
|
examples/httpassembly/httpassembly
|
||||||
|
examples/statsassembly/statsassembly
|
||||||
|
examples/arpscan/arpscan
|
||||||
|
examples/bidirectional/bidirectional
|
||||||
|
examples/bytediff/bytediff
|
||||||
|
examples/reassemblydump/reassemblydump
|
||||||
|
layers/gen
|
||||||
|
macs/gen
|
||||||
|
pcap/pcap_tester
|
7
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.gofmt.sh
generated
vendored
Normal file
7
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.gofmt.sh
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd "$(dirname $0)"
|
||||||
|
if [ -n "$(go fmt ./...)" ]; then
|
||||||
|
echo "Go code is not formatted, run 'go fmt github.com/google/stenographer/...'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
28
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.golint.sh
generated
vendored
Normal file
28
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.golint.sh
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd "$(dirname $0)"
|
||||||
|
|
||||||
|
go get golang.org/x/lint/golint
|
||||||
|
DIRS=". tcpassembly tcpassembly/tcpreader ip4defrag reassembly macs pcapgo pcap afpacket pfring routing defrag/lcmdefrag"
|
||||||
|
# Add subdirectories here as we clean up golint on each.
|
||||||
|
for subdir in $DIRS; do
|
||||||
|
pushd $subdir
|
||||||
|
if golint |
|
||||||
|
grep -v CannotSetRFMon | # pcap exported error name
|
||||||
|
grep -v DataLost | # tcpassembly/tcpreader exported error name
|
||||||
|
grep .; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
popd
|
||||||
|
done
|
||||||
|
|
||||||
|
pushd layers
|
||||||
|
for file in *.go; do
|
||||||
|
if cat .lint_blacklist | grep -q $file; then
|
||||||
|
echo "Skipping lint of $file due to .lint_blacklist"
|
||||||
|
elif golint $file | grep .; then
|
||||||
|
echo "Lint error in file $file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
popd
|
10
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.govet.sh
generated
vendored
Normal file
10
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.govet.sh
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd "$(dirname $0)"
|
||||||
|
DIRS=". layers pcap pcapgo tcpassembly tcpassembly/tcpreader routing ip4defrag bytediff macs defrag/lcmdefrag"
|
||||||
|
set -e
|
||||||
|
for subdir in $DIRS; do
|
||||||
|
pushd $subdir
|
||||||
|
go vet
|
||||||
|
popd
|
||||||
|
done
|
9
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.install.sh
generated
vendored
Normal file
9
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.install.sh
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -ev
|
||||||
|
|
||||||
|
go get github.com/google/gopacket
|
||||||
|
go get github.com/google/gopacket/layers
|
||||||
|
go get github.com/google/gopacket/tcpassembly
|
||||||
|
go get github.com/google/gopacket/reassembly
|
||||||
|
go get github.com/google/gopacket/pcapgo
|
10
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.script.sh
generated
vendored
Normal file
10
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.script.sh
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -ev
|
||||||
|
|
||||||
|
go test github.com/google/gopacket
|
||||||
|
go test github.com/google/gopacket/layers
|
||||||
|
go test github.com/google/gopacket/tcpassembly
|
||||||
|
go test github.com/google/gopacket/reassembly
|
||||||
|
go test github.com/google/gopacket/pcapgo
|
||||||
|
go test github.com/google/gopacket/pcap
|
57
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.yml
generated
vendored
Normal file
57
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
language: go
|
||||||
|
go:
|
||||||
|
- 1.11.x
|
||||||
|
- 1.12.x
|
||||||
|
- 1.13.x
|
||||||
|
- master
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
libpcap-dev
|
||||||
|
|
||||||
|
# use modules except for older versions (see below)
|
||||||
|
install: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
- GO111MODULE=on
|
||||||
|
|
||||||
|
script: ./.travis.script.sh
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
allow_failures:
|
||||||
|
- go: master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- go: 1.5.x
|
||||||
|
install: ./.travis.install.sh
|
||||||
|
- go: 1.6.x
|
||||||
|
install: ./.travis.install.sh
|
||||||
|
- go: 1.7.x
|
||||||
|
install: ./.travis.install.sh
|
||||||
|
- go: 1.8.x
|
||||||
|
install: ./.travis.install.sh
|
||||||
|
- go: 1.9.x
|
||||||
|
install: ./.travis.install.sh
|
||||||
|
- go: 1.10.x
|
||||||
|
install: ./.travis.install.sh
|
||||||
|
- os: osx
|
||||||
|
go: 1.x
|
||||||
|
# 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
|
||||||
|
script:
|
||||||
|
- ./.travis.gofmt.sh
|
||||||
|
- ./.travis.govet.sh
|
||||||
|
- ./.travis.golint.sh
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- style
|
||||||
|
- test
|
54
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/AUTHORS
generated
vendored
Normal file
54
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/AUTHORS
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
AUTHORS AND MAINTAINERS:
|
||||||
|
|
||||||
|
MAIN DEVELOPERS:
|
||||||
|
Graeme Connell <gconnell@google.com, gsconnell@gmail.com>
|
||||||
|
|
||||||
|
AUTHORS:
|
||||||
|
Nigel Tao <nigeltao@google.com>
|
||||||
|
Cole Mickens <cole.mickens@gmail.com>
|
||||||
|
Ben Daglish <bdaglish@restorepoint.com>
|
||||||
|
Luis Martinez <martinezlc99@gmail.com>
|
||||||
|
Remco Verhoef <remco@dutchcoders.io>
|
||||||
|
Hiroaki Kawai <Hiroaki.Kawai@gmail.com>
|
||||||
|
Lukas Lueg <lukas.lueg@gmail.com>
|
||||||
|
Laurent Hausermann <laurent.hausermann@gmail.com>
|
||||||
|
Bill Green <bgreen@newrelic.com>
|
||||||
|
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>
|
||||||
|
Vittus Mikiassen <matt.miki.vimik@gmail.com>
|
||||||
|
Matthias Radestock <matthias.radestock@gmail.com>
|
||||||
|
Matthew Sackman <matthew@wellquite.org>
|
||||||
|
Loic Prylli <loicp@google.com>
|
||||||
|
Alexandre Fiori <fiorix@gmail.com>
|
||||||
|
Adrian Tam <adrian.c.m.tam@gmail.com>
|
||||||
|
Satoshi Matsumoto <kaorimatz@gmail.com>
|
||||||
|
David Stainton <dstainton415@gmail.com>
|
||||||
|
Jesse Ward <jesse@jesseward.com>
|
||||||
|
Kane Mathers <kane@kanemathers.name>
|
||||||
|
Jose Selvi <jselvi@pentester.es>
|
||||||
|
Yerden Zhumabekov <yerden.zhumabekov@gmail.com>
|
||||||
|
Jensen Hwa <jensenhwa@gmail.com>
|
||||||
|
|
||||||
|
-----------------------------------------------
|
||||||
|
FORKED FROM github.com/akrennmair/gopcap
|
||||||
|
ALL THE FOLLOWING ARE FOR THAT PROJECT
|
||||||
|
|
||||||
|
MAIN DEVELOPERS:
|
||||||
|
Andreas Krennmair <ak@synflood.at>
|
||||||
|
|
||||||
|
CONTRIBUTORS:
|
||||||
|
Andrea Nall <anall@andreanall.com>
|
||||||
|
Daniel Arndt <danielarndt@gmail.com>
|
||||||
|
Dustin Sallings <dustin@spy.net>
|
||||||
|
Graeme Connell <gconnell@google.com, gsconnell@gmail.com>
|
||||||
|
Guillaume Savary <guillaume@savary.name>
|
||||||
|
Mark Smith <mark@qq.is>
|
||||||
|
Miek Gieben <miek@miek.nl>
|
||||||
|
Mike Bell <mike@mikebell.org>
|
||||||
|
Trevor Strohman <strohman@google.com>
|
215
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/CONTRIBUTING.md
generated
vendored
Normal file
215
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/CONTRIBUTING.md
generated
vendored
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
Contributing To gopacket
|
||||||
|
========================
|
||||||
|
|
||||||
|
So you've got some code and you'd like it to be part of gopacket... wonderful!
|
||||||
|
We're happy to accept contributions, whether they're fixes to old protocols, new
|
||||||
|
protocols entirely, or anything else you think would improve the gopacket
|
||||||
|
library. This document is designed to help you to do just that.
|
||||||
|
|
||||||
|
The first section deals with the plumbing: how to actually get a change
|
||||||
|
submitted.
|
||||||
|
|
||||||
|
The second section deals with coding style... Go is great in that it
|
||||||
|
has a uniform style implemented by 'go fmt', but there's still some decisions
|
||||||
|
we've made that go above and beyond, and if you follow them, they won't come up
|
||||||
|
in your code review.
|
||||||
|
|
||||||
|
The third section deals with some of the implementation decisions we've made,
|
||||||
|
which may help you to understand the current code and which we may ask you to
|
||||||
|
conform to (or provide compelling reasons for ignoring).
|
||||||
|
|
||||||
|
Overall, we hope this document will help you to understand our system and write
|
||||||
|
great code which fits in, and help us to turn around on your code review quickly
|
||||||
|
so the code can make it into the master branch as quickly as possible.
|
||||||
|
|
||||||
|
|
||||||
|
How To Submit Code
|
||||||
|
------------------
|
||||||
|
|
||||||
|
We use github.com's Pull Request feature to receive code contributions from
|
||||||
|
external contributors. See
|
||||||
|
https://help.github.com/articles/creating-a-pull-request/ for details on
|
||||||
|
how to create a request.
|
||||||
|
|
||||||
|
Also, there's a local script `gc` in the base directory of GoPacket that
|
||||||
|
runs a local set of checks, which should give you relatively high confidence
|
||||||
|
that your pull won't fail github pull checks.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go get github.com/google/gopacket
|
||||||
|
cd $GOROOT/src/pkg/github.com/google/gopacket
|
||||||
|
git checkout -b <mynewfeature> # create a new branch to work from
|
||||||
|
... code code code ...
|
||||||
|
./gc # Run this to do local commits, it performs a number of checks
|
||||||
|
```
|
||||||
|
|
||||||
|
To sum up:
|
||||||
|
|
||||||
|
* DO
|
||||||
|
+ Pull down the latest version.
|
||||||
|
+ Make a feature-specific branch.
|
||||||
|
+ Code using the style and methods discussed in the rest of this document.
|
||||||
|
+ Use the ./gc command to do local commits or check correctness.
|
||||||
|
+ Push your new feature branch up to github.com, as a pull request.
|
||||||
|
+ Handle comments and requests from reviewers, pushing new commits up to
|
||||||
|
your feature branch as problems are addressed.
|
||||||
|
+ Put interesting comments and discussions into commit comments.
|
||||||
|
* DON'T
|
||||||
|
+ Push to someone else's branch without their permission.
|
||||||
|
|
||||||
|
|
||||||
|
Coding Style
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Go code must be run through `go fmt`, `go vet`, and `golint`
|
||||||
|
* Follow http://golang.org/doc/effective_go.html as much as possible.
|
||||||
|
+ In particular, http://golang.org/doc/effective_go.html#mixed-caps. Enums
|
||||||
|
should be be CamelCase, with acronyms capitalized (TCPSourcePort, vs.
|
||||||
|
TcpSourcePort or TCP_SOURCE_PORT).
|
||||||
|
* Bonus points for giving enum types a String() field.
|
||||||
|
* Any exported types or functions should have commentary
|
||||||
|
(http://golang.org/doc/effective_go.html#commentary)
|
||||||
|
|
||||||
|
|
||||||
|
Coding Methods And Implementation Notes
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
Many times, you'll be decoding a protocol and run across something bad, a packet
|
||||||
|
corruption or the like. How do you handle this? First off, ALWAYS report the
|
||||||
|
error. You can do this either by returning the error from the decode() function
|
||||||
|
(most common), or if you're up for it you can implement and add an ErrorLayer
|
||||||
|
through the packet builder (the first method is a simple shortcut that does
|
||||||
|
exactly this, then stops any future decoding).
|
||||||
|
|
||||||
|
Often, you'll already have decode some part of your protocol by the time you hit
|
||||||
|
your error. Use your own discretion to determine whether the stuff you've
|
||||||
|
already decoded should be returned to the caller or not:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func decodeMyProtocol(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
prot := &MyProtocol{}
|
||||||
|
if len(data) < 10 {
|
||||||
|
// This error occurred before we did ANYTHING, so there's nothing in my
|
||||||
|
// protocol that the caller could possibly want. Just return the error.
|
||||||
|
return fmt.Errorf("Length %d less than 10", len(data))
|
||||||
|
}
|
||||||
|
prot.ImportantField1 = data[:5]
|
||||||
|
prot.ImportantField2 = data[5:10]
|
||||||
|
// At this point, we've already got enough information in 'prot' to
|
||||||
|
// warrant returning it to the caller, so we'll add it now.
|
||||||
|
p.AddLayer(prot)
|
||||||
|
if len(data) < 15 {
|
||||||
|
// We encountered an error later in the packet, but the caller already
|
||||||
|
// has the important info we've gleaned so far.
|
||||||
|
return fmt.Errorf("Length %d less than 15", len(data))
|
||||||
|
}
|
||||||
|
prot.ImportantField3 = data[10:15]
|
||||||
|
return nil // We've already added the layer, we can just return success.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In general, our code follows the approach of returning the first error it
|
||||||
|
encounters. In general, we don't trust any bytes after the first error we see.
|
||||||
|
|
||||||
|
### What Is A Layer?
|
||||||
|
|
||||||
|
The definition of a layer is up to the discretion of the coder. It should be
|
||||||
|
something important enough that it's actually useful to the caller (IE: every
|
||||||
|
TLV value should probably NOT be a layer). However, it can be more granular
|
||||||
|
than a single protocol... IPv6 and SCTP both implement many layers to handle the
|
||||||
|
various parts of the protocol. Use your best judgement, and prepare to defend
|
||||||
|
your decisions during code review. ;)
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
We strive to make gopacket as fast as possible while still providing lots of
|
||||||
|
features. In general, this means:
|
||||||
|
|
||||||
|
* Focus performance tuning on common protocols (IP4/6, TCP, etc), and optimize
|
||||||
|
others on an as-needed basis (tons of MPLS on your network? Time to optimize
|
||||||
|
MPLS!)
|
||||||
|
* Use fast operations. See the toplevel benchmark_test for benchmarks of some
|
||||||
|
of Go's underlying features and types.
|
||||||
|
* Test your performance changes! You should use the ./gc script's --benchmark
|
||||||
|
flag to submit any performance-related changes. Use pcap/gopacket_benchmark
|
||||||
|
to test your change against a PCAP file based on your traffic patterns.
|
||||||
|
* Don't be TOO hacky. Sometimes, removing an unused struct from a field causes
|
||||||
|
a huge performance hit, due to the way that Go currently handles its segmented
|
||||||
|
stack... don't be afraid to clean it up anyway. We'll trust the Go compiler
|
||||||
|
to get good enough over time to handle this. Also, this type of
|
||||||
|
compiler-specific optimization is very fragile; someone adding a field to an
|
||||||
|
entirely different struct elsewhere in the codebase could reverse any gains
|
||||||
|
you might achieve by aligning your allocations.
|
||||||
|
* Try to minimize memory allocations. If possible, use []byte to reference
|
||||||
|
pieces of the input, instead of using string, which requires copying the bytes
|
||||||
|
into a new memory allocation.
|
||||||
|
* Think hard about what should be evaluated lazily vs. not. In general, a
|
||||||
|
layer's struct should almost exactly mirror the layer's frame. Anything
|
||||||
|
that's more interesting should be a function. This may not always be
|
||||||
|
possible, but it's a good rule of thumb.
|
||||||
|
* Don't fear micro-optimizations. With the above in mind, we welcome
|
||||||
|
micro-optimizations that we think will have positive/neutral impacts on the
|
||||||
|
majority of workloads. A prime example of this is pre-allocating certain
|
||||||
|
structs within a larger one:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type MyProtocol struct {
|
||||||
|
// Most packets have 1-4 of VeryCommon, so we preallocate it here.
|
||||||
|
initialAllocation [4]uint32
|
||||||
|
VeryCommon []uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeMyProtocol(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
prot := &MyProtocol{}
|
||||||
|
prot.VeryCommon = proto.initialAllocation[:0]
|
||||||
|
for len(data) > 4 {
|
||||||
|
field := binary.BigEndian.Uint32(data[:4])
|
||||||
|
data = data[4:]
|
||||||
|
// Since we're using the underlying initialAllocation, we won't need to
|
||||||
|
// allocate new memory for the following append unless we more than 16
|
||||||
|
// bytes of data, which should be the uncommon case.
|
||||||
|
prot.VeryCommon = append(prot.VeryCommon, field)
|
||||||
|
}
|
||||||
|
p.AddLayer(prot)
|
||||||
|
if len(data) > 0 {
|
||||||
|
return fmt.Errorf("MyProtocol packet has %d bytes left after decoding", len(data))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Slices And Data
|
||||||
|
|
||||||
|
If you're pulling a slice from the data you're decoding, don't copy it. Just
|
||||||
|
use the slice itself.
|
||||||
|
|
||||||
|
```go
|
||||||
|
type MyProtocol struct {
|
||||||
|
A, B net.IP
|
||||||
|
}
|
||||||
|
func decodeMyProtocol(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
p.AddLayer(&MyProtocol{
|
||||||
|
A: data[:4],
|
||||||
|
B: data[4:8],
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The caller has already agreed, by using this library, that they won't modify the
|
||||||
|
set of bytes they pass in to the decoder, or the library has already copied the
|
||||||
|
set of bytes to a read-only location. See DecodeOptions.NoCopy for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
### Enums/Types
|
||||||
|
|
||||||
|
If a protocol has an integer field (uint8, uint16, etc) with a couple of known
|
||||||
|
values that mean something special, make it a type. This allows us to do really
|
||||||
|
nice things like adding a String() function to them, so we can more easily
|
||||||
|
display those to users. Check out layers/enums.go for one example, as well as
|
||||||
|
layers/icmp.go for layer-specific enums.
|
||||||
|
|
||||||
|
When naming things, try for descriptiveness over suscinctness. For example,
|
||||||
|
choose DNSResponseRecord over DNSRR.
|
28
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/LICENSE
generated
vendored
Normal file
28
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
Copyright (c) 2012 Google, Inc. All rights reserved.
|
||||||
|
Copyright (c) 2009-2011 Andreas Krennmair. 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 Andreas Krennmair, Google, 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.
|
12
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/README.md
generated
vendored
Normal file
12
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/README.md
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# GoPacket
|
||||||
|
|
||||||
|
This library provides packet decoding capabilities for Go.
|
||||||
|
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.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).
|
178
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/base.go
generated
vendored
Normal file
178
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/base.go
generated
vendored
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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 gopacket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Layer represents a single decoded packet layer (using either the
|
||||||
|
// OSI or TCP/IP definition of a layer). When decoding, a packet's data is
|
||||||
|
// broken up into a number of layers. The caller may call LayerType() to
|
||||||
|
// figure out which type of layer they've received from the packet. Optionally,
|
||||||
|
// they may then use a type assertion to get the actual layer type for deep
|
||||||
|
// inspection of the data.
|
||||||
|
type Layer interface {
|
||||||
|
// LayerType is the gopacket type for this layer.
|
||||||
|
LayerType() LayerType
|
||||||
|
// LayerContents returns the set of bytes that make up this layer.
|
||||||
|
LayerContents() []byte
|
||||||
|
// LayerPayload returns the set of bytes contained within this layer, not
|
||||||
|
// including the layer itself.
|
||||||
|
LayerPayload() []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payload is a Layer containing the payload of a packet. The definition of
|
||||||
|
// what constitutes the payload of a packet depends on previous layers; for
|
||||||
|
// TCP and UDP, we stop decoding above layer 4 and return the remaining
|
||||||
|
// bytes as a Payload. Payload is an ApplicationLayer.
|
||||||
|
type Payload []byte
|
||||||
|
|
||||||
|
// LayerType returns LayerTypePayload
|
||||||
|
func (p Payload) LayerType() LayerType { return LayerTypePayload }
|
||||||
|
|
||||||
|
// LayerContents returns the bytes making up this layer.
|
||||||
|
func (p Payload) LayerContents() []byte { return []byte(p) }
|
||||||
|
|
||||||
|
// LayerPayload returns the payload within this layer.
|
||||||
|
func (p Payload) LayerPayload() []byte { return nil }
|
||||||
|
|
||||||
|
// Payload returns this layer as bytes.
|
||||||
|
func (p Payload) Payload() []byte { return []byte(p) }
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
func (p Payload) String() string { return fmt.Sprintf("%d byte(s)", len(p)) }
|
||||||
|
|
||||||
|
// GoString implements fmt.GoStringer.
|
||||||
|
func (p Payload) GoString() string { return LongBytesGoString([]byte(p)) }
|
||||||
|
|
||||||
|
// CanDecode implements DecodingLayer.
|
||||||
|
func (p Payload) CanDecode() LayerClass { return LayerTypePayload }
|
||||||
|
|
||||||
|
// NextLayerType implements DecodingLayer.
|
||||||
|
func (p Payload) NextLayerType() LayerType { return LayerTypeZero }
|
||||||
|
|
||||||
|
// DecodeFromBytes implements DecodingLayer.
|
||||||
|
func (p *Payload) DecodeFromBytes(data []byte, df DecodeFeedback) error {
|
||||||
|
*p = Payload(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (p Payload) SerializeTo(b SerializeBuffer, opts SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(len(p))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
copy(bytes, p)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodePayload decodes data by returning it all in a Payload layer.
|
||||||
|
func decodePayload(data []byte, p PacketBuilder) error {
|
||||||
|
payload := &Payload{}
|
||||||
|
if err := payload.DecodeFromBytes(data, p); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(payload)
|
||||||
|
p.SetApplicationLayer(payload)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fragment is a Layer containing a fragment of a larger frame, used by layers
|
||||||
|
// like IPv4 and IPv6 that allow for fragmentation of their payloads.
|
||||||
|
type Fragment []byte
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeFragment
|
||||||
|
func (p *Fragment) LayerType() LayerType { return LayerTypeFragment }
|
||||||
|
|
||||||
|
// LayerContents implements Layer.
|
||||||
|
func (p *Fragment) LayerContents() []byte { return []byte(*p) }
|
||||||
|
|
||||||
|
// LayerPayload implements Layer.
|
||||||
|
func (p *Fragment) LayerPayload() []byte { return nil }
|
||||||
|
|
||||||
|
// Payload returns this layer as a byte slice.
|
||||||
|
func (p *Fragment) Payload() []byte { return []byte(*p) }
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
func (p *Fragment) String() string { return fmt.Sprintf("%d byte(s)", len(*p)) }
|
||||||
|
|
||||||
|
// CanDecode implements DecodingLayer.
|
||||||
|
func (p *Fragment) CanDecode() LayerClass { return LayerTypeFragment }
|
||||||
|
|
||||||
|
// NextLayerType implements DecodingLayer.
|
||||||
|
func (p *Fragment) NextLayerType() LayerType { return LayerTypeZero }
|
||||||
|
|
||||||
|
// DecodeFromBytes implements DecodingLayer.
|
||||||
|
func (p *Fragment) DecodeFromBytes(data []byte, df DecodeFeedback) error {
|
||||||
|
*p = Fragment(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (p *Fragment) SerializeTo(b SerializeBuffer, opts SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(len(*p))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
copy(bytes, *p)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeFragment decodes data by returning it all in a Fragment layer.
|
||||||
|
func decodeFragment(data []byte, p PacketBuilder) error {
|
||||||
|
payload := &Fragment{}
|
||||||
|
if err := payload.DecodeFromBytes(data, p); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(payload)
|
||||||
|
p.SetApplicationLayer(payload)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// These layers correspond to Internet Protocol Suite (TCP/IP) layers, and their
|
||||||
|
// corresponding OSI layers, as best as possible.
|
||||||
|
|
||||||
|
// LinkLayer is the packet layer corresponding to TCP/IP layer 1 (OSI layer 2)
|
||||||
|
type LinkLayer interface {
|
||||||
|
Layer
|
||||||
|
LinkFlow() Flow
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkLayer is the packet layer corresponding to TCP/IP layer 2 (OSI
|
||||||
|
// layer 3)
|
||||||
|
type NetworkLayer interface {
|
||||||
|
Layer
|
||||||
|
NetworkFlow() Flow
|
||||||
|
}
|
||||||
|
|
||||||
|
// TransportLayer is the packet layer corresponding to the TCP/IP layer 3 (OSI
|
||||||
|
// layer 4)
|
||||||
|
type TransportLayer interface {
|
||||||
|
Layer
|
||||||
|
TransportFlow() Flow
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplicationLayer is the packet layer corresponding to the TCP/IP layer 4 (OSI
|
||||||
|
// layer 7), also known as the packet payload.
|
||||||
|
type ApplicationLayer interface {
|
||||||
|
Layer
|
||||||
|
Payload() []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorLayer is a packet layer created when decoding of the packet has failed.
|
||||||
|
// Its payload is all the bytes that we were unable to decode, and the returned
|
||||||
|
// error details why the decoding failed.
|
||||||
|
type ErrorLayer interface {
|
||||||
|
Layer
|
||||||
|
Error() error
|
||||||
|
}
|
157
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/decode.go
generated
vendored
Normal file
157
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/decode.go
generated
vendored
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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 gopacket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DecodeFeedback is used by DecodingLayer layers to provide decoding metadata.
|
||||||
|
type DecodeFeedback interface {
|
||||||
|
// SetTruncated should be called if during decoding you notice that a packet
|
||||||
|
// is shorter than internal layer variables (HeaderLength, or the like) say it
|
||||||
|
// should be. It sets packet.Metadata().Truncated.
|
||||||
|
SetTruncated()
|
||||||
|
}
|
||||||
|
|
||||||
|
type nilDecodeFeedback struct{}
|
||||||
|
|
||||||
|
func (nilDecodeFeedback) SetTruncated() {}
|
||||||
|
|
||||||
|
// NilDecodeFeedback implements DecodeFeedback by doing nothing.
|
||||||
|
var NilDecodeFeedback DecodeFeedback = nilDecodeFeedback{}
|
||||||
|
|
||||||
|
// PacketBuilder is used by layer decoders to store the layers they've decoded,
|
||||||
|
// and to defer future decoding via NextDecoder.
|
||||||
|
// Typically, the pattern for use is:
|
||||||
|
// func (m *myDecoder) Decode(data []byte, p PacketBuilder) error {
|
||||||
|
// if myLayer, err := myDecodingLogic(data); err != nil {
|
||||||
|
// return err
|
||||||
|
// } else {
|
||||||
|
// p.AddLayer(myLayer)
|
||||||
|
// }
|
||||||
|
// // maybe do this, if myLayer is a LinkLayer
|
||||||
|
// p.SetLinkLayer(myLayer)
|
||||||
|
// return p.NextDecoder(nextDecoder)
|
||||||
|
// }
|
||||||
|
type PacketBuilder interface {
|
||||||
|
DecodeFeedback
|
||||||
|
// AddLayer should be called by a decoder immediately upon successful
|
||||||
|
// decoding of a layer.
|
||||||
|
AddLayer(l Layer)
|
||||||
|
// The following functions set the various specific layers in the final
|
||||||
|
// packet. Note that if many layers call SetX, the first call is kept and all
|
||||||
|
// other calls are ignored.
|
||||||
|
SetLinkLayer(LinkLayer)
|
||||||
|
SetNetworkLayer(NetworkLayer)
|
||||||
|
SetTransportLayer(TransportLayer)
|
||||||
|
SetApplicationLayer(ApplicationLayer)
|
||||||
|
SetErrorLayer(ErrorLayer)
|
||||||
|
// NextDecoder should be called by a decoder when they're done decoding a
|
||||||
|
// packet layer but not done with decoding the entire packet. The next
|
||||||
|
// decoder will be called to decode the last AddLayer's LayerPayload.
|
||||||
|
// Because of this, NextDecoder must only be called once all other
|
||||||
|
// PacketBuilder calls have been made. Set*Layer and AddLayer calls after
|
||||||
|
// NextDecoder calls will behave incorrectly.
|
||||||
|
NextDecoder(next Decoder) error
|
||||||
|
// DumpPacketData is used solely for decoding. If you come across an error
|
||||||
|
// you need to diagnose while processing a packet, call this and your packet's
|
||||||
|
// data will be dumped to stderr so you can create a test. This should never
|
||||||
|
// be called from a production decoder.
|
||||||
|
DumpPacketData()
|
||||||
|
// DecodeOptions returns the decode options
|
||||||
|
DecodeOptions() *DecodeOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder is an interface for logic to decode a packet layer. Users may
|
||||||
|
// implement a Decoder to handle their own strange packet types, or may use one
|
||||||
|
// of the many decoders available in the 'layers' subpackage to decode things
|
||||||
|
// for them.
|
||||||
|
type Decoder interface {
|
||||||
|
// Decode decodes the bytes of a packet, sending decoded values and other
|
||||||
|
// information to PacketBuilder, and returning an error if unsuccessful. See
|
||||||
|
// the PacketBuilder documentation for more details.
|
||||||
|
Decode([]byte, PacketBuilder) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFunc wraps a function to make it a Decoder.
|
||||||
|
type DecodeFunc func([]byte, PacketBuilder) error
|
||||||
|
|
||||||
|
// Decode implements Decoder by calling itself.
|
||||||
|
func (d DecodeFunc) Decode(data []byte, p PacketBuilder) error {
|
||||||
|
// function, call thyself.
|
||||||
|
return d(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodePayload is a Decoder that returns a Payload layer containing all
|
||||||
|
// remaining bytes.
|
||||||
|
var DecodePayload Decoder = DecodeFunc(decodePayload)
|
||||||
|
|
||||||
|
// DecodeUnknown is a Decoder that returns an Unknown layer containing all
|
||||||
|
// remaining bytes, useful if you run up against a layer that you're unable to
|
||||||
|
// decode yet. This layer is considered an ErrorLayer.
|
||||||
|
var DecodeUnknown Decoder = DecodeFunc(decodeUnknown)
|
||||||
|
|
||||||
|
// DecodeFragment is a Decoder that returns a Fragment layer containing all
|
||||||
|
// remaining bytes.
|
||||||
|
var DecodeFragment Decoder = DecodeFunc(decodeFragment)
|
||||||
|
|
||||||
|
// LayerTypeZero is an invalid layer type, but can be used to determine whether
|
||||||
|
// layer type has actually been set correctly.
|
||||||
|
var LayerTypeZero = RegisterLayerType(0, LayerTypeMetadata{Name: "Unknown", Decoder: DecodeUnknown})
|
||||||
|
|
||||||
|
// LayerTypeDecodeFailure is the layer type for the default error layer.
|
||||||
|
var LayerTypeDecodeFailure = RegisterLayerType(1, LayerTypeMetadata{Name: "DecodeFailure", Decoder: DecodeUnknown})
|
||||||
|
|
||||||
|
// LayerTypePayload is the layer type for a payload that we don't try to decode
|
||||||
|
// but treat as a success, IE: an application-level payload.
|
||||||
|
var LayerTypePayload = RegisterLayerType(2, LayerTypeMetadata{Name: "Payload", Decoder: DecodePayload})
|
||||||
|
|
||||||
|
// LayerTypeFragment is the layer type for a fragment of a layer transported
|
||||||
|
// by an underlying layer that supports fragmentation.
|
||||||
|
var LayerTypeFragment = RegisterLayerType(3, LayerTypeMetadata{Name: "Fragment", Decoder: DecodeFragment})
|
||||||
|
|
||||||
|
// DecodeFailure is a packet layer created if decoding of the packet data failed
|
||||||
|
// for some reason. It implements ErrorLayer. LayerContents will be the entire
|
||||||
|
// set of bytes that failed to parse, and Error will return the reason parsing
|
||||||
|
// failed.
|
||||||
|
type DecodeFailure struct {
|
||||||
|
data []byte
|
||||||
|
err error
|
||||||
|
stack []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns the error encountered during decoding.
|
||||||
|
func (d *DecodeFailure) Error() error { return d.err }
|
||||||
|
|
||||||
|
// LayerContents implements Layer.
|
||||||
|
func (d *DecodeFailure) LayerContents() []byte { return d.data }
|
||||||
|
|
||||||
|
// LayerPayload implements Layer.
|
||||||
|
func (d *DecodeFailure) LayerPayload() []byte { return nil }
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
func (d *DecodeFailure) String() string {
|
||||||
|
return "Packet decoding error: " + d.Error().Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump implements Dumper.
|
||||||
|
func (d *DecodeFailure) Dump() (s string) {
|
||||||
|
if d.stack != nil {
|
||||||
|
s = string(d.stack)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeDecodeFailure
|
||||||
|
func (d *DecodeFailure) LayerType() LayerType { return LayerTypeDecodeFailure }
|
||||||
|
|
||||||
|
// decodeUnknown "decodes" unsupported data types by returning an error.
|
||||||
|
// This decoder will thus always return a DecodeFailure layer.
|
||||||
|
func decodeUnknown(data []byte, p PacketBuilder) error {
|
||||||
|
return errors.New("Layer type not currently supported")
|
||||||
|
}
|
432
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/doc.go
generated
vendored
Normal file
432
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,432 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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 gopacket provides packet decoding for the Go language.
|
||||||
|
|
||||||
|
gopacket contains many sub-packages with additional functionality you may find
|
||||||
|
useful, including:
|
||||||
|
|
||||||
|
* layers: You'll probably use this every time. This contains of the logic
|
||||||
|
built into gopacket for decoding packet protocols. Note that all example
|
||||||
|
code below assumes that you have imported both gopacket and
|
||||||
|
gopacket/layers.
|
||||||
|
* pcap: C bindings to use libpcap to read packets off the wire.
|
||||||
|
* pfring: C bindings to use PF_RING to read packets off the wire.
|
||||||
|
* afpacket: C bindings for Linux's AF_PACKET to read packets off the wire.
|
||||||
|
* tcpassembly: TCP stream reassembly
|
||||||
|
|
||||||
|
Also, if you're looking to dive right into code, see the examples subdirectory
|
||||||
|
for numerous simple binaries built using gopacket libraries.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Basic Usage
|
||||||
|
|
||||||
|
gopacket takes in packet data as a []byte and decodes it into a packet with
|
||||||
|
a non-zero number of "layers". Each layer corresponds to a protocol
|
||||||
|
within the bytes. Once a packet has been decoded, the layers of the packet
|
||||||
|
can be requested from the packet.
|
||||||
|
|
||||||
|
// Decode a packet
|
||||||
|
packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Default)
|
||||||
|
// Get the TCP layer from this packet
|
||||||
|
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
|
||||||
|
fmt.Println("This is a TCP packet!")
|
||||||
|
// Get actual TCP data from this layer
|
||||||
|
tcp, _ := tcpLayer.(*layers.TCP)
|
||||||
|
fmt.Printf("From src port %d to dst port %d\n", tcp.SrcPort, tcp.DstPort)
|
||||||
|
}
|
||||||
|
// Iterate over all layers, printing out each layer type
|
||||||
|
for _, layer := range packet.Layers() {
|
||||||
|
fmt.Println("PACKET LAYER:", layer.LayerType())
|
||||||
|
}
|
||||||
|
|
||||||
|
Packets can be decoded from a number of starting points. Many of our base
|
||||||
|
types implement Decoder, which allow us to decode packets for which
|
||||||
|
we don't have full data.
|
||||||
|
|
||||||
|
// Decode an ethernet packet
|
||||||
|
ethP := gopacket.NewPacket(p1, layers.LayerTypeEthernet, gopacket.Default)
|
||||||
|
// Decode an IPv6 header and everything it contains
|
||||||
|
ipP := gopacket.NewPacket(p2, layers.LayerTypeIPv6, gopacket.Default)
|
||||||
|
// Decode a TCP header and its payload
|
||||||
|
tcpP := gopacket.NewPacket(p3, layers.LayerTypeTCP, gopacket.Default)
|
||||||
|
|
||||||
|
|
||||||
|
Reading Packets From A Source
|
||||||
|
|
||||||
|
Most of the time, you won't just have a []byte of packet data lying around.
|
||||||
|
Instead, you'll want to read packets in from somewhere (file, interface, etc)
|
||||||
|
and process them. To do that, you'll want to build a PacketSource.
|
||||||
|
|
||||||
|
First, you'll need to construct an object that implements the PacketDataSource
|
||||||
|
interface. There are implementations of this interface bundled with gopacket
|
||||||
|
in the gopacket/pcap and gopacket/pfring subpackages... see their documentation
|
||||||
|
for more information on their usage. Once you have a PacketDataSource, you can
|
||||||
|
pass it into NewPacketSource, along with a Decoder of your choice, to create
|
||||||
|
a PacketSource.
|
||||||
|
|
||||||
|
Once you have a PacketSource, you can read packets from it in multiple ways.
|
||||||
|
See the docs for PacketSource for more details. The easiest method is the
|
||||||
|
Packets function, which returns a channel, then asynchronously writes new
|
||||||
|
packets into that channel, closing the channel if the packetSource hits an
|
||||||
|
end-of-file.
|
||||||
|
|
||||||
|
packetSource := ... // construct using pcap or pfring
|
||||||
|
for packet := range packetSource.Packets() {
|
||||||
|
handlePacket(packet) // do something with each packet
|
||||||
|
}
|
||||||
|
|
||||||
|
You can change the decoding options of the packetSource by setting fields in
|
||||||
|
packetSource.DecodeOptions... see the following sections for more details.
|
||||||
|
|
||||||
|
|
||||||
|
Lazy Decoding
|
||||||
|
|
||||||
|
gopacket optionally decodes packet data lazily, meaning it
|
||||||
|
only decodes a packet layer when it needs to handle a function call.
|
||||||
|
|
||||||
|
// Create a packet, but don't actually decode anything yet
|
||||||
|
packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Lazy)
|
||||||
|
// Now, decode the packet up to the first IPv4 layer found but no further.
|
||||||
|
// If no IPv4 layer was found, the whole packet will be decoded looking for
|
||||||
|
// it.
|
||||||
|
ip4 := packet.Layer(layers.LayerTypeIPv4)
|
||||||
|
// Decode all layers and return them. The layers up to the first IPv4 layer
|
||||||
|
// are already decoded, and will not require decoding a second time.
|
||||||
|
layers := packet.Layers()
|
||||||
|
|
||||||
|
Lazily-decoded packets are not concurrency-safe. Since layers have not all been
|
||||||
|
decoded, each call to Layer() or Layers() has the potential to mutate the packet
|
||||||
|
in order to decode the next layer. If a packet is used
|
||||||
|
in multiple goroutines concurrently, don't use gopacket.Lazy. Then gopacket
|
||||||
|
will decode the packet fully, and all future function calls won't mutate the
|
||||||
|
object.
|
||||||
|
|
||||||
|
|
||||||
|
NoCopy Decoding
|
||||||
|
|
||||||
|
By default, gopacket will copy the slice passed to NewPacket and store the
|
||||||
|
copy within the packet, so future mutations to the bytes underlying the slice
|
||||||
|
don't affect the packet and its layers. If you can guarantee that the
|
||||||
|
underlying slice bytes won't be changed, you can use NoCopy to tell
|
||||||
|
gopacket.NewPacket, and it'll use the passed-in slice itself.
|
||||||
|
|
||||||
|
// This channel returns new byte slices, each of which points to a new
|
||||||
|
// memory location that's guaranteed immutable for the duration of the
|
||||||
|
// packet.
|
||||||
|
for data := range myByteSliceChannel {
|
||||||
|
p := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy)
|
||||||
|
doSomethingWithPacket(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
The fastest method of decoding is to use both Lazy and NoCopy, but note from
|
||||||
|
the many caveats above that for some implementations either or both may be
|
||||||
|
dangerous.
|
||||||
|
|
||||||
|
|
||||||
|
Pointers To Known Layers
|
||||||
|
|
||||||
|
During decoding, certain layers are stored in the packet as well-known
|
||||||
|
layer types. For example, IPv4 and IPv6 are both considered NetworkLayer
|
||||||
|
layers, while TCP and UDP are both TransportLayer layers. We support 4
|
||||||
|
layers, corresponding to the 4 layers of the TCP/IP layering scheme (roughly
|
||||||
|
anagalous to layers 2, 3, 4, and 7 of the OSI model). To access these,
|
||||||
|
you can use the packet.LinkLayer, packet.NetworkLayer,
|
||||||
|
packet.TransportLayer, and packet.ApplicationLayer functions. Each of
|
||||||
|
these functions returns a corresponding interface
|
||||||
|
(gopacket.{Link,Network,Transport,Application}Layer). The first three
|
||||||
|
provide methods for getting src/dst addresses for that particular layer,
|
||||||
|
while the final layer provides a Payload function to get payload data.
|
||||||
|
This is helpful, for example, to get payloads for all packets regardless
|
||||||
|
of their underlying data type:
|
||||||
|
|
||||||
|
// Get packets from some source
|
||||||
|
for packet := range someSource {
|
||||||
|
if app := packet.ApplicationLayer(); app != nil {
|
||||||
|
if strings.Contains(string(app.Payload()), "magic string") {
|
||||||
|
fmt.Println("Found magic string in a packet!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
A particularly useful layer is ErrorLayer, which is set whenever there's
|
||||||
|
an error parsing part of the packet.
|
||||||
|
|
||||||
|
packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Default)
|
||||||
|
if err := packet.ErrorLayer(); err != nil {
|
||||||
|
fmt.Println("Error decoding some part of the packet:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Note that we don't return an error from NewPacket because we may have decoded
|
||||||
|
a number of layers successfully before running into our erroneous layer. You
|
||||||
|
may still be able to get your Ethernet and IPv4 layers correctly, even if
|
||||||
|
your TCP layer is malformed.
|
||||||
|
|
||||||
|
|
||||||
|
Flow And Endpoint
|
||||||
|
|
||||||
|
gopacket has two useful objects, Flow and Endpoint, for communicating in a protocol
|
||||||
|
independent manner the fact that a packet is coming from A and going to B.
|
||||||
|
The general layer types LinkLayer, NetworkLayer, and TransportLayer all provide
|
||||||
|
methods for extracting their flow information, without worrying about the type
|
||||||
|
of the underlying Layer.
|
||||||
|
|
||||||
|
A Flow is a simple object made up of a set of two Endpoints, one source and one
|
||||||
|
destination. It details the sender and receiver of the Layer of the Packet.
|
||||||
|
|
||||||
|
An Endpoint is a hashable representation of a source or destination. For
|
||||||
|
example, for LayerTypeIPv4, an Endpoint contains the IP address bytes for a v4
|
||||||
|
IP packet. A Flow can be broken into Endpoints, and Endpoints can be combined
|
||||||
|
into Flows:
|
||||||
|
|
||||||
|
packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Lazy)
|
||||||
|
netFlow := packet.NetworkLayer().NetworkFlow()
|
||||||
|
src, dst := netFlow.Endpoints()
|
||||||
|
reverseFlow := gopacket.NewFlow(dst, src)
|
||||||
|
|
||||||
|
Both Endpoint and Flow objects can be used as map keys, and the equality
|
||||||
|
operator can compare them, so you can easily group together all packets
|
||||||
|
based on endpoint criteria:
|
||||||
|
|
||||||
|
flows := map[gopacket.Endpoint]chan gopacket.Packet
|
||||||
|
packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Lazy)
|
||||||
|
// Send all TCP packets to channels based on their destination port.
|
||||||
|
if tcp := packet.Layer(layers.LayerTypeTCP); tcp != nil {
|
||||||
|
flows[tcp.TransportFlow().Dst()] <- packet
|
||||||
|
}
|
||||||
|
// Look for all packets with the same source and destination network address
|
||||||
|
if net := packet.NetworkLayer(); net != nil {
|
||||||
|
src, dst := net.NetworkFlow().Endpoints()
|
||||||
|
if src == dst {
|
||||||
|
fmt.Println("Fishy packet has same network source and dst: %s", src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Find all packets coming from UDP port 1000 to UDP port 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!")
|
||||||
|
}
|
||||||
|
|
||||||
|
For load-balancing purposes, both Flow and Endpoint have FastHash() functions,
|
||||||
|
which provide quick, non-cryptographic hashes of their contents. Of particular
|
||||||
|
importance is the fact that Flow FastHash() is symmetric: A->B will have the same
|
||||||
|
hash as B->A. An example usage could be:
|
||||||
|
|
||||||
|
channels := [8]chan gopacket.Packet
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
channels[i] = make(chan gopacket.Packet)
|
||||||
|
go packetHandler(channels[i])
|
||||||
|
}
|
||||||
|
for packet := range getPackets() {
|
||||||
|
if net := packet.NetworkLayer(); net != nil {
|
||||||
|
channels[int(net.NetworkFlow().FastHash()) & 0x7] <- packet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
This allows us to split up a packet stream while still making sure that each
|
||||||
|
stream sees all packets for a flow (and its bidirectional opposite).
|
||||||
|
|
||||||
|
|
||||||
|
Implementing Your Own Decoder
|
||||||
|
|
||||||
|
If your network has some strange encapsulation, you can implement your own
|
||||||
|
decoder. In this example, we handle Ethernet packets which are encapsulated
|
||||||
|
in a 4-byte header.
|
||||||
|
|
||||||
|
// Create a layer type, should be unique and high, so it doesn't conflict,
|
||||||
|
// giving it a name and a decoder to use.
|
||||||
|
var MyLayerType = gopacket.RegisterLayerType(12345, gopacket.LayerTypeMetadata{Name: "MyLayerType", Decoder: gopacket.DecodeFunc(decodeMyLayer)})
|
||||||
|
|
||||||
|
// Implement my layer
|
||||||
|
type MyLayer struct {
|
||||||
|
StrangeHeader []byte
|
||||||
|
payload []byte
|
||||||
|
}
|
||||||
|
func (m MyLayer) LayerType() gopacket.LayerType { return MyLayerType }
|
||||||
|
func (m MyLayer) LayerContents() []byte { return m.StrangeHeader }
|
||||||
|
func (m MyLayer) LayerPayload() []byte { return m.payload }
|
||||||
|
|
||||||
|
// Now implement a decoder... this one strips off the first 4 bytes of the
|
||||||
|
// packet.
|
||||||
|
func decodeMyLayer(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
// Create my layer
|
||||||
|
p.AddLayer(&MyLayer{data[:4], data[4:]})
|
||||||
|
// Determine how to handle the rest of the packet
|
||||||
|
return p.NextDecoder(layers.LayerTypeEthernet)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, decode your packets:
|
||||||
|
p := gopacket.NewPacket(data, MyLayerType, gopacket.Lazy)
|
||||||
|
|
||||||
|
See the docs for Decoder and PacketBuilder for more details on how coding
|
||||||
|
decoders works, or look at RegisterLayerType and RegisterEndpointType to see how
|
||||||
|
to add layer/endpoint types to gopacket.
|
||||||
|
|
||||||
|
|
||||||
|
Fast Decoding With DecodingLayerParser
|
||||||
|
|
||||||
|
TLDR: DecodingLayerParser takes about 10% of the time as NewPacket to decode
|
||||||
|
packet data, but only for known packet stacks.
|
||||||
|
|
||||||
|
Basic decoding using gopacket.NewPacket or PacketSource.Packets is somewhat slow
|
||||||
|
due to its need to allocate a new packet and every respective layer. It's very
|
||||||
|
versatile and can handle all known layer types, but sometimes you really only
|
||||||
|
care about a specific set of layers regardless, so that versatility is wasted.
|
||||||
|
|
||||||
|
DecodingLayerParser avoids memory allocation altogether by decoding packet
|
||||||
|
layers directly into preallocated objects, which you can then reference to get
|
||||||
|
the packet's information. A quick example:
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var eth layers.Ethernet
|
||||||
|
var ip4 layers.IPv4
|
||||||
|
var ip6 layers.IPv6
|
||||||
|
var tcp layers.TCP
|
||||||
|
parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &ip4, &ip6, &tcp)
|
||||||
|
decoded := []gopacket.LayerType{}
|
||||||
|
for packetData := range somehowGetPacketData() {
|
||||||
|
if err := parser.DecodeLayers(packetData, &decoded); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Could not decode layers: %v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, layerType := range decoded {
|
||||||
|
switch layerType {
|
||||||
|
case layers.LayerTypeIPv6:
|
||||||
|
fmt.Println(" IP6 ", ip6.SrcIP, ip6.DstIP)
|
||||||
|
case layers.LayerTypeIPv4:
|
||||||
|
fmt.Println(" IP4 ", ip4.SrcIP, ip4.DstIP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The important thing to note here is that the parser is modifying the passed in
|
||||||
|
layers (eth, ip4, ip6, tcp) instead of allocating new ones, thus greatly
|
||||||
|
speeding up the decoding process. It's even branching based on layer type...
|
||||||
|
it'll handle an (eth, ip4, tcp) or (eth, ip6, tcp) stack. However, it won't
|
||||||
|
handle any other type... since no other decoders were passed in, an (eth, ip4,
|
||||||
|
udp) stack will stop decoding after ip4, and only pass back [LayerTypeEthernet,
|
||||||
|
LayerTypeIPv4] through the 'decoded' slice (along with an error saying it can't
|
||||||
|
decode a UDP packet).
|
||||||
|
|
||||||
|
Unfortunately, not all layers can be used by DecodingLayerParser... only those
|
||||||
|
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
|
||||||
|
|
||||||
|
As well as offering the ability to decode packet data, gopacket will allow you
|
||||||
|
to create packets from scratch, as well. A number of gopacket layers implement
|
||||||
|
the SerializableLayer interface; these layers can be serialized to a []byte in
|
||||||
|
the following manner:
|
||||||
|
|
||||||
|
ip := &layers.IPv4{
|
||||||
|
SrcIP: net.IP{1, 2, 3, 4},
|
||||||
|
DstIP: net.IP{5, 6, 7, 8},
|
||||||
|
// etc...
|
||||||
|
}
|
||||||
|
buf := gopacket.NewSerializeBuffer()
|
||||||
|
opts := gopacket.SerializeOptions{} // See SerializeOptions for more details.
|
||||||
|
err := ip.SerializeTo(buf, opts)
|
||||||
|
if err != nil { panic(err) }
|
||||||
|
fmt.Println(buf.Bytes()) // prints out a byte slice containing the serialized IPv4 layer.
|
||||||
|
|
||||||
|
SerializeTo PREPENDS the given layer onto the SerializeBuffer, and they treat
|
||||||
|
the current buffer's Bytes() slice as the payload of the serializing layer.
|
||||||
|
Therefore, you can serialize an entire packet by serializing a set of layers in
|
||||||
|
reverse order (Payload, then TCP, then IP, then Ethernet, for example). The
|
||||||
|
SerializeBuffer's SerializeLayers function is a helper that does exactly that.
|
||||||
|
|
||||||
|
To generate a (empty and useless, because no fields are set)
|
||||||
|
Ethernet(IPv4(TCP(Payload))) packet, for example, you can run:
|
||||||
|
|
||||||
|
buf := gopacket.NewSerializeBuffer()
|
||||||
|
opts := gopacket.SerializeOptions{}
|
||||||
|
gopacket.SerializeLayers(buf, opts,
|
||||||
|
&layers.Ethernet{},
|
||||||
|
&layers.IPv4{},
|
||||||
|
&layers.TCP{},
|
||||||
|
gopacket.Payload([]byte{1, 2, 3, 4}))
|
||||||
|
packetData := buf.Bytes()
|
||||||
|
|
||||||
|
A Final Note
|
||||||
|
|
||||||
|
If you use gopacket, you'll almost definitely want to make sure gopacket/layers
|
||||||
|
is imported, since when imported it sets all the LayerType variables and fills
|
||||||
|
in a lot of interesting variables/maps (DecodersByLayerName, etc). Therefore,
|
||||||
|
it's recommended that even if you don't use any layers functions directly, you still import with:
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/google/gopacket/layers"
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
package gopacket
|
236
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/flows.go
generated
vendored
Normal file
236
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/flows.go
generated
vendored
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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 gopacket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MaxEndpointSize determines the maximum size in bytes of an endpoint address.
|
||||||
|
//
|
||||||
|
// Endpoints/Flows have a problem: They need to be hashable. Therefore, they
|
||||||
|
// can't use a byte slice. The two obvious choices are to use a string or a
|
||||||
|
// byte array. Strings work great, but string creation requires memory
|
||||||
|
// allocation, which can be slow. Arrays work great, but have a fixed size. We
|
||||||
|
// originally used the former, now we've switched to the latter. Use of a fixed
|
||||||
|
// byte-array doubles the speed of constructing a flow (due to not needing to
|
||||||
|
// allocate). This is a huge increase... too much for us to pass up.
|
||||||
|
//
|
||||||
|
// The end result of this, though, is that an endpoint/flow can't be created
|
||||||
|
// using more than MaxEndpointSize bytes per address.
|
||||||
|
const MaxEndpointSize = 16
|
||||||
|
|
||||||
|
// Endpoint is the set of bytes used to address packets at various layers.
|
||||||
|
// See LinkLayer, NetworkLayer, and TransportLayer specifications.
|
||||||
|
// Endpoints are usable as map keys.
|
||||||
|
type Endpoint struct {
|
||||||
|
typ EndpointType
|
||||||
|
len int
|
||||||
|
raw [MaxEndpointSize]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// EndpointType returns the endpoint type associated with this endpoint.
|
||||||
|
func (a Endpoint) EndpointType() EndpointType { return a.typ }
|
||||||
|
|
||||||
|
// Raw returns the raw bytes of this endpoint. These aren't human-readable
|
||||||
|
// most of the time, but they are faster than calling String.
|
||||||
|
func (a Endpoint) Raw() []byte { return a.raw[:a.len] }
|
||||||
|
|
||||||
|
// LessThan provides a stable ordering for all endpoints. It sorts first based
|
||||||
|
// on the EndpointType of an endpoint, then based on the raw bytes of that
|
||||||
|
// endpoint.
|
||||||
|
//
|
||||||
|
// For some endpoints, the actual comparison may not make sense, however this
|
||||||
|
// ordering does provide useful information for most Endpoint types.
|
||||||
|
// Ordering is based first on endpoint type, then on raw endpoint bytes.
|
||||||
|
// Endpoint bytes are sorted lexicographically.
|
||||||
|
func (a Endpoint) LessThan(b Endpoint) bool {
|
||||||
|
return a.typ < b.typ || (a.typ == b.typ && bytes.Compare(a.raw[:a.len], b.raw[:b.len]) < 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fnvHash is used by our FastHash functions, and implements the FNV hash
|
||||||
|
// created by Glenn Fowler, Landon Curt Noll, and Phong Vo.
|
||||||
|
// See http://isthe.com/chongo/tech/comp/fnv/.
|
||||||
|
func fnvHash(s []byte) (h uint64) {
|
||||||
|
h = fnvBasis
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
h ^= uint64(s[i])
|
||||||
|
h *= fnvPrime
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnvBasis = 14695981039346656037
|
||||||
|
const fnvPrime = 1099511628211
|
||||||
|
|
||||||
|
// FastHash provides a quick hashing function for an endpoint, useful if you'd
|
||||||
|
// like to split up endpoints by modulos or other load-balancing techniques.
|
||||||
|
// It uses a variant of Fowler-Noll-Vo hashing.
|
||||||
|
//
|
||||||
|
// The output of FastHash is not guaranteed to remain the same through future
|
||||||
|
// code revisions, so should not be used to key values in persistent storage.
|
||||||
|
func (a Endpoint) FastHash() (h uint64) {
|
||||||
|
h = fnvHash(a.raw[:a.len])
|
||||||
|
h ^= uint64(a.typ)
|
||||||
|
h *= fnvPrime
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEndpoint creates a new Endpoint object.
|
||||||
|
//
|
||||||
|
// The size of raw must be less than MaxEndpointSize, otherwise this function
|
||||||
|
// will panic.
|
||||||
|
func NewEndpoint(typ EndpointType, raw []byte) (e Endpoint) {
|
||||||
|
e.len = len(raw)
|
||||||
|
if e.len > MaxEndpointSize {
|
||||||
|
panic("raw byte length greater than MaxEndpointSize")
|
||||||
|
}
|
||||||
|
e.typ = typ
|
||||||
|
copy(e.raw[:], raw)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// EndpointTypeMetadata is used to register a new endpoint type.
|
||||||
|
type EndpointTypeMetadata struct {
|
||||||
|
// Name is the string returned by an EndpointType's String function.
|
||||||
|
Name string
|
||||||
|
// Formatter is called from an Endpoint's String function to format the raw
|
||||||
|
// bytes in an Endpoint into a human-readable string.
|
||||||
|
Formatter func([]byte) string
|
||||||
|
}
|
||||||
|
|
||||||
|
// EndpointType is the type of a gopacket Endpoint. This type determines how
|
||||||
|
// the bytes stored in the endpoint should be interpreted.
|
||||||
|
type EndpointType int64
|
||||||
|
|
||||||
|
var endpointTypes = map[EndpointType]EndpointTypeMetadata{}
|
||||||
|
|
||||||
|
// RegisterEndpointType creates a new EndpointType and registers it globally.
|
||||||
|
// It MUST be passed a unique number, or it will panic. Numbers 0-999 are
|
||||||
|
// reserved for gopacket's use.
|
||||||
|
func RegisterEndpointType(num int, meta EndpointTypeMetadata) EndpointType {
|
||||||
|
t := EndpointType(num)
|
||||||
|
if _, ok := endpointTypes[t]; ok {
|
||||||
|
panic("Endpoint type number already in use")
|
||||||
|
}
|
||||||
|
endpointTypes[t] = meta
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e EndpointType) String() string {
|
||||||
|
if t, ok := endpointTypes[e]; ok {
|
||||||
|
return t.Name
|
||||||
|
}
|
||||||
|
return strconv.Itoa(int(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Endpoint) String() string {
|
||||||
|
if t, ok := endpointTypes[a.typ]; ok && t.Formatter != nil {
|
||||||
|
return t.Formatter(a.raw[:a.len])
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v:%v", a.typ, a.raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flow represents the direction of traffic for a packet layer, as a source and destination Endpoint.
|
||||||
|
// Flows are usable as map keys.
|
||||||
|
type Flow struct {
|
||||||
|
typ EndpointType
|
||||||
|
slen, dlen int
|
||||||
|
src, dst [MaxEndpointSize]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlowFromEndpoints creates a new flow by pasting together two endpoints.
|
||||||
|
// The endpoints must have the same EndpointType, or this function will return
|
||||||
|
// an error.
|
||||||
|
func FlowFromEndpoints(src, dst Endpoint) (_ Flow, err error) {
|
||||||
|
if src.typ != dst.typ {
|
||||||
|
err = fmt.Errorf("Mismatched endpoint types: %v->%v", src.typ, dst.typ)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return Flow{src.typ, src.len, dst.len, src.raw, dst.raw}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FastHash provides a quick hashing function for a flow, useful if you'd
|
||||||
|
// like to split up flows by modulos or other load-balancing techniques.
|
||||||
|
// It uses a variant of Fowler-Noll-Vo hashing, and is guaranteed to collide
|
||||||
|
// with its reverse flow. IE: the flow A->B will have the same hash as the flow
|
||||||
|
// B->A.
|
||||||
|
//
|
||||||
|
// The output of FastHash is not guaranteed to remain the same through future
|
||||||
|
// code revisions, so should not be used to key values in persistent storage.
|
||||||
|
func (f Flow) FastHash() (h uint64) {
|
||||||
|
// This combination must be commutative. We don't use ^, since that would
|
||||||
|
// give the same hash for all A->A flows.
|
||||||
|
h = fnvHash(f.src[:f.slen]) + fnvHash(f.dst[:f.dlen])
|
||||||
|
h ^= uint64(f.typ)
|
||||||
|
h *= fnvPrime
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a human-readable representation of this flow, in the form
|
||||||
|
// "Src->Dst"
|
||||||
|
func (f Flow) String() string {
|
||||||
|
s, d := f.Endpoints()
|
||||||
|
return fmt.Sprintf("%v->%v", s, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EndpointType returns the EndpointType for this Flow.
|
||||||
|
func (f Flow) EndpointType() EndpointType {
|
||||||
|
return f.typ
|
||||||
|
}
|
||||||
|
|
||||||
|
// Endpoints returns the two Endpoints for this flow.
|
||||||
|
func (f Flow) Endpoints() (src, dst Endpoint) {
|
||||||
|
return Endpoint{f.typ, f.slen, f.src}, Endpoint{f.typ, f.dlen, f.dst}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Src returns the source Endpoint for this flow.
|
||||||
|
func (f Flow) Src() (src Endpoint) {
|
||||||
|
src, _ = f.Endpoints()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dst returns the destination Endpoint for this flow.
|
||||||
|
func (f Flow) Dst() (dst Endpoint) {
|
||||||
|
_, dst = f.Endpoints()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse returns a new flow with endpoints reversed.
|
||||||
|
func (f Flow) Reverse() Flow {
|
||||||
|
return Flow{f.typ, f.dlen, f.slen, f.dst, f.src}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFlow creates a new flow.
|
||||||
|
//
|
||||||
|
// src and dst must have length <= MaxEndpointSize, otherwise NewFlow will
|
||||||
|
// panic.
|
||||||
|
func NewFlow(t EndpointType, src, dst []byte) (f Flow) {
|
||||||
|
f.slen = len(src)
|
||||||
|
f.dlen = len(dst)
|
||||||
|
if f.slen > MaxEndpointSize || f.dlen > MaxEndpointSize {
|
||||||
|
panic("flow raw byte length greater than MaxEndpointSize")
|
||||||
|
}
|
||||||
|
f.typ = t
|
||||||
|
copy(f.src[:], src)
|
||||||
|
copy(f.dst[:], dst)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// EndpointInvalid is an endpoint type used for invalid endpoints, IE endpoints
|
||||||
|
// that are specified incorrectly during creation.
|
||||||
|
var EndpointInvalid = RegisterEndpointType(0, EndpointTypeMetadata{Name: "invalid", Formatter: func(b []byte) string {
|
||||||
|
return fmt.Sprintf("%v", b)
|
||||||
|
}})
|
||||||
|
|
||||||
|
// InvalidEndpoint is a singleton Endpoint of type EndpointInvalid.
|
||||||
|
var InvalidEndpoint = NewEndpoint(EndpointInvalid, nil)
|
||||||
|
|
||||||
|
// InvalidFlow is a singleton Flow of type EndpointInvalid.
|
||||||
|
var InvalidFlow = NewFlow(EndpointInvalid, nil, nil)
|
288
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/gc
generated
vendored
Normal file
288
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/gc
generated
vendored
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
|
||||||
|
# This script provides a simple way to run benchmarks against previous code and
|
||||||
|
# keep a log of how benchmarks change over time. When used with the --benchmark
|
||||||
|
# flag, it runs benchmarks from the current code and from the last commit run
|
||||||
|
# with --benchmark, then stores the results in the git commit description. We
|
||||||
|
# rerun the old benchmarks along with the new ones, since there's no guarantee
|
||||||
|
# that git commits will happen on the same machine, so machine differences could
|
||||||
|
# cause wildly inaccurate results.
|
||||||
|
#
|
||||||
|
# If you're making changes to 'gopacket' which could cause performance changes,
|
||||||
|
# you may be requested to use this commit script to make sure your changes don't
|
||||||
|
# have large detrimental effects (or to show off how awesome your performance
|
||||||
|
# improvements are).
|
||||||
|
#
|
||||||
|
# If not run with the --benchmark flag, this script is still very useful... it
|
||||||
|
# makes sure all the correct go formatting, building, and testing work as
|
||||||
|
# expected.
|
||||||
|
|
||||||
|
function Usage {
|
||||||
|
cat <<EOF
|
||||||
|
USAGE: $0 [--benchmark regexp] [--root] [--gen] <git commit flags...>
|
||||||
|
|
||||||
|
--benchmark: Run benchmark comparisons against last benchmark'd commit
|
||||||
|
--root: Run tests that require root priviledges
|
||||||
|
--gen: Generate code for MACs/ports by pulling down external data
|
||||||
|
|
||||||
|
Note, some 'git commit' flags are necessary, if all else fails, pass in -a
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCH=""
|
||||||
|
GEN=""
|
||||||
|
ROOT=""
|
||||||
|
while [ ! -z "$1" ]; do
|
||||||
|
case "$1" in
|
||||||
|
"--benchmark")
|
||||||
|
BENCH="$2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"--gen")
|
||||||
|
GEN="yes"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"--root")
|
||||||
|
ROOT="yes"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"--help")
|
||||||
|
Usage
|
||||||
|
;;
|
||||||
|
"-h")
|
||||||
|
Usage
|
||||||
|
;;
|
||||||
|
"help")
|
||||||
|
Usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
function Root {
|
||||||
|
if [ ! -z "$ROOT" ]; then
|
||||||
|
local exec="$1"
|
||||||
|
# Some folks (like me) keep source code in places inaccessible by root (like
|
||||||
|
# NFS), so to make sure things run smoothly we copy them to a /tmp location.
|
||||||
|
local tmpfile="$(mktemp -t gopacket_XXXXXXXX)"
|
||||||
|
echo "Running root test executable $exec as $tmpfile"
|
||||||
|
cp "$exec" "$tmpfile"
|
||||||
|
chmod a+x "$tmpfile"
|
||||||
|
shift
|
||||||
|
sudo "$tmpfile" "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$#" -eq "0" ]; then
|
||||||
|
Usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $(dirname $0)
|
||||||
|
|
||||||
|
# Check for copyright notices.
|
||||||
|
for filename in $(find ./ -type f -name '*.go'); do
|
||||||
|
if ! head -n 1 "$filename" | grep -q Copyright; then
|
||||||
|
echo "File '$filename' may not have copyright notice"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [ ! -z "$ROOT" ]; then
|
||||||
|
echo "Running SUDO to get root priviledges for root tests"
|
||||||
|
sudo echo "have root"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z "$GEN" ]; then
|
||||||
|
pushd macs
|
||||||
|
go run gen.go | gofmt > valid_mac_prefixes.go
|
||||||
|
popd
|
||||||
|
pushd layers
|
||||||
|
go run gen.go | gofmt > iana_ports.go
|
||||||
|
go run gen2.go | gofmt > enums_generated.go
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure everything is formatted, compiles, and tests pass.
|
||||||
|
go fmt ./...
|
||||||
|
go test -i ./... 2>/dev/null >/dev/null || true
|
||||||
|
go test
|
||||||
|
go build
|
||||||
|
pushd examples/bytediff
|
||||||
|
go build
|
||||||
|
popd
|
||||||
|
if [ -f /usr/include/pcap.h ]; then
|
||||||
|
pushd pcap
|
||||||
|
go test ./...
|
||||||
|
go build ./...
|
||||||
|
go build pcap_tester.go
|
||||||
|
Root pcap_tester --mode=basic
|
||||||
|
Root pcap_tester --mode=filtered
|
||||||
|
Root pcap_tester --mode=timestamp || echo "You might not support timestamp sources"
|
||||||
|
popd
|
||||||
|
pushd examples/afpacket
|
||||||
|
go build
|
||||||
|
popd
|
||||||
|
pushd examples/pcapdump
|
||||||
|
go build
|
||||||
|
popd
|
||||||
|
pushd examples/arpscan
|
||||||
|
go build
|
||||||
|
popd
|
||||||
|
pushd examples/bidirectional
|
||||||
|
go build
|
||||||
|
popd
|
||||||
|
pushd examples/synscan
|
||||||
|
go build
|
||||||
|
popd
|
||||||
|
pushd examples/httpassembly
|
||||||
|
go build
|
||||||
|
popd
|
||||||
|
pushd examples/statsassembly
|
||||||
|
go build
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
pushd macs
|
||||||
|
go test ./...
|
||||||
|
gofmt -w gen.go
|
||||||
|
go build gen.go
|
||||||
|
popd
|
||||||
|
pushd tcpassembly
|
||||||
|
go test ./...
|
||||||
|
popd
|
||||||
|
pushd reassembly
|
||||||
|
go test ./...
|
||||||
|
popd
|
||||||
|
pushd layers
|
||||||
|
gofmt -w gen.go
|
||||||
|
go build gen.go
|
||||||
|
go test ./...
|
||||||
|
popd
|
||||||
|
pushd pcapgo
|
||||||
|
go test ./...
|
||||||
|
go build ./...
|
||||||
|
popd
|
||||||
|
if [ -f /usr/include/linux/if_packet.h ]; then
|
||||||
|
if grep -q TPACKET_V3 /usr/include/linux/if_packet.h; then
|
||||||
|
pushd afpacket
|
||||||
|
go build ./...
|
||||||
|
go test ./...
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -f /usr/include/pfring.h ]; then
|
||||||
|
pushd pfring
|
||||||
|
go test ./...
|
||||||
|
go build ./...
|
||||||
|
popd
|
||||||
|
pushd examples/pfdump
|
||||||
|
go build
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
pushd ip4defrag
|
||||||
|
go test ./...
|
||||||
|
popd
|
||||||
|
pushd defrag
|
||||||
|
go test ./...
|
||||||
|
popd
|
||||||
|
|
||||||
|
for travis_script in `ls .travis.*.sh`; do
|
||||||
|
./$travis_script
|
||||||
|
done
|
||||||
|
|
||||||
|
# Run our initial commit
|
||||||
|
git commit "$@"
|
||||||
|
|
||||||
|
if [ -z "$BENCH" ]; then
|
||||||
|
set +x
|
||||||
|
echo "We're not benchmarking and we've committed... we're done!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
### If we get here, we want to run benchmarks from current commit, and compare
|
||||||
|
### then to benchmarks from the last --benchmark commit.
|
||||||
|
|
||||||
|
# Get our current branch.
|
||||||
|
BRANCH="$(git branch | grep '^*' | awk '{print $2}')"
|
||||||
|
|
||||||
|
# File we're going to build our commit description in.
|
||||||
|
COMMIT_FILE="$(mktemp /tmp/tmp.XXXXXXXX)"
|
||||||
|
|
||||||
|
# Add the word "BENCH" to the start of the git commit.
|
||||||
|
echo -n "BENCH " > $COMMIT_FILE
|
||||||
|
|
||||||
|
# Get the current description... there must be an easier way.
|
||||||
|
git log -n 1 | grep '^ ' | sed 's/^ //' >> $COMMIT_FILE
|
||||||
|
|
||||||
|
# Get the commit sha for the last benchmark commit
|
||||||
|
PREV=$(git log -n 1 --grep='BENCHMARK_MARKER_DO_NOT_CHANGE' | head -n 1 | awk '{print $2}')
|
||||||
|
|
||||||
|
## Run current benchmarks
|
||||||
|
|
||||||
|
cat >> $COMMIT_FILE <<EOF
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------
|
||||||
|
BENCHMARK_MARKER_DO_NOT_CHANGE
|
||||||
|
----------------------------------------------------------
|
||||||
|
|
||||||
|
Go version $(go version)
|
||||||
|
|
||||||
|
|
||||||
|
TEST BENCHMARKS "$BENCH"
|
||||||
|
EOF
|
||||||
|
# go seems to have trouble with 'go test --bench=. ./...'
|
||||||
|
go test --test.bench="$BENCH" 2>&1 | tee -a $COMMIT_FILE
|
||||||
|
pushd layers
|
||||||
|
go test --test.bench="$BENCH" 2>&1 | tee -a $COMMIT_FILE
|
||||||
|
popd
|
||||||
|
cat >> $COMMIT_FILE <<EOF
|
||||||
|
|
||||||
|
|
||||||
|
PCAP BENCHMARK
|
||||||
|
EOF
|
||||||
|
if [ "$BENCH" -eq ".*" ]; then
|
||||||
|
go run pcap/gopacket_benchmark/*.go 2>&1 | tee -a $COMMIT_FILE
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Reset to last benchmark commit, run benchmarks
|
||||||
|
|
||||||
|
git checkout $PREV
|
||||||
|
|
||||||
|
cat >> $COMMIT_FILE <<EOF
|
||||||
|
----------------------------------------------------------
|
||||||
|
BENCHMARKING AGAINST COMMIT $PREV
|
||||||
|
----------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
OLD TEST BENCHMARKS
|
||||||
|
EOF
|
||||||
|
# go seems to have trouble with 'go test --bench=. ./...'
|
||||||
|
go test --test.bench="$BENCH" 2>&1 | tee -a $COMMIT_FILE
|
||||||
|
pushd layers
|
||||||
|
go test --test.bench="$BENCH" 2>&1 | tee -a $COMMIT_FILE
|
||||||
|
popd
|
||||||
|
cat >> $COMMIT_FILE <<EOF
|
||||||
|
|
||||||
|
|
||||||
|
OLD PCAP BENCHMARK
|
||||||
|
EOF
|
||||||
|
if [ "$BENCH" -eq ".*" ]; then
|
||||||
|
go run pcap/gopacket_benchmark/*.go 2>&1 | tee -a $COMMIT_FILE
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Reset back to the most recent commit, edit the commit message by appending
|
||||||
|
## benchmark results.
|
||||||
|
git checkout $BRANCH
|
||||||
|
git commit --amend -F $COMMIT_FILE
|
107
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layerclass.go
generated
vendored
Normal file
107
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layerclass.go
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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 gopacket
|
||||||
|
|
||||||
|
// LayerClass is a set of LayerTypes, used for grabbing one of a number of
|
||||||
|
// different types from a packet.
|
||||||
|
type LayerClass interface {
|
||||||
|
// Contains returns true if the given layer type should be considered part
|
||||||
|
// of this layer class.
|
||||||
|
Contains(LayerType) bool
|
||||||
|
// LayerTypes returns the set of all layer types in this layer class.
|
||||||
|
// Note that this may not be a fast operation on all LayerClass
|
||||||
|
// implementations.
|
||||||
|
LayerTypes() []LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains implements LayerClass.
|
||||||
|
func (l LayerType) Contains(a LayerType) bool {
|
||||||
|
return l == a
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerTypes implements LayerClass.
|
||||||
|
func (l LayerType) LayerTypes() []LayerType {
|
||||||
|
return []LayerType{l}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerClassSlice implements a LayerClass with a slice.
|
||||||
|
type LayerClassSlice []bool
|
||||||
|
|
||||||
|
// Contains returns true if the given layer type should be considered part
|
||||||
|
// of this layer class.
|
||||||
|
func (s LayerClassSlice) Contains(t LayerType) bool {
|
||||||
|
return int(t) < len(s) && s[t]
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerTypes returns all layer types in this LayerClassSlice.
|
||||||
|
// Because of LayerClassSlice's implementation, this could be quite slow.
|
||||||
|
func (s LayerClassSlice) LayerTypes() (all []LayerType) {
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if s[i] {
|
||||||
|
all = append(all, LayerType(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLayerClassSlice creates a new LayerClassSlice by creating a slice of
|
||||||
|
// size max(types) and setting slice[t] to true for each type t. Note, if
|
||||||
|
// you implement your own LayerType and give it a high value, this WILL create
|
||||||
|
// a very large slice.
|
||||||
|
func NewLayerClassSlice(types []LayerType) LayerClassSlice {
|
||||||
|
var max LayerType
|
||||||
|
for _, typ := range types {
|
||||||
|
if typ > max {
|
||||||
|
max = typ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t := make([]bool, int(max+1))
|
||||||
|
for _, typ := range types {
|
||||||
|
t[typ] = true
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerClassMap implements a LayerClass with a map.
|
||||||
|
type LayerClassMap map[LayerType]bool
|
||||||
|
|
||||||
|
// Contains returns true if the given layer type should be considered part
|
||||||
|
// of this layer class.
|
||||||
|
func (m LayerClassMap) Contains(t LayerType) bool {
|
||||||
|
return m[t]
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerTypes returns all layer types in this LayerClassMap.
|
||||||
|
func (m LayerClassMap) LayerTypes() (all []LayerType) {
|
||||||
|
for t := range m {
|
||||||
|
all = append(all, t)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLayerClassMap creates a LayerClassMap and sets map[t] to true for each
|
||||||
|
// type in types.
|
||||||
|
func NewLayerClassMap(types []LayerType) LayerClassMap {
|
||||||
|
m := LayerClassMap{}
|
||||||
|
for _, typ := range types {
|
||||||
|
m[typ] = true
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLayerClass creates a LayerClass, attempting to be smart about which type
|
||||||
|
// it creates based on which types are passed in.
|
||||||
|
func NewLayerClass(types []LayerType) LayerClass {
|
||||||
|
for _, typ := range types {
|
||||||
|
if typ > maxLayerType {
|
||||||
|
// NewLayerClassSlice could create a very large object, so instead create
|
||||||
|
// a map.
|
||||||
|
return NewLayerClassMap(types)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NewLayerClassSlice(types)
|
||||||
|
}
|
39
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/.lint_blacklist
generated
vendored
Normal file
39
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/.lint_blacklist
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
dot11.go
|
||||||
|
eap.go
|
||||||
|
endpoints.go
|
||||||
|
enums_generated.go
|
||||||
|
enums.go
|
||||||
|
ethernet.go
|
||||||
|
geneve.go
|
||||||
|
icmp4.go
|
||||||
|
icmp6.go
|
||||||
|
igmp.go
|
||||||
|
ip4.go
|
||||||
|
ip6.go
|
||||||
|
layertypes.go
|
||||||
|
linux_sll.go
|
||||||
|
llc.go
|
||||||
|
lldp.go
|
||||||
|
mpls.go
|
||||||
|
ndp.go
|
||||||
|
ntp.go
|
||||||
|
ospf.go
|
||||||
|
pflog.go
|
||||||
|
pppoe.go
|
||||||
|
prism.go
|
||||||
|
radiotap.go
|
||||||
|
rudp.go
|
||||||
|
sctp.go
|
||||||
|
sflow.go
|
||||||
|
tcp.go
|
||||||
|
tcpip.go
|
||||||
|
tls.go
|
||||||
|
tls_alert.go
|
||||||
|
tls_appdata.go
|
||||||
|
tls_cipherspec.go
|
||||||
|
tls_hanshake.go
|
||||||
|
tls_test.go
|
||||||
|
udp.go
|
||||||
|
udplite.go
|
||||||
|
usb.go
|
||||||
|
vrrp.go
|
118
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/arp.go
generated
vendored
Normal file
118
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/arp.go
generated
vendored
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Potential values for ARP.Operation.
|
||||||
|
const (
|
||||||
|
ARPRequest = 1
|
||||||
|
ARPReply = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// ARP is a ARP packet header.
|
||||||
|
type ARP struct {
|
||||||
|
BaseLayer
|
||||||
|
AddrType LinkType
|
||||||
|
Protocol EthernetType
|
||||||
|
HwAddressSize uint8
|
||||||
|
ProtAddressSize uint8
|
||||||
|
Operation uint16
|
||||||
|
SourceHwAddress []byte
|
||||||
|
SourceProtAddress []byte
|
||||||
|
DstHwAddress []byte
|
||||||
|
DstProtAddress []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeARP
|
||||||
|
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]
|
||||||
|
|
||||||
|
arp.Contents = data[:arpLength]
|
||||||
|
arp.Payload = data[arpLength:]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (arp *ARP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
size := 8 + len(arp.SourceHwAddress) + len(arp.SourceProtAddress) + len(arp.DstHwAddress) + len(arp.DstProtAddress)
|
||||||
|
bytes, err := b.PrependBytes(size)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if opts.FixLengths {
|
||||||
|
if len(arp.SourceHwAddress) != len(arp.DstHwAddress) {
|
||||||
|
return errors.New("mismatched hardware address sizes")
|
||||||
|
}
|
||||||
|
arp.HwAddressSize = uint8(len(arp.SourceHwAddress))
|
||||||
|
if len(arp.SourceProtAddress) != len(arp.DstProtAddress) {
|
||||||
|
return errors.New("mismatched prot address sizes")
|
||||||
|
}
|
||||||
|
arp.ProtAddressSize = uint8(len(arp.SourceProtAddress))
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes, uint16(arp.AddrType))
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], uint16(arp.Protocol))
|
||||||
|
bytes[4] = arp.HwAddressSize
|
||||||
|
bytes[5] = arp.ProtAddressSize
|
||||||
|
binary.BigEndian.PutUint16(bytes[6:], arp.Operation)
|
||||||
|
start := 8
|
||||||
|
for _, addr := range [][]byte{
|
||||||
|
arp.SourceHwAddress,
|
||||||
|
arp.SourceProtAddress,
|
||||||
|
arp.DstHwAddress,
|
||||||
|
arp.DstProtAddress,
|
||||||
|
} {
|
||||||
|
copy(bytes[start:], addr)
|
||||||
|
start += len(addr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (arp *ARP) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeARP
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (arp *ARP) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeARP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
|
||||||
|
arp := &ARP{}
|
||||||
|
return decodingLayerDecoder(arp, data, p)
|
||||||
|
}
|
166
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/asf.go
generated
vendored
Normal file
166
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/asf.go
generated
vendored
Normal file
|
@ -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
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/asf_presencepong.go
generated
vendored
Normal file
194
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/asf_presencepong.go
generated
vendored
Normal file
|
@ -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)
|
||||||
|
}
|
52
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/base.go
generated
vendored
Normal file
52
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/base.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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 (
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BaseLayer is a convenience struct which implements the LayerData and
|
||||||
|
// LayerPayload functions of the Layer interface.
|
||||||
|
type BaseLayer struct {
|
||||||
|
// Contents is the set of bytes that make up this layer. IE: for an
|
||||||
|
// Ethernet packet, this would be the set of bytes making up the
|
||||||
|
// Ethernet frame.
|
||||||
|
Contents []byte
|
||||||
|
// Payload is the set of bytes contained by (but not part of) this
|
||||||
|
// Layer. Again, to take Ethernet as an example, this would be the
|
||||||
|
// set of bytes encapsulated by the Ethernet protocol.
|
||||||
|
Payload []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerContents returns the bytes of the packet layer.
|
||||||
|
func (b *BaseLayer) LayerContents() []byte { return b.Contents }
|
||||||
|
|
||||||
|
// LayerPayload returns the bytes contained within the packet layer.
|
||||||
|
func (b *BaseLayer) LayerPayload() []byte { return b.Payload }
|
||||||
|
|
||||||
|
type layerDecodingLayer interface {
|
||||||
|
gopacket.Layer
|
||||||
|
DecodeFromBytes([]byte, gopacket.DecodeFeedback) error
|
||||||
|
NextLayerType() gopacket.LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodingLayerDecoder(d layerDecodingLayer, data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
err := d.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(d)
|
||||||
|
next := d.NextLayerType()
|
||||||
|
if next == gopacket.LayerTypeZero {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return p.NextDecoder(next)
|
||||||
|
}
|
||||||
|
|
||||||
|
// hacky way to zero out memory... there must be a better way?
|
||||||
|
var lotsOfZeros [1024]byte
|
481
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/bfd.go
generated
vendored
Normal file
481
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/bfd.go
generated
vendored
Normal file
|
@ -0,0 +1,481 @@
|
||||||
|
// Copyright 2017 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BFD Control Packet Format
|
||||||
|
// -------------------------
|
||||||
|
// The current version of BFD's RFC (RFC 5880) contains the following
|
||||||
|
// diagram for the BFD Control packet format:
|
||||||
|
//
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | My Discriminator |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Your Discriminator |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Desired Min TX Interval |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Required Min RX Interval |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Required Min Echo RX Interval |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
//
|
||||||
|
// An optional Authentication Section MAY be present:
|
||||||
|
//
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Auth Type | Auth Len | Authentication Data... |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Simple Password Authentication Section Format
|
||||||
|
// ---------------------------------------------
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Auth Type | Auth Len | Auth Key ID | Password... |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | ... |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Keyed MD5 and Meticulous Keyed MD5 Authentication Section Format
|
||||||
|
// ----------------------------------------------------------------
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Auth Type | Auth Len | Auth Key ID | Reserved |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Sequence Number |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Auth Key/Digest... |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | ... |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Keyed SHA1 and Meticulous Keyed SHA1 Authentication Section Format
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Auth Type | Auth Len | Auth Key ID | Reserved |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Sequence Number |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Auth Key/Hash... |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | ... |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
//
|
||||||
|
// From https://tools.ietf.org/rfc/rfc5880.txt
|
||||||
|
const bfdMinimumRecordSizeInBytes int = 24
|
||||||
|
|
||||||
|
// BFDVersion represents the version as decoded from the BFD control message
|
||||||
|
type BFDVersion uint8
|
||||||
|
|
||||||
|
// BFDDiagnostic represents diagnostic infomation about a BFD session
|
||||||
|
type BFDDiagnostic uint8
|
||||||
|
|
||||||
|
// constants that define BFDDiagnostic flags
|
||||||
|
const (
|
||||||
|
BFDDiagnosticNone BFDDiagnostic = 0 // No Diagnostic
|
||||||
|
BFDDiagnosticTimeExpired BFDDiagnostic = 1 // Control Detection Time Expired
|
||||||
|
BFDDiagnosticEchoFailed BFDDiagnostic = 2 // Echo Function Failed
|
||||||
|
BFDDiagnosticNeighborSignalDown BFDDiagnostic = 3 // Neighbor Signaled Session Down
|
||||||
|
BFDDiagnosticForwardPlaneReset BFDDiagnostic = 4 // Forwarding Plane Reset
|
||||||
|
BFDDiagnosticPathDown BFDDiagnostic = 5 // Path Down
|
||||||
|
BFDDiagnosticConcatPathDown BFDDiagnostic = 6 // Concatenated Path Down
|
||||||
|
BFDDiagnosticAdminDown BFDDiagnostic = 7 // Administratively Down
|
||||||
|
BFDDiagnosticRevConcatPathDown BFDDiagnostic = 8 // Reverse Concatenated Path Dow
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of BFDDiagnostic
|
||||||
|
func (bd BFDDiagnostic) String() string {
|
||||||
|
switch bd {
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
case BFDDiagnosticNone:
|
||||||
|
return "None"
|
||||||
|
case BFDDiagnosticTimeExpired:
|
||||||
|
return "Control Detection Time Expired"
|
||||||
|
case BFDDiagnosticEchoFailed:
|
||||||
|
return "Echo Function Failed"
|
||||||
|
case BFDDiagnosticNeighborSignalDown:
|
||||||
|
return "Neighbor Signaled Session Down"
|
||||||
|
case BFDDiagnosticForwardPlaneReset:
|
||||||
|
return "Forwarding Plane Reset"
|
||||||
|
case BFDDiagnosticPathDown:
|
||||||
|
return "Path Down"
|
||||||
|
case BFDDiagnosticConcatPathDown:
|
||||||
|
return "Concatenated Path Down"
|
||||||
|
case BFDDiagnosticAdminDown:
|
||||||
|
return "Administratively Down"
|
||||||
|
case BFDDiagnosticRevConcatPathDown:
|
||||||
|
return "Reverse Concatenated Path Down"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BFDState represents the state of a BFD session
|
||||||
|
type BFDState uint8
|
||||||
|
|
||||||
|
// constants that define BFDState
|
||||||
|
const (
|
||||||
|
BFDStateAdminDown BFDState = 0
|
||||||
|
BFDStateDown BFDState = 1
|
||||||
|
BFDStateInit BFDState = 2
|
||||||
|
BFDStateUp BFDState = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of BFDState
|
||||||
|
func (s BFDState) String() string {
|
||||||
|
switch s {
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
case BFDStateAdminDown:
|
||||||
|
return "Admin Down"
|
||||||
|
case BFDStateDown:
|
||||||
|
return "Down"
|
||||||
|
case BFDStateInit:
|
||||||
|
return "Init"
|
||||||
|
case BFDStateUp:
|
||||||
|
return "Up"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BFDDetectMultiplier represents the negotiated transmit interval,
|
||||||
|
// multiplied by this value, provides the Detection Time for the
|
||||||
|
// receiving system in Asynchronous mode.
|
||||||
|
type BFDDetectMultiplier uint8
|
||||||
|
|
||||||
|
// BFDDiscriminator is a unique, nonzero discriminator value used
|
||||||
|
// to demultiplex multiple BFD sessions between the same pair of systems.
|
||||||
|
type BFDDiscriminator uint32
|
||||||
|
|
||||||
|
// BFDTimeInterval represents a time interval in microseconds
|
||||||
|
type BFDTimeInterval uint32
|
||||||
|
|
||||||
|
// BFDAuthType represents the authentication used in the BFD session
|
||||||
|
type BFDAuthType uint8
|
||||||
|
|
||||||
|
// constants that define the BFDAuthType
|
||||||
|
const (
|
||||||
|
BFDAuthTypeNone BFDAuthType = 0 // No Auth
|
||||||
|
BFDAuthTypePassword BFDAuthType = 1 // Simple Password
|
||||||
|
BFDAuthTypeKeyedMD5 BFDAuthType = 2 // Keyed MD5
|
||||||
|
BFDAuthTypeMeticulousKeyedMD5 BFDAuthType = 3 // Meticulous Keyed MD5
|
||||||
|
BFDAuthTypeKeyedSHA1 BFDAuthType = 4 // Keyed SHA1
|
||||||
|
BFDAuthTypeMeticulousKeyedSHA1 BFDAuthType = 5 // Meticulous Keyed SHA1
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of BFDAuthType
|
||||||
|
func (at BFDAuthType) String() string {
|
||||||
|
switch at {
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
case BFDAuthTypeNone:
|
||||||
|
return "No Authentication"
|
||||||
|
case BFDAuthTypePassword:
|
||||||
|
return "Simple Password"
|
||||||
|
case BFDAuthTypeKeyedMD5:
|
||||||
|
return "Keyed MD5"
|
||||||
|
case BFDAuthTypeMeticulousKeyedMD5:
|
||||||
|
return "Meticulous Keyed MD5"
|
||||||
|
case BFDAuthTypeKeyedSHA1:
|
||||||
|
return "Keyed SHA1"
|
||||||
|
case BFDAuthTypeMeticulousKeyedSHA1:
|
||||||
|
return "Meticulous Keyed SHA1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BFDAuthKeyID represents the authentication key ID in use for
|
||||||
|
// this packet. This allows multiple keys to be active simultaneously.
|
||||||
|
type BFDAuthKeyID uint8
|
||||||
|
|
||||||
|
// BFDAuthSequenceNumber represents the sequence number for this packet.
|
||||||
|
// For Keyed Authentication, this value is incremented occasionally. For
|
||||||
|
// Meticulous Keyed Authentication, this value is incremented for each
|
||||||
|
// successive packet transmitted for a session. This provides protection
|
||||||
|
// against replay attacks.
|
||||||
|
type BFDAuthSequenceNumber uint32
|
||||||
|
|
||||||
|
// BFDAuthData represents the authentication key or digest
|
||||||
|
type BFDAuthData []byte
|
||||||
|
|
||||||
|
// BFDAuthHeader represents authentication data used in the BFD session
|
||||||
|
type BFDAuthHeader struct {
|
||||||
|
AuthType BFDAuthType
|
||||||
|
KeyID BFDAuthKeyID
|
||||||
|
SequenceNumber BFDAuthSequenceNumber
|
||||||
|
Data BFDAuthData
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length returns the data length of the BFDAuthHeader based on the
|
||||||
|
// authentication type
|
||||||
|
func (h *BFDAuthHeader) Length() int {
|
||||||
|
switch h.AuthType {
|
||||||
|
case BFDAuthTypePassword:
|
||||||
|
return 3 + len(h.Data)
|
||||||
|
case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:
|
||||||
|
return 8 + len(h.Data)
|
||||||
|
case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:
|
||||||
|
return 8 + len(h.Data)
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BFD represents a BFD control message packet whose payload contains
|
||||||
|
// the control information required to for a BFD session.
|
||||||
|
//
|
||||||
|
// References
|
||||||
|
// ----------
|
||||||
|
//
|
||||||
|
// Wikipedia's BFD entry:
|
||||||
|
// https://en.wikipedia.org/wiki/Bidirectional_Forwarding_Detection
|
||||||
|
// This is the best place to get an overview of BFD.
|
||||||
|
//
|
||||||
|
// RFC 5880 "Bidirectional Forwarding Detection (BFD)" (2010)
|
||||||
|
// https://tools.ietf.org/html/rfc5880
|
||||||
|
// This is the original BFD specification.
|
||||||
|
//
|
||||||
|
// RFC 5881 "Bidirectional Forwarding Detection (BFD) for IPv4 and IPv6 (Single Hop)" (2010)
|
||||||
|
// https://tools.ietf.org/html/rfc5881
|
||||||
|
// Describes the use of the Bidirectional Forwarding Detection (BFD)
|
||||||
|
// protocol over IPv4 and IPv6 for single IP hops.
|
||||||
|
type BFD struct {
|
||||||
|
BaseLayer // Stores the packet bytes and payload bytes.
|
||||||
|
|
||||||
|
Version BFDVersion // Version of the BFD protocol.
|
||||||
|
Diagnostic BFDDiagnostic // Diagnostic code for last state change
|
||||||
|
State BFDState // Current state
|
||||||
|
Poll bool // Requesting verification
|
||||||
|
Final bool // Responding to a received BFD Control packet that had the Poll (P) bit set.
|
||||||
|
ControlPlaneIndependent bool // BFD implementation does not share fate with its control plane
|
||||||
|
AuthPresent bool // Authentication Section is present and the session is to be authenticated
|
||||||
|
Demand bool // Demand mode is active
|
||||||
|
Multipoint bool // For future point-to-multipoint extensions. Must always be zero
|
||||||
|
DetectMultiplier BFDDetectMultiplier // Detection time multiplier
|
||||||
|
MyDiscriminator BFDDiscriminator // A unique, nonzero discriminator value
|
||||||
|
YourDiscriminator BFDDiscriminator // discriminator received from the remote system.
|
||||||
|
DesiredMinTxInterval BFDTimeInterval // Minimum interval, in microseconds, the local system would like to use when transmitting BFD Control packets
|
||||||
|
RequiredMinRxInterval BFDTimeInterval // Minimum interval, in microseconds, between received BFD Control packets that this system is capable of supporting
|
||||||
|
RequiredMinEchoRxInterval BFDTimeInterval // Minimum interval, in microseconds, between received BFD Echo packets that this system is capable of supporting
|
||||||
|
AuthHeader *BFDAuthHeader // Authentication data, variable length.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length returns the data length of a BFD Control message which
|
||||||
|
// changes based on the presence and type of authentication
|
||||||
|
// contained in the message
|
||||||
|
func (d *BFD) Length() int {
|
||||||
|
if d.AuthPresent && (d.AuthHeader != nil) {
|
||||||
|
return bfdMinimumRecordSizeInBytes + d.AuthHeader.Length()
|
||||||
|
}
|
||||||
|
|
||||||
|
return bfdMinimumRecordSizeInBytes
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns the layer type of the BFD object, which is LayerTypeBFD.
|
||||||
|
func (d *BFD) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeBFD
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeBFD analyses a byte slice and attempts to decode it as a BFD
|
||||||
|
// control packet
|
||||||
|
//
|
||||||
|
// If it succeeds, it loads p with information about the packet and returns nil.
|
||||||
|
// If it fails, it returns an error (non nil).
|
||||||
|
//
|
||||||
|
// This function is employed in layertypes.go to register the BFD layer.
|
||||||
|
func decodeBFD(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
|
||||||
|
// Attempt to decode the byte slice.
|
||||||
|
d := &BFD{}
|
||||||
|
err := d.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the decoding worked, add the layer to the packet and set it
|
||||||
|
// as the application layer too, if there isn't already one.
|
||||||
|
p.AddLayer(d)
|
||||||
|
p.SetApplicationLayer(d)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes analyses a byte slice and attempts to decode it as a BFD
|
||||||
|
// control packet.
|
||||||
|
//
|
||||||
|
// Upon succeeds, it loads the BFD object with information about the packet
|
||||||
|
// and returns nil.
|
||||||
|
// Upon failure, it returns an error (non nil).
|
||||||
|
func (d *BFD) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
|
||||||
|
// If the data block is too short to be a BFD record, then return an error.
|
||||||
|
if len(data) < bfdMinimumRecordSizeInBytes {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("BFD packet too short")
|
||||||
|
}
|
||||||
|
|
||||||
|
pLen := uint8(data[3])
|
||||||
|
if len(data) != int(pLen) {
|
||||||
|
return errors.New("BFD packet length does not match")
|
||||||
|
}
|
||||||
|
|
||||||
|
// BFD type embeds type BaseLayer which contains two fields:
|
||||||
|
// Contents is supposed to contain the bytes of the data at this level.
|
||||||
|
// Payload is supposed to contain the payload of this level.
|
||||||
|
// Here we set the baselayer to be the bytes of the BFD record.
|
||||||
|
d.BaseLayer = BaseLayer{Contents: data[:len(data)]}
|
||||||
|
|
||||||
|
// Extract the fields from the block of bytes.
|
||||||
|
// To make sense of this, refer to the packet diagram
|
||||||
|
// above and the section on endian conventions.
|
||||||
|
|
||||||
|
// The first few fields are all packed into the first 32 bits. Unpack them.
|
||||||
|
d.Version = BFDVersion(((data[0] & 0xE0) >> 5))
|
||||||
|
d.Diagnostic = BFDDiagnostic(data[0] & 0x1F)
|
||||||
|
data = data[1:]
|
||||||
|
|
||||||
|
d.State = BFDState((data[0] & 0xC0) >> 6)
|
||||||
|
d.Poll = data[0]&0x20 != 0
|
||||||
|
d.Final = data[0]&0x10 != 0
|
||||||
|
d.ControlPlaneIndependent = data[0]&0x08 != 0
|
||||||
|
d.AuthPresent = data[0]&0x04 != 0
|
||||||
|
d.Demand = data[0]&0x02 != 0
|
||||||
|
d.Multipoint = data[0]&0x01 != 0
|
||||||
|
data = data[1:]
|
||||||
|
|
||||||
|
data, d.DetectMultiplier = data[1:], BFDDetectMultiplier(data[0])
|
||||||
|
data, _ = data[1:], uint8(data[0]) // Consume length
|
||||||
|
|
||||||
|
// The remaining fields can just be copied in big endian order.
|
||||||
|
data, d.MyDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4]))
|
||||||
|
data, d.YourDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4]))
|
||||||
|
data, d.DesiredMinTxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
|
||||||
|
data, d.RequiredMinRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
|
||||||
|
data, d.RequiredMinEchoRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))
|
||||||
|
|
||||||
|
if d.AuthPresent && (len(data) > 2) {
|
||||||
|
d.AuthHeader = &BFDAuthHeader{}
|
||||||
|
data, d.AuthHeader.AuthType = data[1:], BFDAuthType(data[0])
|
||||||
|
data, _ = data[1:], uint8(data[0]) // Consume length
|
||||||
|
data, d.AuthHeader.KeyID = data[1:], BFDAuthKeyID(data[0])
|
||||||
|
|
||||||
|
switch d.AuthHeader.AuthType {
|
||||||
|
case BFDAuthTypePassword:
|
||||||
|
d.AuthHeader.Data = BFDAuthData(data)
|
||||||
|
case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:
|
||||||
|
// Skipped reserved byte
|
||||||
|
data, d.AuthHeader.SequenceNumber = data[5:], BFDAuthSequenceNumber(binary.BigEndian.Uint32(data[1:5]))
|
||||||
|
d.AuthHeader.Data = BFDAuthData(data)
|
||||||
|
case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:
|
||||||
|
// Skipped reserved byte
|
||||||
|
data, d.AuthHeader.SequenceNumber = data[5:], BFDAuthSequenceNumber(binary.BigEndian.Uint32(data[1:5]))
|
||||||
|
d.AuthHeader.Data = BFDAuthData(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (d *BFD) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
data, err := b.PrependBytes(bfdMinimumRecordSizeInBytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pack the first few fields into the first 32 bits.
|
||||||
|
data[0] = byte(byte(d.Version<<5) | byte(d.Diagnostic))
|
||||||
|
h := uint8(0)
|
||||||
|
h |= (uint8(d.State) << 6)
|
||||||
|
h |= (uint8(bool2uint8(d.Poll)) << 5)
|
||||||
|
h |= (uint8(bool2uint8(d.Final)) << 4)
|
||||||
|
h |= (uint8(bool2uint8(d.ControlPlaneIndependent)) << 3)
|
||||||
|
h |= (uint8(bool2uint8(d.AuthPresent)) << 2)
|
||||||
|
h |= (uint8(bool2uint8(d.Demand)) << 1)
|
||||||
|
h |= uint8(bool2uint8(d.Multipoint))
|
||||||
|
data[1] = byte(h)
|
||||||
|
data[2] = byte(d.DetectMultiplier)
|
||||||
|
data[3] = byte(d.Length())
|
||||||
|
|
||||||
|
// The remaining fields can just be copied in big endian order.
|
||||||
|
binary.BigEndian.PutUint32(data[4:], uint32(d.MyDiscriminator))
|
||||||
|
binary.BigEndian.PutUint32(data[8:], uint32(d.YourDiscriminator))
|
||||||
|
binary.BigEndian.PutUint32(data[12:], uint32(d.DesiredMinTxInterval))
|
||||||
|
binary.BigEndian.PutUint32(data[16:], uint32(d.RequiredMinRxInterval))
|
||||||
|
binary.BigEndian.PutUint32(data[20:], uint32(d.RequiredMinEchoRxInterval))
|
||||||
|
|
||||||
|
if d.AuthPresent && (d.AuthHeader != nil) {
|
||||||
|
auth, err := b.AppendBytes(int(d.AuthHeader.Length()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
auth[0] = byte(d.AuthHeader.AuthType)
|
||||||
|
auth[1] = byte(d.AuthHeader.Length())
|
||||||
|
auth[2] = byte(d.AuthHeader.KeyID)
|
||||||
|
|
||||||
|
switch d.AuthHeader.AuthType {
|
||||||
|
case BFDAuthTypePassword:
|
||||||
|
copy(auth[3:], d.AuthHeader.Data)
|
||||||
|
case BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:
|
||||||
|
auth[3] = byte(0)
|
||||||
|
binary.BigEndian.PutUint32(auth[4:], uint32(d.AuthHeader.SequenceNumber))
|
||||||
|
copy(auth[8:], d.AuthHeader.Data)
|
||||||
|
case BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:
|
||||||
|
auth[3] = byte(0)
|
||||||
|
binary.BigEndian.PutUint32(auth[4:], uint32(d.AuthHeader.SequenceNumber))
|
||||||
|
copy(auth[8:], d.AuthHeader.Data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns a set of layers that BFD objects can decode.
|
||||||
|
// As BFD objects can only decide the BFD layer, we can return just that layer.
|
||||||
|
// Apparently a single layer type implements LayerClass.
|
||||||
|
func (d *BFD) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeBFD
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType specifies the next layer that GoPacket should attempt to
|
||||||
|
// analyse after this (BFD) layer. As BFD packets do not contain any payload
|
||||||
|
// bytes, there are no further layers to analyse.
|
||||||
|
func (d *BFD) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payload returns an empty byte slice as BFD packets do not carry a payload
|
||||||
|
func (d *BFD) Payload() []byte {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bool2uint8 converts a bool to uint8
|
||||||
|
func bool2uint8(b bool) uint8 {
|
||||||
|
if b {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
659
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/cdp.go
generated
vendored
Normal file
659
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/cdp.go
generated
vendored
Normal file
|
@ -0,0 +1,659 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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.
|
||||||
|
|
||||||
|
// Enum types courtesy of...
|
||||||
|
// http://search.cpan.org/~mchapman/Net-CDP-0.09/lib/Net/CDP.pm
|
||||||
|
// https://code.google.com/p/ladvd/
|
||||||
|
// http://anonsvn.wireshark.org/viewvc/releases/wireshark-1.8.6/epan/dissectors/packet-cdp.c
|
||||||
|
|
||||||
|
package layers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CDPTLVType is the type of each TLV value in a CiscoDiscovery packet.
|
||||||
|
type CDPTLVType uint16
|
||||||
|
|
||||||
|
// CDPTLVType values.
|
||||||
|
const (
|
||||||
|
CDPTLVDevID CDPTLVType = 0x0001
|
||||||
|
CDPTLVAddress CDPTLVType = 0x0002
|
||||||
|
CDPTLVPortID CDPTLVType = 0x0003
|
||||||
|
CDPTLVCapabilities CDPTLVType = 0x0004
|
||||||
|
CDPTLVVersion CDPTLVType = 0x0005
|
||||||
|
CDPTLVPlatform CDPTLVType = 0x0006
|
||||||
|
CDPTLVIPPrefix CDPTLVType = 0x0007
|
||||||
|
CDPTLVHello CDPTLVType = 0x0008
|
||||||
|
CDPTLVVTPDomain CDPTLVType = 0x0009
|
||||||
|
CDPTLVNativeVLAN CDPTLVType = 0x000a
|
||||||
|
CDPTLVFullDuplex CDPTLVType = 0x000b
|
||||||
|
CDPTLVVLANReply CDPTLVType = 0x000e
|
||||||
|
CDPTLVVLANQuery CDPTLVType = 0x000f
|
||||||
|
CDPTLVPower CDPTLVType = 0x0010
|
||||||
|
CDPTLVMTU CDPTLVType = 0x0011
|
||||||
|
CDPTLVExtendedTrust CDPTLVType = 0x0012
|
||||||
|
CDPTLVUntrustedCOS CDPTLVType = 0x0013
|
||||||
|
CDPTLVSysName CDPTLVType = 0x0014
|
||||||
|
CDPTLVSysOID CDPTLVType = 0x0015
|
||||||
|
CDPTLVMgmtAddresses CDPTLVType = 0x0016
|
||||||
|
CDPTLVLocation CDPTLVType = 0x0017
|
||||||
|
CDPTLVExternalPortID CDPTLVType = 0x0018
|
||||||
|
CDPTLVPowerRequested CDPTLVType = 0x0019
|
||||||
|
CDPTLVPowerAvailable CDPTLVType = 0x001a
|
||||||
|
CDPTLVPortUnidirectional CDPTLVType = 0x001b
|
||||||
|
CDPTLVEnergyWise CDPTLVType = 0x001d
|
||||||
|
CDPTLVSparePairPOE CDPTLVType = 0x001f
|
||||||
|
)
|
||||||
|
|
||||||
|
// CiscoDiscoveryValue is a TLV value inside a CiscoDiscovery packet layer.
|
||||||
|
type CiscoDiscoveryValue struct {
|
||||||
|
Type CDPTLVType
|
||||||
|
Length uint16
|
||||||
|
Value []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// CiscoDiscovery is a packet layer containing the Cisco Discovery Protocol.
|
||||||
|
// See http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm#31885
|
||||||
|
type CiscoDiscovery struct {
|
||||||
|
BaseLayer
|
||||||
|
Version byte
|
||||||
|
TTL byte
|
||||||
|
Checksum uint16
|
||||||
|
Values []CiscoDiscoveryValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDPCapability is the set of capabilities advertised by a CDP device.
|
||||||
|
type CDPCapability uint32
|
||||||
|
|
||||||
|
// CDPCapability values.
|
||||||
|
const (
|
||||||
|
CDPCapMaskRouter CDPCapability = 0x0001
|
||||||
|
CDPCapMaskTBBridge CDPCapability = 0x0002
|
||||||
|
CDPCapMaskSPBridge CDPCapability = 0x0004
|
||||||
|
CDPCapMaskSwitch CDPCapability = 0x0008
|
||||||
|
CDPCapMaskHost CDPCapability = 0x0010
|
||||||
|
CDPCapMaskIGMPFilter CDPCapability = 0x0020
|
||||||
|
CDPCapMaskRepeater CDPCapability = 0x0040
|
||||||
|
CDPCapMaskPhone CDPCapability = 0x0080
|
||||||
|
CDPCapMaskRemote CDPCapability = 0x0100
|
||||||
|
)
|
||||||
|
|
||||||
|
// CDPCapabilities represents the capabilities of a device
|
||||||
|
type CDPCapabilities struct {
|
||||||
|
L3Router bool
|
||||||
|
TBBridge bool
|
||||||
|
SPBridge bool
|
||||||
|
L2Switch bool
|
||||||
|
IsHost bool
|
||||||
|
IGMPFilter bool
|
||||||
|
L1Repeater bool
|
||||||
|
IsPhone bool
|
||||||
|
RemotelyManaged bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDP Power-over-Ethernet values.
|
||||||
|
const (
|
||||||
|
CDPPoEFourWire byte = 0x01
|
||||||
|
CDPPoEPDArch byte = 0x02
|
||||||
|
CDPPoEPDRequest byte = 0x04
|
||||||
|
CDPPoEPSE byte = 0x08
|
||||||
|
)
|
||||||
|
|
||||||
|
// CDPSparePairPoE provides information on PoE.
|
||||||
|
type CDPSparePairPoE struct {
|
||||||
|
PSEFourWire bool // Supported / Not supported
|
||||||
|
PDArchShared bool // Shared / Independent
|
||||||
|
PDRequestOn bool // On / Off
|
||||||
|
PSEOn bool // On / Off
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDPVLANDialogue encapsulates a VLAN Query/Reply
|
||||||
|
type CDPVLANDialogue struct {
|
||||||
|
ID uint8
|
||||||
|
VLAN uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDPPowerDialogue encapsulates a Power Query/Reply
|
||||||
|
type CDPPowerDialogue struct {
|
||||||
|
ID uint16
|
||||||
|
MgmtID uint16
|
||||||
|
Values []uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDPLocation provides location information for a CDP device.
|
||||||
|
type CDPLocation struct {
|
||||||
|
Type uint8 // Undocumented
|
||||||
|
Location string
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDPHello is a Cisco Hello message (undocumented, hence the "Unknown" fields)
|
||||||
|
type CDPHello struct {
|
||||||
|
OUI []byte
|
||||||
|
ProtocolID uint16
|
||||||
|
ClusterMaster net.IP
|
||||||
|
Unknown1 net.IP
|
||||||
|
Version byte
|
||||||
|
SubVersion byte
|
||||||
|
Status byte
|
||||||
|
Unknown2 byte
|
||||||
|
ClusterCommander net.HardwareAddr
|
||||||
|
SwitchMAC net.HardwareAddr
|
||||||
|
Unknown3 byte
|
||||||
|
ManagementVLAN uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDPEnergyWiseSubtype is used within CDP to define TLV values.
|
||||||
|
type CDPEnergyWiseSubtype uint32
|
||||||
|
|
||||||
|
// CDPEnergyWiseSubtype values.
|
||||||
|
const (
|
||||||
|
CDPEnergyWiseRole CDPEnergyWiseSubtype = 0x00000007
|
||||||
|
CDPEnergyWiseDomain CDPEnergyWiseSubtype = 0x00000008
|
||||||
|
CDPEnergyWiseName CDPEnergyWiseSubtype = 0x00000009
|
||||||
|
CDPEnergyWiseReplyTo CDPEnergyWiseSubtype = 0x00000017
|
||||||
|
)
|
||||||
|
|
||||||
|
// CDPEnergyWise is used by CDP to monitor and control power usage.
|
||||||
|
type CDPEnergyWise struct {
|
||||||
|
EncryptedData []byte
|
||||||
|
Unknown1 uint32
|
||||||
|
SequenceNumber uint32
|
||||||
|
ModelNumber string
|
||||||
|
Unknown2 uint16
|
||||||
|
HardwareID string
|
||||||
|
SerialNum string
|
||||||
|
Unknown3 []byte
|
||||||
|
Role string
|
||||||
|
Domain string
|
||||||
|
Name string
|
||||||
|
ReplyUnknown1 []byte
|
||||||
|
ReplyPort []byte
|
||||||
|
ReplyAddress []byte
|
||||||
|
ReplyUnknown2 []byte
|
||||||
|
ReplyUnknown3 []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// CiscoDiscoveryInfo represents the decoded details for a set of CiscoDiscoveryValues
|
||||||
|
type CiscoDiscoveryInfo struct {
|
||||||
|
BaseLayer
|
||||||
|
CDPHello
|
||||||
|
DeviceID string
|
||||||
|
Addresses []net.IP
|
||||||
|
PortID string
|
||||||
|
Capabilities CDPCapabilities
|
||||||
|
Version string
|
||||||
|
Platform string
|
||||||
|
IPPrefixes []net.IPNet
|
||||||
|
VTPDomain string
|
||||||
|
NativeVLAN uint16
|
||||||
|
FullDuplex bool
|
||||||
|
VLANReply CDPVLANDialogue
|
||||||
|
VLANQuery CDPVLANDialogue
|
||||||
|
PowerConsumption uint16
|
||||||
|
MTU uint32
|
||||||
|
ExtendedTrust uint8
|
||||||
|
UntrustedCOS uint8
|
||||||
|
SysName string
|
||||||
|
SysOID string
|
||||||
|
MgmtAddresses []net.IP
|
||||||
|
Location CDPLocation
|
||||||
|
PowerRequest CDPPowerDialogue
|
||||||
|
PowerAvailable CDPPowerDialogue
|
||||||
|
SparePairPoe CDPSparePairPoE
|
||||||
|
EnergyWise CDPEnergyWise
|
||||||
|
Unknown []CiscoDiscoveryValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeCiscoDiscovery.
|
||||||
|
func (c *CiscoDiscovery) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeCiscoDiscovery
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeCiscoDiscovery(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
c := &CiscoDiscovery{
|
||||||
|
Version: data[0],
|
||||||
|
TTL: data[1],
|
||||||
|
Checksum: binary.BigEndian.Uint16(data[2:4]),
|
||||||
|
}
|
||||||
|
if c.Version != 1 && c.Version != 2 {
|
||||||
|
return fmt.Errorf("Invalid CiscoDiscovery version number %d", c.Version)
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
c.Values, err = decodeCiscoDiscoveryTLVs(data[4:], p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.Contents = data[0:4]
|
||||||
|
c.Payload = data[4:]
|
||||||
|
p.AddLayer(c)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeCiscoDiscoveryInfo))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeCiscoDiscoveryInfo.
|
||||||
|
func (c *CiscoDiscoveryInfo) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeCiscoDiscoveryInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeCiscoDiscoveryTLVs(data []byte, p gopacket.PacketBuilder) (values []CiscoDiscoveryValue, err error) {
|
||||||
|
for len(data) > 0 {
|
||||||
|
if len(data) < 4 {
|
||||||
|
p.SetTruncated()
|
||||||
|
return nil, errors.New("CDP TLV < 4 bytes")
|
||||||
|
}
|
||||||
|
val := CiscoDiscoveryValue{
|
||||||
|
Type: CDPTLVType(binary.BigEndian.Uint16(data[:2])),
|
||||||
|
Length: binary.BigEndian.Uint16(data[2:4]),
|
||||||
|
}
|
||||||
|
if val.Length < 4 {
|
||||||
|
err = fmt.Errorf("Invalid CiscoDiscovery value length %d", val.Length)
|
||||||
|
break
|
||||||
|
} else if len(data) < int(val.Length) {
|
||||||
|
p.SetTruncated()
|
||||||
|
return nil, fmt.Errorf("CDP TLV < length %d", val.Length)
|
||||||
|
}
|
||||||
|
val.Value = data[4:val.Length]
|
||||||
|
values = append(values, val)
|
||||||
|
data = data[val.Length:]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeCiscoDiscoveryInfo(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
var err error
|
||||||
|
info := &CiscoDiscoveryInfo{BaseLayer: BaseLayer{Contents: data}}
|
||||||
|
p.AddLayer(info)
|
||||||
|
values, err := decodeCiscoDiscoveryTLVs(data, p)
|
||||||
|
if err != nil { // Unlikely, as parent decode will fail, but better safe...
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, val := range values {
|
||||||
|
switch val.Type {
|
||||||
|
case CDPTLVDevID:
|
||||||
|
info.DeviceID = string(val.Value)
|
||||||
|
case CDPTLVAddress:
|
||||||
|
if err = checkCDPTLVLen(val, 4); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.Addresses, err = decodeAddresses(val.Value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case CDPTLVPortID:
|
||||||
|
info.PortID = string(val.Value)
|
||||||
|
case CDPTLVCapabilities:
|
||||||
|
if err = checkCDPTLVLen(val, 4); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
val := CDPCapability(binary.BigEndian.Uint32(val.Value[0:4]))
|
||||||
|
info.Capabilities.L3Router = (val&CDPCapMaskRouter > 0)
|
||||||
|
info.Capabilities.TBBridge = (val&CDPCapMaskTBBridge > 0)
|
||||||
|
info.Capabilities.SPBridge = (val&CDPCapMaskSPBridge > 0)
|
||||||
|
info.Capabilities.L2Switch = (val&CDPCapMaskSwitch > 0)
|
||||||
|
info.Capabilities.IsHost = (val&CDPCapMaskHost > 0)
|
||||||
|
info.Capabilities.IGMPFilter = (val&CDPCapMaskIGMPFilter > 0)
|
||||||
|
info.Capabilities.L1Repeater = (val&CDPCapMaskRepeater > 0)
|
||||||
|
info.Capabilities.IsPhone = (val&CDPCapMaskPhone > 0)
|
||||||
|
info.Capabilities.RemotelyManaged = (val&CDPCapMaskRemote > 0)
|
||||||
|
case CDPTLVVersion:
|
||||||
|
info.Version = string(val.Value)
|
||||||
|
case CDPTLVPlatform:
|
||||||
|
info.Platform = string(val.Value)
|
||||||
|
case CDPTLVIPPrefix:
|
||||||
|
v := val.Value
|
||||||
|
l := len(v)
|
||||||
|
if l%5 == 0 && l >= 5 {
|
||||||
|
for len(v) > 0 {
|
||||||
|
_, ipnet, _ := net.ParseCIDR(fmt.Sprintf("%d.%d.%d.%d/%d", v[0], v[1], v[2], v[3], v[4]))
|
||||||
|
info.IPPrefixes = append(info.IPPrefixes, *ipnet)
|
||||||
|
v = v[5:]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Invalid TLV %v length %d", val.Type, len(val.Value))
|
||||||
|
}
|
||||||
|
case CDPTLVHello:
|
||||||
|
if err = checkCDPTLVLen(val, 32); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v := val.Value
|
||||||
|
info.CDPHello.OUI = v[0:3]
|
||||||
|
info.CDPHello.ProtocolID = binary.BigEndian.Uint16(v[3:5])
|
||||||
|
info.CDPHello.ClusterMaster = v[5:9]
|
||||||
|
info.CDPHello.Unknown1 = v[9:13]
|
||||||
|
info.CDPHello.Version = v[13]
|
||||||
|
info.CDPHello.SubVersion = v[14]
|
||||||
|
info.CDPHello.Status = v[15]
|
||||||
|
info.CDPHello.Unknown2 = v[16]
|
||||||
|
info.CDPHello.ClusterCommander = v[17:23]
|
||||||
|
info.CDPHello.SwitchMAC = v[23:29]
|
||||||
|
info.CDPHello.Unknown3 = v[29]
|
||||||
|
info.CDPHello.ManagementVLAN = binary.BigEndian.Uint16(v[30:32])
|
||||||
|
case CDPTLVVTPDomain:
|
||||||
|
info.VTPDomain = string(val.Value)
|
||||||
|
case CDPTLVNativeVLAN:
|
||||||
|
if err = checkCDPTLVLen(val, 2); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.NativeVLAN = binary.BigEndian.Uint16(val.Value[0:2])
|
||||||
|
case CDPTLVFullDuplex:
|
||||||
|
if err = checkCDPTLVLen(val, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.FullDuplex = (val.Value[0] == 1)
|
||||||
|
case CDPTLVVLANReply:
|
||||||
|
if err = checkCDPTLVLen(val, 3); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.VLANReply.ID = uint8(val.Value[0])
|
||||||
|
info.VLANReply.VLAN = binary.BigEndian.Uint16(val.Value[1:3])
|
||||||
|
case CDPTLVVLANQuery:
|
||||||
|
if err = checkCDPTLVLen(val, 3); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.VLANQuery.ID = uint8(val.Value[0])
|
||||||
|
info.VLANQuery.VLAN = binary.BigEndian.Uint16(val.Value[1:3])
|
||||||
|
case CDPTLVPower:
|
||||||
|
if err = checkCDPTLVLen(val, 2); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.PowerConsumption = binary.BigEndian.Uint16(val.Value[0:2])
|
||||||
|
case CDPTLVMTU:
|
||||||
|
if err = checkCDPTLVLen(val, 4); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.MTU = binary.BigEndian.Uint32(val.Value[0:4])
|
||||||
|
case CDPTLVExtendedTrust:
|
||||||
|
if err = checkCDPTLVLen(val, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.ExtendedTrust = uint8(val.Value[0])
|
||||||
|
case CDPTLVUntrustedCOS:
|
||||||
|
if err = checkCDPTLVLen(val, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.UntrustedCOS = uint8(val.Value[0])
|
||||||
|
case CDPTLVSysName:
|
||||||
|
info.SysName = string(val.Value)
|
||||||
|
case CDPTLVSysOID:
|
||||||
|
info.SysOID = string(val.Value)
|
||||||
|
case CDPTLVMgmtAddresses:
|
||||||
|
if err = checkCDPTLVLen(val, 4); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.MgmtAddresses, err = decodeAddresses(val.Value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case CDPTLVLocation:
|
||||||
|
if err = checkCDPTLVLen(val, 2); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.Location.Type = uint8(val.Value[0])
|
||||||
|
info.Location.Location = string(val.Value[1:])
|
||||||
|
|
||||||
|
// case CDPTLVLExternalPortID:
|
||||||
|
// Undocumented
|
||||||
|
case CDPTLVPowerRequested:
|
||||||
|
if err = checkCDPTLVLen(val, 4); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.PowerRequest.ID = binary.BigEndian.Uint16(val.Value[0:2])
|
||||||
|
info.PowerRequest.MgmtID = binary.BigEndian.Uint16(val.Value[2:4])
|
||||||
|
for n := 4; n < len(val.Value); n += 4 {
|
||||||
|
info.PowerRequest.Values = append(info.PowerRequest.Values, binary.BigEndian.Uint32(val.Value[n:n+4]))
|
||||||
|
}
|
||||||
|
case CDPTLVPowerAvailable:
|
||||||
|
if err = checkCDPTLVLen(val, 4); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.PowerAvailable.ID = binary.BigEndian.Uint16(val.Value[0:2])
|
||||||
|
info.PowerAvailable.MgmtID = binary.BigEndian.Uint16(val.Value[2:4])
|
||||||
|
for n := 4; n < len(val.Value); n += 4 {
|
||||||
|
info.PowerAvailable.Values = append(info.PowerAvailable.Values, binary.BigEndian.Uint32(val.Value[n:n+4]))
|
||||||
|
}
|
||||||
|
// case CDPTLVPortUnidirectional
|
||||||
|
// Undocumented
|
||||||
|
case CDPTLVEnergyWise:
|
||||||
|
if err = checkCDPTLVLen(val, 72); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.EnergyWise.EncryptedData = val.Value[0:20]
|
||||||
|
info.EnergyWise.Unknown1 = binary.BigEndian.Uint32(val.Value[20:24])
|
||||||
|
info.EnergyWise.SequenceNumber = binary.BigEndian.Uint32(val.Value[24:28])
|
||||||
|
info.EnergyWise.ModelNumber = string(val.Value[28:44])
|
||||||
|
info.EnergyWise.Unknown2 = binary.BigEndian.Uint16(val.Value[44:46])
|
||||||
|
info.EnergyWise.HardwareID = string(val.Value[46:49])
|
||||||
|
info.EnergyWise.SerialNum = string(val.Value[49:60])
|
||||||
|
info.EnergyWise.Unknown3 = val.Value[60:68]
|
||||||
|
tlvLen := binary.BigEndian.Uint16(val.Value[68:70])
|
||||||
|
tlvNum := binary.BigEndian.Uint16(val.Value[70:72])
|
||||||
|
data := val.Value[72:]
|
||||||
|
if len(data) < int(tlvLen) {
|
||||||
|
return fmt.Errorf("Invalid TLV length %d vs %d", tlvLen, len(data))
|
||||||
|
}
|
||||||
|
numSeen := 0
|
||||||
|
for len(data) > 8 {
|
||||||
|
numSeen++
|
||||||
|
if numSeen > int(tlvNum) { // Too many TLV's ?
|
||||||
|
return fmt.Errorf("Too many TLV's - wanted %d, saw %d", tlvNum, numSeen)
|
||||||
|
}
|
||||||
|
tType := CDPEnergyWiseSubtype(binary.BigEndian.Uint32(data[0:4]))
|
||||||
|
tLen := int(binary.BigEndian.Uint32(data[4:8]))
|
||||||
|
if tLen > len(data)-8 {
|
||||||
|
return fmt.Errorf("Invalid TLV length %d vs %d", tLen, len(data)-8)
|
||||||
|
}
|
||||||
|
data = data[8:]
|
||||||
|
switch tType {
|
||||||
|
case CDPEnergyWiseRole:
|
||||||
|
info.EnergyWise.Role = string(data[:])
|
||||||
|
case CDPEnergyWiseDomain:
|
||||||
|
info.EnergyWise.Domain = string(data[:])
|
||||||
|
case CDPEnergyWiseName:
|
||||||
|
info.EnergyWise.Name = string(data[:])
|
||||||
|
case CDPEnergyWiseReplyTo:
|
||||||
|
if len(data) >= 18 {
|
||||||
|
info.EnergyWise.ReplyUnknown1 = data[0:2]
|
||||||
|
info.EnergyWise.ReplyPort = data[2:4]
|
||||||
|
info.EnergyWise.ReplyAddress = data[4:8]
|
||||||
|
info.EnergyWise.ReplyUnknown2 = data[8:10]
|
||||||
|
info.EnergyWise.ReplyUnknown3 = data[10:14]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = data[tLen:]
|
||||||
|
}
|
||||||
|
case CDPTLVSparePairPOE:
|
||||||
|
if err = checkCDPTLVLen(val, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v := val.Value[0]
|
||||||
|
info.SparePairPoe.PSEFourWire = (v&CDPPoEFourWire > 0)
|
||||||
|
info.SparePairPoe.PDArchShared = (v&CDPPoEPDArch > 0)
|
||||||
|
info.SparePairPoe.PDRequestOn = (v&CDPPoEPDRequest > 0)
|
||||||
|
info.SparePairPoe.PSEOn = (v&CDPPoEPSE > 0)
|
||||||
|
default:
|
||||||
|
info.Unknown = append(info.Unknown, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDP Protocol Types
|
||||||
|
const (
|
||||||
|
CDPProtocolTypeNLPID byte = 1
|
||||||
|
CDPProtocolType802_2 byte = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// CDPAddressType is used to define TLV values within CDP addresses.
|
||||||
|
type CDPAddressType uint64
|
||||||
|
|
||||||
|
// CDP Address types.
|
||||||
|
const (
|
||||||
|
CDPAddressTypeCLNP CDPAddressType = 0x81
|
||||||
|
CDPAddressTypeIPV4 CDPAddressType = 0xcc
|
||||||
|
CDPAddressTypeIPV6 CDPAddressType = 0xaaaa030000000800
|
||||||
|
CDPAddressTypeDECNET CDPAddressType = 0xaaaa030000006003
|
||||||
|
CDPAddressTypeAPPLETALK CDPAddressType = 0xaaaa03000000809b
|
||||||
|
CDPAddressTypeIPX CDPAddressType = 0xaaaa030000008137
|
||||||
|
CDPAddressTypeVINES CDPAddressType = 0xaaaa0300000080c4
|
||||||
|
CDPAddressTypeXNS CDPAddressType = 0xaaaa030000000600
|
||||||
|
CDPAddressTypeAPOLLO CDPAddressType = 0xaaaa030000008019
|
||||||
|
)
|
||||||
|
|
||||||
|
func decodeAddresses(v []byte) (addresses []net.IP, err error) {
|
||||||
|
numaddr := int(binary.BigEndian.Uint32(v[0:4]))
|
||||||
|
if numaddr < 1 {
|
||||||
|
return nil, fmt.Errorf("Invalid Address TLV number %d", numaddr)
|
||||||
|
}
|
||||||
|
v = v[4:]
|
||||||
|
if len(v) < numaddr*8 {
|
||||||
|
return nil, fmt.Errorf("Invalid Address TLV length %d", len(v))
|
||||||
|
}
|
||||||
|
for i := 0; i < numaddr; i++ {
|
||||||
|
prottype := v[0]
|
||||||
|
if prottype != CDPProtocolTypeNLPID && prottype != CDPProtocolType802_2 { // invalid protocol type
|
||||||
|
return nil, fmt.Errorf("Invalid Address Protocol %d", prottype)
|
||||||
|
}
|
||||||
|
protlen := int(v[1])
|
||||||
|
if (prottype == CDPProtocolTypeNLPID && protlen != 1) ||
|
||||||
|
(prottype == CDPProtocolType802_2 && protlen != 3 && protlen != 8) { // invalid length
|
||||||
|
return nil, fmt.Errorf("Invalid Address Protocol length %d", protlen)
|
||||||
|
}
|
||||||
|
plen := make([]byte, 8)
|
||||||
|
copy(plen[8-protlen:], v[2:2+protlen])
|
||||||
|
protocol := CDPAddressType(binary.BigEndian.Uint64(plen))
|
||||||
|
v = v[2+protlen:]
|
||||||
|
addrlen := binary.BigEndian.Uint16(v[0:2])
|
||||||
|
ab := v[2 : 2+addrlen]
|
||||||
|
if protocol == CDPAddressTypeIPV4 && addrlen == 4 {
|
||||||
|
addresses = append(addresses, net.IPv4(ab[0], ab[1], ab[2], ab[3]))
|
||||||
|
} else if protocol == CDPAddressTypeIPV6 && addrlen == 16 {
|
||||||
|
addresses = append(addresses, net.IP(ab))
|
||||||
|
} else {
|
||||||
|
// only handle IPV4 & IPV6 for now
|
||||||
|
}
|
||||||
|
v = v[2+addrlen:]
|
||||||
|
if len(v) < 8 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CDPTLVType) String() (s string) {
|
||||||
|
switch t {
|
||||||
|
case CDPTLVDevID:
|
||||||
|
s = "Device ID"
|
||||||
|
case CDPTLVAddress:
|
||||||
|
s = "Addresses"
|
||||||
|
case CDPTLVPortID:
|
||||||
|
s = "Port ID"
|
||||||
|
case CDPTLVCapabilities:
|
||||||
|
s = "Capabilities"
|
||||||
|
case CDPTLVVersion:
|
||||||
|
s = "Software Version"
|
||||||
|
case CDPTLVPlatform:
|
||||||
|
s = "Platform"
|
||||||
|
case CDPTLVIPPrefix:
|
||||||
|
s = "IP Prefix"
|
||||||
|
case CDPTLVHello:
|
||||||
|
s = "Protocol Hello"
|
||||||
|
case CDPTLVVTPDomain:
|
||||||
|
s = "VTP Management Domain"
|
||||||
|
case CDPTLVNativeVLAN:
|
||||||
|
s = "Native VLAN"
|
||||||
|
case CDPTLVFullDuplex:
|
||||||
|
s = "Full Duplex"
|
||||||
|
case CDPTLVVLANReply:
|
||||||
|
s = "VoIP VLAN Reply"
|
||||||
|
case CDPTLVVLANQuery:
|
||||||
|
s = "VLANQuery"
|
||||||
|
case CDPTLVPower:
|
||||||
|
s = "Power consumption"
|
||||||
|
case CDPTLVMTU:
|
||||||
|
s = "MTU"
|
||||||
|
case CDPTLVExtendedTrust:
|
||||||
|
s = "Extended Trust Bitmap"
|
||||||
|
case CDPTLVUntrustedCOS:
|
||||||
|
s = "Untrusted Port CoS"
|
||||||
|
case CDPTLVSysName:
|
||||||
|
s = "System Name"
|
||||||
|
case CDPTLVSysOID:
|
||||||
|
s = "System OID"
|
||||||
|
case CDPTLVMgmtAddresses:
|
||||||
|
s = "Management Addresses"
|
||||||
|
case CDPTLVLocation:
|
||||||
|
s = "Location"
|
||||||
|
case CDPTLVExternalPortID:
|
||||||
|
s = "External Port ID"
|
||||||
|
case CDPTLVPowerRequested:
|
||||||
|
s = "Power Requested"
|
||||||
|
case CDPTLVPowerAvailable:
|
||||||
|
s = "Power Available"
|
||||||
|
case CDPTLVPortUnidirectional:
|
||||||
|
s = "Port Unidirectional"
|
||||||
|
case CDPTLVEnergyWise:
|
||||||
|
s = "Energy Wise"
|
||||||
|
case CDPTLVSparePairPOE:
|
||||||
|
s = "Spare Pair POE"
|
||||||
|
default:
|
||||||
|
s = "Unknown"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a CDPAddressType) String() (s string) {
|
||||||
|
switch a {
|
||||||
|
case CDPAddressTypeCLNP:
|
||||||
|
s = "Connectionless Network Protocol"
|
||||||
|
case CDPAddressTypeIPV4:
|
||||||
|
s = "IPv4"
|
||||||
|
case CDPAddressTypeIPV6:
|
||||||
|
s = "IPv6"
|
||||||
|
case CDPAddressTypeDECNET:
|
||||||
|
s = "DECnet Phase IV"
|
||||||
|
case CDPAddressTypeAPPLETALK:
|
||||||
|
s = "Apple Talk"
|
||||||
|
case CDPAddressTypeIPX:
|
||||||
|
s = "Novell IPX"
|
||||||
|
case CDPAddressTypeVINES:
|
||||||
|
s = "Banyan VINES"
|
||||||
|
case CDPAddressTypeXNS:
|
||||||
|
s = "Xerox Network Systems"
|
||||||
|
case CDPAddressTypeAPOLLO:
|
||||||
|
s = "Apollo"
|
||||||
|
default:
|
||||||
|
s = "Unknown"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t CDPEnergyWiseSubtype) String() (s string) {
|
||||||
|
switch t {
|
||||||
|
case CDPEnergyWiseRole:
|
||||||
|
s = "Role"
|
||||||
|
case CDPEnergyWiseDomain:
|
||||||
|
s = "Domain"
|
||||||
|
case CDPEnergyWiseName:
|
||||||
|
s = "Name"
|
||||||
|
case CDPEnergyWiseReplyTo:
|
||||||
|
s = "ReplyTo"
|
||||||
|
default:
|
||||||
|
s = "Unknown"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkCDPTLVLen(v CiscoDiscoveryValue, l int) (err error) {
|
||||||
|
if len(v.Value) < l {
|
||||||
|
err = fmt.Errorf("Invalid TLV %v length %d", v.Type, len(v.Value))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
109
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ctp.go
generated
vendored
Normal file
109
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ctp.go
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EthernetCTPFunction is the function code used by the EthernetCTP protocol to identify each
|
||||||
|
// EthernetCTP layer.
|
||||||
|
type EthernetCTPFunction uint16
|
||||||
|
|
||||||
|
// EthernetCTPFunction values.
|
||||||
|
const (
|
||||||
|
EthernetCTPFunctionReply EthernetCTPFunction = 1
|
||||||
|
EthernetCTPFunctionForwardData EthernetCTPFunction = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// EthernetCTP implements the EthernetCTP protocol, see http://www.mit.edu/people/jhawk/ctp.html.
|
||||||
|
// We split EthernetCTP up into the top-level EthernetCTP layer, followed by zero or more
|
||||||
|
// EthernetCTPForwardData layers, followed by a final EthernetCTPReply layer.
|
||||||
|
type EthernetCTP struct {
|
||||||
|
BaseLayer
|
||||||
|
SkipCount uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeEthernetCTP.
|
||||||
|
func (c *EthernetCTP) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeEthernetCTP
|
||||||
|
}
|
||||||
|
|
||||||
|
// EthernetCTPForwardData is the ForwardData layer inside EthernetCTP. See EthernetCTP's docs for more
|
||||||
|
// details.
|
||||||
|
type EthernetCTPForwardData struct {
|
||||||
|
BaseLayer
|
||||||
|
Function EthernetCTPFunction
|
||||||
|
ForwardAddress []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeEthernetCTPForwardData.
|
||||||
|
func (c *EthernetCTPForwardData) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeEthernetCTPForwardData
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForwardEndpoint returns the EthernetCTPForwardData ForwardAddress as an endpoint.
|
||||||
|
func (c *EthernetCTPForwardData) ForwardEndpoint() gopacket.Endpoint {
|
||||||
|
return gopacket.NewEndpoint(EndpointMAC, c.ForwardAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EthernetCTPReply is the Reply layer inside EthernetCTP. See EthernetCTP's docs for more details.
|
||||||
|
type EthernetCTPReply struct {
|
||||||
|
BaseLayer
|
||||||
|
Function EthernetCTPFunction
|
||||||
|
ReceiptNumber uint16
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeEthernetCTPReply.
|
||||||
|
func (c *EthernetCTPReply) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeEthernetCTPReply
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payload returns the EthernetCTP reply's Data bytes.
|
||||||
|
func (c *EthernetCTPReply) Payload() []byte { return c.Data }
|
||||||
|
|
||||||
|
func decodeEthernetCTP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
c := &EthernetCTP{
|
||||||
|
SkipCount: binary.LittleEndian.Uint16(data[:2]),
|
||||||
|
BaseLayer: BaseLayer{data[:2], data[2:]},
|
||||||
|
}
|
||||||
|
if c.SkipCount%2 != 0 {
|
||||||
|
return fmt.Errorf("EthernetCTP skip count is odd: %d", c.SkipCount)
|
||||||
|
}
|
||||||
|
p.AddLayer(c)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType))
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeEthernetCTPFromFunctionType reads in the first 2 bytes to determine the EthernetCTP
|
||||||
|
// layer type to decode next, then decodes based on that.
|
||||||
|
func decodeEthernetCTPFromFunctionType(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
function := EthernetCTPFunction(binary.LittleEndian.Uint16(data[:2]))
|
||||||
|
switch function {
|
||||||
|
case EthernetCTPFunctionReply:
|
||||||
|
reply := &EthernetCTPReply{
|
||||||
|
Function: function,
|
||||||
|
ReceiptNumber: binary.LittleEndian.Uint16(data[2:4]),
|
||||||
|
Data: data[4:],
|
||||||
|
BaseLayer: BaseLayer{data, nil},
|
||||||
|
}
|
||||||
|
p.AddLayer(reply)
|
||||||
|
p.SetApplicationLayer(reply)
|
||||||
|
return nil
|
||||||
|
case EthernetCTPFunctionForwardData:
|
||||||
|
forward := &EthernetCTPForwardData{
|
||||||
|
Function: function,
|
||||||
|
ForwardAddress: data[2:8],
|
||||||
|
BaseLayer: BaseLayer{data[:8], data[8:]},
|
||||||
|
}
|
||||||
|
p.AddLayer(forward)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType))
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Unknown EthernetCTP function type %v", function)
|
||||||
|
}
|
592
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dhcpv4.go
generated
vendored
Normal file
592
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dhcpv4.go
generated
vendored
Normal file
|
@ -0,0 +1,592 @@
|
||||||
|
// Copyright 2016 Google, Inc. 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 (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DHCPOp rerprents a bootp operation
|
||||||
|
type DHCPOp byte
|
||||||
|
|
||||||
|
// bootp operations
|
||||||
|
const (
|
||||||
|
DHCPOpRequest DHCPOp = 1
|
||||||
|
DHCPOpReply DHCPOp = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of a DHCPOp.
|
||||||
|
func (o DHCPOp) String() string {
|
||||||
|
switch o {
|
||||||
|
case DHCPOpRequest:
|
||||||
|
return "Request"
|
||||||
|
case DHCPOpReply:
|
||||||
|
return "Reply"
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPMsgType represents a DHCP operation
|
||||||
|
type DHCPMsgType byte
|
||||||
|
|
||||||
|
// Constants that represent DHCP operations
|
||||||
|
const (
|
||||||
|
DHCPMsgTypeUnspecified DHCPMsgType = iota
|
||||||
|
DHCPMsgTypeDiscover
|
||||||
|
DHCPMsgTypeOffer
|
||||||
|
DHCPMsgTypeRequest
|
||||||
|
DHCPMsgTypeDecline
|
||||||
|
DHCPMsgTypeAck
|
||||||
|
DHCPMsgTypeNak
|
||||||
|
DHCPMsgTypeRelease
|
||||||
|
DHCPMsgTypeInform
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of a DHCPMsgType.
|
||||||
|
func (o DHCPMsgType) String() string {
|
||||||
|
switch o {
|
||||||
|
case DHCPMsgTypeUnspecified:
|
||||||
|
return "Unspecified"
|
||||||
|
case DHCPMsgTypeDiscover:
|
||||||
|
return "Discover"
|
||||||
|
case DHCPMsgTypeOffer:
|
||||||
|
return "Offer"
|
||||||
|
case DHCPMsgTypeRequest:
|
||||||
|
return "Request"
|
||||||
|
case DHCPMsgTypeDecline:
|
||||||
|
return "Decline"
|
||||||
|
case DHCPMsgTypeAck:
|
||||||
|
return "Ack"
|
||||||
|
case DHCPMsgTypeNak:
|
||||||
|
return "Nak"
|
||||||
|
case DHCPMsgTypeRelease:
|
||||||
|
return "Release"
|
||||||
|
case DHCPMsgTypeInform:
|
||||||
|
return "Inform"
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//DHCPMagic is the RFC 2131 "magic cooke" for DHCP.
|
||||||
|
var DHCPMagic uint32 = 0x63825363
|
||||||
|
|
||||||
|
// DHCPv4 contains data for a single DHCP packet.
|
||||||
|
type DHCPv4 struct {
|
||||||
|
BaseLayer
|
||||||
|
Operation DHCPOp
|
||||||
|
HardwareType LinkType
|
||||||
|
HardwareLen uint8
|
||||||
|
HardwareOpts uint8
|
||||||
|
Xid uint32
|
||||||
|
Secs uint16
|
||||||
|
Flags uint16
|
||||||
|
ClientIP net.IP
|
||||||
|
YourClientIP net.IP
|
||||||
|
NextServerIP net.IP
|
||||||
|
RelayAgentIP net.IP
|
||||||
|
ClientHWAddr net.HardwareAddr
|
||||||
|
ServerName []byte
|
||||||
|
File []byte
|
||||||
|
Options DHCPOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPOptions is used to get nicely printed option lists which would normally
|
||||||
|
// be cut off after 5 options.
|
||||||
|
type DHCPOptions []DHCPOption
|
||||||
|
|
||||||
|
// String returns a string version of the options list.
|
||||||
|
func (o DHCPOptions) String() string {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
buf.WriteByte('[')
|
||||||
|
for i, opt := range o {
|
||||||
|
buf.WriteString(opt.String())
|
||||||
|
if i+1 != len(o) {
|
||||||
|
buf.WriteString(", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.WriteByte(']')
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeDHCPv4
|
||||||
|
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])
|
||||||
|
d.HardwareLen = data[2]
|
||||||
|
d.HardwareOpts = data[3]
|
||||||
|
d.Xid = binary.BigEndian.Uint32(data[4:8])
|
||||||
|
d.Secs = binary.BigEndian.Uint16(data[8:10])
|
||||||
|
d.Flags = binary.BigEndian.Uint16(data[10:12])
|
||||||
|
d.ClientIP = net.IP(data[12:16])
|
||||||
|
d.YourClientIP = net.IP(data[16:20])
|
||||||
|
d.NextServerIP = net.IP(data[20:24])
|
||||||
|
d.RelayAgentIP = net.IP(data[24:28])
|
||||||
|
d.ClientHWAddr = net.HardwareAddr(data[28 : 28+d.HardwareLen])
|
||||||
|
d.ServerName = data[44:108]
|
||||||
|
d.File = data[108:236]
|
||||||
|
if binary.BigEndian.Uint32(data[236:240]) != DHCPMagic {
|
||||||
|
return InvalidMagicCookie
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) <= 240 {
|
||||||
|
// DHCP Packet could have no option (??)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
options := data[240:]
|
||||||
|
|
||||||
|
stop := len(options)
|
||||||
|
start := 0
|
||||||
|
for start < stop {
|
||||||
|
o := DHCPOption{}
|
||||||
|
if err := o.decode(options[start:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if o.Type == DHCPOptEnd {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d.Options = append(d.Options, o)
|
||||||
|
// Check if the option is a single byte pad
|
||||||
|
if o.Type == DHCPOptPad {
|
||||||
|
start++
|
||||||
|
} else {
|
||||||
|
start += int(o.Length) + 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Contents = data
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the length of a DHCPv4 packet.
|
||||||
|
func (d *DHCPv4) Len() uint16 {
|
||||||
|
n := uint16(240)
|
||||||
|
for _, o := range d.Options {
|
||||||
|
if o.Type == DHCPOptPad {
|
||||||
|
n++
|
||||||
|
} else {
|
||||||
|
n += uint16(o.Length) + 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n++ // for opt end
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (d *DHCPv4) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
plen := int(d.Len())
|
||||||
|
|
||||||
|
data, err := b.PrependBytes(plen)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
data[0] = byte(d.Operation)
|
||||||
|
data[1] = byte(d.HardwareType)
|
||||||
|
if opts.FixLengths {
|
||||||
|
d.HardwareLen = uint8(len(d.ClientHWAddr))
|
||||||
|
}
|
||||||
|
data[2] = d.HardwareLen
|
||||||
|
data[3] = d.HardwareOpts
|
||||||
|
binary.BigEndian.PutUint32(data[4:8], d.Xid)
|
||||||
|
binary.BigEndian.PutUint16(data[8:10], d.Secs)
|
||||||
|
binary.BigEndian.PutUint16(data[10:12], d.Flags)
|
||||||
|
copy(data[12:16], d.ClientIP.To4())
|
||||||
|
copy(data[16:20], d.YourClientIP.To4())
|
||||||
|
copy(data[20:24], d.NextServerIP.To4())
|
||||||
|
copy(data[24:28], d.RelayAgentIP.To4())
|
||||||
|
copy(data[28:44], d.ClientHWAddr)
|
||||||
|
copy(data[44:108], d.ServerName)
|
||||||
|
copy(data[108:236], d.File)
|
||||||
|
binary.BigEndian.PutUint32(data[236:240], DHCPMagic)
|
||||||
|
|
||||||
|
if len(d.Options) > 0 {
|
||||||
|
offset := 240
|
||||||
|
for _, o := range d.Options {
|
||||||
|
if err := o.encode(data[offset:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// A pad option is only a single byte
|
||||||
|
if o.Type == DHCPOptPad {
|
||||||
|
offset++
|
||||||
|
} else {
|
||||||
|
offset += 2 + len(o.Data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
optend := NewDHCPOption(DHCPOptEnd, nil)
|
||||||
|
if err := optend.encode(data[offset:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (d *DHCPv4) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeDHCPv4
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (d *DHCPv4) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeDHCPv4(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
dhcp := &DHCPv4{}
|
||||||
|
err := dhcp.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(dhcp)
|
||||||
|
return p.NextDecoder(gopacket.LayerTypePayload)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPOpt represents a DHCP option or parameter from RFC-2132
|
||||||
|
type DHCPOpt byte
|
||||||
|
|
||||||
|
// Constants for the DHCPOpt options.
|
||||||
|
const (
|
||||||
|
DHCPOptPad DHCPOpt = 0
|
||||||
|
DHCPOptSubnetMask DHCPOpt = 1 // 4, net.IP
|
||||||
|
DHCPOptTimeOffset DHCPOpt = 2 // 4, int32 (signed seconds from UTC)
|
||||||
|
DHCPOptRouter DHCPOpt = 3 // n*4, [n]net.IP
|
||||||
|
DHCPOptTimeServer DHCPOpt = 4 // n*4, [n]net.IP
|
||||||
|
DHCPOptNameServer DHCPOpt = 5 // n*4, [n]net.IP
|
||||||
|
DHCPOptDNS DHCPOpt = 6 // n*4, [n]net.IP
|
||||||
|
DHCPOptLogServer DHCPOpt = 7 // n*4, [n]net.IP
|
||||||
|
DHCPOptCookieServer DHCPOpt = 8 // n*4, [n]net.IP
|
||||||
|
DHCPOptLPRServer DHCPOpt = 9 // n*4, [n]net.IP
|
||||||
|
DHCPOptImpressServer DHCPOpt = 10 // n*4, [n]net.IP
|
||||||
|
DHCPOptResLocServer DHCPOpt = 11 // n*4, [n]net.IP
|
||||||
|
DHCPOptHostname DHCPOpt = 12 // n, string
|
||||||
|
DHCPOptBootfileSize DHCPOpt = 13 // 2, uint16
|
||||||
|
DHCPOptMeritDumpFile DHCPOpt = 14 // >1, string
|
||||||
|
DHCPOptDomainName DHCPOpt = 15 // n, string
|
||||||
|
DHCPOptSwapServer DHCPOpt = 16 // n*4, [n]net.IP
|
||||||
|
DHCPOptRootPath DHCPOpt = 17 // n, string
|
||||||
|
DHCPOptExtensionsPath DHCPOpt = 18 // n, string
|
||||||
|
DHCPOptIPForwarding DHCPOpt = 19 // 1, bool
|
||||||
|
DHCPOptSourceRouting DHCPOpt = 20 // 1, bool
|
||||||
|
DHCPOptPolicyFilter DHCPOpt = 21 // 8*n, [n]{net.IP/net.IP}
|
||||||
|
DHCPOptDatagramMTU DHCPOpt = 22 // 2, uint16
|
||||||
|
DHCPOptDefaultTTL DHCPOpt = 23 // 1, byte
|
||||||
|
DHCPOptPathMTUAgingTimeout DHCPOpt = 24 // 4, uint32
|
||||||
|
DHCPOptPathPlateuTableOption DHCPOpt = 25 // 2*n, []uint16
|
||||||
|
DHCPOptInterfaceMTU DHCPOpt = 26 // 2, uint16
|
||||||
|
DHCPOptAllSubsLocal DHCPOpt = 27 // 1, bool
|
||||||
|
DHCPOptBroadcastAddr DHCPOpt = 28 // 4, net.IP
|
||||||
|
DHCPOptMaskDiscovery DHCPOpt = 29 // 1, bool
|
||||||
|
DHCPOptMaskSupplier DHCPOpt = 30 // 1, bool
|
||||||
|
DHCPOptRouterDiscovery DHCPOpt = 31 // 1, bool
|
||||||
|
DHCPOptSolicitAddr DHCPOpt = 32 // 4, net.IP
|
||||||
|
DHCPOptStaticRoute DHCPOpt = 33 // n*8, [n]{net.IP/net.IP} -- note the 2nd is router not mask
|
||||||
|
DHCPOptARPTrailers DHCPOpt = 34 // 1, bool
|
||||||
|
DHCPOptARPTimeout DHCPOpt = 35 // 4, uint32
|
||||||
|
DHCPOptEthernetEncap DHCPOpt = 36 // 1, bool
|
||||||
|
DHCPOptTCPTTL DHCPOpt = 37 // 1, byte
|
||||||
|
DHCPOptTCPKeepAliveInt DHCPOpt = 38 // 4, uint32
|
||||||
|
DHCPOptTCPKeepAliveGarbage DHCPOpt = 39 // 1, bool
|
||||||
|
DHCPOptNISDomain DHCPOpt = 40 // n, string
|
||||||
|
DHCPOptNISServers DHCPOpt = 41 // 4*n, [n]net.IP
|
||||||
|
DHCPOptNTPServers DHCPOpt = 42 // 4*n, [n]net.IP
|
||||||
|
DHCPOptVendorOption DHCPOpt = 43 // n, [n]byte // may be encapsulated.
|
||||||
|
DHCPOptNetBIOSTCPNS DHCPOpt = 44 // 4*n, [n]net.IP
|
||||||
|
DHCPOptNetBIOSTCPDDS DHCPOpt = 45 // 4*n, [n]net.IP
|
||||||
|
DHCPOptNETBIOSTCPNodeType DHCPOpt = 46 // 1, magic byte
|
||||||
|
DHCPOptNetBIOSTCPScope DHCPOpt = 47 // n, string
|
||||||
|
DHCPOptXFontServer DHCPOpt = 48 // n, string
|
||||||
|
DHCPOptXDisplayManager DHCPOpt = 49 // n, string
|
||||||
|
DHCPOptRequestIP DHCPOpt = 50 // 4, net.IP
|
||||||
|
DHCPOptLeaseTime DHCPOpt = 51 // 4, uint32
|
||||||
|
DHCPOptExtOptions DHCPOpt = 52 // 1, 1/2/3
|
||||||
|
DHCPOptMessageType DHCPOpt = 53 // 1, 1-7
|
||||||
|
DHCPOptServerID DHCPOpt = 54 // 4, net.IP
|
||||||
|
DHCPOptParamsRequest DHCPOpt = 55 // n, []byte
|
||||||
|
DHCPOptMessage DHCPOpt = 56 // n, 3
|
||||||
|
DHCPOptMaxMessageSize DHCPOpt = 57 // 2, uint16
|
||||||
|
DHCPOptT1 DHCPOpt = 58 // 4, uint32
|
||||||
|
DHCPOptT2 DHCPOpt = 59 // 4, uint32
|
||||||
|
DHCPOptClassID DHCPOpt = 60 // n, []byte
|
||||||
|
DHCPOptClientID DHCPOpt = 61 // n >= 2, []byte
|
||||||
|
DHCPOptDomainSearch DHCPOpt = 119 // n, string
|
||||||
|
DHCPOptSIPServers DHCPOpt = 120 // n, url
|
||||||
|
DHCPOptClasslessStaticRoute DHCPOpt = 121 //
|
||||||
|
DHCPOptEnd DHCPOpt = 255
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of a DHCPOpt.
|
||||||
|
func (o DHCPOpt) String() string {
|
||||||
|
switch o {
|
||||||
|
case DHCPOptPad:
|
||||||
|
return "(padding)"
|
||||||
|
case DHCPOptSubnetMask:
|
||||||
|
return "SubnetMask"
|
||||||
|
case DHCPOptTimeOffset:
|
||||||
|
return "TimeOffset"
|
||||||
|
case DHCPOptRouter:
|
||||||
|
return "Router"
|
||||||
|
case DHCPOptTimeServer:
|
||||||
|
return "rfc868" // old time server protocol stringified to dissuade confusion w. NTP
|
||||||
|
case DHCPOptNameServer:
|
||||||
|
return "ien116" // obscure nameserver protocol stringified to dissuade confusion w. DNS
|
||||||
|
case DHCPOptDNS:
|
||||||
|
return "DNS"
|
||||||
|
case DHCPOptLogServer:
|
||||||
|
return "mitLCS" // MIT LCS server protocol yada yada w. Syslog
|
||||||
|
case DHCPOptCookieServer:
|
||||||
|
return "CookieServer"
|
||||||
|
case DHCPOptLPRServer:
|
||||||
|
return "LPRServer"
|
||||||
|
case DHCPOptImpressServer:
|
||||||
|
return "ImpressServer"
|
||||||
|
case DHCPOptResLocServer:
|
||||||
|
return "ResourceLocationServer"
|
||||||
|
case DHCPOptHostname:
|
||||||
|
return "Hostname"
|
||||||
|
case DHCPOptBootfileSize:
|
||||||
|
return "BootfileSize"
|
||||||
|
case DHCPOptMeritDumpFile:
|
||||||
|
return "MeritDumpFile"
|
||||||
|
case DHCPOptDomainName:
|
||||||
|
return "DomainName"
|
||||||
|
case DHCPOptSwapServer:
|
||||||
|
return "SwapServer"
|
||||||
|
case DHCPOptRootPath:
|
||||||
|
return "RootPath"
|
||||||
|
case DHCPOptExtensionsPath:
|
||||||
|
return "ExtensionsPath"
|
||||||
|
case DHCPOptIPForwarding:
|
||||||
|
return "IPForwarding"
|
||||||
|
case DHCPOptSourceRouting:
|
||||||
|
return "SourceRouting"
|
||||||
|
case DHCPOptPolicyFilter:
|
||||||
|
return "PolicyFilter"
|
||||||
|
case DHCPOptDatagramMTU:
|
||||||
|
return "DatagramMTU"
|
||||||
|
case DHCPOptDefaultTTL:
|
||||||
|
return "DefaultTTL"
|
||||||
|
case DHCPOptPathMTUAgingTimeout:
|
||||||
|
return "PathMTUAgingTimeout"
|
||||||
|
case DHCPOptPathPlateuTableOption:
|
||||||
|
return "PathPlateuTableOption"
|
||||||
|
case DHCPOptInterfaceMTU:
|
||||||
|
return "InterfaceMTU"
|
||||||
|
case DHCPOptAllSubsLocal:
|
||||||
|
return "AllSubsLocal"
|
||||||
|
case DHCPOptBroadcastAddr:
|
||||||
|
return "BroadcastAddress"
|
||||||
|
case DHCPOptMaskDiscovery:
|
||||||
|
return "MaskDiscovery"
|
||||||
|
case DHCPOptMaskSupplier:
|
||||||
|
return "MaskSupplier"
|
||||||
|
case DHCPOptRouterDiscovery:
|
||||||
|
return "RouterDiscovery"
|
||||||
|
case DHCPOptSolicitAddr:
|
||||||
|
return "SolicitAddr"
|
||||||
|
case DHCPOptStaticRoute:
|
||||||
|
return "StaticRoute"
|
||||||
|
case DHCPOptARPTrailers:
|
||||||
|
return "ARPTrailers"
|
||||||
|
case DHCPOptARPTimeout:
|
||||||
|
return "ARPTimeout"
|
||||||
|
case DHCPOptEthernetEncap:
|
||||||
|
return "EthernetEncap"
|
||||||
|
case DHCPOptTCPTTL:
|
||||||
|
return "TCPTTL"
|
||||||
|
case DHCPOptTCPKeepAliveInt:
|
||||||
|
return "TCPKeepAliveInt"
|
||||||
|
case DHCPOptTCPKeepAliveGarbage:
|
||||||
|
return "TCPKeepAliveGarbage"
|
||||||
|
case DHCPOptNISDomain:
|
||||||
|
return "NISDomain"
|
||||||
|
case DHCPOptNISServers:
|
||||||
|
return "NISServers"
|
||||||
|
case DHCPOptNTPServers:
|
||||||
|
return "NTPServers"
|
||||||
|
case DHCPOptVendorOption:
|
||||||
|
return "VendorOption"
|
||||||
|
case DHCPOptNetBIOSTCPNS:
|
||||||
|
return "NetBIOSOverTCPNS"
|
||||||
|
case DHCPOptNetBIOSTCPDDS:
|
||||||
|
return "NetBiosOverTCPDDS"
|
||||||
|
case DHCPOptNETBIOSTCPNodeType:
|
||||||
|
return "NetBIOSOverTCPNodeType"
|
||||||
|
case DHCPOptNetBIOSTCPScope:
|
||||||
|
return "NetBIOSOverTCPScope"
|
||||||
|
case DHCPOptXFontServer:
|
||||||
|
return "XFontServer"
|
||||||
|
case DHCPOptXDisplayManager:
|
||||||
|
return "XDisplayManager"
|
||||||
|
case DHCPOptEnd:
|
||||||
|
return "(end)"
|
||||||
|
case DHCPOptSIPServers:
|
||||||
|
return "SipServers"
|
||||||
|
case DHCPOptRequestIP:
|
||||||
|
return "RequestIP"
|
||||||
|
case DHCPOptLeaseTime:
|
||||||
|
return "LeaseTime"
|
||||||
|
case DHCPOptExtOptions:
|
||||||
|
return "ExtOpts"
|
||||||
|
case DHCPOptMessageType:
|
||||||
|
return "MessageType"
|
||||||
|
case DHCPOptServerID:
|
||||||
|
return "ServerID"
|
||||||
|
case DHCPOptParamsRequest:
|
||||||
|
return "ParamsRequest"
|
||||||
|
case DHCPOptMessage:
|
||||||
|
return "Message"
|
||||||
|
case DHCPOptMaxMessageSize:
|
||||||
|
return "MaxDHCPSize"
|
||||||
|
case DHCPOptT1:
|
||||||
|
return "Timer1"
|
||||||
|
case DHCPOptT2:
|
||||||
|
return "Timer2"
|
||||||
|
case DHCPOptClassID:
|
||||||
|
return "ClassID"
|
||||||
|
case DHCPOptClientID:
|
||||||
|
return "ClientID"
|
||||||
|
case DHCPOptDomainSearch:
|
||||||
|
return "DomainSearch"
|
||||||
|
case DHCPOptClasslessStaticRoute:
|
||||||
|
return "ClasslessStaticRoute"
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPOption rerpresents a DHCP option.
|
||||||
|
type DHCPOption struct {
|
||||||
|
Type DHCPOpt
|
||||||
|
Length uint8
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string version of a DHCP Option.
|
||||||
|
func (o DHCPOption) String() string {
|
||||||
|
switch o.Type {
|
||||||
|
|
||||||
|
case DHCPOptHostname, DHCPOptMeritDumpFile, DHCPOptDomainName, DHCPOptRootPath,
|
||||||
|
DHCPOptExtensionsPath, DHCPOptNISDomain, DHCPOptNetBIOSTCPScope, DHCPOptXFontServer,
|
||||||
|
DHCPOptXDisplayManager, DHCPOptMessage, DHCPOptDomainSearch: // string
|
||||||
|
return fmt.Sprintf("Option(%s:%s)", o.Type, string(o.Data))
|
||||||
|
|
||||||
|
case DHCPOptMessageType:
|
||||||
|
if len(o.Data) != 1 {
|
||||||
|
return fmt.Sprintf("Option(%s:INVALID)", o.Type)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Option(%s:%s)", o.Type, DHCPMsgType(o.Data[0]))
|
||||||
|
|
||||||
|
case DHCPOptSubnetMask, DHCPOptServerID, DHCPOptBroadcastAddr,
|
||||||
|
DHCPOptSolicitAddr, DHCPOptRequestIP: // net.IP
|
||||||
|
if len(o.Data) < 4 {
|
||||||
|
return fmt.Sprintf("Option(%s:INVALID)", o.Type)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Option(%s:%s)", o.Type, net.IP(o.Data))
|
||||||
|
|
||||||
|
case DHCPOptT1, DHCPOptT2, DHCPOptLeaseTime, DHCPOptPathMTUAgingTimeout,
|
||||||
|
DHCPOptARPTimeout, DHCPOptTCPKeepAliveInt: // uint32
|
||||||
|
if len(o.Data) != 4 {
|
||||||
|
return fmt.Sprintf("Option(%s:INVALID)", o.Type)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Option(%s:%d)", o.Type,
|
||||||
|
uint32(o.Data[0])<<24|uint32(o.Data[1])<<16|uint32(o.Data[2])<<8|uint32(o.Data[3]))
|
||||||
|
|
||||||
|
case DHCPOptParamsRequest:
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
buf.WriteString(fmt.Sprintf("Option(%s:", o.Type))
|
||||||
|
for i, v := range o.Data {
|
||||||
|
buf.WriteString(DHCPOpt(v).String())
|
||||||
|
if i+1 != len(o.Data) {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.WriteString(")")
|
||||||
|
return buf.String()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("Option(%s:%v)", o.Type, o.Data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDHCPOption constructs a new DHCPOption with a given type and data.
|
||||||
|
func NewDHCPOption(t DHCPOpt, data []byte) DHCPOption {
|
||||||
|
o := DHCPOption{Type: t}
|
||||||
|
if data != nil {
|
||||||
|
o.Data = data
|
||||||
|
o.Length = uint8(len(data))
|
||||||
|
}
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *DHCPOption) encode(b []byte) error {
|
||||||
|
switch o.Type {
|
||||||
|
case DHCPOptPad, DHCPOptEnd:
|
||||||
|
b[0] = byte(o.Type)
|
||||||
|
default:
|
||||||
|
b[0] = byte(o.Type)
|
||||||
|
b[1] = o.Length
|
||||||
|
copy(b[2:], o.Data)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *DHCPOption) decode(data []byte) error {
|
||||||
|
if len(data) < 1 {
|
||||||
|
// Pad/End have a length of 1
|
||||||
|
return DecOptionNotEnoughData
|
||||||
|
}
|
||||||
|
o.Type = DHCPOpt(data[0])
|
||||||
|
switch o.Type {
|
||||||
|
case DHCPOptPad, DHCPOptEnd:
|
||||||
|
o.Data = nil
|
||||||
|
default:
|
||||||
|
if len(data) < 2 {
|
||||||
|
return DecOptionNotEnoughData
|
||||||
|
}
|
||||||
|
o.Length = data[1]
|
||||||
|
if int(o.Length) > len(data[2:]) {
|
||||||
|
return DecOptionMalformed
|
||||||
|
}
|
||||||
|
o.Data = data[2 : 2+int(o.Length)]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPv4Error is used for constant errors for DHCPv4. It is needed for test asserts.
|
||||||
|
type DHCPv4Error string
|
||||||
|
|
||||||
|
// DHCPv4Error implements error interface.
|
||||||
|
func (d DHCPv4Error) Error() string {
|
||||||
|
return string(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DecOptionNotEnoughData is returned when there is not enough data during option's decode process
|
||||||
|
DecOptionNotEnoughData = DHCPv4Error("Not enough data to decode")
|
||||||
|
// DecOptionMalformed is returned when the option is malformed
|
||||||
|
DecOptionMalformed = DHCPv4Error("Option is malformed")
|
||||||
|
// InvalidMagicCookie is returned when Magic cookie is missing into BOOTP header
|
||||||
|
InvalidMagicCookie = DHCPv4Error("Bad DHCP header")
|
||||||
|
)
|
360
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dhcpv6.go
generated
vendored
Normal file
360
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dhcpv6.go
generated
vendored
Normal file
|
@ -0,0 +1,360 @@
|
||||||
|
// Copyright 2018 Google, Inc. 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"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DHCPv6MsgType represents a DHCPv6 operation
|
||||||
|
type DHCPv6MsgType byte
|
||||||
|
|
||||||
|
// Constants that represent DHCP operations
|
||||||
|
const (
|
||||||
|
DHCPv6MsgTypeUnspecified DHCPv6MsgType = iota
|
||||||
|
DHCPv6MsgTypeSolicit
|
||||||
|
DHCPv6MsgTypeAdverstise
|
||||||
|
DHCPv6MsgTypeRequest
|
||||||
|
DHCPv6MsgTypeConfirm
|
||||||
|
DHCPv6MsgTypeRenew
|
||||||
|
DHCPv6MsgTypeRebind
|
||||||
|
DHCPv6MsgTypeReply
|
||||||
|
DHCPv6MsgTypeRelease
|
||||||
|
DHCPv6MsgTypeDecline
|
||||||
|
DHCPv6MsgTypeReconfigure
|
||||||
|
DHCPv6MsgTypeInformationRequest
|
||||||
|
DHCPv6MsgTypeRelayForward
|
||||||
|
DHCPv6MsgTypeRelayReply
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of a DHCPv6MsgType.
|
||||||
|
func (o DHCPv6MsgType) String() string {
|
||||||
|
switch o {
|
||||||
|
case DHCPv6MsgTypeUnspecified:
|
||||||
|
return "Unspecified"
|
||||||
|
case DHCPv6MsgTypeSolicit:
|
||||||
|
return "Solicit"
|
||||||
|
case DHCPv6MsgTypeAdverstise:
|
||||||
|
return "Adverstise"
|
||||||
|
case DHCPv6MsgTypeRequest:
|
||||||
|
return "Request"
|
||||||
|
case DHCPv6MsgTypeConfirm:
|
||||||
|
return "Confirm"
|
||||||
|
case DHCPv6MsgTypeRenew:
|
||||||
|
return "Renew"
|
||||||
|
case DHCPv6MsgTypeRebind:
|
||||||
|
return "Rebind"
|
||||||
|
case DHCPv6MsgTypeReply:
|
||||||
|
return "Reply"
|
||||||
|
case DHCPv6MsgTypeRelease:
|
||||||
|
return "Release"
|
||||||
|
case DHCPv6MsgTypeDecline:
|
||||||
|
return "Decline"
|
||||||
|
case DHCPv6MsgTypeReconfigure:
|
||||||
|
return "Reconfigure"
|
||||||
|
case DHCPv6MsgTypeInformationRequest:
|
||||||
|
return "InformationRequest"
|
||||||
|
case DHCPv6MsgTypeRelayForward:
|
||||||
|
return "RelayForward"
|
||||||
|
case DHCPv6MsgTypeRelayReply:
|
||||||
|
return "RelayReply"
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPv6 contains data for a single DHCP packet.
|
||||||
|
type DHCPv6 struct {
|
||||||
|
BaseLayer
|
||||||
|
MsgType DHCPv6MsgType
|
||||||
|
HopCount uint8
|
||||||
|
LinkAddr net.IP
|
||||||
|
PeerAddr net.IP
|
||||||
|
TransactionID []byte
|
||||||
|
Options DHCPv6Options
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeDHCPv6
|
||||||
|
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])
|
||||||
|
offset = 34
|
||||||
|
} else {
|
||||||
|
d.TransactionID = data[1:4]
|
||||||
|
offset = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
stop := len(data)
|
||||||
|
for offset < stop {
|
||||||
|
o := DHCPv6Option{}
|
||||||
|
if err := o.decode(data[offset:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
d.Options = append(d.Options, o)
|
||||||
|
offset += int(o.Length) + 4 // 2 from option code, 2 from option length
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the length of a DHCPv6 packet.
|
||||||
|
func (d *DHCPv6) Len() int {
|
||||||
|
n := 1
|
||||||
|
if d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply {
|
||||||
|
n += 33
|
||||||
|
} else {
|
||||||
|
n += 3
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range d.Options {
|
||||||
|
n += int(o.Length) + 4 // 2 from option code, 2 from option length
|
||||||
|
}
|
||||||
|
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (d *DHCPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
plen := int(d.Len())
|
||||||
|
|
||||||
|
data, err := b.PrependBytes(plen)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := 0
|
||||||
|
data[0] = byte(d.MsgType)
|
||||||
|
if d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply {
|
||||||
|
data[1] = byte(d.HopCount)
|
||||||
|
copy(data[2:18], d.LinkAddr.To16())
|
||||||
|
copy(data[18:34], d.PeerAddr.To16())
|
||||||
|
offset = 34
|
||||||
|
} else {
|
||||||
|
copy(data[1:4], d.TransactionID)
|
||||||
|
offset = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(d.Options) > 0 {
|
||||||
|
for _, o := range d.Options {
|
||||||
|
if err := o.encode(data[offset:], opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
offset += int(o.Length) + 4 // 2 from option code, 2 from option length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (d *DHCPv6) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeDHCPv6
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (d *DHCPv6) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeDHCPv6(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
dhcp := &DHCPv6{}
|
||||||
|
err := dhcp.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(dhcp)
|
||||||
|
return p.NextDecoder(gopacket.LayerTypePayload)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPv6StatusCode represents a DHCP status code - RFC-3315
|
||||||
|
type DHCPv6StatusCode uint16
|
||||||
|
|
||||||
|
// Constants for the DHCPv6StatusCode.
|
||||||
|
const (
|
||||||
|
DHCPv6StatusCodeSuccess DHCPv6StatusCode = iota
|
||||||
|
DHCPv6StatusCodeUnspecFail
|
||||||
|
DHCPv6StatusCodeNoAddrsAvail
|
||||||
|
DHCPv6StatusCodeNoBinding
|
||||||
|
DHCPv6StatusCodeNotOnLink
|
||||||
|
DHCPv6StatusCodeUseMulticast
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of a DHCPv6StatusCode.
|
||||||
|
func (o DHCPv6StatusCode) String() string {
|
||||||
|
switch o {
|
||||||
|
case DHCPv6StatusCodeSuccess:
|
||||||
|
return "Success"
|
||||||
|
case DHCPv6StatusCodeUnspecFail:
|
||||||
|
return "UnspecifiedFailure"
|
||||||
|
case DHCPv6StatusCodeNoAddrsAvail:
|
||||||
|
return "NoAddressAvailable"
|
||||||
|
case DHCPv6StatusCodeNoBinding:
|
||||||
|
return "NoBinding"
|
||||||
|
case DHCPv6StatusCodeNotOnLink:
|
||||||
|
return "NotOnLink"
|
||||||
|
case DHCPv6StatusCodeUseMulticast:
|
||||||
|
return "UseMulticast"
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPv6DUIDType represents a DHCP DUID - RFC-3315
|
||||||
|
type DHCPv6DUIDType uint16
|
||||||
|
|
||||||
|
// Constants for the DHCPv6DUIDType.
|
||||||
|
const (
|
||||||
|
DHCPv6DUIDTypeLLT DHCPv6DUIDType = iota + 1
|
||||||
|
DHCPv6DUIDTypeEN
|
||||||
|
DHCPv6DUIDTypeLL
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of a DHCPv6DUIDType.
|
||||||
|
func (o DHCPv6DUIDType) String() string {
|
||||||
|
switch o {
|
||||||
|
case DHCPv6DUIDTypeLLT:
|
||||||
|
return "LLT"
|
||||||
|
case DHCPv6DUIDTypeEN:
|
||||||
|
return "EN"
|
||||||
|
case DHCPv6DUIDTypeLL:
|
||||||
|
return "LL"
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPv6DUID means DHCP Unique Identifier as stated in RFC 3315, section 9 (https://tools.ietf.org/html/rfc3315#page-19)
|
||||||
|
type DHCPv6DUID struct {
|
||||||
|
Type DHCPv6DUIDType
|
||||||
|
// LLT, LL
|
||||||
|
HardwareType []byte
|
||||||
|
// EN
|
||||||
|
EnterpriseNumber []byte
|
||||||
|
// LLT
|
||||||
|
Time []byte
|
||||||
|
// LLT, LL
|
||||||
|
LinkLayerAddress net.HardwareAddr
|
||||||
|
// EN
|
||||||
|
Identifier []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into a DHCPv6DUID
|
||||||
|
func (d *DHCPv6DUID) DecodeFromBytes(data []byte) error {
|
||||||
|
if len(data) < 2 {
|
||||||
|
return fmt.Errorf("Not enough bytes to decode: %d", len(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Type = DHCPv6DUIDType(binary.BigEndian.Uint16(data[:2]))
|
||||||
|
if d.Type == DHCPv6DUIDTypeLLT || d.Type == DHCPv6DUIDTypeLL {
|
||||||
|
if len(data) < 4 {
|
||||||
|
return fmt.Errorf("Not enough bytes to decode: %d", len(data))
|
||||||
|
}
|
||||||
|
d.HardwareType = data[2:4]
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Type == DHCPv6DUIDTypeLLT {
|
||||||
|
if len(data) < 8 {
|
||||||
|
return fmt.Errorf("Not enough bytes to decode: %d", len(data))
|
||||||
|
}
|
||||||
|
d.Time = data[4:8]
|
||||||
|
d.LinkLayerAddress = net.HardwareAddr(data[8:])
|
||||||
|
} else if d.Type == DHCPv6DUIDTypeEN {
|
||||||
|
if len(data) < 6 {
|
||||||
|
return fmt.Errorf("Not enough bytes to decode: %d", len(data))
|
||||||
|
}
|
||||||
|
d.EnterpriseNumber = data[2:6]
|
||||||
|
d.Identifier = data[6:]
|
||||||
|
} else { // DHCPv6DUIDTypeLL
|
||||||
|
if len(data) < 4 {
|
||||||
|
return fmt.Errorf("Not enough bytes to decode: %d", len(data))
|
||||||
|
}
|
||||||
|
d.LinkLayerAddress = net.HardwareAddr(data[4:])
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode encodes the DHCPv6DUID in a slice of bytes
|
||||||
|
func (d *DHCPv6DUID) Encode() []byte {
|
||||||
|
length := d.Len()
|
||||||
|
data := make([]byte, length)
|
||||||
|
binary.BigEndian.PutUint16(data[0:2], uint16(d.Type))
|
||||||
|
|
||||||
|
if d.Type == DHCPv6DUIDTypeLLT || d.Type == DHCPv6DUIDTypeLL {
|
||||||
|
copy(data[2:4], d.HardwareType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Type == DHCPv6DUIDTypeLLT {
|
||||||
|
copy(data[4:8], d.Time)
|
||||||
|
copy(data[8:], d.LinkLayerAddress)
|
||||||
|
} else if d.Type == DHCPv6DUIDTypeEN {
|
||||||
|
copy(data[2:6], d.EnterpriseNumber)
|
||||||
|
copy(data[6:], d.Identifier)
|
||||||
|
} else {
|
||||||
|
copy(data[4:], d.LinkLayerAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the length of the DHCPv6DUID, respecting the type
|
||||||
|
func (d *DHCPv6DUID) Len() int {
|
||||||
|
length := 2 // d.Type
|
||||||
|
if d.Type == DHCPv6DUIDTypeLLT {
|
||||||
|
length += 2 /*HardwareType*/ + 4 /*d.Time*/ + len(d.LinkLayerAddress)
|
||||||
|
} else if d.Type == DHCPv6DUIDTypeEN {
|
||||||
|
length += 4 /*d.EnterpriseNumber*/ + len(d.Identifier)
|
||||||
|
} else { // LL
|
||||||
|
length += 2 /*d.HardwareType*/ + len(d.LinkLayerAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
return length
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DHCPv6DUID) String() string {
|
||||||
|
duid := "Type: " + d.Type.String() + ", "
|
||||||
|
if d.Type == DHCPv6DUIDTypeLLT {
|
||||||
|
duid += fmt.Sprintf("HardwareType: %v, Time: %v, LinkLayerAddress: %v", d.HardwareType, d.Time, d.LinkLayerAddress)
|
||||||
|
} else if d.Type == DHCPv6DUIDTypeEN {
|
||||||
|
duid += fmt.Sprintf("EnterpriseNumber: %v, Identifier: %v", d.EnterpriseNumber, d.Identifier)
|
||||||
|
} else { // DHCPv6DUIDTypeLL
|
||||||
|
duid += fmt.Sprintf("HardwareType: %v, LinkLayerAddress: %v", d.HardwareType, d.LinkLayerAddress)
|
||||||
|
}
|
||||||
|
return duid
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeDHCPv6DUID(data []byte) (*DHCPv6DUID, error) {
|
||||||
|
duid := &DHCPv6DUID{}
|
||||||
|
err := duid.DecodeFromBytes(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return duid, nil
|
||||||
|
}
|
621
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dhcpv6_options.go
generated
vendored
Normal file
621
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dhcpv6_options.go
generated
vendored
Normal file
|
@ -0,0 +1,621 @@
|
||||||
|
// Copyright 2018 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 (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DHCPv6Opt represents a DHCP option or parameter from RFC-3315
|
||||||
|
type DHCPv6Opt uint16
|
||||||
|
|
||||||
|
// Constants for the DHCPv6Opt options.
|
||||||
|
const (
|
||||||
|
DHCPv6OptClientID DHCPv6Opt = 1
|
||||||
|
DHCPv6OptServerID DHCPv6Opt = 2
|
||||||
|
DHCPv6OptIANA DHCPv6Opt = 3
|
||||||
|
DHCPv6OptIATA DHCPv6Opt = 4
|
||||||
|
DHCPv6OptIAAddr DHCPv6Opt = 5
|
||||||
|
DHCPv6OptOro DHCPv6Opt = 6
|
||||||
|
DHCPv6OptPreference DHCPv6Opt = 7
|
||||||
|
DHCPv6OptElapsedTime DHCPv6Opt = 8
|
||||||
|
DHCPv6OptRelayMessage DHCPv6Opt = 9
|
||||||
|
DHCPv6OptAuth DHCPv6Opt = 11
|
||||||
|
DHCPv6OptUnicast DHCPv6Opt = 12
|
||||||
|
DHCPv6OptStatusCode DHCPv6Opt = 13
|
||||||
|
DHCPv6OptRapidCommit DHCPv6Opt = 14
|
||||||
|
DHCPv6OptUserClass DHCPv6Opt = 15
|
||||||
|
DHCPv6OptVendorClass DHCPv6Opt = 16
|
||||||
|
DHCPv6OptVendorOpts DHCPv6Opt = 17
|
||||||
|
DHCPv6OptInterfaceID DHCPv6Opt = 18
|
||||||
|
DHCPv6OptReconfigureMessage DHCPv6Opt = 19
|
||||||
|
DHCPv6OptReconfigureAccept DHCPv6Opt = 20
|
||||||
|
|
||||||
|
// RFC 3319 Session Initiation Protocol (SIP)
|
||||||
|
DHCPv6OptSIPServersDomainList DHCPv6Opt = 21
|
||||||
|
DHCPv6OptSIPServersAddressList DHCPv6Opt = 22
|
||||||
|
|
||||||
|
// RFC 3646 DNS Configuration
|
||||||
|
DHCPv6OptDNSServers DHCPv6Opt = 23
|
||||||
|
DHCPv6OptDomainList DHCPv6Opt = 24
|
||||||
|
|
||||||
|
// RFC 3633 Prefix Delegation
|
||||||
|
DHCPv6OptIAPD DHCPv6Opt = 25
|
||||||
|
DHCPv6OptIAPrefix DHCPv6Opt = 26
|
||||||
|
|
||||||
|
// RFC 3898 Network Information Service (NIS)
|
||||||
|
DHCPv6OptNISServers DHCPv6Opt = 27
|
||||||
|
DHCPv6OptNISPServers DHCPv6Opt = 28
|
||||||
|
DHCPv6OptNISDomainName DHCPv6Opt = 29
|
||||||
|
DHCPv6OptNISPDomainName DHCPv6Opt = 30
|
||||||
|
|
||||||
|
// RFC 4075 Simple Network Time Protocol (SNTP)
|
||||||
|
DHCPv6OptSNTPServers DHCPv6Opt = 31
|
||||||
|
|
||||||
|
// RFC 4242 Information Refresh Time Option
|
||||||
|
DHCPv6OptInformationRefreshTime DHCPv6Opt = 32
|
||||||
|
|
||||||
|
// RFC 4280 Broadcast and Multicast Control Servers
|
||||||
|
DHCPv6OptBCMCSServerDomainNameList DHCPv6Opt = 33
|
||||||
|
DHCPv6OptBCMCSServerAddressList DHCPv6Opt = 34
|
||||||
|
|
||||||
|
// RFC 4776 Civic Address ConfigurationOption
|
||||||
|
DHCPv6OptGeoconfCivic DHCPv6Opt = 36
|
||||||
|
|
||||||
|
// RFC 4649 Relay Agent Remote-ID
|
||||||
|
DHCPv6OptRemoteID DHCPv6Opt = 37
|
||||||
|
|
||||||
|
// RFC 4580 Relay Agent Subscriber-ID
|
||||||
|
DHCPv6OptSubscriberID DHCPv6Opt = 38
|
||||||
|
|
||||||
|
// RFC 4704 Client Full Qualified Domain Name (FQDN)
|
||||||
|
DHCPv6OptClientFQDN DHCPv6Opt = 39
|
||||||
|
|
||||||
|
// RFC 5192 Protocol for Carrying Authentication for Network Access (PANA)
|
||||||
|
DHCPv6OptPanaAgent DHCPv6Opt = 40
|
||||||
|
|
||||||
|
// RFC 4833 Timezone Options
|
||||||
|
DHCPv6OptNewPOSIXTimezone DHCPv6Opt = 41
|
||||||
|
DHCPv6OptNewTZDBTimezone DHCPv6Opt = 42
|
||||||
|
|
||||||
|
// RFC 4994 Relay Agent Echo Request
|
||||||
|
DHCPv6OptEchoRequestOption DHCPv6Opt = 43
|
||||||
|
|
||||||
|
// RFC 5007 Leasequery
|
||||||
|
DHCPv6OptLQQuery DHCPv6Opt = 44
|
||||||
|
DHCPv6OptCLTTime DHCPv6Opt = 45
|
||||||
|
DHCPv6OptClientData DHCPv6Opt = 46
|
||||||
|
DHCPv6OptLQRelayData DHCPv6Opt = 47
|
||||||
|
DHCPv6OptLQClientLink DHCPv6Opt = 48
|
||||||
|
|
||||||
|
// RFC 6610 Home Information Discovery in Mobile IPv6 (MIPv6)
|
||||||
|
DHCPv6OptMIP6HNIDF DHCPv6Opt = 49
|
||||||
|
DHCPv6OptMIP6VDINF DHCPv6Opt = 50
|
||||||
|
DHCPv6OptMIP6IDINF DHCPv6Opt = 69
|
||||||
|
DHCPv6OptMIP6UDINF DHCPv6Opt = 70
|
||||||
|
DHCPv6OptMIP6HNP DHCPv6Opt = 71
|
||||||
|
DHCPv6OptMIP6HAA DHCPv6Opt = 72
|
||||||
|
DHCPv6OptMIP6HAF DHCPv6Opt = 73
|
||||||
|
|
||||||
|
// RFC 5223 Discovering Location-to-Service Translation (LoST) Servers
|
||||||
|
DHCPv6OptV6LOST DHCPv6Opt = 51
|
||||||
|
|
||||||
|
// RFC 5417 Control And Provisioning of Wireless Access Points (CAPWAP)
|
||||||
|
DHCPv6OptCAPWAPACV6 DHCPv6Opt = 52
|
||||||
|
|
||||||
|
// RFC 5460 Bulk Leasequery
|
||||||
|
DHCPv6OptRelayID DHCPv6Opt = 53
|
||||||
|
|
||||||
|
// RFC 5678 IEEE 802.21 Mobility Services (MoS) Discovery
|
||||||
|
DHCPv6OptIPv6AddressMoS DHCPv6Opt = 54
|
||||||
|
DHCPv6OptIPv6FQDNMoS DHCPv6Opt = 55
|
||||||
|
|
||||||
|
// RFC 5908 NTP Server Option
|
||||||
|
DHCPv6OptNTPServer DHCPv6Opt = 56
|
||||||
|
|
||||||
|
// RFC 5986 Discovering the Local Location Information Server (LIS)
|
||||||
|
DHCPv6OptV6AccessDomain DHCPv6Opt = 57
|
||||||
|
|
||||||
|
// RFC 5986 SIP User Agent
|
||||||
|
DHCPv6OptSIPUACSList DHCPv6Opt = 58
|
||||||
|
|
||||||
|
// RFC 5970 Options for Network Boot
|
||||||
|
DHCPv6OptBootFileURL DHCPv6Opt = 59
|
||||||
|
DHCPv6OptBootFileParam DHCPv6Opt = 60
|
||||||
|
DHCPv6OptClientArchType DHCPv6Opt = 61
|
||||||
|
DHCPv6OptNII DHCPv6Opt = 62
|
||||||
|
|
||||||
|
// RFC 6225 Coordinate-Based Location Configuration Information
|
||||||
|
DHCPv6OptGeolocation DHCPv6Opt = 63
|
||||||
|
|
||||||
|
// RFC 6334 Dual-Stack Lite
|
||||||
|
DHCPv6OptAFTRName DHCPv6Opt = 64
|
||||||
|
|
||||||
|
// RFC 6440 EAP Re-authentication Protocol (ERP)
|
||||||
|
DHCPv6OptERPLocalDomainName DHCPv6Opt = 65
|
||||||
|
|
||||||
|
// RFC 6422 Relay-Supplied DHCP Options
|
||||||
|
DHCPv6OptRSOO DHCPv6Opt = 66
|
||||||
|
|
||||||
|
// RFC 6603 Prefix Exclude Option for DHCPv6-based Prefix Delegation
|
||||||
|
DHCPv6OptPDExclude DHCPv6Opt = 67
|
||||||
|
|
||||||
|
// RFC 6607 Virtual Subnet Selection
|
||||||
|
DHCPv6OptVSS DHCPv6Opt = 68
|
||||||
|
|
||||||
|
// RFC 6731 Improved Recursive DNS Server Selection for Multi-Interfaced Nodes
|
||||||
|
DHCPv6OptRDNSSSelection DHCPv6Opt = 74
|
||||||
|
|
||||||
|
// RFC 6784 Kerberos Options for DHCPv6
|
||||||
|
DHCPv6OptKRBPrincipalName DHCPv6Opt = 75
|
||||||
|
DHCPv6OptKRBRealmName DHCPv6Opt = 76
|
||||||
|
DHCPv6OptKRBKDC DHCPv6Opt = 77
|
||||||
|
|
||||||
|
// RFC 6939 Client Link-Layer Address Option
|
||||||
|
DHCPv6OptClientLinkLayerAddress DHCPv6Opt = 79
|
||||||
|
|
||||||
|
// RFC 6977 Triggering DHCPv6 Reconfiguration from Relay Agents
|
||||||
|
DHCPv6OptLinkAddress DHCPv6Opt = 80
|
||||||
|
|
||||||
|
// RFC 7037 RADIUS Option for the DHCPv6 Relay Agent
|
||||||
|
DHCPv6OptRADIUS DHCPv6Opt = 81
|
||||||
|
|
||||||
|
// RFC 7083 Modification to Default Values of SOL_MAX_RT and INF_MAX_RT
|
||||||
|
DHCPv6OptSolMaxRt DHCPv6Opt = 82
|
||||||
|
DHCPv6OptInfMaxRt DHCPv6Opt = 83
|
||||||
|
|
||||||
|
// RFC 7078 Distributing Address Selection Policy
|
||||||
|
DHCPv6OptAddrSel DHCPv6Opt = 84
|
||||||
|
DHCPv6OptAddrSelTable DHCPv6Opt = 85
|
||||||
|
|
||||||
|
// RFC 7291 DHCP Options for the Port Control Protocol (PCP)
|
||||||
|
DHCPv6OptV6PCPServer DHCPv6Opt = 86
|
||||||
|
|
||||||
|
// RFC 7341 DHCPv4-over-DHCPv6 (DHCP 4o6) Transport
|
||||||
|
DHCPv6OptDHCPv4Message DHCPv6Opt = 87
|
||||||
|
DHCPv6OptDHCPv4OverDHCPv6Server DHCPv6Opt = 88
|
||||||
|
|
||||||
|
// RFC 7598 Configuration of Softwire Address and Port-Mapped Clients
|
||||||
|
DHCPv6OptS46Rule DHCPv6Opt = 89
|
||||||
|
DHCPv6OptS46BR DHCPv6Opt = 90
|
||||||
|
DHCPv6OptS46DMR DHCPv6Opt = 91
|
||||||
|
DHCPv6OptS46V4V4Bind DHCPv6Opt = 92
|
||||||
|
DHCPv6OptS46PortParameters DHCPv6Opt = 93
|
||||||
|
DHCPv6OptS46ContMAPE DHCPv6Opt = 94
|
||||||
|
DHCPv6OptS46ContMAPT DHCPv6Opt = 95
|
||||||
|
DHCPv6OptS46ContLW DHCPv6Opt = 96
|
||||||
|
|
||||||
|
// RFC 7600 IPv4 Residual Deployment via IPv6
|
||||||
|
DHCPv6Opt4RD DHCPv6Opt = 97
|
||||||
|
DHCPv6Opt4RDMapRule DHCPv6Opt = 98
|
||||||
|
DHCPv6Opt4RDNonMapRule DHCPv6Opt = 99
|
||||||
|
|
||||||
|
// RFC 7653 Active Leasequery
|
||||||
|
DHCPv6OptLQBaseTime DHCPv6Opt = 100
|
||||||
|
DHCPv6OptLQStartTime DHCPv6Opt = 101
|
||||||
|
DHCPv6OptLQEndTime DHCPv6Opt = 102
|
||||||
|
|
||||||
|
// RFC 7710 Captive-Portal Identification
|
||||||
|
DHCPv6OptCaptivePortal DHCPv6Opt = 103
|
||||||
|
|
||||||
|
// RFC 7774 Multicast Protocol for Low-Power and Lossy Networks (MPL) Parameter Configuration
|
||||||
|
DHCPv6OptMPLParameters DHCPv6Opt = 104
|
||||||
|
|
||||||
|
// RFC 7839 Access-Network-Identifier (ANI)
|
||||||
|
DHCPv6OptANIATT DHCPv6Opt = 105
|
||||||
|
DHCPv6OptANINetworkName DHCPv6Opt = 106
|
||||||
|
DHCPv6OptANIAPName DHCPv6Opt = 107
|
||||||
|
DHCPv6OptANIAPBSSID DHCPv6Opt = 108
|
||||||
|
DHCPv6OptANIOperatorID DHCPv6Opt = 109
|
||||||
|
DHCPv6OptANIOperatorRealm DHCPv6Opt = 110
|
||||||
|
|
||||||
|
// RFC 8026 Unified IPv4-in-IPv6 Softwire Customer Premises Equipment (CPE)
|
||||||
|
DHCPv6OptS46Priority DHCPv6Opt = 111
|
||||||
|
|
||||||
|
// draft-ietf-opsawg-mud-25 Manufacturer Usage Description (MUD)
|
||||||
|
DHCPv6OptMUDURLV6 DHCPv6Opt = 112
|
||||||
|
|
||||||
|
// RFC 8115 IPv4-Embedded Multicast and Unicast IPv6 Prefixes
|
||||||
|
DHCPv6OptV6Prefix64 DHCPv6Opt = 113
|
||||||
|
|
||||||
|
// RFC 8156 DHCPv6 Failover Protocol
|
||||||
|
DHCPv6OptFBindingStatus DHCPv6Opt = 114
|
||||||
|
DHCPv6OptFConnectFlags DHCPv6Opt = 115
|
||||||
|
DHCPv6OptFDNSRemovalInfo DHCPv6Opt = 116
|
||||||
|
DHCPv6OptFDNSHostName DHCPv6Opt = 117
|
||||||
|
DHCPv6OptFDNSZoneName DHCPv6Opt = 118
|
||||||
|
DHCPv6OptFDNSFlags DHCPv6Opt = 119
|
||||||
|
DHCPv6OptFExpirationTime DHCPv6Opt = 120
|
||||||
|
DHCPv6OptFMaxUnacknowledgedBNDUPD DHCPv6Opt = 121
|
||||||
|
DHCPv6OptFMCLT DHCPv6Opt = 122
|
||||||
|
DHCPv6OptFPartnerLifetime DHCPv6Opt = 123
|
||||||
|
DHCPv6OptFPartnerLifetimeSent DHCPv6Opt = 124
|
||||||
|
DHCPv6OptFPartnerDownTime DHCPv6Opt = 125
|
||||||
|
DHCPv6OptFPartnerRawCltTime DHCPv6Opt = 126
|
||||||
|
DHCPv6OptFProtocolVersion DHCPv6Opt = 127
|
||||||
|
DHCPv6OptFKeepaliveTime DHCPv6Opt = 128
|
||||||
|
DHCPv6OptFReconfigureData DHCPv6Opt = 129
|
||||||
|
DHCPv6OptFRelationshipName DHCPv6Opt = 130
|
||||||
|
DHCPv6OptFServerFlags DHCPv6Opt = 131
|
||||||
|
DHCPv6OptFServerState DHCPv6Opt = 132
|
||||||
|
DHCPv6OptFStartTimeOfState DHCPv6Opt = 133
|
||||||
|
DHCPv6OptFStateExpirationTime DHCPv6Opt = 134
|
||||||
|
|
||||||
|
// RFC 8357 Generalized UDP Source Port for DHCP Relay
|
||||||
|
DHCPv6OptRelayPort DHCPv6Opt = 135
|
||||||
|
|
||||||
|
// draft-ietf-netconf-zerotouch-25 Zero Touch Provisioning for Networking Devices
|
||||||
|
DHCPv6OptV6ZeroTouchRedirect DHCPv6Opt = 136
|
||||||
|
|
||||||
|
// RFC 6153 Access Network Discovery and Selection Function (ANDSF) Discovery
|
||||||
|
DHCPv6OptIPV6AddressANDSF DHCPv6Opt = 143
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of a DHCPv6Opt.
|
||||||
|
func (o DHCPv6Opt) String() string {
|
||||||
|
switch o {
|
||||||
|
case DHCPv6OptClientID:
|
||||||
|
return "ClientID"
|
||||||
|
case DHCPv6OptServerID:
|
||||||
|
return "ServerID"
|
||||||
|
case DHCPv6OptIANA:
|
||||||
|
return "IA_NA"
|
||||||
|
case DHCPv6OptIATA:
|
||||||
|
return "IA_TA"
|
||||||
|
case DHCPv6OptIAAddr:
|
||||||
|
return "IAAddr"
|
||||||
|
case DHCPv6OptOro:
|
||||||
|
return "Oro"
|
||||||
|
case DHCPv6OptPreference:
|
||||||
|
return "Preference"
|
||||||
|
case DHCPv6OptElapsedTime:
|
||||||
|
return "ElapsedTime"
|
||||||
|
case DHCPv6OptRelayMessage:
|
||||||
|
return "RelayMessage"
|
||||||
|
case DHCPv6OptAuth:
|
||||||
|
return "Auth"
|
||||||
|
case DHCPv6OptUnicast:
|
||||||
|
return "Unicast"
|
||||||
|
case DHCPv6OptStatusCode:
|
||||||
|
return "StatusCode"
|
||||||
|
case DHCPv6OptRapidCommit:
|
||||||
|
return "RapidCommit"
|
||||||
|
case DHCPv6OptUserClass:
|
||||||
|
return "UserClass"
|
||||||
|
case DHCPv6OptVendorClass:
|
||||||
|
return "VendorClass"
|
||||||
|
case DHCPv6OptVendorOpts:
|
||||||
|
return "VendorOpts"
|
||||||
|
case DHCPv6OptInterfaceID:
|
||||||
|
return "InterfaceID"
|
||||||
|
case DHCPv6OptReconfigureMessage:
|
||||||
|
return "ReconfigureMessage"
|
||||||
|
case DHCPv6OptReconfigureAccept:
|
||||||
|
return "ReconfigureAccept"
|
||||||
|
case DHCPv6OptSIPServersDomainList:
|
||||||
|
return "SIPServersDomainList"
|
||||||
|
case DHCPv6OptSIPServersAddressList:
|
||||||
|
return "SIPServersAddressList"
|
||||||
|
case DHCPv6OptDNSServers:
|
||||||
|
return "DNSRecursiveNameServer"
|
||||||
|
case DHCPv6OptDomainList:
|
||||||
|
return "DomainSearchList"
|
||||||
|
case DHCPv6OptIAPD:
|
||||||
|
return "IdentityAssociationPrefixDelegation"
|
||||||
|
case DHCPv6OptIAPrefix:
|
||||||
|
return "IAPDPrefix"
|
||||||
|
case DHCPv6OptNISServers:
|
||||||
|
return "NISServers"
|
||||||
|
case DHCPv6OptNISPServers:
|
||||||
|
return "NISv2Servers"
|
||||||
|
case DHCPv6OptNISDomainName:
|
||||||
|
return "NISDomainName"
|
||||||
|
case DHCPv6OptNISPDomainName:
|
||||||
|
return "NISv2DomainName"
|
||||||
|
case DHCPv6OptSNTPServers:
|
||||||
|
return "SNTPServers"
|
||||||
|
case DHCPv6OptInformationRefreshTime:
|
||||||
|
return "InformationRefreshTime"
|
||||||
|
case DHCPv6OptBCMCSServerDomainNameList:
|
||||||
|
return "BCMCSControlServersDomainNameList"
|
||||||
|
case DHCPv6OptBCMCSServerAddressList:
|
||||||
|
return "BCMCSControlServersAddressList"
|
||||||
|
case DHCPv6OptGeoconfCivic:
|
||||||
|
return "CivicAddress"
|
||||||
|
case DHCPv6OptRemoteID:
|
||||||
|
return "RelayAgentRemoteID"
|
||||||
|
case DHCPv6OptSubscriberID:
|
||||||
|
return "RelayAgentSubscriberID"
|
||||||
|
case DHCPv6OptClientFQDN:
|
||||||
|
return "ClientFQDN"
|
||||||
|
case DHCPv6OptPanaAgent:
|
||||||
|
return "PANAAuthenticationAgent"
|
||||||
|
case DHCPv6OptNewPOSIXTimezone:
|
||||||
|
return "NewPOSIXTimezone"
|
||||||
|
case DHCPv6OptNewTZDBTimezone:
|
||||||
|
return "NewTZDBTimezone"
|
||||||
|
case DHCPv6OptEchoRequestOption:
|
||||||
|
return "EchoRequest"
|
||||||
|
case DHCPv6OptLQQuery:
|
||||||
|
return "LeasequeryQuery"
|
||||||
|
case DHCPv6OptClientData:
|
||||||
|
return "LeasequeryClientData"
|
||||||
|
case DHCPv6OptCLTTime:
|
||||||
|
return "LeasequeryClientLastTransactionTime"
|
||||||
|
case DHCPv6OptLQRelayData:
|
||||||
|
return "LeasequeryRelayData"
|
||||||
|
case DHCPv6OptLQClientLink:
|
||||||
|
return "LeasequeryClientLink"
|
||||||
|
case DHCPv6OptMIP6HNIDF:
|
||||||
|
return "MIPv6HomeNetworkIDFQDN"
|
||||||
|
case DHCPv6OptMIP6VDINF:
|
||||||
|
return "MIPv6VisitedHomeNetworkInformation"
|
||||||
|
case DHCPv6OptMIP6IDINF:
|
||||||
|
return "MIPv6IdentifiedHomeNetworkInformation"
|
||||||
|
case DHCPv6OptMIP6UDINF:
|
||||||
|
return "MIPv6UnrestrictedHomeNetworkInformation"
|
||||||
|
case DHCPv6OptMIP6HNP:
|
||||||
|
return "MIPv6HomeNetworkPrefix"
|
||||||
|
case DHCPv6OptMIP6HAA:
|
||||||
|
return "MIPv6HomeAgentAddress"
|
||||||
|
case DHCPv6OptMIP6HAF:
|
||||||
|
return "MIPv6HomeAgentFQDN"
|
||||||
|
case DHCPv6OptV6LOST:
|
||||||
|
return "LoST Server"
|
||||||
|
case DHCPv6OptCAPWAPACV6:
|
||||||
|
return "CAPWAPAccessControllerV6"
|
||||||
|
case DHCPv6OptRelayID:
|
||||||
|
return "LeasequeryRelayID"
|
||||||
|
case DHCPv6OptIPv6AddressMoS:
|
||||||
|
return "MoSIPv6Address"
|
||||||
|
case DHCPv6OptIPv6FQDNMoS:
|
||||||
|
return "MoSDomainNameList"
|
||||||
|
case DHCPv6OptNTPServer:
|
||||||
|
return "NTPServer"
|
||||||
|
case DHCPv6OptV6AccessDomain:
|
||||||
|
return "AccessNetworkDomainName"
|
||||||
|
case DHCPv6OptSIPUACSList:
|
||||||
|
return "SIPUserAgentConfigurationServiceDomains"
|
||||||
|
case DHCPv6OptBootFileURL:
|
||||||
|
return "BootFileURL"
|
||||||
|
case DHCPv6OptBootFileParam:
|
||||||
|
return "BootFileParameters"
|
||||||
|
case DHCPv6OptClientArchType:
|
||||||
|
return "ClientSystemArchitectureType"
|
||||||
|
case DHCPv6OptNII:
|
||||||
|
return "ClientNetworkInterfaceIdentifier"
|
||||||
|
case DHCPv6OptGeolocation:
|
||||||
|
return "Geolocation"
|
||||||
|
case DHCPv6OptAFTRName:
|
||||||
|
return "AFTRName"
|
||||||
|
case DHCPv6OptERPLocalDomainName:
|
||||||
|
return "AFTRName"
|
||||||
|
case DHCPv6OptRSOO:
|
||||||
|
return "RSOOption"
|
||||||
|
case DHCPv6OptPDExclude:
|
||||||
|
return "PrefixExclude"
|
||||||
|
case DHCPv6OptVSS:
|
||||||
|
return "VirtualSubnetSelection"
|
||||||
|
case DHCPv6OptRDNSSSelection:
|
||||||
|
return "RDNSSSelection"
|
||||||
|
case DHCPv6OptKRBPrincipalName:
|
||||||
|
return "KerberosPrincipalName"
|
||||||
|
case DHCPv6OptKRBRealmName:
|
||||||
|
return "KerberosRealmName"
|
||||||
|
case DHCPv6OptKRBKDC:
|
||||||
|
return "KerberosKDC"
|
||||||
|
case DHCPv6OptClientLinkLayerAddress:
|
||||||
|
return "ClientLinkLayerAddress"
|
||||||
|
case DHCPv6OptLinkAddress:
|
||||||
|
return "LinkAddress"
|
||||||
|
case DHCPv6OptRADIUS:
|
||||||
|
return "RADIUS"
|
||||||
|
case DHCPv6OptSolMaxRt:
|
||||||
|
return "SolMaxRt"
|
||||||
|
case DHCPv6OptInfMaxRt:
|
||||||
|
return "InfMaxRt"
|
||||||
|
case DHCPv6OptAddrSel:
|
||||||
|
return "AddressSelection"
|
||||||
|
case DHCPv6OptAddrSelTable:
|
||||||
|
return "AddressSelectionTable"
|
||||||
|
case DHCPv6OptV6PCPServer:
|
||||||
|
return "PCPServer"
|
||||||
|
case DHCPv6OptDHCPv4Message:
|
||||||
|
return "DHCPv4Message"
|
||||||
|
case DHCPv6OptDHCPv4OverDHCPv6Server:
|
||||||
|
return "DHCP4o6ServerAddress"
|
||||||
|
case DHCPv6OptS46Rule:
|
||||||
|
return "S46Rule"
|
||||||
|
case DHCPv6OptS46BR:
|
||||||
|
return "S46BR"
|
||||||
|
case DHCPv6OptS46DMR:
|
||||||
|
return "S46DMR"
|
||||||
|
case DHCPv6OptS46V4V4Bind:
|
||||||
|
return "S46IPv4IPv6AddressBinding"
|
||||||
|
case DHCPv6OptS46PortParameters:
|
||||||
|
return "S46PortParameters"
|
||||||
|
case DHCPv6OptS46ContMAPE:
|
||||||
|
return "S46MAPEContainer"
|
||||||
|
case DHCPv6OptS46ContMAPT:
|
||||||
|
return "S46MAPTContainer"
|
||||||
|
case DHCPv6OptS46ContLW:
|
||||||
|
return "S46Lightweight4Over6Container"
|
||||||
|
case DHCPv6Opt4RD:
|
||||||
|
return "4RD"
|
||||||
|
case DHCPv6Opt4RDMapRule:
|
||||||
|
return "4RDMapRule"
|
||||||
|
case DHCPv6Opt4RDNonMapRule:
|
||||||
|
return "4RDNonMapRule"
|
||||||
|
case DHCPv6OptLQBaseTime:
|
||||||
|
return "LQBaseTime"
|
||||||
|
case DHCPv6OptLQStartTime:
|
||||||
|
return "LQStartTime"
|
||||||
|
case DHCPv6OptLQEndTime:
|
||||||
|
return "LQEndTime"
|
||||||
|
case DHCPv6OptCaptivePortal:
|
||||||
|
return "CaptivePortal"
|
||||||
|
case DHCPv6OptMPLParameters:
|
||||||
|
return "MPLParameterConfiguration"
|
||||||
|
case DHCPv6OptANIATT:
|
||||||
|
return "ANIAccessTechnologyType"
|
||||||
|
case DHCPv6OptANINetworkName:
|
||||||
|
return "ANINetworkName"
|
||||||
|
case DHCPv6OptANIAPName:
|
||||||
|
return "ANIAccessPointName"
|
||||||
|
case DHCPv6OptANIAPBSSID:
|
||||||
|
return "ANIAccessPointBSSID"
|
||||||
|
case DHCPv6OptANIOperatorID:
|
||||||
|
return "ANIOperatorIdentifier"
|
||||||
|
case DHCPv6OptANIOperatorRealm:
|
||||||
|
return "ANIOperatorRealm"
|
||||||
|
case DHCPv6OptS46Priority:
|
||||||
|
return "S64Priority"
|
||||||
|
case DHCPv6OptMUDURLV6:
|
||||||
|
return "ManufacturerUsageDescriptionURL"
|
||||||
|
case DHCPv6OptV6Prefix64:
|
||||||
|
return "V6Prefix64"
|
||||||
|
case DHCPv6OptFBindingStatus:
|
||||||
|
return "FailoverBindingStatus"
|
||||||
|
case DHCPv6OptFConnectFlags:
|
||||||
|
return "FailoverConnectFlags"
|
||||||
|
case DHCPv6OptFDNSRemovalInfo:
|
||||||
|
return "FailoverDNSRemovalInfo"
|
||||||
|
case DHCPv6OptFDNSHostName:
|
||||||
|
return "FailoverDNSHostName"
|
||||||
|
case DHCPv6OptFDNSZoneName:
|
||||||
|
return "FailoverDNSZoneName"
|
||||||
|
case DHCPv6OptFDNSFlags:
|
||||||
|
return "FailoverDNSFlags"
|
||||||
|
case DHCPv6OptFExpirationTime:
|
||||||
|
return "FailoverExpirationTime"
|
||||||
|
case DHCPv6OptFMaxUnacknowledgedBNDUPD:
|
||||||
|
return "FailoverMaxUnacknowledgedBNDUPDMessages"
|
||||||
|
case DHCPv6OptFMCLT:
|
||||||
|
return "FailoverMaximumClientLeadTime"
|
||||||
|
case DHCPv6OptFPartnerLifetime:
|
||||||
|
return "FailoverPartnerLifetime"
|
||||||
|
case DHCPv6OptFPartnerLifetimeSent:
|
||||||
|
return "FailoverPartnerLifetimeSent"
|
||||||
|
case DHCPv6OptFPartnerDownTime:
|
||||||
|
return "FailoverPartnerDownTime"
|
||||||
|
case DHCPv6OptFPartnerRawCltTime:
|
||||||
|
return "FailoverPartnerRawClientLeadTime"
|
||||||
|
case DHCPv6OptFProtocolVersion:
|
||||||
|
return "FailoverProtocolVersion"
|
||||||
|
case DHCPv6OptFKeepaliveTime:
|
||||||
|
return "FailoverKeepaliveTime"
|
||||||
|
case DHCPv6OptFReconfigureData:
|
||||||
|
return "FailoverReconfigureData"
|
||||||
|
case DHCPv6OptFRelationshipName:
|
||||||
|
return "FailoverRelationshipName"
|
||||||
|
case DHCPv6OptFServerFlags:
|
||||||
|
return "FailoverServerFlags"
|
||||||
|
case DHCPv6OptFServerState:
|
||||||
|
return "FailoverServerState"
|
||||||
|
case DHCPv6OptFStartTimeOfState:
|
||||||
|
return "FailoverStartTimeOfState"
|
||||||
|
case DHCPv6OptFStateExpirationTime:
|
||||||
|
return "FailoverStateExpirationTime"
|
||||||
|
case DHCPv6OptRelayPort:
|
||||||
|
return "RelayPort"
|
||||||
|
case DHCPv6OptV6ZeroTouchRedirect:
|
||||||
|
return "ZeroTouch"
|
||||||
|
case DHCPv6OptIPV6AddressANDSF:
|
||||||
|
return "ANDSFIPv6Address"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("Unknown(%d)", uint16(o))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPv6Options is used to get nicely printed option lists which would normally
|
||||||
|
// be cut off after 5 options.
|
||||||
|
type DHCPv6Options []DHCPv6Option
|
||||||
|
|
||||||
|
// String returns a string version of the options list.
|
||||||
|
func (o DHCPv6Options) String() string {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
buf.WriteByte('[')
|
||||||
|
for i, opt := range o {
|
||||||
|
buf.WriteString(opt.String())
|
||||||
|
if i+1 != len(o) {
|
||||||
|
buf.WriteString(", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.WriteByte(']')
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCPv6Option rerpresents a DHCP option.
|
||||||
|
type DHCPv6Option struct {
|
||||||
|
Code DHCPv6Opt
|
||||||
|
Length uint16
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string version of a DHCP Option.
|
||||||
|
func (o DHCPv6Option) String() string {
|
||||||
|
switch o.Code {
|
||||||
|
case DHCPv6OptClientID, DHCPv6OptServerID:
|
||||||
|
duid, err := decodeDHCPv6DUID(o.Data)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("Option(%s:INVALID)", o.Code)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Option(%s:[%s])", o.Code, duid.String())
|
||||||
|
case DHCPv6OptOro:
|
||||||
|
options := ""
|
||||||
|
for i := 0; i < int(o.Length); i += 2 {
|
||||||
|
if options != "" {
|
||||||
|
options += ","
|
||||||
|
}
|
||||||
|
option := DHCPv6Opt(binary.BigEndian.Uint16(o.Data[i : i+2]))
|
||||||
|
options += option.String()
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Option(%s:[%s])", o.Code, options)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("Option(%s:%v)", o.Code, o.Data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDHCPv6Option constructs a new DHCPv6Option with a given type and data.
|
||||||
|
func NewDHCPv6Option(code DHCPv6Opt, data []byte) DHCPv6Option {
|
||||||
|
o := DHCPv6Option{Code: code}
|
||||||
|
if data != nil {
|
||||||
|
o.Data = data
|
||||||
|
o.Length = uint16(len(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *DHCPv6Option) encode(b []byte, opts gopacket.SerializeOptions) error {
|
||||||
|
binary.BigEndian.PutUint16(b[0:2], uint16(o.Code))
|
||||||
|
if opts.FixLengths {
|
||||||
|
binary.BigEndian.PutUint16(b[2:4], uint16(len(o.Data)))
|
||||||
|
} else {
|
||||||
|
binary.BigEndian.PutUint16(b[2:4], o.Length)
|
||||||
|
}
|
||||||
|
copy(b[4:], o.Data)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *DHCPv6Option) decode(data []byte) error {
|
||||||
|
if len(data) < 4 {
|
||||||
|
return errors.New("not enough data to decode")
|
||||||
|
}
|
||||||
|
o.Code = DHCPv6Opt(binary.BigEndian.Uint16(data[0:2]))
|
||||||
|
o.Length = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
if len(data) < 4+int(o.Length) {
|
||||||
|
return fmt.Errorf("dhcpv6 option size < length %d", 4+o.Length)
|
||||||
|
}
|
||||||
|
o.Data = data[4 : 4+o.Length]
|
||||||
|
return nil
|
||||||
|
}
|
1098
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dns.go
generated
vendored
Normal file
1098
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dns.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
61
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/doc.go
generated
vendored
Normal file
61
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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 provides decoding layers for many common protocols.
|
||||||
|
|
||||||
|
The layers package contains decode implementations for a number of different
|
||||||
|
types of packet layers. Users of gopacket will almost always want to also use
|
||||||
|
layers to actually decode packet data into useful pieces. To see the set of
|
||||||
|
protocols that gopacket/layers is currently able to decode,
|
||||||
|
look at the set of LayerTypes defined in the Variables sections. The
|
||||||
|
layers package also defines endpoints for many of the common packet layers
|
||||||
|
that have source/destination addresses associated with them, for example IPv4/6
|
||||||
|
(IPs) and TCP/UDP (ports).
|
||||||
|
Finally, layers contains a number of useful enumerations (IPProtocol,
|
||||||
|
EthernetType, LinkType, PPPType, etc...). Many of these implement the
|
||||||
|
gopacket.Decoder interface, so they can be passed into gopacket as decoders.
|
||||||
|
|
||||||
|
Most common protocol layers are named using acronyms or other industry-common
|
||||||
|
names (IPv4, TCP, PPP). Some of the less common ones have their names expanded
|
||||||
|
(CiscoDiscoveryProtocol).
|
||||||
|
For certain protocols, sub-parts of the protocol are split out into their own
|
||||||
|
layers (SCTP, for example). This is done mostly in cases where portions of the
|
||||||
|
protocol may fulfill the capabilities of interesting layers (SCTPData implements
|
||||||
|
ApplicationLayer, while base SCTP implements TransportLayer), or possibly
|
||||||
|
because splitting a protocol into a few layers makes decoding easier.
|
||||||
|
|
||||||
|
This package is meant to be used with its parent,
|
||||||
|
http://github.com/google/gopacket.
|
||||||
|
|
||||||
|
Port Types
|
||||||
|
|
||||||
|
Instead of using raw uint16 or uint8 values for ports, we use a different port
|
||||||
|
type for every protocol, for example TCPPort and UDPPort. This allows us to
|
||||||
|
override string behavior for each port, which we do by setting up port name
|
||||||
|
maps (TCPPortNames, UDPPortNames, etc...). Well-known ports are annotated with
|
||||||
|
their protocol names, and their String function displays these names:
|
||||||
|
|
||||||
|
p := TCPPort(80)
|
||||||
|
fmt.Printf("Number: %d String: %v", p, p)
|
||||||
|
// Prints: "Number: 80 String: 80(http)"
|
||||||
|
|
||||||
|
Modifying Decode Behavior
|
||||||
|
|
||||||
|
layers links together decoding through its enumerations. For example, after
|
||||||
|
decoding layer type Ethernet, it uses Ethernet.EthernetType as its next decoder.
|
||||||
|
All enumerations that act as decoders, like EthernetType, can be modified by
|
||||||
|
users depending on their preferences. For example, if you have a spiffy new
|
||||||
|
IPv4 decoder that works way better than the one built into layers, you can do
|
||||||
|
this:
|
||||||
|
|
||||||
|
var mySpiffyIPv4Decoder gopacket.Decoder = ...
|
||||||
|
layers.EthernetTypeMetadata[EthernetTypeIPv4].DecodeWith = mySpiffyIPv4Decoder
|
||||||
|
|
||||||
|
This will make all future ethernet packets use your new decoder to decode IPv4
|
||||||
|
packets, instead of the built-in decoder used by gopacket.
|
||||||
|
*/
|
||||||
|
package layers
|
2118
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dot11.go
generated
vendored
Normal file
2118
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dot11.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
75
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dot1q.go
generated
vendored
Normal file
75
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/dot1q.go
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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"
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Dot1Q is the packet layer for 802.1Q VLAN headers.
|
||||||
|
type Dot1Q struct {
|
||||||
|
BaseLayer
|
||||||
|
Priority uint8
|
||||||
|
DropEligible bool
|
||||||
|
VLANIdentifier uint16
|
||||||
|
Type EthernetType
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeDot1Q
|
||||||
|
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
|
||||||
|
d.Type = EthernetType(binary.BigEndian.Uint16(data[2:4]))
|
||||||
|
d.BaseLayer = BaseLayer{Contents: data[:4], Payload: data[4:]}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (d *Dot1Q) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeDot1Q
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (d *Dot1Q) NextLayerType() gopacket.LayerType {
|
||||||
|
return d.Type.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeDot1Q(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
d := &Dot1Q{}
|
||||||
|
return decodingLayerDecoder(d, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (d *Dot1Q) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if d.VLANIdentifier > 0xFFF {
|
||||||
|
return fmt.Errorf("vlan identifier %v is too high", d.VLANIdentifier)
|
||||||
|
}
|
||||||
|
firstBytes := uint16(d.Priority)<<13 | d.VLANIdentifier
|
||||||
|
if d.DropEligible {
|
||||||
|
firstBytes |= 0x1000
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes, firstBytes)
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], uint16(d.Type))
|
||||||
|
return nil
|
||||||
|
}
|
114
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/eap.go
generated
vendored
Normal file
114
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/eap.go
generated
vendored
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EAPCode uint8
|
||||||
|
type EAPType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
EAPCodeRequest EAPCode = 1
|
||||||
|
EAPCodeResponse EAPCode = 2
|
||||||
|
EAPCodeSuccess EAPCode = 3
|
||||||
|
EAPCodeFailure EAPCode = 4
|
||||||
|
|
||||||
|
// EAPTypeNone means that this EAP layer has no Type or TypeData.
|
||||||
|
// Success and Failure EAPs will have this set.
|
||||||
|
EAPTypeNone EAPType = 0
|
||||||
|
|
||||||
|
EAPTypeIdentity EAPType = 1
|
||||||
|
EAPTypeNotification EAPType = 2
|
||||||
|
EAPTypeNACK EAPType = 3
|
||||||
|
EAPTypeOTP EAPType = 4
|
||||||
|
EAPTypeTokenCard EAPType = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
// EAP defines an Extensible Authentication Protocol (rfc 3748) layer.
|
||||||
|
type EAP struct {
|
||||||
|
BaseLayer
|
||||||
|
Code EAPCode
|
||||||
|
Id uint8
|
||||||
|
Length uint16
|
||||||
|
Type EAPType
|
||||||
|
TypeData []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeEAP.
|
||||||
|
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])
|
||||||
|
e.TypeData = data[5:]
|
||||||
|
case e.Length == 4:
|
||||||
|
e.Type = 0
|
||||||
|
e.TypeData = nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid EAP length %d", e.Length)
|
||||||
|
}
|
||||||
|
e.BaseLayer.Contents = data[:e.Length]
|
||||||
|
e.BaseLayer.Payload = data[e.Length:] // Should be 0 bytes
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (e *EAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if opts.FixLengths {
|
||||||
|
e.Length = uint16(len(e.TypeData) + 1)
|
||||||
|
}
|
||||||
|
size := len(e.TypeData) + 4
|
||||||
|
if size > 4 {
|
||||||
|
size++
|
||||||
|
}
|
||||||
|
bytes, err := b.PrependBytes(size)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = byte(e.Code)
|
||||||
|
bytes[1] = e.Id
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], e.Length)
|
||||||
|
if size > 4 {
|
||||||
|
bytes[4] = byte(e.Type)
|
||||||
|
copy(bytes[5:], e.TypeData)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (e *EAP) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeEAP
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (e *EAP) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeEAP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
e := &EAP{}
|
||||||
|
return decodingLayerDecoder(e, data, p)
|
||||||
|
}
|
302
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/eapol.go
generated
vendored
Normal file
302
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/eapol.go
generated
vendored
Normal file
|
@ -0,0 +1,302 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EAPOL defines an EAP over LAN (802.1x) layer.
|
||||||
|
type EAPOL struct {
|
||||||
|
BaseLayer
|
||||||
|
Version uint8
|
||||||
|
Type EAPOLType
|
||||||
|
Length uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeEAPOL.
|
||||||
|
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])
|
||||||
|
e.BaseLayer = BaseLayer{data[:4], data[4:]}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer
|
||||||
|
func (e *EAPOL) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, _ := b.PrependBytes(4)
|
||||||
|
bytes[0] = e.Version
|
||||||
|
bytes[1] = byte(e.Type)
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], e.Length)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (e *EAPOL) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeEAPOL
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (e *EAPOL) NextLayerType() gopacket.LayerType {
|
||||||
|
return e.Type.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeEAPOL(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
e := &EAPOL{}
|
||||||
|
return decodingLayerDecoder(e, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EAPOLKeyDescriptorType is an enumeration of key descriptor types
|
||||||
|
// as specified by 802.1x in the EAPOL-Key frame
|
||||||
|
type EAPOLKeyDescriptorType uint8
|
||||||
|
|
||||||
|
// Enumeration of EAPOLKeyDescriptorType
|
||||||
|
const (
|
||||||
|
EAPOLKeyDescriptorTypeRC4 EAPOLKeyDescriptorType = 1
|
||||||
|
EAPOLKeyDescriptorTypeDot11 EAPOLKeyDescriptorType = 2
|
||||||
|
EAPOLKeyDescriptorTypeWPA EAPOLKeyDescriptorType = 254
|
||||||
|
)
|
||||||
|
|
||||||
|
func (kdt EAPOLKeyDescriptorType) String() string {
|
||||||
|
switch kdt {
|
||||||
|
case EAPOLKeyDescriptorTypeRC4:
|
||||||
|
return "RC4"
|
||||||
|
case EAPOLKeyDescriptorTypeDot11:
|
||||||
|
return "802.11"
|
||||||
|
case EAPOLKeyDescriptorTypeWPA:
|
||||||
|
return "WPA"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown descriptor type %d", kdt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EAPOLKeyDescriptorVersion is an enumeration of versions specifying the
|
||||||
|
// encryption algorithm for the key data and the authentication for the
|
||||||
|
// message integrity code (MIC)
|
||||||
|
type EAPOLKeyDescriptorVersion uint8
|
||||||
|
|
||||||
|
// Enumeration of EAPOLKeyDescriptorVersion
|
||||||
|
const (
|
||||||
|
EAPOLKeyDescriptorVersionOther EAPOLKeyDescriptorVersion = 0
|
||||||
|
EAPOLKeyDescriptorVersionRC4HMACMD5 EAPOLKeyDescriptorVersion = 1
|
||||||
|
EAPOLKeyDescriptorVersionAESHMACSHA1 EAPOLKeyDescriptorVersion = 2
|
||||||
|
EAPOLKeyDescriptorVersionAES128CMAC EAPOLKeyDescriptorVersion = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v EAPOLKeyDescriptorVersion) String() string {
|
||||||
|
switch v {
|
||||||
|
case EAPOLKeyDescriptorVersionOther:
|
||||||
|
return "Other"
|
||||||
|
case EAPOLKeyDescriptorVersionRC4HMACMD5:
|
||||||
|
return "RC4-HMAC-MD5"
|
||||||
|
case EAPOLKeyDescriptorVersionAESHMACSHA1:
|
||||||
|
return "AES-HMAC-SHA1-128"
|
||||||
|
case EAPOLKeyDescriptorVersionAES128CMAC:
|
||||||
|
return "AES-128-CMAC"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown version %d", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EAPOLKeyType is an enumeration of key derivation types describing
|
||||||
|
// the purpose of the keys being derived.
|
||||||
|
type EAPOLKeyType uint8
|
||||||
|
|
||||||
|
// Enumeration of EAPOLKeyType
|
||||||
|
const (
|
||||||
|
EAPOLKeyTypeGroupSMK EAPOLKeyType = 0
|
||||||
|
EAPOLKeyTypePairwise EAPOLKeyType = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
func (kt EAPOLKeyType) String() string {
|
||||||
|
switch kt {
|
||||||
|
case EAPOLKeyTypeGroupSMK:
|
||||||
|
return "Group/SMK"
|
||||||
|
case EAPOLKeyTypePairwise:
|
||||||
|
return "Pairwise"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("unknown key type %d", kt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EAPOLKey defines an EAPOL-Key frame for 802.1x authentication
|
||||||
|
type EAPOLKey struct {
|
||||||
|
BaseLayer
|
||||||
|
KeyDescriptorType EAPOLKeyDescriptorType
|
||||||
|
KeyDescriptorVersion EAPOLKeyDescriptorVersion
|
||||||
|
KeyType EAPOLKeyType
|
||||||
|
KeyIndex uint8
|
||||||
|
Install bool
|
||||||
|
KeyACK bool
|
||||||
|
KeyMIC bool
|
||||||
|
Secure bool
|
||||||
|
MICError bool
|
||||||
|
Request bool
|
||||||
|
HasEncryptedKeyData bool
|
||||||
|
SMKMessage bool
|
||||||
|
KeyLength uint16
|
||||||
|
ReplayCounter uint64
|
||||||
|
Nonce []byte
|
||||||
|
IV []byte
|
||||||
|
RSC uint64
|
||||||
|
ID uint64
|
||||||
|
MIC []byte
|
||||||
|
KeyDataLength uint16
|
||||||
|
EncryptedKeyData []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeEAPOLKey.
|
||||||
|
func (ek *EAPOLKey) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeEAPOLKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (ek *EAPOLKey) CanDecode() gopacket.LayerType {
|
||||||
|
return LayerTypeEAPOLKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns layers.LayerTypeDot11InformationElement if the key
|
||||||
|
// data exists and is unencrypted, otherwise it does not expect a next layer.
|
||||||
|
func (ek *EAPOLKey) NextLayerType() gopacket.LayerType {
|
||||||
|
if !ek.HasEncryptedKeyData && ek.KeyDataLength > 0 {
|
||||||
|
return LayerTypeDot11InformationElement
|
||||||
|
}
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
const eapolKeyFrameLen = 95
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (ek *EAPOLKey) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < eapolKeyFrameLen {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("EAPOLKey length %v too short, %v required",
|
||||||
|
len(data), eapolKeyFrameLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
ek.KeyDescriptorType = EAPOLKeyDescriptorType(data[0])
|
||||||
|
|
||||||
|
info := binary.BigEndian.Uint16(data[1:3])
|
||||||
|
ek.KeyDescriptorVersion = EAPOLKeyDescriptorVersion(info & 0x0007)
|
||||||
|
ek.KeyType = EAPOLKeyType((info & 0x0008) >> 3)
|
||||||
|
ek.KeyIndex = uint8((info & 0x0030) >> 4)
|
||||||
|
ek.Install = (info & 0x0040) != 0
|
||||||
|
ek.KeyACK = (info & 0x0080) != 0
|
||||||
|
ek.KeyMIC = (info & 0x0100) != 0
|
||||||
|
ek.Secure = (info & 0x0200) != 0
|
||||||
|
ek.MICError = (info & 0x0400) != 0
|
||||||
|
ek.Request = (info & 0x0800) != 0
|
||||||
|
ek.HasEncryptedKeyData = (info & 0x1000) != 0
|
||||||
|
ek.SMKMessage = (info & 0x2000) != 0
|
||||||
|
|
||||||
|
ek.KeyLength = binary.BigEndian.Uint16(data[3:5])
|
||||||
|
ek.ReplayCounter = binary.BigEndian.Uint64(data[5:13])
|
||||||
|
|
||||||
|
ek.Nonce = data[13:45]
|
||||||
|
ek.IV = data[45:61]
|
||||||
|
ek.RSC = binary.BigEndian.Uint64(data[61:69])
|
||||||
|
ek.ID = binary.BigEndian.Uint64(data[69:77])
|
||||||
|
ek.MIC = data[77:93]
|
||||||
|
|
||||||
|
ek.KeyDataLength = binary.BigEndian.Uint16(data[93:95])
|
||||||
|
|
||||||
|
totalLength := eapolKeyFrameLen + int(ek.KeyDataLength)
|
||||||
|
if len(data) < totalLength {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("EAPOLKey data length %d too short, %d required",
|
||||||
|
len(data)-eapolKeyFrameLen, ek.KeyDataLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ek.HasEncryptedKeyData {
|
||||||
|
ek.EncryptedKeyData = data[eapolKeyFrameLen:totalLength]
|
||||||
|
ek.BaseLayer = BaseLayer{
|
||||||
|
Contents: data[:totalLength],
|
||||||
|
Payload: data[totalLength:],
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ek.BaseLayer = BaseLayer{
|
||||||
|
Contents: data[:eapolKeyFrameLen],
|
||||||
|
Payload: data[eapolKeyFrameLen:],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (ek *EAPOLKey) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
buf, err := b.PrependBytes(eapolKeyFrameLen + len(ek.EncryptedKeyData))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = byte(ek.KeyDescriptorType)
|
||||||
|
|
||||||
|
var info uint16
|
||||||
|
info |= uint16(ek.KeyDescriptorVersion)
|
||||||
|
info |= uint16(ek.KeyType) << 3
|
||||||
|
info |= uint16(ek.KeyIndex) << 4
|
||||||
|
if ek.Install {
|
||||||
|
info |= 0x0040
|
||||||
|
}
|
||||||
|
if ek.KeyACK {
|
||||||
|
info |= 0x0080
|
||||||
|
}
|
||||||
|
if ek.KeyMIC {
|
||||||
|
info |= 0x0100
|
||||||
|
}
|
||||||
|
if ek.Secure {
|
||||||
|
info |= 0x0200
|
||||||
|
}
|
||||||
|
if ek.MICError {
|
||||||
|
info |= 0x0400
|
||||||
|
}
|
||||||
|
if ek.Request {
|
||||||
|
info |= 0x0800
|
||||||
|
}
|
||||||
|
if ek.HasEncryptedKeyData {
|
||||||
|
info |= 0x1000
|
||||||
|
}
|
||||||
|
if ek.SMKMessage {
|
||||||
|
info |= 0x2000
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(buf[1:3], info)
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint16(buf[3:5], ek.KeyLength)
|
||||||
|
binary.BigEndian.PutUint64(buf[5:13], ek.ReplayCounter)
|
||||||
|
|
||||||
|
copy(buf[13:45], ek.Nonce)
|
||||||
|
copy(buf[45:61], ek.IV)
|
||||||
|
binary.BigEndian.PutUint64(buf[61:69], ek.RSC)
|
||||||
|
binary.BigEndian.PutUint64(buf[69:77], ek.ID)
|
||||||
|
copy(buf[77:93], ek.MIC)
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint16(buf[93:95], ek.KeyDataLength)
|
||||||
|
if len(ek.EncryptedKeyData) > 0 {
|
||||||
|
copy(buf[95:95+len(ek.EncryptedKeyData)], ek.EncryptedKeyData)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeEAPOLKey(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
ek := &EAPOLKey{}
|
||||||
|
return decodingLayerDecoder(ek, data, p)
|
||||||
|
}
|
97
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/endpoints.go
generated
vendored
Normal file
97
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/endpoints.go
generated
vendored
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// We use two different endpoint types for IPv4 vs IPv6 addresses, so that
|
||||||
|
// ordering with endpointA.LessThan(endpointB) sanely groups all IPv4
|
||||||
|
// addresses and all IPv6 addresses, such that IPv6 > IPv4 for all addresses.
|
||||||
|
EndpointIPv4 = gopacket.RegisterEndpointType(1, gopacket.EndpointTypeMetadata{Name: "IPv4", Formatter: func(b []byte) string {
|
||||||
|
return net.IP(b).String()
|
||||||
|
}})
|
||||||
|
EndpointIPv6 = gopacket.RegisterEndpointType(2, gopacket.EndpointTypeMetadata{Name: "IPv6", Formatter: func(b []byte) string {
|
||||||
|
return net.IP(b).String()
|
||||||
|
}})
|
||||||
|
|
||||||
|
EndpointMAC = gopacket.RegisterEndpointType(3, gopacket.EndpointTypeMetadata{Name: "MAC", Formatter: func(b []byte) string {
|
||||||
|
return net.HardwareAddr(b).String()
|
||||||
|
}})
|
||||||
|
EndpointTCPPort = gopacket.RegisterEndpointType(4, gopacket.EndpointTypeMetadata{Name: "TCP", Formatter: func(b []byte) string {
|
||||||
|
return strconv.Itoa(int(binary.BigEndian.Uint16(b)))
|
||||||
|
}})
|
||||||
|
EndpointUDPPort = gopacket.RegisterEndpointType(5, gopacket.EndpointTypeMetadata{Name: "UDP", Formatter: func(b []byte) string {
|
||||||
|
return strconv.Itoa(int(binary.BigEndian.Uint16(b)))
|
||||||
|
}})
|
||||||
|
EndpointSCTPPort = gopacket.RegisterEndpointType(6, gopacket.EndpointTypeMetadata{Name: "SCTP", Formatter: func(b []byte) string {
|
||||||
|
return strconv.Itoa(int(binary.BigEndian.Uint16(b)))
|
||||||
|
}})
|
||||||
|
EndpointRUDPPort = gopacket.RegisterEndpointType(7, gopacket.EndpointTypeMetadata{Name: "RUDP", Formatter: func(b []byte) string {
|
||||||
|
return strconv.Itoa(int(b[0]))
|
||||||
|
}})
|
||||||
|
EndpointUDPLitePort = gopacket.RegisterEndpointType(8, gopacket.EndpointTypeMetadata{Name: "UDPLite", Formatter: func(b []byte) string {
|
||||||
|
return strconv.Itoa(int(binary.BigEndian.Uint16(b)))
|
||||||
|
}})
|
||||||
|
EndpointPPP = gopacket.RegisterEndpointType(9, gopacket.EndpointTypeMetadata{Name: "PPP", Formatter: func([]byte) string {
|
||||||
|
return "point"
|
||||||
|
}})
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewIPEndpoint creates a new IP (v4 or v6) endpoint from a net.IP address.
|
||||||
|
// It returns gopacket.InvalidEndpoint if the IP address is invalid.
|
||||||
|
func NewIPEndpoint(a net.IP) gopacket.Endpoint {
|
||||||
|
ipv4 := a.To4()
|
||||||
|
if ipv4 != nil {
|
||||||
|
return gopacket.NewEndpoint(EndpointIPv4, []byte(ipv4))
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv6 := a.To16()
|
||||||
|
if ipv6 != nil {
|
||||||
|
return gopacket.NewEndpoint(EndpointIPv6, []byte(ipv6))
|
||||||
|
}
|
||||||
|
|
||||||
|
return gopacket.InvalidEndpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMACEndpoint returns a new MAC address endpoint.
|
||||||
|
func NewMACEndpoint(a net.HardwareAddr) gopacket.Endpoint {
|
||||||
|
return gopacket.NewEndpoint(EndpointMAC, []byte(a))
|
||||||
|
}
|
||||||
|
func newPortEndpoint(t gopacket.EndpointType, p uint16) gopacket.Endpoint {
|
||||||
|
return gopacket.NewEndpoint(t, []byte{byte(p >> 8), byte(p)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTCPPortEndpoint returns an endpoint based on a TCP port.
|
||||||
|
func NewTCPPortEndpoint(p TCPPort) gopacket.Endpoint {
|
||||||
|
return newPortEndpoint(EndpointTCPPort, uint16(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUDPPortEndpoint returns an endpoint based on a UDP port.
|
||||||
|
func NewUDPPortEndpoint(p UDPPort) gopacket.Endpoint {
|
||||||
|
return newPortEndpoint(EndpointUDPPort, uint16(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSCTPPortEndpoint returns an endpoint based on a SCTP port.
|
||||||
|
func NewSCTPPortEndpoint(p SCTPPort) gopacket.Endpoint {
|
||||||
|
return newPortEndpoint(EndpointSCTPPort, uint16(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRUDPPortEndpoint returns an endpoint based on a RUDP port.
|
||||||
|
func NewRUDPPortEndpoint(p RUDPPort) gopacket.Endpoint {
|
||||||
|
return gopacket.NewEndpoint(EndpointRUDPPort, []byte{byte(p)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUDPLitePortEndpoint returns an endpoint based on a UDPLite port.
|
||||||
|
func NewUDPLitePortEndpoint(p UDPLitePort) gopacket.Endpoint {
|
||||||
|
return newPortEndpoint(EndpointUDPLitePort, uint16(p))
|
||||||
|
}
|
443
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/enums.go
generated
vendored
Normal file
443
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/enums.go
generated
vendored
Normal file
|
@ -0,0 +1,443 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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 (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EnumMetadata keeps track of a set of metadata for each enumeration value
|
||||||
|
// for protocol enumerations.
|
||||||
|
type EnumMetadata struct {
|
||||||
|
// DecodeWith is the decoder to use to decode this protocol's data.
|
||||||
|
DecodeWith gopacket.Decoder
|
||||||
|
// Name is the name of the enumeration value.
|
||||||
|
Name string
|
||||||
|
// LayerType is the layer type implied by the given enum.
|
||||||
|
LayerType gopacket.LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
// EthernetType is an enumeration of ethernet type values, and acts as a decoder
|
||||||
|
// for any type it supports.
|
||||||
|
type EthernetType uint16
|
||||||
|
|
||||||
|
const (
|
||||||
|
// EthernetTypeLLC is not an actual ethernet type. It is instead a
|
||||||
|
// placeholder we use in Ethernet frames that use the 802.3 standard of
|
||||||
|
// srcmac|dstmac|length|LLC instead of srcmac|dstmac|ethertype.
|
||||||
|
EthernetTypeLLC EthernetType = 0
|
||||||
|
EthernetTypeIPv4 EthernetType = 0x0800
|
||||||
|
EthernetTypeARP EthernetType = 0x0806
|
||||||
|
EthernetTypeIPv6 EthernetType = 0x86DD
|
||||||
|
EthernetTypeCiscoDiscovery EthernetType = 0x2000
|
||||||
|
EthernetTypeNortelDiscovery EthernetType = 0x01a2
|
||||||
|
EthernetTypeTransparentEthernetBridging EthernetType = 0x6558
|
||||||
|
EthernetTypeDot1Q EthernetType = 0x8100
|
||||||
|
EthernetTypePPP EthernetType = 0x880b
|
||||||
|
EthernetTypePPPoEDiscovery EthernetType = 0x8863
|
||||||
|
EthernetTypePPPoESession EthernetType = 0x8864
|
||||||
|
EthernetTypeMPLSUnicast EthernetType = 0x8847
|
||||||
|
EthernetTypeMPLSMulticast EthernetType = 0x8848
|
||||||
|
EthernetTypeEAPOL EthernetType = 0x888e
|
||||||
|
EthernetTypeERSPAN EthernetType = 0x88be
|
||||||
|
EthernetTypeQinQ EthernetType = 0x88a8
|
||||||
|
EthernetTypeLinkLayerDiscovery EthernetType = 0x88cc
|
||||||
|
EthernetTypeEthernetCTP EthernetType = 0x9000
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPProtocol is an enumeration of IP protocol values, and acts as a decoder
|
||||||
|
// for any type it supports.
|
||||||
|
type IPProtocol uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
IPProtocolIPv6HopByHop IPProtocol = 0
|
||||||
|
IPProtocolICMPv4 IPProtocol = 1
|
||||||
|
IPProtocolIGMP IPProtocol = 2
|
||||||
|
IPProtocolIPv4 IPProtocol = 4
|
||||||
|
IPProtocolTCP IPProtocol = 6
|
||||||
|
IPProtocolUDP IPProtocol = 17
|
||||||
|
IPProtocolRUDP IPProtocol = 27
|
||||||
|
IPProtocolIPv6 IPProtocol = 41
|
||||||
|
IPProtocolIPv6Routing IPProtocol = 43
|
||||||
|
IPProtocolIPv6Fragment IPProtocol = 44
|
||||||
|
IPProtocolGRE IPProtocol = 47
|
||||||
|
IPProtocolESP IPProtocol = 50
|
||||||
|
IPProtocolAH IPProtocol = 51
|
||||||
|
IPProtocolICMPv6 IPProtocol = 58
|
||||||
|
IPProtocolNoNextHeader IPProtocol = 59
|
||||||
|
IPProtocolIPv6Destination IPProtocol = 60
|
||||||
|
IPProtocolOSPF IPProtocol = 89
|
||||||
|
IPProtocolIPIP IPProtocol = 94
|
||||||
|
IPProtocolEtherIP IPProtocol = 97
|
||||||
|
IPProtocolVRRP IPProtocol = 112
|
||||||
|
IPProtocolSCTP IPProtocol = 132
|
||||||
|
IPProtocolUDPLite IPProtocol = 136
|
||||||
|
IPProtocolMPLSInIP IPProtocol = 137
|
||||||
|
)
|
||||||
|
|
||||||
|
// LinkType is an enumeration of link types, and acts as a decoder for any
|
||||||
|
// link type it supports.
|
||||||
|
type LinkType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// According to pcap-linktype(7) and http://www.tcpdump.org/linktypes.html
|
||||||
|
LinkTypeNull LinkType = 0
|
||||||
|
LinkTypeEthernet LinkType = 1
|
||||||
|
LinkTypeAX25 LinkType = 3
|
||||||
|
LinkTypeTokenRing LinkType = 6
|
||||||
|
LinkTypeArcNet LinkType = 7
|
||||||
|
LinkTypeSLIP LinkType = 8
|
||||||
|
LinkTypePPP LinkType = 9
|
||||||
|
LinkTypeFDDI LinkType = 10
|
||||||
|
LinkTypePPP_HDLC LinkType = 50
|
||||||
|
LinkTypePPPEthernet LinkType = 51
|
||||||
|
LinkTypeATM_RFC1483 LinkType = 100
|
||||||
|
LinkTypeRaw LinkType = 101
|
||||||
|
LinkTypeC_HDLC LinkType = 104
|
||||||
|
LinkTypeIEEE802_11 LinkType = 105
|
||||||
|
LinkTypeFRelay LinkType = 107
|
||||||
|
LinkTypeLoop LinkType = 108
|
||||||
|
LinkTypeLinuxSLL LinkType = 113
|
||||||
|
LinkTypeLTalk LinkType = 114
|
||||||
|
LinkTypePFLog LinkType = 117
|
||||||
|
LinkTypePrismHeader LinkType = 119
|
||||||
|
LinkTypeIPOverFC LinkType = 122
|
||||||
|
LinkTypeSunATM LinkType = 123
|
||||||
|
LinkTypeIEEE80211Radio LinkType = 127
|
||||||
|
LinkTypeARCNetLinux LinkType = 129
|
||||||
|
LinkTypeIPOver1394 LinkType = 138
|
||||||
|
LinkTypeMTP2Phdr LinkType = 139
|
||||||
|
LinkTypeMTP2 LinkType = 140
|
||||||
|
LinkTypeMTP3 LinkType = 141
|
||||||
|
LinkTypeSCCP LinkType = 142
|
||||||
|
LinkTypeDOCSIS LinkType = 143
|
||||||
|
LinkTypeLinuxIRDA LinkType = 144
|
||||||
|
LinkTypeLinuxLAPD LinkType = 177
|
||||||
|
LinkTypeLinuxUSB LinkType = 220
|
||||||
|
LinkTypeFC2 LinkType = 224
|
||||||
|
LinkTypeFC2Framed LinkType = 225
|
||||||
|
LinkTypeIPv4 LinkType = 228
|
||||||
|
LinkTypeIPv6 LinkType = 229
|
||||||
|
)
|
||||||
|
|
||||||
|
// PPPoECode is the PPPoE code enum, taken from http://tools.ietf.org/html/rfc2516
|
||||||
|
type PPPoECode uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
PPPoECodePADI PPPoECode = 0x09
|
||||||
|
PPPoECodePADO PPPoECode = 0x07
|
||||||
|
PPPoECodePADR PPPoECode = 0x19
|
||||||
|
PPPoECodePADS PPPoECode = 0x65
|
||||||
|
PPPoECodePADT PPPoECode = 0xA7
|
||||||
|
PPPoECodeSession PPPoECode = 0x00
|
||||||
|
)
|
||||||
|
|
||||||
|
// PPPType is an enumeration of PPP type values, and acts as a decoder for any
|
||||||
|
// type it supports.
|
||||||
|
type PPPType uint16
|
||||||
|
|
||||||
|
const (
|
||||||
|
PPPTypeIPv4 PPPType = 0x0021
|
||||||
|
PPPTypeIPv6 PPPType = 0x0057
|
||||||
|
PPPTypeMPLSUnicast PPPType = 0x0281
|
||||||
|
PPPTypeMPLSMulticast PPPType = 0x0283
|
||||||
|
)
|
||||||
|
|
||||||
|
// SCTPChunkType is an enumeration of chunk types inside SCTP packets.
|
||||||
|
type SCTPChunkType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
SCTPChunkTypeData SCTPChunkType = 0
|
||||||
|
SCTPChunkTypeInit SCTPChunkType = 1
|
||||||
|
SCTPChunkTypeInitAck SCTPChunkType = 2
|
||||||
|
SCTPChunkTypeSack SCTPChunkType = 3
|
||||||
|
SCTPChunkTypeHeartbeat SCTPChunkType = 4
|
||||||
|
SCTPChunkTypeHeartbeatAck SCTPChunkType = 5
|
||||||
|
SCTPChunkTypeAbort SCTPChunkType = 6
|
||||||
|
SCTPChunkTypeShutdown SCTPChunkType = 7
|
||||||
|
SCTPChunkTypeShutdownAck SCTPChunkType = 8
|
||||||
|
SCTPChunkTypeError SCTPChunkType = 9
|
||||||
|
SCTPChunkTypeCookieEcho SCTPChunkType = 10
|
||||||
|
SCTPChunkTypeCookieAck SCTPChunkType = 11
|
||||||
|
SCTPChunkTypeShutdownComplete SCTPChunkType = 14
|
||||||
|
)
|
||||||
|
|
||||||
|
// FDDIFrameControl is an enumeration of FDDI frame control bytes.
|
||||||
|
type FDDIFrameControl uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
FDDIFrameControlLLC FDDIFrameControl = 0x50
|
||||||
|
)
|
||||||
|
|
||||||
|
// EAPOLType is an enumeration of EAPOL packet types.
|
||||||
|
type EAPOLType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
EAPOLTypeEAP EAPOLType = 0
|
||||||
|
EAPOLTypeStart EAPOLType = 1
|
||||||
|
EAPOLTypeLogOff EAPOLType = 2
|
||||||
|
EAPOLTypeKey EAPOLType = 3
|
||||||
|
EAPOLTypeASFAlert EAPOLType = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProtocolFamily is the set of values defined as PF_* in sys/socket.h
|
||||||
|
type ProtocolFamily uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
ProtocolFamilyIPv4 ProtocolFamily = 2
|
||||||
|
// BSDs use different values for INET6... glory be. These values taken from
|
||||||
|
// tcpdump 4.3.0.
|
||||||
|
ProtocolFamilyIPv6BSD ProtocolFamily = 24
|
||||||
|
ProtocolFamilyIPv6FreeBSD ProtocolFamily = 28
|
||||||
|
ProtocolFamilyIPv6Darwin ProtocolFamily = 30
|
||||||
|
ProtocolFamilyIPv6Linux ProtocolFamily = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
// Dot11Type is a combination of IEEE 802.11 frame's Type and Subtype fields.
|
||||||
|
// By combining these two fields together into a single type, we're able to
|
||||||
|
// provide a String function that correctly displays the subtype given the
|
||||||
|
// top-level type.
|
||||||
|
//
|
||||||
|
// If you just care about the top-level type, use the MainType function.
|
||||||
|
type Dot11Type uint8
|
||||||
|
|
||||||
|
// MainType strips the subtype information from the given type,
|
||||||
|
// returning just the overarching type (Mgmt, Ctrl, Data, Reserved).
|
||||||
|
func (d Dot11Type) MainType() Dot11Type {
|
||||||
|
return d & dot11TypeMask
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Dot11Type) QOS() bool {
|
||||||
|
return d&dot11QOSMask == Dot11TypeDataQOSData
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
Dot11TypeMgmt Dot11Type = 0x00
|
||||||
|
Dot11TypeCtrl Dot11Type = 0x01
|
||||||
|
Dot11TypeData Dot11Type = 0x02
|
||||||
|
Dot11TypeReserved Dot11Type = 0x03
|
||||||
|
dot11TypeMask = 0x03
|
||||||
|
dot11QOSMask = 0x23
|
||||||
|
|
||||||
|
// The following are type/subtype conglomerations.
|
||||||
|
|
||||||
|
// Management
|
||||||
|
Dot11TypeMgmtAssociationReq Dot11Type = 0x00
|
||||||
|
Dot11TypeMgmtAssociationResp Dot11Type = 0x04
|
||||||
|
Dot11TypeMgmtReassociationReq Dot11Type = 0x08
|
||||||
|
Dot11TypeMgmtReassociationResp Dot11Type = 0x0c
|
||||||
|
Dot11TypeMgmtProbeReq Dot11Type = 0x10
|
||||||
|
Dot11TypeMgmtProbeResp Dot11Type = 0x14
|
||||||
|
Dot11TypeMgmtMeasurementPilot Dot11Type = 0x18
|
||||||
|
Dot11TypeMgmtBeacon Dot11Type = 0x20
|
||||||
|
Dot11TypeMgmtATIM Dot11Type = 0x24
|
||||||
|
Dot11TypeMgmtDisassociation Dot11Type = 0x28
|
||||||
|
Dot11TypeMgmtAuthentication Dot11Type = 0x2c
|
||||||
|
Dot11TypeMgmtDeauthentication Dot11Type = 0x30
|
||||||
|
Dot11TypeMgmtAction Dot11Type = 0x34
|
||||||
|
Dot11TypeMgmtActionNoAck Dot11Type = 0x38
|
||||||
|
|
||||||
|
// Control
|
||||||
|
Dot11TypeCtrlWrapper Dot11Type = 0x1d
|
||||||
|
Dot11TypeCtrlBlockAckReq Dot11Type = 0x21
|
||||||
|
Dot11TypeCtrlBlockAck Dot11Type = 0x25
|
||||||
|
Dot11TypeCtrlPowersavePoll Dot11Type = 0x29
|
||||||
|
Dot11TypeCtrlRTS Dot11Type = 0x2d
|
||||||
|
Dot11TypeCtrlCTS Dot11Type = 0x31
|
||||||
|
Dot11TypeCtrlAck Dot11Type = 0x35
|
||||||
|
Dot11TypeCtrlCFEnd Dot11Type = 0x39
|
||||||
|
Dot11TypeCtrlCFEndAck Dot11Type = 0x3d
|
||||||
|
|
||||||
|
// Data
|
||||||
|
Dot11TypeDataCFAck Dot11Type = 0x06
|
||||||
|
Dot11TypeDataCFPoll Dot11Type = 0x0a
|
||||||
|
Dot11TypeDataCFAckPoll Dot11Type = 0x0e
|
||||||
|
Dot11TypeDataNull Dot11Type = 0x12
|
||||||
|
Dot11TypeDataCFAckNoData Dot11Type = 0x16
|
||||||
|
Dot11TypeDataCFPollNoData Dot11Type = 0x1a
|
||||||
|
Dot11TypeDataCFAckPollNoData Dot11Type = 0x1e
|
||||||
|
Dot11TypeDataQOSData Dot11Type = 0x22
|
||||||
|
Dot11TypeDataQOSDataCFAck Dot11Type = 0x26
|
||||||
|
Dot11TypeDataQOSDataCFPoll Dot11Type = 0x2a
|
||||||
|
Dot11TypeDataQOSDataCFAckPoll Dot11Type = 0x2e
|
||||||
|
Dot11TypeDataQOSNull Dot11Type = 0x32
|
||||||
|
Dot11TypeDataQOSCFPollNoData Dot11Type = 0x3a
|
||||||
|
Dot11TypeDataQOSCFAckPollNoData Dot11Type = 0x3e
|
||||||
|
)
|
||||||
|
|
||||||
|
// Decode a raw v4 or v6 IP packet.
|
||||||
|
func decodeIPv4or6(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
version := data[0] >> 4
|
||||||
|
switch version {
|
||||||
|
case 4:
|
||||||
|
return decodeIPv4(data, p)
|
||||||
|
case 6:
|
||||||
|
return decodeIPv6(data, p)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid IP packet version %v", version)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initActualTypeData() {
|
||||||
|
// Each of the XXXTypeMetadata arrays contains mappings of how to handle enum
|
||||||
|
// values for various enum types in gopacket/layers.
|
||||||
|
// These arrays are actually created by gen2.go and stored in
|
||||||
|
// enums_generated.go.
|
||||||
|
//
|
||||||
|
// So, EthernetTypeMetadata[2] contains information on how to handle EthernetType
|
||||||
|
// 2, including which name to give it and which decoder to use to decode
|
||||||
|
// packet data of that type. These arrays are filled by default with all of the
|
||||||
|
// protocols gopacket/layers knows how to handle, but users of the library can
|
||||||
|
// add new decoders or override existing ones. For example, if you write a better
|
||||||
|
// TCP decoder, you can override IPProtocolMetadata[IPProtocolTCP].DecodeWith
|
||||||
|
// with your new decoder, and all gopacket/layers decoding will use your new
|
||||||
|
// decoder whenever they encounter that IPProtocol.
|
||||||
|
|
||||||
|
// Here we link up all enumerations with their respective names and decoders.
|
||||||
|
EthernetTypeMetadata[EthernetTypeLLC] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLLC), Name: "LLC", LayerType: LayerTypeLLC}
|
||||||
|
EthernetTypeMetadata[EthernetTypeIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4}
|
||||||
|
EthernetTypeMetadata[EthernetTypeIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6}
|
||||||
|
EthernetTypeMetadata[EthernetTypeARP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeARP), Name: "ARP", LayerType: LayerTypeARP}
|
||||||
|
EthernetTypeMetadata[EthernetTypeDot1Q] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot1Q), Name: "Dot1Q", LayerType: LayerTypeDot1Q}
|
||||||
|
EthernetTypeMetadata[EthernetTypePPP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPP), Name: "PPP", LayerType: LayerTypePPP}
|
||||||
|
EthernetTypeMetadata[EthernetTypePPPoEDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPPoE), Name: "PPPoEDiscovery", LayerType: LayerTypePPPoE}
|
||||||
|
EthernetTypeMetadata[EthernetTypePPPoESession] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPPoE), Name: "PPPoESession", LayerType: LayerTypePPPoE}
|
||||||
|
EthernetTypeMetadata[EthernetTypeEthernetCTP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernetCTP), Name: "EthernetCTP", LayerType: LayerTypeEthernetCTP}
|
||||||
|
EthernetTypeMetadata[EthernetTypeCiscoDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeCiscoDiscovery), Name: "CiscoDiscovery", LayerType: LayerTypeCiscoDiscovery}
|
||||||
|
EthernetTypeMetadata[EthernetTypeNortelDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeNortelDiscovery), Name: "NortelDiscovery", LayerType: LayerTypeNortelDiscovery}
|
||||||
|
EthernetTypeMetadata[EthernetTypeLinkLayerDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLinkLayerDiscovery), Name: "LinkLayerDiscovery", LayerType: LayerTypeLinkLayerDiscovery}
|
||||||
|
EthernetTypeMetadata[EthernetTypeMPLSUnicast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: "MPLSUnicast", LayerType: LayerTypeMPLS}
|
||||||
|
EthernetTypeMetadata[EthernetTypeMPLSMulticast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: "MPLSMulticast", LayerType: LayerTypeMPLS}
|
||||||
|
EthernetTypeMetadata[EthernetTypeEAPOL] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAPOL), Name: "EAPOL", LayerType: LayerTypeEAPOL}
|
||||||
|
EthernetTypeMetadata[EthernetTypeQinQ] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot1Q), Name: "Dot1Q", LayerType: LayerTypeDot1Q}
|
||||||
|
EthernetTypeMetadata[EthernetTypeTransparentEthernetBridging] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernet), Name: "TransparentEthernetBridging", LayerType: LayerTypeEthernet}
|
||||||
|
EthernetTypeMetadata[EthernetTypeERSPAN] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeERSPANII), Name: "ERSPAN Type II", LayerType: LayerTypeERSPANII}
|
||||||
|
|
||||||
|
IPProtocolMetadata[IPProtocolIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4}
|
||||||
|
IPProtocolMetadata[IPProtocolTCP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeTCP), Name: "TCP", LayerType: LayerTypeTCP}
|
||||||
|
IPProtocolMetadata[IPProtocolUDP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUDP), Name: "UDP", LayerType: LayerTypeUDP}
|
||||||
|
IPProtocolMetadata[IPProtocolICMPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeICMPv4), Name: "ICMPv4", LayerType: LayerTypeICMPv4}
|
||||||
|
IPProtocolMetadata[IPProtocolICMPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeICMPv6), Name: "ICMPv6", LayerType: LayerTypeICMPv6}
|
||||||
|
IPProtocolMetadata[IPProtocolSCTP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTP), Name: "SCTP", LayerType: LayerTypeSCTP}
|
||||||
|
IPProtocolMetadata[IPProtocolIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6}
|
||||||
|
IPProtocolMetadata[IPProtocolIPIP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4}
|
||||||
|
IPProtocolMetadata[IPProtocolEtherIP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEtherIP), Name: "EtherIP", LayerType: LayerTypeEtherIP}
|
||||||
|
IPProtocolMetadata[IPProtocolRUDP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeRUDP), Name: "RUDP", LayerType: LayerTypeRUDP}
|
||||||
|
IPProtocolMetadata[IPProtocolGRE] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeGRE), Name: "GRE", LayerType: LayerTypeGRE}
|
||||||
|
IPProtocolMetadata[IPProtocolIPv6HopByHop] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6HopByHop), Name: "IPv6HopByHop", LayerType: LayerTypeIPv6HopByHop}
|
||||||
|
IPProtocolMetadata[IPProtocolIPv6Routing] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6Routing), Name: "IPv6Routing", LayerType: LayerTypeIPv6Routing}
|
||||||
|
IPProtocolMetadata[IPProtocolIPv6Fragment] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6Fragment), Name: "IPv6Fragment", LayerType: LayerTypeIPv6Fragment}
|
||||||
|
IPProtocolMetadata[IPProtocolIPv6Destination] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6Destination), Name: "IPv6Destination", LayerType: LayerTypeIPv6Destination}
|
||||||
|
IPProtocolMetadata[IPProtocolOSPF] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeOSPF), Name: "OSPF", LayerType: LayerTypeOSPF}
|
||||||
|
IPProtocolMetadata[IPProtocolAH] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPSecAH), Name: "IPSecAH", LayerType: LayerTypeIPSecAH}
|
||||||
|
IPProtocolMetadata[IPProtocolESP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPSecESP), Name: "IPSecESP", LayerType: LayerTypeIPSecESP}
|
||||||
|
IPProtocolMetadata[IPProtocolUDPLite] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUDPLite), Name: "UDPLite", LayerType: LayerTypeUDPLite}
|
||||||
|
IPProtocolMetadata[IPProtocolMPLSInIP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: "MPLS", LayerType: LayerTypeMPLS}
|
||||||
|
IPProtocolMetadata[IPProtocolNoNextHeader] = EnumMetadata{DecodeWith: gopacket.DecodePayload, Name: "NoNextHeader", LayerType: gopacket.LayerTypePayload}
|
||||||
|
IPProtocolMetadata[IPProtocolIGMP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIGMP), Name: "IGMP", LayerType: LayerTypeIGMP}
|
||||||
|
IPProtocolMetadata[IPProtocolVRRP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeVRRP), Name: "VRRP", LayerType: LayerTypeVRRP}
|
||||||
|
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPData), Name: "Data"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeInit] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPInit), Name: "Init"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeInitAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPInit), Name: "InitAck"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeSack] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPSack), Name: "Sack"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeHeartbeat] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPHeartbeat), Name: "Heartbeat"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeHeartbeatAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPHeartbeat), Name: "HeartbeatAck"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeAbort] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPError), Name: "Abort"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeError] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPError), Name: "Error"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeShutdown] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPShutdown), Name: "Shutdown"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeShutdownAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPShutdownAck), Name: "ShutdownAck"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeCookieEcho] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPCookieEcho), Name: "CookieEcho"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeCookieAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPEmptyLayer), Name: "CookieAck"}
|
||||||
|
SCTPChunkTypeMetadata[SCTPChunkTypeShutdownComplete] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPEmptyLayer), Name: "ShutdownComplete"}
|
||||||
|
|
||||||
|
PPPTypeMetadata[PPPTypeIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4"}
|
||||||
|
PPPTypeMetadata[PPPTypeIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6"}
|
||||||
|
PPPTypeMetadata[PPPTypeMPLSUnicast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: "MPLSUnicast"}
|
||||||
|
PPPTypeMetadata[PPPTypeMPLSMulticast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: "MPLSMulticast"}
|
||||||
|
|
||||||
|
PPPoECodeMetadata[PPPoECodeSession] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPP), Name: "PPP"}
|
||||||
|
|
||||||
|
LinkTypeMetadata[LinkTypeEthernet] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernet), Name: "Ethernet"}
|
||||||
|
LinkTypeMetadata[LinkTypePPP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPP), Name: "PPP"}
|
||||||
|
LinkTypeMetadata[LinkTypeFDDI] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeFDDI), Name: "FDDI"}
|
||||||
|
LinkTypeMetadata[LinkTypeNull] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLoopback), Name: "Null"}
|
||||||
|
LinkTypeMetadata[LinkTypeIEEE802_11] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11), Name: "Dot11"}
|
||||||
|
LinkTypeMetadata[LinkTypeLoop] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLoopback), Name: "Loop"}
|
||||||
|
LinkTypeMetadata[LinkTypeIEEE802_11] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11), Name: "802.11"}
|
||||||
|
LinkTypeMetadata[LinkTypeRaw] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: "Raw"}
|
||||||
|
// See https://github.com/the-tcpdump-group/libpcap/blob/170f717e6e818cdc4bcbbfd906b63088eaa88fa0/pcap/dlt.h#L85
|
||||||
|
// Or https://github.com/wireshark/wireshark/blob/854cfe53efe44080609c78053ecfb2342ad84a08/wiretap/pcap-common.c#L508
|
||||||
|
if runtime.GOOS == "openbsd" {
|
||||||
|
LinkTypeMetadata[14] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: "Raw"}
|
||||||
|
} else {
|
||||||
|
LinkTypeMetadata[12] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: "Raw"}
|
||||||
|
}
|
||||||
|
LinkTypeMetadata[LinkTypePFLog] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePFLog), Name: "PFLog"}
|
||||||
|
LinkTypeMetadata[LinkTypeIEEE80211Radio] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeRadioTap), Name: "RadioTap"}
|
||||||
|
LinkTypeMetadata[LinkTypeLinuxUSB] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSB), Name: "USB"}
|
||||||
|
LinkTypeMetadata[LinkTypeLinuxSLL] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLinuxSLL), Name: "Linux SLL"}
|
||||||
|
LinkTypeMetadata[LinkTypePrismHeader] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePrismHeader), Name: "Prism"}
|
||||||
|
|
||||||
|
FDDIFrameControlMetadata[FDDIFrameControlLLC] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLLC), Name: "LLC"}
|
||||||
|
|
||||||
|
EAPOLTypeMetadata[EAPOLTypeEAP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAP), Name: "EAP", LayerType: LayerTypeEAP}
|
||||||
|
EAPOLTypeMetadata[EAPOLTypeKey] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAPOLKey), Name: "EAPOLKey", LayerType: LayerTypeEAPOLKey}
|
||||||
|
|
||||||
|
ProtocolFamilyMetadata[ProtocolFamilyIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4}
|
||||||
|
ProtocolFamilyMetadata[ProtocolFamilyIPv6BSD] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6}
|
||||||
|
ProtocolFamilyMetadata[ProtocolFamilyIPv6FreeBSD] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6}
|
||||||
|
ProtocolFamilyMetadata[ProtocolFamilyIPv6Darwin] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6}
|
||||||
|
ProtocolFamilyMetadata[ProtocolFamilyIPv6Linux] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6}
|
||||||
|
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtAssociationReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAssociationReq), Name: "MgmtAssociationReq", LayerType: LayerTypeDot11MgmtAssociationReq}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtAssociationResp] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAssociationResp), Name: "MgmtAssociationResp", LayerType: LayerTypeDot11MgmtAssociationResp}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtReassociationReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtReassociationReq), Name: "MgmtReassociationReq", LayerType: LayerTypeDot11MgmtReassociationReq}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtReassociationResp] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtReassociationResp), Name: "MgmtReassociationResp", LayerType: LayerTypeDot11MgmtReassociationResp}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtProbeReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtProbeReq), Name: "MgmtProbeReq", LayerType: LayerTypeDot11MgmtProbeReq}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtProbeResp] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtProbeResp), Name: "MgmtProbeResp", LayerType: LayerTypeDot11MgmtProbeResp}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtMeasurementPilot] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot), Name: "MgmtMeasurementPilot", LayerType: LayerTypeDot11MgmtMeasurementPilot}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtBeacon] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtBeacon), Name: "MgmtBeacon", LayerType: LayerTypeDot11MgmtBeacon}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtATIM] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtATIM), Name: "MgmtATIM", LayerType: LayerTypeDot11MgmtATIM}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtDisassociation] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtDisassociation), Name: "MgmtDisassociation", LayerType: LayerTypeDot11MgmtDisassociation}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtAuthentication] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAuthentication), Name: "MgmtAuthentication", LayerType: LayerTypeDot11MgmtAuthentication}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtDeauthentication] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtDeauthentication), Name: "MgmtDeauthentication", LayerType: LayerTypeDot11MgmtDeauthentication}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtAction] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAction), Name: "MgmtAction", LayerType: LayerTypeDot11MgmtAction}
|
||||||
|
Dot11TypeMetadata[Dot11TypeMgmtActionNoAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtActionNoAck), Name: "MgmtActionNoAck", LayerType: LayerTypeDot11MgmtActionNoAck}
|
||||||
|
Dot11TypeMetadata[Dot11TypeCtrl] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11Ctrl), Name: "Ctrl", LayerType: LayerTypeDot11Ctrl}
|
||||||
|
Dot11TypeMetadata[Dot11TypeCtrlWrapper] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11Ctrl), Name: "CtrlWrapper", LayerType: LayerTypeDot11Ctrl}
|
||||||
|
Dot11TypeMetadata[Dot11TypeCtrlBlockAckReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq), Name: "CtrlBlockAckReq", LayerType: LayerTypeDot11CtrlBlockAckReq}
|
||||||
|
Dot11TypeMetadata[Dot11TypeCtrlBlockAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlBlockAck), Name: "CtrlBlockAck", LayerType: LayerTypeDot11CtrlBlockAck}
|
||||||
|
Dot11TypeMetadata[Dot11TypeCtrlPowersavePoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll), Name: "CtrlPowersavePoll", LayerType: LayerTypeDot11CtrlPowersavePoll}
|
||||||
|
Dot11TypeMetadata[Dot11TypeCtrlRTS] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlRTS), Name: "CtrlRTS", LayerType: LayerTypeDot11CtrlRTS}
|
||||||
|
Dot11TypeMetadata[Dot11TypeCtrlCTS] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlCTS), Name: "CtrlCTS", LayerType: LayerTypeDot11CtrlCTS}
|
||||||
|
Dot11TypeMetadata[Dot11TypeCtrlAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlAck), Name: "CtrlAck", LayerType: LayerTypeDot11CtrlAck}
|
||||||
|
Dot11TypeMetadata[Dot11TypeCtrlCFEnd] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlCFEnd), Name: "CtrlCFEnd", LayerType: LayerTypeDot11CtrlCFEnd}
|
||||||
|
Dot11TypeMetadata[Dot11TypeCtrlCFEndAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlCFEndAck), Name: "CtrlCFEndAck", LayerType: LayerTypeDot11CtrlCFEndAck}
|
||||||
|
Dot11TypeMetadata[Dot11TypeData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11Data), Name: "Data", LayerType: LayerTypeDot11Data}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataCFAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAck), Name: "DataCFAck", LayerType: LayerTypeDot11DataCFAck}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataCFPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFPoll), Name: "DataCFPoll", LayerType: LayerTypeDot11DataCFPoll}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataCFAckPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAckPoll), Name: "DataCFAckPoll", LayerType: LayerTypeDot11DataCFAckPoll}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataNull] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataNull), Name: "DataNull", LayerType: LayerTypeDot11DataNull}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataCFAckNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAckNoData), Name: "DataCFAckNoData", LayerType: LayerTypeDot11DataCFAckNoData}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataCFPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFPollNoData), Name: "DataCFPollNoData", LayerType: LayerTypeDot11DataCFPollNoData}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataCFAckPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAckPollNoData), Name: "DataCFAckPollNoData", LayerType: LayerTypeDot11DataCFAckPollNoData}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataQOSData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSData), Name: "DataQOSData", LayerType: LayerTypeDot11DataQOSData}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataQOSDataCFAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck), Name: "DataQOSDataCFAck", LayerType: LayerTypeDot11DataQOSDataCFAck}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataQOSDataCFPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll), Name: "DataQOSDataCFPoll", LayerType: LayerTypeDot11DataQOSDataCFPoll}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataQOSDataCFAckPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll), Name: "DataQOSDataCFAckPoll", LayerType: LayerTypeDot11DataQOSDataCFAckPoll}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataQOSNull] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSNull), Name: "DataQOSNull", LayerType: LayerTypeDot11DataQOSNull}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataQOSCFPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData), Name: "DataQOSCFPollNoData", LayerType: LayerTypeDot11DataQOSCFPollNoData}
|
||||||
|
Dot11TypeMetadata[Dot11TypeDataQOSCFAckPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData), Name: "DataQOSCFAckPollNoData", LayerType: LayerTypeDot11DataQOSCFAckPollNoData}
|
||||||
|
|
||||||
|
USBTransportTypeMetadata[USBTransportTypeInterrupt] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBInterrupt), Name: "Interrupt", LayerType: LayerTypeUSBInterrupt}
|
||||||
|
USBTransportTypeMetadata[USBTransportTypeControl] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBControl), Name: "Control", LayerType: LayerTypeUSBControl}
|
||||||
|
USBTransportTypeMetadata[USBTransportTypeBulk] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBBulk), Name: "Bulk", LayerType: LayerTypeUSBBulk}
|
||||||
|
}
|
434
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/enums_generated.go
generated
vendored
Normal file
434
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/enums_generated.go
generated
vendored
Normal file
|
@ -0,0 +1,434 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
|
||||||
|
package layers
|
||||||
|
|
||||||
|
// Created by gen2.go, don't edit manually
|
||||||
|
// Generated at 2017-10-23 10:20:24.458771856 -0600 MDT m=+0.001159033
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
initUnknownTypesForLinkType()
|
||||||
|
initUnknownTypesForEthernetType()
|
||||||
|
initUnknownTypesForPPPType()
|
||||||
|
initUnknownTypesForIPProtocol()
|
||||||
|
initUnknownTypesForSCTPChunkType()
|
||||||
|
initUnknownTypesForPPPoECode()
|
||||||
|
initUnknownTypesForFDDIFrameControl()
|
||||||
|
initUnknownTypesForEAPOLType()
|
||||||
|
initUnknownTypesForProtocolFamily()
|
||||||
|
initUnknownTypesForDot11Type()
|
||||||
|
initUnknownTypesForUSBTransportType()
|
||||||
|
initActualTypeData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls LinkTypeMetadata.DecodeWith's decoder.
|
||||||
|
func (a LinkType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return LinkTypeMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns LinkTypeMetadata.Name.
|
||||||
|
func (a LinkType) String() string {
|
||||||
|
return LinkTypeMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LinkTypeMetadata.LayerType.
|
||||||
|
func (a LinkType) LayerType() gopacket.LayerType {
|
||||||
|
return LinkTypeMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForLinkType int
|
||||||
|
|
||||||
|
func (a *errorDecoderForLinkType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForLinkType) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode LinkType %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForLinkType [256]errorDecoderForLinkType
|
||||||
|
var LinkTypeMetadata [256]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForLinkType() {
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
errorDecodersForLinkType[i] = errorDecoderForLinkType(i)
|
||||||
|
LinkTypeMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForLinkType[i],
|
||||||
|
Name: "UnknownLinkType",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls EthernetTypeMetadata.DecodeWith's decoder.
|
||||||
|
func (a EthernetType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return EthernetTypeMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns EthernetTypeMetadata.Name.
|
||||||
|
func (a EthernetType) String() string {
|
||||||
|
return EthernetTypeMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns EthernetTypeMetadata.LayerType.
|
||||||
|
func (a EthernetType) LayerType() gopacket.LayerType {
|
||||||
|
return EthernetTypeMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForEthernetType int
|
||||||
|
|
||||||
|
func (a *errorDecoderForEthernetType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForEthernetType) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode EthernetType %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForEthernetType [65536]errorDecoderForEthernetType
|
||||||
|
var EthernetTypeMetadata [65536]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForEthernetType() {
|
||||||
|
for i := 0; i < 65536; i++ {
|
||||||
|
errorDecodersForEthernetType[i] = errorDecoderForEthernetType(i)
|
||||||
|
EthernetTypeMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForEthernetType[i],
|
||||||
|
Name: "UnknownEthernetType",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls PPPTypeMetadata.DecodeWith's decoder.
|
||||||
|
func (a PPPType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return PPPTypeMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns PPPTypeMetadata.Name.
|
||||||
|
func (a PPPType) String() string {
|
||||||
|
return PPPTypeMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns PPPTypeMetadata.LayerType.
|
||||||
|
func (a PPPType) LayerType() gopacket.LayerType {
|
||||||
|
return PPPTypeMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForPPPType int
|
||||||
|
|
||||||
|
func (a *errorDecoderForPPPType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForPPPType) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode PPPType %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForPPPType [65536]errorDecoderForPPPType
|
||||||
|
var PPPTypeMetadata [65536]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForPPPType() {
|
||||||
|
for i := 0; i < 65536; i++ {
|
||||||
|
errorDecodersForPPPType[i] = errorDecoderForPPPType(i)
|
||||||
|
PPPTypeMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForPPPType[i],
|
||||||
|
Name: "UnknownPPPType",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls IPProtocolMetadata.DecodeWith's decoder.
|
||||||
|
func (a IPProtocol) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return IPProtocolMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns IPProtocolMetadata.Name.
|
||||||
|
func (a IPProtocol) String() string {
|
||||||
|
return IPProtocolMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns IPProtocolMetadata.LayerType.
|
||||||
|
func (a IPProtocol) LayerType() gopacket.LayerType {
|
||||||
|
return IPProtocolMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForIPProtocol int
|
||||||
|
|
||||||
|
func (a *errorDecoderForIPProtocol) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForIPProtocol) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode IPProtocol %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForIPProtocol [256]errorDecoderForIPProtocol
|
||||||
|
var IPProtocolMetadata [256]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForIPProtocol() {
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
errorDecodersForIPProtocol[i] = errorDecoderForIPProtocol(i)
|
||||||
|
IPProtocolMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForIPProtocol[i],
|
||||||
|
Name: "UnknownIPProtocol",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls SCTPChunkTypeMetadata.DecodeWith's decoder.
|
||||||
|
func (a SCTPChunkType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return SCTPChunkTypeMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns SCTPChunkTypeMetadata.Name.
|
||||||
|
func (a SCTPChunkType) String() string {
|
||||||
|
return SCTPChunkTypeMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns SCTPChunkTypeMetadata.LayerType.
|
||||||
|
func (a SCTPChunkType) LayerType() gopacket.LayerType {
|
||||||
|
return SCTPChunkTypeMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForSCTPChunkType int
|
||||||
|
|
||||||
|
func (a *errorDecoderForSCTPChunkType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForSCTPChunkType) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode SCTPChunkType %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForSCTPChunkType [256]errorDecoderForSCTPChunkType
|
||||||
|
var SCTPChunkTypeMetadata [256]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForSCTPChunkType() {
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
errorDecodersForSCTPChunkType[i] = errorDecoderForSCTPChunkType(i)
|
||||||
|
SCTPChunkTypeMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForSCTPChunkType[i],
|
||||||
|
Name: "UnknownSCTPChunkType",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls PPPoECodeMetadata.DecodeWith's decoder.
|
||||||
|
func (a PPPoECode) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return PPPoECodeMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns PPPoECodeMetadata.Name.
|
||||||
|
func (a PPPoECode) String() string {
|
||||||
|
return PPPoECodeMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns PPPoECodeMetadata.LayerType.
|
||||||
|
func (a PPPoECode) LayerType() gopacket.LayerType {
|
||||||
|
return PPPoECodeMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForPPPoECode int
|
||||||
|
|
||||||
|
func (a *errorDecoderForPPPoECode) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForPPPoECode) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode PPPoECode %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForPPPoECode [256]errorDecoderForPPPoECode
|
||||||
|
var PPPoECodeMetadata [256]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForPPPoECode() {
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
errorDecodersForPPPoECode[i] = errorDecoderForPPPoECode(i)
|
||||||
|
PPPoECodeMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForPPPoECode[i],
|
||||||
|
Name: "UnknownPPPoECode",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls FDDIFrameControlMetadata.DecodeWith's decoder.
|
||||||
|
func (a FDDIFrameControl) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return FDDIFrameControlMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns FDDIFrameControlMetadata.Name.
|
||||||
|
func (a FDDIFrameControl) String() string {
|
||||||
|
return FDDIFrameControlMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns FDDIFrameControlMetadata.LayerType.
|
||||||
|
func (a FDDIFrameControl) LayerType() gopacket.LayerType {
|
||||||
|
return FDDIFrameControlMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForFDDIFrameControl int
|
||||||
|
|
||||||
|
func (a *errorDecoderForFDDIFrameControl) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForFDDIFrameControl) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode FDDIFrameControl %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForFDDIFrameControl [256]errorDecoderForFDDIFrameControl
|
||||||
|
var FDDIFrameControlMetadata [256]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForFDDIFrameControl() {
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
errorDecodersForFDDIFrameControl[i] = errorDecoderForFDDIFrameControl(i)
|
||||||
|
FDDIFrameControlMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForFDDIFrameControl[i],
|
||||||
|
Name: "UnknownFDDIFrameControl",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls EAPOLTypeMetadata.DecodeWith's decoder.
|
||||||
|
func (a EAPOLType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return EAPOLTypeMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns EAPOLTypeMetadata.Name.
|
||||||
|
func (a EAPOLType) String() string {
|
||||||
|
return EAPOLTypeMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns EAPOLTypeMetadata.LayerType.
|
||||||
|
func (a EAPOLType) LayerType() gopacket.LayerType {
|
||||||
|
return EAPOLTypeMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForEAPOLType int
|
||||||
|
|
||||||
|
func (a *errorDecoderForEAPOLType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForEAPOLType) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode EAPOLType %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForEAPOLType [256]errorDecoderForEAPOLType
|
||||||
|
var EAPOLTypeMetadata [256]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForEAPOLType() {
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
errorDecodersForEAPOLType[i] = errorDecoderForEAPOLType(i)
|
||||||
|
EAPOLTypeMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForEAPOLType[i],
|
||||||
|
Name: "UnknownEAPOLType",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls ProtocolFamilyMetadata.DecodeWith's decoder.
|
||||||
|
func (a ProtocolFamily) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return ProtocolFamilyMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns ProtocolFamilyMetadata.Name.
|
||||||
|
func (a ProtocolFamily) String() string {
|
||||||
|
return ProtocolFamilyMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns ProtocolFamilyMetadata.LayerType.
|
||||||
|
func (a ProtocolFamily) LayerType() gopacket.LayerType {
|
||||||
|
return ProtocolFamilyMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForProtocolFamily int
|
||||||
|
|
||||||
|
func (a *errorDecoderForProtocolFamily) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForProtocolFamily) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode ProtocolFamily %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForProtocolFamily [256]errorDecoderForProtocolFamily
|
||||||
|
var ProtocolFamilyMetadata [256]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForProtocolFamily() {
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
errorDecodersForProtocolFamily[i] = errorDecoderForProtocolFamily(i)
|
||||||
|
ProtocolFamilyMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForProtocolFamily[i],
|
||||||
|
Name: "UnknownProtocolFamily",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls Dot11TypeMetadata.DecodeWith's decoder.
|
||||||
|
func (a Dot11Type) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return Dot11TypeMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns Dot11TypeMetadata.Name.
|
||||||
|
func (a Dot11Type) String() string {
|
||||||
|
return Dot11TypeMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns Dot11TypeMetadata.LayerType.
|
||||||
|
func (a Dot11Type) LayerType() gopacket.LayerType {
|
||||||
|
return Dot11TypeMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForDot11Type int
|
||||||
|
|
||||||
|
func (a *errorDecoderForDot11Type) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForDot11Type) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode Dot11Type %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForDot11Type [256]errorDecoderForDot11Type
|
||||||
|
var Dot11TypeMetadata [256]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForDot11Type() {
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
errorDecodersForDot11Type[i] = errorDecoderForDot11Type(i)
|
||||||
|
Dot11TypeMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForDot11Type[i],
|
||||||
|
Name: "UnknownDot11Type",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder calls USBTransportTypeMetadata.DecodeWith's decoder.
|
||||||
|
func (a USBTransportType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return USBTransportTypeMetadata[a].DecodeWith.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns USBTransportTypeMetadata.Name.
|
||||||
|
func (a USBTransportType) String() string {
|
||||||
|
return USBTransportTypeMetadata[a].Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns USBTransportTypeMetadata.LayerType.
|
||||||
|
func (a USBTransportType) LayerType() gopacket.LayerType {
|
||||||
|
return USBTransportTypeMetadata[a].LayerType
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorDecoderForUSBTransportType int
|
||||||
|
|
||||||
|
func (a *errorDecoderForUSBTransportType) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
func (a *errorDecoderForUSBTransportType) Error() string {
|
||||||
|
return fmt.Sprintf("Unable to decode USBTransportType %d", int(*a))
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorDecodersForUSBTransportType [256]errorDecoderForUSBTransportType
|
||||||
|
var USBTransportTypeMetadata [256]EnumMetadata
|
||||||
|
|
||||||
|
func initUnknownTypesForUSBTransportType() {
|
||||||
|
for i := 0; i < 256; i++ {
|
||||||
|
errorDecodersForUSBTransportType[i] = errorDecoderForUSBTransportType(i)
|
||||||
|
USBTransportTypeMetadata[i] = EnumMetadata{
|
||||||
|
DecodeWith: &errorDecodersForUSBTransportType[i],
|
||||||
|
Name: "UnknownUSBTransportType",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
86
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/erspan2.go
generated
vendored
Normal file
86
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/erspan2.go
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// Copyright 2018 Google, Inc. 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
//ERSPANIIVersionObsolete - The obsolete value for the version field
|
||||||
|
ERSPANIIVersionObsolete = 0x0
|
||||||
|
// ERSPANIIVersion - The current value for the version field
|
||||||
|
ERSPANIIVersion = 0x1
|
||||||
|
)
|
||||||
|
|
||||||
|
// ERSPANII contains all of the fields found in an ERSPAN Type II header
|
||||||
|
// https://tools.ietf.org/html/draft-foschiano-erspan-03
|
||||||
|
type ERSPANII struct {
|
||||||
|
BaseLayer
|
||||||
|
IsTruncated bool
|
||||||
|
Version, CoS, TrunkEncap uint8
|
||||||
|
VLANIdentifier, SessionID, Reserved uint16
|
||||||
|
Index uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (erspan2 *ERSPANII) LayerType() gopacket.LayerType { return LayerTypeERSPANII }
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (erspan2 *ERSPANII) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
erspan2Length := 8
|
||||||
|
erspan2.Version = data[0] & 0xF0 >> 4
|
||||||
|
erspan2.VLANIdentifier = binary.BigEndian.Uint16(data[:2]) & 0x0FFF
|
||||||
|
erspan2.CoS = data[2] & 0xE0 >> 5
|
||||||
|
erspan2.TrunkEncap = data[2] & 0x18 >> 3
|
||||||
|
erspan2.IsTruncated = data[2]&0x4>>2 != 0
|
||||||
|
erspan2.SessionID = binary.BigEndian.Uint16(data[2:4]) & 0x03FF
|
||||||
|
erspan2.Reserved = binary.BigEndian.Uint16(data[4:6]) & 0xFFF0 >> 4
|
||||||
|
erspan2.Index = binary.BigEndian.Uint32(data[4:8]) & 0x000FFFFF
|
||||||
|
erspan2.Contents = data[:erspan2Length]
|
||||||
|
erspan2.Payload = data[erspan2Length:]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (erspan2 *ERSPANII) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(8)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
twoByteInt := uint16(erspan2.Version&0xF)<<12 | erspan2.VLANIdentifier&0x0FFF
|
||||||
|
binary.BigEndian.PutUint16(bytes, twoByteInt)
|
||||||
|
|
||||||
|
twoByteInt = uint16(erspan2.CoS&0x7)<<13 | uint16(erspan2.TrunkEncap&0x3)<<11 | erspan2.SessionID&0x03FF
|
||||||
|
if erspan2.IsTruncated {
|
||||||
|
twoByteInt |= 0x400
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], twoByteInt)
|
||||||
|
|
||||||
|
fourByteInt := uint32(erspan2.Reserved&0x0FFF)<<20 | erspan2.Index&0x000FFFFF
|
||||||
|
binary.BigEndian.PutUint32(bytes[4:], fourByteInt)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (erspan2 *ERSPANII) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeERSPANII
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (erspan2 *ERSPANII) NextLayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeEthernet
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeERSPANII(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
erspan2 := &ERSPANII{}
|
||||||
|
return decodingLayerDecoder(erspan2, data, p)
|
||||||
|
}
|
45
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/etherip.go
generated
vendored
Normal file
45
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/etherip.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EtherIP is the struct for storing RFC 3378 EtherIP packet headers.
|
||||||
|
type EtherIP struct {
|
||||||
|
BaseLayer
|
||||||
|
Version uint8
|
||||||
|
Reserved uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeEtherIP.
|
||||||
|
func (e *EtherIP) LayerType() gopacket.LayerType { return LayerTypeEtherIP }
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (e *EtherIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
e.Version = data[0] >> 4
|
||||||
|
e.Reserved = binary.BigEndian.Uint16(data[:2]) & 0x0fff
|
||||||
|
e.BaseLayer = BaseLayer{data[:2], data[2:]}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (e *EtherIP) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeEtherIP
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (e *EtherIP) NextLayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeEthernet
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeEtherIP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
e := &EtherIP{}
|
||||||
|
return decodingLayerDecoder(e, data, p)
|
||||||
|
}
|
123
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ethernet.go
generated
vendored
Normal file
123
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ethernet.go
generated
vendored
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EthernetBroadcast is the broadcast MAC address used by Ethernet.
|
||||||
|
var EthernetBroadcast = net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
|
||||||
|
|
||||||
|
// Ethernet is the layer for Ethernet frame headers.
|
||||||
|
type Ethernet struct {
|
||||||
|
BaseLayer
|
||||||
|
SrcMAC, DstMAC net.HardwareAddr
|
||||||
|
EthernetType EthernetType
|
||||||
|
// Length is only set if a length field exists within this header. Ethernet
|
||||||
|
// headers follow two different standards, one that uses an EthernetType, the
|
||||||
|
// other which defines a length the follows with a LLC header (802.3). If the
|
||||||
|
// former is the case, we set EthernetType and Length stays 0. In the latter
|
||||||
|
// case, we set Length and EthernetType = EthernetTypeLLC.
|
||||||
|
Length uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeEthernet
|
||||||
|
func (e *Ethernet) LayerType() gopacket.LayerType { return LayerTypeEthernet }
|
||||||
|
|
||||||
|
func (e *Ethernet) LinkFlow() gopacket.Flow {
|
||||||
|
return gopacket.NewFlow(EndpointMAC, e.SrcMAC, e.DstMAC)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (eth *Ethernet) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 14 {
|
||||||
|
return errors.New("Ethernet packet too small")
|
||||||
|
}
|
||||||
|
eth.DstMAC = net.HardwareAddr(data[0:6])
|
||||||
|
eth.SrcMAC = net.HardwareAddr(data[6:12])
|
||||||
|
eth.EthernetType = EthernetType(binary.BigEndian.Uint16(data[12:14]))
|
||||||
|
eth.BaseLayer = BaseLayer{data[:14], data[14:]}
|
||||||
|
eth.Length = 0
|
||||||
|
if eth.EthernetType < 0x0600 {
|
||||||
|
eth.Length = uint16(eth.EthernetType)
|
||||||
|
eth.EthernetType = EthernetTypeLLC
|
||||||
|
if cmp := len(eth.Payload) - int(eth.Length); cmp < 0 {
|
||||||
|
df.SetTruncated()
|
||||||
|
} else if cmp > 0 {
|
||||||
|
// Strip off bytes at the end, since we have too many bytes
|
||||||
|
eth.Payload = eth.Payload[:len(eth.Payload)-cmp]
|
||||||
|
}
|
||||||
|
// fmt.Println(eth)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (eth *Ethernet) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if len(eth.DstMAC) != 6 {
|
||||||
|
return fmt.Errorf("invalid dst MAC: %v", eth.DstMAC)
|
||||||
|
}
|
||||||
|
if len(eth.SrcMAC) != 6 {
|
||||||
|
return fmt.Errorf("invalid src MAC: %v", eth.SrcMAC)
|
||||||
|
}
|
||||||
|
payload := b.Bytes()
|
||||||
|
bytes, err := b.PrependBytes(14)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
copy(bytes, eth.DstMAC)
|
||||||
|
copy(bytes[6:], eth.SrcMAC)
|
||||||
|
if eth.Length != 0 || eth.EthernetType == EthernetTypeLLC {
|
||||||
|
if opts.FixLengths {
|
||||||
|
eth.Length = uint16(len(payload))
|
||||||
|
}
|
||||||
|
if eth.EthernetType != EthernetTypeLLC {
|
||||||
|
return fmt.Errorf("ethernet type %v not compatible with length value %v", eth.EthernetType, eth.Length)
|
||||||
|
} else if eth.Length > 0x0600 {
|
||||||
|
return fmt.Errorf("invalid ethernet length %v", eth.Length)
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes[12:], eth.Length)
|
||||||
|
} else {
|
||||||
|
binary.BigEndian.PutUint16(bytes[12:], uint16(eth.EthernetType))
|
||||||
|
}
|
||||||
|
length := len(b.Bytes())
|
||||||
|
if length < 60 {
|
||||||
|
// Pad out to 60 bytes.
|
||||||
|
padding, err := b.AppendBytes(60 - length)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
copy(padding, lotsOfZeros[:])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (eth *Ethernet) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeEthernet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (eth *Ethernet) NextLayerType() gopacket.LayerType {
|
||||||
|
return eth.EthernetType.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeEthernet(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
eth := &Ethernet{}
|
||||||
|
err := eth.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(eth)
|
||||||
|
p.SetLinkLayer(eth)
|
||||||
|
return p.NextDecoder(eth.EthernetType)
|
||||||
|
}
|
41
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/fddi.go
generated
vendored
Normal file
41
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/fddi.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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 (
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FDDI contains the header for FDDI frames.
|
||||||
|
type FDDI struct {
|
||||||
|
BaseLayer
|
||||||
|
FrameControl FDDIFrameControl
|
||||||
|
Priority uint8
|
||||||
|
SrcMAC, DstMAC net.HardwareAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeFDDI.
|
||||||
|
func (f *FDDI) LayerType() gopacket.LayerType { return LayerTypeFDDI }
|
||||||
|
|
||||||
|
// LinkFlow returns a new flow of type EndpointMAC.
|
||||||
|
func (f *FDDI) LinkFlow() gopacket.Flow {
|
||||||
|
return gopacket.NewFlow(EndpointMAC, f.SrcMAC, f.DstMAC)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeFDDI(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
f := &FDDI{
|
||||||
|
FrameControl: FDDIFrameControl(data[0] & 0xF8),
|
||||||
|
Priority: data[0] & 0x07,
|
||||||
|
SrcMAC: net.HardwareAddr(data[1:7]),
|
||||||
|
DstMAC: net.HardwareAddr(data[7:13]),
|
||||||
|
BaseLayer: BaseLayer{data[:13], data[13:]},
|
||||||
|
}
|
||||||
|
p.SetLinkLayer(f)
|
||||||
|
p.AddLayer(f)
|
||||||
|
return p.NextDecoder(f.FrameControl)
|
||||||
|
}
|
39
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/fuzz_layer.go
generated
vendored
Normal file
39
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/fuzz_layer.go
generated
vendored
Normal file
|
@ -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
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/gen_linted.sh
generated
vendored
Normal file
3
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/gen_linted.sh
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
for i in *.go; do golint $i | grep -q . || echo $i; done > .linted
|
121
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/geneve.go
generated
vendored
Normal file
121
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/geneve.go
generated
vendored
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
// Copyright 2016 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Geneve is specifed here https://tools.ietf.org/html/draft-ietf-nvo3-geneve-03
|
||||||
|
// Geneve Header:
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// |Ver| Opt Len |O|C| Rsvd. | Protocol Type |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Virtual Network Identifier (VNI) | Reserved |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Variable Length Options |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
type Geneve struct {
|
||||||
|
BaseLayer
|
||||||
|
Version uint8 // 2 bits
|
||||||
|
OptionsLength uint8 // 6 bits
|
||||||
|
OAMPacket bool // 1 bits
|
||||||
|
CriticalOption bool // 1 bits
|
||||||
|
Protocol EthernetType // 16 bits
|
||||||
|
VNI uint32 // 24bits
|
||||||
|
Options []*GeneveOption
|
||||||
|
}
|
||||||
|
|
||||||
|
// Geneve Tunnel Options
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Option Class | Type |R|R|R| Length |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Variable Option Data |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
type GeneveOption struct {
|
||||||
|
Class uint16 // 16 bits
|
||||||
|
Type uint8 // 8 bits
|
||||||
|
Flags uint8 // 3 bits
|
||||||
|
Length uint8 // 5 bits
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeGeneve
|
||||||
|
func (gn *Geneve) LayerType() gopacket.LayerType { return LayerTypeGeneve }
|
||||||
|
|
||||||
|
func decodeGeneveOption(data []byte, gn *Geneve, df gopacket.DecodeFeedback) (*GeneveOption, uint8, error) {
|
||||||
|
if len(data) < 3 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return nil, 0, errors.New("geneve option too small")
|
||||||
|
}
|
||||||
|
opt := &GeneveOption{}
|
||||||
|
|
||||||
|
opt.Class = binary.BigEndian.Uint16(data[0:2])
|
||||||
|
opt.Type = data[2]
|
||||||
|
opt.Flags = data[3] >> 4
|
||||||
|
opt.Length = (data[3]&0xf)*4 + 4
|
||||||
|
|
||||||
|
if len(data) < int(opt.Length) {
|
||||||
|
df.SetTruncated()
|
||||||
|
return nil, 0, errors.New("geneve option too small")
|
||||||
|
}
|
||||||
|
opt.Data = make([]byte, opt.Length-4)
|
||||||
|
copy(opt.Data, data[4:opt.Length])
|
||||||
|
|
||||||
|
return opt, opt.Length, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gn *Geneve) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 7 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("geneve packet too short")
|
||||||
|
}
|
||||||
|
|
||||||
|
gn.Version = data[0] >> 7
|
||||||
|
gn.OptionsLength = (data[0] & 0x3f) * 4
|
||||||
|
|
||||||
|
gn.OAMPacket = data[1]&0x80 > 0
|
||||||
|
gn.CriticalOption = data[1]&0x40 > 0
|
||||||
|
gn.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))
|
||||||
|
|
||||||
|
var buf [4]byte
|
||||||
|
copy(buf[1:], data[4:7])
|
||||||
|
gn.VNI = binary.BigEndian.Uint32(buf[:])
|
||||||
|
|
||||||
|
offset, length := uint8(8), int32(gn.OptionsLength)
|
||||||
|
if len(data) < int(length+7) {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("geneve packet too short")
|
||||||
|
}
|
||||||
|
|
||||||
|
for length > 0 {
|
||||||
|
opt, len, err := decodeGeneveOption(data[offset:], gn, df)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
gn.Options = append(gn.Options, opt)
|
||||||
|
|
||||||
|
length -= int32(len)
|
||||||
|
offset += len
|
||||||
|
}
|
||||||
|
|
||||||
|
gn.BaseLayer = BaseLayer{data[:offset], data[offset:]}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gn *Geneve) NextLayerType() gopacket.LayerType {
|
||||||
|
return gn.Protocol.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeGeneve(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
gn := &Geneve{}
|
||||||
|
return decodingLayerDecoder(gn, data, p)
|
||||||
|
}
|
200
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/gre.go
generated
vendored
Normal file
200
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/gre.go
generated
vendored
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GRE is a Generic Routing Encapsulation header.
|
||||||
|
type GRE struct {
|
||||||
|
BaseLayer
|
||||||
|
ChecksumPresent, RoutingPresent, KeyPresent, SeqPresent, StrictSourceRoute, AckPresent bool
|
||||||
|
RecursionControl, Flags, Version uint8
|
||||||
|
Protocol EthernetType
|
||||||
|
Checksum, Offset uint16
|
||||||
|
Key, Seq, Ack uint32
|
||||||
|
*GRERouting
|
||||||
|
}
|
||||||
|
|
||||||
|
// GRERouting is GRE routing information, present if the RoutingPresent flag is
|
||||||
|
// set.
|
||||||
|
type GRERouting struct {
|
||||||
|
AddressFamily uint16
|
||||||
|
SREOffset, SRELength uint8
|
||||||
|
RoutingInformation []byte
|
||||||
|
Next *GRERouting
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeGRE.
|
||||||
|
func (g *GRE) LayerType() gopacket.LayerType { return LayerTypeGRE }
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (g *GRE) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
g.ChecksumPresent = data[0]&0x80 != 0
|
||||||
|
g.RoutingPresent = data[0]&0x40 != 0
|
||||||
|
g.KeyPresent = data[0]&0x20 != 0
|
||||||
|
g.SeqPresent = data[0]&0x10 != 0
|
||||||
|
g.StrictSourceRoute = data[0]&0x08 != 0
|
||||||
|
g.AckPresent = data[1]&0x80 != 0
|
||||||
|
g.RecursionControl = data[0] & 0x7
|
||||||
|
g.Flags = data[1] >> 3
|
||||||
|
g.Version = data[1] & 0x7
|
||||||
|
g.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))
|
||||||
|
offset := 4
|
||||||
|
if g.ChecksumPresent || g.RoutingPresent {
|
||||||
|
g.Checksum = binary.BigEndian.Uint16(data[offset : offset+2])
|
||||||
|
g.Offset = binary.BigEndian.Uint16(data[offset+2 : offset+4])
|
||||||
|
offset += 4
|
||||||
|
}
|
||||||
|
if g.KeyPresent {
|
||||||
|
g.Key = binary.BigEndian.Uint32(data[offset : offset+4])
|
||||||
|
offset += 4
|
||||||
|
}
|
||||||
|
if g.SeqPresent {
|
||||||
|
g.Seq = binary.BigEndian.Uint32(data[offset : offset+4])
|
||||||
|
offset += 4
|
||||||
|
}
|
||||||
|
if g.RoutingPresent {
|
||||||
|
tail := &g.GRERouting
|
||||||
|
for {
|
||||||
|
sre := &GRERouting{
|
||||||
|
AddressFamily: binary.BigEndian.Uint16(data[offset : offset+2]),
|
||||||
|
SREOffset: data[offset+2],
|
||||||
|
SRELength: data[offset+3],
|
||||||
|
}
|
||||||
|
sre.RoutingInformation = data[offset+4 : offset+4+int(sre.SRELength)]
|
||||||
|
offset += 4 + int(sre.SRELength)
|
||||||
|
if sre.AddressFamily == 0 && sre.SRELength == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
(*tail) = sre
|
||||||
|
tail = &sre.Next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if g.AckPresent {
|
||||||
|
g.Ack = binary.BigEndian.Uint32(data[offset : offset+4])
|
||||||
|
offset += 4
|
||||||
|
}
|
||||||
|
g.BaseLayer = BaseLayer{data[:offset], data[offset:]}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the SerializationBuffer,
|
||||||
|
// implementing gopacket.SerializableLayer. See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (g *GRE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
size := 4
|
||||||
|
if g.ChecksumPresent || g.RoutingPresent {
|
||||||
|
size += 4
|
||||||
|
}
|
||||||
|
if g.KeyPresent {
|
||||||
|
size += 4
|
||||||
|
}
|
||||||
|
if g.SeqPresent {
|
||||||
|
size += 4
|
||||||
|
}
|
||||||
|
if g.RoutingPresent {
|
||||||
|
r := g.GRERouting
|
||||||
|
for r != nil {
|
||||||
|
size += 4 + int(r.SRELength)
|
||||||
|
r = r.Next
|
||||||
|
}
|
||||||
|
size += 4
|
||||||
|
}
|
||||||
|
if g.AckPresent {
|
||||||
|
size += 4
|
||||||
|
}
|
||||||
|
buf, err := b.PrependBytes(size)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Reset any potentially dirty memory in the first 2 bytes, as these use OR to set flags.
|
||||||
|
buf[0] = 0
|
||||||
|
buf[1] = 0
|
||||||
|
if g.ChecksumPresent {
|
||||||
|
buf[0] |= 0x80
|
||||||
|
}
|
||||||
|
if g.RoutingPresent {
|
||||||
|
buf[0] |= 0x40
|
||||||
|
}
|
||||||
|
if g.KeyPresent {
|
||||||
|
buf[0] |= 0x20
|
||||||
|
}
|
||||||
|
if g.SeqPresent {
|
||||||
|
buf[0] |= 0x10
|
||||||
|
}
|
||||||
|
if g.StrictSourceRoute {
|
||||||
|
buf[0] |= 0x08
|
||||||
|
}
|
||||||
|
if g.AckPresent {
|
||||||
|
buf[1] |= 0x80
|
||||||
|
}
|
||||||
|
buf[0] |= g.RecursionControl
|
||||||
|
buf[1] |= g.Flags << 3
|
||||||
|
buf[1] |= g.Version
|
||||||
|
binary.BigEndian.PutUint16(buf[2:4], uint16(g.Protocol))
|
||||||
|
offset := 4
|
||||||
|
if g.ChecksumPresent || g.RoutingPresent {
|
||||||
|
// Don't write the checksum value yet, as we may need to compute it,
|
||||||
|
// which requires the entire header be complete.
|
||||||
|
// Instead we zeroize the memory in case it is dirty.
|
||||||
|
buf[offset] = 0
|
||||||
|
buf[offset+1] = 0
|
||||||
|
binary.BigEndian.PutUint16(buf[offset+2:offset+4], g.Offset)
|
||||||
|
offset += 4
|
||||||
|
}
|
||||||
|
if g.KeyPresent {
|
||||||
|
binary.BigEndian.PutUint32(buf[offset:offset+4], g.Key)
|
||||||
|
offset += 4
|
||||||
|
}
|
||||||
|
if g.SeqPresent {
|
||||||
|
binary.BigEndian.PutUint32(buf[offset:offset+4], g.Seq)
|
||||||
|
offset += 4
|
||||||
|
}
|
||||||
|
if g.RoutingPresent {
|
||||||
|
sre := g.GRERouting
|
||||||
|
for sre != nil {
|
||||||
|
binary.BigEndian.PutUint16(buf[offset:offset+2], sre.AddressFamily)
|
||||||
|
buf[offset+2] = sre.SREOffset
|
||||||
|
buf[offset+3] = sre.SRELength
|
||||||
|
copy(buf[offset+4:offset+4+int(sre.SRELength)], sre.RoutingInformation)
|
||||||
|
offset += 4 + int(sre.SRELength)
|
||||||
|
sre = sre.Next
|
||||||
|
}
|
||||||
|
// Terminate routing field with a "NULL" SRE.
|
||||||
|
binary.BigEndian.PutUint32(buf[offset:offset+4], 0)
|
||||||
|
}
|
||||||
|
if g.AckPresent {
|
||||||
|
binary.BigEndian.PutUint32(buf[offset:offset+4], g.Ack)
|
||||||
|
offset += 4
|
||||||
|
}
|
||||||
|
if g.ChecksumPresent {
|
||||||
|
if opts.ComputeChecksums {
|
||||||
|
g.Checksum = tcpipChecksum(b.Bytes(), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint16(buf[4:6], g.Checksum)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (g *GRE) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeGRE
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (g *GRE) NextLayerType() gopacket.LayerType {
|
||||||
|
return g.Protocol.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeGRE(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
g := &GRE{}
|
||||||
|
return decodingLayerDecoder(g, data, p)
|
||||||
|
}
|
184
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/gtp.go
generated
vendored
Normal file
184
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/gtp.go
generated
vendored
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
// Copyright 2017 Google, Inc. 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"
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const gtpMinimumSizeInBytes int = 8
|
||||||
|
|
||||||
|
// GTPExtensionHeader is used to carry extra data and enable future extensions of the GTP without the need to use another version number.
|
||||||
|
type GTPExtensionHeader struct {
|
||||||
|
Type uint8
|
||||||
|
Content []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// GTPv1U protocol is used to exchange user data over GTP tunnels across the Sx interfaces.
|
||||||
|
// Defined in https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1595
|
||||||
|
type GTPv1U struct {
|
||||||
|
BaseLayer
|
||||||
|
Version uint8
|
||||||
|
ProtocolType uint8
|
||||||
|
Reserved uint8
|
||||||
|
ExtensionHeaderFlag bool
|
||||||
|
SequenceNumberFlag bool
|
||||||
|
NPDUFlag bool
|
||||||
|
MessageType uint8
|
||||||
|
MessageLength uint16
|
||||||
|
TEID uint32
|
||||||
|
SequenceNumber uint16
|
||||||
|
NPDU uint8
|
||||||
|
GTPExtensionHeaders []GTPExtensionHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeGTPV1U
|
||||||
|
func (g *GTPv1U) LayerType() gopacket.LayerType { return LayerTypeGTPv1U }
|
||||||
|
|
||||||
|
// DecodeFromBytes analyses a byte slice and attempts to decode it as a GTPv1U packet
|
||||||
|
func (g *GTPv1U) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
hLen := gtpMinimumSizeInBytes
|
||||||
|
dLen := len(data)
|
||||||
|
if dLen < hLen {
|
||||||
|
return fmt.Errorf("GTP packet too small: %d bytes", dLen)
|
||||||
|
}
|
||||||
|
g.Version = (data[0] >> 5) & 0x07
|
||||||
|
g.ProtocolType = (data[0] >> 4) & 0x01
|
||||||
|
g.Reserved = (data[0] >> 3) & 0x01
|
||||||
|
g.SequenceNumberFlag = ((data[0] >> 1) & 0x01) == 1
|
||||||
|
g.NPDUFlag = (data[0] & 0x01) == 1
|
||||||
|
g.ExtensionHeaderFlag = ((data[0] >> 2) & 0x01) == 1
|
||||||
|
g.MessageType = data[1]
|
||||||
|
g.MessageLength = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
pLen := 8 + g.MessageLength
|
||||||
|
if uint16(dLen) < pLen {
|
||||||
|
return fmt.Errorf("GTP packet too small: %d bytes", dLen)
|
||||||
|
}
|
||||||
|
// Field used to multiplex different connections in the same GTP tunnel.
|
||||||
|
g.TEID = binary.BigEndian.Uint32(data[4:8])
|
||||||
|
cIndex := uint16(hLen)
|
||||||
|
if g.SequenceNumberFlag || g.NPDUFlag || g.ExtensionHeaderFlag {
|
||||||
|
hLen += 4
|
||||||
|
cIndex += 4
|
||||||
|
if dLen < hLen {
|
||||||
|
return fmt.Errorf("GTP packet too small: %d bytes", dLen)
|
||||||
|
}
|
||||||
|
if g.SequenceNumberFlag {
|
||||||
|
g.SequenceNumber = binary.BigEndian.Uint16(data[8:10])
|
||||||
|
}
|
||||||
|
if g.NPDUFlag {
|
||||||
|
g.NPDU = data[10]
|
||||||
|
}
|
||||||
|
if g.ExtensionHeaderFlag {
|
||||||
|
extensionFlag := true
|
||||||
|
for extensionFlag {
|
||||||
|
extensionType := uint8(data[cIndex-1])
|
||||||
|
extensionLength := uint(data[cIndex])
|
||||||
|
if extensionLength == 0 {
|
||||||
|
return fmt.Errorf("GTP packet with invalid extension header")
|
||||||
|
}
|
||||||
|
// extensionLength is in 4-octet units
|
||||||
|
lIndex := cIndex + (uint16(extensionLength) * 4)
|
||||||
|
if uint16(dLen) < lIndex {
|
||||||
|
fmt.Println(dLen, lIndex)
|
||||||
|
return fmt.Errorf("GTP packet with small extension header: %d bytes", dLen)
|
||||||
|
}
|
||||||
|
content := data[cIndex+1 : lIndex-1]
|
||||||
|
eh := GTPExtensionHeader{Type: extensionType, Content: content}
|
||||||
|
g.GTPExtensionHeaders = append(g.GTPExtensionHeaders, eh)
|
||||||
|
cIndex = lIndex
|
||||||
|
// Check if coming bytes are from an extension header
|
||||||
|
extensionFlag = data[cIndex-1] != 0
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.BaseLayer = BaseLayer{Contents: data[:cIndex], Payload: data[cIndex:]}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (g *GTPv1U) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
data, err := b.PrependBytes(gtpMinimumSizeInBytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data[0] |= (g.Version << 5)
|
||||||
|
data[0] |= (1 << 4)
|
||||||
|
if len(g.GTPExtensionHeaders) > 0 {
|
||||||
|
data[0] |= 0x04
|
||||||
|
g.ExtensionHeaderFlag = true
|
||||||
|
}
|
||||||
|
if g.SequenceNumberFlag {
|
||||||
|
data[0] |= 0x02
|
||||||
|
}
|
||||||
|
if g.NPDUFlag {
|
||||||
|
data[0] |= 0x01
|
||||||
|
}
|
||||||
|
data[1] = g.MessageType
|
||||||
|
binary.BigEndian.PutUint16(data[2:4], g.MessageLength)
|
||||||
|
binary.BigEndian.PutUint32(data[4:8], g.TEID)
|
||||||
|
if g.ExtensionHeaderFlag || g.SequenceNumberFlag || g.NPDUFlag {
|
||||||
|
data, err := b.AppendBytes(4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(data[:2], g.SequenceNumber)
|
||||||
|
data[2] = g.NPDU
|
||||||
|
for _, eh := range g.GTPExtensionHeaders {
|
||||||
|
data[len(data)-1] = eh.Type
|
||||||
|
lContent := len(eh.Content)
|
||||||
|
// extensionLength is in 4-octet units
|
||||||
|
extensionLength := (lContent + 2) / 4
|
||||||
|
// Get two extra byte for the next extension header type and length
|
||||||
|
data, err = b.AppendBytes(lContent + 2)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data[0] = byte(extensionLength)
|
||||||
|
copy(data[1:lContent+1], eh.Content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns a set of layers that GTP objects can decode.
|
||||||
|
func (g *GTPv1U) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeGTPv1U
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType specifies the next layer that GoPacket should attempt to
|
||||||
|
func (g *GTPv1U) NextLayerType() gopacket.LayerType {
|
||||||
|
if len(g.LayerPayload()) == 0 {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
version := uint8(g.LayerPayload()[0]) >> 4
|
||||||
|
if version == 4 {
|
||||||
|
return LayerTypeIPv4
|
||||||
|
} else if version == 6 {
|
||||||
|
return LayerTypeIPv6
|
||||||
|
} else {
|
||||||
|
return LayerTypePPP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeGTPv1u(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
gtp := >Pv1U{}
|
||||||
|
err := gtp.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(gtp)
|
||||||
|
return p.NextDecoder(gtp.NextLayerType())
|
||||||
|
}
|
11351
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/iana_ports.go
generated
vendored
Normal file
11351
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/iana_ports.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
267
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/icmp4.go
generated
vendored
Normal file
267
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/icmp4.go
generated
vendored
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ICMPv4TypeEchoReply = 0
|
||||||
|
ICMPv4TypeDestinationUnreachable = 3
|
||||||
|
ICMPv4TypeSourceQuench = 4
|
||||||
|
ICMPv4TypeRedirect = 5
|
||||||
|
ICMPv4TypeEchoRequest = 8
|
||||||
|
ICMPv4TypeRouterAdvertisement = 9
|
||||||
|
ICMPv4TypeRouterSolicitation = 10
|
||||||
|
ICMPv4TypeTimeExceeded = 11
|
||||||
|
ICMPv4TypeParameterProblem = 12
|
||||||
|
ICMPv4TypeTimestampRequest = 13
|
||||||
|
ICMPv4TypeTimestampReply = 14
|
||||||
|
ICMPv4TypeInfoRequest = 15
|
||||||
|
ICMPv4TypeInfoReply = 16
|
||||||
|
ICMPv4TypeAddressMaskRequest = 17
|
||||||
|
ICMPv4TypeAddressMaskReply = 18
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DestinationUnreachable
|
||||||
|
ICMPv4CodeNet = 0
|
||||||
|
ICMPv4CodeHost = 1
|
||||||
|
ICMPv4CodeProtocol = 2
|
||||||
|
ICMPv4CodePort = 3
|
||||||
|
ICMPv4CodeFragmentationNeeded = 4
|
||||||
|
ICMPv4CodeSourceRoutingFailed = 5
|
||||||
|
ICMPv4CodeNetUnknown = 6
|
||||||
|
ICMPv4CodeHostUnknown = 7
|
||||||
|
ICMPv4CodeSourceIsolated = 8
|
||||||
|
ICMPv4CodeNetAdminProhibited = 9
|
||||||
|
ICMPv4CodeHostAdminProhibited = 10
|
||||||
|
ICMPv4CodeNetTOS = 11
|
||||||
|
ICMPv4CodeHostTOS = 12
|
||||||
|
ICMPv4CodeCommAdminProhibited = 13
|
||||||
|
ICMPv4CodeHostPrecedence = 14
|
||||||
|
ICMPv4CodePrecedenceCutoff = 15
|
||||||
|
|
||||||
|
// TimeExceeded
|
||||||
|
ICMPv4CodeTTLExceeded = 0
|
||||||
|
ICMPv4CodeFragmentReassemblyTimeExceeded = 1
|
||||||
|
|
||||||
|
// ParameterProblem
|
||||||
|
ICMPv4CodePointerIndicatesError = 0
|
||||||
|
ICMPv4CodeMissingOption = 1
|
||||||
|
ICMPv4CodeBadLength = 2
|
||||||
|
|
||||||
|
// Redirect
|
||||||
|
// ICMPv4CodeNet = same as for DestinationUnreachable
|
||||||
|
// ICMPv4CodeHost = same as for DestinationUnreachable
|
||||||
|
ICMPv4CodeTOSNet = 2
|
||||||
|
ICMPv4CodeTOSHost = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
type icmpv4TypeCodeInfoStruct struct {
|
||||||
|
typeStr string
|
||||||
|
codeStr *map[uint8]string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
icmpv4TypeCodeInfo = map[uint8]icmpv4TypeCodeInfoStruct{
|
||||||
|
ICMPv4TypeDestinationUnreachable: icmpv4TypeCodeInfoStruct{
|
||||||
|
"DestinationUnreachable", &map[uint8]string{
|
||||||
|
ICMPv4CodeNet: "Net",
|
||||||
|
ICMPv4CodeHost: "Host",
|
||||||
|
ICMPv4CodeProtocol: "Protocol",
|
||||||
|
ICMPv4CodePort: "Port",
|
||||||
|
ICMPv4CodeFragmentationNeeded: "FragmentationNeeded",
|
||||||
|
ICMPv4CodeSourceRoutingFailed: "SourceRoutingFailed",
|
||||||
|
ICMPv4CodeNetUnknown: "NetUnknown",
|
||||||
|
ICMPv4CodeHostUnknown: "HostUnknown",
|
||||||
|
ICMPv4CodeSourceIsolated: "SourceIsolated",
|
||||||
|
ICMPv4CodeNetAdminProhibited: "NetAdminProhibited",
|
||||||
|
ICMPv4CodeHostAdminProhibited: "HostAdminProhibited",
|
||||||
|
ICMPv4CodeNetTOS: "NetTOS",
|
||||||
|
ICMPv4CodeHostTOS: "HostTOS",
|
||||||
|
ICMPv4CodeCommAdminProhibited: "CommAdminProhibited",
|
||||||
|
ICMPv4CodeHostPrecedence: "HostPrecedence",
|
||||||
|
ICMPv4CodePrecedenceCutoff: "PrecedenceCutoff",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ICMPv4TypeTimeExceeded: icmpv4TypeCodeInfoStruct{
|
||||||
|
"TimeExceeded", &map[uint8]string{
|
||||||
|
ICMPv4CodeTTLExceeded: "TTLExceeded",
|
||||||
|
ICMPv4CodeFragmentReassemblyTimeExceeded: "FragmentReassemblyTimeExceeded",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ICMPv4TypeParameterProblem: icmpv4TypeCodeInfoStruct{
|
||||||
|
"ParameterProblem", &map[uint8]string{
|
||||||
|
ICMPv4CodePointerIndicatesError: "PointerIndicatesError",
|
||||||
|
ICMPv4CodeMissingOption: "MissingOption",
|
||||||
|
ICMPv4CodeBadLength: "BadLength",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ICMPv4TypeSourceQuench: icmpv4TypeCodeInfoStruct{
|
||||||
|
"SourceQuench", nil,
|
||||||
|
},
|
||||||
|
ICMPv4TypeRedirect: icmpv4TypeCodeInfoStruct{
|
||||||
|
"Redirect", &map[uint8]string{
|
||||||
|
ICMPv4CodeNet: "Net",
|
||||||
|
ICMPv4CodeHost: "Host",
|
||||||
|
ICMPv4CodeTOSNet: "TOS+Net",
|
||||||
|
ICMPv4CodeTOSHost: "TOS+Host",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ICMPv4TypeEchoRequest: icmpv4TypeCodeInfoStruct{
|
||||||
|
"EchoRequest", nil,
|
||||||
|
},
|
||||||
|
ICMPv4TypeEchoReply: icmpv4TypeCodeInfoStruct{
|
||||||
|
"EchoReply", nil,
|
||||||
|
},
|
||||||
|
ICMPv4TypeTimestampRequest: icmpv4TypeCodeInfoStruct{
|
||||||
|
"TimestampRequest", nil,
|
||||||
|
},
|
||||||
|
ICMPv4TypeTimestampReply: icmpv4TypeCodeInfoStruct{
|
||||||
|
"TimestampReply", nil,
|
||||||
|
},
|
||||||
|
ICMPv4TypeInfoRequest: icmpv4TypeCodeInfoStruct{
|
||||||
|
"InfoRequest", nil,
|
||||||
|
},
|
||||||
|
ICMPv4TypeInfoReply: icmpv4TypeCodeInfoStruct{
|
||||||
|
"InfoReply", nil,
|
||||||
|
},
|
||||||
|
ICMPv4TypeRouterSolicitation: icmpv4TypeCodeInfoStruct{
|
||||||
|
"RouterSolicitation", nil,
|
||||||
|
},
|
||||||
|
ICMPv4TypeRouterAdvertisement: icmpv4TypeCodeInfoStruct{
|
||||||
|
"RouterAdvertisement", nil,
|
||||||
|
},
|
||||||
|
ICMPv4TypeAddressMaskRequest: icmpv4TypeCodeInfoStruct{
|
||||||
|
"AddressMaskRequest", nil,
|
||||||
|
},
|
||||||
|
ICMPv4TypeAddressMaskReply: icmpv4TypeCodeInfoStruct{
|
||||||
|
"AddressMaskReply", nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type ICMPv4TypeCode uint16
|
||||||
|
|
||||||
|
// Type returns the ICMPv4 type field.
|
||||||
|
func (a ICMPv4TypeCode) Type() uint8 {
|
||||||
|
return uint8(a >> 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code returns the ICMPv4 code field.
|
||||||
|
func (a ICMPv4TypeCode) Code() uint8 {
|
||||||
|
return uint8(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a ICMPv4TypeCode) String() string {
|
||||||
|
t, c := a.Type(), a.Code()
|
||||||
|
strInfo, ok := icmpv4TypeCodeInfo[t]
|
||||||
|
if !ok {
|
||||||
|
// Unknown ICMPv4 type field
|
||||||
|
return fmt.Sprintf("%d(%d)", t, c)
|
||||||
|
}
|
||||||
|
typeStr := strInfo.typeStr
|
||||||
|
if strInfo.codeStr == nil && c == 0 {
|
||||||
|
// The ICMPv4 type does not make use of the code field
|
||||||
|
return fmt.Sprintf("%s", strInfo.typeStr)
|
||||||
|
}
|
||||||
|
if strInfo.codeStr == nil && c != 0 {
|
||||||
|
// The ICMPv4 type does not make use of the code field, but it is present anyway
|
||||||
|
return fmt.Sprintf("%s(Code: %d)", typeStr, c)
|
||||||
|
}
|
||||||
|
codeStr, ok := (*strInfo.codeStr)[c]
|
||||||
|
if !ok {
|
||||||
|
// We don't know this ICMPv4 code; print the numerical value
|
||||||
|
return fmt.Sprintf("%s(Code: %d)", typeStr, c)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s(%s)", typeStr, codeStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a ICMPv4TypeCode) GoString() string {
|
||||||
|
t := reflect.TypeOf(a)
|
||||||
|
return fmt.Sprintf("%s(%d, %d)", t.String(), a.Type(), a.Code())
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the ICMPv4TypeCode value to the 'bytes' buffer.
|
||||||
|
func (a ICMPv4TypeCode) SerializeTo(bytes []byte) {
|
||||||
|
binary.BigEndian.PutUint16(bytes, uint16(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateICMPv4TypeCode is a convenience function to create an ICMPv4TypeCode
|
||||||
|
// gopacket type from the ICMPv4 type and code values.
|
||||||
|
func CreateICMPv4TypeCode(typ uint8, code uint8) ICMPv4TypeCode {
|
||||||
|
return ICMPv4TypeCode(binary.BigEndian.Uint16([]byte{typ, code}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICMPv4 is the layer for IPv4 ICMP packet data.
|
||||||
|
type ICMPv4 struct {
|
||||||
|
BaseLayer
|
||||||
|
TypeCode ICMPv4TypeCode
|
||||||
|
Checksum uint16
|
||||||
|
Id uint16
|
||||||
|
Seq uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeICMPv4.
|
||||||
|
func (i *ICMPv4) LayerType() gopacket.LayerType { return LayerTypeICMPv4 }
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (i *ICMPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 8 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less then 8 bytes for ICMPv4 packet")
|
||||||
|
}
|
||||||
|
i.TypeCode = CreateICMPv4TypeCode(data[0], data[1])
|
||||||
|
i.Checksum = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
i.Id = binary.BigEndian.Uint16(data[4:6])
|
||||||
|
i.Seq = binary.BigEndian.Uint16(data[6:8])
|
||||||
|
i.BaseLayer = BaseLayer{data[:8], data[8:]}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (i *ICMPv4) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(8)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i.TypeCode.SerializeTo(bytes)
|
||||||
|
binary.BigEndian.PutUint16(bytes[4:], i.Id)
|
||||||
|
binary.BigEndian.PutUint16(bytes[6:], i.Seq)
|
||||||
|
if opts.ComputeChecksums {
|
||||||
|
bytes[2] = 0
|
||||||
|
bytes[3] = 0
|
||||||
|
i.Checksum = tcpipChecksum(b.Bytes(), 0)
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], i.Checksum)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (i *ICMPv4) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeICMPv4
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (i *ICMPv4) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeICMPv4(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &ICMPv4{}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
}
|
266
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/icmp6.go
generated
vendored
Normal file
266
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/icmp6.go
generated
vendored
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// The following are from RFC 4443
|
||||||
|
ICMPv6TypeDestinationUnreachable = 1
|
||||||
|
ICMPv6TypePacketTooBig = 2
|
||||||
|
ICMPv6TypeTimeExceeded = 3
|
||||||
|
ICMPv6TypeParameterProblem = 4
|
||||||
|
ICMPv6TypeEchoRequest = 128
|
||||||
|
ICMPv6TypeEchoReply = 129
|
||||||
|
|
||||||
|
// The following are from RFC 4861
|
||||||
|
ICMPv6TypeRouterSolicitation = 133
|
||||||
|
ICMPv6TypeRouterAdvertisement = 134
|
||||||
|
ICMPv6TypeNeighborSolicitation = 135
|
||||||
|
ICMPv6TypeNeighborAdvertisement = 136
|
||||||
|
ICMPv6TypeRedirect = 137
|
||||||
|
|
||||||
|
// The following are from RFC 2710
|
||||||
|
ICMPv6TypeMLDv1MulticastListenerQueryMessage = 130
|
||||||
|
ICMPv6TypeMLDv1MulticastListenerReportMessage = 131
|
||||||
|
ICMPv6TypeMLDv1MulticastListenerDoneMessage = 132
|
||||||
|
|
||||||
|
// The following are from RFC 3810
|
||||||
|
ICMPv6TypeMLDv2MulticastListenerReportMessageV2 = 143
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DestinationUnreachable
|
||||||
|
ICMPv6CodeNoRouteToDst = 0
|
||||||
|
ICMPv6CodeAdminProhibited = 1
|
||||||
|
ICMPv6CodeBeyondScopeOfSrc = 2
|
||||||
|
ICMPv6CodeAddressUnreachable = 3
|
||||||
|
ICMPv6CodePortUnreachable = 4
|
||||||
|
ICMPv6CodeSrcAddressFailedPolicy = 5
|
||||||
|
ICMPv6CodeRejectRouteToDst = 6
|
||||||
|
|
||||||
|
// TimeExceeded
|
||||||
|
ICMPv6CodeHopLimitExceeded = 0
|
||||||
|
ICMPv6CodeFragmentReassemblyTimeExceeded = 1
|
||||||
|
|
||||||
|
// ParameterProblem
|
||||||
|
ICMPv6CodeErroneousHeaderField = 0
|
||||||
|
ICMPv6CodeUnrecognizedNextHeader = 1
|
||||||
|
ICMPv6CodeUnrecognizedIPv6Option = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type icmpv6TypeCodeInfoStruct struct {
|
||||||
|
typeStr string
|
||||||
|
codeStr *map[uint8]string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
icmpv6TypeCodeInfo = map[uint8]icmpv6TypeCodeInfoStruct{
|
||||||
|
ICMPv6TypeDestinationUnreachable: icmpv6TypeCodeInfoStruct{
|
||||||
|
"DestinationUnreachable", &map[uint8]string{
|
||||||
|
ICMPv6CodeNoRouteToDst: "NoRouteToDst",
|
||||||
|
ICMPv6CodeAdminProhibited: "AdminProhibited",
|
||||||
|
ICMPv6CodeBeyondScopeOfSrc: "BeyondScopeOfSrc",
|
||||||
|
ICMPv6CodeAddressUnreachable: "AddressUnreachable",
|
||||||
|
ICMPv6CodePortUnreachable: "PortUnreachable",
|
||||||
|
ICMPv6CodeSrcAddressFailedPolicy: "SrcAddressFailedPolicy",
|
||||||
|
ICMPv6CodeRejectRouteToDst: "RejectRouteToDst",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ICMPv6TypePacketTooBig: icmpv6TypeCodeInfoStruct{
|
||||||
|
"PacketTooBig", nil,
|
||||||
|
},
|
||||||
|
ICMPv6TypeTimeExceeded: icmpv6TypeCodeInfoStruct{
|
||||||
|
"TimeExceeded", &map[uint8]string{
|
||||||
|
ICMPv6CodeHopLimitExceeded: "HopLimitExceeded",
|
||||||
|
ICMPv6CodeFragmentReassemblyTimeExceeded: "FragmentReassemblyTimeExceeded",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ICMPv6TypeParameterProblem: icmpv6TypeCodeInfoStruct{
|
||||||
|
"ParameterProblem", &map[uint8]string{
|
||||||
|
ICMPv6CodeErroneousHeaderField: "ErroneousHeaderField",
|
||||||
|
ICMPv6CodeUnrecognizedNextHeader: "UnrecognizedNextHeader",
|
||||||
|
ICMPv6CodeUnrecognizedIPv6Option: "UnrecognizedIPv6Option",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ICMPv6TypeEchoRequest: icmpv6TypeCodeInfoStruct{
|
||||||
|
"EchoRequest", nil,
|
||||||
|
},
|
||||||
|
ICMPv6TypeEchoReply: icmpv6TypeCodeInfoStruct{
|
||||||
|
"EchoReply", nil,
|
||||||
|
},
|
||||||
|
ICMPv6TypeRouterSolicitation: icmpv6TypeCodeInfoStruct{
|
||||||
|
"RouterSolicitation", nil,
|
||||||
|
},
|
||||||
|
ICMPv6TypeRouterAdvertisement: icmpv6TypeCodeInfoStruct{
|
||||||
|
"RouterAdvertisement", nil,
|
||||||
|
},
|
||||||
|
ICMPv6TypeNeighborSolicitation: icmpv6TypeCodeInfoStruct{
|
||||||
|
"NeighborSolicitation", nil,
|
||||||
|
},
|
||||||
|
ICMPv6TypeNeighborAdvertisement: icmpv6TypeCodeInfoStruct{
|
||||||
|
"NeighborAdvertisement", nil,
|
||||||
|
},
|
||||||
|
ICMPv6TypeRedirect: icmpv6TypeCodeInfoStruct{
|
||||||
|
"Redirect", nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type ICMPv6TypeCode uint16
|
||||||
|
|
||||||
|
// Type returns the ICMPv6 type field.
|
||||||
|
func (a ICMPv6TypeCode) Type() uint8 {
|
||||||
|
return uint8(a >> 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code returns the ICMPv6 code field.
|
||||||
|
func (a ICMPv6TypeCode) Code() uint8 {
|
||||||
|
return uint8(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a ICMPv6TypeCode) String() string {
|
||||||
|
t, c := a.Type(), a.Code()
|
||||||
|
strInfo, ok := icmpv6TypeCodeInfo[t]
|
||||||
|
if !ok {
|
||||||
|
// Unknown ICMPv6 type field
|
||||||
|
return fmt.Sprintf("%d(%d)", t, c)
|
||||||
|
}
|
||||||
|
typeStr := strInfo.typeStr
|
||||||
|
if strInfo.codeStr == nil && c == 0 {
|
||||||
|
// The ICMPv6 type does not make use of the code field
|
||||||
|
return fmt.Sprintf("%s", strInfo.typeStr)
|
||||||
|
}
|
||||||
|
if strInfo.codeStr == nil && c != 0 {
|
||||||
|
// The ICMPv6 type does not make use of the code field, but it is present anyway
|
||||||
|
return fmt.Sprintf("%s(Code: %d)", typeStr, c)
|
||||||
|
}
|
||||||
|
codeStr, ok := (*strInfo.codeStr)[c]
|
||||||
|
if !ok {
|
||||||
|
// We don't know this ICMPv6 code; print the numerical value
|
||||||
|
return fmt.Sprintf("%s(Code: %d)", typeStr, c)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s(%s)", typeStr, codeStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a ICMPv6TypeCode) GoString() string {
|
||||||
|
t := reflect.TypeOf(a)
|
||||||
|
return fmt.Sprintf("%s(%d, %d)", t.String(), a.Type(), a.Code())
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the ICMPv6TypeCode value to the 'bytes' buffer.
|
||||||
|
func (a ICMPv6TypeCode) SerializeTo(bytes []byte) {
|
||||||
|
binary.BigEndian.PutUint16(bytes, uint16(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateICMPv6TypeCode is a convenience function to create an ICMPv6TypeCode
|
||||||
|
// gopacket type from the ICMPv6 type and code values.
|
||||||
|
func CreateICMPv6TypeCode(typ uint8, code uint8) ICMPv6TypeCode {
|
||||||
|
return ICMPv6TypeCode(binary.BigEndian.Uint16([]byte{typ, code}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICMPv6 is the layer for IPv6 ICMP packet data
|
||||||
|
type ICMPv6 struct {
|
||||||
|
BaseLayer
|
||||||
|
TypeCode ICMPv6TypeCode
|
||||||
|
Checksum uint16
|
||||||
|
// TypeBytes is deprecated and always nil. See the different ICMPv6 message types
|
||||||
|
// instead (e.g. ICMPv6TypeRouterSolicitation).
|
||||||
|
TypeBytes []byte
|
||||||
|
tcpipchecksum
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeICMPv6.
|
||||||
|
func (i *ICMPv6) LayerType() gopacket.LayerType { return LayerTypeICMPv6 }
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (i *ICMPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 4 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less then 4 bytes for ICMPv6 packet")
|
||||||
|
}
|
||||||
|
i.TypeCode = CreateICMPv6TypeCode(data[0], data[1])
|
||||||
|
i.Checksum = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
i.BaseLayer = BaseLayer{data[:4], data[4:]}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (i *ICMPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i.TypeCode.SerializeTo(bytes)
|
||||||
|
|
||||||
|
if opts.ComputeChecksums {
|
||||||
|
bytes[2] = 0
|
||||||
|
bytes[3] = 0
|
||||||
|
csum, err := i.computeChecksum(b.Bytes(), IPProtocolICMPv6)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i.Checksum = csum
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], i.Checksum)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (i *ICMPv6) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeICMPv6
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (i *ICMPv6) NextLayerType() gopacket.LayerType {
|
||||||
|
switch i.TypeCode.Type() {
|
||||||
|
case ICMPv6TypeEchoRequest:
|
||||||
|
return LayerTypeICMPv6Echo
|
||||||
|
case ICMPv6TypeEchoReply:
|
||||||
|
return LayerTypeICMPv6Echo
|
||||||
|
case ICMPv6TypeRouterSolicitation:
|
||||||
|
return LayerTypeICMPv6RouterSolicitation
|
||||||
|
case ICMPv6TypeRouterAdvertisement:
|
||||||
|
return LayerTypeICMPv6RouterAdvertisement
|
||||||
|
case ICMPv6TypeNeighborSolicitation:
|
||||||
|
return LayerTypeICMPv6NeighborSolicitation
|
||||||
|
case ICMPv6TypeNeighborAdvertisement:
|
||||||
|
return LayerTypeICMPv6NeighborAdvertisement
|
||||||
|
case ICMPv6TypeRedirect:
|
||||||
|
return LayerTypeICMPv6Redirect
|
||||||
|
case ICMPv6TypeMLDv1MulticastListenerQueryMessage: // Same Code for MLDv1 Query and MLDv2 Query
|
||||||
|
if len(i.Payload) > 20 { // Only payload size differs
|
||||||
|
return LayerTypeMLDv2MulticastListenerQuery
|
||||||
|
} else {
|
||||||
|
return LayerTypeMLDv1MulticastListenerQuery
|
||||||
|
}
|
||||||
|
case ICMPv6TypeMLDv1MulticastListenerDoneMessage:
|
||||||
|
return LayerTypeMLDv1MulticastListenerDone
|
||||||
|
case ICMPv6TypeMLDv1MulticastListenerReportMessage:
|
||||||
|
return LayerTypeMLDv1MulticastListenerReport
|
||||||
|
case ICMPv6TypeMLDv2MulticastListenerReportMessageV2:
|
||||||
|
return LayerTypeMLDv2MulticastListenerReport
|
||||||
|
}
|
||||||
|
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeICMPv6(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &ICMPv6{}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
}
|
578
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/icmp6msg.go
generated
vendored
Normal file
578
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/icmp6msg.go
generated
vendored
Normal file
|
@ -0,0 +1,578 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Based on RFC 4861
|
||||||
|
|
||||||
|
// ICMPv6Opt indicate how to decode the data associated with each ICMPv6Option.
|
||||||
|
type ICMPv6Opt uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ ICMPv6Opt = iota
|
||||||
|
|
||||||
|
// ICMPv6OptSourceAddress contains the link-layer address of the sender of
|
||||||
|
// the packet. It is used in the Neighbor Solicitation, Router
|
||||||
|
// Solicitation, and Router Advertisement packets. Must be ignored for other
|
||||||
|
// Neighbor discovery messages.
|
||||||
|
ICMPv6OptSourceAddress
|
||||||
|
|
||||||
|
// ICMPv6OptTargetAddress contains the link-layer address of the target. It
|
||||||
|
// is used in Neighbor Advertisement and Redirect packets. Must be ignored
|
||||||
|
// for other Neighbor discovery messages.
|
||||||
|
ICMPv6OptTargetAddress
|
||||||
|
|
||||||
|
// ICMPv6OptPrefixInfo provides hosts with on-link prefixes and prefixes
|
||||||
|
// for Address Autoconfiguration. The Prefix Information option appears in
|
||||||
|
// Router Advertisement packets and MUST be silently ignored for other
|
||||||
|
// messages.
|
||||||
|
ICMPv6OptPrefixInfo
|
||||||
|
|
||||||
|
// ICMPv6OptRedirectedHeader is used in Redirect messages and contains all
|
||||||
|
// or part of the packet that is being redirected.
|
||||||
|
ICMPv6OptRedirectedHeader
|
||||||
|
|
||||||
|
// ICMPv6OptMTU is used in Router Advertisement messages to ensure that all
|
||||||
|
// nodes on a link use the same MTU value in those cases where the link MTU
|
||||||
|
// is not well known. This option MUST be silently ignored for other
|
||||||
|
// Neighbor Discovery messages.
|
||||||
|
ICMPv6OptMTU
|
||||||
|
)
|
||||||
|
|
||||||
|
// ICMPv6Echo represents the structure of a ping.
|
||||||
|
type ICMPv6Echo struct {
|
||||||
|
BaseLayer
|
||||||
|
Identifier uint16
|
||||||
|
SeqNumber uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICMPv6RouterSolicitation is sent by hosts to find routers.
|
||||||
|
type ICMPv6RouterSolicitation struct {
|
||||||
|
BaseLayer
|
||||||
|
Options ICMPv6Options
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICMPv6RouterAdvertisement is sent by routers in response to Solicitation.
|
||||||
|
type ICMPv6RouterAdvertisement struct {
|
||||||
|
BaseLayer
|
||||||
|
HopLimit uint8
|
||||||
|
Flags uint8
|
||||||
|
RouterLifetime uint16
|
||||||
|
ReachableTime uint32
|
||||||
|
RetransTimer uint32
|
||||||
|
Options ICMPv6Options
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICMPv6NeighborSolicitation is sent to request the link-layer address of a
|
||||||
|
// target node.
|
||||||
|
type ICMPv6NeighborSolicitation struct {
|
||||||
|
BaseLayer
|
||||||
|
TargetAddress net.IP
|
||||||
|
Options ICMPv6Options
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICMPv6NeighborAdvertisement is sent by nodes in response to Solicitation.
|
||||||
|
type ICMPv6NeighborAdvertisement struct {
|
||||||
|
BaseLayer
|
||||||
|
Flags uint8
|
||||||
|
TargetAddress net.IP
|
||||||
|
Options ICMPv6Options
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICMPv6Redirect is sent by routers to inform hosts of a better first-hop node
|
||||||
|
// on the path to a destination.
|
||||||
|
type ICMPv6Redirect struct {
|
||||||
|
BaseLayer
|
||||||
|
TargetAddress net.IP
|
||||||
|
DestinationAddress net.IP
|
||||||
|
Options ICMPv6Options
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICMPv6Option contains the type and data for a single option.
|
||||||
|
type ICMPv6Option struct {
|
||||||
|
Type ICMPv6Opt
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// ICMPv6Options is a slice of ICMPv6Option.
|
||||||
|
type ICMPv6Options []ICMPv6Option
|
||||||
|
|
||||||
|
func (i ICMPv6Opt) String() string {
|
||||||
|
switch i {
|
||||||
|
case ICMPv6OptSourceAddress:
|
||||||
|
return "SourceAddress"
|
||||||
|
case ICMPv6OptTargetAddress:
|
||||||
|
return "TargetAddress"
|
||||||
|
case ICMPv6OptPrefixInfo:
|
||||||
|
return "PrefixInfo"
|
||||||
|
case ICMPv6OptRedirectedHeader:
|
||||||
|
return "RedirectedHeader"
|
||||||
|
case ICMPv6OptMTU:
|
||||||
|
return "MTU"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("Unknown(%d)", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (i *ICMPv6Echo) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeICMPv6Echo
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeICMPv6Echo.
|
||||||
|
func (i *ICMPv6Echo) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeICMPv6Echo
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (i *ICMPv6Echo) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (i *ICMPv6Echo) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 4 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less then 4 bytes for ICMPv6 Echo")
|
||||||
|
}
|
||||||
|
i.Identifier = binary.BigEndian.Uint16(data[0:2])
|
||||||
|
i.SeqNumber = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (i *ICMPv6Echo) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
buf, err := b.PrependBytes(4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint16(buf, i.Identifier)
|
||||||
|
binary.BigEndian.PutUint16(buf[2:], i.SeqNumber)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeICMPv6.
|
||||||
|
func (i *ICMPv6RouterSolicitation) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeICMPv6RouterSolicitation
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (i *ICMPv6RouterSolicitation) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (i *ICMPv6RouterSolicitation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
// first 4 bytes are reserved followed by options
|
||||||
|
if len(data) < 4 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less then 4 bytes for ICMPv6 router solicitation")
|
||||||
|
}
|
||||||
|
|
||||||
|
// truncate old options
|
||||||
|
i.Options = i.Options[:0]
|
||||||
|
|
||||||
|
return i.Options.DecodeFromBytes(data[4:], df)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (i *ICMPv6RouterSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if err := i.Options.SerializeTo(b, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(buf, lotsOfZeros[:4])
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (i *ICMPv6RouterSolicitation) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeICMPv6RouterSolicitation
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeICMPv6RouterAdvertisement.
|
||||||
|
func (i *ICMPv6RouterAdvertisement) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeICMPv6RouterAdvertisement
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (i *ICMPv6RouterAdvertisement) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (i *ICMPv6RouterAdvertisement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 12 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less then 12 bytes for ICMPv6 router advertisement")
|
||||||
|
}
|
||||||
|
|
||||||
|
i.HopLimit = uint8(data[0])
|
||||||
|
// M, O bit followed by 6 reserved bits
|
||||||
|
i.Flags = uint8(data[1])
|
||||||
|
i.RouterLifetime = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
i.ReachableTime = binary.BigEndian.Uint32(data[4:8])
|
||||||
|
i.RetransTimer = binary.BigEndian.Uint32(data[8:12])
|
||||||
|
i.BaseLayer = BaseLayer{data, nil} // assume no payload
|
||||||
|
|
||||||
|
// truncate old options
|
||||||
|
i.Options = i.Options[:0]
|
||||||
|
|
||||||
|
return i.Options.DecodeFromBytes(data[12:], df)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (i *ICMPv6RouterAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if err := i.Options.SerializeTo(b, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(12)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = byte(i.HopLimit)
|
||||||
|
buf[1] = byte(i.Flags)
|
||||||
|
binary.BigEndian.PutUint16(buf[2:], i.RouterLifetime)
|
||||||
|
binary.BigEndian.PutUint32(buf[4:], i.ReachableTime)
|
||||||
|
binary.BigEndian.PutUint32(buf[8:], i.RetransTimer)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (i *ICMPv6RouterAdvertisement) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeICMPv6RouterAdvertisement
|
||||||
|
}
|
||||||
|
|
||||||
|
// ManagedAddressConfig is true when addresses are available via DHCPv6. If
|
||||||
|
// set, the OtherConfig flag is redundant.
|
||||||
|
func (i *ICMPv6RouterAdvertisement) ManagedAddressConfig() bool {
|
||||||
|
return i.Flags&0x80 != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// OtherConfig is true when there is other configuration information available
|
||||||
|
// via DHCPv6. For example, DNS-related information.
|
||||||
|
func (i *ICMPv6RouterAdvertisement) OtherConfig() bool {
|
||||||
|
return i.Flags&0x40 != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeICMPv6NeighborSolicitation.
|
||||||
|
func (i *ICMPv6NeighborSolicitation) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeICMPv6NeighborSolicitation
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (i *ICMPv6NeighborSolicitation) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (i *ICMPv6NeighborSolicitation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 20 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less then 20 bytes for ICMPv6 neighbor solicitation")
|
||||||
|
}
|
||||||
|
|
||||||
|
i.TargetAddress = net.IP(data[4:20])
|
||||||
|
i.BaseLayer = BaseLayer{data, nil} // assume no payload
|
||||||
|
|
||||||
|
// truncate old options
|
||||||
|
i.Options = i.Options[:0]
|
||||||
|
|
||||||
|
return i.Options.DecodeFromBytes(data[20:], df)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (i *ICMPv6NeighborSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if err := i.Options.SerializeTo(b, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(20)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(buf, lotsOfZeros[:4])
|
||||||
|
copy(buf[4:], i.TargetAddress)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (i *ICMPv6NeighborSolicitation) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeICMPv6NeighborSolicitation
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeICMPv6NeighborAdvertisement.
|
||||||
|
func (i *ICMPv6NeighborAdvertisement) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeICMPv6NeighborAdvertisement
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (i *ICMPv6NeighborAdvertisement) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (i *ICMPv6NeighborAdvertisement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 20 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less then 20 bytes for ICMPv6 neighbor advertisement")
|
||||||
|
}
|
||||||
|
|
||||||
|
i.Flags = uint8(data[0])
|
||||||
|
i.TargetAddress = net.IP(data[4:20])
|
||||||
|
i.BaseLayer = BaseLayer{data, nil} // assume no payload
|
||||||
|
|
||||||
|
// truncate old options
|
||||||
|
i.Options = i.Options[:0]
|
||||||
|
|
||||||
|
return i.Options.DecodeFromBytes(data[20:], df)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (i *ICMPv6NeighborAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if err := i.Options.SerializeTo(b, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(20)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = byte(i.Flags)
|
||||||
|
copy(buf[1:], lotsOfZeros[:3])
|
||||||
|
copy(buf[4:], i.TargetAddress)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (i *ICMPv6NeighborAdvertisement) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeICMPv6NeighborAdvertisement
|
||||||
|
}
|
||||||
|
|
||||||
|
// Router indicates whether the sender is a router or not.
|
||||||
|
func (i *ICMPv6NeighborAdvertisement) Router() bool {
|
||||||
|
return i.Flags&0x80 != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solicited indicates whether the advertisement was solicited or not.
|
||||||
|
func (i *ICMPv6NeighborAdvertisement) Solicited() bool {
|
||||||
|
return i.Flags&0x40 != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override indicates whether the advertisement should Override an existing
|
||||||
|
// cache entry.
|
||||||
|
func (i *ICMPv6NeighborAdvertisement) Override() bool {
|
||||||
|
return i.Flags&0x20 != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeICMPv6Redirect.
|
||||||
|
func (i *ICMPv6Redirect) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeICMPv6Redirect
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (i *ICMPv6Redirect) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (i *ICMPv6Redirect) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 36 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less then 36 bytes for ICMPv6 redirect")
|
||||||
|
}
|
||||||
|
|
||||||
|
i.TargetAddress = net.IP(data[4:20])
|
||||||
|
i.DestinationAddress = net.IP(data[20:36])
|
||||||
|
i.BaseLayer = BaseLayer{data, nil} // assume no payload
|
||||||
|
|
||||||
|
// truncate old options
|
||||||
|
i.Options = i.Options[:0]
|
||||||
|
|
||||||
|
return i.Options.DecodeFromBytes(data[36:], df)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (i *ICMPv6Redirect) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if err := i.Options.SerializeTo(b, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(36)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(buf, lotsOfZeros[:4])
|
||||||
|
copy(buf[4:], i.TargetAddress)
|
||||||
|
copy(buf[20:], i.DestinationAddress)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (i *ICMPv6Redirect) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeICMPv6Redirect
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i ICMPv6Option) String() string {
|
||||||
|
hd := hex.EncodeToString(i.Data)
|
||||||
|
if len(hd) > 0 {
|
||||||
|
hd = " 0x" + hd
|
||||||
|
}
|
||||||
|
|
||||||
|
switch i.Type {
|
||||||
|
case ICMPv6OptSourceAddress, ICMPv6OptTargetAddress:
|
||||||
|
return fmt.Sprintf("ICMPv6Option(%s:%v)",
|
||||||
|
i.Type,
|
||||||
|
net.HardwareAddr(i.Data))
|
||||||
|
case ICMPv6OptPrefixInfo:
|
||||||
|
if len(i.Data) == 30 {
|
||||||
|
prefixLen := uint8(i.Data[0])
|
||||||
|
onLink := (i.Data[1]&0x80 != 0)
|
||||||
|
autonomous := (i.Data[1]&0x40 != 0)
|
||||||
|
validLifetime := time.Duration(binary.BigEndian.Uint32(i.Data[2:6])) * time.Second
|
||||||
|
preferredLifetime := time.Duration(binary.BigEndian.Uint32(i.Data[6:10])) * time.Second
|
||||||
|
|
||||||
|
prefix := net.IP(i.Data[14:])
|
||||||
|
|
||||||
|
return fmt.Sprintf("ICMPv6Option(%s:%v/%v:%t:%t:%v:%v)",
|
||||||
|
i.Type,
|
||||||
|
prefix, prefixLen,
|
||||||
|
onLink, autonomous,
|
||||||
|
validLifetime, preferredLifetime)
|
||||||
|
}
|
||||||
|
case ICMPv6OptRedirectedHeader:
|
||||||
|
// could invoke IP decoder on data... probably best not to
|
||||||
|
break
|
||||||
|
case ICMPv6OptMTU:
|
||||||
|
if len(i.Data) == 6 {
|
||||||
|
return fmt.Sprintf("ICMPv6Option(%s:%v)",
|
||||||
|
i.Type,
|
||||||
|
binary.BigEndian.Uint32(i.Data[2:]))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("ICMPv6Option(%s:%s)", i.Type, hd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (i *ICMPv6Options) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
for len(data) > 0 {
|
||||||
|
if len(data) < 2 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less then 2 bytes for ICMPv6 message option")
|
||||||
|
}
|
||||||
|
|
||||||
|
// unit is 8 octets, convert to bytes
|
||||||
|
length := int(data[1]) * 8
|
||||||
|
|
||||||
|
if length == 0 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMPv6 message option with length 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) < length {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("ICMP layer only %v bytes for ICMPv6 message option with length %v", len(data), length)
|
||||||
|
}
|
||||||
|
|
||||||
|
o := ICMPv6Option{
|
||||||
|
Type: ICMPv6Opt(data[0]),
|
||||||
|
Data: data[2:length],
|
||||||
|
}
|
||||||
|
|
||||||
|
// chop off option we just consumed
|
||||||
|
data = data[length:]
|
||||||
|
|
||||||
|
*i = append(*i, o)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (i *ICMPv6Options) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
for _, opt := range []ICMPv6Option(*i) {
|
||||||
|
length := len(opt.Data) + 2
|
||||||
|
buf, err := b.PrependBytes(length)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = byte(opt.Type)
|
||||||
|
buf[1] = byte(length / 8)
|
||||||
|
copy(buf[2:], opt.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeICMPv6Echo(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &ICMPv6Echo{}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeICMPv6RouterSolicitation(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &ICMPv6RouterSolicitation{}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeICMPv6RouterAdvertisement(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &ICMPv6RouterAdvertisement{}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeICMPv6NeighborSolicitation(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &ICMPv6NeighborSolicitation{}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeICMPv6NeighborAdvertisement(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &ICMPv6NeighborAdvertisement{}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeICMPv6Redirect(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &ICMPv6Redirect{}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
}
|
355
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/igmp.go
generated
vendored
Normal file
355
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/igmp.go
generated
vendored
Normal file
|
@ -0,0 +1,355 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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"
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IGMPType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
IGMPMembershipQuery IGMPType = 0x11 // General or group specific query
|
||||||
|
IGMPMembershipReportV1 IGMPType = 0x12 // Version 1 Membership Report
|
||||||
|
IGMPMembershipReportV2 IGMPType = 0x16 // Version 2 Membership Report
|
||||||
|
IGMPLeaveGroup IGMPType = 0x17 // Leave Group
|
||||||
|
IGMPMembershipReportV3 IGMPType = 0x22 // Version 3 Membership Report
|
||||||
|
)
|
||||||
|
|
||||||
|
// String conversions for IGMP message types
|
||||||
|
func (i IGMPType) String() string {
|
||||||
|
switch i {
|
||||||
|
case IGMPMembershipQuery:
|
||||||
|
return "IGMP Membership Query"
|
||||||
|
case IGMPMembershipReportV1:
|
||||||
|
return "IGMPv1 Membership Report"
|
||||||
|
case IGMPMembershipReportV2:
|
||||||
|
return "IGMPv2 Membership Report"
|
||||||
|
case IGMPMembershipReportV3:
|
||||||
|
return "IGMPv3 Membership Report"
|
||||||
|
case IGMPLeaveGroup:
|
||||||
|
return "Leave Group"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type IGMPv3GroupRecordType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
IGMPIsIn IGMPv3GroupRecordType = 0x01 // Type MODE_IS_INCLUDE, source addresses x
|
||||||
|
IGMPIsEx IGMPv3GroupRecordType = 0x02 // Type MODE_IS_EXCLUDE, source addresses x
|
||||||
|
IGMPToIn IGMPv3GroupRecordType = 0x03 // Type CHANGE_TO_INCLUDE_MODE, source addresses x
|
||||||
|
IGMPToEx IGMPv3GroupRecordType = 0x04 // Type CHANGE_TO_EXCLUDE_MODE, source addresses x
|
||||||
|
IGMPAllow IGMPv3GroupRecordType = 0x05 // Type ALLOW_NEW_SOURCES, source addresses x
|
||||||
|
IGMPBlock IGMPv3GroupRecordType = 0x06 // Type BLOCK_OLD_SOURCES, source addresses x
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i IGMPv3GroupRecordType) String() string {
|
||||||
|
switch i {
|
||||||
|
case IGMPIsIn:
|
||||||
|
return "MODE_IS_INCLUDE"
|
||||||
|
case IGMPIsEx:
|
||||||
|
return "MODE_IS_EXCLUDE"
|
||||||
|
case IGMPToIn:
|
||||||
|
return "CHANGE_TO_INCLUDE_MODE"
|
||||||
|
case IGMPToEx:
|
||||||
|
return "CHANGE_TO_EXCLUDE_MODE"
|
||||||
|
case IGMPAllow:
|
||||||
|
return "ALLOW_NEW_SOURCES"
|
||||||
|
case IGMPBlock:
|
||||||
|
return "BLOCK_OLD_SOURCES"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IGMP represents an IGMPv3 message.
|
||||||
|
type IGMP struct {
|
||||||
|
BaseLayer
|
||||||
|
Type IGMPType
|
||||||
|
MaxResponseTime time.Duration
|
||||||
|
Checksum uint16
|
||||||
|
GroupAddress net.IP
|
||||||
|
SupressRouterProcessing bool
|
||||||
|
RobustnessValue uint8
|
||||||
|
IntervalTime time.Duration
|
||||||
|
SourceAddresses []net.IP
|
||||||
|
NumberOfGroupRecords uint16
|
||||||
|
NumberOfSources uint16
|
||||||
|
GroupRecords []IGMPv3GroupRecord
|
||||||
|
Version uint8 // IGMP protocol version
|
||||||
|
}
|
||||||
|
|
||||||
|
// IGMPv1or2 stores header details for an IGMPv1 or IGMPv2 packet.
|
||||||
|
//
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Type | Max Resp Time | Checksum |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Group Address |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
type IGMPv1or2 struct {
|
||||||
|
BaseLayer
|
||||||
|
Type IGMPType // IGMP message type
|
||||||
|
MaxResponseTime time.Duration // meaningful only in Membership Query messages
|
||||||
|
Checksum uint16 // 16-bit checksum of entire ip payload
|
||||||
|
GroupAddress net.IP // either 0 or an IP multicast address
|
||||||
|
Version uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeResponse dissects IGMPv1 or IGMPv2 packet.
|
||||||
|
func (i *IGMPv1or2) decodeResponse(data []byte) error {
|
||||||
|
if len(data) < 8 {
|
||||||
|
return errors.New("IGMP packet too small")
|
||||||
|
}
|
||||||
|
|
||||||
|
i.MaxResponseTime = igmpTimeDecode(data[1])
|
||||||
|
i.Checksum = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
i.GroupAddress = net.IP(data[4:8])
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Type = 0x22 | Reserved | Checksum |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Reserved | Number of Group Records (M) |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// . Group Record [1] .
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// . Group Record [2] .
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// . Group Record [M] .
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Record Type | Aux Data Len | Number of Sources (N) |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Multicast Address |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Source Address [1] |
|
||||||
|
// +- -+
|
||||||
|
// | Source Address [2] |
|
||||||
|
// +- -+
|
||||||
|
// | Source Address [N] |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// . Auxiliary Data .
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
// IGMPv3GroupRecord stores individual group records for a V3 Membership Report message.
|
||||||
|
type IGMPv3GroupRecord struct {
|
||||||
|
Type IGMPv3GroupRecordType
|
||||||
|
AuxDataLen uint8 // this should always be 0 as per IGMPv3 spec.
|
||||||
|
NumberOfSources uint16
|
||||||
|
MulticastAddress net.IP
|
||||||
|
SourceAddresses []net.IP
|
||||||
|
AuxData uint32 // NOT USED
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IGMP) decodeIGMPv3MembershipReport(data []byte) error {
|
||||||
|
if len(data) < 8 {
|
||||||
|
return errors.New("IGMPv3 Membership Report too small #1")
|
||||||
|
}
|
||||||
|
|
||||||
|
i.Checksum = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
i.NumberOfGroupRecords = binary.BigEndian.Uint16(data[6:8])
|
||||||
|
|
||||||
|
recordOffset := 8
|
||||||
|
for j := 0; j < int(i.NumberOfGroupRecords); j++ {
|
||||||
|
if len(data) < recordOffset+8 {
|
||||||
|
return errors.New("IGMPv3 Membership Report too small #2")
|
||||||
|
}
|
||||||
|
|
||||||
|
var gr IGMPv3GroupRecord
|
||||||
|
gr.Type = IGMPv3GroupRecordType(data[recordOffset])
|
||||||
|
gr.AuxDataLen = data[recordOffset+1]
|
||||||
|
gr.NumberOfSources = binary.BigEndian.Uint16(data[recordOffset+2 : recordOffset+4])
|
||||||
|
gr.MulticastAddress = net.IP(data[recordOffset+4 : recordOffset+8])
|
||||||
|
|
||||||
|
if len(data) < recordOffset+8+int(gr.NumberOfSources)*4 {
|
||||||
|
return errors.New("IGMPv3 Membership Report too small #3")
|
||||||
|
}
|
||||||
|
|
||||||
|
// append source address records.
|
||||||
|
for i := 0; i < int(gr.NumberOfSources); i++ {
|
||||||
|
sourceAddr := net.IP(data[recordOffset+8+i*4 : recordOffset+12+i*4])
|
||||||
|
gr.SourceAddresses = append(gr.SourceAddresses, sourceAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
i.GroupRecords = append(i.GroupRecords, gr)
|
||||||
|
recordOffset += 8 + 4*int(gr.NumberOfSources)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Type = 0x11 | Max Resp Code | Checksum |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Group Address |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Resv |S| QRV | QQIC | Number of Sources (N) |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Source Address [1] |
|
||||||
|
// +- -+
|
||||||
|
// | Source Address [2] |
|
||||||
|
// +- . -+
|
||||||
|
// | Source Address [N] |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
//
|
||||||
|
// decodeIGMPv3MembershipQuery parses the IGMPv3 message of type 0x11
|
||||||
|
func (i *IGMP) decodeIGMPv3MembershipQuery(data []byte) error {
|
||||||
|
if len(data) < 12 {
|
||||||
|
return errors.New("IGMPv3 Membership Query too small #1")
|
||||||
|
}
|
||||||
|
|
||||||
|
i.MaxResponseTime = igmpTimeDecode(data[1])
|
||||||
|
i.Checksum = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
i.SupressRouterProcessing = data[8]&0x8 != 0
|
||||||
|
i.GroupAddress = net.IP(data[4:8])
|
||||||
|
i.RobustnessValue = data[8] & 0x7
|
||||||
|
i.IntervalTime = igmpTimeDecode(data[9])
|
||||||
|
i.NumberOfSources = binary.BigEndian.Uint16(data[10:12])
|
||||||
|
|
||||||
|
if len(data) < 12+int(i.NumberOfSources)*4 {
|
||||||
|
return errors.New("IGMPv3 Membership Query too small #2")
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := 0; j < int(i.NumberOfSources); j++ {
|
||||||
|
i.SourceAddresses = append(i.SourceAddresses, net.IP(data[12+j*4:16+j*4]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// igmpTimeDecode decodes the duration created by the given byte, using the
|
||||||
|
// algorithm in http://www.rfc-base.org/txt/rfc-3376.txt section 4.1.1.
|
||||||
|
func igmpTimeDecode(t uint8) time.Duration {
|
||||||
|
if t&0x80 == 0 {
|
||||||
|
return time.Millisecond * 100 * time.Duration(t)
|
||||||
|
}
|
||||||
|
mant := (t & 0x70) >> 4
|
||||||
|
exp := t & 0x0F
|
||||||
|
return time.Millisecond * 100 * time.Duration((mant|0x10)<<(exp+3))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeIGMP for the V1,2,3 message protocol formats.
|
||||||
|
func (i *IGMP) LayerType() gopacket.LayerType { return LayerTypeIGMP }
|
||||||
|
func (i *IGMPv1or2) LayerType() gopacket.LayerType { return LayerTypeIGMP }
|
||||||
|
|
||||||
|
func (i *IGMPv1or2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 8 {
|
||||||
|
return errors.New("IGMP Packet too small")
|
||||||
|
}
|
||||||
|
|
||||||
|
i.Type = IGMPType(data[0])
|
||||||
|
i.MaxResponseTime = igmpTimeDecode(data[1])
|
||||||
|
i.Checksum = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
i.GroupAddress = net.IP(data[4:8])
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IGMPv1or2) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IGMPv1or2) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeIGMP
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (i *IGMP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 1 {
|
||||||
|
return errors.New("IGMP packet is too small")
|
||||||
|
}
|
||||||
|
|
||||||
|
// common IGMP header values between versions 1..3 of IGMP specification..
|
||||||
|
i.Type = IGMPType(data[0])
|
||||||
|
|
||||||
|
switch i.Type {
|
||||||
|
case IGMPMembershipQuery:
|
||||||
|
i.decodeIGMPv3MembershipQuery(data)
|
||||||
|
case IGMPMembershipReportV3:
|
||||||
|
i.decodeIGMPv3MembershipReport(data)
|
||||||
|
default:
|
||||||
|
return errors.New("unsupported IGMP type")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (i *IGMP) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeIGMP
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (i *IGMP) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeIGMP will parse IGMP v1,2 or 3 protocols. Checks against the
|
||||||
|
// IGMP type are performed against byte[0], logic then iniitalizes and
|
||||||
|
// passes the appropriate struct (IGMP or IGMPv1or2) to
|
||||||
|
// decodingLayerDecoder.
|
||||||
|
func decodeIGMP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
if len(data) < 1 {
|
||||||
|
return errors.New("IGMP packet is too small")
|
||||||
|
}
|
||||||
|
|
||||||
|
// byte 0 contains IGMP message type.
|
||||||
|
switch IGMPType(data[0]) {
|
||||||
|
case IGMPMembershipQuery:
|
||||||
|
// IGMPv3 Membership Query payload is >= 12
|
||||||
|
if len(data) >= 12 {
|
||||||
|
i := &IGMP{Version: 3}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
} else if len(data) == 8 {
|
||||||
|
i := &IGMPv1or2{}
|
||||||
|
if data[1] == 0x00 {
|
||||||
|
i.Version = 1 // IGMPv1 has a query length of 8 and MaxResp = 0
|
||||||
|
} else {
|
||||||
|
i.Version = 2 // IGMPv2 has a query length of 8 and MaxResp != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
}
|
||||||
|
case IGMPMembershipReportV3:
|
||||||
|
i := &IGMP{Version: 3}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
case IGMPMembershipReportV1:
|
||||||
|
i := &IGMPv1or2{Version: 1}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
case IGMPLeaveGroup, IGMPMembershipReportV2:
|
||||||
|
// leave group and Query Report v2 used in IGMPv2 only.
|
||||||
|
i := &IGMPv1or2{Version: 2}
|
||||||
|
return decodingLayerDecoder(i, data, p)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("Unable to determine IGMP type.")
|
||||||
|
}
|
325
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ip4.go
generated
vendored
Normal file
325
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ip4.go
generated
vendored
Normal file
|
@ -0,0 +1,325 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IPv4Flag uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
IPv4EvilBit IPv4Flag = 1 << 2 // http://tools.ietf.org/html/rfc3514 ;)
|
||||||
|
IPv4DontFragment IPv4Flag = 1 << 1
|
||||||
|
IPv4MoreFragments IPv4Flag = 1 << 0
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f IPv4Flag) String() string {
|
||||||
|
var s []string
|
||||||
|
if f&IPv4EvilBit != 0 {
|
||||||
|
s = append(s, "Evil")
|
||||||
|
}
|
||||||
|
if f&IPv4DontFragment != 0 {
|
||||||
|
s = append(s, "DF")
|
||||||
|
}
|
||||||
|
if f&IPv4MoreFragments != 0 {
|
||||||
|
s = append(s, "MF")
|
||||||
|
}
|
||||||
|
return strings.Join(s, "|")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv4 is the header of an IP packet.
|
||||||
|
type IPv4 struct {
|
||||||
|
BaseLayer
|
||||||
|
Version uint8
|
||||||
|
IHL uint8
|
||||||
|
TOS uint8
|
||||||
|
Length uint16
|
||||||
|
Id uint16
|
||||||
|
Flags IPv4Flag
|
||||||
|
FragOffset uint16
|
||||||
|
TTL uint8
|
||||||
|
Protocol IPProtocol
|
||||||
|
Checksum uint16
|
||||||
|
SrcIP net.IP
|
||||||
|
DstIP net.IP
|
||||||
|
Options []IPv4Option
|
||||||
|
Padding []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeIPv4
|
||||||
|
func (i *IPv4) LayerType() gopacket.LayerType { return LayerTypeIPv4 }
|
||||||
|
func (i *IPv4) NetworkFlow() gopacket.Flow {
|
||||||
|
return gopacket.NewFlow(EndpointIPv4, i.SrcIP, i.DstIP)
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPv4Option struct {
|
||||||
|
OptionType uint8
|
||||||
|
OptionLength uint8
|
||||||
|
OptionData []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i IPv4Option) String() string {
|
||||||
|
return fmt.Sprintf("IPv4Option(%v:%v)", i.OptionType, i.OptionData)
|
||||||
|
}
|
||||||
|
|
||||||
|
// for the current ipv4 options, return the number of bytes (including
|
||||||
|
// padding that the options used)
|
||||||
|
func (ip *IPv4) getIPv4OptionSize() uint8 {
|
||||||
|
optionSize := uint8(0)
|
||||||
|
for _, opt := range ip.Options {
|
||||||
|
switch opt.OptionType {
|
||||||
|
case 0:
|
||||||
|
// this is the end of option lists
|
||||||
|
optionSize++
|
||||||
|
case 1:
|
||||||
|
// this is the padding
|
||||||
|
optionSize++
|
||||||
|
default:
|
||||||
|
optionSize += opt.OptionLength
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// make sure the options are aligned to 32 bit boundary
|
||||||
|
if (optionSize % 4) != 0 {
|
||||||
|
optionSize += 4 - (optionSize % 4)
|
||||||
|
}
|
||||||
|
return optionSize
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
func (ip *IPv4) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
optionLength := ip.getIPv4OptionSize()
|
||||||
|
bytes, err := b.PrependBytes(20 + int(optionLength))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if opts.FixLengths {
|
||||||
|
ip.IHL = 5 + (optionLength / 4)
|
||||||
|
ip.Length = uint16(len(b.Bytes()))
|
||||||
|
}
|
||||||
|
bytes[0] = (ip.Version << 4) | ip.IHL
|
||||||
|
bytes[1] = ip.TOS
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], ip.Length)
|
||||||
|
binary.BigEndian.PutUint16(bytes[4:], ip.Id)
|
||||||
|
binary.BigEndian.PutUint16(bytes[6:], ip.flagsfrags())
|
||||||
|
bytes[8] = ip.TTL
|
||||||
|
bytes[9] = byte(ip.Protocol)
|
||||||
|
if err := ip.AddressTo4(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
copy(bytes[12:16], ip.SrcIP)
|
||||||
|
copy(bytes[16:20], ip.DstIP)
|
||||||
|
|
||||||
|
curLocation := 20
|
||||||
|
// Now, we will encode the options
|
||||||
|
for _, opt := range ip.Options {
|
||||||
|
switch opt.OptionType {
|
||||||
|
case 0:
|
||||||
|
// this is the end of option lists
|
||||||
|
bytes[curLocation] = 0
|
||||||
|
curLocation++
|
||||||
|
case 1:
|
||||||
|
// this is the padding
|
||||||
|
bytes[curLocation] = 1
|
||||||
|
curLocation++
|
||||||
|
default:
|
||||||
|
bytes[curLocation] = opt.OptionType
|
||||||
|
bytes[curLocation+1] = opt.OptionLength
|
||||||
|
|
||||||
|
// sanity checking to protect us from buffer overrun
|
||||||
|
if len(opt.OptionData) > int(opt.OptionLength-2) {
|
||||||
|
return errors.New("option length is smaller than length of option data")
|
||||||
|
}
|
||||||
|
copy(bytes[curLocation+2:curLocation+int(opt.OptionLength)], opt.OptionData)
|
||||||
|
curLocation += int(opt.OptionLength)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.ComputeChecksums {
|
||||||
|
ip.Checksum = checksum(bytes)
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes[10:], ip.Checksum)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checksum(bytes []byte) uint16 {
|
||||||
|
// Clear checksum bytes
|
||||||
|
bytes[10] = 0
|
||||||
|
bytes[11] = 0
|
||||||
|
|
||||||
|
// Compute checksum
|
||||||
|
var csum uint32
|
||||||
|
for i := 0; i < len(bytes); i += 2 {
|
||||||
|
csum += uint32(bytes[i]) << 8
|
||||||
|
csum += uint32(bytes[i+1])
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
// Break when sum is less or equals to 0xFFFF
|
||||||
|
if csum <= 65535 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// Add carry to the sum
|
||||||
|
csum = (csum >> 16) + uint32(uint16(csum))
|
||||||
|
}
|
||||||
|
// Flip all the bits
|
||||||
|
return ^uint16(csum)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ip *IPv4) flagsfrags() (ff uint16) {
|
||||||
|
ff |= uint16(ip.Flags) << 13
|
||||||
|
ff |= ip.FragOffset
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (ip *IPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 20 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("Invalid ip4 header. Length %d less than 20", len(data))
|
||||||
|
}
|
||||||
|
flagsfrags := binary.BigEndian.Uint16(data[6:8])
|
||||||
|
|
||||||
|
ip.Version = uint8(data[0]) >> 4
|
||||||
|
ip.IHL = uint8(data[0]) & 0x0F
|
||||||
|
ip.TOS = data[1]
|
||||||
|
ip.Length = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
ip.Id = binary.BigEndian.Uint16(data[4:6])
|
||||||
|
ip.Flags = IPv4Flag(flagsfrags >> 13)
|
||||||
|
ip.FragOffset = flagsfrags & 0x1FFF
|
||||||
|
ip.TTL = data[8]
|
||||||
|
ip.Protocol = IPProtocol(data[9])
|
||||||
|
ip.Checksum = binary.BigEndian.Uint16(data[10:12])
|
||||||
|
ip.SrcIP = data[12:16]
|
||||||
|
ip.DstIP = data[16:20]
|
||||||
|
ip.Options = ip.Options[:0]
|
||||||
|
ip.Padding = nil
|
||||||
|
// Set up an initial guess for contents/payload... we'll reset these soon.
|
||||||
|
ip.BaseLayer = BaseLayer{Contents: data}
|
||||||
|
|
||||||
|
// This code is added for the following enviroment:
|
||||||
|
// * Windows 10 with TSO option activated. ( tested on Hyper-V, RealTek ethernet driver )
|
||||||
|
if ip.Length == 0 {
|
||||||
|
// If using TSO(TCP Segmentation Offload), length is zero.
|
||||||
|
// The actual packet length is the length of data.
|
||||||
|
ip.Length = uint16(len(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
if ip.Length < 20 {
|
||||||
|
return fmt.Errorf("Invalid (too small) IP length (%d < 20)", ip.Length)
|
||||||
|
} else if ip.IHL < 5 {
|
||||||
|
return fmt.Errorf("Invalid (too small) IP header length (%d < 5)", ip.IHL)
|
||||||
|
} else if int(ip.IHL*4) > int(ip.Length) {
|
||||||
|
return fmt.Errorf("Invalid IP header length > IP length (%d > %d)", ip.IHL, ip.Length)
|
||||||
|
}
|
||||||
|
if cmp := len(data) - int(ip.Length); cmp > 0 {
|
||||||
|
data = data[:ip.Length]
|
||||||
|
} else if cmp < 0 {
|
||||||
|
df.SetTruncated()
|
||||||
|
if int(ip.IHL)*4 > len(data) {
|
||||||
|
return errors.New("Not all IP header bytes available")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ip.Contents = data[:ip.IHL*4]
|
||||||
|
ip.Payload = data[ip.IHL*4:]
|
||||||
|
// From here on, data contains the header options.
|
||||||
|
data = data[20 : ip.IHL*4]
|
||||||
|
// Pull out IP options
|
||||||
|
for len(data) > 0 {
|
||||||
|
if ip.Options == nil {
|
||||||
|
// Pre-allocate to avoid growing the slice too much.
|
||||||
|
ip.Options = make([]IPv4Option, 0, 4)
|
||||||
|
}
|
||||||
|
opt := IPv4Option{OptionType: data[0]}
|
||||||
|
switch opt.OptionType {
|
||||||
|
case 0: // End of options
|
||||||
|
opt.OptionLength = 1
|
||||||
|
ip.Options = append(ip.Options, opt)
|
||||||
|
ip.Padding = data[1:]
|
||||||
|
return nil
|
||||||
|
case 1: // 1 byte padding
|
||||||
|
opt.OptionLength = 1
|
||||||
|
data = data[1:]
|
||||||
|
ip.Options = append(ip.Options, opt)
|
||||||
|
default:
|
||||||
|
if len(data) < 2 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("Invalid ip4 option length. Length %d less than 2", len(data))
|
||||||
|
}
|
||||||
|
opt.OptionLength = data[1]
|
||||||
|
if len(data) < int(opt.OptionLength) {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("IP option length exceeds remaining IP header size, option type %v length %v", opt.OptionType, opt.OptionLength)
|
||||||
|
}
|
||||||
|
if opt.OptionLength <= 2 {
|
||||||
|
return fmt.Errorf("Invalid IP option type %v length %d. Must be greater than 2", opt.OptionType, opt.OptionLength)
|
||||||
|
}
|
||||||
|
opt.OptionData = data[2:opt.OptionLength]
|
||||||
|
data = data[opt.OptionLength:]
|
||||||
|
ip.Options = append(ip.Options, opt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IPv4) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeIPv4
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IPv4) NextLayerType() gopacket.LayerType {
|
||||||
|
if i.Flags&IPv4MoreFragments != 0 || i.FragOffset != 0 {
|
||||||
|
return gopacket.LayerTypeFragment
|
||||||
|
}
|
||||||
|
return i.Protocol.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeIPv4(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
ip := &IPv4{}
|
||||||
|
err := ip.DecodeFromBytes(data, p)
|
||||||
|
p.AddLayer(ip)
|
||||||
|
p.SetNetworkLayer(ip)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.NextDecoder(ip.NextLayerType())
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkIPv4Address(addr net.IP) (net.IP, error) {
|
||||||
|
if c := addr.To4(); c != nil {
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
if len(addr) == net.IPv6len {
|
||||||
|
return nil, errors.New("address is IPv6")
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("wrong length of %d bytes instead of %d", len(addr), net.IPv4len)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ip *IPv4) AddressTo4() error {
|
||||||
|
var src, dst net.IP
|
||||||
|
|
||||||
|
if addr, err := checkIPv4Address(ip.SrcIP); err != nil {
|
||||||
|
return fmt.Errorf("Invalid source IPv4 address (%s)", err)
|
||||||
|
} else {
|
||||||
|
src = addr
|
||||||
|
}
|
||||||
|
if addr, err := checkIPv4Address(ip.DstIP); err != nil {
|
||||||
|
return fmt.Errorf("Invalid destination IPv4 address (%s)", err)
|
||||||
|
} else {
|
||||||
|
dst = addr
|
||||||
|
}
|
||||||
|
ip.SrcIP = src
|
||||||
|
ip.DstIP = dst
|
||||||
|
return nil
|
||||||
|
}
|
722
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ip6.go
generated
vendored
Normal file
722
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ip6.go
generated
vendored
Normal file
|
@ -0,0 +1,722 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// IPv6HopByHopOptionJumbogram code as defined in RFC 2675
|
||||||
|
IPv6HopByHopOptionJumbogram = 0xC2
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ipv6MaxPayloadLength = 65535
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPv6 is the layer for the IPv6 header.
|
||||||
|
type IPv6 struct {
|
||||||
|
// http://www.networksorcery.com/enp/protocol/ipv6.htm
|
||||||
|
BaseLayer
|
||||||
|
Version uint8
|
||||||
|
TrafficClass uint8
|
||||||
|
FlowLabel uint32
|
||||||
|
Length uint16
|
||||||
|
NextHeader IPProtocol
|
||||||
|
HopLimit uint8
|
||||||
|
SrcIP net.IP
|
||||||
|
DstIP net.IP
|
||||||
|
HopByHop *IPv6HopByHop
|
||||||
|
// hbh will be pointed to by HopByHop if that layer exists.
|
||||||
|
hbh IPv6HopByHop
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeIPv6
|
||||||
|
func (ipv6 *IPv6) LayerType() gopacket.LayerType { return LayerTypeIPv6 }
|
||||||
|
|
||||||
|
// NetworkFlow returns this new Flow (EndpointIPv6, SrcIP, DstIP)
|
||||||
|
func (ipv6 *IPv6) NetworkFlow() gopacket.Flow {
|
||||||
|
return gopacket.NewFlow(EndpointIPv6, ipv6.SrcIP, ipv6.DstIP)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for Jumbo Payload TLV in IPv6HopByHop and return (length, true) if found
|
||||||
|
func getIPv6HopByHopJumboLength(hopopts *IPv6HopByHop) (uint32, bool, error) {
|
||||||
|
var tlv *IPv6HopByHopOption
|
||||||
|
|
||||||
|
for _, t := range hopopts.Options {
|
||||||
|
if t.OptionType == IPv6HopByHopOptionJumbogram {
|
||||||
|
tlv = t
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tlv == nil {
|
||||||
|
// Not found
|
||||||
|
return 0, false, nil
|
||||||
|
}
|
||||||
|
if len(tlv.OptionData) != 4 {
|
||||||
|
return 0, false, errors.New("Jumbo length TLV data must have length 4")
|
||||||
|
}
|
||||||
|
l := binary.BigEndian.Uint32(tlv.OptionData)
|
||||||
|
if l <= ipv6MaxPayloadLength {
|
||||||
|
return 0, false, fmt.Errorf("Jumbo length cannot be less than %d", ipv6MaxPayloadLength+1)
|
||||||
|
}
|
||||||
|
// Found
|
||||||
|
return l, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds zero-valued Jumbo TLV to IPv6 header if it does not exist
|
||||||
|
// (if necessary add hop-by-hop header)
|
||||||
|
func addIPv6JumboOption(ip6 *IPv6) {
|
||||||
|
var tlv *IPv6HopByHopOption
|
||||||
|
|
||||||
|
if ip6.HopByHop == nil {
|
||||||
|
// Add IPv6 HopByHop
|
||||||
|
ip6.HopByHop = &IPv6HopByHop{}
|
||||||
|
ip6.HopByHop.NextHeader = ip6.NextHeader
|
||||||
|
ip6.HopByHop.HeaderLength = 0
|
||||||
|
ip6.NextHeader = IPProtocolIPv6HopByHop
|
||||||
|
}
|
||||||
|
for _, t := range ip6.HopByHop.Options {
|
||||||
|
if t.OptionType == IPv6HopByHopOptionJumbogram {
|
||||||
|
tlv = t
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tlv == nil {
|
||||||
|
// Add Jumbo TLV
|
||||||
|
tlv = &IPv6HopByHopOption{}
|
||||||
|
ip6.HopByHop.Options = append(ip6.HopByHop.Options, tlv)
|
||||||
|
}
|
||||||
|
tlv.SetJumboLength(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set jumbo length in serialized IPv6 payload (starting with HopByHop header)
|
||||||
|
func setIPv6PayloadJumboLength(hbh []byte) error {
|
||||||
|
pLen := len(hbh)
|
||||||
|
if pLen < 8 {
|
||||||
|
//HopByHop is minimum 8 bytes
|
||||||
|
return fmt.Errorf("Invalid IPv6 payload (length %d)", pLen)
|
||||||
|
}
|
||||||
|
hbhLen := int((hbh[1] + 1) * 8)
|
||||||
|
if hbhLen > pLen {
|
||||||
|
return fmt.Errorf("Invalid hop-by-hop length (length: %d, payload: %d", hbhLen, pLen)
|
||||||
|
}
|
||||||
|
offset := 2 //start with options
|
||||||
|
for offset < hbhLen {
|
||||||
|
opt := hbh[offset]
|
||||||
|
if opt == 0 {
|
||||||
|
//Pad1
|
||||||
|
offset++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
optLen := int(hbh[offset+1])
|
||||||
|
if opt == IPv6HopByHopOptionJumbogram {
|
||||||
|
if optLen == 4 {
|
||||||
|
binary.BigEndian.PutUint32(hbh[offset+2:], uint32(pLen))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Jumbo TLV too short (%d bytes)", optLen)
|
||||||
|
}
|
||||||
|
offset += 2 + optLen
|
||||||
|
}
|
||||||
|
return errors.New("Jumbo TLV not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (ipv6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
var jumbo bool
|
||||||
|
var err error
|
||||||
|
|
||||||
|
payload := b.Bytes()
|
||||||
|
pLen := len(payload)
|
||||||
|
if pLen > ipv6MaxPayloadLength {
|
||||||
|
jumbo = true
|
||||||
|
if opts.FixLengths {
|
||||||
|
// We need to set the length later because the hop-by-hop header may
|
||||||
|
// not exist or else need padding, so pLen may yet change
|
||||||
|
addIPv6JumboOption(ipv6)
|
||||||
|
} else if ipv6.HopByHop == nil {
|
||||||
|
return fmt.Errorf("Cannot fit payload length of %d into IPv6 packet", pLen)
|
||||||
|
} else {
|
||||||
|
_, ok, err := getIPv6HopByHopJumboLength(ipv6.HopByHop)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return errors.New("Missing jumbo length hop-by-hop option")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hbhAlreadySerialized := false
|
||||||
|
if ipv6.HopByHop != nil {
|
||||||
|
for _, l := range b.Layers() {
|
||||||
|
if l == LayerTypeIPv6HopByHop {
|
||||||
|
hbhAlreadySerialized = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ipv6.HopByHop != nil && !hbhAlreadySerialized {
|
||||||
|
if ipv6.NextHeader != IPProtocolIPv6HopByHop {
|
||||||
|
// Just fix it instead of throwing an error
|
||||||
|
ipv6.NextHeader = IPProtocolIPv6HopByHop
|
||||||
|
}
|
||||||
|
err = ipv6.HopByHop.SerializeTo(b, opts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
payload = b.Bytes()
|
||||||
|
pLen = len(payload)
|
||||||
|
if opts.FixLengths && jumbo {
|
||||||
|
err := setIPv6PayloadJumboLength(payload)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !jumbo && pLen > ipv6MaxPayloadLength {
|
||||||
|
return errors.New("Cannot fit payload into IPv6 header")
|
||||||
|
}
|
||||||
|
bytes, err := b.PrependBytes(40)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = (ipv6.Version << 4) | (ipv6.TrafficClass >> 4)
|
||||||
|
bytes[1] = (ipv6.TrafficClass << 4) | uint8(ipv6.FlowLabel>>16)
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], uint16(ipv6.FlowLabel))
|
||||||
|
if opts.FixLengths {
|
||||||
|
if jumbo {
|
||||||
|
ipv6.Length = 0
|
||||||
|
} else {
|
||||||
|
ipv6.Length = uint16(pLen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes[4:], ipv6.Length)
|
||||||
|
bytes[6] = byte(ipv6.NextHeader)
|
||||||
|
bytes[7] = byte(ipv6.HopLimit)
|
||||||
|
if err := ipv6.AddressTo16(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
copy(bytes[8:], ipv6.SrcIP)
|
||||||
|
copy(bytes[24:], ipv6.DstIP)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes implementation according to gopacket.DecodingLayer
|
||||||
|
func (ipv6 *IPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 40 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("Invalid ip6 header. Length %d less than 40", len(data))
|
||||||
|
}
|
||||||
|
ipv6.Version = uint8(data[0]) >> 4
|
||||||
|
ipv6.TrafficClass = uint8((binary.BigEndian.Uint16(data[0:2]) >> 4) & 0x00FF)
|
||||||
|
ipv6.FlowLabel = binary.BigEndian.Uint32(data[0:4]) & 0x000FFFFF
|
||||||
|
ipv6.Length = binary.BigEndian.Uint16(data[4:6])
|
||||||
|
ipv6.NextHeader = IPProtocol(data[6])
|
||||||
|
ipv6.HopLimit = data[7]
|
||||||
|
ipv6.SrcIP = data[8:24]
|
||||||
|
ipv6.DstIP = data[24:40]
|
||||||
|
ipv6.HopByHop = nil
|
||||||
|
ipv6.BaseLayer = BaseLayer{data[:40], data[40:]}
|
||||||
|
|
||||||
|
// We treat a HopByHop IPv6 option as part of the IPv6 packet, since its
|
||||||
|
// options are crucial for understanding what's actually happening per packet.
|
||||||
|
if ipv6.NextHeader == IPProtocolIPv6HopByHop {
|
||||||
|
err := ipv6.hbh.DecodeFromBytes(ipv6.Payload, df)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ipv6.HopByHop = &ipv6.hbh
|
||||||
|
pEnd, jumbo, err := getIPv6HopByHopJumboLength(ipv6.HopByHop)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if jumbo && ipv6.Length == 0 {
|
||||||
|
pEnd := int(pEnd)
|
||||||
|
if pEnd > len(ipv6.Payload) {
|
||||||
|
df.SetTruncated()
|
||||||
|
pEnd = len(ipv6.Payload)
|
||||||
|
}
|
||||||
|
ipv6.Payload = ipv6.Payload[:pEnd]
|
||||||
|
return nil
|
||||||
|
} else if jumbo && ipv6.Length != 0 {
|
||||||
|
return errors.New("IPv6 has jumbo length and IPv6 length is not 0")
|
||||||
|
} else if !jumbo && ipv6.Length == 0 {
|
||||||
|
return errors.New("IPv6 length 0, but HopByHop header does not have jumbogram option")
|
||||||
|
} else {
|
||||||
|
ipv6.Payload = ipv6.Payload[ipv6.hbh.ActualLength:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ipv6.Length == 0 {
|
||||||
|
return fmt.Errorf("IPv6 length 0, but next header is %v, not HopByHop", ipv6.NextHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
pEnd := int(ipv6.Length)
|
||||||
|
if pEnd > len(ipv6.Payload) {
|
||||||
|
df.SetTruncated()
|
||||||
|
pEnd = len(ipv6.Payload)
|
||||||
|
}
|
||||||
|
ipv6.Payload = ipv6.Payload[:pEnd]
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode implementation according to gopacket.DecodingLayer
|
||||||
|
func (ipv6 *IPv6) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeIPv6
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType implementation according to gopacket.DecodingLayer
|
||||||
|
func (ipv6 *IPv6) NextLayerType() gopacket.LayerType {
|
||||||
|
if ipv6.HopByHop != nil {
|
||||||
|
return ipv6.HopByHop.NextHeader.LayerType()
|
||||||
|
}
|
||||||
|
return ipv6.NextHeader.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeIPv6(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
ip6 := &IPv6{}
|
||||||
|
err := ip6.DecodeFromBytes(data, p)
|
||||||
|
p.AddLayer(ip6)
|
||||||
|
p.SetNetworkLayer(ip6)
|
||||||
|
if ip6.HopByHop != nil {
|
||||||
|
p.AddLayer(ip6.HopByHop)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.NextDecoder(ip6.NextLayerType())
|
||||||
|
}
|
||||||
|
|
||||||
|
type ipv6HeaderTLVOption struct {
|
||||||
|
OptionType, OptionLength uint8
|
||||||
|
ActualLength int
|
||||||
|
OptionData []byte
|
||||||
|
OptionAlignment [2]uint8 // Xn+Y = [2]uint8{X, Y}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ipv6HeaderTLVOption) serializeTo(data []byte, fixLengths bool, dryrun bool) int {
|
||||||
|
if fixLengths {
|
||||||
|
h.OptionLength = uint8(len(h.OptionData))
|
||||||
|
}
|
||||||
|
length := int(h.OptionLength) + 2
|
||||||
|
if !dryrun {
|
||||||
|
data[0] = h.OptionType
|
||||||
|
data[1] = h.OptionLength
|
||||||
|
copy(data[2:], h.OptionData)
|
||||||
|
}
|
||||||
|
return length
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeIPv6HeaderTLVOption(data []byte, df gopacket.DecodeFeedback) (h *ipv6HeaderTLVOption, _ error) {
|
||||||
|
if len(data) < 2 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return nil, errors.New("IPv6 header option too small")
|
||||||
|
}
|
||||||
|
h = &ipv6HeaderTLVOption{}
|
||||||
|
if data[0] == 0 {
|
||||||
|
h.ActualLength = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.OptionType = data[0]
|
||||||
|
h.OptionLength = data[1]
|
||||||
|
h.ActualLength = int(h.OptionLength) + 2
|
||||||
|
if len(data) < h.ActualLength {
|
||||||
|
df.SetTruncated()
|
||||||
|
return nil, errors.New("IPv6 header TLV option too small")
|
||||||
|
}
|
||||||
|
h.OptionData = data[2:h.ActualLength]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func serializeTLVOptionPadding(data []byte, padLength int) {
|
||||||
|
if padLength <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if padLength == 1 {
|
||||||
|
data[0] = 0x0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tlvLength := uint8(padLength) - 2
|
||||||
|
data[0] = 0x1
|
||||||
|
data[1] = tlvLength
|
||||||
|
if tlvLength != 0 {
|
||||||
|
for k := range data[2:] {
|
||||||
|
data[k+2] = 0x0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If buf is 'nil' do a serialize dry run
|
||||||
|
func serializeIPv6HeaderTLVOptions(buf []byte, options []*ipv6HeaderTLVOption, fixLengths bool) int {
|
||||||
|
var l int
|
||||||
|
|
||||||
|
dryrun := buf == nil
|
||||||
|
length := 2
|
||||||
|
for _, opt := range options {
|
||||||
|
if fixLengths {
|
||||||
|
x := int(opt.OptionAlignment[0])
|
||||||
|
y := int(opt.OptionAlignment[1])
|
||||||
|
if x != 0 {
|
||||||
|
n := length / x
|
||||||
|
offset := x*n + y
|
||||||
|
if offset < length {
|
||||||
|
offset += x
|
||||||
|
}
|
||||||
|
if length != offset {
|
||||||
|
pad := offset - length
|
||||||
|
if !dryrun {
|
||||||
|
serializeTLVOptionPadding(buf[length-2:], pad)
|
||||||
|
}
|
||||||
|
length += pad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if dryrun {
|
||||||
|
l = opt.serializeTo(nil, fixLengths, true)
|
||||||
|
} else {
|
||||||
|
l = opt.serializeTo(buf[length-2:], fixLengths, false)
|
||||||
|
}
|
||||||
|
length += l
|
||||||
|
}
|
||||||
|
if fixLengths {
|
||||||
|
pad := length % 8
|
||||||
|
if pad != 0 {
|
||||||
|
if !dryrun {
|
||||||
|
serializeTLVOptionPadding(buf[length-2:], pad)
|
||||||
|
}
|
||||||
|
length += pad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return length - 2
|
||||||
|
}
|
||||||
|
|
||||||
|
type ipv6ExtensionBase struct {
|
||||||
|
BaseLayer
|
||||||
|
NextHeader IPProtocol
|
||||||
|
HeaderLength uint8
|
||||||
|
ActualLength int
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeIPv6ExtensionBase(data []byte, df gopacket.DecodeFeedback) (i ipv6ExtensionBase, returnedErr error) {
|
||||||
|
if len(data) < 2 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return ipv6ExtensionBase{}, fmt.Errorf("Invalid ip6-extension header. Length %d less than 2", len(data))
|
||||||
|
}
|
||||||
|
i.NextHeader = IPProtocol(data[0])
|
||||||
|
i.HeaderLength = data[1]
|
||||||
|
i.ActualLength = int(i.HeaderLength)*8 + 8
|
||||||
|
if len(data) < i.ActualLength {
|
||||||
|
return ipv6ExtensionBase{}, fmt.Errorf("Invalid ip6-extension header. Length %d less than specified length %d", len(data), i.ActualLength)
|
||||||
|
}
|
||||||
|
i.Contents = data[:i.ActualLength]
|
||||||
|
i.Payload = data[i.ActualLength:]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv6ExtensionSkipper is a DecodingLayer which decodes and ignores v6
|
||||||
|
// extensions. You can use it with a DecodingLayerParser to handle IPv6 stacks
|
||||||
|
// which may or may not have extensions.
|
||||||
|
type IPv6ExtensionSkipper struct {
|
||||||
|
NextHeader IPProtocol
|
||||||
|
BaseLayer
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes implementation according to gopacket.DecodingLayer
|
||||||
|
func (i *IPv6ExtensionSkipper) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
extension, err := decodeIPv6ExtensionBase(data, df)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i.BaseLayer = BaseLayer{data[:extension.ActualLength], data[extension.ActualLength:]}
|
||||||
|
i.NextHeader = extension.NextHeader
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode implementation according to gopacket.DecodingLayer
|
||||||
|
func (i *IPv6ExtensionSkipper) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerClassIPv6Extension
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType implementation according to gopacket.DecodingLayer
|
||||||
|
func (i *IPv6ExtensionSkipper) NextLayerType() gopacket.LayerType {
|
||||||
|
return i.NextHeader.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv6HopByHopOption is a TLV option present in an IPv6 hop-by-hop extension.
|
||||||
|
type IPv6HopByHopOption ipv6HeaderTLVOption
|
||||||
|
|
||||||
|
// IPv6HopByHop is the IPv6 hop-by-hop extension.
|
||||||
|
type IPv6HopByHop struct {
|
||||||
|
ipv6ExtensionBase
|
||||||
|
Options []*IPv6HopByHopOption
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeIPv6HopByHop.
|
||||||
|
func (i *IPv6HopByHop) LayerType() gopacket.LayerType { return LayerTypeIPv6HopByHop }
|
||||||
|
|
||||||
|
// SerializeTo implementation according to gopacket.SerializableLayer
|
||||||
|
func (i *IPv6HopByHop) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
var bytes []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
o := make([]*ipv6HeaderTLVOption, 0, len(i.Options))
|
||||||
|
for _, v := range i.Options {
|
||||||
|
o = append(o, (*ipv6HeaderTLVOption)(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
l := serializeIPv6HeaderTLVOptions(nil, o, opts.FixLengths)
|
||||||
|
bytes, err = b.PrependBytes(l)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
serializeIPv6HeaderTLVOptions(bytes, o, opts.FixLengths)
|
||||||
|
|
||||||
|
length := len(bytes) + 2
|
||||||
|
if length%8 != 0 {
|
||||||
|
return errors.New("IPv6HopByHop actual length must be multiple of 8")
|
||||||
|
}
|
||||||
|
bytes, err = b.PrependBytes(2)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(i.NextHeader)
|
||||||
|
if opts.FixLengths {
|
||||||
|
i.HeaderLength = uint8((length / 8) - 1)
|
||||||
|
}
|
||||||
|
bytes[1] = uint8(i.HeaderLength)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes implementation according to gopacket.DecodingLayer
|
||||||
|
func (i *IPv6HopByHop) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
var err error
|
||||||
|
i.ipv6ExtensionBase, err = decodeIPv6ExtensionBase(data, df)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i.Options = i.Options[:0]
|
||||||
|
offset := 2
|
||||||
|
for offset < i.ActualLength {
|
||||||
|
opt, err := decodeIPv6HeaderTLVOption(data[offset:], df)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i.Options = append(i.Options, (*IPv6HopByHopOption)(opt))
|
||||||
|
offset += opt.ActualLength
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeIPv6HopByHop(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &IPv6HopByHop{}
|
||||||
|
err := i.DecodeFromBytes(data, p)
|
||||||
|
p.AddLayer(i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.NextDecoder(i.NextHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetJumboLength adds the IPv6HopByHopOptionJumbogram with the given length
|
||||||
|
func (o *IPv6HopByHopOption) SetJumboLength(len uint32) {
|
||||||
|
o.OptionType = IPv6HopByHopOptionJumbogram
|
||||||
|
o.OptionLength = 4
|
||||||
|
o.ActualLength = 6
|
||||||
|
if o.OptionData == nil {
|
||||||
|
o.OptionData = make([]byte, 4)
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint32(o.OptionData, len)
|
||||||
|
o.OptionAlignment = [2]uint8{4, 2}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv6Routing is the IPv6 routing extension.
|
||||||
|
type IPv6Routing struct {
|
||||||
|
ipv6ExtensionBase
|
||||||
|
RoutingType uint8
|
||||||
|
SegmentsLeft uint8
|
||||||
|
// This segment is supposed to be zero according to RFC2460, the second set of
|
||||||
|
// 4 bytes in the extension.
|
||||||
|
Reserved []byte
|
||||||
|
// SourceRoutingIPs is the set of IPv6 addresses requested for source routing,
|
||||||
|
// set only if RoutingType == 0.
|
||||||
|
SourceRoutingIPs []net.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeIPv6Routing.
|
||||||
|
func (i *IPv6Routing) LayerType() gopacket.LayerType { return LayerTypeIPv6Routing }
|
||||||
|
|
||||||
|
func decodeIPv6Routing(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
base, err := decodeIPv6ExtensionBase(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i := &IPv6Routing{
|
||||||
|
ipv6ExtensionBase: base,
|
||||||
|
RoutingType: data[2],
|
||||||
|
SegmentsLeft: data[3],
|
||||||
|
Reserved: data[4:8],
|
||||||
|
}
|
||||||
|
switch i.RoutingType {
|
||||||
|
case 0: // Source routing
|
||||||
|
if (i.ActualLength-8)%16 != 0 {
|
||||||
|
return fmt.Errorf("Invalid IPv6 source routing, length of type 0 packet %d", i.ActualLength)
|
||||||
|
}
|
||||||
|
for d := i.Contents[8:]; len(d) >= 16; d = d[16:] {
|
||||||
|
i.SourceRoutingIPs = append(i.SourceRoutingIPs, net.IP(d[:16]))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Unknown IPv6 routing header type %d", i.RoutingType)
|
||||||
|
}
|
||||||
|
p.AddLayer(i)
|
||||||
|
return p.NextDecoder(i.NextHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv6Fragment is the IPv6 fragment header, used for packet
|
||||||
|
// fragmentation/defragmentation.
|
||||||
|
type IPv6Fragment struct {
|
||||||
|
BaseLayer
|
||||||
|
NextHeader IPProtocol
|
||||||
|
// Reserved1 is bits [8-16), from least to most significant, 0-indexed
|
||||||
|
Reserved1 uint8
|
||||||
|
FragmentOffset uint16
|
||||||
|
// Reserved2 is bits [29-31), from least to most significant, 0-indexed
|
||||||
|
Reserved2 uint8
|
||||||
|
MoreFragments bool
|
||||||
|
Identification uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeIPv6Fragment.
|
||||||
|
func (i *IPv6Fragment) LayerType() gopacket.LayerType { return LayerTypeIPv6Fragment }
|
||||||
|
|
||||||
|
func decodeIPv6Fragment(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
if len(data) < 8 {
|
||||||
|
p.SetTruncated()
|
||||||
|
return fmt.Errorf("Invalid ip6-fragment header. Length %d less than 8", len(data))
|
||||||
|
}
|
||||||
|
i := &IPv6Fragment{
|
||||||
|
BaseLayer: BaseLayer{data[:8], data[8:]},
|
||||||
|
NextHeader: IPProtocol(data[0]),
|
||||||
|
Reserved1: data[1],
|
||||||
|
FragmentOffset: binary.BigEndian.Uint16(data[2:4]) >> 3,
|
||||||
|
Reserved2: data[3] & 0x6 >> 1,
|
||||||
|
MoreFragments: data[3]&0x1 != 0,
|
||||||
|
Identification: binary.BigEndian.Uint32(data[4:8]),
|
||||||
|
}
|
||||||
|
p.AddLayer(i)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFragment)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv6DestinationOption is a TLV option present in an IPv6 destination options extension.
|
||||||
|
type IPv6DestinationOption ipv6HeaderTLVOption
|
||||||
|
|
||||||
|
// IPv6Destination is the IPv6 destination options header.
|
||||||
|
type IPv6Destination struct {
|
||||||
|
ipv6ExtensionBase
|
||||||
|
Options []*IPv6DestinationOption
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeIPv6Destination.
|
||||||
|
func (i *IPv6Destination) LayerType() gopacket.LayerType { return LayerTypeIPv6Destination }
|
||||||
|
|
||||||
|
// DecodeFromBytes implementation according to gopacket.DecodingLayer
|
||||||
|
func (i *IPv6Destination) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
var err error
|
||||||
|
i.ipv6ExtensionBase, err = decodeIPv6ExtensionBase(data, df)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
offset := 2
|
||||||
|
for offset < i.ActualLength {
|
||||||
|
opt, err := decodeIPv6HeaderTLVOption(data[offset:], df)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i.Options = append(i.Options, (*IPv6DestinationOption)(opt))
|
||||||
|
offset += opt.ActualLength
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeIPv6Destination(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &IPv6Destination{}
|
||||||
|
err := i.DecodeFromBytes(data, p)
|
||||||
|
p.AddLayer(i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.NextDecoder(i.NextHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (i *IPv6Destination) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
var bytes []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
o := make([]*ipv6HeaderTLVOption, 0, len(i.Options))
|
||||||
|
for _, v := range i.Options {
|
||||||
|
o = append(o, (*ipv6HeaderTLVOption)(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
l := serializeIPv6HeaderTLVOptions(nil, o, opts.FixLengths)
|
||||||
|
bytes, err = b.PrependBytes(l)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
serializeIPv6HeaderTLVOptions(bytes, o, opts.FixLengths)
|
||||||
|
|
||||||
|
length := len(bytes) + 2
|
||||||
|
if length%8 != 0 {
|
||||||
|
return errors.New("IPv6Destination actual length must be multiple of 8")
|
||||||
|
}
|
||||||
|
bytes, err = b.PrependBytes(2)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(i.NextHeader)
|
||||||
|
if opts.FixLengths {
|
||||||
|
i.HeaderLength = uint8((length / 8) - 1)
|
||||||
|
}
|
||||||
|
bytes[1] = uint8(i.HeaderLength)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkIPv6Address(addr net.IP) error {
|
||||||
|
if len(addr) == net.IPv6len {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if len(addr) == net.IPv4len {
|
||||||
|
return errors.New("address is IPv4")
|
||||||
|
}
|
||||||
|
return fmt.Errorf("wrong length of %d bytes instead of %d", len(addr), net.IPv6len)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddressTo16 ensures IPv6.SrcIP and IPv6.DstIP are actually IPv6 addresses (i.e. 16 byte addresses)
|
||||||
|
func (ipv6 *IPv6) AddressTo16() error {
|
||||||
|
if err := checkIPv6Address(ipv6.SrcIP); err != nil {
|
||||||
|
return fmt.Errorf("Invalid source IPv6 address (%s)", err)
|
||||||
|
}
|
||||||
|
if err := checkIPv6Address(ipv6.DstIP); err != nil {
|
||||||
|
return fmt.Errorf("Invalid destination IPv6 address (%s)", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
77
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ipsec.go
generated
vendored
Normal file
77
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ipsec.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPSecAH is the authentication header for IPv4/6 defined in
|
||||||
|
// http://tools.ietf.org/html/rfc2402
|
||||||
|
type IPSecAH struct {
|
||||||
|
// While the auth header can be used for both IPv4 and v6, its format is that of
|
||||||
|
// an IPv6 extension (NextHeader, PayloadLength, etc...), so we use ipv6ExtensionBase
|
||||||
|
// to build it.
|
||||||
|
ipv6ExtensionBase
|
||||||
|
Reserved uint16
|
||||||
|
SPI, Seq uint32
|
||||||
|
AuthenticationData []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeIPSecAH.
|
||||||
|
func (i *IPSecAH) LayerType() gopacket.LayerType { return LayerTypeIPSecAH }
|
||||||
|
|
||||||
|
func decodeIPSecAH(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
if len(data) < 12 {
|
||||||
|
p.SetTruncated()
|
||||||
|
return errors.New("IPSec AH packet less than 12 bytes")
|
||||||
|
}
|
||||||
|
i := &IPSecAH{
|
||||||
|
ipv6ExtensionBase: ipv6ExtensionBase{
|
||||||
|
NextHeader: IPProtocol(data[0]),
|
||||||
|
HeaderLength: data[1],
|
||||||
|
},
|
||||||
|
Reserved: binary.BigEndian.Uint16(data[2:4]),
|
||||||
|
SPI: binary.BigEndian.Uint32(data[4:8]),
|
||||||
|
Seq: binary.BigEndian.Uint32(data[8:12]),
|
||||||
|
}
|
||||||
|
i.ActualLength = (int(i.HeaderLength) + 2) * 4
|
||||||
|
if len(data) < i.ActualLength {
|
||||||
|
p.SetTruncated()
|
||||||
|
return errors.New("Truncated AH packet < ActualLength")
|
||||||
|
}
|
||||||
|
i.AuthenticationData = data[12:i.ActualLength]
|
||||||
|
i.Contents = data[:i.ActualLength]
|
||||||
|
i.Payload = data[i.ActualLength:]
|
||||||
|
p.AddLayer(i)
|
||||||
|
return p.NextDecoder(i.NextHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPSecESP is the encapsulating security payload defined in
|
||||||
|
// http://tools.ietf.org/html/rfc2406
|
||||||
|
type IPSecESP struct {
|
||||||
|
BaseLayer
|
||||||
|
SPI, Seq uint32
|
||||||
|
// Encrypted contains the encrypted set of bytes sent in an ESP
|
||||||
|
Encrypted []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeIPSecESP.
|
||||||
|
func (i *IPSecESP) LayerType() gopacket.LayerType { return LayerTypeIPSecESP }
|
||||||
|
|
||||||
|
func decodeIPSecESP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
i := &IPSecESP{
|
||||||
|
BaseLayer: BaseLayer{data, nil},
|
||||||
|
SPI: binary.BigEndian.Uint32(data[:4]),
|
||||||
|
Seq: binary.BigEndian.Uint32(data[4:8]),
|
||||||
|
Encrypted: data[8:],
|
||||||
|
}
|
||||||
|
p.AddLayer(i)
|
||||||
|
return nil
|
||||||
|
}
|
223
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/layertypes.go
generated
vendored
Normal file
223
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/layertypes.go
generated
vendored
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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 (
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
LayerTypeARP = gopacket.RegisterLayerType(10, gopacket.LayerTypeMetadata{Name: "ARP", Decoder: gopacket.DecodeFunc(decodeARP)})
|
||||||
|
LayerTypeCiscoDiscovery = gopacket.RegisterLayerType(11, gopacket.LayerTypeMetadata{Name: "CiscoDiscovery", Decoder: gopacket.DecodeFunc(decodeCiscoDiscovery)})
|
||||||
|
LayerTypeEthernetCTP = gopacket.RegisterLayerType(12, gopacket.LayerTypeMetadata{Name: "EthernetCTP", Decoder: gopacket.DecodeFunc(decodeEthernetCTP)})
|
||||||
|
LayerTypeEthernetCTPForwardData = gopacket.RegisterLayerType(13, gopacket.LayerTypeMetadata{Name: "EthernetCTPForwardData", Decoder: nil})
|
||||||
|
LayerTypeEthernetCTPReply = gopacket.RegisterLayerType(14, gopacket.LayerTypeMetadata{Name: "EthernetCTPReply", Decoder: nil})
|
||||||
|
LayerTypeDot1Q = gopacket.RegisterLayerType(15, gopacket.LayerTypeMetadata{Name: "Dot1Q", Decoder: gopacket.DecodeFunc(decodeDot1Q)})
|
||||||
|
LayerTypeEtherIP = gopacket.RegisterLayerType(16, gopacket.LayerTypeMetadata{Name: "EtherIP", Decoder: gopacket.DecodeFunc(decodeEtherIP)})
|
||||||
|
LayerTypeEthernet = gopacket.RegisterLayerType(17, gopacket.LayerTypeMetadata{Name: "Ethernet", Decoder: gopacket.DecodeFunc(decodeEthernet)})
|
||||||
|
LayerTypeGRE = gopacket.RegisterLayerType(18, gopacket.LayerTypeMetadata{Name: "GRE", Decoder: gopacket.DecodeFunc(decodeGRE)})
|
||||||
|
LayerTypeICMPv4 = gopacket.RegisterLayerType(19, gopacket.LayerTypeMetadata{Name: "ICMPv4", Decoder: gopacket.DecodeFunc(decodeICMPv4)})
|
||||||
|
LayerTypeIPv4 = gopacket.RegisterLayerType(20, gopacket.LayerTypeMetadata{Name: "IPv4", Decoder: gopacket.DecodeFunc(decodeIPv4)})
|
||||||
|
LayerTypeIPv6 = gopacket.RegisterLayerType(21, gopacket.LayerTypeMetadata{Name: "IPv6", Decoder: gopacket.DecodeFunc(decodeIPv6)})
|
||||||
|
LayerTypeLLC = gopacket.RegisterLayerType(22, gopacket.LayerTypeMetadata{Name: "LLC", Decoder: gopacket.DecodeFunc(decodeLLC)})
|
||||||
|
LayerTypeSNAP = gopacket.RegisterLayerType(23, gopacket.LayerTypeMetadata{Name: "SNAP", Decoder: gopacket.DecodeFunc(decodeSNAP)})
|
||||||
|
LayerTypeMPLS = gopacket.RegisterLayerType(24, gopacket.LayerTypeMetadata{Name: "MPLS", Decoder: gopacket.DecodeFunc(decodeMPLS)})
|
||||||
|
LayerTypePPP = gopacket.RegisterLayerType(25, gopacket.LayerTypeMetadata{Name: "PPP", Decoder: gopacket.DecodeFunc(decodePPP)})
|
||||||
|
LayerTypePPPoE = gopacket.RegisterLayerType(26, gopacket.LayerTypeMetadata{Name: "PPPoE", Decoder: gopacket.DecodeFunc(decodePPPoE)})
|
||||||
|
LayerTypeRUDP = gopacket.RegisterLayerType(27, gopacket.LayerTypeMetadata{Name: "RUDP", Decoder: gopacket.DecodeFunc(decodeRUDP)})
|
||||||
|
LayerTypeSCTP = gopacket.RegisterLayerType(28, gopacket.LayerTypeMetadata{Name: "SCTP", Decoder: gopacket.DecodeFunc(decodeSCTP)})
|
||||||
|
LayerTypeSCTPUnknownChunkType = gopacket.RegisterLayerType(29, gopacket.LayerTypeMetadata{Name: "SCTPUnknownChunkType", Decoder: nil})
|
||||||
|
LayerTypeSCTPData = gopacket.RegisterLayerType(30, gopacket.LayerTypeMetadata{Name: "SCTPData", Decoder: nil})
|
||||||
|
LayerTypeSCTPInit = gopacket.RegisterLayerType(31, gopacket.LayerTypeMetadata{Name: "SCTPInit", Decoder: nil})
|
||||||
|
LayerTypeSCTPSack = gopacket.RegisterLayerType(32, gopacket.LayerTypeMetadata{Name: "SCTPSack", Decoder: nil})
|
||||||
|
LayerTypeSCTPHeartbeat = gopacket.RegisterLayerType(33, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeat", Decoder: nil})
|
||||||
|
LayerTypeSCTPError = gopacket.RegisterLayerType(34, gopacket.LayerTypeMetadata{Name: "SCTPError", Decoder: nil})
|
||||||
|
LayerTypeSCTPShutdown = gopacket.RegisterLayerType(35, gopacket.LayerTypeMetadata{Name: "SCTPShutdown", Decoder: nil})
|
||||||
|
LayerTypeSCTPShutdownAck = gopacket.RegisterLayerType(36, gopacket.LayerTypeMetadata{Name: "SCTPShutdownAck", Decoder: nil})
|
||||||
|
LayerTypeSCTPCookieEcho = gopacket.RegisterLayerType(37, gopacket.LayerTypeMetadata{Name: "SCTPCookieEcho", Decoder: nil})
|
||||||
|
LayerTypeSCTPEmptyLayer = gopacket.RegisterLayerType(38, gopacket.LayerTypeMetadata{Name: "SCTPEmptyLayer", Decoder: nil})
|
||||||
|
LayerTypeSCTPInitAck = gopacket.RegisterLayerType(39, gopacket.LayerTypeMetadata{Name: "SCTPInitAck", Decoder: nil})
|
||||||
|
LayerTypeSCTPHeartbeatAck = gopacket.RegisterLayerType(40, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeatAck", Decoder: nil})
|
||||||
|
LayerTypeSCTPAbort = gopacket.RegisterLayerType(41, gopacket.LayerTypeMetadata{Name: "SCTPAbort", Decoder: nil})
|
||||||
|
LayerTypeSCTPShutdownComplete = gopacket.RegisterLayerType(42, gopacket.LayerTypeMetadata{Name: "SCTPShutdownComplete", Decoder: nil})
|
||||||
|
LayerTypeSCTPCookieAck = gopacket.RegisterLayerType(43, gopacket.LayerTypeMetadata{Name: "SCTPCookieAck", Decoder: nil})
|
||||||
|
LayerTypeTCP = gopacket.RegisterLayerType(44, gopacket.LayerTypeMetadata{Name: "TCP", Decoder: gopacket.DecodeFunc(decodeTCP)})
|
||||||
|
LayerTypeUDP = gopacket.RegisterLayerType(45, gopacket.LayerTypeMetadata{Name: "UDP", Decoder: gopacket.DecodeFunc(decodeUDP)})
|
||||||
|
LayerTypeIPv6HopByHop = gopacket.RegisterLayerType(46, gopacket.LayerTypeMetadata{Name: "IPv6HopByHop", Decoder: gopacket.DecodeFunc(decodeIPv6HopByHop)})
|
||||||
|
LayerTypeIPv6Routing = gopacket.RegisterLayerType(47, gopacket.LayerTypeMetadata{Name: "IPv6Routing", Decoder: gopacket.DecodeFunc(decodeIPv6Routing)})
|
||||||
|
LayerTypeIPv6Fragment = gopacket.RegisterLayerType(48, gopacket.LayerTypeMetadata{Name: "IPv6Fragment", Decoder: gopacket.DecodeFunc(decodeIPv6Fragment)})
|
||||||
|
LayerTypeIPv6Destination = gopacket.RegisterLayerType(49, gopacket.LayerTypeMetadata{Name: "IPv6Destination", Decoder: gopacket.DecodeFunc(decodeIPv6Destination)})
|
||||||
|
LayerTypeIPSecAH = gopacket.RegisterLayerType(50, gopacket.LayerTypeMetadata{Name: "IPSecAH", Decoder: gopacket.DecodeFunc(decodeIPSecAH)})
|
||||||
|
LayerTypeIPSecESP = gopacket.RegisterLayerType(51, gopacket.LayerTypeMetadata{Name: "IPSecESP", Decoder: gopacket.DecodeFunc(decodeIPSecESP)})
|
||||||
|
LayerTypeUDPLite = gopacket.RegisterLayerType(52, gopacket.LayerTypeMetadata{Name: "UDPLite", Decoder: gopacket.DecodeFunc(decodeUDPLite)})
|
||||||
|
LayerTypeFDDI = gopacket.RegisterLayerType(53, gopacket.LayerTypeMetadata{Name: "FDDI", Decoder: gopacket.DecodeFunc(decodeFDDI)})
|
||||||
|
LayerTypeLoopback = gopacket.RegisterLayerType(54, gopacket.LayerTypeMetadata{Name: "Loopback", Decoder: gopacket.DecodeFunc(decodeLoopback)})
|
||||||
|
LayerTypeEAP = gopacket.RegisterLayerType(55, gopacket.LayerTypeMetadata{Name: "EAP", Decoder: gopacket.DecodeFunc(decodeEAP)})
|
||||||
|
LayerTypeEAPOL = gopacket.RegisterLayerType(56, gopacket.LayerTypeMetadata{Name: "EAPOL", Decoder: gopacket.DecodeFunc(decodeEAPOL)})
|
||||||
|
LayerTypeICMPv6 = gopacket.RegisterLayerType(57, gopacket.LayerTypeMetadata{Name: "ICMPv6", Decoder: gopacket.DecodeFunc(decodeICMPv6)})
|
||||||
|
LayerTypeLinkLayerDiscovery = gopacket.RegisterLayerType(58, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscovery", Decoder: gopacket.DecodeFunc(decodeLinkLayerDiscovery)})
|
||||||
|
LayerTypeCiscoDiscoveryInfo = gopacket.RegisterLayerType(59, gopacket.LayerTypeMetadata{Name: "CiscoDiscoveryInfo", Decoder: gopacket.DecodeFunc(decodeCiscoDiscoveryInfo)})
|
||||||
|
LayerTypeLinkLayerDiscoveryInfo = gopacket.RegisterLayerType(60, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscoveryInfo", Decoder: nil})
|
||||||
|
LayerTypeNortelDiscovery = gopacket.RegisterLayerType(61, gopacket.LayerTypeMetadata{Name: "NortelDiscovery", Decoder: gopacket.DecodeFunc(decodeNortelDiscovery)})
|
||||||
|
LayerTypeIGMP = gopacket.RegisterLayerType(62, gopacket.LayerTypeMetadata{Name: "IGMP", Decoder: gopacket.DecodeFunc(decodeIGMP)})
|
||||||
|
LayerTypePFLog = gopacket.RegisterLayerType(63, gopacket.LayerTypeMetadata{Name: "PFLog", Decoder: gopacket.DecodeFunc(decodePFLog)})
|
||||||
|
LayerTypeRadioTap = gopacket.RegisterLayerType(64, gopacket.LayerTypeMetadata{Name: "RadioTap", Decoder: gopacket.DecodeFunc(decodeRadioTap)})
|
||||||
|
LayerTypeDot11 = gopacket.RegisterLayerType(65, gopacket.LayerTypeMetadata{Name: "Dot11", Decoder: gopacket.DecodeFunc(decodeDot11)})
|
||||||
|
LayerTypeDot11Ctrl = gopacket.RegisterLayerType(66, gopacket.LayerTypeMetadata{Name: "Dot11Ctrl", Decoder: gopacket.DecodeFunc(decodeDot11Ctrl)})
|
||||||
|
LayerTypeDot11Data = gopacket.RegisterLayerType(67, gopacket.LayerTypeMetadata{Name: "Dot11Data", Decoder: gopacket.DecodeFunc(decodeDot11Data)})
|
||||||
|
LayerTypeDot11DataCFAck = gopacket.RegisterLayerType(68, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)})
|
||||||
|
LayerTypeDot11DataCFPoll = gopacket.RegisterLayerType(69, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)})
|
||||||
|
LayerTypeDot11DataCFAckPoll = gopacket.RegisterLayerType(70, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)})
|
||||||
|
LayerTypeDot11DataNull = gopacket.RegisterLayerType(71, gopacket.LayerTypeMetadata{Name: "Dot11DataNull", Decoder: gopacket.DecodeFunc(decodeDot11DataNull)})
|
||||||
|
LayerTypeDot11DataCFAckNoData = gopacket.RegisterLayerType(72, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)})
|
||||||
|
LayerTypeDot11DataCFPollNoData = gopacket.RegisterLayerType(73, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)})
|
||||||
|
LayerTypeDot11DataCFAckPollNoData = gopacket.RegisterLayerType(74, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)})
|
||||||
|
LayerTypeDot11DataQOSData = gopacket.RegisterLayerType(75, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSData", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSData)})
|
||||||
|
LayerTypeDot11DataQOSDataCFAck = gopacket.RegisterLayerType(76, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck)})
|
||||||
|
LayerTypeDot11DataQOSDataCFPoll = gopacket.RegisterLayerType(77, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll)})
|
||||||
|
LayerTypeDot11DataQOSDataCFAckPoll = gopacket.RegisterLayerType(78, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll)})
|
||||||
|
LayerTypeDot11DataQOSNull = gopacket.RegisterLayerType(79, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSNull", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSNull)})
|
||||||
|
LayerTypeDot11DataQOSCFPollNoData = gopacket.RegisterLayerType(80, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData)})
|
||||||
|
LayerTypeDot11DataQOSCFAckPollNoData = gopacket.RegisterLayerType(81, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData)})
|
||||||
|
LayerTypeDot11InformationElement = gopacket.RegisterLayerType(82, gopacket.LayerTypeMetadata{Name: "Dot11InformationElement", Decoder: gopacket.DecodeFunc(decodeDot11InformationElement)})
|
||||||
|
LayerTypeDot11CtrlCTS = gopacket.RegisterLayerType(83, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCTS)})
|
||||||
|
LayerTypeDot11CtrlRTS = gopacket.RegisterLayerType(84, gopacket.LayerTypeMetadata{Name: "Dot11CtrlRTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlRTS)})
|
||||||
|
LayerTypeDot11CtrlBlockAckReq = gopacket.RegisterLayerType(85, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAckReq", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq)})
|
||||||
|
LayerTypeDot11CtrlBlockAck = gopacket.RegisterLayerType(86, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAck)})
|
||||||
|
LayerTypeDot11CtrlPowersavePoll = gopacket.RegisterLayerType(87, gopacket.LayerTypeMetadata{Name: "Dot11CtrlPowersavePoll", Decoder: gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll)})
|
||||||
|
LayerTypeDot11CtrlAck = gopacket.RegisterLayerType(88, gopacket.LayerTypeMetadata{Name: "Dot11CtrlAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlAck)})
|
||||||
|
LayerTypeDot11CtrlCFEnd = gopacket.RegisterLayerType(89, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEnd", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEnd)})
|
||||||
|
LayerTypeDot11CtrlCFEndAck = gopacket.RegisterLayerType(90, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEndAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEndAck)})
|
||||||
|
LayerTypeDot11MgmtAssociationReq = gopacket.RegisterLayerType(91, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationReq)})
|
||||||
|
LayerTypeDot11MgmtAssociationResp = gopacket.RegisterLayerType(92, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationResp)})
|
||||||
|
LayerTypeDot11MgmtReassociationReq = gopacket.RegisterLayerType(93, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationReq)})
|
||||||
|
LayerTypeDot11MgmtReassociationResp = gopacket.RegisterLayerType(94, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationResp)})
|
||||||
|
LayerTypeDot11MgmtProbeReq = gopacket.RegisterLayerType(95, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeReq)})
|
||||||
|
LayerTypeDot11MgmtProbeResp = gopacket.RegisterLayerType(96, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeResp)})
|
||||||
|
LayerTypeDot11MgmtMeasurementPilot = gopacket.RegisterLayerType(97, gopacket.LayerTypeMetadata{Name: "Dot11MgmtMeasurementPilot", Decoder: gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot)})
|
||||||
|
LayerTypeDot11MgmtBeacon = gopacket.RegisterLayerType(98, gopacket.LayerTypeMetadata{Name: "Dot11MgmtBeacon", Decoder: gopacket.DecodeFunc(decodeDot11MgmtBeacon)})
|
||||||
|
LayerTypeDot11MgmtATIM = gopacket.RegisterLayerType(99, gopacket.LayerTypeMetadata{Name: "Dot11MgmtATIM", Decoder: gopacket.DecodeFunc(decodeDot11MgmtATIM)})
|
||||||
|
LayerTypeDot11MgmtDisassociation = gopacket.RegisterLayerType(100, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDisassociation", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDisassociation)})
|
||||||
|
LayerTypeDot11MgmtAuthentication = gopacket.RegisterLayerType(101, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAuthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAuthentication)})
|
||||||
|
LayerTypeDot11MgmtDeauthentication = gopacket.RegisterLayerType(102, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDeauthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDeauthentication)})
|
||||||
|
LayerTypeDot11MgmtAction = gopacket.RegisterLayerType(103, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAction", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAction)})
|
||||||
|
LayerTypeDot11MgmtActionNoAck = gopacket.RegisterLayerType(104, gopacket.LayerTypeMetadata{Name: "Dot11MgmtActionNoAck", Decoder: gopacket.DecodeFunc(decodeDot11MgmtActionNoAck)})
|
||||||
|
LayerTypeDot11MgmtArubaWLAN = gopacket.RegisterLayerType(105, gopacket.LayerTypeMetadata{Name: "Dot11MgmtArubaWLAN", Decoder: gopacket.DecodeFunc(decodeDot11MgmtArubaWLAN)})
|
||||||
|
LayerTypeDot11WEP = gopacket.RegisterLayerType(106, gopacket.LayerTypeMetadata{Name: "Dot11WEP", Decoder: gopacket.DecodeFunc(decodeDot11WEP)})
|
||||||
|
LayerTypeDNS = gopacket.RegisterLayerType(107, gopacket.LayerTypeMetadata{Name: "DNS", Decoder: gopacket.DecodeFunc(decodeDNS)})
|
||||||
|
LayerTypeUSB = gopacket.RegisterLayerType(108, gopacket.LayerTypeMetadata{Name: "USB", Decoder: gopacket.DecodeFunc(decodeUSB)})
|
||||||
|
LayerTypeUSBRequestBlockSetup = gopacket.RegisterLayerType(109, gopacket.LayerTypeMetadata{Name: "USBRequestBlockSetup", Decoder: gopacket.DecodeFunc(decodeUSBRequestBlockSetup)})
|
||||||
|
LayerTypeUSBControl = gopacket.RegisterLayerType(110, gopacket.LayerTypeMetadata{Name: "USBControl", Decoder: gopacket.DecodeFunc(decodeUSBControl)})
|
||||||
|
LayerTypeUSBInterrupt = gopacket.RegisterLayerType(111, gopacket.LayerTypeMetadata{Name: "USBInterrupt", Decoder: gopacket.DecodeFunc(decodeUSBInterrupt)})
|
||||||
|
LayerTypeUSBBulk = gopacket.RegisterLayerType(112, gopacket.LayerTypeMetadata{Name: "USBBulk", Decoder: gopacket.DecodeFunc(decodeUSBBulk)})
|
||||||
|
LayerTypeLinuxSLL = gopacket.RegisterLayerType(113, gopacket.LayerTypeMetadata{Name: "Linux SLL", Decoder: gopacket.DecodeFunc(decodeLinuxSLL)})
|
||||||
|
LayerTypeSFlow = gopacket.RegisterLayerType(114, gopacket.LayerTypeMetadata{Name: "SFlow", Decoder: gopacket.DecodeFunc(decodeSFlow)})
|
||||||
|
LayerTypePrismHeader = gopacket.RegisterLayerType(115, gopacket.LayerTypeMetadata{Name: "Prism monitor mode header", Decoder: gopacket.DecodeFunc(decodePrismHeader)})
|
||||||
|
LayerTypeVXLAN = gopacket.RegisterLayerType(116, gopacket.LayerTypeMetadata{Name: "VXLAN", Decoder: gopacket.DecodeFunc(decodeVXLAN)})
|
||||||
|
LayerTypeNTP = gopacket.RegisterLayerType(117, gopacket.LayerTypeMetadata{Name: "NTP", Decoder: gopacket.DecodeFunc(decodeNTP)})
|
||||||
|
LayerTypeDHCPv4 = gopacket.RegisterLayerType(118, gopacket.LayerTypeMetadata{Name: "DHCPv4", Decoder: gopacket.DecodeFunc(decodeDHCPv4)})
|
||||||
|
LayerTypeVRRP = gopacket.RegisterLayerType(119, gopacket.LayerTypeMetadata{Name: "VRRP", Decoder: gopacket.DecodeFunc(decodeVRRP)})
|
||||||
|
LayerTypeGeneve = gopacket.RegisterLayerType(120, gopacket.LayerTypeMetadata{Name: "Geneve", Decoder: gopacket.DecodeFunc(decodeGeneve)})
|
||||||
|
LayerTypeSTP = gopacket.RegisterLayerType(121, gopacket.LayerTypeMetadata{Name: "STP", Decoder: gopacket.DecodeFunc(decodeSTP)})
|
||||||
|
LayerTypeBFD = gopacket.RegisterLayerType(122, gopacket.LayerTypeMetadata{Name: "BFD", Decoder: gopacket.DecodeFunc(decodeBFD)})
|
||||||
|
LayerTypeOSPF = gopacket.RegisterLayerType(123, gopacket.LayerTypeMetadata{Name: "OSPF", Decoder: gopacket.DecodeFunc(decodeOSPF)})
|
||||||
|
LayerTypeICMPv6RouterSolicitation = gopacket.RegisterLayerType(124, gopacket.LayerTypeMetadata{Name: "ICMPv6RouterSolicitation", Decoder: gopacket.DecodeFunc(decodeICMPv6RouterSolicitation)})
|
||||||
|
LayerTypeICMPv6RouterAdvertisement = gopacket.RegisterLayerType(125, gopacket.LayerTypeMetadata{Name: "ICMPv6RouterAdvertisement", Decoder: gopacket.DecodeFunc(decodeICMPv6RouterAdvertisement)})
|
||||||
|
LayerTypeICMPv6NeighborSolicitation = gopacket.RegisterLayerType(126, gopacket.LayerTypeMetadata{Name: "ICMPv6NeighborSolicitation", Decoder: gopacket.DecodeFunc(decodeICMPv6NeighborSolicitation)})
|
||||||
|
LayerTypeICMPv6NeighborAdvertisement = gopacket.RegisterLayerType(127, gopacket.LayerTypeMetadata{Name: "ICMPv6NeighborAdvertisement", Decoder: gopacket.DecodeFunc(decodeICMPv6NeighborAdvertisement)})
|
||||||
|
LayerTypeICMPv6Redirect = gopacket.RegisterLayerType(128, gopacket.LayerTypeMetadata{Name: "ICMPv6Redirect", Decoder: gopacket.DecodeFunc(decodeICMPv6Redirect)})
|
||||||
|
LayerTypeGTPv1U = gopacket.RegisterLayerType(129, gopacket.LayerTypeMetadata{Name: "GTPv1U", Decoder: gopacket.DecodeFunc(decodeGTPv1u)})
|
||||||
|
LayerTypeEAPOLKey = gopacket.RegisterLayerType(130, gopacket.LayerTypeMetadata{Name: "EAPOLKey", Decoder: gopacket.DecodeFunc(decodeEAPOLKey)})
|
||||||
|
LayerTypeLCM = gopacket.RegisterLayerType(131, gopacket.LayerTypeMetadata{Name: "LCM", Decoder: gopacket.DecodeFunc(decodeLCM)})
|
||||||
|
LayerTypeICMPv6Echo = gopacket.RegisterLayerType(132, gopacket.LayerTypeMetadata{Name: "ICMPv6Echo", Decoder: gopacket.DecodeFunc(decodeICMPv6Echo)})
|
||||||
|
LayerTypeSIP = gopacket.RegisterLayerType(133, gopacket.LayerTypeMetadata{Name: "SIP", Decoder: gopacket.DecodeFunc(decodeSIP)})
|
||||||
|
LayerTypeDHCPv6 = gopacket.RegisterLayerType(134, gopacket.LayerTypeMetadata{Name: "DHCPv6", Decoder: gopacket.DecodeFunc(decodeDHCPv6)})
|
||||||
|
LayerTypeMLDv1MulticastListenerReport = gopacket.RegisterLayerType(135, gopacket.LayerTypeMetadata{Name: "MLDv1MulticastListenerReport", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerReport)})
|
||||||
|
LayerTypeMLDv1MulticastListenerDone = gopacket.RegisterLayerType(136, gopacket.LayerTypeMetadata{Name: "MLDv1MulticastListenerDone", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerDone)})
|
||||||
|
LayerTypeMLDv1MulticastListenerQuery = gopacket.RegisterLayerType(137, gopacket.LayerTypeMetadata{Name: "MLDv1MulticastListenerQuery", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerQuery)})
|
||||||
|
LayerTypeMLDv2MulticastListenerReport = gopacket.RegisterLayerType(138, gopacket.LayerTypeMetadata{Name: "MLDv2MulticastListenerReport", Decoder: gopacket.DecodeFunc(decodeMLDv2MulticastListenerReport)})
|
||||||
|
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)})
|
||||||
|
LayerTypeERSPANII = gopacket.RegisterLayerType(145, gopacket.LayerTypeMetadata{Name: "ERSPAN Type II", Decoder: gopacket.DecodeFunc(decodeERSPANII)})
|
||||||
|
LayerTypeRADIUS = gopacket.RegisterLayerType(146, gopacket.LayerTypeMetadata{Name: "RADIUS", Decoder: gopacket.DecodeFunc(decodeRADIUS)})
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// LayerClassIPNetwork contains TCP/IP network layer types.
|
||||||
|
LayerClassIPNetwork = gopacket.NewLayerClass([]gopacket.LayerType{
|
||||||
|
LayerTypeIPv4,
|
||||||
|
LayerTypeIPv6,
|
||||||
|
})
|
||||||
|
// LayerClassIPTransport contains TCP/IP transport layer types.
|
||||||
|
LayerClassIPTransport = gopacket.NewLayerClass([]gopacket.LayerType{
|
||||||
|
LayerTypeTCP,
|
||||||
|
LayerTypeUDP,
|
||||||
|
LayerTypeSCTP,
|
||||||
|
})
|
||||||
|
// LayerClassIPControl contains TCP/IP control protocols.
|
||||||
|
LayerClassIPControl = gopacket.NewLayerClass([]gopacket.LayerType{
|
||||||
|
LayerTypeICMPv4,
|
||||||
|
LayerTypeICMPv6,
|
||||||
|
})
|
||||||
|
// LayerClassSCTPChunk contains SCTP chunk types (not the top-level SCTP
|
||||||
|
// layer).
|
||||||
|
LayerClassSCTPChunk = gopacket.NewLayerClass([]gopacket.LayerType{
|
||||||
|
LayerTypeSCTPUnknownChunkType,
|
||||||
|
LayerTypeSCTPData,
|
||||||
|
LayerTypeSCTPInit,
|
||||||
|
LayerTypeSCTPSack,
|
||||||
|
LayerTypeSCTPHeartbeat,
|
||||||
|
LayerTypeSCTPError,
|
||||||
|
LayerTypeSCTPShutdown,
|
||||||
|
LayerTypeSCTPShutdownAck,
|
||||||
|
LayerTypeSCTPCookieEcho,
|
||||||
|
LayerTypeSCTPEmptyLayer,
|
||||||
|
LayerTypeSCTPInitAck,
|
||||||
|
LayerTypeSCTPHeartbeatAck,
|
||||||
|
LayerTypeSCTPAbort,
|
||||||
|
LayerTypeSCTPShutdownComplete,
|
||||||
|
LayerTypeSCTPCookieAck,
|
||||||
|
})
|
||||||
|
// LayerClassIPv6Extension contains IPv6 extension headers.
|
||||||
|
LayerClassIPv6Extension = gopacket.NewLayerClass([]gopacket.LayerType{
|
||||||
|
LayerTypeIPv6HopByHop,
|
||||||
|
LayerTypeIPv6Routing,
|
||||||
|
LayerTypeIPv6Fragment,
|
||||||
|
LayerTypeIPv6Destination,
|
||||||
|
})
|
||||||
|
LayerClassIPSec = gopacket.NewLayerClass([]gopacket.LayerType{
|
||||||
|
LayerTypeIPSecAH,
|
||||||
|
LayerTypeIPSecESP,
|
||||||
|
})
|
||||||
|
// LayerClassICMPv6NDP contains ICMPv6 neighbor discovery protocol
|
||||||
|
// messages.
|
||||||
|
LayerClassICMPv6NDP = gopacket.NewLayerClass([]gopacket.LayerType{
|
||||||
|
LayerTypeICMPv6RouterSolicitation,
|
||||||
|
LayerTypeICMPv6RouterAdvertisement,
|
||||||
|
LayerTypeICMPv6NeighborSolicitation,
|
||||||
|
LayerTypeICMPv6NeighborAdvertisement,
|
||||||
|
LayerTypeICMPv6Redirect,
|
||||||
|
})
|
||||||
|
// LayerClassMLDv1 contains multicast listener discovery protocol
|
||||||
|
LayerClassMLDv1 = gopacket.NewLayerClass([]gopacket.LayerType{
|
||||||
|
LayerTypeMLDv1MulticastListenerQuery,
|
||||||
|
LayerTypeMLDv1MulticastListenerReport,
|
||||||
|
LayerTypeMLDv1MulticastListenerDone,
|
||||||
|
})
|
||||||
|
// LayerClassMLDv2 contains multicast listener discovery protocol v2
|
||||||
|
LayerClassMLDv2 = gopacket.NewLayerClass([]gopacket.LayerType{
|
||||||
|
LayerTypeMLDv1MulticastListenerReport,
|
||||||
|
LayerTypeMLDv1MulticastListenerDone,
|
||||||
|
LayerTypeMLDv2MulticastListenerReport,
|
||||||
|
LayerTypeMLDv1MulticastListenerQuery,
|
||||||
|
LayerTypeMLDv2MulticastListenerQuery,
|
||||||
|
})
|
||||||
|
)
|
218
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/lcm.go
generated
vendored
Normal file
218
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/lcm.go
generated
vendored
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
// Copyright 2018 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// LCMShortHeaderMagic is the LCM small message header magic number
|
||||||
|
LCMShortHeaderMagic uint32 = 0x4c433032
|
||||||
|
// LCMFragmentedHeaderMagic is the LCM fragmented message header magic number
|
||||||
|
LCMFragmentedHeaderMagic uint32 = 0x4c433033
|
||||||
|
)
|
||||||
|
|
||||||
|
// LCM (Lightweight Communications and Marshalling) is a set of libraries and
|
||||||
|
// tools for message passing and data marshalling, targeted at real-time systems
|
||||||
|
// where high-bandwidth and low latency are critical. It provides a
|
||||||
|
// publish/subscribe message passing model and automatic
|
||||||
|
// marshalling/unmarshalling code generation with bindings for applications in a
|
||||||
|
// variety of programming languages.
|
||||||
|
//
|
||||||
|
// References
|
||||||
|
// https://lcm-proj.github.io/
|
||||||
|
// https://github.com/lcm-proj/lcm
|
||||||
|
type LCM struct {
|
||||||
|
// Common (short & fragmented header) fields
|
||||||
|
Magic uint32
|
||||||
|
SequenceNumber uint32
|
||||||
|
// Fragmented header only fields
|
||||||
|
PayloadSize uint32
|
||||||
|
FragmentOffset uint32
|
||||||
|
FragmentNumber uint16
|
||||||
|
TotalFragments uint16
|
||||||
|
// Common field
|
||||||
|
ChannelName string
|
||||||
|
// Gopacket helper fields
|
||||||
|
Fragmented bool
|
||||||
|
fingerprint LCMFingerprint
|
||||||
|
contents []byte
|
||||||
|
payload []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LCMFingerprint is the type of a LCM fingerprint.
|
||||||
|
type LCMFingerprint uint64
|
||||||
|
|
||||||
|
var (
|
||||||
|
// lcmLayerTypes contains a map of all LCM fingerprints that we support and
|
||||||
|
// their LayerType
|
||||||
|
lcmLayerTypes = map[LCMFingerprint]gopacket.LayerType{}
|
||||||
|
layerTypeIndex = 1001
|
||||||
|
)
|
||||||
|
|
||||||
|
// RegisterLCMLayerType allows users to register decoders for the underlying
|
||||||
|
// LCM payload. This is done based on the fingerprint that every LCM message
|
||||||
|
// contains and which identifies it uniquely. If num is not the zero value it
|
||||||
|
// will be used when registering with RegisterLayerType towards gopacket,
|
||||||
|
// otherwise an incremental value starting from 1001 will be used.
|
||||||
|
func RegisterLCMLayerType(num int, name string, fingerprint LCMFingerprint,
|
||||||
|
decoder gopacket.Decoder) gopacket.LayerType {
|
||||||
|
metadata := gopacket.LayerTypeMetadata{Name: name, Decoder: decoder}
|
||||||
|
|
||||||
|
if num == 0 {
|
||||||
|
num = layerTypeIndex
|
||||||
|
layerTypeIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
lcmLayerTypes[fingerprint] = gopacket.RegisterLayerType(num, metadata)
|
||||||
|
|
||||||
|
return lcmLayerTypes[fingerprint]
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupportedLCMFingerprints returns a slice of all LCM fingerprints that has
|
||||||
|
// been registered so far.
|
||||||
|
func SupportedLCMFingerprints() []LCMFingerprint {
|
||||||
|
fingerprints := make([]LCMFingerprint, 0, len(lcmLayerTypes))
|
||||||
|
for fp := range lcmLayerTypes {
|
||||||
|
fingerprints = append(fingerprints, fp)
|
||||||
|
}
|
||||||
|
return fingerprints
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLCMLayerType returns the underlying LCM message's LayerType.
|
||||||
|
// This LayerType has to be registered by using RegisterLCMLayerType.
|
||||||
|
func GetLCMLayerType(fingerprint LCMFingerprint) gopacket.LayerType {
|
||||||
|
layerType, ok := lcmLayerTypes[fingerprint]
|
||||||
|
if !ok {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
return layerType
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeLCM(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
lcm := &LCM{}
|
||||||
|
|
||||||
|
err := lcm.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
p.AddLayer(lcm)
|
||||||
|
p.SetApplicationLayer(lcm)
|
||||||
|
|
||||||
|
return p.NextDecoder(lcm.NextLayerType())
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (lcm *LCM) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 8 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("LCM < 8 bytes")
|
||||||
|
}
|
||||||
|
offset := 0
|
||||||
|
|
||||||
|
lcm.Magic = binary.BigEndian.Uint32(data[offset:4])
|
||||||
|
offset += 4
|
||||||
|
|
||||||
|
if lcm.Magic != LCMShortHeaderMagic && lcm.Magic != LCMFragmentedHeaderMagic {
|
||||||
|
return fmt.Errorf("Received LCM header magic %v does not match know "+
|
||||||
|
"LCM magic numbers. Dropping packet.", lcm.Magic)
|
||||||
|
}
|
||||||
|
|
||||||
|
lcm.SequenceNumber = binary.BigEndian.Uint32(data[offset:8])
|
||||||
|
offset += 4
|
||||||
|
|
||||||
|
if lcm.Magic == LCMFragmentedHeaderMagic {
|
||||||
|
lcm.Fragmented = true
|
||||||
|
|
||||||
|
lcm.PayloadSize = binary.BigEndian.Uint32(data[offset : offset+4])
|
||||||
|
offset += 4
|
||||||
|
|
||||||
|
lcm.FragmentOffset = binary.BigEndian.Uint32(data[offset : offset+4])
|
||||||
|
offset += 4
|
||||||
|
|
||||||
|
lcm.FragmentNumber = binary.BigEndian.Uint16(data[offset : offset+2])
|
||||||
|
offset += 2
|
||||||
|
|
||||||
|
lcm.TotalFragments = binary.BigEndian.Uint16(data[offset : offset+2])
|
||||||
|
offset += 2
|
||||||
|
} else {
|
||||||
|
lcm.Fragmented = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !lcm.Fragmented || (lcm.Fragmented && lcm.FragmentNumber == 0) {
|
||||||
|
buffer := make([]byte, 0)
|
||||||
|
for _, b := range data[offset:] {
|
||||||
|
offset++
|
||||||
|
|
||||||
|
if b == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = append(buffer, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
lcm.ChannelName = string(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
lcm.fingerprint = LCMFingerprint(
|
||||||
|
binary.BigEndian.Uint64(data[offset : offset+8]))
|
||||||
|
|
||||||
|
lcm.contents = data[:offset]
|
||||||
|
lcm.payload = data[offset:]
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns a set of layers that LCM objects can decode.
|
||||||
|
// As LCM objects can only decode the LCM layer, we just return that layer.
|
||||||
|
func (lcm LCM) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeLCM
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType specifies the LCM payload layer type following this header.
|
||||||
|
// As LCM packets are serialized structs with uniq fingerprints for each uniq
|
||||||
|
// combination of data types, lookup of correct layer type is based on that
|
||||||
|
// fingerprint.
|
||||||
|
func (lcm LCM) NextLayerType() gopacket.LayerType {
|
||||||
|
if !lcm.Fragmented || (lcm.Fragmented && lcm.FragmentNumber == 0) {
|
||||||
|
return GetLCMLayerType(lcm.fingerprint)
|
||||||
|
}
|
||||||
|
|
||||||
|
return gopacket.LayerTypeFragment
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeLCM
|
||||||
|
func (lcm LCM) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeLCM
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerContents returns the contents of the LCM header.
|
||||||
|
func (lcm LCM) LayerContents() []byte {
|
||||||
|
return lcm.contents
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerPayload returns the payload following this LCM header.
|
||||||
|
func (lcm LCM) LayerPayload() []byte {
|
||||||
|
return lcm.payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payload returns the payload following this LCM header.
|
||||||
|
func (lcm LCM) Payload() []byte {
|
||||||
|
return lcm.LayerPayload()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fingerprint returns the LCM fingerprint of the underlying message.
|
||||||
|
func (lcm LCM) Fingerprint() LCMFingerprint {
|
||||||
|
return lcm.fingerprint
|
||||||
|
}
|
98
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/linux_sll.go
generated
vendored
Normal file
98
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/linux_sll.go
generated
vendored
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LinuxSLLPacketType uint16
|
||||||
|
|
||||||
|
const (
|
||||||
|
LinuxSLLPacketTypeHost LinuxSLLPacketType = 0 // To us
|
||||||
|
LinuxSLLPacketTypeBroadcast LinuxSLLPacketType = 1 // To all
|
||||||
|
LinuxSLLPacketTypeMulticast LinuxSLLPacketType = 2 // To group
|
||||||
|
LinuxSLLPacketTypeOtherhost LinuxSLLPacketType = 3 // To someone else
|
||||||
|
LinuxSLLPacketTypeOutgoing LinuxSLLPacketType = 4 // Outgoing of any type
|
||||||
|
// These ones are invisible by user level
|
||||||
|
LinuxSLLPacketTypeLoopback LinuxSLLPacketType = 5 // MC/BRD frame looped back
|
||||||
|
LinuxSLLPacketTypeFastroute LinuxSLLPacketType = 6 // Fastrouted frame
|
||||||
|
)
|
||||||
|
|
||||||
|
func (l LinuxSLLPacketType) String() string {
|
||||||
|
switch l {
|
||||||
|
case LinuxSLLPacketTypeHost:
|
||||||
|
return "host"
|
||||||
|
case LinuxSLLPacketTypeBroadcast:
|
||||||
|
return "broadcast"
|
||||||
|
case LinuxSLLPacketTypeMulticast:
|
||||||
|
return "multicast"
|
||||||
|
case LinuxSLLPacketTypeOtherhost:
|
||||||
|
return "otherhost"
|
||||||
|
case LinuxSLLPacketTypeOutgoing:
|
||||||
|
return "outgoing"
|
||||||
|
case LinuxSLLPacketTypeLoopback:
|
||||||
|
return "loopback"
|
||||||
|
case LinuxSLLPacketTypeFastroute:
|
||||||
|
return "fastroute"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Unknown(%d)", int(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
type LinuxSLL struct {
|
||||||
|
BaseLayer
|
||||||
|
PacketType LinuxSLLPacketType
|
||||||
|
AddrLen uint16
|
||||||
|
Addr net.HardwareAddr
|
||||||
|
EthernetType EthernetType
|
||||||
|
AddrType uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeLinuxSLL.
|
||||||
|
func (sll *LinuxSLL) LayerType() gopacket.LayerType { return LayerTypeLinuxSLL }
|
||||||
|
|
||||||
|
func (sll *LinuxSLL) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeLinuxSLL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sll *LinuxSLL) LinkFlow() gopacket.Flow {
|
||||||
|
return gopacket.NewFlow(EndpointMAC, sll.Addr, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sll *LinuxSLL) NextLayerType() gopacket.LayerType {
|
||||||
|
return sll.EthernetType.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sll *LinuxSLL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 16 {
|
||||||
|
return errors.New("Linux SLL packet too small")
|
||||||
|
}
|
||||||
|
sll.PacketType = LinuxSLLPacketType(binary.BigEndian.Uint16(data[0:2]))
|
||||||
|
sll.AddrType = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
sll.AddrLen = binary.BigEndian.Uint16(data[4:6])
|
||||||
|
|
||||||
|
sll.Addr = net.HardwareAddr(data[6 : sll.AddrLen+6])
|
||||||
|
sll.EthernetType = EthernetType(binary.BigEndian.Uint16(data[14:16]))
|
||||||
|
sll.BaseLayer = BaseLayer{data[:16], data[16:]}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeLinuxSLL(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
sll := &LinuxSLL{}
|
||||||
|
if err := sll.DecodeFromBytes(data, p); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(sll)
|
||||||
|
p.SetLinkLayer(sll)
|
||||||
|
return p.NextDecoder(sll.EthernetType)
|
||||||
|
}
|
193
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/llc.go
generated
vendored
Normal file
193
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/llc.go
generated
vendored
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LLC is the layer used for 802.2 Logical Link Control headers.
|
||||||
|
// See http://standards.ieee.org/getieee802/download/802.2-1998.pdf
|
||||||
|
type LLC struct {
|
||||||
|
BaseLayer
|
||||||
|
DSAP uint8
|
||||||
|
IG bool // true means group, false means individual
|
||||||
|
SSAP uint8
|
||||||
|
CR bool // true means response, false means command
|
||||||
|
Control uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeLLC.
|
||||||
|
func (l *LLC) LayerType() gopacket.LayerType { return LayerTypeLLC }
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (l *LLC) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 3 {
|
||||||
|
return errors.New("LLC header too small")
|
||||||
|
}
|
||||||
|
l.DSAP = data[0] & 0xFE
|
||||||
|
l.IG = data[0]&0x1 != 0
|
||||||
|
l.SSAP = data[1] & 0xFE
|
||||||
|
l.CR = data[1]&0x1 != 0
|
||||||
|
l.Control = uint16(data[2])
|
||||||
|
|
||||||
|
if l.Control&0x1 == 0 || l.Control&0x3 == 0x1 {
|
||||||
|
if len(data) < 4 {
|
||||||
|
return errors.New("LLC header too small")
|
||||||
|
}
|
||||||
|
l.Control = l.Control<<8 | uint16(data[3])
|
||||||
|
l.Contents = data[:4]
|
||||||
|
l.Payload = data[4:]
|
||||||
|
} else {
|
||||||
|
l.Contents = data[:3]
|
||||||
|
l.Payload = data[3:]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (l *LLC) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeLLC
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (l *LLC) NextLayerType() gopacket.LayerType {
|
||||||
|
switch {
|
||||||
|
case l.DSAP == 0xAA && l.SSAP == 0xAA:
|
||||||
|
return LayerTypeSNAP
|
||||||
|
case l.DSAP == 0x42 && l.SSAP == 0x42:
|
||||||
|
return LayerTypeSTP
|
||||||
|
}
|
||||||
|
return gopacket.LayerTypeZero // Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// SNAP is used inside LLC. See
|
||||||
|
// http://standards.ieee.org/getieee802/download/802-2001.pdf.
|
||||||
|
// From http://en.wikipedia.org/wiki/Subnetwork_Access_Protocol:
|
||||||
|
// "[T]he Subnetwork Access Protocol (SNAP) is a mechanism for multiplexing,
|
||||||
|
// on networks using IEEE 802.2 LLC, more protocols than can be distinguished
|
||||||
|
// by the 8-bit 802.2 Service Access Point (SAP) fields."
|
||||||
|
type SNAP struct {
|
||||||
|
BaseLayer
|
||||||
|
OrganizationalCode []byte
|
||||||
|
Type EthernetType
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeSNAP.
|
||||||
|
func (s *SNAP) LayerType() gopacket.LayerType { return LayerTypeSNAP }
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (s *SNAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 5 {
|
||||||
|
return errors.New("SNAP header too small")
|
||||||
|
}
|
||||||
|
s.OrganizationalCode = data[:3]
|
||||||
|
s.Type = EthernetType(binary.BigEndian.Uint16(data[3:5]))
|
||||||
|
s.BaseLayer = BaseLayer{data[:5], data[5:]}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (s *SNAP) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeSNAP
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (s *SNAP) NextLayerType() gopacket.LayerType {
|
||||||
|
// See BUG(gconnel) in decodeSNAP
|
||||||
|
return s.Type.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeLLC(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
l := &LLC{}
|
||||||
|
err := l.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(l)
|
||||||
|
return p.NextDecoder(l.NextLayerType())
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSNAP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
s := &SNAP{}
|
||||||
|
err := s.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(s)
|
||||||
|
// BUG(gconnell): When decoding SNAP, we treat the SNAP type as an Ethernet
|
||||||
|
// type. This may not actually be an ethernet type in all cases,
|
||||||
|
// depending on the organizational code. Right now, we don't check.
|
||||||
|
return p.NextDecoder(s.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
var igFlag, crFlag byte
|
||||||
|
var length int
|
||||||
|
|
||||||
|
if l.Control&0xFF00 != 0 {
|
||||||
|
length = 4
|
||||||
|
} else {
|
||||||
|
length = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
if l.DSAP&0x1 != 0 {
|
||||||
|
return errors.New("DSAP value invalid, should not include IG flag bit")
|
||||||
|
}
|
||||||
|
|
||||||
|
if l.SSAP&0x1 != 0 {
|
||||||
|
return errors.New("SSAP value invalid, should not include CR flag bit")
|
||||||
|
}
|
||||||
|
|
||||||
|
if buf, err := b.PrependBytes(length); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
igFlag = 0
|
||||||
|
if l.IG {
|
||||||
|
igFlag = 0x1
|
||||||
|
}
|
||||||
|
|
||||||
|
crFlag = 0
|
||||||
|
if l.CR {
|
||||||
|
crFlag = 0x1
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = l.DSAP + igFlag
|
||||||
|
buf[1] = l.SSAP + crFlag
|
||||||
|
|
||||||
|
if length == 4 {
|
||||||
|
buf[2] = uint8(l.Control >> 8)
|
||||||
|
buf[3] = uint8(l.Control)
|
||||||
|
} else {
|
||||||
|
buf[2] = uint8(l.Control)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (s *SNAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if buf, err := b.PrependBytes(5); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
buf[0] = s.OrganizationalCode[0]
|
||||||
|
buf[1] = s.OrganizationalCode[1]
|
||||||
|
buf[2] = s.OrganizationalCode[2]
|
||||||
|
binary.BigEndian.PutUint16(buf[3:5], uint16(s.Type))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
1603
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/lldp.go
generated
vendored
Normal file
1603
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/lldp.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
80
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/loopback.go
generated
vendored
Normal file
80
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/loopback.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Loopback contains the header for loopback encapsulation. This header is
|
||||||
|
// used by both BSD and OpenBSD style loopback decoding (pcap's DLT_NULL
|
||||||
|
// and DLT_LOOP, respectively).
|
||||||
|
type Loopback struct {
|
||||||
|
BaseLayer
|
||||||
|
Family ProtocolFamily
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeLoopback.
|
||||||
|
func (l *Loopback) LayerType() gopacket.LayerType { return LayerTypeLoopback }
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (l *Loopback) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 4 {
|
||||||
|
return errors.New("Loopback packet too small")
|
||||||
|
}
|
||||||
|
|
||||||
|
// The protocol could be either big-endian or little-endian, we're
|
||||||
|
// not sure. But we're PRETTY sure that the value is less than
|
||||||
|
// 256, so we can check the first two bytes.
|
||||||
|
var prot uint32
|
||||||
|
if data[0] == 0 && data[1] == 0 {
|
||||||
|
prot = binary.BigEndian.Uint32(data[:4])
|
||||||
|
} else {
|
||||||
|
prot = binary.LittleEndian.Uint32(data[:4])
|
||||||
|
}
|
||||||
|
if prot > 0xFF {
|
||||||
|
return fmt.Errorf("Invalid loopback protocol %q", data[:4])
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Family = ProtocolFamily(prot)
|
||||||
|
l.BaseLayer = BaseLayer{data[:4], data[4:]}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (l *Loopback) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeLoopback
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (l *Loopback) NextLayerType() gopacket.LayerType {
|
||||||
|
return l.Family.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
func (l *Loopback) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
binary.LittleEndian.PutUint32(bytes, uint32(l.Family))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeLoopback(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
l := Loopback{}
|
||||||
|
if err := l.DecodeFromBytes(data, gopacket.NilDecodeFeedback); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(&l)
|
||||||
|
return p.NextDecoder(l.Family)
|
||||||
|
}
|
182
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/mldv1.go
generated
vendored
Normal file
182
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/mldv1.go
generated
vendored
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
// Copyright 2018 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MLDv1Message represents the common structure of all MLDv1 messages
|
||||||
|
type MLDv1Message struct {
|
||||||
|
BaseLayer
|
||||||
|
// 3.4. Maximum Response Delay
|
||||||
|
MaximumResponseDelay time.Duration
|
||||||
|
// 3.6. Multicast Address
|
||||||
|
// Zero in general query
|
||||||
|
// Specific IPv6 multicast address otherwise
|
||||||
|
MulticastAddress net.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (m *MLDv1Message) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 20 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less than 20 bytes for Multicast Listener Query Message V1")
|
||||||
|
}
|
||||||
|
|
||||||
|
m.MaximumResponseDelay = time.Duration(binary.BigEndian.Uint16(data[0:2])) * time.Millisecond
|
||||||
|
// data[2:4] is reserved and not used in mldv1
|
||||||
|
m.MulticastAddress = data[4:20]
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (*MLDv1Message) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (m *MLDv1Message) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
buf, err := b.PrependBytes(20)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.MaximumResponseDelay < 0 {
|
||||||
|
return errors.New("maximum response delay must not be negative")
|
||||||
|
}
|
||||||
|
dms := m.MaximumResponseDelay / time.Millisecond
|
||||||
|
if dms > math.MaxUint16 {
|
||||||
|
return fmt.Errorf("maximum response delay %dms is more than the allowed 65535ms", dms)
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(buf[0:2], uint16(dms))
|
||||||
|
|
||||||
|
copy(buf[2:4], []byte{0x0, 0x0})
|
||||||
|
|
||||||
|
ma16 := m.MulticastAddress.To16()
|
||||||
|
if ma16 == nil {
|
||||||
|
return fmt.Errorf("invalid multicast address '%s'", m.MulticastAddress)
|
||||||
|
}
|
||||||
|
copy(buf[4:20], ma16)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sums this layer up nicely formatted
|
||||||
|
func (m *MLDv1Message) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"Maximum Response Delay: %dms, Multicast Address: %s",
|
||||||
|
m.MaximumResponseDelay/time.Millisecond,
|
||||||
|
m.MulticastAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MLDv1MulticastListenerQueryMessage are sent by the router to determine
|
||||||
|
// whether there are multicast listeners on the link.
|
||||||
|
// https://tools.ietf.org/html/rfc2710 Page 5
|
||||||
|
type MLDv1MulticastListenerQueryMessage struct {
|
||||||
|
MLDv1Message
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (m *MLDv1MulticastListenerQueryMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
err := m.MLDv1Message.DecodeFromBytes(data, df)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) > 20 {
|
||||||
|
m.Payload = data[20:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeMLDv1MulticastListenerQuery.
|
||||||
|
func (*MLDv1MulticastListenerQueryMessage) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeMLDv1MulticastListenerQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (*MLDv1MulticastListenerQueryMessage) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeMLDv1MulticastListenerQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsGeneralQuery is true when this is a general query.
|
||||||
|
// In a Query message, the Multicast Address field is set to zero when
|
||||||
|
// sending a General Query.
|
||||||
|
// https://tools.ietf.org/html/rfc2710#section-3.6
|
||||||
|
func (m *MLDv1MulticastListenerQueryMessage) IsGeneralQuery() bool {
|
||||||
|
return net.IPv6zero.Equal(m.MulticastAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSpecificQuery is true when this is not a general query.
|
||||||
|
// In a Query message, the Multicast Address field is set to a specific
|
||||||
|
// IPv6 multicast address when sending a Multicast-Address-Specific Query.
|
||||||
|
// https://tools.ietf.org/html/rfc2710#section-3.6
|
||||||
|
func (m *MLDv1MulticastListenerQueryMessage) IsSpecificQuery() bool {
|
||||||
|
return !m.IsGeneralQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MLDv1MulticastListenerReportMessage is sent by a client listening on
|
||||||
|
// a specific multicast address to indicate that it is (still) listening
|
||||||
|
// on the specific multicast address.
|
||||||
|
// https://tools.ietf.org/html/rfc2710 Page 6
|
||||||
|
type MLDv1MulticastListenerReportMessage struct {
|
||||||
|
MLDv1Message
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeMLDv1MulticastListenerReport.
|
||||||
|
func (*MLDv1MulticastListenerReportMessage) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeMLDv1MulticastListenerReport
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (*MLDv1MulticastListenerReportMessage) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeMLDv1MulticastListenerReport
|
||||||
|
}
|
||||||
|
|
||||||
|
// MLDv1MulticastListenerDoneMessage should be sent by a client when it ceases
|
||||||
|
// to listen to a multicast address on an interface.
|
||||||
|
// https://tools.ietf.org/html/rfc2710 Page 7
|
||||||
|
type MLDv1MulticastListenerDoneMessage struct {
|
||||||
|
MLDv1Message
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeMLDv1MulticastListenerDone.
|
||||||
|
func (*MLDv1MulticastListenerDoneMessage) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeMLDv1MulticastListenerDone
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (*MLDv1MulticastListenerDoneMessage) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeMLDv1MulticastListenerDone
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeMLDv1MulticastListenerReport(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
m := &MLDv1MulticastListenerReportMessage{}
|
||||||
|
return decodingLayerDecoder(m, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeMLDv1MulticastListenerQuery(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
m := &MLDv1MulticastListenerQueryMessage{}
|
||||||
|
return decodingLayerDecoder(m, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeMLDv1MulticastListenerDone(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
m := &MLDv1MulticastListenerDoneMessage{}
|
||||||
|
return decodingLayerDecoder(m, data, p)
|
||||||
|
}
|
619
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/mldv2.go
generated
vendored
Normal file
619
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/mldv2.go
generated
vendored
Normal file
|
@ -0,0 +1,619 @@
|
||||||
|
// Copyright 2018 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// S Flag bit is 1
|
||||||
|
mldv2STrue uint8 = 0x8
|
||||||
|
|
||||||
|
// S Flag value mask
|
||||||
|
// mldv2STrue & mldv2SMask == mldv2STrue // true
|
||||||
|
// 0x1 & mldv2SMask == mldv2STrue // true
|
||||||
|
// 0x0 & mldv2SMask == mldv2STrue // false
|
||||||
|
mldv2SMask uint8 = 0x8
|
||||||
|
|
||||||
|
// QRV value mask
|
||||||
|
mldv2QRVMask uint8 = 0x7
|
||||||
|
)
|
||||||
|
|
||||||
|
// MLDv2MulticastListenerQueryMessage are sent by multicast routers to query the
|
||||||
|
// multicast listening state of neighboring interfaces.
|
||||||
|
// https://tools.ietf.org/html/rfc3810#section-5.1
|
||||||
|
//
|
||||||
|
// Some information, like Maximum Response Code and Multicast Address are in the
|
||||||
|
// previous layer LayerTypeMLDv1MulticastListenerQuery
|
||||||
|
type MLDv2MulticastListenerQueryMessage struct {
|
||||||
|
BaseLayer
|
||||||
|
// 5.1.3. Maximum Response Delay COde
|
||||||
|
MaximumResponseCode uint16
|
||||||
|
// 5.1.5. Multicast Address
|
||||||
|
// Zero in general query
|
||||||
|
// Specific IPv6 multicast address otherwise
|
||||||
|
MulticastAddress net.IP
|
||||||
|
// 5.1.7. S Flag (Suppress Router-Side Processing)
|
||||||
|
SuppressRoutersideProcessing bool
|
||||||
|
// 5.1.8. QRV (Querier's Robustness Variable)
|
||||||
|
QueriersRobustnessVariable uint8
|
||||||
|
// 5.1.9. QQIC (Querier's Query Interval Code)
|
||||||
|
QueriersQueryIntervalCode uint8
|
||||||
|
// 5.1.10. Number of Sources (N)
|
||||||
|
NumberOfSources uint16
|
||||||
|
// 5.1.11 Source Address [i]
|
||||||
|
SourceAddresses []net.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (m *MLDv2MulticastListenerQueryMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 24 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less than 24 bytes for Multicast Listener Query Message V2")
|
||||||
|
}
|
||||||
|
|
||||||
|
m.MaximumResponseCode = binary.BigEndian.Uint16(data[0:2])
|
||||||
|
// ignore data[2:4] as per https://tools.ietf.org/html/rfc3810#section-5.1.4
|
||||||
|
m.MulticastAddress = data[4:20]
|
||||||
|
m.SuppressRoutersideProcessing = (data[20] & mldv2SMask) == mldv2STrue
|
||||||
|
m.QueriersRobustnessVariable = data[20] & mldv2QRVMask
|
||||||
|
m.QueriersQueryIntervalCode = data[21]
|
||||||
|
|
||||||
|
m.NumberOfSources = binary.BigEndian.Uint16(data[22:24])
|
||||||
|
|
||||||
|
var end int
|
||||||
|
for i := uint16(0); i < m.NumberOfSources; i++ {
|
||||||
|
begin := 24 + (int(i) * 16)
|
||||||
|
end = begin + 16
|
||||||
|
|
||||||
|
if end > len(data) {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("ICMP layer less than %d bytes for Multicast Listener Query Message V2", end)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.SourceAddresses = append(m.SourceAddresses, data[begin:end])
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (*MLDv2MulticastListenerQueryMessage) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (m *MLDv2MulticastListenerQueryMessage) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if err := m.serializeSourceAddressesTo(b, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(24)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint16(buf[0:2], m.MaximumResponseCode)
|
||||||
|
copy(buf[2:4], []byte{0x00, 0x00}) // set reserved bytes to zero
|
||||||
|
|
||||||
|
ma16 := m.MulticastAddress.To16()
|
||||||
|
if ma16 == nil {
|
||||||
|
return fmt.Errorf("invalid MulticastAddress '%s'", m.MulticastAddress)
|
||||||
|
}
|
||||||
|
copy(buf[4:20], ma16)
|
||||||
|
|
||||||
|
byte20 := m.QueriersRobustnessVariable & mldv2QRVMask
|
||||||
|
if m.SuppressRoutersideProcessing {
|
||||||
|
byte20 |= mldv2STrue
|
||||||
|
} else {
|
||||||
|
byte20 &= ^mldv2STrue // the complement of mldv2STrue
|
||||||
|
}
|
||||||
|
byte20 &= 0x0F // set reserved bits to zero
|
||||||
|
buf[20] = byte20
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint16(buf[22:24], m.NumberOfSources)
|
||||||
|
buf[21] = m.QueriersQueryIntervalCode
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// writes each source address to the buffer preserving the order
|
||||||
|
func (m *MLDv2MulticastListenerQueryMessage) serializeSourceAddressesTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
numberOfSourceAddresses := len(m.SourceAddresses)
|
||||||
|
if numberOfSourceAddresses > math.MaxUint16 {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"there are more than %d source addresses, but 65535 is the maximum number of supported addresses",
|
||||||
|
numberOfSourceAddresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.FixLengths {
|
||||||
|
m.NumberOfSources = uint16(numberOfSourceAddresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSAIdx := numberOfSourceAddresses - 1
|
||||||
|
for k := range m.SourceAddresses {
|
||||||
|
i := lastSAIdx - k // reverse order
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(16)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sa16 := m.SourceAddresses[i].To16()
|
||||||
|
if sa16 == nil {
|
||||||
|
return fmt.Errorf("invalid source address [%d] '%s'", i, m.SourceAddresses[i])
|
||||||
|
}
|
||||||
|
copy(buf[0:16], sa16)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String sums this layer up nicely formatted
|
||||||
|
func (m *MLDv2MulticastListenerQueryMessage) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"Maximum Response Code: %#x (%dms), Multicast Address: %s, Suppress Routerside Processing: %t, QRV: %#x, QQIC: %#x (%ds), Number of Source Address: %d (actual: %d), Source Addresses: %s",
|
||||||
|
m.MaximumResponseCode,
|
||||||
|
m.MaximumResponseDelay(),
|
||||||
|
m.MulticastAddress,
|
||||||
|
m.SuppressRoutersideProcessing,
|
||||||
|
m.QueriersRobustnessVariable,
|
||||||
|
m.QueriersQueryIntervalCode,
|
||||||
|
m.QQI()/time.Second,
|
||||||
|
m.NumberOfSources,
|
||||||
|
len(m.SourceAddresses),
|
||||||
|
m.SourceAddresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeMLDv2MulticastListenerQuery.
|
||||||
|
func (*MLDv2MulticastListenerQueryMessage) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeMLDv2MulticastListenerQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (*MLDv2MulticastListenerQueryMessage) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeMLDv2MulticastListenerQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
// QQI calculates the Querier's Query Interval based on the QQIC
|
||||||
|
// according to https://tools.ietf.org/html/rfc3810#section-5.1.9
|
||||||
|
func (m *MLDv2MulticastListenerQueryMessage) QQI() time.Duration {
|
||||||
|
data := m.QueriersQueryIntervalCode
|
||||||
|
if data < 128 {
|
||||||
|
return time.Second * time.Duration(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
exp := uint16(data) & 0x70 >> 4
|
||||||
|
mant := uint16(data) & 0x0F
|
||||||
|
return time.Second * time.Duration(mant|0x1000<<(exp+3))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetQQI calculates and updates the Querier's Query Interval Code (QQIC)
|
||||||
|
// according to https://tools.ietf.org/html/rfc3810#section-5.1.9
|
||||||
|
func (m *MLDv2MulticastListenerQueryMessage) SetQQI(d time.Duration) error {
|
||||||
|
if d < 0 {
|
||||||
|
m.QueriersQueryIntervalCode = 0
|
||||||
|
return errors.New("QQI duration is negative")
|
||||||
|
}
|
||||||
|
|
||||||
|
if d == 0 {
|
||||||
|
m.QueriersQueryIntervalCode = 0
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dms := d / time.Second
|
||||||
|
if dms < 128 {
|
||||||
|
m.QueriersQueryIntervalCode = uint8(dms)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dms > 31744 { // mant=0xF, exp=0x7
|
||||||
|
m.QueriersQueryIntervalCode = 0xFF
|
||||||
|
return fmt.Errorf("QQI duration %ds is, maximum allowed is 31744s", dms)
|
||||||
|
}
|
||||||
|
|
||||||
|
value := uint16(dms) // ok, because 31744 < math.MaxUint16
|
||||||
|
exp := uint8(7)
|
||||||
|
for mask := uint16(0x4000); exp > 0; exp-- {
|
||||||
|
if mask&value != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
mask >>= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
mant := uint8(0x000F & (value >> (exp + 3)))
|
||||||
|
sig := uint8(0x10)
|
||||||
|
m.QueriersQueryIntervalCode = sig | exp<<4 | mant
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaximumResponseDelay returns the Maximum Response Delay based on the
|
||||||
|
// Maximum Response Code according to
|
||||||
|
// https://tools.ietf.org/html/rfc3810#section-5.1.3
|
||||||
|
func (m *MLDv2MulticastListenerQueryMessage) MaximumResponseDelay() time.Duration {
|
||||||
|
if m.MaximumResponseCode < 0x8000 {
|
||||||
|
return time.Duration(m.MaximumResponseCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
exp := m.MaximumResponseCode & 0x7000 >> 12
|
||||||
|
mant := m.MaximumResponseCode & 0x0FFF
|
||||||
|
|
||||||
|
return time.Millisecond * time.Duration(mant|0x1000<<(exp+3))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMLDv2MaximumResponseDelay updates the Maximum Response Code according to
|
||||||
|
// https://tools.ietf.org/html/rfc3810#section-5.1.3
|
||||||
|
func (m *MLDv2MulticastListenerQueryMessage) SetMLDv2MaximumResponseDelay(d time.Duration) error {
|
||||||
|
if d == 0 {
|
||||||
|
m.MaximumResponseCode = 0
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if d < 0 {
|
||||||
|
return errors.New("maximum response delay must not be negative")
|
||||||
|
}
|
||||||
|
|
||||||
|
dms := d / time.Millisecond
|
||||||
|
|
||||||
|
if dms < 32768 {
|
||||||
|
m.MaximumResponseCode = uint16(dms)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dms > 4193280 { // mant=0xFFF, exp=0x7
|
||||||
|
return fmt.Errorf("maximum response delay %dms is bigger the than maximum of 4193280ms", dms)
|
||||||
|
}
|
||||||
|
|
||||||
|
value := uint32(dms) // ok, because 4193280 < math.MaxUint32
|
||||||
|
exp := uint8(7)
|
||||||
|
for mask := uint32(0x40000000); exp > 0; exp-- {
|
||||||
|
if mask&value != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
mask >>= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
mant := uint16(0x00000FFF & (value >> (exp + 3)))
|
||||||
|
sig := uint16(0x1000)
|
||||||
|
m.MaximumResponseCode = sig | uint16(exp)<<12 | mant
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MLDv2MulticastListenerReportMessage is sent by an IP node to report the
|
||||||
|
// current multicast listening state, or changes therein.
|
||||||
|
// https://tools.ietf.org/html/rfc3810#section-5.2
|
||||||
|
type MLDv2MulticastListenerReportMessage struct {
|
||||||
|
BaseLayer
|
||||||
|
// 5.2.3. Nr of Mcast Address Records
|
||||||
|
NumberOfMulticastAddressRecords uint16
|
||||||
|
// 5.2.4. Multicast Address Record [i]
|
||||||
|
MulticastAddressRecords []MLDv2MulticastAddressRecord
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (m *MLDv2MulticastListenerReportMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 4 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ICMP layer less than 4 bytes for Multicast Listener Report Message V2")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore data[0:2] as per RFC
|
||||||
|
// https://tools.ietf.org/html/rfc3810#section-5.2.1
|
||||||
|
m.NumberOfMulticastAddressRecords = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
|
||||||
|
begin := 4
|
||||||
|
for i := uint16(0); i < m.NumberOfMulticastAddressRecords; i++ {
|
||||||
|
mar := MLDv2MulticastAddressRecord{}
|
||||||
|
read, err := mar.decode(data[begin:], df)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m.MulticastAddressRecords = append(m.MulticastAddressRecords, mar)
|
||||||
|
|
||||||
|
begin += read
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (m *MLDv2MulticastListenerReportMessage) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
lastItemIdx := len(m.MulticastAddressRecords) - 1
|
||||||
|
for k := range m.MulticastAddressRecords {
|
||||||
|
i := lastItemIdx - k // reverse order
|
||||||
|
|
||||||
|
err := m.MulticastAddressRecords[i].serializeTo(b, opts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.FixLengths {
|
||||||
|
numberOfMAR := len(m.MulticastAddressRecords)
|
||||||
|
if numberOfMAR > math.MaxUint16 {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"%d multicast address records added, but the maximum is 65535",
|
||||||
|
numberOfMAR)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.NumberOfMulticastAddressRecords = uint16(numberOfMAR)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(buf[0:2], []byte{0x0, 0x0})
|
||||||
|
binary.BigEndian.PutUint16(buf[2:4], m.NumberOfMulticastAddressRecords)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sums this layer up nicely formatted
|
||||||
|
func (m *MLDv2MulticastListenerReportMessage) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"Number of Mcast Addr Records: %d (actual %d), Multicast Address Records: %+v",
|
||||||
|
m.NumberOfMulticastAddressRecords,
|
||||||
|
len(m.MulticastAddressRecords),
|
||||||
|
m.MulticastAddressRecords)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeMLDv2MulticastListenerQuery.
|
||||||
|
func (*MLDv2MulticastListenerReportMessage) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeMLDv2MulticastListenerReport
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (*MLDv2MulticastListenerReportMessage) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeMLDv2MulticastListenerReport
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (*MLDv2MulticastListenerReportMessage) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
// MLDv2MulticastAddressRecordType holds the type of a
|
||||||
|
// Multicast Address Record, according to
|
||||||
|
// https://tools.ietf.org/html/rfc3810#section-5.2.5 and
|
||||||
|
// https://tools.ietf.org/html/rfc3810#section-5.2.12
|
||||||
|
type MLDv2MulticastAddressRecordType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// MLDv2MulticastAddressRecordTypeModeIsIncluded stands for
|
||||||
|
// MODE_IS_INCLUDE - indicates that the interface has a filter
|
||||||
|
// mode of INCLUDE for the specified multicast address.
|
||||||
|
MLDv2MulticastAddressRecordTypeModeIsIncluded MLDv2MulticastAddressRecordType = 1
|
||||||
|
// MLDv2MulticastAddressRecordTypeModeIsExcluded stands for
|
||||||
|
// MODE_IS_EXCLUDE - indicates that the interface has a filter
|
||||||
|
// mode of EXCLUDE for the specified multicast address.
|
||||||
|
MLDv2MulticastAddressRecordTypeModeIsExcluded MLDv2MulticastAddressRecordType = 2
|
||||||
|
// MLDv2MulticastAddressRecordTypeChangeToIncludeMode stands for
|
||||||
|
// CHANGE_TO_INCLUDE_MODE - indicates that the interface has
|
||||||
|
// changed to INCLUDE filter mode for the specified multicast
|
||||||
|
// address.
|
||||||
|
MLDv2MulticastAddressRecordTypeChangeToIncludeMode MLDv2MulticastAddressRecordType = 3
|
||||||
|
// MLDv2MulticastAddressRecordTypeChangeToExcludeMode stands for
|
||||||
|
// CHANGE_TO_EXCLUDE_MODE - indicates that the interface has
|
||||||
|
// changed to EXCLUDE filter mode for the specified multicast
|
||||||
|
// address
|
||||||
|
MLDv2MulticastAddressRecordTypeChangeToExcludeMode MLDv2MulticastAddressRecordType = 4
|
||||||
|
// MLDv2MulticastAddressRecordTypeAllowNewSources stands for
|
||||||
|
// ALLOW_NEW_SOURCES - indicates that the Source Address [i]
|
||||||
|
// fields in this Multicast Address Record contain a list of
|
||||||
|
// the additional sources that the node wishes to listen to,
|
||||||
|
// for packets sent to the specified multicast address.
|
||||||
|
MLDv2MulticastAddressRecordTypeAllowNewSources MLDv2MulticastAddressRecordType = 5
|
||||||
|
// MLDv2MulticastAddressRecordTypeBlockOldSources stands for
|
||||||
|
// BLOCK_OLD_SOURCES - indicates that the Source Address [i]
|
||||||
|
// fields in this Multicast Address Record contain a list of
|
||||||
|
// the sources that the node no longer wishes to listen to,
|
||||||
|
// for packets sent to the specified multicast address.
|
||||||
|
MLDv2MulticastAddressRecordTypeBlockOldSources MLDv2MulticastAddressRecordType = 6
|
||||||
|
)
|
||||||
|
|
||||||
|
// Human readable record types
|
||||||
|
// Naming follows https://tools.ietf.org/html/rfc3810#section-5.2.12
|
||||||
|
func (m MLDv2MulticastAddressRecordType) String() string {
|
||||||
|
switch m {
|
||||||
|
case MLDv2MulticastAddressRecordTypeModeIsIncluded:
|
||||||
|
return "MODE_IS_INCLUDE"
|
||||||
|
case MLDv2MulticastAddressRecordTypeModeIsExcluded:
|
||||||
|
return "MODE_IS_EXCLUDE"
|
||||||
|
case MLDv2MulticastAddressRecordTypeChangeToIncludeMode:
|
||||||
|
return "CHANGE_TO_INCLUDE_MODE"
|
||||||
|
case MLDv2MulticastAddressRecordTypeChangeToExcludeMode:
|
||||||
|
return "CHANGE_TO_EXCLUDE_MODE"
|
||||||
|
case MLDv2MulticastAddressRecordTypeAllowNewSources:
|
||||||
|
return "ALLOW_NEW_SOURCES"
|
||||||
|
case MLDv2MulticastAddressRecordTypeBlockOldSources:
|
||||||
|
return "BLOCK_OLD_SOURCES"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("UNKNOWN(%d)", m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MLDv2MulticastAddressRecord contains information on the sender listening to a
|
||||||
|
// single multicast address on the interface the report is sent.
|
||||||
|
// https://tools.ietf.org/html/rfc3810#section-5.2.4
|
||||||
|
type MLDv2MulticastAddressRecord struct {
|
||||||
|
// 5.2.5. Record Type
|
||||||
|
RecordType MLDv2MulticastAddressRecordType
|
||||||
|
// 5.2.6. Auxiliary Data Length (number of 32-bit words)
|
||||||
|
AuxDataLen uint8
|
||||||
|
// 5.2.7. Number Of Sources (N)
|
||||||
|
N uint16
|
||||||
|
// 5.2.8. Multicast Address
|
||||||
|
MulticastAddress net.IP
|
||||||
|
// 5.2.9 Source Address [i]
|
||||||
|
SourceAddresses []net.IP
|
||||||
|
// 5.2.10 Auxiliary Data
|
||||||
|
AuxiliaryData []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodes a multicast address record from bytes
|
||||||
|
func (m *MLDv2MulticastAddressRecord) decode(data []byte, df gopacket.DecodeFeedback) (int, error) {
|
||||||
|
if len(data) < 20 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return 0, errors.New(
|
||||||
|
"Multicast Listener Report Message V2 layer less than 4 bytes for Multicast Address Record")
|
||||||
|
}
|
||||||
|
|
||||||
|
m.RecordType = MLDv2MulticastAddressRecordType(data[0])
|
||||||
|
m.AuxDataLen = data[1]
|
||||||
|
m.N = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
m.MulticastAddress = data[4:20]
|
||||||
|
|
||||||
|
for i := uint16(0); i < m.N; i++ {
|
||||||
|
begin := 20 + (int(i) * 16)
|
||||||
|
end := begin + 16
|
||||||
|
|
||||||
|
if len(data) < end {
|
||||||
|
df.SetTruncated()
|
||||||
|
return begin, fmt.Errorf(
|
||||||
|
"Multicast Listener Report Message V2 layer less than %d bytes for Multicast Address Record", end)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.SourceAddresses = append(m.SourceAddresses, data[begin:end])
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedLengthWithouAuxData := 20 + (int(m.N) * 16)
|
||||||
|
expectedTotalLength := (int(m.AuxDataLen) * 4) + expectedLengthWithouAuxData // *4 because AuxDataLen are 32bit words
|
||||||
|
if len(data) < expectedTotalLength {
|
||||||
|
return expectedLengthWithouAuxData, fmt.Errorf(
|
||||||
|
"Multicast Listener Report Message V2 layer less than %d bytes for Multicast Address Record",
|
||||||
|
expectedLengthWithouAuxData)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.AuxiliaryData = data[expectedLengthWithouAuxData:expectedTotalLength]
|
||||||
|
|
||||||
|
return expectedTotalLength, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String sums this layer up nicely formatted
|
||||||
|
func (m *MLDv2MulticastAddressRecord) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"RecordType: %d (%s), AuxDataLen: %d [32-bit words], N: %d, Multicast Address: %s, SourceAddresses: %s, Auxiliary Data: %#x",
|
||||||
|
m.RecordType,
|
||||||
|
m.RecordType.String(),
|
||||||
|
m.AuxDataLen,
|
||||||
|
m.N,
|
||||||
|
m.MulticastAddress.To16(),
|
||||||
|
m.SourceAddresses,
|
||||||
|
m.AuxiliaryData)
|
||||||
|
}
|
||||||
|
|
||||||
|
// serializes a multicast address record
|
||||||
|
func (m *MLDv2MulticastAddressRecord) serializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if err := m.serializeAuxiliaryDataTo(b, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.serializeSourceAddressesTo(b, opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(20)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = uint8(m.RecordType)
|
||||||
|
buf[1] = m.AuxDataLen
|
||||||
|
binary.BigEndian.PutUint16(buf[2:4], m.N)
|
||||||
|
|
||||||
|
ma16 := m.MulticastAddress.To16()
|
||||||
|
if ma16 == nil {
|
||||||
|
return fmt.Errorf("invalid multicast address '%s'", m.MulticastAddress)
|
||||||
|
}
|
||||||
|
copy(buf[4:20], ma16)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// serializes the auxiliary data of a multicast address record
|
||||||
|
func (m *MLDv2MulticastAddressRecord) serializeAuxiliaryDataTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if remainder := len(m.AuxiliaryData) % 4; remainder != 0 {
|
||||||
|
zeroWord := []byte{0x0, 0x0, 0x0, 0x0}
|
||||||
|
m.AuxiliaryData = append(m.AuxiliaryData, zeroWord[:remainder]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.FixLengths {
|
||||||
|
auxDataLen := len(m.AuxiliaryData) / 4
|
||||||
|
|
||||||
|
if auxDataLen > math.MaxUint8 {
|
||||||
|
return fmt.Errorf("auxilary data is %d 32-bit words, but the maximum is 255 32-bit words", auxDataLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.AuxDataLen = uint8(auxDataLen)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(len(m.AuxiliaryData))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(buf, m.AuxiliaryData)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// serializes the source addresses of a multicast address record preserving the order
|
||||||
|
func (m *MLDv2MulticastAddressRecord) serializeSourceAddressesTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if opts.FixLengths {
|
||||||
|
numberOfSourceAddresses := len(m.SourceAddresses)
|
||||||
|
|
||||||
|
if numberOfSourceAddresses > math.MaxUint16 {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"%d source addresses added, but the maximum is 65535",
|
||||||
|
numberOfSourceAddresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.N = uint16(numberOfSourceAddresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastItemIdx := len(m.SourceAddresses) - 1
|
||||||
|
for k := range m.SourceAddresses {
|
||||||
|
i := lastItemIdx - k // reverse order
|
||||||
|
|
||||||
|
buf, err := b.PrependBytes(16)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sa16 := m.SourceAddresses[i].To16()
|
||||||
|
if sa16 == nil {
|
||||||
|
return fmt.Errorf("invalid source address [%d] '%s'", i, m.SourceAddresses[i])
|
||||||
|
}
|
||||||
|
copy(buf, sa16)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeMLDv2MulticastListenerReport(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
m := &MLDv2MulticastListenerReportMessage{}
|
||||||
|
return decodingLayerDecoder(m, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeMLDv2MulticastListenerQuery(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
m := &MLDv2MulticastListenerQueryMessage{}
|
||||||
|
return decodingLayerDecoder(m, data, p)
|
||||||
|
}
|
150
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/modbustcp.go
generated
vendored
Normal file
150
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/modbustcp.go
generated
vendored
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
// Copyright 2018, 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"
|
||||||
|
"errors"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
//
|
||||||
|
// ModbusTCP Decoding Layer
|
||||||
|
// ------------------------------------------
|
||||||
|
// This file provides a GoPacket decoding layer for ModbusTCP.
|
||||||
|
//
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
const mbapRecordSizeInBytes int = 7
|
||||||
|
const modbusPDUMinimumRecordSizeInBytes int = 2
|
||||||
|
const modbusPDUMaximumRecordSizeInBytes int = 253
|
||||||
|
|
||||||
|
// ModbusProtocol type
|
||||||
|
type ModbusProtocol uint16
|
||||||
|
|
||||||
|
// ModbusProtocol known values.
|
||||||
|
const (
|
||||||
|
ModbusProtocolModbus ModbusProtocol = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
func (mp ModbusProtocol) String() string {
|
||||||
|
switch mp {
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
case ModbusProtocolModbus:
|
||||||
|
return "Modbus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// ModbusTCP Type
|
||||||
|
// --------
|
||||||
|
// Type ModbusTCP implements the DecodingLayer interface. Each ModbusTCP object
|
||||||
|
// represents in a structured form the MODBUS Application Protocol header (MBAP) record present as the TCP
|
||||||
|
// payload in an ModbusTCP TCP packet.
|
||||||
|
//
|
||||||
|
type ModbusTCP struct {
|
||||||
|
BaseLayer // Stores the packet bytes and payload (Modbus PDU) bytes .
|
||||||
|
|
||||||
|
TransactionIdentifier uint16 // Identification of a MODBUS Request/Response transaction
|
||||||
|
ProtocolIdentifier ModbusProtocol // It is used for intra-system multiplexing
|
||||||
|
Length uint16 // Number of following bytes (includes 1 byte for UnitIdentifier + Modbus data length
|
||||||
|
UnitIdentifier uint8 // Identification of a remote slave connected on a serial line or on other buses
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// LayerType returns the layer type of the ModbusTCP object, which is LayerTypeModbusTCP.
|
||||||
|
func (d *ModbusTCP) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeModbusTCP
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// decodeModbusTCP analyses a byte slice and attempts to decode it as an ModbusTCP
|
||||||
|
// record of a TCP packet.
|
||||||
|
//
|
||||||
|
// If it succeeds, it loads p with information about the packet and returns nil.
|
||||||
|
// If it fails, it returns an error (non nil).
|
||||||
|
//
|
||||||
|
// This function is employed in layertypes.go to register the ModbusTCP layer.
|
||||||
|
func decodeModbusTCP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
|
||||||
|
// Attempt to decode the byte slice.
|
||||||
|
d := &ModbusTCP{}
|
||||||
|
err := d.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// If the decoding worked, add the layer to the packet and set it
|
||||||
|
// as the application layer too, if there isn't already one.
|
||||||
|
p.AddLayer(d)
|
||||||
|
p.SetApplicationLayer(d)
|
||||||
|
|
||||||
|
return p.NextDecoder(d.NextLayerType())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// DecodeFromBytes analyses a byte slice and attempts to decode it as an ModbusTCP
|
||||||
|
// record of a TCP packet.
|
||||||
|
//
|
||||||
|
// Upon succeeds, it loads the ModbusTCP object with information about the packet
|
||||||
|
// and returns nil.
|
||||||
|
// Upon failure, it returns an error (non nil).
|
||||||
|
func (d *ModbusTCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
|
||||||
|
// If the data block is too short to be a MBAP record, then return an error.
|
||||||
|
if len(data) < mbapRecordSizeInBytes+modbusPDUMinimumRecordSizeInBytes {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ModbusTCP packet too short")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) > mbapRecordSizeInBytes+modbusPDUMaximumRecordSizeInBytes {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ModbusTCP packet too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModbusTCP type embeds type BaseLayer which contains two fields:
|
||||||
|
// Contents is supposed to contain the bytes of the data at this level (MPBA).
|
||||||
|
// Payload is supposed to contain the payload of this level (PDU).
|
||||||
|
d.BaseLayer = BaseLayer{Contents: data[:mbapRecordSizeInBytes], Payload: data[mbapRecordSizeInBytes:len(data)]}
|
||||||
|
|
||||||
|
// Extract the fields from the block of bytes.
|
||||||
|
// The fields can just be copied in big endian order.
|
||||||
|
d.TransactionIdentifier = binary.BigEndian.Uint16(data[:2])
|
||||||
|
d.ProtocolIdentifier = ModbusProtocol(binary.BigEndian.Uint16(data[2:4]))
|
||||||
|
d.Length = binary.BigEndian.Uint16(data[4:6])
|
||||||
|
|
||||||
|
// Length should have the size of the payload plus one byte (size of UnitIdentifier)
|
||||||
|
if d.Length != uint16(len(d.BaseLayer.Payload)+1) {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("ModbusTCP packet with wrong field value (Length)")
|
||||||
|
}
|
||||||
|
d.UnitIdentifier = uint8(data[6])
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type of the ModbusTCP payload, which is LayerTypePayload.
|
||||||
|
func (d *ModbusTCP) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// Payload returns Modbus Protocol Data Unit (PDU) composed by Function Code and Data, it is carried within ModbusTCP packets
|
||||||
|
func (d *ModbusTCP) Payload() []byte {
|
||||||
|
return d.BaseLayer.Payload
|
||||||
|
}
|
87
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/mpls.go
generated
vendored
Normal file
87
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/mpls.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MPLS is the MPLS packet header.
|
||||||
|
type MPLS struct {
|
||||||
|
BaseLayer
|
||||||
|
Label uint32
|
||||||
|
TrafficClass uint8
|
||||||
|
StackBottom bool
|
||||||
|
TTL uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeMPLS.
|
||||||
|
func (m *MPLS) LayerType() gopacket.LayerType { return LayerTypeMPLS }
|
||||||
|
|
||||||
|
// ProtocolGuessingDecoder attempts to guess the protocol of the bytes it's
|
||||||
|
// given, then decode the packet accordingly. Its algorithm for guessing is:
|
||||||
|
// If the packet starts with byte 0x45-0x4F: IPv4
|
||||||
|
// If the packet starts with byte 0x60-0x6F: IPv6
|
||||||
|
// Otherwise: Error
|
||||||
|
// See draft-hsmit-isis-aal5mux-00.txt for more detail on this approach.
|
||||||
|
type ProtocolGuessingDecoder struct{}
|
||||||
|
|
||||||
|
func (ProtocolGuessingDecoder) Decode(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
switch data[0] {
|
||||||
|
// 0x40 | header_len, where header_len is at least 5.
|
||||||
|
case 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f:
|
||||||
|
return decodeIPv4(data, p)
|
||||||
|
// IPv6 can start with any byte whose first 4 bits are 0x6.
|
||||||
|
case 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f:
|
||||||
|
return decodeIPv6(data, p)
|
||||||
|
}
|
||||||
|
return errors.New("Unable to guess protocol of packet data")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MPLSPayloadDecoder is the decoder used to data encapsulated by each MPLS
|
||||||
|
// layer. MPLS contains no type information, so we have to explicitly decide
|
||||||
|
// which decoder to use. This is initially set to ProtocolGuessingDecoder, our
|
||||||
|
// simple attempt at guessing protocols based on the first few bytes of data
|
||||||
|
// available to us. However, if you know that in your environment MPLS always
|
||||||
|
// encapsulates a specific protocol, you may reset this.
|
||||||
|
var MPLSPayloadDecoder gopacket.Decoder = ProtocolGuessingDecoder{}
|
||||||
|
|
||||||
|
func decodeMPLS(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
decoded := binary.BigEndian.Uint32(data[:4])
|
||||||
|
mpls := &MPLS{
|
||||||
|
Label: decoded >> 12,
|
||||||
|
TrafficClass: uint8(decoded>>9) & 0x7,
|
||||||
|
StackBottom: decoded&0x100 != 0,
|
||||||
|
TTL: uint8(decoded),
|
||||||
|
BaseLayer: BaseLayer{data[:4], data[4:]},
|
||||||
|
}
|
||||||
|
p.AddLayer(mpls)
|
||||||
|
if mpls.StackBottom {
|
||||||
|
return p.NextDecoder(MPLSPayloadDecoder)
|
||||||
|
}
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeMPLS))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (m *MPLS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
encoded := m.Label << 12
|
||||||
|
encoded |= uint32(m.TrafficClass) << 9
|
||||||
|
encoded |= uint32(m.TTL)
|
||||||
|
if m.StackBottom {
|
||||||
|
encoded |= 0x100
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint32(bytes, encoded)
|
||||||
|
return nil
|
||||||
|
}
|
611
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ndp.go
generated
vendored
Normal file
611
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ndp.go
generated
vendored
Normal file
|
@ -0,0 +1,611 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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.
|
||||||
|
|
||||||
|
// Enum types courtesy of...
|
||||||
|
// http://anonsvn.wireshark.org/wireshark/trunk/epan/dissectors/packet-ndp.c
|
||||||
|
|
||||||
|
package layers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NDPChassisType uint8
|
||||||
|
|
||||||
|
// Nortel Chassis Types
|
||||||
|
const (
|
||||||
|
NDPChassisother NDPChassisType = 1
|
||||||
|
NDPChassis3000 NDPChassisType = 2
|
||||||
|
NDPChassis3030 NDPChassisType = 3
|
||||||
|
NDPChassis2310 NDPChassisType = 4
|
||||||
|
NDPChassis2810 NDPChassisType = 5
|
||||||
|
NDPChassis2912 NDPChassisType = 6
|
||||||
|
NDPChassis2914 NDPChassisType = 7
|
||||||
|
NDPChassis271x NDPChassisType = 8
|
||||||
|
NDPChassis2813 NDPChassisType = 9
|
||||||
|
NDPChassis2814 NDPChassisType = 10
|
||||||
|
NDPChassis2915 NDPChassisType = 11
|
||||||
|
NDPChassis5000 NDPChassisType = 12
|
||||||
|
NDPChassis2813SA NDPChassisType = 13
|
||||||
|
NDPChassis2814SA NDPChassisType = 14
|
||||||
|
NDPChassis810M NDPChassisType = 15
|
||||||
|
NDPChassisEthercell NDPChassisType = 16
|
||||||
|
NDPChassis5005 NDPChassisType = 17
|
||||||
|
NDPChassisAlcatelEWC NDPChassisType = 18
|
||||||
|
NDPChassis2715SA NDPChassisType = 20
|
||||||
|
NDPChassis2486 NDPChassisType = 21
|
||||||
|
NDPChassis28000series NDPChassisType = 22
|
||||||
|
NDPChassis23000series NDPChassisType = 23
|
||||||
|
NDPChassis5DN00xseries NDPChassisType = 24
|
||||||
|
NDPChassisBayStackEthernet NDPChassisType = 25
|
||||||
|
NDPChassis23100series NDPChassisType = 26
|
||||||
|
NDPChassis100BaseTHub NDPChassisType = 27
|
||||||
|
NDPChassis3000FastEthernet NDPChassisType = 28
|
||||||
|
NDPChassisOrionSwitch NDPChassisType = 29
|
||||||
|
NDPChassisDDS NDPChassisType = 31
|
||||||
|
NDPChassisCentillion6slot NDPChassisType = 32
|
||||||
|
NDPChassisCentillion12slot NDPChassisType = 33
|
||||||
|
NDPChassisCentillion1slot NDPChassisType = 34
|
||||||
|
NDPChassisBayStack301 NDPChassisType = 35
|
||||||
|
NDPChassisBayStackTokenRingHub NDPChassisType = 36
|
||||||
|
NDPChassisFVCMultimediaSwitch NDPChassisType = 37
|
||||||
|
NDPChassisSwitchNode NDPChassisType = 38
|
||||||
|
NDPChassisBayStack302Switch NDPChassisType = 39
|
||||||
|
NDPChassisBayStack350Switch NDPChassisType = 40
|
||||||
|
NDPChassisBayStack150EthernetHub NDPChassisType = 41
|
||||||
|
NDPChassisCentillion50NSwitch NDPChassisType = 42
|
||||||
|
NDPChassisCentillion50TSwitch NDPChassisType = 43
|
||||||
|
NDPChassisBayStack303304Switches NDPChassisType = 44
|
||||||
|
NDPChassisBayStack200EthernetHub NDPChassisType = 45
|
||||||
|
NDPChassisBayStack25010100EthernetHub NDPChassisType = 46
|
||||||
|
NDPChassisBayStack450101001000Switches NDPChassisType = 48
|
||||||
|
NDPChassisBayStack41010100Switches NDPChassisType = 49
|
||||||
|
NDPChassisPassport1200L3Switch NDPChassisType = 50
|
||||||
|
NDPChassisPassport1250L3Switch NDPChassisType = 51
|
||||||
|
NDPChassisPassport1100L3Switch NDPChassisType = 52
|
||||||
|
NDPChassisPassport1150L3Switch NDPChassisType = 53
|
||||||
|
NDPChassisPassport1050L3Switch NDPChassisType = 54
|
||||||
|
NDPChassisPassport1051L3Switch NDPChassisType = 55
|
||||||
|
NDPChassisPassport8610L3Switch NDPChassisType = 56
|
||||||
|
NDPChassisPassport8606L3Switch NDPChassisType = 57
|
||||||
|
NDPChassisPassport8010 NDPChassisType = 58
|
||||||
|
NDPChassisPassport8006 NDPChassisType = 59
|
||||||
|
NDPChassisBayStack670wirelessaccesspoint NDPChassisType = 60
|
||||||
|
NDPChassisPassport740 NDPChassisType = 61
|
||||||
|
NDPChassisPassport750 NDPChassisType = 62
|
||||||
|
NDPChassisPassport790 NDPChassisType = 63
|
||||||
|
NDPChassisBusinessPolicySwitch200010100Switches NDPChassisType = 64
|
||||||
|
NDPChassisPassport8110L2Switch NDPChassisType = 65
|
||||||
|
NDPChassisPassport8106L2Switch NDPChassisType = 66
|
||||||
|
NDPChassisBayStack3580GigSwitch NDPChassisType = 67
|
||||||
|
NDPChassisBayStack10PowerSupplyUnit NDPChassisType = 68
|
||||||
|
NDPChassisBayStack42010100Switch NDPChassisType = 69
|
||||||
|
NDPChassisOPTeraMetro1200EthernetServiceModule NDPChassisType = 70
|
||||||
|
NDPChassisOPTera8010co NDPChassisType = 71
|
||||||
|
NDPChassisOPTera8610coL3Switch NDPChassisType = 72
|
||||||
|
NDPChassisOPTera8110coL2Switch NDPChassisType = 73
|
||||||
|
NDPChassisOPTera8003 NDPChassisType = 74
|
||||||
|
NDPChassisOPTera8603L3Switch NDPChassisType = 75
|
||||||
|
NDPChassisOPTera8103L2Switch NDPChassisType = 76
|
||||||
|
NDPChassisBayStack380101001000Switch NDPChassisType = 77
|
||||||
|
NDPChassisEthernetSwitch47048T NDPChassisType = 78
|
||||||
|
NDPChassisOPTeraMetro1450EthernetServiceModule NDPChassisType = 79
|
||||||
|
NDPChassisOPTeraMetro1400EthernetServiceModule NDPChassisType = 80
|
||||||
|
NDPChassisAlteonSwitchFamily NDPChassisType = 81
|
||||||
|
NDPChassisEthernetSwitch46024TPWR NDPChassisType = 82
|
||||||
|
NDPChassisOPTeraMetro8010OPML2Switch NDPChassisType = 83
|
||||||
|
NDPChassisOPTeraMetro8010coOPML2Switch NDPChassisType = 84
|
||||||
|
NDPChassisOPTeraMetro8006OPML2Switch NDPChassisType = 85
|
||||||
|
NDPChassisOPTeraMetro8003OPML2Switch NDPChassisType = 86
|
||||||
|
NDPChassisAlteon180e NDPChassisType = 87
|
||||||
|
NDPChassisAlteonAD3 NDPChassisType = 88
|
||||||
|
NDPChassisAlteon184 NDPChassisType = 89
|
||||||
|
NDPChassisAlteonAD4 NDPChassisType = 90
|
||||||
|
NDPChassisPassport1424L3Switch NDPChassisType = 91
|
||||||
|
NDPChassisPassport1648L3Switch NDPChassisType = 92
|
||||||
|
NDPChassisPassport1612L3Switch NDPChassisType = 93
|
||||||
|
NDPChassisPassport1624L3Switch NDPChassisType = 94
|
||||||
|
NDPChassisBayStack38024FFiber1000Switch NDPChassisType = 95
|
||||||
|
NDPChassisEthernetRoutingSwitch551024T NDPChassisType = 96
|
||||||
|
NDPChassisEthernetRoutingSwitch551048T NDPChassisType = 97
|
||||||
|
NDPChassisEthernetSwitch47024T NDPChassisType = 98
|
||||||
|
NDPChassisNortelNetworksWirelessLANAccessPoint2220 NDPChassisType = 99
|
||||||
|
NDPChassisPassportRBS2402L3Switch NDPChassisType = 100
|
||||||
|
NDPChassisAlteonApplicationSwitch2424 NDPChassisType = 101
|
||||||
|
NDPChassisAlteonApplicationSwitch2224 NDPChassisType = 102
|
||||||
|
NDPChassisAlteonApplicationSwitch2208 NDPChassisType = 103
|
||||||
|
NDPChassisAlteonApplicationSwitch2216 NDPChassisType = 104
|
||||||
|
NDPChassisAlteonApplicationSwitch3408 NDPChassisType = 105
|
||||||
|
NDPChassisAlteonApplicationSwitch3416 NDPChassisType = 106
|
||||||
|
NDPChassisNortelNetworksWirelessLANSecuritySwitch2250 NDPChassisType = 107
|
||||||
|
NDPChassisEthernetSwitch42548T NDPChassisType = 108
|
||||||
|
NDPChassisEthernetSwitch42524T NDPChassisType = 109
|
||||||
|
NDPChassisNortelNetworksWirelessLANAccessPoint2221 NDPChassisType = 110
|
||||||
|
NDPChassisNortelMetroEthernetServiceUnit24TSPFswitch NDPChassisType = 111
|
||||||
|
NDPChassisNortelMetroEthernetServiceUnit24TLXDCswitch NDPChassisType = 112
|
||||||
|
NDPChassisPassport830010slotchassis NDPChassisType = 113
|
||||||
|
NDPChassisPassport83006slotchassis NDPChassisType = 114
|
||||||
|
NDPChassisEthernetRoutingSwitch552024TPWR NDPChassisType = 115
|
||||||
|
NDPChassisEthernetRoutingSwitch552048TPWR NDPChassisType = 116
|
||||||
|
NDPChassisNortelNetworksVPNGateway3050 NDPChassisType = 117
|
||||||
|
NDPChassisAlteonSSL31010100 NDPChassisType = 118
|
||||||
|
NDPChassisAlteonSSL31010100Fiber NDPChassisType = 119
|
||||||
|
NDPChassisAlteonSSL31010100FIPS NDPChassisType = 120
|
||||||
|
NDPChassisAlteonSSL410101001000 NDPChassisType = 121
|
||||||
|
NDPChassisAlteonSSL410101001000Fiber NDPChassisType = 122
|
||||||
|
NDPChassisAlteonApplicationSwitch2424SSL NDPChassisType = 123
|
||||||
|
NDPChassisEthernetSwitch32524T NDPChassisType = 124
|
||||||
|
NDPChassisEthernetSwitch32524G NDPChassisType = 125
|
||||||
|
NDPChassisNortelNetworksWirelessLANAccessPoint2225 NDPChassisType = 126
|
||||||
|
NDPChassisNortelNetworksWirelessLANSecuritySwitch2270 NDPChassisType = 127
|
||||||
|
NDPChassis24portEthernetSwitch47024TPWR NDPChassisType = 128
|
||||||
|
NDPChassis48portEthernetSwitch47048TPWR NDPChassisType = 129
|
||||||
|
NDPChassisEthernetRoutingSwitch553024TFD NDPChassisType = 130
|
||||||
|
NDPChassisEthernetSwitch351024T NDPChassisType = 131
|
||||||
|
NDPChassisNortelMetroEthernetServiceUnit12GACL3Switch NDPChassisType = 132
|
||||||
|
NDPChassisNortelMetroEthernetServiceUnit12GDCL3Switch NDPChassisType = 133
|
||||||
|
NDPChassisNortelSecureAccessSwitch NDPChassisType = 134
|
||||||
|
NDPChassisNortelNetworksVPNGateway3070 NDPChassisType = 135
|
||||||
|
NDPChassisOPTeraMetro3500 NDPChassisType = 136
|
||||||
|
NDPChassisSMBBES101024T NDPChassisType = 137
|
||||||
|
NDPChassisSMBBES101048T NDPChassisType = 138
|
||||||
|
NDPChassisSMBBES102024TPWR NDPChassisType = 139
|
||||||
|
NDPChassisSMBBES102048TPWR NDPChassisType = 140
|
||||||
|
NDPChassisSMBBES201024T NDPChassisType = 141
|
||||||
|
NDPChassisSMBBES201048T NDPChassisType = 142
|
||||||
|
NDPChassisSMBBES202024TPWR NDPChassisType = 143
|
||||||
|
NDPChassisSMBBES202048TPWR NDPChassisType = 144
|
||||||
|
NDPChassisSMBBES11024T NDPChassisType = 145
|
||||||
|
NDPChassisSMBBES11048T NDPChassisType = 146
|
||||||
|
NDPChassisSMBBES12024TPWR NDPChassisType = 147
|
||||||
|
NDPChassisSMBBES12048TPWR NDPChassisType = 148
|
||||||
|
NDPChassisSMBBES21024T NDPChassisType = 149
|
||||||
|
NDPChassisSMBBES21048T NDPChassisType = 150
|
||||||
|
NDPChassisSMBBES22024TPWR NDPChassisType = 151
|
||||||
|
NDPChassisSMBBES22048TPWR NDPChassisType = 152
|
||||||
|
NDPChassisOME6500 NDPChassisType = 153
|
||||||
|
NDPChassisEthernetRoutingSwitch4548GT NDPChassisType = 154
|
||||||
|
NDPChassisEthernetRoutingSwitch4548GTPWR NDPChassisType = 155
|
||||||
|
NDPChassisEthernetRoutingSwitch4550T NDPChassisType = 156
|
||||||
|
NDPChassisEthernetRoutingSwitch4550TPWR NDPChassisType = 157
|
||||||
|
NDPChassisEthernetRoutingSwitch4526FX NDPChassisType = 158
|
||||||
|
NDPChassisEthernetRoutingSwitch250026T NDPChassisType = 159
|
||||||
|
NDPChassisEthernetRoutingSwitch250026TPWR NDPChassisType = 160
|
||||||
|
NDPChassisEthernetRoutingSwitch250050T NDPChassisType = 161
|
||||||
|
NDPChassisEthernetRoutingSwitch250050TPWR NDPChassisType = 162
|
||||||
|
)
|
||||||
|
|
||||||
|
type NDPBackplaneType uint8
|
||||||
|
|
||||||
|
// Nortel Backplane Types
|
||||||
|
const (
|
||||||
|
NDPBackplaneOther NDPBackplaneType = 1
|
||||||
|
NDPBackplaneEthernet NDPBackplaneType = 2
|
||||||
|
NDPBackplaneEthernetTokenring NDPBackplaneType = 3
|
||||||
|
NDPBackplaneEthernetFDDI NDPBackplaneType = 4
|
||||||
|
NDPBackplaneEthernetTokenringFDDI NDPBackplaneType = 5
|
||||||
|
NDPBackplaneEthernetTokenringRedundantPower NDPBackplaneType = 6
|
||||||
|
NDPBackplaneEthernetTokenringFDDIRedundantPower NDPBackplaneType = 7
|
||||||
|
NDPBackplaneTokenRing NDPBackplaneType = 8
|
||||||
|
NDPBackplaneEthernetTokenringFastEthernet NDPBackplaneType = 9
|
||||||
|
NDPBackplaneEthernetFastEthernet NDPBackplaneType = 10
|
||||||
|
NDPBackplaneEthernetTokenringFastEthernetRedundantPower NDPBackplaneType = 11
|
||||||
|
NDPBackplaneEthernetFastEthernetGigabitEthernet NDPBackplaneType = 12
|
||||||
|
)
|
||||||
|
|
||||||
|
type NDPState uint8
|
||||||
|
|
||||||
|
// Device State
|
||||||
|
const (
|
||||||
|
NDPStateTopology NDPState = 1
|
||||||
|
NDPStateHeartbeat NDPState = 2
|
||||||
|
NDPStateNew NDPState = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// NortelDiscovery is a packet layer containing the Nortel Discovery Protocol.
|
||||||
|
type NortelDiscovery struct {
|
||||||
|
BaseLayer
|
||||||
|
IPAddress net.IP
|
||||||
|
SegmentID []byte
|
||||||
|
Chassis NDPChassisType
|
||||||
|
Backplane NDPBackplaneType
|
||||||
|
State NDPState
|
||||||
|
NumLinks uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeNortelDiscovery.
|
||||||
|
func (c *NortelDiscovery) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeNortelDiscovery
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeNortelDiscovery(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
c := &NortelDiscovery{}
|
||||||
|
if len(data) < 11 {
|
||||||
|
return fmt.Errorf("Invalid NortelDiscovery packet length %d", len(data))
|
||||||
|
}
|
||||||
|
c.IPAddress = data[0:4]
|
||||||
|
c.SegmentID = data[4:7]
|
||||||
|
c.Chassis = NDPChassisType(data[7])
|
||||||
|
c.Backplane = NDPBackplaneType(data[8])
|
||||||
|
c.State = NDPState(data[9])
|
||||||
|
c.NumLinks = uint8(data[10])
|
||||||
|
p.AddLayer(c)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t NDPChassisType) String() (s string) {
|
||||||
|
switch t {
|
||||||
|
case NDPChassisother:
|
||||||
|
s = "other"
|
||||||
|
case NDPChassis3000:
|
||||||
|
s = "3000"
|
||||||
|
case NDPChassis3030:
|
||||||
|
s = "3030"
|
||||||
|
case NDPChassis2310:
|
||||||
|
s = "2310"
|
||||||
|
case NDPChassis2810:
|
||||||
|
s = "2810"
|
||||||
|
case NDPChassis2912:
|
||||||
|
s = "2912"
|
||||||
|
case NDPChassis2914:
|
||||||
|
s = "2914"
|
||||||
|
case NDPChassis271x:
|
||||||
|
s = "271x"
|
||||||
|
case NDPChassis2813:
|
||||||
|
s = "2813"
|
||||||
|
case NDPChassis2814:
|
||||||
|
s = "2814"
|
||||||
|
case NDPChassis2915:
|
||||||
|
s = "2915"
|
||||||
|
case NDPChassis5000:
|
||||||
|
s = "5000"
|
||||||
|
case NDPChassis2813SA:
|
||||||
|
s = "2813SA"
|
||||||
|
case NDPChassis2814SA:
|
||||||
|
s = "2814SA"
|
||||||
|
case NDPChassis810M:
|
||||||
|
s = "810M"
|
||||||
|
case NDPChassisEthercell:
|
||||||
|
s = "Ethercell"
|
||||||
|
case NDPChassis5005:
|
||||||
|
s = "5005"
|
||||||
|
case NDPChassisAlcatelEWC:
|
||||||
|
s = "Alcatel Ethernet workgroup conc."
|
||||||
|
case NDPChassis2715SA:
|
||||||
|
s = "2715SA"
|
||||||
|
case NDPChassis2486:
|
||||||
|
s = "2486"
|
||||||
|
case NDPChassis28000series:
|
||||||
|
s = "28000 series"
|
||||||
|
case NDPChassis23000series:
|
||||||
|
s = "23000 series"
|
||||||
|
case NDPChassis5DN00xseries:
|
||||||
|
s = "5DN00x series"
|
||||||
|
case NDPChassisBayStackEthernet:
|
||||||
|
s = "BayStack Ethernet"
|
||||||
|
case NDPChassis23100series:
|
||||||
|
s = "23100 series"
|
||||||
|
case NDPChassis100BaseTHub:
|
||||||
|
s = "100Base-T Hub"
|
||||||
|
case NDPChassis3000FastEthernet:
|
||||||
|
s = "3000 Fast Ethernet"
|
||||||
|
case NDPChassisOrionSwitch:
|
||||||
|
s = "Orion switch"
|
||||||
|
case NDPChassisDDS:
|
||||||
|
s = "DDS"
|
||||||
|
case NDPChassisCentillion6slot:
|
||||||
|
s = "Centillion (6 slot)"
|
||||||
|
case NDPChassisCentillion12slot:
|
||||||
|
s = "Centillion (12 slot)"
|
||||||
|
case NDPChassisCentillion1slot:
|
||||||
|
s = "Centillion (1 slot)"
|
||||||
|
case NDPChassisBayStack301:
|
||||||
|
s = "BayStack 301"
|
||||||
|
case NDPChassisBayStackTokenRingHub:
|
||||||
|
s = "BayStack TokenRing Hub"
|
||||||
|
case NDPChassisFVCMultimediaSwitch:
|
||||||
|
s = "FVC Multimedia Switch"
|
||||||
|
case NDPChassisSwitchNode:
|
||||||
|
s = "Switch Node"
|
||||||
|
case NDPChassisBayStack302Switch:
|
||||||
|
s = "BayStack 302 Switch"
|
||||||
|
case NDPChassisBayStack350Switch:
|
||||||
|
s = "BayStack 350 Switch"
|
||||||
|
case NDPChassisBayStack150EthernetHub:
|
||||||
|
s = "BayStack 150 Ethernet Hub"
|
||||||
|
case NDPChassisCentillion50NSwitch:
|
||||||
|
s = "Centillion 50N switch"
|
||||||
|
case NDPChassisCentillion50TSwitch:
|
||||||
|
s = "Centillion 50T switch"
|
||||||
|
case NDPChassisBayStack303304Switches:
|
||||||
|
s = "BayStack 303 and 304 Switches"
|
||||||
|
case NDPChassisBayStack200EthernetHub:
|
||||||
|
s = "BayStack 200 Ethernet Hub"
|
||||||
|
case NDPChassisBayStack25010100EthernetHub:
|
||||||
|
s = "BayStack 250 10/100 Ethernet Hub"
|
||||||
|
case NDPChassisBayStack450101001000Switches:
|
||||||
|
s = "BayStack 450 10/100/1000 Switches"
|
||||||
|
case NDPChassisBayStack41010100Switches:
|
||||||
|
s = "BayStack 410 10/100 Switches"
|
||||||
|
case NDPChassisPassport1200L3Switch:
|
||||||
|
s = "Passport 1200 L3 Switch"
|
||||||
|
case NDPChassisPassport1250L3Switch:
|
||||||
|
s = "Passport 1250 L3 Switch"
|
||||||
|
case NDPChassisPassport1100L3Switch:
|
||||||
|
s = "Passport 1100 L3 Switch"
|
||||||
|
case NDPChassisPassport1150L3Switch:
|
||||||
|
s = "Passport 1150 L3 Switch"
|
||||||
|
case NDPChassisPassport1050L3Switch:
|
||||||
|
s = "Passport 1050 L3 Switch"
|
||||||
|
case NDPChassisPassport1051L3Switch:
|
||||||
|
s = "Passport 1051 L3 Switch"
|
||||||
|
case NDPChassisPassport8610L3Switch:
|
||||||
|
s = "Passport 8610 L3 Switch"
|
||||||
|
case NDPChassisPassport8606L3Switch:
|
||||||
|
s = "Passport 8606 L3 Switch"
|
||||||
|
case NDPChassisPassport8010:
|
||||||
|
s = "Passport 8010"
|
||||||
|
case NDPChassisPassport8006:
|
||||||
|
s = "Passport 8006"
|
||||||
|
case NDPChassisBayStack670wirelessaccesspoint:
|
||||||
|
s = "BayStack 670 wireless access point"
|
||||||
|
case NDPChassisPassport740:
|
||||||
|
s = "Passport 740"
|
||||||
|
case NDPChassisPassport750:
|
||||||
|
s = "Passport 750"
|
||||||
|
case NDPChassisPassport790:
|
||||||
|
s = "Passport 790"
|
||||||
|
case NDPChassisBusinessPolicySwitch200010100Switches:
|
||||||
|
s = "Business Policy Switch 2000 10/100 Switches"
|
||||||
|
case NDPChassisPassport8110L2Switch:
|
||||||
|
s = "Passport 8110 L2 Switch"
|
||||||
|
case NDPChassisPassport8106L2Switch:
|
||||||
|
s = "Passport 8106 L2 Switch"
|
||||||
|
case NDPChassisBayStack3580GigSwitch:
|
||||||
|
s = "BayStack 3580 Gig Switch"
|
||||||
|
case NDPChassisBayStack10PowerSupplyUnit:
|
||||||
|
s = "BayStack 10 Power Supply Unit"
|
||||||
|
case NDPChassisBayStack42010100Switch:
|
||||||
|
s = "BayStack 420 10/100 Switch"
|
||||||
|
case NDPChassisOPTeraMetro1200EthernetServiceModule:
|
||||||
|
s = "OPTera Metro 1200 Ethernet Service Module"
|
||||||
|
case NDPChassisOPTera8010co:
|
||||||
|
s = "OPTera 8010co"
|
||||||
|
case NDPChassisOPTera8610coL3Switch:
|
||||||
|
s = "OPTera 8610co L3 switch"
|
||||||
|
case NDPChassisOPTera8110coL2Switch:
|
||||||
|
s = "OPTera 8110co L2 switch"
|
||||||
|
case NDPChassisOPTera8003:
|
||||||
|
s = "OPTera 8003"
|
||||||
|
case NDPChassisOPTera8603L3Switch:
|
||||||
|
s = "OPTera 8603 L3 switch"
|
||||||
|
case NDPChassisOPTera8103L2Switch:
|
||||||
|
s = "OPTera 8103 L2 switch"
|
||||||
|
case NDPChassisBayStack380101001000Switch:
|
||||||
|
s = "BayStack 380 10/100/1000 Switch"
|
||||||
|
case NDPChassisEthernetSwitch47048T:
|
||||||
|
s = "Ethernet Switch 470-48T"
|
||||||
|
case NDPChassisOPTeraMetro1450EthernetServiceModule:
|
||||||
|
s = "OPTera Metro 1450 Ethernet Service Module"
|
||||||
|
case NDPChassisOPTeraMetro1400EthernetServiceModule:
|
||||||
|
s = "OPTera Metro 1400 Ethernet Service Module"
|
||||||
|
case NDPChassisAlteonSwitchFamily:
|
||||||
|
s = "Alteon Switch Family"
|
||||||
|
case NDPChassisEthernetSwitch46024TPWR:
|
||||||
|
s = "Ethernet Switch 460-24T-PWR"
|
||||||
|
case NDPChassisOPTeraMetro8010OPML2Switch:
|
||||||
|
s = "OPTera Metro 8010 OPM L2 Switch"
|
||||||
|
case NDPChassisOPTeraMetro8010coOPML2Switch:
|
||||||
|
s = "OPTera Metro 8010co OPM L2 Switch"
|
||||||
|
case NDPChassisOPTeraMetro8006OPML2Switch:
|
||||||
|
s = "OPTera Metro 8006 OPM L2 Switch"
|
||||||
|
case NDPChassisOPTeraMetro8003OPML2Switch:
|
||||||
|
s = "OPTera Metro 8003 OPM L2 Switch"
|
||||||
|
case NDPChassisAlteon180e:
|
||||||
|
s = "Alteon 180e"
|
||||||
|
case NDPChassisAlteonAD3:
|
||||||
|
s = "Alteon AD3"
|
||||||
|
case NDPChassisAlteon184:
|
||||||
|
s = "Alteon 184"
|
||||||
|
case NDPChassisAlteonAD4:
|
||||||
|
s = "Alteon AD4"
|
||||||
|
case NDPChassisPassport1424L3Switch:
|
||||||
|
s = "Passport 1424 L3 switch"
|
||||||
|
case NDPChassisPassport1648L3Switch:
|
||||||
|
s = "Passport 1648 L3 switch"
|
||||||
|
case NDPChassisPassport1612L3Switch:
|
||||||
|
s = "Passport 1612 L3 switch"
|
||||||
|
case NDPChassisPassport1624L3Switch:
|
||||||
|
s = "Passport 1624 L3 switch"
|
||||||
|
case NDPChassisBayStack38024FFiber1000Switch:
|
||||||
|
s = "BayStack 380-24F Fiber 1000 Switch"
|
||||||
|
case NDPChassisEthernetRoutingSwitch551024T:
|
||||||
|
s = "Ethernet Routing Switch 5510-24T"
|
||||||
|
case NDPChassisEthernetRoutingSwitch551048T:
|
||||||
|
s = "Ethernet Routing Switch 5510-48T"
|
||||||
|
case NDPChassisEthernetSwitch47024T:
|
||||||
|
s = "Ethernet Switch 470-24T"
|
||||||
|
case NDPChassisNortelNetworksWirelessLANAccessPoint2220:
|
||||||
|
s = "Nortel Networks Wireless LAN Access Point 2220"
|
||||||
|
case NDPChassisPassportRBS2402L3Switch:
|
||||||
|
s = "Passport RBS 2402 L3 switch"
|
||||||
|
case NDPChassisAlteonApplicationSwitch2424:
|
||||||
|
s = "Alteon Application Switch 2424"
|
||||||
|
case NDPChassisAlteonApplicationSwitch2224:
|
||||||
|
s = "Alteon Application Switch 2224"
|
||||||
|
case NDPChassisAlteonApplicationSwitch2208:
|
||||||
|
s = "Alteon Application Switch 2208"
|
||||||
|
case NDPChassisAlteonApplicationSwitch2216:
|
||||||
|
s = "Alteon Application Switch 2216"
|
||||||
|
case NDPChassisAlteonApplicationSwitch3408:
|
||||||
|
s = "Alteon Application Switch 3408"
|
||||||
|
case NDPChassisAlteonApplicationSwitch3416:
|
||||||
|
s = "Alteon Application Switch 3416"
|
||||||
|
case NDPChassisNortelNetworksWirelessLANSecuritySwitch2250:
|
||||||
|
s = "Nortel Networks Wireless LAN SecuritySwitch 2250"
|
||||||
|
case NDPChassisEthernetSwitch42548T:
|
||||||
|
s = "Ethernet Switch 425-48T"
|
||||||
|
case NDPChassisEthernetSwitch42524T:
|
||||||
|
s = "Ethernet Switch 425-24T"
|
||||||
|
case NDPChassisNortelNetworksWirelessLANAccessPoint2221:
|
||||||
|
s = "Nortel Networks Wireless LAN Access Point 2221"
|
||||||
|
case NDPChassisNortelMetroEthernetServiceUnit24TSPFswitch:
|
||||||
|
s = "Nortel Metro Ethernet Service Unit 24-T SPF switch"
|
||||||
|
case NDPChassisNortelMetroEthernetServiceUnit24TLXDCswitch:
|
||||||
|
s = " Nortel Metro Ethernet Service Unit 24-T LX DC switch"
|
||||||
|
case NDPChassisPassport830010slotchassis:
|
||||||
|
s = "Passport 8300 10-slot chassis"
|
||||||
|
case NDPChassisPassport83006slotchassis:
|
||||||
|
s = "Passport 8300 6-slot chassis"
|
||||||
|
case NDPChassisEthernetRoutingSwitch552024TPWR:
|
||||||
|
s = "Ethernet Routing Switch 5520-24T-PWR"
|
||||||
|
case NDPChassisEthernetRoutingSwitch552048TPWR:
|
||||||
|
s = "Ethernet Routing Switch 5520-48T-PWR"
|
||||||
|
case NDPChassisNortelNetworksVPNGateway3050:
|
||||||
|
s = "Nortel Networks VPN Gateway 3050"
|
||||||
|
case NDPChassisAlteonSSL31010100:
|
||||||
|
s = "Alteon SSL 310 10/100"
|
||||||
|
case NDPChassisAlteonSSL31010100Fiber:
|
||||||
|
s = "Alteon SSL 310 10/100 Fiber"
|
||||||
|
case NDPChassisAlteonSSL31010100FIPS:
|
||||||
|
s = "Alteon SSL 310 10/100 FIPS"
|
||||||
|
case NDPChassisAlteonSSL410101001000:
|
||||||
|
s = "Alteon SSL 410 10/100/1000"
|
||||||
|
case NDPChassisAlteonSSL410101001000Fiber:
|
||||||
|
s = "Alteon SSL 410 10/100/1000 Fiber"
|
||||||
|
case NDPChassisAlteonApplicationSwitch2424SSL:
|
||||||
|
s = "Alteon Application Switch 2424-SSL"
|
||||||
|
case NDPChassisEthernetSwitch32524T:
|
||||||
|
s = "Ethernet Switch 325-24T"
|
||||||
|
case NDPChassisEthernetSwitch32524G:
|
||||||
|
s = "Ethernet Switch 325-24G"
|
||||||
|
case NDPChassisNortelNetworksWirelessLANAccessPoint2225:
|
||||||
|
s = "Nortel Networks Wireless LAN Access Point 2225"
|
||||||
|
case NDPChassisNortelNetworksWirelessLANSecuritySwitch2270:
|
||||||
|
s = "Nortel Networks Wireless LAN SecuritySwitch 2270"
|
||||||
|
case NDPChassis24portEthernetSwitch47024TPWR:
|
||||||
|
s = "24-port Ethernet Switch 470-24T-PWR"
|
||||||
|
case NDPChassis48portEthernetSwitch47048TPWR:
|
||||||
|
s = "48-port Ethernet Switch 470-48T-PWR"
|
||||||
|
case NDPChassisEthernetRoutingSwitch553024TFD:
|
||||||
|
s = "Ethernet Routing Switch 5530-24TFD"
|
||||||
|
case NDPChassisEthernetSwitch351024T:
|
||||||
|
s = "Ethernet Switch 3510-24T"
|
||||||
|
case NDPChassisNortelMetroEthernetServiceUnit12GACL3Switch:
|
||||||
|
s = "Nortel Metro Ethernet Service Unit 12G AC L3 switch"
|
||||||
|
case NDPChassisNortelMetroEthernetServiceUnit12GDCL3Switch:
|
||||||
|
s = "Nortel Metro Ethernet Service Unit 12G DC L3 switch"
|
||||||
|
case NDPChassisNortelSecureAccessSwitch:
|
||||||
|
s = "Nortel Secure Access Switch"
|
||||||
|
case NDPChassisNortelNetworksVPNGateway3070:
|
||||||
|
s = "Nortel Networks VPN Gateway 3070"
|
||||||
|
case NDPChassisOPTeraMetro3500:
|
||||||
|
s = "OPTera Metro 3500"
|
||||||
|
case NDPChassisSMBBES101024T:
|
||||||
|
s = "SMB BES 1010 24T"
|
||||||
|
case NDPChassisSMBBES101048T:
|
||||||
|
s = "SMB BES 1010 48T"
|
||||||
|
case NDPChassisSMBBES102024TPWR:
|
||||||
|
s = "SMB BES 1020 24T PWR"
|
||||||
|
case NDPChassisSMBBES102048TPWR:
|
||||||
|
s = "SMB BES 1020 48T PWR"
|
||||||
|
case NDPChassisSMBBES201024T:
|
||||||
|
s = "SMB BES 2010 24T"
|
||||||
|
case NDPChassisSMBBES201048T:
|
||||||
|
s = "SMB BES 2010 48T"
|
||||||
|
case NDPChassisSMBBES202024TPWR:
|
||||||
|
s = "SMB BES 2020 24T PWR"
|
||||||
|
case NDPChassisSMBBES202048TPWR:
|
||||||
|
s = "SMB BES 2020 48T PWR"
|
||||||
|
case NDPChassisSMBBES11024T:
|
||||||
|
s = "SMB BES 110 24T"
|
||||||
|
case NDPChassisSMBBES11048T:
|
||||||
|
s = "SMB BES 110 48T"
|
||||||
|
case NDPChassisSMBBES12024TPWR:
|
||||||
|
s = "SMB BES 120 24T PWR"
|
||||||
|
case NDPChassisSMBBES12048TPWR:
|
||||||
|
s = "SMB BES 120 48T PWR"
|
||||||
|
case NDPChassisSMBBES21024T:
|
||||||
|
s = "SMB BES 210 24T"
|
||||||
|
case NDPChassisSMBBES21048T:
|
||||||
|
s = "SMB BES 210 48T"
|
||||||
|
case NDPChassisSMBBES22024TPWR:
|
||||||
|
s = "SMB BES 220 24T PWR"
|
||||||
|
case NDPChassisSMBBES22048TPWR:
|
||||||
|
s = "SMB BES 220 48T PWR"
|
||||||
|
case NDPChassisOME6500:
|
||||||
|
s = "OME 6500"
|
||||||
|
case NDPChassisEthernetRoutingSwitch4548GT:
|
||||||
|
s = "Ethernet Routing Switch 4548GT"
|
||||||
|
case NDPChassisEthernetRoutingSwitch4548GTPWR:
|
||||||
|
s = "Ethernet Routing Switch 4548GT-PWR"
|
||||||
|
case NDPChassisEthernetRoutingSwitch4550T:
|
||||||
|
s = "Ethernet Routing Switch 4550T"
|
||||||
|
case NDPChassisEthernetRoutingSwitch4550TPWR:
|
||||||
|
s = "Ethernet Routing Switch 4550T-PWR"
|
||||||
|
case NDPChassisEthernetRoutingSwitch4526FX:
|
||||||
|
s = "Ethernet Routing Switch 4526FX"
|
||||||
|
case NDPChassisEthernetRoutingSwitch250026T:
|
||||||
|
s = "Ethernet Routing Switch 2500-26T"
|
||||||
|
case NDPChassisEthernetRoutingSwitch250026TPWR:
|
||||||
|
s = "Ethernet Routing Switch 2500-26T-PWR"
|
||||||
|
case NDPChassisEthernetRoutingSwitch250050T:
|
||||||
|
s = "Ethernet Routing Switch 2500-50T"
|
||||||
|
case NDPChassisEthernetRoutingSwitch250050TPWR:
|
||||||
|
s = "Ethernet Routing Switch 2500-50T-PWR"
|
||||||
|
default:
|
||||||
|
s = "Unknown"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t NDPBackplaneType) String() (s string) {
|
||||||
|
switch t {
|
||||||
|
case NDPBackplaneOther:
|
||||||
|
s = "Other"
|
||||||
|
case NDPBackplaneEthernet:
|
||||||
|
s = "Ethernet"
|
||||||
|
case NDPBackplaneEthernetTokenring:
|
||||||
|
s = "Ethernet and Tokenring"
|
||||||
|
case NDPBackplaneEthernetFDDI:
|
||||||
|
s = "Ethernet and FDDI"
|
||||||
|
case NDPBackplaneEthernetTokenringFDDI:
|
||||||
|
s = "Ethernet, Tokenring and FDDI"
|
||||||
|
case NDPBackplaneEthernetTokenringRedundantPower:
|
||||||
|
s = "Ethernet and Tokenring with redundant power"
|
||||||
|
case NDPBackplaneEthernetTokenringFDDIRedundantPower:
|
||||||
|
s = "Ethernet, Tokenring, FDDI with redundant power"
|
||||||
|
case NDPBackplaneTokenRing:
|
||||||
|
s = "Token Ring"
|
||||||
|
case NDPBackplaneEthernetTokenringFastEthernet:
|
||||||
|
s = "Ethernet, Tokenring and Fast Ethernet"
|
||||||
|
case NDPBackplaneEthernetFastEthernet:
|
||||||
|
s = "Ethernet and Fast Ethernet"
|
||||||
|
case NDPBackplaneEthernetTokenringFastEthernetRedundantPower:
|
||||||
|
s = "Ethernet, Tokenring, Fast Ethernet with redundant power"
|
||||||
|
case NDPBackplaneEthernetFastEthernetGigabitEthernet:
|
||||||
|
s = "Ethernet, Fast Ethernet and Gigabit Ethernet"
|
||||||
|
default:
|
||||||
|
s = "Unknown"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t NDPState) String() (s string) {
|
||||||
|
switch t {
|
||||||
|
case NDPStateTopology:
|
||||||
|
s = "Topology Change"
|
||||||
|
case NDPStateHeartbeat:
|
||||||
|
s = "Heartbeat"
|
||||||
|
case NDPStateNew:
|
||||||
|
s = "New"
|
||||||
|
default:
|
||||||
|
s = "Unknown"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
416
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ntp.go
generated
vendored
Normal file
416
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ntp.go
generated
vendored
Normal file
|
@ -0,0 +1,416 @@
|
||||||
|
// Copyright 2016 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
//
|
||||||
|
// Network Time Protocol (NTP) Decoding Layer
|
||||||
|
// ------------------------------------------
|
||||||
|
// This file provides a GoPacket decoding layer for NTP.
|
||||||
|
//
|
||||||
|
//******************************************************************************
|
||||||
|
//
|
||||||
|
// About The Network Time Protocol (NTP)
|
||||||
|
// -------------------------------------
|
||||||
|
// NTP is a protocol that enables computers on the internet to set their
|
||||||
|
// clocks to the correct time (or to a time that is acceptably close to the
|
||||||
|
// correct time). NTP runs on top of UDP.
|
||||||
|
//
|
||||||
|
// There have been a series of versions of the NTP protocol. The latest
|
||||||
|
// version is V4 and is specified in RFC 5905:
|
||||||
|
// http://www.ietf.org/rfc/rfc5905.txt
|
||||||
|
//
|
||||||
|
//******************************************************************************
|
||||||
|
//
|
||||||
|
// References
|
||||||
|
// ----------
|
||||||
|
//
|
||||||
|
// Wikipedia's NTP entry:
|
||||||
|
// https://en.wikipedia.org/wiki/Network_Time_Protocol
|
||||||
|
// This is the best place to get an overview of NTP.
|
||||||
|
//
|
||||||
|
// Network Time Protocol Home Website:
|
||||||
|
// http://www.ntp.org/
|
||||||
|
// This appears to be the official website of NTP.
|
||||||
|
//
|
||||||
|
// List of current NTP Protocol RFCs:
|
||||||
|
// http://www.ntp.org/rfc.html
|
||||||
|
//
|
||||||
|
// RFC 958: "Network Time Protocol (NTP)" (1985)
|
||||||
|
// https://tools.ietf.org/html/rfc958
|
||||||
|
// This is the original NTP specification.
|
||||||
|
//
|
||||||
|
// RFC 1305: "Network Time Protocol (Version 3) Specification, Implementation and Analysis" (1992)
|
||||||
|
// https://tools.ietf.org/html/rfc1305
|
||||||
|
// The protocol was updated in 1992 yielding NTP V3.
|
||||||
|
//
|
||||||
|
// RFC 5905: "Network Time Protocol Version 4: Protocol and Algorithms Specification" (2010)
|
||||||
|
// https://www.ietf.org/rfc/rfc5905.txt
|
||||||
|
// The protocol was updated in 2010 yielding NTP V4.
|
||||||
|
// V4 is backwards compatible with all previous versions of NTP.
|
||||||
|
//
|
||||||
|
// RFC 5906: "Network Time Protocol Version 4: Autokey Specification"
|
||||||
|
// https://tools.ietf.org/html/rfc5906
|
||||||
|
// This document addresses the security of the NTP protocol
|
||||||
|
// and is probably not relevant to this package.
|
||||||
|
//
|
||||||
|
// RFC 5907: "Definitions of Managed Objects for Network Time Protocol Version 4 (NTPv4)"
|
||||||
|
// https://tools.ietf.org/html/rfc5907
|
||||||
|
// This document addresses the management of NTP servers and
|
||||||
|
// is probably not relevant to this package.
|
||||||
|
//
|
||||||
|
// RFC 5908: "Network Time Protocol (NTP) Server Option for DHCPv6"
|
||||||
|
// https://tools.ietf.org/html/rfc5908
|
||||||
|
// This document addresses the use of NTP in DHCPv6 and is
|
||||||
|
// probably not relevant to this package.
|
||||||
|
//
|
||||||
|
// "Let's make a NTP Client in C"
|
||||||
|
// https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html
|
||||||
|
// This web page contains useful information about the details of NTP,
|
||||||
|
// including an NTP record struture in C, and C code.
|
||||||
|
//
|
||||||
|
// "NTP Packet Header (NTP Reference Implementation) (Computer Network Time Synchronization)"
|
||||||
|
// http://what-when-how.com/computer-network-time-synchronization/
|
||||||
|
// ntp-packet-header-ntp-reference-implementation-computer-network-time-synchronization/
|
||||||
|
// This web page contains useful information on the details of NTP.
|
||||||
|
//
|
||||||
|
// "Technical information - NTP Data Packet"
|
||||||
|
// https://www.meinbergglobal.com/english/info/ntp-packet.htm
|
||||||
|
// This page has a helpful diagram of an NTP V4 packet.
|
||||||
|
//
|
||||||
|
//******************************************************************************
|
||||||
|
//
|
||||||
|
// Obsolete References
|
||||||
|
// -------------------
|
||||||
|
//
|
||||||
|
// RFC 1119: "RFC-1119 "Network Time Protocol (Version 2) Specification and Implementation" (1989)
|
||||||
|
// https://tools.ietf.org/html/rfc1119
|
||||||
|
// Version 2 was drafted in 1989.
|
||||||
|
// It is unclear whether V2 was ever implememented or whether the
|
||||||
|
// ideas ended up in V3 (which was implemented in 1992).
|
||||||
|
//
|
||||||
|
// RFC 1361: "Simple Network Time Protocol (SNTP)"
|
||||||
|
// https://tools.ietf.org/html/rfc1361
|
||||||
|
// This document is obsoleted by RFC 1769 and is included only for completeness.
|
||||||
|
//
|
||||||
|
// RFC 1769: "Simple Network Time Protocol (SNTP)"
|
||||||
|
// https://tools.ietf.org/html/rfc1769
|
||||||
|
// This document is obsoleted by RFC 2030 and RFC 4330 and is included only for completeness.
|
||||||
|
//
|
||||||
|
// RFC 2030: "Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI"
|
||||||
|
// https://tools.ietf.org/html/rfc2030
|
||||||
|
// This document is obsoleted by RFC 4330 and is included only for completeness.
|
||||||
|
//
|
||||||
|
// RFC 4330: "Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI"
|
||||||
|
// https://tools.ietf.org/html/rfc4330
|
||||||
|
// This document is obsoleted by RFC 5905 and is included only for completeness.
|
||||||
|
//
|
||||||
|
//******************************************************************************
|
||||||
|
//
|
||||||
|
// Endian And Bit Numbering Issues
|
||||||
|
// -------------------------------
|
||||||
|
//
|
||||||
|
// Endian and bit numbering issues can be confusing. Here is some
|
||||||
|
// clarification:
|
||||||
|
//
|
||||||
|
// ENDIAN: Values are sent big endian.
|
||||||
|
// https://en.wikipedia.org/wiki/Endianness
|
||||||
|
//
|
||||||
|
// BIT NUMBERING: Bits are numbered 0 upwards from the most significant
|
||||||
|
// bit to the least significant bit. This means that if there is a 32-bit
|
||||||
|
// value, the most significant bit is called bit 0 and the least
|
||||||
|
// significant bit is called bit 31.
|
||||||
|
//
|
||||||
|
// See RFC 791 Appendix B for more discussion.
|
||||||
|
//
|
||||||
|
//******************************************************************************
|
||||||
|
//
|
||||||
|
// NTP V3 and V4 Packet Format
|
||||||
|
// ---------------------------
|
||||||
|
// NTP packets are UDP packets whose payload contains an NTP record.
|
||||||
|
//
|
||||||
|
// The NTP RFC defines the format of the NTP record.
|
||||||
|
//
|
||||||
|
// There have been four versions of the protocol:
|
||||||
|
//
|
||||||
|
// V1 in 1985
|
||||||
|
// V2 in 1989
|
||||||
|
// V3 in 1992
|
||||||
|
// V4 in 2010
|
||||||
|
//
|
||||||
|
// It is clear that V1 and V2 are obsolete, and there is no need to
|
||||||
|
// cater for these formats.
|
||||||
|
//
|
||||||
|
// V3 and V4 essentially use the same format, with V4 adding some optional
|
||||||
|
// fields on the end. So this package supports the V3 and V4 formats.
|
||||||
|
//
|
||||||
|
// The current version of NTP (NTP V4)'s RFC (V4 - RFC 5905) contains
|
||||||
|
// the following diagram for the NTP record format:
|
||||||
|
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// |LI | VN |Mode | Stratum | Poll | Precision |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Root Delay |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Root Dispersion |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Reference ID |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// + Reference Timestamp (64) +
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// + Origin Timestamp (64) +
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// + Receive Timestamp (64) +
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// + Transmit Timestamp (64) +
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// . .
|
||||||
|
// . Extension Field 1 (variable) .
|
||||||
|
// . .
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// . .
|
||||||
|
// . Extension Field 2 (variable) .
|
||||||
|
// . .
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Key Identifier |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// | dgst (128) |
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// From http://www.ietf.org/rfc/rfc5905.txt
|
||||||
|
//
|
||||||
|
// The fields "Extension Field 1 (variable)" and later are optional fields,
|
||||||
|
// and so we can set a minimum NTP record size of 48 bytes.
|
||||||
|
//
|
||||||
|
const ntpMinimumRecordSizeInBytes int = 48
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// NTP Type
|
||||||
|
// --------
|
||||||
|
// Type NTP implements the DecodingLayer interface. Each NTP object
|
||||||
|
// represents in a structured form the NTP record present as the UDP
|
||||||
|
// payload in an NTP UDP packet.
|
||||||
|
//
|
||||||
|
|
||||||
|
type NTPLeapIndicator uint8
|
||||||
|
type NTPVersion uint8
|
||||||
|
type NTPMode uint8
|
||||||
|
type NTPStratum uint8
|
||||||
|
type NTPLog2Seconds int8
|
||||||
|
type NTPFixed16Seconds uint32
|
||||||
|
type NTPReferenceID uint32
|
||||||
|
type NTPTimestamp uint64
|
||||||
|
|
||||||
|
type NTP struct {
|
||||||
|
BaseLayer // Stores the packet bytes and payload bytes.
|
||||||
|
|
||||||
|
LeapIndicator NTPLeapIndicator // [0,3]. Indicates whether leap second(s) is to be added.
|
||||||
|
Version NTPVersion // [0,7]. Version of the NTP protocol.
|
||||||
|
Mode NTPMode // [0,7]. Mode.
|
||||||
|
Stratum NTPStratum // [0,255]. Stratum of time server in the server tree.
|
||||||
|
Poll NTPLog2Seconds // [-128,127]. The maximum interval between successive messages, in log2 seconds.
|
||||||
|
Precision NTPLog2Seconds // [-128,127]. The precision of the system clock, in log2 seconds.
|
||||||
|
RootDelay NTPFixed16Seconds // [0,2^32-1]. Total round trip delay to the reference clock in seconds times 2^16.
|
||||||
|
RootDispersion NTPFixed16Seconds // [0,2^32-1]. Total dispersion to the reference clock, in seconds times 2^16.
|
||||||
|
ReferenceID NTPReferenceID // ID code of reference clock [0,2^32-1].
|
||||||
|
ReferenceTimestamp NTPTimestamp // Most recent timestamp from the reference clock.
|
||||||
|
OriginTimestamp NTPTimestamp // Local time when request was sent from local host.
|
||||||
|
ReceiveTimestamp NTPTimestamp // Local time (on server) that request arrived at server host.
|
||||||
|
TransmitTimestamp NTPTimestamp // Local time (on server) that request departed server host.
|
||||||
|
|
||||||
|
// FIX: This package should analyse the extension fields and represent the extension fields too.
|
||||||
|
ExtensionBytes []byte // Just put extensions in a byte slice.
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// LayerType returns the layer type of the NTP object, which is LayerTypeNTP.
|
||||||
|
func (d *NTP) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeNTP
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// decodeNTP analyses a byte slice and attempts to decode it as an NTP
|
||||||
|
// record of a UDP packet.
|
||||||
|
//
|
||||||
|
// If it succeeds, it loads p with information about the packet and returns nil.
|
||||||
|
// If it fails, it returns an error (non nil).
|
||||||
|
//
|
||||||
|
// This function is employed in layertypes.go to register the NTP layer.
|
||||||
|
func decodeNTP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
|
||||||
|
// Attempt to decode the byte slice.
|
||||||
|
d := &NTP{}
|
||||||
|
err := d.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the decoding worked, add the layer to the packet and set it
|
||||||
|
// as the application layer too, if there isn't already one.
|
||||||
|
p.AddLayer(d)
|
||||||
|
p.SetApplicationLayer(d)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// DecodeFromBytes analyses a byte slice and attempts to decode it as an NTP
|
||||||
|
// record of a UDP packet.
|
||||||
|
//
|
||||||
|
// Upon succeeds, it loads the NTP object with information about the packet
|
||||||
|
// and returns nil.
|
||||||
|
// Upon failure, it returns an error (non nil).
|
||||||
|
func (d *NTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
|
||||||
|
// If the data block is too short to be a NTP record, then return an error.
|
||||||
|
if len(data) < ntpMinimumRecordSizeInBytes {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("NTP packet too short")
|
||||||
|
}
|
||||||
|
|
||||||
|
// RFC 5905 does not appear to define a maximum NTP record length.
|
||||||
|
// The protocol allows "extension fields" to be included in the record,
|
||||||
|
// and states about these fields:"
|
||||||
|
//
|
||||||
|
// "While the minimum field length containing required fields is
|
||||||
|
// four words (16 octets), a maximum field length remains to be
|
||||||
|
// established."
|
||||||
|
//
|
||||||
|
// For this reason, the packet length is not checked here for being too long.
|
||||||
|
|
||||||
|
// NTP type embeds type BaseLayer which contains two fields:
|
||||||
|
// Contents is supposed to contain the bytes of the data at this level.
|
||||||
|
// Payload is supposed to contain the payload of this level.
|
||||||
|
// Here we set the baselayer to be the bytes of the NTP record.
|
||||||
|
d.BaseLayer = BaseLayer{Contents: data[:len(data)]}
|
||||||
|
|
||||||
|
// Extract the fields from the block of bytes.
|
||||||
|
// To make sense of this, refer to the packet diagram
|
||||||
|
// above and the section on endian conventions.
|
||||||
|
|
||||||
|
// The first few fields are all packed into the first 32 bits. Unpack them.
|
||||||
|
f := data[0]
|
||||||
|
d.LeapIndicator = NTPLeapIndicator((f & 0xC0) >> 6)
|
||||||
|
d.Version = NTPVersion((f & 0x38) >> 3)
|
||||||
|
d.Mode = NTPMode(f & 0x07)
|
||||||
|
d.Stratum = NTPStratum(data[1])
|
||||||
|
d.Poll = NTPLog2Seconds(data[2])
|
||||||
|
d.Precision = NTPLog2Seconds(data[3])
|
||||||
|
|
||||||
|
// The remaining fields can just be copied in big endian order.
|
||||||
|
d.RootDelay = NTPFixed16Seconds(binary.BigEndian.Uint32(data[4:8]))
|
||||||
|
d.RootDispersion = NTPFixed16Seconds(binary.BigEndian.Uint32(data[8:12]))
|
||||||
|
d.ReferenceID = NTPReferenceID(binary.BigEndian.Uint32(data[12:16]))
|
||||||
|
d.ReferenceTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[16:24]))
|
||||||
|
d.OriginTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[24:32]))
|
||||||
|
d.ReceiveTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[32:40]))
|
||||||
|
d.TransmitTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[40:48]))
|
||||||
|
|
||||||
|
// This layer does not attempt to analyse the extension bytes.
|
||||||
|
// But if there are any, we'd like the user to know. So we just
|
||||||
|
// place them all in an ExtensionBytes field.
|
||||||
|
d.ExtensionBytes = data[48:]
|
||||||
|
|
||||||
|
// Return no error.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (d *NTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
data, err := b.PrependBytes(ntpMinimumRecordSizeInBytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pack the first few fields into the first 32 bits.
|
||||||
|
h := uint8(0)
|
||||||
|
h |= (uint8(d.LeapIndicator) << 6) & 0xC0
|
||||||
|
h |= (uint8(d.Version) << 3) & 0x38
|
||||||
|
h |= (uint8(d.Mode)) & 0x07
|
||||||
|
data[0] = byte(h)
|
||||||
|
data[1] = byte(d.Stratum)
|
||||||
|
data[2] = byte(d.Poll)
|
||||||
|
data[3] = byte(d.Precision)
|
||||||
|
|
||||||
|
// The remaining fields can just be copied in big endian order.
|
||||||
|
binary.BigEndian.PutUint32(data[4:8], uint32(d.RootDelay))
|
||||||
|
binary.BigEndian.PutUint32(data[8:12], uint32(d.RootDispersion))
|
||||||
|
binary.BigEndian.PutUint32(data[12:16], uint32(d.ReferenceID))
|
||||||
|
binary.BigEndian.PutUint64(data[16:24], uint64(d.ReferenceTimestamp))
|
||||||
|
binary.BigEndian.PutUint64(data[24:32], uint64(d.OriginTimestamp))
|
||||||
|
binary.BigEndian.PutUint64(data[32:40], uint64(d.ReceiveTimestamp))
|
||||||
|
binary.BigEndian.PutUint64(data[40:48], uint64(d.TransmitTimestamp))
|
||||||
|
|
||||||
|
ex, err := b.AppendBytes(len(d.ExtensionBytes))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
copy(ex, d.ExtensionBytes)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// CanDecode returns a set of layers that NTP objects can decode.
|
||||||
|
// As NTP objects can only decide the NTP layer, we can return just that layer.
|
||||||
|
// Apparently a single layer type implements LayerClass.
|
||||||
|
func (d *NTP) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeNTP
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// NextLayerType specifies the next layer that GoPacket should attempt to
|
||||||
|
// analyse after this (NTP) layer. As NTP packets do not contain any payload
|
||||||
|
// bytes, there are no further layers to analyse.
|
||||||
|
func (d *NTP) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
// NTP packets do not carry any data payload, so the empty byte slice is retured.
|
||||||
|
// In Go, a nil slice is functionally identical to an empty slice, so we
|
||||||
|
// return nil to avoid a heap allocation.
|
||||||
|
func (d *NTP) Payload() []byte {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
//* End Of NTP File *
|
||||||
|
//******************************************************************************
|
715
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ospf.go
generated
vendored
Normal file
715
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ospf.go
generated
vendored
Normal file
|
@ -0,0 +1,715 @@
|
||||||
|
// Copyright 2017 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OSPFType denotes what kind of OSPF type it is
|
||||||
|
type OSPFType uint8
|
||||||
|
|
||||||
|
// Potential values for OSPF.Type.
|
||||||
|
const (
|
||||||
|
OSPFHello OSPFType = 1
|
||||||
|
OSPFDatabaseDescription OSPFType = 2
|
||||||
|
OSPFLinkStateRequest OSPFType = 3
|
||||||
|
OSPFLinkStateUpdate OSPFType = 4
|
||||||
|
OSPFLinkStateAcknowledgment OSPFType = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
// LSA Function Codes for LSAheader.LSType
|
||||||
|
const (
|
||||||
|
RouterLSAtypeV2 = 0x1
|
||||||
|
RouterLSAtype = 0x2001
|
||||||
|
NetworkLSAtypeV2 = 0x2
|
||||||
|
NetworkLSAtype = 0x2002
|
||||||
|
SummaryLSANetworktypeV2 = 0x3
|
||||||
|
InterAreaPrefixLSAtype = 0x2003
|
||||||
|
SummaryLSAASBRtypeV2 = 0x4
|
||||||
|
InterAreaRouterLSAtype = 0x2004
|
||||||
|
ASExternalLSAtypeV2 = 0x5
|
||||||
|
ASExternalLSAtype = 0x4005
|
||||||
|
NSSALSAtype = 0x2007
|
||||||
|
NSSALSAtypeV2 = 0x7
|
||||||
|
LinkLSAtype = 0x0008
|
||||||
|
IntraAreaPrefixLSAtype = 0x2009
|
||||||
|
)
|
||||||
|
|
||||||
|
// String conversions for OSPFType
|
||||||
|
func (i OSPFType) String() string {
|
||||||
|
switch i {
|
||||||
|
case OSPFHello:
|
||||||
|
return "Hello"
|
||||||
|
case OSPFDatabaseDescription:
|
||||||
|
return "Database Description"
|
||||||
|
case OSPFLinkStateRequest:
|
||||||
|
return "Link State Request"
|
||||||
|
case OSPFLinkStateUpdate:
|
||||||
|
return "Link State Update"
|
||||||
|
case OSPFLinkStateAcknowledgment:
|
||||||
|
return "Link State Acknowledgment"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefix extends IntraAreaPrefixLSA
|
||||||
|
type Prefix struct {
|
||||||
|
PrefixLength uint8
|
||||||
|
PrefixOptions uint8
|
||||||
|
Metric uint16
|
||||||
|
AddressPrefix []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntraAreaPrefixLSA is the struct from RFC 5340 A.4.10.
|
||||||
|
type IntraAreaPrefixLSA struct {
|
||||||
|
NumOfPrefixes uint16
|
||||||
|
RefLSType uint16
|
||||||
|
RefLinkStateID uint32
|
||||||
|
RefAdvRouter uint32
|
||||||
|
Prefixes []Prefix
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkLSA is the struct from RFC 5340 A.4.9.
|
||||||
|
type LinkLSA struct {
|
||||||
|
RtrPriority uint8
|
||||||
|
Options uint32
|
||||||
|
LinkLocalAddress []byte
|
||||||
|
NumOfPrefixes uint32
|
||||||
|
Prefixes []Prefix
|
||||||
|
}
|
||||||
|
|
||||||
|
// ASExternalLSAV2 is the struct from RFC 2328 A.4.5.
|
||||||
|
type ASExternalLSAV2 struct {
|
||||||
|
NetworkMask uint32
|
||||||
|
ExternalBit uint8
|
||||||
|
Metric uint32
|
||||||
|
ForwardingAddress uint32
|
||||||
|
ExternalRouteTag uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// ASExternalLSA is the struct from RFC 5340 A.4.7.
|
||||||
|
type ASExternalLSA struct {
|
||||||
|
Flags uint8
|
||||||
|
Metric uint32
|
||||||
|
PrefixLength uint8
|
||||||
|
PrefixOptions uint8
|
||||||
|
RefLSType uint16
|
||||||
|
AddressPrefix []byte
|
||||||
|
ForwardingAddress []byte
|
||||||
|
ExternalRouteTag uint32
|
||||||
|
RefLinkStateID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// InterAreaRouterLSA is the struct from RFC 5340 A.4.6.
|
||||||
|
type InterAreaRouterLSA struct {
|
||||||
|
Options uint32
|
||||||
|
Metric uint32
|
||||||
|
DestinationRouterID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// InterAreaPrefixLSA is the struct from RFC 5340 A.4.5.
|
||||||
|
type InterAreaPrefixLSA struct {
|
||||||
|
Metric uint32
|
||||||
|
PrefixLength uint8
|
||||||
|
PrefixOptions uint8
|
||||||
|
AddressPrefix []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkLSA is the struct from RFC 5340 A.4.4.
|
||||||
|
type NetworkLSA struct {
|
||||||
|
Options uint32
|
||||||
|
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
|
||||||
|
LinkID uint32
|
||||||
|
LinkData uint32
|
||||||
|
Metric uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouterLSAV2 is the struct from RFC 2328 A.4.2.
|
||||||
|
type RouterLSAV2 struct {
|
||||||
|
Flags uint8
|
||||||
|
Links uint16
|
||||||
|
Routers []RouterV2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Router extends RouterLSA
|
||||||
|
type Router struct {
|
||||||
|
Type uint8
|
||||||
|
Metric uint16
|
||||||
|
InterfaceID uint32
|
||||||
|
NeighborInterfaceID uint32
|
||||||
|
NeighborRouterID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouterLSA is the struct from RFC 5340 A.4.3.
|
||||||
|
type RouterLSA struct {
|
||||||
|
Flags uint8
|
||||||
|
Options uint32
|
||||||
|
Routers []Router
|
||||||
|
}
|
||||||
|
|
||||||
|
// LSAheader is the struct from RFC 5340 A.4.2 and RFC 2328 A.4.1.
|
||||||
|
type LSAheader struct {
|
||||||
|
LSAge uint16
|
||||||
|
LSType uint16
|
||||||
|
LinkStateID uint32
|
||||||
|
AdvRouter uint32
|
||||||
|
LSSeqNumber uint32
|
||||||
|
LSChecksum uint16
|
||||||
|
Length uint16
|
||||||
|
LSOptions uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// LSA links LSAheader with the structs from RFC 5340 A.4.
|
||||||
|
type LSA struct {
|
||||||
|
LSAheader
|
||||||
|
Content interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LSUpdate is the struct from RFC 5340 A.3.5.
|
||||||
|
type LSUpdate struct {
|
||||||
|
NumOfLSAs uint32
|
||||||
|
LSAs []LSA
|
||||||
|
}
|
||||||
|
|
||||||
|
// LSReq is the struct from RFC 5340 A.3.4.
|
||||||
|
type LSReq struct {
|
||||||
|
LSType uint16
|
||||||
|
LSID uint32
|
||||||
|
AdvRouter uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// DbDescPkg is the struct from RFC 5340 A.3.3.
|
||||||
|
type DbDescPkg struct {
|
||||||
|
Options uint32
|
||||||
|
InterfaceMTU uint16
|
||||||
|
Flags uint16
|
||||||
|
DDSeqNumber uint32
|
||||||
|
LSAinfo []LSAheader
|
||||||
|
}
|
||||||
|
|
||||||
|
// HelloPkg is the struct from RFC 5340 A.3.2.
|
||||||
|
type HelloPkg struct {
|
||||||
|
InterfaceID uint32
|
||||||
|
RtrPriority uint8
|
||||||
|
Options uint32
|
||||||
|
HelloInterval uint16
|
||||||
|
RouterDeadInterval uint32
|
||||||
|
DesignatedRouterID uint32
|
||||||
|
BackupDesignatedRouterID uint32
|
||||||
|
NeighborID []uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// HelloPkgV2 extends the HelloPkg struct with OSPFv2 information
|
||||||
|
type HelloPkgV2 struct {
|
||||||
|
HelloPkg
|
||||||
|
NetworkMask uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// OSPF is a basic OSPF packet header with common fields of Version 2 and Version 3.
|
||||||
|
type OSPF struct {
|
||||||
|
Version uint8
|
||||||
|
Type OSPFType
|
||||||
|
PacketLength uint16
|
||||||
|
RouterID uint32
|
||||||
|
AreaID uint32
|
||||||
|
Checksum uint16
|
||||||
|
Content interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
//OSPFv2 extend the OSPF head with version 2 specific fields
|
||||||
|
type OSPFv2 struct {
|
||||||
|
BaseLayer
|
||||||
|
OSPF
|
||||||
|
AuType uint16
|
||||||
|
Authentication uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// OSPFv3 extend the OSPF head with version 3 specific fields
|
||||||
|
type OSPFv3 struct {
|
||||||
|
BaseLayer
|
||||||
|
OSPF
|
||||||
|
Instance uint8
|
||||||
|
Reserved uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// getLSAsv2 parses the LSA information from the packet for OSPFv2
|
||||||
|
func getLSAsv2(num uint32, data []byte) ([]LSA, error) {
|
||||||
|
var lsas []LSA
|
||||||
|
var i uint32 = 0
|
||||||
|
var offset uint32 = 0
|
||||||
|
for ; i < num; i++ {
|
||||||
|
lstype := uint16(data[offset+3])
|
||||||
|
lsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20])
|
||||||
|
content, err := extractLSAInformation(lstype, lsalength, data[offset:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Could not extract Link State type.")
|
||||||
|
}
|
||||||
|
lsa := LSA{
|
||||||
|
LSAheader: LSAheader{
|
||||||
|
LSAge: binary.BigEndian.Uint16(data[offset : offset+2]),
|
||||||
|
LSOptions: data[offset+2],
|
||||||
|
LSType: lstype,
|
||||||
|
LinkStateID: binary.BigEndian.Uint32(data[offset+4 : offset+8]),
|
||||||
|
AdvRouter: binary.BigEndian.Uint32(data[offset+8 : offset+12]),
|
||||||
|
LSSeqNumber: binary.BigEndian.Uint32(data[offset+12 : offset+16]),
|
||||||
|
LSChecksum: binary.BigEndian.Uint16(data[offset+16 : offset+18]),
|
||||||
|
Length: lsalength,
|
||||||
|
},
|
||||||
|
Content: content,
|
||||||
|
}
|
||||||
|
lsas = append(lsas, lsa)
|
||||||
|
offset += uint32(lsalength)
|
||||||
|
}
|
||||||
|
return lsas, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractLSAInformation extracts all the LSA information
|
||||||
|
func extractLSAInformation(lstype, lsalength uint16, data []byte) (interface{}, error) {
|
||||||
|
if lsalength < 20 {
|
||||||
|
return nil, fmt.Errorf("Link State header length %v too short, %v required", lsalength, 20)
|
||||||
|
}
|
||||||
|
if len(data) < int(lsalength) {
|
||||||
|
return nil, fmt.Errorf("Link State header length %v too short, %v required", len(data), lsalength)
|
||||||
|
}
|
||||||
|
var content interface{}
|
||||||
|
switch lstype {
|
||||||
|
case RouterLSAtypeV2:
|
||||||
|
var routers []RouterV2
|
||||||
|
var j uint32
|
||||||
|
for j = 24; j < uint32(lsalength); j += 12 {
|
||||||
|
if len(data) < int(j+12) {
|
||||||
|
return nil, errors.New("LSAtypeV2 too small")
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
if len(data) < 24 {
|
||||||
|
return nil, errors.New("LSAtypeV2 too small")
|
||||||
|
}
|
||||||
|
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]),
|
||||||
|
ExternalBit: data[24] & 0x80,
|
||||||
|
Metric: binary.BigEndian.Uint32(data[24:28]) & 0x00FFFFFF,
|
||||||
|
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
|
||||||
|
for j = 24; j < uint32(lsalength); j += 16 {
|
||||||
|
router := Router{
|
||||||
|
Type: uint8(data[j]),
|
||||||
|
Metric: binary.BigEndian.Uint16(data[j+2 : j+4]),
|
||||||
|
InterfaceID: binary.BigEndian.Uint32(data[j+4 : j+8]),
|
||||||
|
NeighborInterfaceID: binary.BigEndian.Uint32(data[j+8 : j+12]),
|
||||||
|
NeighborRouterID: binary.BigEndian.Uint32(data[j+12 : j+16]),
|
||||||
|
}
|
||||||
|
routers = append(routers, router)
|
||||||
|
}
|
||||||
|
content = RouterLSA{
|
||||||
|
Flags: uint8(data[20]),
|
||||||
|
Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||||
|
Routers: routers,
|
||||||
|
}
|
||||||
|
case NetworkLSAtype:
|
||||||
|
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 = NetworkLSA{
|
||||||
|
Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||||
|
AttachedRouter: routers,
|
||||||
|
}
|
||||||
|
case InterAreaPrefixLSAtype:
|
||||||
|
content = InterAreaPrefixLSA{
|
||||||
|
Metric: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||||
|
PrefixLength: uint8(data[24]),
|
||||||
|
PrefixOptions: uint8(data[25]),
|
||||||
|
AddressPrefix: data[28:uint32(lsalength)],
|
||||||
|
}
|
||||||
|
case InterAreaRouterLSAtype:
|
||||||
|
content = InterAreaRouterLSA{
|
||||||
|
Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||||
|
Metric: binary.BigEndian.Uint32(data[24:28]) & 0x00FFFFFF,
|
||||||
|
DestinationRouterID: binary.BigEndian.Uint32(data[28:32]),
|
||||||
|
}
|
||||||
|
case ASExternalLSAtype:
|
||||||
|
fallthrough
|
||||||
|
case NSSALSAtype:
|
||||||
|
flags := uint8(data[20])
|
||||||
|
prefixLen := uint8(data[24]) / 8
|
||||||
|
var forwardingAddress []byte
|
||||||
|
if (flags & 0x02) == 0x02 {
|
||||||
|
forwardingAddress = data[28+uint32(prefixLen) : 28+uint32(prefixLen)+16]
|
||||||
|
}
|
||||||
|
content = ASExternalLSA{
|
||||||
|
Flags: flags,
|
||||||
|
Metric: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||||
|
PrefixLength: prefixLen,
|
||||||
|
PrefixOptions: uint8(data[25]),
|
||||||
|
RefLSType: binary.BigEndian.Uint16(data[26:28]),
|
||||||
|
AddressPrefix: data[28 : 28+uint32(prefixLen)],
|
||||||
|
ForwardingAddress: forwardingAddress,
|
||||||
|
}
|
||||||
|
case LinkLSAtype:
|
||||||
|
var prefixes []Prefix
|
||||||
|
var prefixOffset uint32 = 44
|
||||||
|
var j uint32
|
||||||
|
numOfPrefixes := binary.BigEndian.Uint32(data[40:44])
|
||||||
|
for j = 0; j < numOfPrefixes; j++ {
|
||||||
|
prefixLen := uint8(data[prefixOffset])
|
||||||
|
prefix := Prefix{
|
||||||
|
PrefixLength: prefixLen,
|
||||||
|
PrefixOptions: uint8(data[prefixOffset+1]),
|
||||||
|
AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8],
|
||||||
|
}
|
||||||
|
prefixes = append(prefixes, prefix)
|
||||||
|
prefixOffset = prefixOffset + 4 + uint32(prefixLen)/8
|
||||||
|
}
|
||||||
|
content = LinkLSA{
|
||||||
|
RtrPriority: uint8(data[20]),
|
||||||
|
Options: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,
|
||||||
|
LinkLocalAddress: data[24:40],
|
||||||
|
NumOfPrefixes: numOfPrefixes,
|
||||||
|
Prefixes: prefixes,
|
||||||
|
}
|
||||||
|
case IntraAreaPrefixLSAtype:
|
||||||
|
var prefixes []Prefix
|
||||||
|
var prefixOffset uint32 = 32
|
||||||
|
var j uint16
|
||||||
|
numOfPrefixes := binary.BigEndian.Uint16(data[20:22])
|
||||||
|
for j = 0; j < numOfPrefixes; j++ {
|
||||||
|
prefixLen := uint8(data[prefixOffset])
|
||||||
|
prefix := Prefix{
|
||||||
|
PrefixLength: prefixLen,
|
||||||
|
PrefixOptions: uint8(data[prefixOffset+1]),
|
||||||
|
Metric: binary.BigEndian.Uint16(data[prefixOffset+2 : prefixOffset+4]),
|
||||||
|
AddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8],
|
||||||
|
}
|
||||||
|
prefixes = append(prefixes, prefix)
|
||||||
|
prefixOffset = prefixOffset + 4 + uint32(prefixLen)
|
||||||
|
}
|
||||||
|
content = IntraAreaPrefixLSA{
|
||||||
|
NumOfPrefixes: numOfPrefixes,
|
||||||
|
RefLSType: binary.BigEndian.Uint16(data[22:24]),
|
||||||
|
RefLinkStateID: binary.BigEndian.Uint32(data[24:28]),
|
||||||
|
RefAdvRouter: binary.BigEndian.Uint32(data[28:32]),
|
||||||
|
Prefixes: prefixes,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Unknown Link State type.")
|
||||||
|
}
|
||||||
|
return content, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getLSAs parses the LSA information from the packet for OSPFv3
|
||||||
|
func getLSAs(num uint32, data []byte) ([]LSA, error) {
|
||||||
|
var lsas []LSA
|
||||||
|
var i uint32 = 0
|
||||||
|
var offset uint32 = 0
|
||||||
|
for ; i < num; i++ {
|
||||||
|
var content interface{}
|
||||||
|
lstype := binary.BigEndian.Uint16(data[offset+2 : offset+4])
|
||||||
|
lsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20])
|
||||||
|
|
||||||
|
content, err := extractLSAInformation(lstype, lsalength, data[offset:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Could not extract Link State type.")
|
||||||
|
}
|
||||||
|
lsa := LSA{
|
||||||
|
LSAheader: LSAheader{
|
||||||
|
LSAge: binary.BigEndian.Uint16(data[offset : offset+2]),
|
||||||
|
LSType: lstype,
|
||||||
|
LinkStateID: binary.BigEndian.Uint32(data[offset+4 : offset+8]),
|
||||||
|
AdvRouter: binary.BigEndian.Uint32(data[offset+8 : offset+12]),
|
||||||
|
LSSeqNumber: binary.BigEndian.Uint32(data[offset+12 : offset+16]),
|
||||||
|
LSChecksum: binary.BigEndian.Uint16(data[offset+16 : offset+18]),
|
||||||
|
Length: lsalength,
|
||||||
|
},
|
||||||
|
Content: content,
|
||||||
|
}
|
||||||
|
lsas = append(lsas, lsa)
|
||||||
|
offset += uint32(lsalength)
|
||||||
|
}
|
||||||
|
return lsas, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into the OSPF layer.
|
||||||
|
func (ospf *OSPFv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 24 {
|
||||||
|
return fmt.Errorf("Packet too smal for OSPF Version 2")
|
||||||
|
}
|
||||||
|
|
||||||
|
ospf.Version = uint8(data[0])
|
||||||
|
ospf.Type = OSPFType(data[1])
|
||||||
|
ospf.PacketLength = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
ospf.RouterID = binary.BigEndian.Uint32(data[4:8])
|
||||||
|
ospf.AreaID = binary.BigEndian.Uint32(data[8:12])
|
||||||
|
ospf.Checksum = binary.BigEndian.Uint16(data[12:14])
|
||||||
|
ospf.AuType = binary.BigEndian.Uint16(data[14:16])
|
||||||
|
ospf.Authentication = binary.BigEndian.Uint64(data[16:24])
|
||||||
|
|
||||||
|
switch ospf.Type {
|
||||||
|
case OSPFHello:
|
||||||
|
var neighbors []uint32
|
||||||
|
for i := 44; uint16(i+4) <= ospf.PacketLength; i += 4 {
|
||||||
|
neighbors = append(neighbors, binary.BigEndian.Uint32(data[i:i+4]))
|
||||||
|
}
|
||||||
|
ospf.Content = HelloPkgV2{
|
||||||
|
NetworkMask: binary.BigEndian.Uint32(data[24:28]),
|
||||||
|
HelloPkg: HelloPkg{
|
||||||
|
HelloInterval: binary.BigEndian.Uint16(data[28:30]),
|
||||||
|
Options: uint32(data[30]),
|
||||||
|
RtrPriority: uint8(data[31]),
|
||||||
|
RouterDeadInterval: binary.BigEndian.Uint32(data[32:36]),
|
||||||
|
DesignatedRouterID: binary.BigEndian.Uint32(data[36:40]),
|
||||||
|
BackupDesignatedRouterID: binary.BigEndian.Uint32(data[40:44]),
|
||||||
|
NeighborID: neighbors,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
case OSPFDatabaseDescription:
|
||||||
|
var lsas []LSAheader
|
||||||
|
for i := 32; uint16(i+20) <= ospf.PacketLength; i += 20 {
|
||||||
|
lsa := LSAheader{
|
||||||
|
LSAge: binary.BigEndian.Uint16(data[i : i+2]),
|
||||||
|
LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
|
||||||
|
LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||||
|
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||||
|
LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
|
||||||
|
LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
|
||||||
|
Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
|
||||||
|
}
|
||||||
|
lsas = append(lsas, lsa)
|
||||||
|
}
|
||||||
|
ospf.Content = DbDescPkg{
|
||||||
|
InterfaceMTU: binary.BigEndian.Uint16(data[24:26]),
|
||||||
|
Options: uint32(data[26]),
|
||||||
|
Flags: uint16(data[27]),
|
||||||
|
DDSeqNumber: binary.BigEndian.Uint32(data[28:32]),
|
||||||
|
LSAinfo: lsas,
|
||||||
|
}
|
||||||
|
case OSPFLinkStateRequest:
|
||||||
|
var lsrs []LSReq
|
||||||
|
for i := 24; uint16(i+12) <= ospf.PacketLength; i += 12 {
|
||||||
|
lsr := LSReq{
|
||||||
|
LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
|
||||||
|
LSID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||||
|
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||||
|
}
|
||||||
|
lsrs = append(lsrs, lsr)
|
||||||
|
}
|
||||||
|
ospf.Content = lsrs
|
||||||
|
case OSPFLinkStateUpdate:
|
||||||
|
num := binary.BigEndian.Uint32(data[24:28])
|
||||||
|
|
||||||
|
lsas, err := getLSAsv2(num, data[28:])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Cannot parse Link State Update packet: %v", err)
|
||||||
|
}
|
||||||
|
ospf.Content = LSUpdate{
|
||||||
|
NumOfLSAs: num,
|
||||||
|
LSAs: lsas,
|
||||||
|
}
|
||||||
|
case OSPFLinkStateAcknowledgment:
|
||||||
|
var lsas []LSAheader
|
||||||
|
for i := 24; uint16(i+20) <= ospf.PacketLength; i += 20 {
|
||||||
|
lsa := LSAheader{
|
||||||
|
LSAge: binary.BigEndian.Uint16(data[i : i+2]),
|
||||||
|
LSOptions: data[i+2],
|
||||||
|
LSType: uint16(data[i+3]),
|
||||||
|
LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||||
|
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||||
|
LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
|
||||||
|
LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
|
||||||
|
Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
|
||||||
|
}
|
||||||
|
lsas = append(lsas, lsa)
|
||||||
|
}
|
||||||
|
ospf.Content = lsas
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into the OSPF layer.
|
||||||
|
func (ospf *OSPFv3) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
|
||||||
|
if len(data) < 16 {
|
||||||
|
return fmt.Errorf("Packet too smal for OSPF Version 3")
|
||||||
|
}
|
||||||
|
|
||||||
|
ospf.Version = uint8(data[0])
|
||||||
|
ospf.Type = OSPFType(data[1])
|
||||||
|
ospf.PacketLength = binary.BigEndian.Uint16(data[2:4])
|
||||||
|
ospf.RouterID = binary.BigEndian.Uint32(data[4:8])
|
||||||
|
ospf.AreaID = binary.BigEndian.Uint32(data[8:12])
|
||||||
|
ospf.Checksum = binary.BigEndian.Uint16(data[12:14])
|
||||||
|
ospf.Instance = uint8(data[14])
|
||||||
|
ospf.Reserved = uint8(data[15])
|
||||||
|
|
||||||
|
switch ospf.Type {
|
||||||
|
case OSPFHello:
|
||||||
|
var neighbors []uint32
|
||||||
|
for i := 36; uint16(i+4) <= ospf.PacketLength; i += 4 {
|
||||||
|
neighbors = append(neighbors, binary.BigEndian.Uint32(data[i:i+4]))
|
||||||
|
}
|
||||||
|
ospf.Content = HelloPkg{
|
||||||
|
InterfaceID: binary.BigEndian.Uint32(data[16:20]),
|
||||||
|
RtrPriority: uint8(data[20]),
|
||||||
|
Options: binary.BigEndian.Uint32(data[21:25]) >> 8,
|
||||||
|
HelloInterval: binary.BigEndian.Uint16(data[24:26]),
|
||||||
|
RouterDeadInterval: uint32(binary.BigEndian.Uint16(data[26:28])),
|
||||||
|
DesignatedRouterID: binary.BigEndian.Uint32(data[28:32]),
|
||||||
|
BackupDesignatedRouterID: binary.BigEndian.Uint32(data[32:36]),
|
||||||
|
NeighborID: neighbors,
|
||||||
|
}
|
||||||
|
case OSPFDatabaseDescription:
|
||||||
|
var lsas []LSAheader
|
||||||
|
for i := 28; uint16(i+20) <= ospf.PacketLength; i += 20 {
|
||||||
|
lsa := LSAheader{
|
||||||
|
LSAge: binary.BigEndian.Uint16(data[i : i+2]),
|
||||||
|
LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
|
||||||
|
LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||||
|
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||||
|
LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
|
||||||
|
LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
|
||||||
|
Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
|
||||||
|
}
|
||||||
|
lsas = append(lsas, lsa)
|
||||||
|
}
|
||||||
|
ospf.Content = DbDescPkg{
|
||||||
|
Options: binary.BigEndian.Uint32(data[16:20]) & 0x00FFFFFF,
|
||||||
|
InterfaceMTU: binary.BigEndian.Uint16(data[20:22]),
|
||||||
|
Flags: binary.BigEndian.Uint16(data[22:24]),
|
||||||
|
DDSeqNumber: binary.BigEndian.Uint32(data[24:28]),
|
||||||
|
LSAinfo: lsas,
|
||||||
|
}
|
||||||
|
case OSPFLinkStateRequest:
|
||||||
|
var lsrs []LSReq
|
||||||
|
for i := 16; uint16(i+12) <= ospf.PacketLength; i += 12 {
|
||||||
|
lsr := LSReq{
|
||||||
|
LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
|
||||||
|
LSID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||||
|
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||||
|
}
|
||||||
|
lsrs = append(lsrs, lsr)
|
||||||
|
}
|
||||||
|
ospf.Content = lsrs
|
||||||
|
case OSPFLinkStateUpdate:
|
||||||
|
num := binary.BigEndian.Uint32(data[16:20])
|
||||||
|
lsas, err := getLSAs(num, data[20:])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Cannot parse Link State Update packet: %v", err)
|
||||||
|
}
|
||||||
|
ospf.Content = LSUpdate{
|
||||||
|
NumOfLSAs: num,
|
||||||
|
LSAs: lsas,
|
||||||
|
}
|
||||||
|
|
||||||
|
case OSPFLinkStateAcknowledgment:
|
||||||
|
var lsas []LSAheader
|
||||||
|
for i := 16; uint16(i+20) <= ospf.PacketLength; i += 20 {
|
||||||
|
lsa := LSAheader{
|
||||||
|
LSAge: binary.BigEndian.Uint16(data[i : i+2]),
|
||||||
|
LSType: binary.BigEndian.Uint16(data[i+2 : i+4]),
|
||||||
|
LinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),
|
||||||
|
AdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),
|
||||||
|
LSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),
|
||||||
|
LSChecksum: binary.BigEndian.Uint16(data[i+16 : i+18]),
|
||||||
|
Length: binary.BigEndian.Uint16(data[i+18 : i+20]),
|
||||||
|
}
|
||||||
|
lsas = append(lsas, lsa)
|
||||||
|
}
|
||||||
|
ospf.Content = lsas
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeOSPF
|
||||||
|
func (ospf *OSPFv2) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeOSPF
|
||||||
|
}
|
||||||
|
func (ospf *OSPFv3) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeOSPF
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (ospf *OSPFv2) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
func (ospf *OSPFv3) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (ospf *OSPFv2) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeOSPF
|
||||||
|
}
|
||||||
|
func (ospf *OSPFv3) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeOSPF
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeOSPF(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
if len(data) < 14 {
|
||||||
|
return fmt.Errorf("Packet too smal for OSPF")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch uint8(data[0]) {
|
||||||
|
case 2:
|
||||||
|
ospf := &OSPFv2{}
|
||||||
|
return decodingLayerDecoder(ospf, data, p)
|
||||||
|
case 3:
|
||||||
|
ospf := &OSPFv3{}
|
||||||
|
return decodingLayerDecoder(ospf, data, p)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("Unable to determine OSPF type.")
|
||||||
|
}
|
84
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/pflog.go
generated
vendored
Normal file
84
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/pflog.go
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PFDirection uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
PFDirectionInOut PFDirection = 0
|
||||||
|
PFDirectionIn PFDirection = 1
|
||||||
|
PFDirectionOut PFDirection = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// PFLog provides the layer for 'pf' packet-filter logging, as described at
|
||||||
|
// http://www.freebsd.org/cgi/man.cgi?query=pflog&sektion=4
|
||||||
|
type PFLog struct {
|
||||||
|
BaseLayer
|
||||||
|
Length uint8
|
||||||
|
Family ProtocolFamily
|
||||||
|
Action, Reason uint8
|
||||||
|
IFName, Ruleset []byte
|
||||||
|
RuleNum, SubruleNum uint32
|
||||||
|
UID uint32
|
||||||
|
PID int32
|
||||||
|
RuleUID uint32
|
||||||
|
RulePID int32
|
||||||
|
Direction PFDirection
|
||||||
|
// The remainder is padding
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pf *PFLog) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 60 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("PFLog data less than 60 bytes")
|
||||||
|
}
|
||||||
|
pf.Length = data[0]
|
||||||
|
pf.Family = ProtocolFamily(data[1])
|
||||||
|
pf.Action = data[2]
|
||||||
|
pf.Reason = data[3]
|
||||||
|
pf.IFName = data[4:20]
|
||||||
|
pf.Ruleset = data[20:36]
|
||||||
|
pf.RuleNum = binary.BigEndian.Uint32(data[36:40])
|
||||||
|
pf.SubruleNum = binary.BigEndian.Uint32(data[40:44])
|
||||||
|
pf.UID = binary.BigEndian.Uint32(data[44:48])
|
||||||
|
pf.PID = int32(binary.BigEndian.Uint32(data[48:52]))
|
||||||
|
pf.RuleUID = binary.BigEndian.Uint32(data[52:56])
|
||||||
|
pf.RulePID = int32(binary.BigEndian.Uint32(data[56:60]))
|
||||||
|
pf.Direction = PFDirection(data[60])
|
||||||
|
if pf.Length%4 != 1 {
|
||||||
|
return errors.New("PFLog header length should be 3 less than multiple of 4")
|
||||||
|
}
|
||||||
|
actualLength := int(pf.Length) + 3
|
||||||
|
if len(data) < actualLength {
|
||||||
|
return fmt.Errorf("PFLog data size < %d", actualLength)
|
||||||
|
}
|
||||||
|
pf.Contents = data[:actualLength]
|
||||||
|
pf.Payload = data[actualLength:]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns layers.LayerTypePFLog
|
||||||
|
func (pf *PFLog) LayerType() gopacket.LayerType { return LayerTypePFLog }
|
||||||
|
|
||||||
|
func (pf *PFLog) CanDecode() gopacket.LayerClass { return LayerTypePFLog }
|
||||||
|
|
||||||
|
func (pf *PFLog) NextLayerType() gopacket.LayerType {
|
||||||
|
return pf.Family.LayerType()
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodePFLog(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
pf := &PFLog{}
|
||||||
|
return decodingLayerDecoder(pf, data, p)
|
||||||
|
}
|
156
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ports.go
generated
vendored
Normal file
156
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ports.go
generated
vendored
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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 (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TCPPort is a port in a TCP layer.
|
||||||
|
type TCPPort uint16
|
||||||
|
|
||||||
|
// UDPPort is a port in a UDP layer.
|
||||||
|
type UDPPort uint16
|
||||||
|
|
||||||
|
// RUDPPort is a port in a RUDP layer.
|
||||||
|
type RUDPPort uint8
|
||||||
|
|
||||||
|
// SCTPPort is a port in a SCTP layer.
|
||||||
|
type SCTPPort uint16
|
||||||
|
|
||||||
|
// UDPLitePort is a port in a UDPLite layer.
|
||||||
|
type UDPLitePort uint16
|
||||||
|
|
||||||
|
// RUDPPortNames contains the string names for all RUDP ports.
|
||||||
|
var RUDPPortNames = map[RUDPPort]string{}
|
||||||
|
|
||||||
|
// UDPLitePortNames contains the string names for all UDPLite ports.
|
||||||
|
var UDPLitePortNames = map[UDPLitePort]string{}
|
||||||
|
|
||||||
|
// {TCP,UDP,SCTP}PortNames can be found in iana_ports.go
|
||||||
|
|
||||||
|
// String returns the port as "number(name)" if there's a well-known port name,
|
||||||
|
// or just "number" if there isn't. Well-known names are stored in
|
||||||
|
// TCPPortNames.
|
||||||
|
func (a TCPPort) String() string {
|
||||||
|
if name, ok := TCPPortNames[a]; ok {
|
||||||
|
return fmt.Sprintf("%d(%s)", a, name)
|
||||||
|
}
|
||||||
|
return strconv.Itoa(int(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns a LayerType that would be able to decode the
|
||||||
|
// application payload. It uses some well-known ports such as 53 for
|
||||||
|
// DNS.
|
||||||
|
//
|
||||||
|
// Returns gopacket.LayerTypePayload for unknown/unsupported port numbers.
|
||||||
|
func (a TCPPort) LayerType() gopacket.LayerType {
|
||||||
|
lt := tcpPortLayerType[uint16(a)]
|
||||||
|
if lt != 0 {
|
||||||
|
return lt
|
||||||
|
}
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
var tcpPortLayerType = [65536]gopacket.LayerType{
|
||||||
|
53: LayerTypeDNS,
|
||||||
|
443: LayerTypeTLS, // https
|
||||||
|
502: LayerTypeModbusTCP, // modbustcp
|
||||||
|
636: LayerTypeTLS, // ldaps
|
||||||
|
989: LayerTypeTLS, // ftps-data
|
||||||
|
990: LayerTypeTLS, // ftps
|
||||||
|
992: LayerTypeTLS, // telnets
|
||||||
|
993: LayerTypeTLS, // imaps
|
||||||
|
994: LayerTypeTLS, // ircs
|
||||||
|
995: LayerTypeTLS, // pop3s
|
||||||
|
5061: LayerTypeTLS, // ips
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterTCPPortLayerType creates a new mapping between a TCPPort
|
||||||
|
// and an underlaying LayerType.
|
||||||
|
func RegisterTCPPortLayerType(port TCPPort, layerType gopacket.LayerType) {
|
||||||
|
tcpPortLayerType[port] = layerType
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the port as "number(name)" if there's a well-known port name,
|
||||||
|
// or just "number" if there isn't. Well-known names are stored in
|
||||||
|
// UDPPortNames.
|
||||||
|
func (a UDPPort) String() string {
|
||||||
|
if name, ok := UDPPortNames[a]; ok {
|
||||||
|
return fmt.Sprintf("%d(%s)", a, name)
|
||||||
|
}
|
||||||
|
return strconv.Itoa(int(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns a LayerType that would be able to decode the
|
||||||
|
// application payload. It uses some well-known ports such as 53 for
|
||||||
|
// DNS.
|
||||||
|
//
|
||||||
|
// Returns gopacket.LayerTypePayload for unknown/unsupported port numbers.
|
||||||
|
func (a UDPPort) LayerType() gopacket.LayerType {
|
||||||
|
lt := udpPortLayerType[uint16(a)]
|
||||||
|
if lt != 0 {
|
||||||
|
return lt
|
||||||
|
}
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
var udpPortLayerType = [65536]gopacket.LayerType{
|
||||||
|
53: LayerTypeDNS,
|
||||||
|
123: LayerTypeNTP,
|
||||||
|
4789: LayerTypeVXLAN,
|
||||||
|
67: LayerTypeDHCPv4,
|
||||||
|
68: LayerTypeDHCPv4,
|
||||||
|
546: LayerTypeDHCPv6,
|
||||||
|
547: LayerTypeDHCPv6,
|
||||||
|
5060: LayerTypeSIP,
|
||||||
|
6343: LayerTypeSFlow,
|
||||||
|
6081: LayerTypeGeneve,
|
||||||
|
3784: LayerTypeBFD,
|
||||||
|
2152: LayerTypeGTPv1U,
|
||||||
|
623: LayerTypeRMCP,
|
||||||
|
1812: LayerTypeRADIUS,
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterUDPPortLayerType creates a new mapping between a UDPPort
|
||||||
|
// and an underlaying LayerType.
|
||||||
|
func RegisterUDPPortLayerType(port UDPPort, layerType gopacket.LayerType) {
|
||||||
|
udpPortLayerType[port] = layerType
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the port as "number(name)" if there's a well-known port name,
|
||||||
|
// or just "number" if there isn't. Well-known names are stored in
|
||||||
|
// RUDPPortNames.
|
||||||
|
func (a RUDPPort) String() string {
|
||||||
|
if name, ok := RUDPPortNames[a]; ok {
|
||||||
|
return fmt.Sprintf("%d(%s)", a, name)
|
||||||
|
}
|
||||||
|
return strconv.Itoa(int(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the port as "number(name)" if there's a well-known port name,
|
||||||
|
// or just "number" if there isn't. Well-known names are stored in
|
||||||
|
// SCTPPortNames.
|
||||||
|
func (a SCTPPort) String() string {
|
||||||
|
if name, ok := SCTPPortNames[a]; ok {
|
||||||
|
return fmt.Sprintf("%d(%s)", a, name)
|
||||||
|
}
|
||||||
|
return strconv.Itoa(int(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the port as "number(name)" if there's a well-known port name,
|
||||||
|
// or just "number" if there isn't. Well-known names are stored in
|
||||||
|
// UDPLitePortNames.
|
||||||
|
func (a UDPLitePort) String() string {
|
||||||
|
if name, ok := UDPLitePortNames[a]; ok {
|
||||||
|
return fmt.Sprintf("%d(%s)", a, name)
|
||||||
|
}
|
||||||
|
return strconv.Itoa(int(a))
|
||||||
|
}
|
88
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ppp.go
generated
vendored
Normal file
88
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/ppp.go
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PPP is the layer for PPP encapsulation headers.
|
||||||
|
type PPP struct {
|
||||||
|
BaseLayer
|
||||||
|
PPPType PPPType
|
||||||
|
HasPPTPHeader bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// PPPEndpoint is a singleton endpoint for PPP. Since there is no actual
|
||||||
|
// addressing for the two ends of a PPP connection, we use a singleton value
|
||||||
|
// named 'point' for each endpoint.
|
||||||
|
var PPPEndpoint = gopacket.NewEndpoint(EndpointPPP, nil)
|
||||||
|
|
||||||
|
// PPPFlow is a singleton flow for PPP. Since there is no actual addressing for
|
||||||
|
// the two ends of a PPP connection, we use a singleton value to represent the
|
||||||
|
// flow for all PPP connections.
|
||||||
|
var PPPFlow = gopacket.NewFlow(EndpointPPP, nil, nil)
|
||||||
|
|
||||||
|
// LayerType returns LayerTypePPP
|
||||||
|
func (p *PPP) LayerType() gopacket.LayerType { return LayerTypePPP }
|
||||||
|
|
||||||
|
// LinkFlow returns PPPFlow.
|
||||||
|
func (p *PPP) LinkFlow() gopacket.Flow { return PPPFlow }
|
||||||
|
|
||||||
|
func decodePPP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
ppp := &PPP{}
|
||||||
|
offset := 0
|
||||||
|
if data[0] == 0xff && data[1] == 0x03 {
|
||||||
|
offset = 2
|
||||||
|
ppp.HasPPTPHeader = true
|
||||||
|
}
|
||||||
|
if data[offset]&0x1 == 0 {
|
||||||
|
if data[offset+1]&0x1 == 0 {
|
||||||
|
return errors.New("PPP has invalid type")
|
||||||
|
}
|
||||||
|
ppp.PPPType = PPPType(binary.BigEndian.Uint16(data[offset : offset+2]))
|
||||||
|
ppp.Contents = data[offset : offset+2]
|
||||||
|
ppp.Payload = data[offset+2:]
|
||||||
|
} else {
|
||||||
|
ppp.PPPType = PPPType(data[offset])
|
||||||
|
ppp.Contents = data[offset : offset+1]
|
||||||
|
ppp.Payload = data[offset+1:]
|
||||||
|
}
|
||||||
|
p.AddLayer(ppp)
|
||||||
|
p.SetLinkLayer(ppp)
|
||||||
|
return p.NextDecoder(ppp.PPPType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (p *PPP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
if p.PPPType&0x100 == 0 {
|
||||||
|
bytes, err := b.PrependBytes(2)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes, uint16(p.PPPType))
|
||||||
|
} else {
|
||||||
|
bytes, err := b.PrependBytes(1)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(p.PPPType)
|
||||||
|
}
|
||||||
|
if p.HasPPTPHeader {
|
||||||
|
bytes, err := b.PrependBytes(2)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = 0xff
|
||||||
|
bytes[1] = 0x03
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
60
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/pppoe.go
generated
vendored
Normal file
60
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/pppoe.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PPPoE is the layer for PPPoE encapsulation headers.
|
||||||
|
type PPPoE struct {
|
||||||
|
BaseLayer
|
||||||
|
Version uint8
|
||||||
|
Type uint8
|
||||||
|
Code PPPoECode
|
||||||
|
SessionId uint16
|
||||||
|
Length uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypePPPoE.
|
||||||
|
func (p *PPPoE) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypePPPoE
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodePPPoE decodes the PPPoE header (see http://tools.ietf.org/html/rfc2516).
|
||||||
|
func decodePPPoE(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
pppoe := &PPPoE{
|
||||||
|
Version: data[0] >> 4,
|
||||||
|
Type: data[0] & 0x0F,
|
||||||
|
Code: PPPoECode(data[1]),
|
||||||
|
SessionId: binary.BigEndian.Uint16(data[2:4]),
|
||||||
|
Length: binary.BigEndian.Uint16(data[4:6]),
|
||||||
|
}
|
||||||
|
pppoe.BaseLayer = BaseLayer{data[:6], data[6 : 6+pppoe.Length]}
|
||||||
|
p.AddLayer(pppoe)
|
||||||
|
return p.NextDecoder(pppoe.Code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (p *PPPoE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
payload := b.Bytes()
|
||||||
|
bytes, err := b.PrependBytes(6)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = (p.Version << 4) | p.Type
|
||||||
|
bytes[1] = byte(p.Code)
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], p.SessionId)
|
||||||
|
if opts.FixLengths {
|
||||||
|
p.Length = uint16(len(payload))
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes[4:], p.Length)
|
||||||
|
return nil
|
||||||
|
}
|
146
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/prism.go
generated
vendored
Normal file
146
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/prism.go
generated
vendored
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
// Copyright 2015 Google, Inc. 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.
|
||||||
|
|
||||||
|
// http://www.tcpdump.org/linktypes/LINKTYPE_IEEE802_11_PRISM.html
|
||||||
|
|
||||||
|
package layers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func decodePrismValue(data []byte, pv *PrismValue) {
|
||||||
|
pv.DID = PrismDID(binary.LittleEndian.Uint32(data[0:4]))
|
||||||
|
pv.Status = binary.LittleEndian.Uint16(data[4:6])
|
||||||
|
pv.Length = binary.LittleEndian.Uint16(data[6:8])
|
||||||
|
pv.Data = data[8 : 8+pv.Length]
|
||||||
|
}
|
||||||
|
|
||||||
|
type PrismDID uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
PrismDIDType1HostTime PrismDID = 0x10044
|
||||||
|
PrismDIDType2HostTime PrismDID = 0x01041
|
||||||
|
PrismDIDType1MACTime PrismDID = 0x20044
|
||||||
|
PrismDIDType2MACTime PrismDID = 0x02041
|
||||||
|
PrismDIDType1Channel PrismDID = 0x30044
|
||||||
|
PrismDIDType2Channel PrismDID = 0x03041
|
||||||
|
PrismDIDType1RSSI PrismDID = 0x40044
|
||||||
|
PrismDIDType2RSSI PrismDID = 0x04041
|
||||||
|
PrismDIDType1SignalQuality PrismDID = 0x50044
|
||||||
|
PrismDIDType2SignalQuality PrismDID = 0x05041
|
||||||
|
PrismDIDType1Signal PrismDID = 0x60044
|
||||||
|
PrismDIDType2Signal PrismDID = 0x06041
|
||||||
|
PrismDIDType1Noise PrismDID = 0x70044
|
||||||
|
PrismDIDType2Noise PrismDID = 0x07041
|
||||||
|
PrismDIDType1Rate PrismDID = 0x80044
|
||||||
|
PrismDIDType2Rate PrismDID = 0x08041
|
||||||
|
PrismDIDType1TransmittedFrameIndicator PrismDID = 0x90044
|
||||||
|
PrismDIDType2TransmittedFrameIndicator PrismDID = 0x09041
|
||||||
|
PrismDIDType1FrameLength PrismDID = 0xA0044
|
||||||
|
PrismDIDType2FrameLength PrismDID = 0x0A041
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PrismType1MessageCode uint16 = 0x00000044
|
||||||
|
PrismType2MessageCode uint16 = 0x00000041
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p PrismDID) String() string {
|
||||||
|
dids := map[PrismDID]string{
|
||||||
|
PrismDIDType1HostTime: "Host Time",
|
||||||
|
PrismDIDType2HostTime: "Host Time",
|
||||||
|
PrismDIDType1MACTime: "MAC Time",
|
||||||
|
PrismDIDType2MACTime: "MAC Time",
|
||||||
|
PrismDIDType1Channel: "Channel",
|
||||||
|
PrismDIDType2Channel: "Channel",
|
||||||
|
PrismDIDType1RSSI: "RSSI",
|
||||||
|
PrismDIDType2RSSI: "RSSI",
|
||||||
|
PrismDIDType1SignalQuality: "Signal Quality",
|
||||||
|
PrismDIDType2SignalQuality: "Signal Quality",
|
||||||
|
PrismDIDType1Signal: "Signal",
|
||||||
|
PrismDIDType2Signal: "Signal",
|
||||||
|
PrismDIDType1Noise: "Noise",
|
||||||
|
PrismDIDType2Noise: "Noise",
|
||||||
|
PrismDIDType1Rate: "Rate",
|
||||||
|
PrismDIDType2Rate: "Rate",
|
||||||
|
PrismDIDType1TransmittedFrameIndicator: "Transmitted Frame Indicator",
|
||||||
|
PrismDIDType2TransmittedFrameIndicator: "Transmitted Frame Indicator",
|
||||||
|
PrismDIDType1FrameLength: "Frame Length",
|
||||||
|
PrismDIDType2FrameLength: "Frame Length",
|
||||||
|
}
|
||||||
|
|
||||||
|
if str, ok := dids[p]; ok {
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown DID"
|
||||||
|
}
|
||||||
|
|
||||||
|
type PrismValue struct {
|
||||||
|
DID PrismDID
|
||||||
|
Status uint16
|
||||||
|
Length uint16
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pv *PrismValue) IsSupplied() bool {
|
||||||
|
return pv.Status == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrPrismExpectedMoreData = errors.New("Expected more data.")
|
||||||
|
var ErrPrismInvalidCode = errors.New("Invalid header code.")
|
||||||
|
|
||||||
|
func decodePrismHeader(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
d := &PrismHeader{}
|
||||||
|
return decodingLayerDecoder(d, data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PrismHeader struct {
|
||||||
|
BaseLayer
|
||||||
|
Code uint16
|
||||||
|
Length uint16
|
||||||
|
DeviceName string
|
||||||
|
Values []PrismValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *PrismHeader) LayerType() gopacket.LayerType { return LayerTypePrismHeader }
|
||||||
|
|
||||||
|
func (m *PrismHeader) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
m.Code = binary.LittleEndian.Uint16(data[0:4])
|
||||||
|
m.Length = binary.LittleEndian.Uint16(data[4:8])
|
||||||
|
m.DeviceName = string(data[8:24])
|
||||||
|
m.BaseLayer = BaseLayer{Contents: data[:m.Length], Payload: data[m.Length:len(data)]}
|
||||||
|
|
||||||
|
switch m.Code {
|
||||||
|
case PrismType1MessageCode:
|
||||||
|
fallthrough
|
||||||
|
case PrismType2MessageCode:
|
||||||
|
// valid message code
|
||||||
|
default:
|
||||||
|
return ErrPrismInvalidCode
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := uint16(24)
|
||||||
|
|
||||||
|
m.Values = make([]PrismValue, (m.Length-offset)/12)
|
||||||
|
for i := 0; i < len(m.Values); i++ {
|
||||||
|
decodePrismValue(data[offset:offset+12], &m.Values[i])
|
||||||
|
offset += 12
|
||||||
|
}
|
||||||
|
|
||||||
|
if offset != m.Length {
|
||||||
|
return ErrPrismExpectedMoreData
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *PrismHeader) CanDecode() gopacket.LayerClass { return LayerTypePrismHeader }
|
||||||
|
func (m *PrismHeader) NextLayerType() gopacket.LayerType { return LayerTypeDot11 }
|
1076
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/radiotap.go
generated
vendored
Normal file
1076
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/radiotap.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
560
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/radius.go
generated
vendored
Normal file
560
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/radius.go
generated
vendored
Normal file
|
@ -0,0 +1,560 @@
|
||||||
|
// Copyright 2020 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"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RFC 2865 3. Packet Format
|
||||||
|
// `The minimum length is 20 and maximum length is 4096.`
|
||||||
|
radiusMinimumRecordSizeInBytes int = 20
|
||||||
|
radiusMaximumRecordSizeInBytes int = 4096
|
||||||
|
|
||||||
|
// RFC 2865 5. Attributes
|
||||||
|
// `The Length field is one octet, and indicates the length of this Attribute including the Type, Length and Value fields.`
|
||||||
|
// `The Value field is zero or more octets and contains information specific to the Attribute.`
|
||||||
|
radiusAttributesMinimumRecordSizeInBytes int = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// RADIUS represents a Remote Authentication Dial In User Service layer.
|
||||||
|
type RADIUS struct {
|
||||||
|
BaseLayer
|
||||||
|
|
||||||
|
Code RADIUSCode
|
||||||
|
Identifier RADIUSIdentifier
|
||||||
|
Length RADIUSLength
|
||||||
|
Authenticator RADIUSAuthenticator
|
||||||
|
Attributes []RADIUSAttribute
|
||||||
|
}
|
||||||
|
|
||||||
|
// RADIUSCode represents packet type.
|
||||||
|
type RADIUSCode uint8
|
||||||
|
|
||||||
|
// constants that define RADIUSCode.
|
||||||
|
const (
|
||||||
|
RADIUSCodeAccessRequest RADIUSCode = 1 // RFC2865 3. Packet Format
|
||||||
|
RADIUSCodeAccessAccept RADIUSCode = 2 // RFC2865 3. Packet Format
|
||||||
|
RADIUSCodeAccessReject RADIUSCode = 3 // RFC2865 3. Packet Format
|
||||||
|
RADIUSCodeAccountingRequest RADIUSCode = 4 // RFC2865 3. Packet Format
|
||||||
|
RADIUSCodeAccountingResponse RADIUSCode = 5 // RFC2865 3. Packet Format
|
||||||
|
RADIUSCodeAccessChallenge RADIUSCode = 11 // RFC2865 3. Packet Format
|
||||||
|
RADIUSCodeStatusServer RADIUSCode = 12 // RFC2865 3. Packet Format (experimental)
|
||||||
|
RADIUSCodeStatusClient RADIUSCode = 13 // RFC2865 3. Packet Format (experimental)
|
||||||
|
RADIUSCodeReserved RADIUSCode = 255 // RFC2865 3. Packet Format
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string version of a RADIUSCode.
|
||||||
|
func (t RADIUSCode) String() (s string) {
|
||||||
|
switch t {
|
||||||
|
case RADIUSCodeAccessRequest:
|
||||||
|
s = "Access-Request"
|
||||||
|
case RADIUSCodeAccessAccept:
|
||||||
|
s = "Access-Accept"
|
||||||
|
case RADIUSCodeAccessReject:
|
||||||
|
s = "Access-Reject"
|
||||||
|
case RADIUSCodeAccountingRequest:
|
||||||
|
s = "Accounting-Request"
|
||||||
|
case RADIUSCodeAccountingResponse:
|
||||||
|
s = "Accounting-Response"
|
||||||
|
case RADIUSCodeAccessChallenge:
|
||||||
|
s = "Access-Challenge"
|
||||||
|
case RADIUSCodeStatusServer:
|
||||||
|
s = "Status-Server"
|
||||||
|
case RADIUSCodeStatusClient:
|
||||||
|
s = "Status-Client"
|
||||||
|
case RADIUSCodeReserved:
|
||||||
|
s = "Reserved"
|
||||||
|
default:
|
||||||
|
s = fmt.Sprintf("Unknown(%d)", t)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// RADIUSIdentifier represents packet identifier.
|
||||||
|
type RADIUSIdentifier uint8
|
||||||
|
|
||||||
|
// RADIUSLength represents packet length.
|
||||||
|
type RADIUSLength uint16
|
||||||
|
|
||||||
|
// RADIUSAuthenticator represents authenticator.
|
||||||
|
type RADIUSAuthenticator [16]byte
|
||||||
|
|
||||||
|
// RADIUSAttribute represents attributes.
|
||||||
|
type RADIUSAttribute struct {
|
||||||
|
Type RADIUSAttributeType
|
||||||
|
Length RADIUSAttributeLength
|
||||||
|
Value RADIUSAttributeValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// RADIUSAttributeType represents attribute type.
|
||||||
|
type RADIUSAttributeType uint8
|
||||||
|
|
||||||
|
// constants that define RADIUSAttributeType.
|
||||||
|
const (
|
||||||
|
RADIUSAttributeTypeUserName RADIUSAttributeType = 1 // RFC2865 5.1. User-Name
|
||||||
|
RADIUSAttributeTypeUserPassword RADIUSAttributeType = 2 // RFC2865 5.2. User-Password
|
||||||
|
RADIUSAttributeTypeCHAPPassword RADIUSAttributeType = 3 // RFC2865 5.3. CHAP-Password
|
||||||
|
RADIUSAttributeTypeNASIPAddress RADIUSAttributeType = 4 // RFC2865 5.4. NAS-IP-Address
|
||||||
|
RADIUSAttributeTypeNASPort RADIUSAttributeType = 5 // RFC2865 5.5. NAS-Port
|
||||||
|
RADIUSAttributeTypeServiceType RADIUSAttributeType = 6 // RFC2865 5.6. Service-Type
|
||||||
|
RADIUSAttributeTypeFramedProtocol RADIUSAttributeType = 7 // RFC2865 5.7. Framed-Protocol
|
||||||
|
RADIUSAttributeTypeFramedIPAddress RADIUSAttributeType = 8 // RFC2865 5.8. Framed-IP-Address
|
||||||
|
RADIUSAttributeTypeFramedIPNetmask RADIUSAttributeType = 9 // RFC2865 5.9. Framed-IP-Netmask
|
||||||
|
RADIUSAttributeTypeFramedRouting RADIUSAttributeType = 10 // RFC2865 5.10. Framed-Routing
|
||||||
|
RADIUSAttributeTypeFilterId RADIUSAttributeType = 11 // RFC2865 5.11. Filter-Id
|
||||||
|
RADIUSAttributeTypeFramedMTU RADIUSAttributeType = 12 // RFC2865 5.12. Framed-MTU
|
||||||
|
RADIUSAttributeTypeFramedCompression RADIUSAttributeType = 13 // RFC2865 5.13. Framed-Compression
|
||||||
|
RADIUSAttributeTypeLoginIPHost RADIUSAttributeType = 14 // RFC2865 5.14. Login-IP-Host
|
||||||
|
RADIUSAttributeTypeLoginService RADIUSAttributeType = 15 // RFC2865 5.15. Login-Service
|
||||||
|
RADIUSAttributeTypeLoginTCPPort RADIUSAttributeType = 16 // RFC2865 5.16. Login-TCP-Port
|
||||||
|
RADIUSAttributeTypeReplyMessage RADIUSAttributeType = 18 // RFC2865 5.18. Reply-Message
|
||||||
|
RADIUSAttributeTypeCallbackNumber RADIUSAttributeType = 19 // RFC2865 5.19. Callback-Number
|
||||||
|
RADIUSAttributeTypeCallbackId RADIUSAttributeType = 20 // RFC2865 5.20. Callback-Id
|
||||||
|
RADIUSAttributeTypeFramedRoute RADIUSAttributeType = 22 // RFC2865 5.22. Framed-Route
|
||||||
|
RADIUSAttributeTypeFramedIPXNetwork RADIUSAttributeType = 23 // RFC2865 5.23. Framed-IPX-Network
|
||||||
|
RADIUSAttributeTypeState RADIUSAttributeType = 24 // RFC2865 5.24. State
|
||||||
|
RADIUSAttributeTypeClass RADIUSAttributeType = 25 // RFC2865 5.25. Class
|
||||||
|
RADIUSAttributeTypeVendorSpecific RADIUSAttributeType = 26 // RFC2865 5.26. Vendor-Specific
|
||||||
|
RADIUSAttributeTypeSessionTimeout RADIUSAttributeType = 27 // RFC2865 5.27. Session-Timeout
|
||||||
|
RADIUSAttributeTypeIdleTimeout RADIUSAttributeType = 28 // RFC2865 5.28. Idle-Timeout
|
||||||
|
RADIUSAttributeTypeTerminationAction RADIUSAttributeType = 29 // RFC2865 5.29. Termination-Action
|
||||||
|
RADIUSAttributeTypeCalledStationId RADIUSAttributeType = 30 // RFC2865 5.30. Called-Station-Id
|
||||||
|
RADIUSAttributeTypeCallingStationId RADIUSAttributeType = 31 // RFC2865 5.31. Calling-Station-Id
|
||||||
|
RADIUSAttributeTypeNASIdentifier RADIUSAttributeType = 32 // RFC2865 5.32. NAS-Identifier
|
||||||
|
RADIUSAttributeTypeProxyState RADIUSAttributeType = 33 // RFC2865 5.33. Proxy-State
|
||||||
|
RADIUSAttributeTypeLoginLATService RADIUSAttributeType = 34 // RFC2865 5.34. Login-LAT-Service
|
||||||
|
RADIUSAttributeTypeLoginLATNode RADIUSAttributeType = 35 // RFC2865 5.35. Login-LAT-Node
|
||||||
|
RADIUSAttributeTypeLoginLATGroup RADIUSAttributeType = 36 // RFC2865 5.36. Login-LAT-Group
|
||||||
|
RADIUSAttributeTypeFramedAppleTalkLink RADIUSAttributeType = 37 // RFC2865 5.37. Framed-AppleTalk-Link
|
||||||
|
RADIUSAttributeTypeFramedAppleTalkNetwork RADIUSAttributeType = 38 // RFC2865 5.38. Framed-AppleTalk-Network
|
||||||
|
RADIUSAttributeTypeFramedAppleTalkZone RADIUSAttributeType = 39 // RFC2865 5.39. Framed-AppleTalk-Zone
|
||||||
|
RADIUSAttributeTypeAcctStatusType RADIUSAttributeType = 40 // RFC2866 5.1. Acct-Status-Type
|
||||||
|
RADIUSAttributeTypeAcctDelayTime RADIUSAttributeType = 41 // RFC2866 5.2. Acct-Delay-Time
|
||||||
|
RADIUSAttributeTypeAcctInputOctets RADIUSAttributeType = 42 // RFC2866 5.3. Acct-Input-Octets
|
||||||
|
RADIUSAttributeTypeAcctOutputOctets RADIUSAttributeType = 43 // RFC2866 5.4. Acct-Output-Octets
|
||||||
|
RADIUSAttributeTypeAcctSessionId RADIUSAttributeType = 44 // RFC2866 5.5. Acct-Session-Id
|
||||||
|
RADIUSAttributeTypeAcctAuthentic RADIUSAttributeType = 45 // RFC2866 5.6. Acct-Authentic
|
||||||
|
RADIUSAttributeTypeAcctSessionTime RADIUSAttributeType = 46 // RFC2866 5.7. Acct-Session-Time
|
||||||
|
RADIUSAttributeTypeAcctInputPackets RADIUSAttributeType = 47 // RFC2866 5.8. Acct-Input-Packets
|
||||||
|
RADIUSAttributeTypeAcctOutputPackets RADIUSAttributeType = 48 // RFC2866 5.9. Acct-Output-Packets
|
||||||
|
RADIUSAttributeTypeAcctTerminateCause RADIUSAttributeType = 49 // RFC2866 5.10. Acct-Terminate-Cause
|
||||||
|
RADIUSAttributeTypeAcctMultiSessionId RADIUSAttributeType = 50 // RFC2866 5.11. Acct-Multi-Session-Id
|
||||||
|
RADIUSAttributeTypeAcctLinkCount RADIUSAttributeType = 51 // RFC2866 5.12. Acct-Link-Count
|
||||||
|
RADIUSAttributeTypeAcctInputGigawords RADIUSAttributeType = 52 // RFC2869 5.1. Acct-Input-Gigawords
|
||||||
|
RADIUSAttributeTypeAcctOutputGigawords RADIUSAttributeType = 53 // RFC2869 5.2. Acct-Output-Gigawords
|
||||||
|
RADIUSAttributeTypeEventTimestamp RADIUSAttributeType = 55 // RFC2869 5.3. Event-Timestamp
|
||||||
|
RADIUSAttributeTypeCHAPChallenge RADIUSAttributeType = 60 // RFC2865 5.40. CHAP-Challenge
|
||||||
|
RADIUSAttributeTypeNASPortType RADIUSAttributeType = 61 // RFC2865 5.41. NAS-Port-Type
|
||||||
|
RADIUSAttributeTypePortLimit RADIUSAttributeType = 62 // RFC2865 5.42. Port-Limit
|
||||||
|
RADIUSAttributeTypeLoginLATPort RADIUSAttributeType = 63 // RFC2865 5.43. Login-LAT-Port
|
||||||
|
RADIUSAttributeTypeTunnelType RADIUSAttributeType = 64 // RFC2868 3.1. Tunnel-Type
|
||||||
|
RADIUSAttributeTypeTunnelMediumType RADIUSAttributeType = 65 // RFC2868 3.2. Tunnel-Medium-Type
|
||||||
|
RADIUSAttributeTypeTunnelClientEndpoint RADIUSAttributeType = 66 // RFC2868 3.3. Tunnel-Client-Endpoint
|
||||||
|
RADIUSAttributeTypeTunnelServerEndpoint RADIUSAttributeType = 67 // RFC2868 3.4. Tunnel-Server-Endpoint
|
||||||
|
RADIUSAttributeTypeAcctTunnelConnection RADIUSAttributeType = 68 // RFC2867 4.1. Acct-Tunnel-Connection
|
||||||
|
RADIUSAttributeTypeTunnelPassword RADIUSAttributeType = 69 // RFC2868 3.5. Tunnel-Password
|
||||||
|
RADIUSAttributeTypeARAPPassword RADIUSAttributeType = 70 // RFC2869 5.4. ARAP-Password
|
||||||
|
RADIUSAttributeTypeARAPFeatures RADIUSAttributeType = 71 // RFC2869 5.5. ARAP-Features
|
||||||
|
RADIUSAttributeTypeARAPZoneAccess RADIUSAttributeType = 72 // RFC2869 5.6. ARAP-Zone-Access
|
||||||
|
RADIUSAttributeTypeARAPSecurity RADIUSAttributeType = 73 // RFC2869 5.7. ARAP-Security
|
||||||
|
RADIUSAttributeTypeARAPSecurityData RADIUSAttributeType = 74 // RFC2869 5.8. ARAP-Security-Data
|
||||||
|
RADIUSAttributeTypePasswordRetry RADIUSAttributeType = 75 // RFC2869 5.9. Password-Retry
|
||||||
|
RADIUSAttributeTypePrompt RADIUSAttributeType = 76 // RFC2869 5.10. Prompt
|
||||||
|
RADIUSAttributeTypeConnectInfo RADIUSAttributeType = 77 // RFC2869 5.11. Connect-Info
|
||||||
|
RADIUSAttributeTypeConfigurationToken RADIUSAttributeType = 78 // RFC2869 5.12. Configuration-Token
|
||||||
|
RADIUSAttributeTypeEAPMessage RADIUSAttributeType = 79 // RFC2869 5.13. EAP-Message
|
||||||
|
RADIUSAttributeTypeMessageAuthenticator RADIUSAttributeType = 80 // RFC2869 5.14. Message-Authenticator
|
||||||
|
RADIUSAttributeTypeTunnelPrivateGroupID RADIUSAttributeType = 81 // RFC2868 3.6. Tunnel-Private-Group-ID
|
||||||
|
RADIUSAttributeTypeTunnelAssignmentID RADIUSAttributeType = 82 // RFC2868 3.7. Tunnel-Assignment-ID
|
||||||
|
RADIUSAttributeTypeTunnelPreference RADIUSAttributeType = 83 // RFC2868 3.8. Tunnel-Preference
|
||||||
|
RADIUSAttributeTypeARAPChallengeResponse RADIUSAttributeType = 84 // RFC2869 5.15. ARAP-Challenge-Response
|
||||||
|
RADIUSAttributeTypeAcctInterimInterval RADIUSAttributeType = 85 // RFC2869 5.16. Acct-Interim-Interval
|
||||||
|
RADIUSAttributeTypeAcctTunnelPacketsLost RADIUSAttributeType = 86 // RFC2867 4.2. Acct-Tunnel-Packets-Lost
|
||||||
|
RADIUSAttributeTypeNASPortId RADIUSAttributeType = 87 // RFC2869 5.17. NAS-Port-Id
|
||||||
|
RADIUSAttributeTypeFramedPool RADIUSAttributeType = 88 // RFC2869 5.18. Framed-Pool
|
||||||
|
RADIUSAttributeTypeTunnelClientAuthID RADIUSAttributeType = 90 // RFC2868 3.9. Tunnel-Client-Auth-ID
|
||||||
|
RADIUSAttributeTypeTunnelServerAuthID RADIUSAttributeType = 91 // RFC2868 3.10. Tunnel-Server-Auth-ID
|
||||||
|
)
|
||||||
|
|
||||||
|
// RADIUSAttributeType represents attribute length.
|
||||||
|
type RADIUSAttributeLength uint8
|
||||||
|
|
||||||
|
// RADIUSAttributeType represents attribute value.
|
||||||
|
type RADIUSAttributeValue []byte
|
||||||
|
|
||||||
|
// String returns a string version of a RADIUSAttributeType.
|
||||||
|
func (t RADIUSAttributeType) String() (s string) {
|
||||||
|
switch t {
|
||||||
|
case RADIUSAttributeTypeUserName:
|
||||||
|
s = "User-Name"
|
||||||
|
case RADIUSAttributeTypeUserPassword:
|
||||||
|
s = "User-Password"
|
||||||
|
case RADIUSAttributeTypeCHAPPassword:
|
||||||
|
s = "CHAP-Password"
|
||||||
|
case RADIUSAttributeTypeNASIPAddress:
|
||||||
|
s = "NAS-IP-Address"
|
||||||
|
case RADIUSAttributeTypeNASPort:
|
||||||
|
s = "NAS-Port"
|
||||||
|
case RADIUSAttributeTypeServiceType:
|
||||||
|
s = "Service-Type"
|
||||||
|
case RADIUSAttributeTypeFramedProtocol:
|
||||||
|
s = "Framed-Protocol"
|
||||||
|
case RADIUSAttributeTypeFramedIPAddress:
|
||||||
|
s = "Framed-IP-Address"
|
||||||
|
case RADIUSAttributeTypeFramedIPNetmask:
|
||||||
|
s = "Framed-IP-Netmask"
|
||||||
|
case RADIUSAttributeTypeFramedRouting:
|
||||||
|
s = "Framed-Routing"
|
||||||
|
case RADIUSAttributeTypeFilterId:
|
||||||
|
s = "Filter-Id"
|
||||||
|
case RADIUSAttributeTypeFramedMTU:
|
||||||
|
s = "Framed-MTU"
|
||||||
|
case RADIUSAttributeTypeFramedCompression:
|
||||||
|
s = "Framed-Compression"
|
||||||
|
case RADIUSAttributeTypeLoginIPHost:
|
||||||
|
s = "Login-IP-Host"
|
||||||
|
case RADIUSAttributeTypeLoginService:
|
||||||
|
s = "Login-Service"
|
||||||
|
case RADIUSAttributeTypeLoginTCPPort:
|
||||||
|
s = "Login-TCP-Port"
|
||||||
|
case RADIUSAttributeTypeReplyMessage:
|
||||||
|
s = "Reply-Message"
|
||||||
|
case RADIUSAttributeTypeCallbackNumber:
|
||||||
|
s = "Callback-Number"
|
||||||
|
case RADIUSAttributeTypeCallbackId:
|
||||||
|
s = "Callback-Id"
|
||||||
|
case RADIUSAttributeTypeFramedRoute:
|
||||||
|
s = "Framed-Route"
|
||||||
|
case RADIUSAttributeTypeFramedIPXNetwork:
|
||||||
|
s = "Framed-IPX-Network"
|
||||||
|
case RADIUSAttributeTypeState:
|
||||||
|
s = "State"
|
||||||
|
case RADIUSAttributeTypeClass:
|
||||||
|
s = "Class"
|
||||||
|
case RADIUSAttributeTypeVendorSpecific:
|
||||||
|
s = "Vendor-Specific"
|
||||||
|
case RADIUSAttributeTypeSessionTimeout:
|
||||||
|
s = "Session-Timeout"
|
||||||
|
case RADIUSAttributeTypeIdleTimeout:
|
||||||
|
s = "Idle-Timeout"
|
||||||
|
case RADIUSAttributeTypeTerminationAction:
|
||||||
|
s = "Termination-Action"
|
||||||
|
case RADIUSAttributeTypeCalledStationId:
|
||||||
|
s = "Called-Station-Id"
|
||||||
|
case RADIUSAttributeTypeCallingStationId:
|
||||||
|
s = "Calling-Station-Id"
|
||||||
|
case RADIUSAttributeTypeNASIdentifier:
|
||||||
|
s = "NAS-Identifier"
|
||||||
|
case RADIUSAttributeTypeProxyState:
|
||||||
|
s = "Proxy-State"
|
||||||
|
case RADIUSAttributeTypeLoginLATService:
|
||||||
|
s = "Login-LAT-Service"
|
||||||
|
case RADIUSAttributeTypeLoginLATNode:
|
||||||
|
s = "Login-LAT-Node"
|
||||||
|
case RADIUSAttributeTypeLoginLATGroup:
|
||||||
|
s = "Login-LAT-Group"
|
||||||
|
case RADIUSAttributeTypeFramedAppleTalkLink:
|
||||||
|
s = "Framed-AppleTalk-Link"
|
||||||
|
case RADIUSAttributeTypeFramedAppleTalkNetwork:
|
||||||
|
s = "Framed-AppleTalk-Network"
|
||||||
|
case RADIUSAttributeTypeFramedAppleTalkZone:
|
||||||
|
s = "Framed-AppleTalk-Zone"
|
||||||
|
case RADIUSAttributeTypeAcctStatusType:
|
||||||
|
s = "Acct-Status-Type"
|
||||||
|
case RADIUSAttributeTypeAcctDelayTime:
|
||||||
|
s = "Acct-Delay-Time"
|
||||||
|
case RADIUSAttributeTypeAcctInputOctets:
|
||||||
|
s = "Acct-Input-Octets"
|
||||||
|
case RADIUSAttributeTypeAcctOutputOctets:
|
||||||
|
s = "Acct-Output-Octets"
|
||||||
|
case RADIUSAttributeTypeAcctSessionId:
|
||||||
|
s = "Acct-Session-Id"
|
||||||
|
case RADIUSAttributeTypeAcctAuthentic:
|
||||||
|
s = "Acct-Authentic"
|
||||||
|
case RADIUSAttributeTypeAcctSessionTime:
|
||||||
|
s = "Acct-Session-Time"
|
||||||
|
case RADIUSAttributeTypeAcctInputPackets:
|
||||||
|
s = "Acct-Input-Packets"
|
||||||
|
case RADIUSAttributeTypeAcctOutputPackets:
|
||||||
|
s = "Acct-Output-Packets"
|
||||||
|
case RADIUSAttributeTypeAcctTerminateCause:
|
||||||
|
s = "Acct-Terminate-Cause"
|
||||||
|
case RADIUSAttributeTypeAcctMultiSessionId:
|
||||||
|
s = "Acct-Multi-Session-Id"
|
||||||
|
case RADIUSAttributeTypeAcctLinkCount:
|
||||||
|
s = "Acct-Link-Count"
|
||||||
|
case RADIUSAttributeTypeAcctInputGigawords:
|
||||||
|
s = "Acct-Input-Gigawords"
|
||||||
|
case RADIUSAttributeTypeAcctOutputGigawords:
|
||||||
|
s = "Acct-Output-Gigawords"
|
||||||
|
case RADIUSAttributeTypeEventTimestamp:
|
||||||
|
s = "Event-Timestamp"
|
||||||
|
case RADIUSAttributeTypeCHAPChallenge:
|
||||||
|
s = "CHAP-Challenge"
|
||||||
|
case RADIUSAttributeTypeNASPortType:
|
||||||
|
s = "NAS-Port-Type"
|
||||||
|
case RADIUSAttributeTypePortLimit:
|
||||||
|
s = "Port-Limit"
|
||||||
|
case RADIUSAttributeTypeLoginLATPort:
|
||||||
|
s = "Login-LAT-Port"
|
||||||
|
case RADIUSAttributeTypeTunnelType:
|
||||||
|
s = "Tunnel-Type"
|
||||||
|
case RADIUSAttributeTypeTunnelMediumType:
|
||||||
|
s = "Tunnel-Medium-Type"
|
||||||
|
case RADIUSAttributeTypeTunnelClientEndpoint:
|
||||||
|
s = "Tunnel-Client-Endpoint"
|
||||||
|
case RADIUSAttributeTypeTunnelServerEndpoint:
|
||||||
|
s = "Tunnel-Server-Endpoint"
|
||||||
|
case RADIUSAttributeTypeAcctTunnelConnection:
|
||||||
|
s = "Acct-Tunnel-Connection"
|
||||||
|
case RADIUSAttributeTypeTunnelPassword:
|
||||||
|
s = "Tunnel-Password"
|
||||||
|
case RADIUSAttributeTypeARAPPassword:
|
||||||
|
s = "ARAP-Password"
|
||||||
|
case RADIUSAttributeTypeARAPFeatures:
|
||||||
|
s = "ARAP-Features"
|
||||||
|
case RADIUSAttributeTypeARAPZoneAccess:
|
||||||
|
s = "ARAP-Zone-Access"
|
||||||
|
case RADIUSAttributeTypeARAPSecurity:
|
||||||
|
s = "ARAP-Security"
|
||||||
|
case RADIUSAttributeTypeARAPSecurityData:
|
||||||
|
s = "ARAP-Security-Data"
|
||||||
|
case RADIUSAttributeTypePasswordRetry:
|
||||||
|
s = "Password-Retry"
|
||||||
|
case RADIUSAttributeTypePrompt:
|
||||||
|
s = "Prompt"
|
||||||
|
case RADIUSAttributeTypeConnectInfo:
|
||||||
|
s = "Connect-Info"
|
||||||
|
case RADIUSAttributeTypeConfigurationToken:
|
||||||
|
s = "Configuration-Token"
|
||||||
|
case RADIUSAttributeTypeEAPMessage:
|
||||||
|
s = "EAP-Message"
|
||||||
|
case RADIUSAttributeTypeMessageAuthenticator:
|
||||||
|
s = "Message-Authenticator"
|
||||||
|
case RADIUSAttributeTypeTunnelPrivateGroupID:
|
||||||
|
s = "Tunnel-Private-Group-ID"
|
||||||
|
case RADIUSAttributeTypeTunnelAssignmentID:
|
||||||
|
s = "Tunnel-Assignment-ID"
|
||||||
|
case RADIUSAttributeTypeTunnelPreference:
|
||||||
|
s = "Tunnel-Preference"
|
||||||
|
case RADIUSAttributeTypeARAPChallengeResponse:
|
||||||
|
s = "ARAP-Challenge-Response"
|
||||||
|
case RADIUSAttributeTypeAcctInterimInterval:
|
||||||
|
s = "Acct-Interim-Interval"
|
||||||
|
case RADIUSAttributeTypeAcctTunnelPacketsLost:
|
||||||
|
s = "Acct-Tunnel-Packets-Lost"
|
||||||
|
case RADIUSAttributeTypeNASPortId:
|
||||||
|
s = "NAS-Port-Id"
|
||||||
|
case RADIUSAttributeTypeFramedPool:
|
||||||
|
s = "Framed-Pool"
|
||||||
|
case RADIUSAttributeTypeTunnelClientAuthID:
|
||||||
|
s = "Tunnel-Client-Auth-ID"
|
||||||
|
case RADIUSAttributeTypeTunnelServerAuthID:
|
||||||
|
s = "Tunnel-Server-Auth-ID"
|
||||||
|
default:
|
||||||
|
s = fmt.Sprintf("Unknown(%d)", t)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the length of a RADIUS packet.
|
||||||
|
func (radius *RADIUS) Len() (int, error) {
|
||||||
|
n := radiusMinimumRecordSizeInBytes
|
||||||
|
for _, v := range radius.Attributes {
|
||||||
|
alen, err := attributeValueLength(v.Value)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
n += int(alen) + 2 // Added Type and Length
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeRADIUS.
|
||||||
|
func (radius *RADIUS) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeRADIUS
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the given bytes into this layer.
|
||||||
|
func (radius *RADIUS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) > radiusMaximumRecordSizeInBytes {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("RADIUS length %d too big", len(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) < radiusMinimumRecordSizeInBytes {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("RADIUS length %d too short", len(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
radius.BaseLayer = BaseLayer{Contents: data}
|
||||||
|
|
||||||
|
radius.Code = RADIUSCode(data[0])
|
||||||
|
radius.Identifier = RADIUSIdentifier(data[1])
|
||||||
|
radius.Length = RADIUSLength(binary.BigEndian.Uint16(data[2:4]))
|
||||||
|
|
||||||
|
if int(radius.Length) > radiusMaximumRecordSizeInBytes {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("RADIUS length %d too big", radius.Length)
|
||||||
|
}
|
||||||
|
|
||||||
|
if int(radius.Length) < radiusMinimumRecordSizeInBytes {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("RADIUS length %d too short", radius.Length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RFC 2865 3. Packet Format
|
||||||
|
// `If the packet is shorter than the Length field indicates, it MUST be silently discarded.`
|
||||||
|
if int(radius.Length) > len(data) {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("RADIUS length %d too big", radius.Length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RFC 2865 3. Packet Format
|
||||||
|
// `Octets outside the range of the Length field MUST be treated as padding and ignored on reception.`
|
||||||
|
if int(radius.Length) < len(data) {
|
||||||
|
df.SetTruncated()
|
||||||
|
data = data[:radius.Length]
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(radius.Authenticator[:], data[4:20])
|
||||||
|
|
||||||
|
if len(data) == radiusMinimumRecordSizeInBytes {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pos := radiusMinimumRecordSizeInBytes
|
||||||
|
for {
|
||||||
|
if len(data) == pos {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data[pos:]) < radiusAttributesMinimumRecordSizeInBytes {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("RADIUS attributes length %d too short", len(data[pos:]))
|
||||||
|
}
|
||||||
|
|
||||||
|
attr := RADIUSAttribute{}
|
||||||
|
attr.Type = RADIUSAttributeType(data[pos])
|
||||||
|
attr.Length = RADIUSAttributeLength(data[pos+1])
|
||||||
|
|
||||||
|
if int(attr.Length) > len(data[pos:]) {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("RADIUS attributes length %d too big", attr.Length)
|
||||||
|
}
|
||||||
|
|
||||||
|
if int(attr.Length) < radiusAttributesMinimumRecordSizeInBytes {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("RADIUS attributes length %d too short", attr.Length)
|
||||||
|
}
|
||||||
|
|
||||||
|
if int(attr.Length) > radiusAttributesMinimumRecordSizeInBytes {
|
||||||
|
attr.Value = make([]byte, attr.Length-2)
|
||||||
|
copy(attr.Value[:], data[pos+2:pos+int(attr.Length)])
|
||||||
|
radius.Attributes = append(radius.Attributes, attr)
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += int(attr.Length)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range radius.Attributes {
|
||||||
|
if v.Type == RADIUSAttributeTypeEAPMessage {
|
||||||
|
radius.BaseLayer.Payload = append(radius.BaseLayer.Payload, v.Value...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (radius *RADIUS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
plen, err := radius.Len()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.FixLengths {
|
||||||
|
radius.Length = RADIUSLength(plen)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := b.PrependBytes(plen)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
data[0] = byte(radius.Code)
|
||||||
|
data[1] = byte(radius.Identifier)
|
||||||
|
binary.BigEndian.PutUint16(data[2:], uint16(radius.Length))
|
||||||
|
copy(data[4:20], radius.Authenticator[:])
|
||||||
|
|
||||||
|
pos := radiusMinimumRecordSizeInBytes
|
||||||
|
for _, v := range radius.Attributes {
|
||||||
|
if opts.FixLengths {
|
||||||
|
v.Length, err = attributeValueLength(v.Value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data[pos] = byte(v.Type)
|
||||||
|
data[pos+1] = byte(v.Length)
|
||||||
|
copy(data[pos+2:], v.Value[:])
|
||||||
|
|
||||||
|
pos += len(v.Value) + 2 // Added Type and Length
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode.
|
||||||
|
func (radius *RADIUS) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeRADIUS
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer.
|
||||||
|
func (radius *RADIUS) NextLayerType() gopacket.LayerType {
|
||||||
|
if len(radius.BaseLayer.Payload) > 0 {
|
||||||
|
return LayerTypeEAP
|
||||||
|
} else {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payload returns the EAP Type-Data for EAP-Message attributes.
|
||||||
|
func (radius *RADIUS) Payload() []byte {
|
||||||
|
return radius.BaseLayer.Payload
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeRADIUS(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
radius := &RADIUS{}
|
||||||
|
err := radius.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(radius)
|
||||||
|
p.SetApplicationLayer(radius)
|
||||||
|
next := radius.NextLayerType()
|
||||||
|
if next == gopacket.LayerTypeZero {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return p.NextDecoder(next)
|
||||||
|
}
|
||||||
|
|
||||||
|
func attributeValueLength(v []byte) (RADIUSAttributeLength, error) {
|
||||||
|
n := len(v)
|
||||||
|
if n > 255 {
|
||||||
|
return 0, fmt.Errorf("RADIUS attribute value length %d too long", n)
|
||||||
|
} else {
|
||||||
|
return RADIUSAttributeLength(n), nil
|
||||||
|
}
|
||||||
|
}
|
170
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/rmcp.go
generated
vendored
Normal file
170
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/rmcp.go
generated
vendored
Normal file
|
@ -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())
|
||||||
|
}
|
93
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/rudp.go
generated
vendored
Normal file
93
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/rudp.go
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RUDP struct {
|
||||||
|
BaseLayer
|
||||||
|
SYN, ACK, EACK, RST, NUL bool
|
||||||
|
Version uint8
|
||||||
|
HeaderLength uint8
|
||||||
|
SrcPort, DstPort RUDPPort
|
||||||
|
DataLength uint16
|
||||||
|
Seq, Ack, Checksum uint32
|
||||||
|
VariableHeaderArea []byte
|
||||||
|
// RUDPHeaderSyn contains SYN information for the RUDP packet,
|
||||||
|
// if the SYN flag is set
|
||||||
|
*RUDPHeaderSYN
|
||||||
|
// RUDPHeaderEack contains EACK information for the RUDP packet,
|
||||||
|
// if the EACK flag is set.
|
||||||
|
*RUDPHeaderEACK
|
||||||
|
}
|
||||||
|
|
||||||
|
type RUDPHeaderSYN struct {
|
||||||
|
MaxOutstandingSegments, MaxSegmentSize, OptionFlags uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type RUDPHeaderEACK struct {
|
||||||
|
SeqsReceivedOK []uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeRUDP.
|
||||||
|
func (r *RUDP) LayerType() gopacket.LayerType { return LayerTypeRUDP }
|
||||||
|
|
||||||
|
func decodeRUDP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
r := &RUDP{
|
||||||
|
SYN: data[0]&0x80 != 0,
|
||||||
|
ACK: data[0]&0x40 != 0,
|
||||||
|
EACK: data[0]&0x20 != 0,
|
||||||
|
RST: data[0]&0x10 != 0,
|
||||||
|
NUL: data[0]&0x08 != 0,
|
||||||
|
Version: data[0] & 0x3,
|
||||||
|
HeaderLength: data[1],
|
||||||
|
SrcPort: RUDPPort(data[2]),
|
||||||
|
DstPort: RUDPPort(data[3]),
|
||||||
|
DataLength: binary.BigEndian.Uint16(data[4:6]),
|
||||||
|
Seq: binary.BigEndian.Uint32(data[6:10]),
|
||||||
|
Ack: binary.BigEndian.Uint32(data[10:14]),
|
||||||
|
Checksum: binary.BigEndian.Uint32(data[14:18]),
|
||||||
|
}
|
||||||
|
if r.HeaderLength < 9 {
|
||||||
|
return fmt.Errorf("RUDP packet with too-short header length %d", r.HeaderLength)
|
||||||
|
}
|
||||||
|
hlen := int(r.HeaderLength) * 2
|
||||||
|
r.Contents = data[:hlen]
|
||||||
|
r.Payload = data[hlen : hlen+int(r.DataLength)]
|
||||||
|
r.VariableHeaderArea = data[18:hlen]
|
||||||
|
headerData := r.VariableHeaderArea
|
||||||
|
switch {
|
||||||
|
case r.SYN:
|
||||||
|
if len(headerData) != 6 {
|
||||||
|
return fmt.Errorf("RUDP packet invalid SYN header length: %d", len(headerData))
|
||||||
|
}
|
||||||
|
r.RUDPHeaderSYN = &RUDPHeaderSYN{
|
||||||
|
MaxOutstandingSegments: binary.BigEndian.Uint16(headerData[:2]),
|
||||||
|
MaxSegmentSize: binary.BigEndian.Uint16(headerData[2:4]),
|
||||||
|
OptionFlags: binary.BigEndian.Uint16(headerData[4:6]),
|
||||||
|
}
|
||||||
|
case r.EACK:
|
||||||
|
if len(headerData)%4 != 0 {
|
||||||
|
return fmt.Errorf("RUDP packet invalid EACK header length: %d", len(headerData))
|
||||||
|
}
|
||||||
|
r.RUDPHeaderEACK = &RUDPHeaderEACK{make([]uint32, len(headerData)/4)}
|
||||||
|
for i := 0; i < len(headerData); i += 4 {
|
||||||
|
r.SeqsReceivedOK[i/4] = binary.BigEndian.Uint32(headerData[i : i+4])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.AddLayer(r)
|
||||||
|
p.SetTransportLayer(r)
|
||||||
|
return p.NextDecoder(gopacket.LayerTypePayload)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RUDP) TransportFlow() gopacket.Flow {
|
||||||
|
return gopacket.NewFlow(EndpointRUDPPort, []byte{byte(r.SrcPort)}, []byte{byte(r.DstPort)})
|
||||||
|
}
|
746
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/sctp.go
generated
vendored
Normal file
746
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/sctp.go
generated
vendored
Normal file
|
@ -0,0 +1,746 @@
|
||||||
|
// Copyright 2012 Google, Inc. 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"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"hash/crc32"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SCTP contains information on the top level of an SCTP packet.
|
||||||
|
type SCTP struct {
|
||||||
|
BaseLayer
|
||||||
|
SrcPort, DstPort SCTPPort
|
||||||
|
VerificationTag uint32
|
||||||
|
Checksum uint32
|
||||||
|
sPort, dPort []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeSCTP
|
||||||
|
func (s *SCTP) LayerType() gopacket.LayerType { return LayerTypeSCTP }
|
||||||
|
|
||||||
|
func decodeSCTP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
sctp := &SCTP{}
|
||||||
|
err := sctp.DecodeFromBytes(data, p)
|
||||||
|
p.AddLayer(sctp)
|
||||||
|
p.SetTransportLayer(sctp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.NextDecoder(sctpChunkTypePrefixDecoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
var sctpChunkTypePrefixDecoder = gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)
|
||||||
|
|
||||||
|
// TransportFlow returns a flow based on the source and destination SCTP port.
|
||||||
|
func (s *SCTP) TransportFlow() gopacket.Flow {
|
||||||
|
return gopacket.NewFlow(EndpointSCTPPort, s.sPort, s.dPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeWithSCTPChunkTypePrefix(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
chunkType := SCTPChunkType(data[0])
|
||||||
|
return chunkType.Decode(data, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (s SCTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(12)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes[0:2], uint16(s.SrcPort))
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:4], uint16(s.DstPort))
|
||||||
|
binary.BigEndian.PutUint32(bytes[4:8], s.VerificationTag)
|
||||||
|
if opts.ComputeChecksums {
|
||||||
|
// Note: MakeTable(Castagnoli) actually only creates the table once, then
|
||||||
|
// passes back a singleton on every other call, so this shouldn't cause
|
||||||
|
// excessive memory allocation.
|
||||||
|
binary.LittleEndian.PutUint32(bytes[8:12], crc32.Checksum(b.Bytes(), crc32.MakeTable(crc32.Castagnoli)))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sctp *SCTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 12 {
|
||||||
|
return errors.New("Invalid SCTP common header length")
|
||||||
|
}
|
||||||
|
sctp.SrcPort = SCTPPort(binary.BigEndian.Uint16(data[:2]))
|
||||||
|
sctp.sPort = data[:2]
|
||||||
|
sctp.DstPort = SCTPPort(binary.BigEndian.Uint16(data[2:4]))
|
||||||
|
sctp.dPort = data[2:4]
|
||||||
|
sctp.VerificationTag = binary.BigEndian.Uint32(data[4:8])
|
||||||
|
sctp.Checksum = binary.BigEndian.Uint32(data[8:12])
|
||||||
|
sctp.BaseLayer = BaseLayer{data[:12], data[12:]}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *SCTP) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeSCTP
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *SCTP) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPChunk contains the common fields in all SCTP chunks.
|
||||||
|
type SCTPChunk struct {
|
||||||
|
BaseLayer
|
||||||
|
Type SCTPChunkType
|
||||||
|
Flags uint8
|
||||||
|
Length uint16
|
||||||
|
// ActualLength is the total length of an SCTP chunk, including padding.
|
||||||
|
// SCTP chunks start and end on 4-byte boundaries. So if a chunk has a length
|
||||||
|
// of 18, it means that it has data up to and including byte 18, then padding
|
||||||
|
// up to the next 4-byte boundary, 20. In this case, Length would be 18, and
|
||||||
|
// ActualLength would be 20.
|
||||||
|
ActualLength int
|
||||||
|
}
|
||||||
|
|
||||||
|
func roundUpToNearest4(i int) int {
|
||||||
|
if i%4 == 0 {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
return i + 4 - (i % 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSCTPChunk(data []byte) (SCTPChunk, error) {
|
||||||
|
length := binary.BigEndian.Uint16(data[2:4])
|
||||||
|
if length < 4 {
|
||||||
|
return SCTPChunk{}, errors.New("invalid SCTP chunk length")
|
||||||
|
}
|
||||||
|
actual := roundUpToNearest4(int(length))
|
||||||
|
ct := SCTPChunkType(data[0])
|
||||||
|
|
||||||
|
// For SCTP Data, use a separate layer for the payload
|
||||||
|
delta := 0
|
||||||
|
if ct == SCTPChunkTypeData {
|
||||||
|
delta = int(actual) - int(length)
|
||||||
|
actual = 16
|
||||||
|
}
|
||||||
|
|
||||||
|
return SCTPChunk{
|
||||||
|
Type: ct,
|
||||||
|
Flags: data[1],
|
||||||
|
Length: length,
|
||||||
|
ActualLength: actual,
|
||||||
|
BaseLayer: BaseLayer{data[:actual], data[actual : len(data)-delta]},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPParameter is a TLV parameter inside a SCTPChunk.
|
||||||
|
type SCTPParameter struct {
|
||||||
|
Type uint16
|
||||||
|
Length uint16
|
||||||
|
ActualLength int
|
||||||
|
Value []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSCTPParameter(data []byte) SCTPParameter {
|
||||||
|
length := binary.BigEndian.Uint16(data[2:4])
|
||||||
|
return SCTPParameter{
|
||||||
|
Type: binary.BigEndian.Uint16(data[0:2]),
|
||||||
|
Length: length,
|
||||||
|
Value: data[4:length],
|
||||||
|
ActualLength: roundUpToNearest4(int(length)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p SCTPParameter) Bytes() []byte {
|
||||||
|
length := 4 + len(p.Value)
|
||||||
|
data := make([]byte, roundUpToNearest4(length))
|
||||||
|
binary.BigEndian.PutUint16(data[0:2], p.Type)
|
||||||
|
binary.BigEndian.PutUint16(data[2:4], uint16(length))
|
||||||
|
copy(data[4:], p.Value)
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPUnknownChunkType is the layer type returned when we don't recognize the
|
||||||
|
// chunk type. Since there's a length in a known location, we can skip over
|
||||||
|
// it even if we don't know what it is, and continue parsing the rest of the
|
||||||
|
// chunks. This chunk is stored as an ErrorLayer in the packet.
|
||||||
|
type SCTPUnknownChunkType struct {
|
||||||
|
SCTPChunk
|
||||||
|
bytes []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSCTPChunkTypeUnknown(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
chunk, err := decodeSCTPChunk(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc := &SCTPUnknownChunkType{SCTPChunk: chunk}
|
||||||
|
sc.bytes = data[:sc.ActualLength]
|
||||||
|
p.AddLayer(sc)
|
||||||
|
p.SetErrorLayer(sc)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (s SCTPUnknownChunkType) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(s.ActualLength)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
copy(bytes, s.bytes)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeSCTPUnknownChunkType.
|
||||||
|
func (s *SCTPUnknownChunkType) LayerType() gopacket.LayerType { return LayerTypeSCTPUnknownChunkType }
|
||||||
|
|
||||||
|
// Payload returns all bytes in this header, including the decoded Type, Length,
|
||||||
|
// and Flags.
|
||||||
|
func (s *SCTPUnknownChunkType) Payload() []byte { return s.bytes }
|
||||||
|
|
||||||
|
// Error implements ErrorLayer.
|
||||||
|
func (s *SCTPUnknownChunkType) Error() error {
|
||||||
|
return fmt.Errorf("No decode method available for SCTP chunk type %s", s.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPData is the SCTP Data chunk layer.
|
||||||
|
type SCTPData struct {
|
||||||
|
SCTPChunk
|
||||||
|
Unordered, BeginFragment, EndFragment bool
|
||||||
|
TSN uint32
|
||||||
|
StreamId uint16
|
||||||
|
StreamSequence uint16
|
||||||
|
PayloadProtocol SCTPPayloadProtocol
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeSCTPData.
|
||||||
|
func (s *SCTPData) LayerType() gopacket.LayerType { return LayerTypeSCTPData }
|
||||||
|
|
||||||
|
// SCTPPayloadProtocol represents a payload protocol
|
||||||
|
type SCTPPayloadProtocol uint32
|
||||||
|
|
||||||
|
// SCTPPayloadProtocol constonts from http://www.iana.org/assignments/sctp-parameters/sctp-parameters.xhtml
|
||||||
|
const (
|
||||||
|
SCTPProtocolReserved SCTPPayloadProtocol = 0
|
||||||
|
SCTPPayloadUIA = 1
|
||||||
|
SCTPPayloadM2UA = 2
|
||||||
|
SCTPPayloadM3UA = 3
|
||||||
|
SCTPPayloadSUA = 4
|
||||||
|
SCTPPayloadM2PA = 5
|
||||||
|
SCTPPayloadV5UA = 6
|
||||||
|
SCTPPayloadH248 = 7
|
||||||
|
SCTPPayloadBICC = 8
|
||||||
|
SCTPPayloadTALI = 9
|
||||||
|
SCTPPayloadDUA = 10
|
||||||
|
SCTPPayloadASAP = 11
|
||||||
|
SCTPPayloadENRP = 12
|
||||||
|
SCTPPayloadH323 = 13
|
||||||
|
SCTPPayloadQIPC = 14
|
||||||
|
SCTPPayloadSIMCO = 15
|
||||||
|
SCTPPayloadDDPSegment = 16
|
||||||
|
SCTPPayloadDDPStream = 17
|
||||||
|
SCTPPayloadS1AP = 18
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p SCTPPayloadProtocol) String() string {
|
||||||
|
switch p {
|
||||||
|
case SCTPProtocolReserved:
|
||||||
|
return "Reserved"
|
||||||
|
case SCTPPayloadUIA:
|
||||||
|
return "UIA"
|
||||||
|
case SCTPPayloadM2UA:
|
||||||
|
return "M2UA"
|
||||||
|
case SCTPPayloadM3UA:
|
||||||
|
return "M3UA"
|
||||||
|
case SCTPPayloadSUA:
|
||||||
|
return "SUA"
|
||||||
|
case SCTPPayloadM2PA:
|
||||||
|
return "M2PA"
|
||||||
|
case SCTPPayloadV5UA:
|
||||||
|
return "V5UA"
|
||||||
|
case SCTPPayloadH248:
|
||||||
|
return "H.248"
|
||||||
|
case SCTPPayloadBICC:
|
||||||
|
return "BICC"
|
||||||
|
case SCTPPayloadTALI:
|
||||||
|
return "TALI"
|
||||||
|
case SCTPPayloadDUA:
|
||||||
|
return "DUA"
|
||||||
|
case SCTPPayloadASAP:
|
||||||
|
return "ASAP"
|
||||||
|
case SCTPPayloadENRP:
|
||||||
|
return "ENRP"
|
||||||
|
case SCTPPayloadH323:
|
||||||
|
return "H.323"
|
||||||
|
case SCTPPayloadQIPC:
|
||||||
|
return "QIPC"
|
||||||
|
case SCTPPayloadSIMCO:
|
||||||
|
return "SIMCO"
|
||||||
|
case SCTPPayloadDDPSegment:
|
||||||
|
return "DDPSegment"
|
||||||
|
case SCTPPayloadDDPStream:
|
||||||
|
return "DDPStream"
|
||||||
|
case SCTPPayloadS1AP:
|
||||||
|
return "S1AP"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Unknown(%d)", p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSCTPData(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
chunk, err := decodeSCTPChunk(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc := &SCTPData{
|
||||||
|
SCTPChunk: chunk,
|
||||||
|
Unordered: data[1]&0x4 != 0,
|
||||||
|
BeginFragment: data[1]&0x2 != 0,
|
||||||
|
EndFragment: data[1]&0x1 != 0,
|
||||||
|
TSN: binary.BigEndian.Uint32(data[4:8]),
|
||||||
|
StreamId: binary.BigEndian.Uint16(data[8:10]),
|
||||||
|
StreamSequence: binary.BigEndian.Uint16(data[10:12]),
|
||||||
|
PayloadProtocol: SCTPPayloadProtocol(binary.BigEndian.Uint32(data[12:16])),
|
||||||
|
}
|
||||||
|
// Length is the length in bytes of the data, INCLUDING the 16-byte header.
|
||||||
|
p.AddLayer(sc)
|
||||||
|
return p.NextDecoder(gopacket.LayerTypePayload)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (sc SCTPData) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
payload := b.Bytes()
|
||||||
|
// Pad the payload to a 32 bit boundary
|
||||||
|
if rem := len(payload) % 4; rem != 0 {
|
||||||
|
b.AppendBytes(4 - rem)
|
||||||
|
}
|
||||||
|
length := 16
|
||||||
|
bytes, err := b.PrependBytes(length)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(sc.Type)
|
||||||
|
flags := uint8(0)
|
||||||
|
if sc.Unordered {
|
||||||
|
flags |= 0x4
|
||||||
|
}
|
||||||
|
if sc.BeginFragment {
|
||||||
|
flags |= 0x2
|
||||||
|
}
|
||||||
|
if sc.EndFragment {
|
||||||
|
flags |= 0x1
|
||||||
|
}
|
||||||
|
bytes[1] = flags
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:4], uint16(length+len(payload)))
|
||||||
|
binary.BigEndian.PutUint32(bytes[4:8], sc.TSN)
|
||||||
|
binary.BigEndian.PutUint16(bytes[8:10], sc.StreamId)
|
||||||
|
binary.BigEndian.PutUint16(bytes[10:12], sc.StreamSequence)
|
||||||
|
binary.BigEndian.PutUint32(bytes[12:16], uint32(sc.PayloadProtocol))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPInitParameter is a parameter for an SCTP Init or InitAck packet.
|
||||||
|
type SCTPInitParameter SCTPParameter
|
||||||
|
|
||||||
|
// SCTPInit is used as the return value for both SCTPInit and SCTPInitAck
|
||||||
|
// messages.
|
||||||
|
type SCTPInit struct {
|
||||||
|
SCTPChunk
|
||||||
|
InitiateTag uint32
|
||||||
|
AdvertisedReceiverWindowCredit uint32
|
||||||
|
OutboundStreams, InboundStreams uint16
|
||||||
|
InitialTSN uint32
|
||||||
|
Parameters []SCTPInitParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns either gopacket.LayerTypeSCTPInit or gopacket.LayerTypeSCTPInitAck.
|
||||||
|
func (sc *SCTPInit) LayerType() gopacket.LayerType {
|
||||||
|
if sc.Type == SCTPChunkTypeInitAck {
|
||||||
|
return LayerTypeSCTPInitAck
|
||||||
|
}
|
||||||
|
// sc.Type == SCTPChunkTypeInit
|
||||||
|
return LayerTypeSCTPInit
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSCTPInit(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
chunk, err := decodeSCTPChunk(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc := &SCTPInit{
|
||||||
|
SCTPChunk: chunk,
|
||||||
|
InitiateTag: binary.BigEndian.Uint32(data[4:8]),
|
||||||
|
AdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]),
|
||||||
|
OutboundStreams: binary.BigEndian.Uint16(data[12:14]),
|
||||||
|
InboundStreams: binary.BigEndian.Uint16(data[14:16]),
|
||||||
|
InitialTSN: binary.BigEndian.Uint32(data[16:20]),
|
||||||
|
}
|
||||||
|
paramData := data[20:sc.ActualLength]
|
||||||
|
for len(paramData) > 0 {
|
||||||
|
p := SCTPInitParameter(decodeSCTPParameter(paramData))
|
||||||
|
paramData = paramData[p.ActualLength:]
|
||||||
|
sc.Parameters = append(sc.Parameters, p)
|
||||||
|
}
|
||||||
|
p.AddLayer(sc)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (sc SCTPInit) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
var payload []byte
|
||||||
|
for _, param := range sc.Parameters {
|
||||||
|
payload = append(payload, SCTPParameter(param).Bytes()...)
|
||||||
|
}
|
||||||
|
length := 20 + len(payload)
|
||||||
|
bytes, err := b.PrependBytes(roundUpToNearest4(length))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(sc.Type)
|
||||||
|
bytes[1] = sc.Flags
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
|
||||||
|
binary.BigEndian.PutUint32(bytes[4:8], sc.InitiateTag)
|
||||||
|
binary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit)
|
||||||
|
binary.BigEndian.PutUint16(bytes[12:14], sc.OutboundStreams)
|
||||||
|
binary.BigEndian.PutUint16(bytes[14:16], sc.InboundStreams)
|
||||||
|
binary.BigEndian.PutUint32(bytes[16:20], sc.InitialTSN)
|
||||||
|
copy(bytes[20:], payload)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPSack is the SCTP Selective ACK chunk layer.
|
||||||
|
type SCTPSack struct {
|
||||||
|
SCTPChunk
|
||||||
|
CumulativeTSNAck uint32
|
||||||
|
AdvertisedReceiverWindowCredit uint32
|
||||||
|
NumGapACKs, NumDuplicateTSNs uint16
|
||||||
|
GapACKs []uint16
|
||||||
|
DuplicateTSNs []uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType return LayerTypeSCTPSack
|
||||||
|
func (sc *SCTPSack) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeSCTPSack
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSCTPSack(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
chunk, err := decodeSCTPChunk(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc := &SCTPSack{
|
||||||
|
SCTPChunk: chunk,
|
||||||
|
CumulativeTSNAck: binary.BigEndian.Uint32(data[4:8]),
|
||||||
|
AdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]),
|
||||||
|
NumGapACKs: binary.BigEndian.Uint16(data[12:14]),
|
||||||
|
NumDuplicateTSNs: binary.BigEndian.Uint16(data[14:16]),
|
||||||
|
}
|
||||||
|
// We maximize gapAcks and dupTSNs here so we're not allocating tons
|
||||||
|
// of memory based on a user-controlable field. Our maximums are not exact,
|
||||||
|
// but should give us sane defaults... we'll still hit slice boundaries and
|
||||||
|
// fail if the user-supplied values are too high (in the for loops below), but
|
||||||
|
// the amount of memory we'll have allocated because of that should be small
|
||||||
|
// (< sc.ActualLength)
|
||||||
|
gapAcks := sc.SCTPChunk.ActualLength / 2
|
||||||
|
dupTSNs := (sc.SCTPChunk.ActualLength - gapAcks*2) / 4
|
||||||
|
if gapAcks > int(sc.NumGapACKs) {
|
||||||
|
gapAcks = int(sc.NumGapACKs)
|
||||||
|
}
|
||||||
|
if dupTSNs > int(sc.NumDuplicateTSNs) {
|
||||||
|
dupTSNs = int(sc.NumDuplicateTSNs)
|
||||||
|
}
|
||||||
|
sc.GapACKs = make([]uint16, 0, gapAcks)
|
||||||
|
sc.DuplicateTSNs = make([]uint32, 0, dupTSNs)
|
||||||
|
bytesRemaining := data[16:]
|
||||||
|
for i := 0; i < int(sc.NumGapACKs); i++ {
|
||||||
|
sc.GapACKs = append(sc.GapACKs, binary.BigEndian.Uint16(bytesRemaining[:2]))
|
||||||
|
bytesRemaining = bytesRemaining[2:]
|
||||||
|
}
|
||||||
|
for i := 0; i < int(sc.NumDuplicateTSNs); i++ {
|
||||||
|
sc.DuplicateTSNs = append(sc.DuplicateTSNs, binary.BigEndian.Uint32(bytesRemaining[:4]))
|
||||||
|
bytesRemaining = bytesRemaining[4:]
|
||||||
|
}
|
||||||
|
p.AddLayer(sc)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (sc SCTPSack) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
length := 16 + 2*len(sc.GapACKs) + 4*len(sc.DuplicateTSNs)
|
||||||
|
bytes, err := b.PrependBytes(roundUpToNearest4(length))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(sc.Type)
|
||||||
|
bytes[1] = sc.Flags
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
|
||||||
|
binary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck)
|
||||||
|
binary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit)
|
||||||
|
binary.BigEndian.PutUint16(bytes[12:14], uint16(len(sc.GapACKs)))
|
||||||
|
binary.BigEndian.PutUint16(bytes[14:16], uint16(len(sc.DuplicateTSNs)))
|
||||||
|
for i, v := range sc.GapACKs {
|
||||||
|
binary.BigEndian.PutUint16(bytes[16+i*2:], v)
|
||||||
|
}
|
||||||
|
offset := 16 + 2*len(sc.GapACKs)
|
||||||
|
for i, v := range sc.DuplicateTSNs {
|
||||||
|
binary.BigEndian.PutUint32(bytes[offset+i*4:], v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPHeartbeatParameter is the parameter type used by SCTP heartbeat and
|
||||||
|
// heartbeat ack layers.
|
||||||
|
type SCTPHeartbeatParameter SCTPParameter
|
||||||
|
|
||||||
|
// SCTPHeartbeat is the SCTP heartbeat layer, also used for heatbeat ack.
|
||||||
|
type SCTPHeartbeat struct {
|
||||||
|
SCTPChunk
|
||||||
|
Parameters []SCTPHeartbeatParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeSCTPHeartbeat.
|
||||||
|
func (sc *SCTPHeartbeat) LayerType() gopacket.LayerType {
|
||||||
|
if sc.Type == SCTPChunkTypeHeartbeatAck {
|
||||||
|
return LayerTypeSCTPHeartbeatAck
|
||||||
|
}
|
||||||
|
// sc.Type == SCTPChunkTypeHeartbeat
|
||||||
|
return LayerTypeSCTPHeartbeat
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSCTPHeartbeat(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
chunk, err := decodeSCTPChunk(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc := &SCTPHeartbeat{
|
||||||
|
SCTPChunk: chunk,
|
||||||
|
}
|
||||||
|
paramData := data[4:sc.Length]
|
||||||
|
for len(paramData) > 0 {
|
||||||
|
p := SCTPHeartbeatParameter(decodeSCTPParameter(paramData))
|
||||||
|
paramData = paramData[p.ActualLength:]
|
||||||
|
sc.Parameters = append(sc.Parameters, p)
|
||||||
|
}
|
||||||
|
p.AddLayer(sc)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (sc SCTPHeartbeat) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
var payload []byte
|
||||||
|
for _, param := range sc.Parameters {
|
||||||
|
payload = append(payload, SCTPParameter(param).Bytes()...)
|
||||||
|
}
|
||||||
|
length := 4 + len(payload)
|
||||||
|
|
||||||
|
bytes, err := b.PrependBytes(roundUpToNearest4(length))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(sc.Type)
|
||||||
|
bytes[1] = sc.Flags
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
|
||||||
|
copy(bytes[4:], payload)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPErrorParameter is the parameter type used by SCTP Abort and Error layers.
|
||||||
|
type SCTPErrorParameter SCTPParameter
|
||||||
|
|
||||||
|
// SCTPError is the SCTP error layer, also used for SCTP aborts.
|
||||||
|
type SCTPError struct {
|
||||||
|
SCTPChunk
|
||||||
|
Parameters []SCTPErrorParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns LayerTypeSCTPAbort or LayerTypeSCTPError.
|
||||||
|
func (sc *SCTPError) LayerType() gopacket.LayerType {
|
||||||
|
if sc.Type == SCTPChunkTypeAbort {
|
||||||
|
return LayerTypeSCTPAbort
|
||||||
|
}
|
||||||
|
// sc.Type == SCTPChunkTypeError
|
||||||
|
return LayerTypeSCTPError
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSCTPError(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
// remarkably similar to decodeSCTPHeartbeat ;)
|
||||||
|
chunk, err := decodeSCTPChunk(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc := &SCTPError{
|
||||||
|
SCTPChunk: chunk,
|
||||||
|
}
|
||||||
|
paramData := data[4:sc.Length]
|
||||||
|
for len(paramData) > 0 {
|
||||||
|
p := SCTPErrorParameter(decodeSCTPParameter(paramData))
|
||||||
|
paramData = paramData[p.ActualLength:]
|
||||||
|
sc.Parameters = append(sc.Parameters, p)
|
||||||
|
}
|
||||||
|
p.AddLayer(sc)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (sc SCTPError) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
var payload []byte
|
||||||
|
for _, param := range sc.Parameters {
|
||||||
|
payload = append(payload, SCTPParameter(param).Bytes()...)
|
||||||
|
}
|
||||||
|
length := 4 + len(payload)
|
||||||
|
|
||||||
|
bytes, err := b.PrependBytes(roundUpToNearest4(length))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(sc.Type)
|
||||||
|
bytes[1] = sc.Flags
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
|
||||||
|
copy(bytes[4:], payload)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPShutdown is the SCTP shutdown layer.
|
||||||
|
type SCTPShutdown struct {
|
||||||
|
SCTPChunk
|
||||||
|
CumulativeTSNAck uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeSCTPShutdown.
|
||||||
|
func (sc *SCTPShutdown) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdown }
|
||||||
|
|
||||||
|
func decodeSCTPShutdown(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
chunk, err := decodeSCTPChunk(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc := &SCTPShutdown{
|
||||||
|
SCTPChunk: chunk,
|
||||||
|
CumulativeTSNAck: binary.BigEndian.Uint32(data[4:8]),
|
||||||
|
}
|
||||||
|
p.AddLayer(sc)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (sc SCTPShutdown) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(8)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(sc.Type)
|
||||||
|
bytes[1] = sc.Flags
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:4], 8)
|
||||||
|
binary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPShutdownAck is the SCTP shutdown layer.
|
||||||
|
type SCTPShutdownAck struct {
|
||||||
|
SCTPChunk
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeSCTPShutdownAck.
|
||||||
|
func (sc *SCTPShutdownAck) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdownAck }
|
||||||
|
|
||||||
|
func decodeSCTPShutdownAck(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
chunk, err := decodeSCTPChunk(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc := &SCTPShutdownAck{
|
||||||
|
SCTPChunk: chunk,
|
||||||
|
}
|
||||||
|
p.AddLayer(sc)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (sc SCTPShutdownAck) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(sc.Type)
|
||||||
|
bytes[1] = sc.Flags
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:4], 4)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCTPCookieEcho is the SCTP Cookie Echo layer.
|
||||||
|
type SCTPCookieEcho struct {
|
||||||
|
SCTPChunk
|
||||||
|
Cookie []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeSCTPCookieEcho.
|
||||||
|
func (sc *SCTPCookieEcho) LayerType() gopacket.LayerType { return LayerTypeSCTPCookieEcho }
|
||||||
|
|
||||||
|
func decodeSCTPCookieEcho(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
chunk, err := decodeSCTPChunk(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc := &SCTPCookieEcho{
|
||||||
|
SCTPChunk: chunk,
|
||||||
|
}
|
||||||
|
sc.Cookie = data[4:sc.Length]
|
||||||
|
p.AddLayer(sc)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (sc SCTPCookieEcho) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
length := 4 + len(sc.Cookie)
|
||||||
|
bytes, err := b.PrependBytes(roundUpToNearest4(length))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(sc.Type)
|
||||||
|
bytes[1] = sc.Flags
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:4], uint16(length))
|
||||||
|
copy(bytes[4:], sc.Cookie)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// This struct is used by all empty SCTP chunks (currently CookieAck and
|
||||||
|
// ShutdownComplete).
|
||||||
|
type SCTPEmptyLayer struct {
|
||||||
|
SCTPChunk
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns either gopacket.LayerTypeSCTPShutdownComplete or
|
||||||
|
// LayerTypeSCTPCookieAck.
|
||||||
|
func (sc *SCTPEmptyLayer) LayerType() gopacket.LayerType {
|
||||||
|
if sc.Type == SCTPChunkTypeShutdownComplete {
|
||||||
|
return LayerTypeSCTPShutdownComplete
|
||||||
|
}
|
||||||
|
// sc.Type == SCTPChunkTypeCookieAck
|
||||||
|
return LayerTypeSCTPCookieAck
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeSCTPEmptyLayer(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
chunk, err := decodeSCTPChunk(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc := &SCTPEmptyLayer{
|
||||||
|
SCTPChunk: chunk,
|
||||||
|
}
|
||||||
|
p.AddLayer(sc)
|
||||||
|
return p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo is for gopacket.SerializableLayer.
|
||||||
|
func (sc SCTPEmptyLayer) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
bytes, err := b.PrependBytes(4)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bytes[0] = uint8(sc.Type)
|
||||||
|
bytes[1] = sc.Flags
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:4], 4)
|
||||||
|
return nil
|
||||||
|
}
|
2567
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/sflow.go
generated
vendored
Normal file
2567
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/sflow.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
542
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/sip.go
generated
vendored
Normal file
542
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/sip.go
generated
vendored
Normal file
|
@ -0,0 +1,542 @@
|
||||||
|
// Copyright 2017 Google, Inc. 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 (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SIPVersion defines the different versions of the SIP Protocol
|
||||||
|
type SIPVersion uint8
|
||||||
|
|
||||||
|
// Represents all the versions of SIP protocol
|
||||||
|
const (
|
||||||
|
SIPVersion1 SIPVersion = 1
|
||||||
|
SIPVersion2 SIPVersion = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
func (sv SIPVersion) String() string {
|
||||||
|
switch sv {
|
||||||
|
default:
|
||||||
|
// Defaulting to SIP/2.0
|
||||||
|
return "SIP/2.0"
|
||||||
|
case SIPVersion1:
|
||||||
|
return "SIP/1.0"
|
||||||
|
case SIPVersion2:
|
||||||
|
return "SIP/2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSIPVersion is used to get SIP version constant
|
||||||
|
func GetSIPVersion(version string) (SIPVersion, error) {
|
||||||
|
switch strings.ToUpper(version) {
|
||||||
|
case "SIP/1.0":
|
||||||
|
return SIPVersion1, nil
|
||||||
|
case "SIP/2.0":
|
||||||
|
return SIPVersion2, nil
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("Unknown SIP version: '%s'", version)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SIPMethod defines the different methods of the SIP Protocol
|
||||||
|
// defined in the different RFC's
|
||||||
|
type SIPMethod uint16
|
||||||
|
|
||||||
|
// Here are all the SIP methods
|
||||||
|
const (
|
||||||
|
SIPMethodInvite SIPMethod = 1 // INVITE [RFC3261]
|
||||||
|
SIPMethodAck SIPMethod = 2 // ACK [RFC3261]
|
||||||
|
SIPMethodBye SIPMethod = 3 // BYE [RFC3261]
|
||||||
|
SIPMethodCancel SIPMethod = 4 // CANCEL [RFC3261]
|
||||||
|
SIPMethodOptions SIPMethod = 5 // OPTIONS [RFC3261]
|
||||||
|
SIPMethodRegister SIPMethod = 6 // REGISTER [RFC3261]
|
||||||
|
SIPMethodPrack SIPMethod = 7 // PRACK [RFC3262]
|
||||||
|
SIPMethodSubscribe SIPMethod = 8 // SUBSCRIBE [RFC6665]
|
||||||
|
SIPMethodNotify SIPMethod = 9 // NOTIFY [RFC6665]
|
||||||
|
SIPMethodPublish SIPMethod = 10 // PUBLISH [RFC3903]
|
||||||
|
SIPMethodInfo SIPMethod = 11 // INFO [RFC6086]
|
||||||
|
SIPMethodRefer SIPMethod = 12 // REFER [RFC3515]
|
||||||
|
SIPMethodMessage SIPMethod = 13 // MESSAGE [RFC3428]
|
||||||
|
SIPMethodUpdate SIPMethod = 14 // UPDATE [RFC3311]
|
||||||
|
SIPMethodPing SIPMethod = 15 // PING [https://tools.ietf.org/html/draft-fwmiller-ping-03]
|
||||||
|
)
|
||||||
|
|
||||||
|
func (sm SIPMethod) String() string {
|
||||||
|
switch sm {
|
||||||
|
default:
|
||||||
|
return "Unknown method"
|
||||||
|
case SIPMethodInvite:
|
||||||
|
return "INVITE"
|
||||||
|
case SIPMethodAck:
|
||||||
|
return "ACK"
|
||||||
|
case SIPMethodBye:
|
||||||
|
return "BYE"
|
||||||
|
case SIPMethodCancel:
|
||||||
|
return "CANCEL"
|
||||||
|
case SIPMethodOptions:
|
||||||
|
return "OPTIONS"
|
||||||
|
case SIPMethodRegister:
|
||||||
|
return "REGISTER"
|
||||||
|
case SIPMethodPrack:
|
||||||
|
return "PRACK"
|
||||||
|
case SIPMethodSubscribe:
|
||||||
|
return "SUBSCRIBE"
|
||||||
|
case SIPMethodNotify:
|
||||||
|
return "NOTIFY"
|
||||||
|
case SIPMethodPublish:
|
||||||
|
return "PUBLISH"
|
||||||
|
case SIPMethodInfo:
|
||||||
|
return "INFO"
|
||||||
|
case SIPMethodRefer:
|
||||||
|
return "REFER"
|
||||||
|
case SIPMethodMessage:
|
||||||
|
return "MESSAGE"
|
||||||
|
case SIPMethodUpdate:
|
||||||
|
return "UPDATE"
|
||||||
|
case SIPMethodPing:
|
||||||
|
return "PING"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSIPMethod returns the constant of a SIP method
|
||||||
|
// from its string
|
||||||
|
func GetSIPMethod(method string) (SIPMethod, error) {
|
||||||
|
switch strings.ToUpper(method) {
|
||||||
|
case "INVITE":
|
||||||
|
return SIPMethodInvite, nil
|
||||||
|
case "ACK":
|
||||||
|
return SIPMethodAck, nil
|
||||||
|
case "BYE":
|
||||||
|
return SIPMethodBye, nil
|
||||||
|
case "CANCEL":
|
||||||
|
return SIPMethodCancel, nil
|
||||||
|
case "OPTIONS":
|
||||||
|
return SIPMethodOptions, nil
|
||||||
|
case "REGISTER":
|
||||||
|
return SIPMethodRegister, nil
|
||||||
|
case "PRACK":
|
||||||
|
return SIPMethodPrack, nil
|
||||||
|
case "SUBSCRIBE":
|
||||||
|
return SIPMethodSubscribe, nil
|
||||||
|
case "NOTIFY":
|
||||||
|
return SIPMethodNotify, nil
|
||||||
|
case "PUBLISH":
|
||||||
|
return SIPMethodPublish, nil
|
||||||
|
case "INFO":
|
||||||
|
return SIPMethodInfo, nil
|
||||||
|
case "REFER":
|
||||||
|
return SIPMethodRefer, nil
|
||||||
|
case "MESSAGE":
|
||||||
|
return SIPMethodMessage, nil
|
||||||
|
case "UPDATE":
|
||||||
|
return SIPMethodUpdate, nil
|
||||||
|
case "PING":
|
||||||
|
return SIPMethodPing, nil
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("Unknown SIP method: '%s'", method)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here is a correspondance between long header names and short
|
||||||
|
// as defined in rfc3261 in section 20
|
||||||
|
var compactSipHeadersCorrespondance = map[string]string{
|
||||||
|
"accept-contact": "a",
|
||||||
|
"allow-events": "u",
|
||||||
|
"call-id": "i",
|
||||||
|
"contact": "m",
|
||||||
|
"content-encoding": "e",
|
||||||
|
"content-length": "l",
|
||||||
|
"content-type": "c",
|
||||||
|
"event": "o",
|
||||||
|
"from": "f",
|
||||||
|
"identity": "y",
|
||||||
|
"refer-to": "r",
|
||||||
|
"referred-by": "b",
|
||||||
|
"reject-contact": "j",
|
||||||
|
"request-disposition": "d",
|
||||||
|
"session-expires": "x",
|
||||||
|
"subject": "s",
|
||||||
|
"supported": "k",
|
||||||
|
"to": "t",
|
||||||
|
"via": "v",
|
||||||
|
}
|
||||||
|
|
||||||
|
// SIP object will contains information about decoded SIP packet.
|
||||||
|
// -> The SIP Version
|
||||||
|
// -> The SIP Headers (in a map[string][]string because of multiple headers with the same name
|
||||||
|
// -> The SIP Method
|
||||||
|
// -> The SIP Response code (if it's a response)
|
||||||
|
// -> The SIP Status line (if it's a response)
|
||||||
|
// You can easily know the type of the packet with the IsResponse boolean
|
||||||
|
//
|
||||||
|
type SIP struct {
|
||||||
|
BaseLayer
|
||||||
|
|
||||||
|
// Base information
|
||||||
|
Version SIPVersion
|
||||||
|
Method SIPMethod
|
||||||
|
Headers map[string][]string
|
||||||
|
|
||||||
|
// Request
|
||||||
|
RequestURI string
|
||||||
|
|
||||||
|
// Response
|
||||||
|
IsResponse bool
|
||||||
|
ResponseCode int
|
||||||
|
ResponseStatus string
|
||||||
|
|
||||||
|
// Private fields
|
||||||
|
cseq int64
|
||||||
|
contentLength int64
|
||||||
|
lastHeaderParsed string
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeSIP decodes the byte slice into a SIP type. It also
|
||||||
|
// setups the application Layer in PacketBuilder.
|
||||||
|
func decodeSIP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
s := NewSIP()
|
||||||
|
err := s.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(s)
|
||||||
|
p.SetApplicationLayer(s)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSIP instantiates a new empty SIP object
|
||||||
|
func NewSIP() *SIP {
|
||||||
|
s := new(SIP)
|
||||||
|
s.Headers = make(map[string][]string)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeSIP.
|
||||||
|
func (s *SIP) LayerType() gopacket.LayerType {
|
||||||
|
return LayerTypeSIP
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payload returns the base layer payload
|
||||||
|
func (s *SIP) Payload() []byte {
|
||||||
|
return s.BaseLayer.Payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode returns the set of layer types that this DecodingLayer can decode
|
||||||
|
func (s *SIP) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeSIP
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType returns the layer type contained by this DecodingLayer
|
||||||
|
func (s *SIP) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypePayload
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
var offset int
|
||||||
|
|
||||||
|
// Iterate on all lines of the SIP Headers
|
||||||
|
// and stop when we reach the SDP (aka when the new line
|
||||||
|
// is at index 0 of the remaining packet)
|
||||||
|
buffer := bytes.NewBuffer(data)
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
// Read next line
|
||||||
|
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
|
||||||
|
if len(line) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// First line is the SIP request/response line
|
||||||
|
// Other lines are headers
|
||||||
|
if countLines == 0 {
|
||||||
|
err = s.ParseFirstLine(line)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
err = s.ParseHeader(line)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
countLines++
|
||||||
|
}
|
||||||
|
s.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseFirstLine will compute the first line of a SIP packet.
|
||||||
|
// The first line will tell us if it's a request or a response.
|
||||||
|
//
|
||||||
|
// Examples of first line of SIP Prococol :
|
||||||
|
//
|
||||||
|
// Request : INVITE bob@example.com SIP/2.0
|
||||||
|
// Response : SIP/2.0 200 OK
|
||||||
|
// Response : SIP/2.0 501 Not Implemented
|
||||||
|
//
|
||||||
|
func (s *SIP) ParseFirstLine(firstLine []byte) error {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Splits line by space
|
||||||
|
splits := strings.SplitN(string(firstLine), " ", 3)
|
||||||
|
|
||||||
|
// We must have at least 3 parts
|
||||||
|
if len(splits) < 3 {
|
||||||
|
return fmt.Errorf("invalid first SIP line: '%s'", string(firstLine))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the SIP packet type
|
||||||
|
if strings.HasPrefix(splits[0], "SIP") {
|
||||||
|
|
||||||
|
// --> Response
|
||||||
|
s.IsResponse = true
|
||||||
|
|
||||||
|
// Validate SIP Version
|
||||||
|
s.Version, err = GetSIPVersion(splits[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute code
|
||||||
|
s.ResponseCode, err = strconv.Atoi(splits[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute status line
|
||||||
|
s.ResponseStatus = splits[2]
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// --> Request
|
||||||
|
|
||||||
|
// Validate method
|
||||||
|
s.Method, err = GetSIPMethod(splits[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.RequestURI = splits[1]
|
||||||
|
|
||||||
|
// Validate SIP Version
|
||||||
|
s.Version, err = GetSIPVersion(splits[2])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseHeader will parse a SIP Header
|
||||||
|
// SIP Headers are quite simple, there are colon separated name and value
|
||||||
|
// Headers can be spread over multiple lines
|
||||||
|
//
|
||||||
|
// Examples of header :
|
||||||
|
//
|
||||||
|
// CSeq: 1 REGISTER
|
||||||
|
// Via: SIP/2.0/UDP there.com:5060
|
||||||
|
// Authorization:Digest username="UserB",
|
||||||
|
// realm="MCI WorldCom SIP",
|
||||||
|
// nonce="1cec4341ae6cbe5a359ea9c8e88df84f", opaque="",
|
||||||
|
// uri="sip:ss2.wcom.com", response="71ba27c64bd01de719686aa4590d5824"
|
||||||
|
//
|
||||||
|
func (s *SIP) ParseHeader(header []byte) (err error) {
|
||||||
|
|
||||||
|
// Ignore empty headers
|
||||||
|
if len(header) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this is the following of last header
|
||||||
|
// RFC 3261 - 7.3.1 - Header Field Format specify that following lines of
|
||||||
|
// multiline headers must begin by SP or TAB
|
||||||
|
if header[0] == '\t' || header[0] == ' ' {
|
||||||
|
|
||||||
|
header = bytes.TrimSpace(header)
|
||||||
|
s.Headers[s.lastHeaderParsed][len(s.Headers[s.lastHeaderParsed])-1] += fmt.Sprintf(" %s", string(header))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the ':' to separate header name and value
|
||||||
|
index := bytes.Index(header, []byte(":"))
|
||||||
|
if index >= 0 {
|
||||||
|
|
||||||
|
headerName := strings.ToLower(string(bytes.Trim(header[:index], " ")))
|
||||||
|
headerValue := string(bytes.Trim(header[index+1:], " "))
|
||||||
|
|
||||||
|
// Add header to object
|
||||||
|
s.Headers[headerName] = append(s.Headers[headerName], headerValue)
|
||||||
|
s.lastHeaderParsed = headerName
|
||||||
|
|
||||||
|
// Compute specific headers
|
||||||
|
err = s.ParseSpecificHeaders(headerName, headerValue)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseSpecificHeaders will parse some specific key values from
|
||||||
|
// specific headers like CSeq or Content-Length integer values
|
||||||
|
func (s *SIP) ParseSpecificHeaders(headerName string, headerValue string) (err error) {
|
||||||
|
|
||||||
|
switch headerName {
|
||||||
|
case "cseq":
|
||||||
|
|
||||||
|
// CSeq header value is formatted like that :
|
||||||
|
// CSeq: 123 INVITE
|
||||||
|
// We split the value to parse Cseq integer value, and method
|
||||||
|
splits := strings.Split(headerValue, " ")
|
||||||
|
if len(splits) > 1 {
|
||||||
|
|
||||||
|
// Parse Cseq
|
||||||
|
s.cseq, err = strconv.ParseInt(splits[0], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate method
|
||||||
|
if s.IsResponse {
|
||||||
|
s.Method, err = GetSIPMethod(splits[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case "content-length":
|
||||||
|
|
||||||
|
// Parse Content-Length
|
||||||
|
s.contentLength, err = strconv.ParseInt(headerValue, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllHeaders will return the full headers of the
|
||||||
|
// current SIP packets in a map[string][]string
|
||||||
|
func (s *SIP) GetAllHeaders() map[string][]string {
|
||||||
|
return s.Headers
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetHeader will return all the headers with
|
||||||
|
// the specified name.
|
||||||
|
func (s *SIP) GetHeader(headerName string) []string {
|
||||||
|
headerName = strings.ToLower(headerName)
|
||||||
|
h := make([]string, 0)
|
||||||
|
if _, ok := s.Headers[headerName]; ok {
|
||||||
|
return s.Headers[headerName]
|
||||||
|
}
|
||||||
|
compactHeader := compactSipHeadersCorrespondance[headerName]
|
||||||
|
if _, ok := s.Headers[compactHeader]; ok {
|
||||||
|
return s.Headers[compactHeader]
|
||||||
|
}
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFirstHeader will return the first header with
|
||||||
|
// the specified name. If the current SIP packet has multiple
|
||||||
|
// headers with the same name, it returns the first.
|
||||||
|
func (s *SIP) GetFirstHeader(headerName string) string {
|
||||||
|
headers := s.GetHeader(headerName)
|
||||||
|
if len(headers) > 0 {
|
||||||
|
return headers[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Some handy getters for most used SIP headers
|
||||||
|
//
|
||||||
|
|
||||||
|
// GetAuthorization will return the Authorization
|
||||||
|
// header of the current SIP packet
|
||||||
|
func (s *SIP) GetAuthorization() string {
|
||||||
|
return s.GetFirstHeader("Authorization")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFrom will return the From
|
||||||
|
// header of the current SIP packet
|
||||||
|
func (s *SIP) GetFrom() string {
|
||||||
|
return s.GetFirstHeader("From")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTo will return the To
|
||||||
|
// header of the current SIP packet
|
||||||
|
func (s *SIP) GetTo() string {
|
||||||
|
return s.GetFirstHeader("To")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContact will return the Contact
|
||||||
|
// header of the current SIP packet
|
||||||
|
func (s *SIP) GetContact() string {
|
||||||
|
return s.GetFirstHeader("Contact")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCallID will return the Call-ID
|
||||||
|
// header of the current SIP packet
|
||||||
|
func (s *SIP) GetCallID() string {
|
||||||
|
return s.GetFirstHeader("Call-ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserAgent will return the User-Agent
|
||||||
|
// header of the current SIP packet
|
||||||
|
func (s *SIP) GetUserAgent() string {
|
||||||
|
return s.GetFirstHeader("User-Agent")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContentLength will return the parsed integer
|
||||||
|
// Content-Length header of the current SIP packet
|
||||||
|
func (s *SIP) GetContentLength() int64 {
|
||||||
|
return s.contentLength
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCSeq will return the parsed integer CSeq header
|
||||||
|
// header of the current SIP packet
|
||||||
|
func (s *SIP) GetCSeq() int64 {
|
||||||
|
return s.cseq
|
||||||
|
}
|
27
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/stp.go
generated
vendored
Normal file
27
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/stp.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2017 Google, Inc. 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 (
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// STP decode spanning tree protocol packets to transport BPDU (bridge protocol data unit) message.
|
||||||
|
type STP struct {
|
||||||
|
BaseLayer
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeSTP.
|
||||||
|
func (s *STP) LayerType() gopacket.LayerType { return LayerTypeSTP }
|
||||||
|
|
||||||
|
func decodeSTP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
stp := &STP{}
|
||||||
|
stp.Contents = data[:]
|
||||||
|
// TODO: parse the STP protocol into actual subfields.
|
||||||
|
p.AddLayer(stp)
|
||||||
|
return nil
|
||||||
|
}
|
341
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/tcp.go
generated
vendored
Normal file
341
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/tcp.go
generated
vendored
Normal file
|
@ -0,0 +1,341 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TCP is the layer for TCP headers.
|
||||||
|
type TCP struct {
|
||||||
|
BaseLayer
|
||||||
|
SrcPort, DstPort TCPPort
|
||||||
|
Seq uint32
|
||||||
|
Ack uint32
|
||||||
|
DataOffset uint8
|
||||||
|
FIN, SYN, RST, PSH, ACK, URG, ECE, CWR, NS bool
|
||||||
|
Window uint16
|
||||||
|
Checksum uint16
|
||||||
|
Urgent uint16
|
||||||
|
sPort, dPort []byte
|
||||||
|
Options []TCPOption
|
||||||
|
Padding []byte
|
||||||
|
opts [4]TCPOption
|
||||||
|
tcpipchecksum
|
||||||
|
}
|
||||||
|
|
||||||
|
// TCPOptionKind represents a TCP option code.
|
||||||
|
type TCPOptionKind uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
TCPOptionKindEndList = 0
|
||||||
|
TCPOptionKindNop = 1
|
||||||
|
TCPOptionKindMSS = 2 // len = 4
|
||||||
|
TCPOptionKindWindowScale = 3 // len = 3
|
||||||
|
TCPOptionKindSACKPermitted = 4 // len = 2
|
||||||
|
TCPOptionKindSACK = 5 // len = n
|
||||||
|
TCPOptionKindEcho = 6 // len = 6, obsolete
|
||||||
|
TCPOptionKindEchoReply = 7 // len = 6, obsolete
|
||||||
|
TCPOptionKindTimestamps = 8 // len = 10
|
||||||
|
TCPOptionKindPartialOrderConnectionPermitted = 9 // len = 2, obsolete
|
||||||
|
TCPOptionKindPartialOrderServiceProfile = 10 // len = 3, obsolete
|
||||||
|
TCPOptionKindCC = 11 // obsolete
|
||||||
|
TCPOptionKindCCNew = 12 // obsolete
|
||||||
|
TCPOptionKindCCEcho = 13 // obsolete
|
||||||
|
TCPOptionKindAltChecksum = 14 // len = 3, obsolete
|
||||||
|
TCPOptionKindAltChecksumData = 15 // len = n, obsolete
|
||||||
|
)
|
||||||
|
|
||||||
|
func (k TCPOptionKind) String() string {
|
||||||
|
switch k {
|
||||||
|
case TCPOptionKindEndList:
|
||||||
|
return "EndList"
|
||||||
|
case TCPOptionKindNop:
|
||||||
|
return "NOP"
|
||||||
|
case TCPOptionKindMSS:
|
||||||
|
return "MSS"
|
||||||
|
case TCPOptionKindWindowScale:
|
||||||
|
return "WindowScale"
|
||||||
|
case TCPOptionKindSACKPermitted:
|
||||||
|
return "SACKPermitted"
|
||||||
|
case TCPOptionKindSACK:
|
||||||
|
return "SACK"
|
||||||
|
case TCPOptionKindEcho:
|
||||||
|
return "Echo"
|
||||||
|
case TCPOptionKindEchoReply:
|
||||||
|
return "EchoReply"
|
||||||
|
case TCPOptionKindTimestamps:
|
||||||
|
return "Timestamps"
|
||||||
|
case TCPOptionKindPartialOrderConnectionPermitted:
|
||||||
|
return "PartialOrderConnectionPermitted"
|
||||||
|
case TCPOptionKindPartialOrderServiceProfile:
|
||||||
|
return "PartialOrderServiceProfile"
|
||||||
|
case TCPOptionKindCC:
|
||||||
|
return "CC"
|
||||||
|
case TCPOptionKindCCNew:
|
||||||
|
return "CCNew"
|
||||||
|
case TCPOptionKindCCEcho:
|
||||||
|
return "CCEcho"
|
||||||
|
case TCPOptionKindAltChecksum:
|
||||||
|
return "AltChecksum"
|
||||||
|
case TCPOptionKindAltChecksumData:
|
||||||
|
return "AltChecksumData"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("Unknown(%d)", k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TCPOption struct {
|
||||||
|
OptionType TCPOptionKind
|
||||||
|
OptionLength uint8
|
||||||
|
OptionData []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t TCPOption) String() string {
|
||||||
|
hd := hex.EncodeToString(t.OptionData)
|
||||||
|
if len(hd) > 0 {
|
||||||
|
hd = " 0x" + hd
|
||||||
|
}
|
||||||
|
switch t.OptionType {
|
||||||
|
case TCPOptionKindMSS:
|
||||||
|
if len(t.OptionData) >= 2 {
|
||||||
|
return fmt.Sprintf("TCPOption(%s:%v%s)",
|
||||||
|
t.OptionType,
|
||||||
|
binary.BigEndian.Uint16(t.OptionData),
|
||||||
|
hd)
|
||||||
|
}
|
||||||
|
|
||||||
|
case TCPOptionKindTimestamps:
|
||||||
|
if len(t.OptionData) == 8 {
|
||||||
|
return fmt.Sprintf("TCPOption(%s:%v/%v%s)",
|
||||||
|
t.OptionType,
|
||||||
|
binary.BigEndian.Uint32(t.OptionData[:4]),
|
||||||
|
binary.BigEndian.Uint32(t.OptionData[4:8]),
|
||||||
|
hd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("TCPOption(%s:%s)", t.OptionType, hd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeTCP
|
||||||
|
func (t *TCP) LayerType() gopacket.LayerType { return LayerTypeTCP }
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
// See the docs for gopacket.SerializableLayer for more info.
|
||||||
|
func (t *TCP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
var optionLength int
|
||||||
|
for _, o := range t.Options {
|
||||||
|
switch o.OptionType {
|
||||||
|
case 0, 1:
|
||||||
|
optionLength += 1
|
||||||
|
default:
|
||||||
|
optionLength += 2 + len(o.OptionData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if opts.FixLengths {
|
||||||
|
if rem := optionLength % 4; rem != 0 {
|
||||||
|
t.Padding = lotsOfZeros[:4-rem]
|
||||||
|
}
|
||||||
|
t.DataOffset = uint8((len(t.Padding) + optionLength + 20) / 4)
|
||||||
|
}
|
||||||
|
bytes, err := b.PrependBytes(20 + optionLength + len(t.Padding))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes, uint16(t.SrcPort))
|
||||||
|
binary.BigEndian.PutUint16(bytes[2:], uint16(t.DstPort))
|
||||||
|
binary.BigEndian.PutUint32(bytes[4:], t.Seq)
|
||||||
|
binary.BigEndian.PutUint32(bytes[8:], t.Ack)
|
||||||
|
binary.BigEndian.PutUint16(bytes[12:], t.flagsAndOffset())
|
||||||
|
binary.BigEndian.PutUint16(bytes[14:], t.Window)
|
||||||
|
binary.BigEndian.PutUint16(bytes[18:], t.Urgent)
|
||||||
|
start := 20
|
||||||
|
for _, o := range t.Options {
|
||||||
|
bytes[start] = byte(o.OptionType)
|
||||||
|
switch o.OptionType {
|
||||||
|
case 0, 1:
|
||||||
|
start++
|
||||||
|
default:
|
||||||
|
if opts.FixLengths {
|
||||||
|
o.OptionLength = uint8(len(o.OptionData) + 2)
|
||||||
|
}
|
||||||
|
bytes[start+1] = o.OptionLength
|
||||||
|
copy(bytes[start+2:start+len(o.OptionData)+2], o.OptionData)
|
||||||
|
start += len(o.OptionData) + 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
copy(bytes[start:], t.Padding)
|
||||||
|
if opts.ComputeChecksums {
|
||||||
|
// zero out checksum bytes in current serialization.
|
||||||
|
bytes[16] = 0
|
||||||
|
bytes[17] = 0
|
||||||
|
csum, err := t.computeChecksum(b.Bytes(), IPProtocolTCP)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.Checksum = csum
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint16(bytes[16:], t.Checksum)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TCP) ComputeChecksum() (uint16, error) {
|
||||||
|
return t.computeChecksum(append(t.Contents, t.Payload...), IPProtocolTCP)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TCP) flagsAndOffset() uint16 {
|
||||||
|
f := uint16(t.DataOffset) << 12
|
||||||
|
if t.FIN {
|
||||||
|
f |= 0x0001
|
||||||
|
}
|
||||||
|
if t.SYN {
|
||||||
|
f |= 0x0002
|
||||||
|
}
|
||||||
|
if t.RST {
|
||||||
|
f |= 0x0004
|
||||||
|
}
|
||||||
|
if t.PSH {
|
||||||
|
f |= 0x0008
|
||||||
|
}
|
||||||
|
if t.ACK {
|
||||||
|
f |= 0x0010
|
||||||
|
}
|
||||||
|
if t.URG {
|
||||||
|
f |= 0x0020
|
||||||
|
}
|
||||||
|
if t.ECE {
|
||||||
|
f |= 0x0040
|
||||||
|
}
|
||||||
|
if t.CWR {
|
||||||
|
f |= 0x0080
|
||||||
|
}
|
||||||
|
if t.NS {
|
||||||
|
f |= 0x0100
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tcp *TCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 20 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("Invalid TCP header. Length %d less than 20", len(data))
|
||||||
|
}
|
||||||
|
tcp.SrcPort = TCPPort(binary.BigEndian.Uint16(data[0:2]))
|
||||||
|
tcp.sPort = data[0:2]
|
||||||
|
tcp.DstPort = TCPPort(binary.BigEndian.Uint16(data[2:4]))
|
||||||
|
tcp.dPort = data[2:4]
|
||||||
|
tcp.Seq = binary.BigEndian.Uint32(data[4:8])
|
||||||
|
tcp.Ack = binary.BigEndian.Uint32(data[8:12])
|
||||||
|
tcp.DataOffset = data[12] >> 4
|
||||||
|
tcp.FIN = data[13]&0x01 != 0
|
||||||
|
tcp.SYN = data[13]&0x02 != 0
|
||||||
|
tcp.RST = data[13]&0x04 != 0
|
||||||
|
tcp.PSH = data[13]&0x08 != 0
|
||||||
|
tcp.ACK = data[13]&0x10 != 0
|
||||||
|
tcp.URG = data[13]&0x20 != 0
|
||||||
|
tcp.ECE = data[13]&0x40 != 0
|
||||||
|
tcp.CWR = data[13]&0x80 != 0
|
||||||
|
tcp.NS = data[12]&0x01 != 0
|
||||||
|
tcp.Window = binary.BigEndian.Uint16(data[14:16])
|
||||||
|
tcp.Checksum = binary.BigEndian.Uint16(data[16:18])
|
||||||
|
tcp.Urgent = binary.BigEndian.Uint16(data[18:20])
|
||||||
|
if tcp.Options == nil {
|
||||||
|
// Pre-allocate to avoid allocating a slice.
|
||||||
|
tcp.Options = tcp.opts[:0]
|
||||||
|
} else {
|
||||||
|
tcp.Options = tcp.Options[:0]
|
||||||
|
}
|
||||||
|
tcp.Padding = tcp.Padding[:0]
|
||||||
|
if tcp.DataOffset < 5 {
|
||||||
|
return fmt.Errorf("Invalid TCP data offset %d < 5", tcp.DataOffset)
|
||||||
|
}
|
||||||
|
dataStart := int(tcp.DataOffset) * 4
|
||||||
|
if dataStart > len(data) {
|
||||||
|
df.SetTruncated()
|
||||||
|
tcp.Payload = nil
|
||||||
|
tcp.Contents = data
|
||||||
|
return errors.New("TCP data offset greater than packet length")
|
||||||
|
}
|
||||||
|
tcp.Contents = data[:dataStart]
|
||||||
|
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]
|
||||||
|
switch opt.OptionType {
|
||||||
|
case TCPOptionKindEndList: // End of options
|
||||||
|
opt.OptionLength = 1
|
||||||
|
tcp.Padding = data[1:]
|
||||||
|
break OPTIONS
|
||||||
|
case TCPOptionKindNop: // 1 byte padding
|
||||||
|
opt.OptionLength = 1
|
||||||
|
default:
|
||||||
|
if len(data) < 2 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("Invalid TCP option length. Length %d less than 2", len(data))
|
||||||
|
}
|
||||||
|
opt.OptionLength = data[1]
|
||||||
|
if opt.OptionLength < 2 {
|
||||||
|
return fmt.Errorf("Invalid TCP option length %d < 2", opt.OptionLength)
|
||||||
|
} else if int(opt.OptionLength) > len(data) {
|
||||||
|
df.SetTruncated()
|
||||||
|
return fmt.Errorf("Invalid TCP option length %d exceeds remaining %d bytes", opt.OptionLength, len(data))
|
||||||
|
}
|
||||||
|
opt.OptionData = data[2:opt.OptionLength]
|
||||||
|
}
|
||||||
|
data = data[opt.OptionLength:]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TCP) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeTCP
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TCP) NextLayerType() gopacket.LayerType {
|
||||||
|
lt := t.DstPort.LayerType()
|
||||||
|
if lt == gopacket.LayerTypePayload {
|
||||||
|
lt = t.SrcPort.LayerType()
|
||||||
|
}
|
||||||
|
return lt
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeTCP(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
tcp := &TCP{}
|
||||||
|
err := tcp.DecodeFromBytes(data, p)
|
||||||
|
p.AddLayer(tcp)
|
||||||
|
p.SetTransportLayer(tcp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if p.DecodeOptions().DecodeStreamsAsDatagrams {
|
||||||
|
return p.NextDecoder(tcp.NextLayerType())
|
||||||
|
} else {
|
||||||
|
return p.NextDecoder(gopacket.LayerTypePayload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TCP) TransportFlow() gopacket.Flow {
|
||||||
|
return gopacket.NewFlow(EndpointTCPPort, t.sPort, t.dPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
// For testing only
|
||||||
|
func (t *TCP) SetInternalPortsForTesting() {
|
||||||
|
t.sPort = make([]byte, 2)
|
||||||
|
t.dPort = make([]byte, 2)
|
||||||
|
binary.BigEndian.PutUint16(t.sPort, uint16(t.SrcPort))
|
||||||
|
binary.BigEndian.PutUint16(t.dPort, uint16(t.DstPort))
|
||||||
|
}
|
104
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/tcpip.go
generated
vendored
Normal file
104
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/tcpip.go
generated
vendored
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
// Copyright 2009-2011 Andreas Krennmair. 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 (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Checksum computation for TCP/UDP.
|
||||||
|
type tcpipchecksum struct {
|
||||||
|
pseudoheader tcpipPseudoHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
type tcpipPseudoHeader interface {
|
||||||
|
pseudoheaderChecksum() (uint32, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ip *IPv4) pseudoheaderChecksum() (csum uint32, err error) {
|
||||||
|
if err := ip.AddressTo4(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
csum += (uint32(ip.SrcIP[0]) + uint32(ip.SrcIP[2])) << 8
|
||||||
|
csum += uint32(ip.SrcIP[1]) + uint32(ip.SrcIP[3])
|
||||||
|
csum += (uint32(ip.DstIP[0]) + uint32(ip.DstIP[2])) << 8
|
||||||
|
csum += uint32(ip.DstIP[1]) + uint32(ip.DstIP[3])
|
||||||
|
return csum, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ip *IPv6) pseudoheaderChecksum() (csum uint32, err error) {
|
||||||
|
if err := ip.AddressTo16(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
for i := 0; i < 16; i += 2 {
|
||||||
|
csum += uint32(ip.SrcIP[i]) << 8
|
||||||
|
csum += uint32(ip.SrcIP[i+1])
|
||||||
|
csum += uint32(ip.DstIP[i]) << 8
|
||||||
|
csum += uint32(ip.DstIP[i+1])
|
||||||
|
}
|
||||||
|
return csum, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the TCP/IP checksum defined in rfc1071. The passed-in csum is any
|
||||||
|
// initial checksum data that's already been computed.
|
||||||
|
func tcpipChecksum(data []byte, csum uint32) uint16 {
|
||||||
|
// to handle odd lengths, we loop to length - 1, incrementing by 2, then
|
||||||
|
// handle the last byte specifically by checking against the original
|
||||||
|
// length.
|
||||||
|
length := len(data) - 1
|
||||||
|
for i := 0; i < length; i += 2 {
|
||||||
|
// For our test packet, doing this manually is about 25% faster
|
||||||
|
// (740 ns vs. 1000ns) than doing it by calling binary.BigEndian.Uint16.
|
||||||
|
csum += uint32(data[i]) << 8
|
||||||
|
csum += uint32(data[i+1])
|
||||||
|
}
|
||||||
|
if len(data)%2 == 1 {
|
||||||
|
csum += uint32(data[length]) << 8
|
||||||
|
}
|
||||||
|
for csum > 0xffff {
|
||||||
|
csum = (csum >> 16) + (csum & 0xffff)
|
||||||
|
}
|
||||||
|
return ^uint16(csum)
|
||||||
|
}
|
||||||
|
|
||||||
|
// computeChecksum computes a TCP or UDP checksum. headerAndPayload is the
|
||||||
|
// serialized TCP or UDP header plus its payload, with the checksum zero'd
|
||||||
|
// out. headerProtocol is the IP protocol number of the upper-layer header.
|
||||||
|
func (c *tcpipchecksum) computeChecksum(headerAndPayload []byte, headerProtocol IPProtocol) (uint16, error) {
|
||||||
|
if c.pseudoheader == nil {
|
||||||
|
return 0, errors.New("TCP/IP layer 4 checksum cannot be computed without network layer... call SetNetworkLayerForChecksum to set which layer to use")
|
||||||
|
}
|
||||||
|
length := uint32(len(headerAndPayload))
|
||||||
|
csum, err := c.pseudoheader.pseudoheaderChecksum()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
csum += uint32(headerProtocol)
|
||||||
|
csum += length & 0xffff
|
||||||
|
csum += length >> 16
|
||||||
|
return tcpipChecksum(headerAndPayload, csum), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNetworkLayerForChecksum tells this layer which network layer is wrapping it.
|
||||||
|
// This is needed for computing the checksum when serializing, since TCP/IP transport
|
||||||
|
// layer checksums depends on fields in the IPv4 or IPv6 layer that contains it.
|
||||||
|
// The passed in layer must be an *IPv4 or *IPv6.
|
||||||
|
func (i *tcpipchecksum) SetNetworkLayerForChecksum(l gopacket.NetworkLayer) error {
|
||||||
|
switch v := l.(type) {
|
||||||
|
case *IPv4:
|
||||||
|
i.pseudoheader = v
|
||||||
|
case *IPv6:
|
||||||
|
i.pseudoheader = v
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("cannot use layer type %v for tcp checksum network layer", l.LayerType())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
103
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/test_creator.py
generated
vendored
Normal file
103
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/test_creator.py
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# Copyright 2012 Google, Inc. All rights reserved.
|
||||||
|
|
||||||
|
"""TestCreator creates test templates from pcap files."""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import base64
|
||||||
|
import glob
|
||||||
|
import re
|
||||||
|
import string
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
class Packet(object):
|
||||||
|
"""Helper class encapsulating packet from a pcap file."""
|
||||||
|
|
||||||
|
def __init__(self, packet_lines):
|
||||||
|
self.packet_lines = packet_lines
|
||||||
|
self.data = self._DecodeText(packet_lines)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _DecodeText(cls, packet_lines):
|
||||||
|
packet_bytes = []
|
||||||
|
# First line is timestamp and stuff, skip it.
|
||||||
|
# Format: 0x0010: 0000 0020 3aff 3ffe 0000 0000 0000 0000 ....:.?.........
|
||||||
|
|
||||||
|
for line in packet_lines[1:]:
|
||||||
|
m = re.match(r'\s+0x[a-f\d]+:\s+((?:[\da-f]{2,4}\s)*)', line, re.IGNORECASE)
|
||||||
|
if m is None: continue
|
||||||
|
for hexpart in m.group(1).split():
|
||||||
|
packet_bytes.append(base64.b16decode(hexpart.upper()))
|
||||||
|
return ''.join(packet_bytes)
|
||||||
|
|
||||||
|
def Test(self, name, link_type):
|
||||||
|
"""Yields a test using this packet, as a set of lines."""
|
||||||
|
yield '// testPacket%s is the packet:' % name
|
||||||
|
for line in self.packet_lines:
|
||||||
|
yield '// ' + line
|
||||||
|
yield 'var testPacket%s = []byte{' % name
|
||||||
|
data = list(self.data)
|
||||||
|
while data:
|
||||||
|
linebytes, data = data[:16], data[16:]
|
||||||
|
yield ''.join(['\t'] + ['0x%02x, ' % ord(c) for c in linebytes])
|
||||||
|
yield '}'
|
||||||
|
yield 'func TestPacket%s(t *testing.T) {' % name
|
||||||
|
yield '\tp := gopacket.NewPacket(testPacket%s, LinkType%s, gopacket.Default)' % (name, link_type)
|
||||||
|
yield '\tif p.ErrorLayer() != nil {'
|
||||||
|
yield '\t\tt.Error("Failed to decode packet:", p.ErrorLayer().Error())'
|
||||||
|
yield '\t}'
|
||||||
|
yield '\tcheckLayers(p, []gopacket.LayerType{LayerType%s, FILL_ME_IN_WITH_ACTUAL_LAYERS}, t)' % link_type
|
||||||
|
yield '}'
|
||||||
|
yield 'func BenchmarkDecodePacket%s(b *testing.B) {' % name
|
||||||
|
yield '\tfor i := 0; i < b.N; i++ {'
|
||||||
|
yield '\t\tgopacket.NewPacket(testPacket%s, LinkType%s, gopacket.NoCopy)' % (name, link_type)
|
||||||
|
yield '\t}'
|
||||||
|
yield '}'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def GetTcpdumpOutput(filename):
|
||||||
|
"""Runs tcpdump on the given file, returning output as string."""
|
||||||
|
return subprocess.check_output(
|
||||||
|
['tcpdump', '-XX', '-s', '0', '-n', '-r', filename])
|
||||||
|
|
||||||
|
|
||||||
|
def TcpdumpOutputToPackets(output):
|
||||||
|
"""Reads a pcap file with TCPDump, yielding Packet objects."""
|
||||||
|
pdata = []
|
||||||
|
for line in output.splitlines():
|
||||||
|
if line[0] not in string.whitespace and pdata:
|
||||||
|
yield Packet(pdata)
|
||||||
|
pdata = []
|
||||||
|
pdata.append(line)
|
||||||
|
if pdata:
|
||||||
|
yield Packet(pdata)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
class CustomHelpFormatter(argparse.ArgumentDefaultsHelpFormatter):
|
||||||
|
def _format_usage(self, usage, actions, groups, prefix=None):
|
||||||
|
header =('TestCreator creates gopacket tests using a pcap file.\n\n'
|
||||||
|
'Tests are written to standard out... they can then be \n'
|
||||||
|
'copied into the file of your choice and modified as \n'
|
||||||
|
'you see.\n\n')
|
||||||
|
return header + argparse.ArgumentDefaultsHelpFormatter._format_usage(
|
||||||
|
self, usage, actions, groups, prefix)
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(formatter_class=CustomHelpFormatter)
|
||||||
|
parser.add_argument('--link_type', default='Ethernet', help='the link type (default: %(default)s)')
|
||||||
|
parser.add_argument('--name', default='Packet%d', help='the layer type, must have "%d" inside it')
|
||||||
|
parser.add_argument('files', metavar='file.pcap', type=str, nargs='+', help='the files to process')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
for arg in args.files:
|
||||||
|
for path in glob.glob(arg):
|
||||||
|
for i, packet in enumerate(TcpdumpOutputToPackets(GetTcpdumpOutput(path))):
|
||||||
|
print '\n'.join(packet.Test(
|
||||||
|
args.name % i, args.link_type))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
283
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/tls.go
generated
vendored
Normal file
283
trunk/3rdparty/srs-bench/vendor/github.com/google/gopacket/layers/tls.go
generated
vendored
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
// Copyright 2018 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"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/google/gopacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TLSType defines the type of data after the TLS Record
|
||||||
|
type TLSType uint8
|
||||||
|
|
||||||
|
// TLSType known values.
|
||||||
|
const (
|
||||||
|
TLSChangeCipherSpec TLSType = 20
|
||||||
|
TLSAlert TLSType = 21
|
||||||
|
TLSHandshake TLSType = 22
|
||||||
|
TLSApplicationData TLSType = 23
|
||||||
|
TLSUnknown TLSType = 255
|
||||||
|
)
|
||||||
|
|
||||||
|
// String shows the register type nicely formatted
|
||||||
|
func (tt TLSType) String() string {
|
||||||
|
switch tt {
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
case TLSChangeCipherSpec:
|
||||||
|
return "Change Cipher Spec"
|
||||||
|
case TLSAlert:
|
||||||
|
return "Alert"
|
||||||
|
case TLSHandshake:
|
||||||
|
return "Handshake"
|
||||||
|
case TLSApplicationData:
|
||||||
|
return "Application Data"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLSVersion represents the TLS version in numeric format
|
||||||
|
type TLSVersion uint16
|
||||||
|
|
||||||
|
// Strings shows the TLS version nicely formatted
|
||||||
|
func (tv TLSVersion) String() string {
|
||||||
|
switch tv {
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
case 0x0200:
|
||||||
|
return "SSL 2.0"
|
||||||
|
case 0x0300:
|
||||||
|
return "SSL 3.0"
|
||||||
|
case 0x0301:
|
||||||
|
return "TLS 1.0"
|
||||||
|
case 0x0302:
|
||||||
|
return "TLS 1.1"
|
||||||
|
case 0x0303:
|
||||||
|
return "TLS 1.2"
|
||||||
|
case 0x0304:
|
||||||
|
return "TLS 1.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLS is specified in RFC 5246
|
||||||
|
//
|
||||||
|
// TLS Record Protocol
|
||||||
|
// 0 1 2 3 4 5 6 7 8
|
||||||
|
// +--+--+--+--+--+--+--+--+
|
||||||
|
// | Content Type |
|
||||||
|
// +--+--+--+--+--+--+--+--+
|
||||||
|
// | Version (major) |
|
||||||
|
// +--+--+--+--+--+--+--+--+
|
||||||
|
// | Version (minor) |
|
||||||
|
// +--+--+--+--+--+--+--+--+
|
||||||
|
// | Length |
|
||||||
|
// +--+--+--+--+--+--+--+--+
|
||||||
|
// | Length |
|
||||||
|
// +--+--+--+--+--+--+--+--+
|
||||||
|
|
||||||
|
// TLS is actually a slide of TLSrecord structures
|
||||||
|
type TLS struct {
|
||||||
|
BaseLayer
|
||||||
|
|
||||||
|
// TLS Records
|
||||||
|
ChangeCipherSpec []TLSChangeCipherSpecRecord
|
||||||
|
Handshake []TLSHandshakeRecord
|
||||||
|
AppData []TLSAppDataRecord
|
||||||
|
Alert []TLSAlertRecord
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLSRecordHeader contains all the information that each TLS Record types should have
|
||||||
|
type TLSRecordHeader struct {
|
||||||
|
ContentType TLSType
|
||||||
|
Version TLSVersion
|
||||||
|
Length uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayerType returns gopacket.LayerTypeTLS.
|
||||||
|
func (t *TLS) LayerType() gopacket.LayerType { return LayerTypeTLS }
|
||||||
|
|
||||||
|
// decodeTLS decodes the byte slice into a TLS type. It also
|
||||||
|
// setups the application Layer in PacketBuilder.
|
||||||
|
func decodeTLS(data []byte, p gopacket.PacketBuilder) error {
|
||||||
|
t := &TLS{}
|
||||||
|
err := t.DecodeFromBytes(data, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.AddLayer(t)
|
||||||
|
p.SetApplicationLayer(t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFromBytes decodes the slice into the TLS struct.
|
||||||
|
func (t *TLS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
t.BaseLayer.Contents = data
|
||||||
|
t.BaseLayer.Payload = nil
|
||||||
|
|
||||||
|
t.ChangeCipherSpec = t.ChangeCipherSpec[:0]
|
||||||
|
t.Handshake = t.Handshake[:0]
|
||||||
|
t.AppData = t.AppData[:0]
|
||||||
|
t.Alert = t.Alert[:0]
|
||||||
|
|
||||||
|
return t.decodeTLSRecords(data, df)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TLS) decodeTLSRecords(data []byte, df gopacket.DecodeFeedback) error {
|
||||||
|
if len(data) < 5 {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("TLS record too short")
|
||||||
|
}
|
||||||
|
|
||||||
|
// since there are no further layers, the baselayer's content is
|
||||||
|
// pointing to this layer
|
||||||
|
// TODO: Consider removing this
|
||||||
|
t.BaseLayer = BaseLayer{Contents: data[:len(data)]}
|
||||||
|
|
||||||
|
var h TLSRecordHeader
|
||||||
|
h.ContentType = TLSType(data[0])
|
||||||
|
h.Version = TLSVersion(binary.BigEndian.Uint16(data[1:3]))
|
||||||
|
h.Length = binary.BigEndian.Uint16(data[3:5])
|
||||||
|
|
||||||
|
if h.ContentType.String() == "Unknown" {
|
||||||
|
return errors.New("Unknown TLS record type")
|
||||||
|
}
|
||||||
|
|
||||||
|
hl := 5 // header length
|
||||||
|
tl := hl + int(h.Length)
|
||||||
|
if len(data) < tl {
|
||||||
|
df.SetTruncated()
|
||||||
|
return errors.New("TLS packet length mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch h.ContentType {
|
||||||
|
default:
|
||||||
|
return errors.New("Unknown TLS record type")
|
||||||
|
case TLSChangeCipherSpec:
|
||||||
|
var r TLSChangeCipherSpecRecord
|
||||||
|
e := r.decodeFromBytes(h, data[hl:tl], df)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
t.ChangeCipherSpec = append(t.ChangeCipherSpec, r)
|
||||||
|
case TLSAlert:
|
||||||
|
var r TLSAlertRecord
|
||||||
|
e := r.decodeFromBytes(h, data[hl:tl], df)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
t.Alert = append(t.Alert, r)
|
||||||
|
case TLSHandshake:
|
||||||
|
var r TLSHandshakeRecord
|
||||||
|
e := r.decodeFromBytes(h, data[hl:tl], df)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
t.Handshake = append(t.Handshake, r)
|
||||||
|
case TLSApplicationData:
|
||||||
|
var r TLSAppDataRecord
|
||||||
|
e := r.decodeFromBytes(h, data[hl:tl], df)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
t.AppData = append(t.AppData, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) == tl {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return t.decodeTLSRecords(data[tl:len(data)], df)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDecode implements gopacket.DecodingLayer.
|
||||||
|
func (t *TLS) CanDecode() gopacket.LayerClass {
|
||||||
|
return LayerTypeTLS
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextLayerType implements gopacket.DecodingLayer.
|
||||||
|
func (t *TLS) NextLayerType() gopacket.LayerType {
|
||||||
|
return gopacket.LayerTypeZero
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payload returns nil, since TLS encrypted payload is inside TLSAppDataRecord
|
||||||
|
func (t *TLS) Payload() []byte {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeTo writes the serialized form of this layer into the
|
||||||
|
// SerializationBuffer, implementing gopacket.SerializableLayer.
|
||||||
|
func (t *TLS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
|
||||||
|
totalLength := 0
|
||||||
|
for _, record := range t.ChangeCipherSpec {
|
||||||
|
if opts.FixLengths {
|
||||||
|
record.Length = 1
|
||||||
|
}
|
||||||
|
totalLength += 5 + 1 // length of header + record
|
||||||
|
}
|
||||||
|
for range t.Handshake {
|
||||||
|
totalLength += 5
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
for _, record := range t.AppData {
|
||||||
|
if opts.FixLengths {
|
||||||
|
record.Length = uint16(len(record.Payload))
|
||||||
|
}
|
||||||
|
totalLength += 5 + len(record.Payload)
|
||||||
|
}
|
||||||
|
for _, record := range t.Alert {
|
||||||
|
if len(record.EncryptedMsg) == 0 {
|
||||||
|
if opts.FixLengths {
|
||||||
|
record.Length = 2
|
||||||
|
}
|
||||||
|
totalLength += 5 + 2
|
||||||
|
} else {
|
||||||
|
if opts.FixLengths {
|
||||||
|
record.Length = uint16(len(record.EncryptedMsg))
|
||||||
|
}
|
||||||
|
totalLength += 5 + len(record.EncryptedMsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data, err := b.PrependBytes(totalLength)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
off := 0
|
||||||
|
for _, record := range t.ChangeCipherSpec {
|
||||||
|
off = encodeHeader(record.TLSRecordHeader, data, off)
|
||||||
|
data[off] = byte(record.Message)
|
||||||
|
off++
|
||||||
|
}
|
||||||
|
for _, record := range t.Handshake {
|
||||||
|
off = encodeHeader(record.TLSRecordHeader, data, off)
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
for _, record := range t.AppData {
|
||||||
|
off = encodeHeader(record.TLSRecordHeader, data, off)
|
||||||
|
copy(data[off:], record.Payload)
|
||||||
|
off += len(record.Payload)
|
||||||
|
}
|
||||||
|
for _, record := range t.Alert {
|
||||||
|
off = encodeHeader(record.TLSRecordHeader, data, off)
|
||||||
|
if len(record.EncryptedMsg) == 0 {
|
||||||
|
data[off] = byte(record.Level)
|
||||||
|
data[off+1] = byte(record.Description)
|
||||||
|
off += 2
|
||||||
|
} else {
|
||||||
|
copy(data[off:], record.EncryptedMsg)
|
||||||
|
off += len(record.EncryptedMsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeHeader(header TLSRecordHeader, data []byte, offset int) int {
|
||||||
|
data[offset] = byte(header.ContentType)
|
||||||
|
binary.BigEndian.PutUint16(data[offset+1:], uint16(header.Version))
|
||||||
|
binary.BigEndian.PutUint16(data[offset+3:], header.Length)
|
||||||
|
|
||||||
|
return offset + 5
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue