mirror of
				https://github.com/zr-hebo/sniffer-agent.git
				synced 2025-11-01 05:19:19 +08:00 
			
		
		
		
	优化抓包性能
This commit is contained in:
		
							
								
								
									
										4
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							| @@ -111,11 +111,11 @@ | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "golang.org/x/sys/unix", | ||||
| 			"Rev": "ac767d655b305d4e9612f5f6e33120b9176c4ad4" | ||||
| 			"Rev": "fde4db37ae7ad8191b03d30d27f258b5291ae4e3" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "golang.org/x/sys/windows", | ||||
| 			"Rev": "ac767d655b305d4e9612f5f6e33120b9176c4ad4" | ||||
| 			"Rev": "fde4db37ae7ad8191b03d30d27f258b5291ae4e3" | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
|   | ||||
| @@ -8,7 +8,6 @@ import ( | ||||
| 	"github.com/google/gopacket/pcap" | ||||
| 	"golang.org/x/net/bpf" | ||||
|  | ||||
| 	// "github.com/google/gopacket/pcap" | ||||
| 	"github.com/google/gopacket/pcapgo" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| 	"github.com/zr-hebo/sniffer-agent/model" | ||||
|   | ||||
							
								
								
									
										38
									
								
								vendor/github.com/google/gopacket/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								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
									
								
								vendor/github.com/google/gopacket/.travis.gofmt.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/google/gopacket/.travis.gofmt.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable 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
									
								
								vendor/github.com/google/gopacket/.travis.golint.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/google/gopacket/.travis.golint.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable 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
									
								
								vendor/github.com/google/gopacket/.travis.govet.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/google/gopacket/.travis.govet.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable 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
									
								
								vendor/github.com/google/gopacket/.travis.install.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/google/gopacket/.travis.install.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable 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
									
								
								vendor/github.com/google/gopacket/.travis.script.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/google/gopacket/.travis.script.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable 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 | ||||
							
								
								
									
										55
									
								
								vendor/github.com/google/gopacket/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								vendor/github.com/google/gopacket/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| language: go | ||||
| go: | ||||
|  - 1.11.x | ||||
|  - 1.12.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 | ||||
|     - os: windows | ||||
|       go: 1.x | ||||
|       # winpcap does not work on travis ci - so install nmap to get libpcap | ||||
|       before_install: choco install nmap | ||||
|     - stage: style | ||||
|       name: "fmt/vet/lint" | ||||
|       go: 1.x | ||||
|       script: | ||||
|         - ./.travis.gofmt.sh | ||||
|         - ./.travis.govet.sh | ||||
|         - ./.travis.golint.sh | ||||
|  | ||||
| stages: | ||||
|   - style | ||||
|   - test | ||||
							
								
								
									
										215
									
								
								vendor/github.com/google/gopacket/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								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. | ||||
							
								
								
									
										12
									
								
								vendor/github.com/google/gopacket/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								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.7 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
									
								
								vendor/github.com/google/gopacket/base.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								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
									
								
								vendor/github.com/google/gopacket/decode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								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
									
								
								vendor/github.com/google/gopacket/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										432
									
								
								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.NewFlow(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
									
								
								vendor/github.com/google/gopacket/flows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								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
									
								
								vendor/github.com/google/gopacket/gc
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										288
									
								
								vendor/github.com/google/gopacket/gc
									
									
									
										generated
									
									
										vendored
									
									
										Executable 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 | ||||
							
								
								
									
										75
									
								
								vendor/github.com/google/gopacket/gen.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								vendor/github.com/google/gopacket/gen.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| // 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. | ||||
|  | ||||
| // +build ignore | ||||
|  | ||||
| // This file generates LayersDecoder function for DecodingLayerContainer | ||||
| // go run gen.go | gofmt > layers_decoder.go | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| const headerFmt = `// Copyright 2019 The GoPacket Authors. All rights reserved. | ||||
|  | ||||
| package gopacket | ||||
|  | ||||
| // Created by gen.go, don't edit manually | ||||
| // Generated at %s | ||||
|  | ||||
| // LayersDecoder returns DecodingLayerFunc for specified | ||||
| // DecodingLayerContainer, LayerType value to start decoding with and | ||||
| // some DecodeFeedback. | ||||
| func LayersDecoder(dl DecodingLayerContainer, first LayerType, df DecodeFeedback) DecodingLayerFunc { | ||||
|   firstDec, ok := dl.Decoder(first) | ||||
|   if !ok { | ||||
|     return func([]byte, *[]LayerType) (LayerType, error) { | ||||
|       return first, nil | ||||
|     } | ||||
|   } | ||||
| ` | ||||
|  | ||||
| var funcBody = `return func(data []byte, decoded *[]LayerType) (LayerType, error) { | ||||
|   *decoded = (*decoded)[:0] // Truncated decoded layers. | ||||
|   typ := first | ||||
|   decoder := firstDec | ||||
|   for { | ||||
|     if err := decoder.DecodeFromBytes(data, df); err != nil { | ||||
|       return LayerTypeZero, err | ||||
|     } | ||||
|     *decoded = append(*decoded, typ) | ||||
|     typ = decoder.NextLayerType() | ||||
|     if data = decoder.LayerPayload(); len(data) == 0 { | ||||
|       break | ||||
|     } | ||||
|     if decoder, ok = dlc.Decoder(typ); !ok { | ||||
|       return typ, nil | ||||
|     } | ||||
|   } | ||||
|   return LayerTypeZero, nil | ||||
| }` | ||||
|  | ||||
| func main() { | ||||
| 	fmt.Fprintf(os.Stderr, "Writing results to stdout\n") | ||||
| 	types := []string{ | ||||
| 		"DecodingLayerSparse", | ||||
| 		"DecodingLayerArray", | ||||
| 		"DecodingLayerMap", | ||||
| 	} | ||||
|  | ||||
| 	fmt.Printf(headerFmt, time.Now()) | ||||
| 	for _, t := range types { | ||||
| 		fmt.Printf("if dlc, ok := dl.(%s); ok {", t) | ||||
| 		fmt.Println(funcBody) | ||||
| 		fmt.Println("}") | ||||
| 	} | ||||
| 	fmt.Println("dlc := dl") | ||||
| 	fmt.Println(funcBody) | ||||
| 	fmt.Println("}") | ||||
| } | ||||
							
								
								
									
										8
									
								
								vendor/github.com/google/gopacket/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/google/gopacket/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| module github.com/google/gopacket | ||||
|  | ||||
| go 1.12 | ||||
|  | ||||
| require ( | ||||
| 	golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 | ||||
| 	golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67 | ||||
| ) | ||||
							
								
								
									
										7
									
								
								vendor/github.com/google/gopacket/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/google/gopacket/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= | ||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67 h1:1Fzlr8kkDLQwqMP8GxrhptBLqZG/EDpiATneiZHY998= | ||||
| golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
							
								
								
									
										107
									
								
								vendor/github.com/google/gopacket/layerclass.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/.lint_blacklist
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								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 | ||||
							
								
								
									
										109
									
								
								vendor/github.com/google/gopacket/layers/arp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/google/gopacket/layers/arp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| // 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" | ||||
|  | ||||
| 	"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 { | ||||
| 	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]) | ||||
| 	arp.SourceHwAddress = data[8 : 8+arp.HwAddressSize] | ||||
| 	arp.SourceProtAddress = data[8+arp.HwAddressSize : 8+arp.HwAddressSize+arp.ProtAddressSize] | ||||
| 	arp.DstHwAddress = data[8+arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+arp.ProtAddressSize] | ||||
| 	arp.DstProtAddress = data[8+2*arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+2*arp.ProtAddressSize] | ||||
|  | ||||
| 	arpLength := 8 + 2*arp.HwAddressSize + 2*arp.ProtAddressSize | ||||
| 	arp.Contents = data[:arpLength] | ||||
| 	arp.Payload = data[arpLength:] | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // 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
									
								
								vendor/github.com/google/gopacket/layers/asf.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/asf_presencepong.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/base.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/bfd.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										481
									
								
								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 | ||||
| } | ||||
							
								
								
									
										651
									
								
								vendor/github.com/google/gopacket/layers/cdp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										651
									
								
								vendor/github.com/google/gopacket/layers/cdp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,651 @@ | ||||
| // 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" | ||||
| 	"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:]) | ||||
| 	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) (values []CiscoDiscoveryValue, err error) { | ||||
| 	for len(data) > 0 { | ||||
| 		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 | ||||
| 		} | ||||
| 		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) | ||||
| 	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
									
								
								vendor/github.com/google/gopacket/layers/ctp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								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) | ||||
| } | ||||
							
								
								
									
										585
									
								
								vendor/github.com/google/gopacket/layers/dhcpv4.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										585
									
								
								vendor/github.com/google/gopacket/layers/dhcpv4.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,585 @@ | ||||
| // 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 { | ||||
| 	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 | ||||
| 		} | ||||
| 	} | ||||
| 	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") | ||||
| ) | ||||
							
								
								
									
										341
									
								
								vendor/github.com/google/gopacket/layers/dhcpv6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								vendor/github.com/google/gopacket/layers/dhcpv6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,341 @@ | ||||
| // 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" | ||||
| 	"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 { | ||||
| 	d.BaseLayer = BaseLayer{Contents: data} | ||||
| 	d.Options = d.Options[:0] | ||||
| 	d.MsgType = DHCPv6MsgType(data[0]) | ||||
|  | ||||
| 	offset := 0 | ||||
| 	if d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply { | ||||
| 		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 errors.New("Not enough bytes to decode: " + string(len(data))) | ||||
| 	} | ||||
|  | ||||
| 	d.Type = DHCPv6DUIDType(binary.BigEndian.Uint16(data[:2])) | ||||
| 	if d.Type == DHCPv6DUIDTypeLLT || d.Type == DHCPv6DUIDTypeLL { | ||||
| 		d.HardwareType = data[2:4] | ||||
| 	} | ||||
|  | ||||
| 	if d.Type == DHCPv6DUIDTypeLLT { | ||||
| 		d.Time = data[4:8] | ||||
| 		d.LinkLayerAddress = net.HardwareAddr(data[8:]) | ||||
| 	} else if d.Type == DHCPv6DUIDTypeEN { | ||||
| 		d.EnterpriseNumber = data[2:6] | ||||
| 		d.Identifier = data[6:] | ||||
| 	} else { // DHCPv6DUIDTypeLL | ||||
| 		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
									
								
								vendor/github.com/google/gopacket/layers/dhcpv6_options.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										621
									
								
								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) < 2 { | ||||
| 		return errors.New("not enough data to decode") | ||||
| 	} | ||||
| 	o.Code = DHCPv6Opt(binary.BigEndian.Uint16(data[0:2])) | ||||
| 	if len(data) < 3 { | ||||
| 		return errors.New("not enough data to decode") | ||||
| 	} | ||||
| 	o.Length = binary.BigEndian.Uint16(data[2:4]) | ||||
| 	o.Data = data[4 : 4+o.Length] | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										1053
									
								
								vendor/github.com/google/gopacket/layers/dns.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1053
									
								
								vendor/github.com/google/gopacket/layers/dns.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										61
									
								
								vendor/github.com/google/gopacket/layers/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								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 | ||||
							
								
								
									
										2105
									
								
								vendor/github.com/google/gopacket/layers/dot11.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2105
									
								
								vendor/github.com/google/gopacket/layers/dot11.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										71
									
								
								vendor/github.com/google/gopacket/layers/dot1q.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								vendor/github.com/google/gopacket/layers/dot1q.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| // 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 { | ||||
| 	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 | ||||
| } | ||||
							
								
								
									
										106
									
								
								vendor/github.com/google/gopacket/layers/eap.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/github.com/google/gopacket/layers/eap.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| // 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 { | ||||
| 	e.Code = EAPCode(data[0]) | ||||
| 	e.Id = data[1] | ||||
| 	e.Length = binary.BigEndian.Uint16(data[2:4]) | ||||
| 	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) | ||||
| } | ||||
							
								
								
									
										298
									
								
								vendor/github.com/google/gopacket/layers/eapol.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								vendor/github.com/google/gopacket/layers/eapol.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,298 @@ | ||||
| // 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 { | ||||
| 	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
									
								
								vendor/github.com/google/gopacket/layers/endpoints.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								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)) | ||||
| } | ||||
							
								
								
									
										448
									
								
								vendor/github.com/google/gopacket/layers/enums.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										448
									
								
								vendor/github.com/google/gopacket/layers/enums.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,448 @@ | ||||
| // 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" | ||||
| 	"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 | ||||
| } | ||||
|  | ||||
| // errorFunc returns a decoder that spits out a specific error message. | ||||
| func errorFunc(msg string) gopacket.Decoder { | ||||
| 	var e = errors.New(msg) | ||||
| 	return gopacket.DecodeFunc(func([]byte, gopacket.PacketBuilder) error { | ||||
| 		return e | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // EthernetType is an enumeration of ethernet type values, and acts as a decoder | ||||
| // for any type it supports. | ||||
| type EthernetType uint16 | ||||
|  | ||||
| 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 | ||||
| 	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 | ||||
| 	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} | ||||
|  | ||||
| 	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
									
								
								vendor/github.com/google/gopacket/layers/enums_generated.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										434
									
								
								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", | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										45
									
								
								vendor/github.com/google/gopacket/layers/etherip.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/ethernet.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/fddi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								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) | ||||
| } | ||||
							
								
								
									
										109
									
								
								vendor/github.com/google/gopacket/layers/gen.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/google/gopacket/layers/gen.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. | ||||
|  | ||||
| // +build ignore | ||||
|  | ||||
| // This binary pulls known ports from IANA, and uses them to populate | ||||
| // iana_ports.go's TCPPortNames and UDPPortNames maps. | ||||
| // | ||||
| //  go run gen.go | gofmt > iana_ports.go | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/xml" | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| const fmtString = `// Copyright 2012 Google, Inc. All rights reserved. | ||||
|  | ||||
| package layers | ||||
|  | ||||
| // Created by gen.go, don't edit manually | ||||
| // Generated at %s | ||||
| // Fetched from %q | ||||
|  | ||||
| // TCPPortNames contains the port names for all TCP ports. | ||||
| var TCPPortNames = tcpPortNames | ||||
|  | ||||
| // UDPPortNames contains the port names for all UDP ports. | ||||
| var UDPPortNames = udpPortNames | ||||
|  | ||||
| // SCTPPortNames contains the port names for all SCTP ports. | ||||
| var SCTPPortNames = sctpPortNames | ||||
|  | ||||
| var tcpPortNames = map[TCPPort]string{ | ||||
| %s} | ||||
| var udpPortNames = map[UDPPort]string{ | ||||
| %s} | ||||
| var sctpPortNames = map[SCTPPort]string{ | ||||
| %s} | ||||
| ` | ||||
|  | ||||
| var url = flag.String("url", "http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml", "URL to grab port numbers from") | ||||
|  | ||||
| func main() { | ||||
| 	fmt.Fprintf(os.Stderr, "Fetching ports from %q\n", *url) | ||||
| 	resp, err := http.Get(*url) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 	body, err := ioutil.ReadAll(resp.Body) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	fmt.Fprintln(os.Stderr, "Parsing XML") | ||||
| 	var registry struct { | ||||
| 		Records []struct { | ||||
| 			Protocol string `xml:"protocol"` | ||||
| 			Number   string `xml:"number"` | ||||
| 			Name     string `xml:"name"` | ||||
| 		} `xml:"record"` | ||||
| 	} | ||||
| 	xml.Unmarshal(body, ®istry) | ||||
| 	var tcpPorts bytes.Buffer | ||||
| 	var udpPorts bytes.Buffer | ||||
| 	var sctpPorts bytes.Buffer | ||||
| 	done := map[string]map[int]bool{ | ||||
| 		"tcp":  map[int]bool{}, | ||||
| 		"udp":  map[int]bool{}, | ||||
| 		"sctp": map[int]bool{}, | ||||
| 	} | ||||
| 	for _, r := range registry.Records { | ||||
| 		port, err := strconv.Atoi(r.Number) | ||||
| 		if err != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		if r.Name == "" { | ||||
| 			continue | ||||
| 		} | ||||
| 		var b *bytes.Buffer | ||||
| 		switch r.Protocol { | ||||
| 		case "tcp": | ||||
| 			b = &tcpPorts | ||||
| 		case "udp": | ||||
| 			b = &udpPorts | ||||
| 		case "sctp": | ||||
| 			b = &sctpPorts | ||||
| 		default: | ||||
| 			continue | ||||
| 		} | ||||
| 		if done[r.Protocol][port] { | ||||
| 			continue | ||||
| 		} | ||||
| 		done[r.Protocol][port] = true | ||||
| 		fmt.Fprintf(b, "\t%d: %q,\n", port, r.Name) | ||||
| 	} | ||||
| 	fmt.Fprintln(os.Stderr, "Writing results to stdout") | ||||
| 	fmt.Printf(fmtString, time.Now(), *url, tcpPorts.String(), udpPorts.String(), sctpPorts.String()) | ||||
| } | ||||
							
								
								
									
										104
									
								
								vendor/github.com/google/gopacket/layers/gen2.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								vendor/github.com/google/gopacket/layers/gen2.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| // 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. | ||||
|  | ||||
| // +build ignore | ||||
|  | ||||
| // This binary handles creating string constants and function templates for enums. | ||||
| // | ||||
| //  go run gen.go | gofmt > enums_generated.go | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"text/template" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| const fmtString = `// Copyright 2012 Google, Inc. All rights reserved. | ||||
|  | ||||
| package layers | ||||
|  | ||||
| // Created by gen2.go, don't edit manually | ||||
| // Generated at %s | ||||
|  | ||||
| import ( | ||||
|   "fmt" | ||||
|  | ||||
|   "github.com/google/gopacket" | ||||
| ) | ||||
|  | ||||
| ` | ||||
|  | ||||
| var funcsTmpl = template.Must(template.New("foo").Parse(` | ||||
| // Decoder calls {{.Name}}Metadata.DecodeWith's decoder. | ||||
| func (a {{.Name}}) Decode(data []byte, p gopacket.PacketBuilder) error { | ||||
| 	return {{.Name}}Metadata[a].DecodeWith.Decode(data, p) | ||||
| } | ||||
| // String returns {{.Name}}Metadata.Name. | ||||
| func (a {{.Name}}) String() string { | ||||
| 	return {{.Name}}Metadata[a].Name | ||||
| } | ||||
| // LayerType returns {{.Name}}Metadata.LayerType. | ||||
| func (a {{.Name}}) LayerType() gopacket.LayerType { | ||||
| 	return {{.Name}}Metadata[a].LayerType | ||||
| } | ||||
|  | ||||
| type errorDecoderFor{{.Name}} int | ||||
| func (a *errorDecoderFor{{.Name}}) Decode(data []byte, p gopacket.PacketBuilder) error { | ||||
|   return a | ||||
| } | ||||
| func (a *errorDecoderFor{{.Name}}) Error() string { | ||||
|   return fmt.Sprintf("Unable to decode {{.Name}} %d", int(*a)) | ||||
| } | ||||
|  | ||||
| var errorDecodersFor{{.Name}} [{{.Num}}]errorDecoderFor{{.Name}} | ||||
| var {{.Name}}Metadata [{{.Num}}]EnumMetadata | ||||
|  | ||||
| func initUnknownTypesFor{{.Name}}() { | ||||
|   for i := 0; i < {{.Num}}; i++ { | ||||
|     errorDecodersFor{{.Name}}[i] = errorDecoderFor{{.Name}}(i) | ||||
|     {{.Name}}Metadata[i] = EnumMetadata{ | ||||
|       DecodeWith: &errorDecodersFor{{.Name}}[i], | ||||
|       Name: "Unknown{{.Name}}", | ||||
|     } | ||||
|   } | ||||
| } | ||||
| `)) | ||||
|  | ||||
| func main() { | ||||
| 	fmt.Fprintf(os.Stderr, "Writing results to stdout\n") | ||||
| 	fmt.Printf(fmtString, time.Now()) | ||||
| 	types := []struct { | ||||
| 		Name string | ||||
| 		Num  int | ||||
| 	}{ | ||||
| 		{"LinkType", 256}, | ||||
| 		{"EthernetType", 65536}, | ||||
| 		{"PPPType", 65536}, | ||||
| 		{"IPProtocol", 256}, | ||||
| 		{"SCTPChunkType", 256}, | ||||
| 		{"PPPoECode", 256}, | ||||
| 		{"FDDIFrameControl", 256}, | ||||
| 		{"EAPOLType", 256}, | ||||
| 		{"ProtocolFamily", 256}, | ||||
| 		{"Dot11Type", 256}, | ||||
| 		{"USBTransportType", 256}, | ||||
| 	} | ||||
|  | ||||
| 	fmt.Println("func init() {") | ||||
| 	for _, t := range types { | ||||
| 		fmt.Printf("initUnknownTypesFor%s()\n", t.Name) | ||||
| 	} | ||||
| 	fmt.Println("initActualTypeData()") | ||||
| 	fmt.Println("}") | ||||
| 	for _, t := range types { | ||||
| 		if err := funcsTmpl.Execute(os.Stdout, t); err != nil { | ||||
| 			log.Fatalf("Failed to execute template %s: %v", t.Name, err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										3
									
								
								vendor/github.com/google/gopacket/layers/gen_linted.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								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 | ||||
							
								
								
									
										110
									
								
								vendor/github.com/google/gopacket/layers/geneve.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								vendor/github.com/google/gopacket/layers/geneve.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| // 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) (*GeneveOption, uint8) { | ||||
| 	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 | ||||
|  | ||||
| 	opt.Data = make([]byte, opt.Length-4) | ||||
| 	copy(opt.Data, data[4:opt.Length]) | ||||
|  | ||||
| 	return opt, opt.Length | ||||
| } | ||||
|  | ||||
| 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 := decodeGeneveOption(data[offset:], gn) | ||||
| 		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
									
								
								vendor/github.com/google/gopacket/layers/gre.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								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) | ||||
| } | ||||
							
								
								
									
										181
									
								
								vendor/github.com/google/gopacket/layers/gtp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								vendor/github.com/google/gopacket/layers/gtp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | ||||
| // 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 { | ||||
| 	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
									
								
								vendor/github.com/google/gopacket/layers/iana_ports.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11351
									
								
								vendor/github.com/google/gopacket/layers/iana_ports.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										267
									
								
								vendor/github.com/google/gopacket/layers/icmp4.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/icmp6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/icmp6msg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										578
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/igmp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										355
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/ip4.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										325
									
								
								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 | ||||
| } | ||||
							
								
								
									
										707
									
								
								vendor/github.com/google/gopacket/layers/ip6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										707
									
								
								vendor/github.com/google/gopacket/layers/ip6.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,707 @@ | ||||
| // 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) (h *ipv6HeaderTLVOption) { | ||||
| 	h = &ipv6HeaderTLVOption{} | ||||
| 	if data[0] == 0 { | ||||
| 		h.ActualLength = 1 | ||||
| 		return | ||||
| 	} | ||||
| 	h.OptionType = data[0] | ||||
| 	h.OptionLength = data[1] | ||||
| 	h.ActualLength = int(h.OptionLength) + 2 | ||||
| 	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 | ||||
| 	} | ||||
| 	offset := 2 | ||||
| 	for offset < i.ActualLength { | ||||
| 		opt := decodeIPv6HeaderTLVOption(data[offset:]) | ||||
| 		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 := decodeIPv6HeaderTLVOption(data[offset:]) | ||||
| 		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 | ||||
| } | ||||
							
								
								
									
										68
									
								
								vendor/github.com/google/gopacket/layers/ipsec.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								vendor/github.com/google/gopacket/layers/ipsec.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| // 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" | ||||
| ) | ||||
|  | ||||
| // 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 { | ||||
| 	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 | ||||
| 	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 | ||||
| } | ||||
							
								
								
									
										221
									
								
								vendor/github.com/google/gopacket/layers/layertypes.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								vendor/github.com/google/gopacket/layers/layertypes.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,221 @@ | ||||
| // 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)}) | ||||
| ) | ||||
|  | ||||
| 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, | ||||
| 	}) | ||||
| ) | ||||
							
								
								
									
										213
									
								
								vendor/github.com/google/gopacket/layers/lcm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								vendor/github.com/google/gopacket/layers/lcm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,213 @@ | ||||
| // 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" | ||||
|  | ||||
| 	"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 { | ||||
| 	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
									
								
								vendor/github.com/google/gopacket/layers/linux_sll.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/llc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								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 | ||||
| } | ||||
							
								
								
									
										1585
									
								
								vendor/github.com/google/gopacket/layers/lldp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1585
									
								
								vendor/github.com/google/gopacket/layers/lldp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										80
									
								
								vendor/github.com/google/gopacket/layers/loopback.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/mldv1.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/mldv2.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										619
									
								
								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) < 4 { | ||||
| 		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
									
								
								vendor/github.com/google/gopacket/layers/modbustcp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/mpls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/ndp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										611
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/ntp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										416
									
								
								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                                 * | ||||
| //****************************************************************************** | ||||
							
								
								
									
										699
									
								
								vendor/github.com/google/gopacket/layers/ospf.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										699
									
								
								vendor/github.com/google/gopacket/layers/ospf.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,699 @@ | ||||
| // 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" | ||||
| ) | ||||
|  | ||||
| // 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 | ||||
| 		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.") | ||||
| } | ||||
							
								
								
									
										76
									
								
								vendor/github.com/google/gopacket/layers/pflog.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								vendor/github.com/google/gopacket/layers/pflog.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| // 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" | ||||
| ) | ||||
|  | ||||
| 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 { | ||||
| 	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 | ||||
| 	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) | ||||
| } | ||||
							
								
								
									
										155
									
								
								vendor/github.com/google/gopacket/layers/ports.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								vendor/github.com/google/gopacket/layers/ports.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| // 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, | ||||
| } | ||||
|  | ||||
| // 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
									
								
								vendor/github.com/google/gopacket/layers/ppp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/pppoe.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/prism.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								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 } | ||||
							
								
								
									
										1069
									
								
								vendor/github.com/google/gopacket/layers/radiotap.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1069
									
								
								vendor/github.com/google/gopacket/layers/radiotap.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										170
									
								
								vendor/github.com/google/gopacket/layers/rmcp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/rudp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/sctp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										746
									
								
								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 | ||||
| } | ||||
							
								
								
									
										2480
									
								
								vendor/github.com/google/gopacket/layers/sflow.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2480
									
								
								vendor/github.com/google/gopacket/layers/sflow.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										546
									
								
								vendor/github.com/google/gopacket/layers/sip.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										546
									
								
								vendor/github.com/google/gopacket/layers/sip.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,546 @@ | ||||
| // 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 | ||||
|  | ||||
| 	// Clean leading new line | ||||
| 	data = bytes.Trim(data, "\n") | ||||
|  | ||||
| 	// 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 { | ||||
| 				break | ||||
| 			} else { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// Trim the new line delimiters | ||||
| 		line = bytes.Trim(line, "\r\n") | ||||
|  | ||||
| 		// Empty line, we hit Body | ||||
| 		// Putting packet remain in Paypload | ||||
| 		if len(line) == 0 { | ||||
| 			s.BaseLayer.Payload = buffer.Bytes() | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		// 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++ | ||||
| 	} | ||||
|  | ||||
| 	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 { | ||||
| 		if len(s.Headers[headerName]) > 0 { | ||||
| 			return s.Headers[headerName] | ||||
| 		} else if len(s.Headers[compactSipHeadersCorrespondance[headerName]]) > 0 { | ||||
| 			return s.Headers[compactSipHeadersCorrespondance[headerName]] | ||||
| 		} | ||||
| 	} | ||||
| 	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 { | ||||
| 	headerName = strings.ToLower(headerName) | ||||
| 	if _, ok := s.Headers[headerName]; ok { | ||||
| 		if len(s.Headers[headerName]) > 0 { | ||||
| 			return s.Headers[headerName][0] | ||||
| 		} else if len(s.Headers[compactSipHeadersCorrespondance[headerName]]) > 0 { | ||||
| 			return s.Headers[compactSipHeadersCorrespondance[headerName]][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
									
								
								vendor/github.com/google/gopacket/layers/stp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								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 | ||||
| } | ||||
							
								
								
									
										337
									
								
								vendor/github.com/google/gopacket/layers/tcp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										337
									
								
								vendor/github.com/google/gopacket/layers/tcp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,337 @@ | ||||
| // 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: | ||||
| 		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] | ||||
| 	} | ||||
| 	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] | ||||
| 	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 | ||||
| 		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
									
								
								vendor/github.com/google/gopacket/layers/tcpip.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								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
									
								
								vendor/github.com/google/gopacket/layers/test_creator.py
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										103
									
								
								vendor/github.com/google/gopacket/layers/test_creator.py
									
									
									
										generated
									
									
										vendored
									
									
										Executable 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() | ||||
							
								
								
									
										208
									
								
								vendor/github.com/google/gopacket/layers/tls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								vendor/github.com/google/gopacket/layers/tls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,208 @@ | ||||
| // 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 | ||||
| 	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 | ||||
| } | ||||
							
								
								
									
										165
									
								
								vendor/github.com/google/gopacket/layers/tls_alert.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								vendor/github.com/google/gopacket/layers/tls_alert.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | ||||
| // 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 ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/google/gopacket" | ||||
| ) | ||||
|  | ||||
| // TLSAlertLevel defines the alert level data type | ||||
| type TLSAlertLevel uint8 | ||||
|  | ||||
| // TLSAlertDescr defines the alert descrption data type | ||||
| type TLSAlertDescr uint8 | ||||
|  | ||||
| const ( | ||||
| 	TLSAlertWarning      TLSAlertLevel = 1 | ||||
| 	TLSAlertFatal        TLSAlertLevel = 2 | ||||
| 	TLSAlertUnknownLevel TLSAlertLevel = 255 | ||||
|  | ||||
| 	TLSAlertCloseNotify               TLSAlertDescr = 0 | ||||
| 	TLSAlertUnexpectedMessage         TLSAlertDescr = 10 | ||||
| 	TLSAlertBadRecordMac              TLSAlertDescr = 20 | ||||
| 	TLSAlertDecryptionFailedRESERVED  TLSAlertDescr = 21 | ||||
| 	TLSAlertRecordOverflow            TLSAlertDescr = 22 | ||||
| 	TLSAlertDecompressionFailure      TLSAlertDescr = 30 | ||||
| 	TLSAlertHandshakeFailure          TLSAlertDescr = 40 | ||||
| 	TLSAlertNoCertificateRESERVED     TLSAlertDescr = 41 | ||||
| 	TLSAlertBadCertificate            TLSAlertDescr = 42 | ||||
| 	TLSAlertUnsupportedCertificate    TLSAlertDescr = 43 | ||||
| 	TLSAlertCertificateRevoked        TLSAlertDescr = 44 | ||||
| 	TLSAlertCertificateExpired        TLSAlertDescr = 45 | ||||
| 	TLSAlertCertificateUnknown        TLSAlertDescr = 46 | ||||
| 	TLSAlertIllegalParameter          TLSAlertDescr = 47 | ||||
| 	TLSAlertUnknownCa                 TLSAlertDescr = 48 | ||||
| 	TLSAlertAccessDenied              TLSAlertDescr = 49 | ||||
| 	TLSAlertDecodeError               TLSAlertDescr = 50 | ||||
| 	TLSAlertDecryptError              TLSAlertDescr = 51 | ||||
| 	TLSAlertExportRestrictionRESERVED TLSAlertDescr = 60 | ||||
| 	TLSAlertProtocolVersion           TLSAlertDescr = 70 | ||||
| 	TLSAlertInsufficientSecurity      TLSAlertDescr = 71 | ||||
| 	TLSAlertInternalError             TLSAlertDescr = 80 | ||||
| 	TLSAlertUserCanceled              TLSAlertDescr = 90 | ||||
| 	TLSAlertNoRenegotiation           TLSAlertDescr = 100 | ||||
| 	TLSAlertUnsupportedExtension      TLSAlertDescr = 110 | ||||
| 	TLSAlertUnknownDescription        TLSAlertDescr = 255 | ||||
| ) | ||||
|  | ||||
| //  TLS Alert | ||||
| //  0  1  2  3  4  5  6  7  8 | ||||
| //  +--+--+--+--+--+--+--+--+ | ||||
| //  |         Level         | | ||||
| //  +--+--+--+--+--+--+--+--+ | ||||
| //  |      Description      | | ||||
| //  +--+--+--+--+--+--+--+--+ | ||||
|  | ||||
| // TLSAlertRecord contains all the information that each Alert Record type should have | ||||
| type TLSAlertRecord struct { | ||||
| 	TLSRecordHeader | ||||
|  | ||||
| 	Level       TLSAlertLevel | ||||
| 	Description TLSAlertDescr | ||||
|  | ||||
| 	EncryptedMsg []byte | ||||
| } | ||||
|  | ||||
| // DecodeFromBytes decodes the slice into the TLS struct. | ||||
| func (t *TLSAlertRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { | ||||
| 	// TLS Record Header | ||||
| 	t.ContentType = h.ContentType | ||||
| 	t.Version = h.Version | ||||
| 	t.Length = h.Length | ||||
|  | ||||
| 	if len(data) < 2 { | ||||
| 		df.SetTruncated() | ||||
| 		return errors.New("TLS Alert packet too short") | ||||
| 	} | ||||
|  | ||||
| 	if t.Length == 2 { | ||||
| 		t.Level = TLSAlertLevel(data[0]) | ||||
| 		t.Description = TLSAlertDescr(data[1]) | ||||
| 	} else { | ||||
| 		t.Level = TLSAlertUnknownLevel | ||||
| 		t.Description = TLSAlertUnknownDescription | ||||
| 		t.EncryptedMsg = data | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Strings shows the TLS alert level nicely formatted | ||||
| func (al TLSAlertLevel) String() string { | ||||
| 	switch al { | ||||
| 	default: | ||||
| 		return fmt.Sprintf("Unknown(%d)", al) | ||||
| 	case TLSAlertWarning: | ||||
| 		return "Warning" | ||||
| 	case TLSAlertFatal: | ||||
| 		return "Fatal" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Strings shows the TLS alert description nicely formatted | ||||
| func (ad TLSAlertDescr) String() string { | ||||
| 	switch ad { | ||||
| 	default: | ||||
| 		return "Unknown" | ||||
| 	case TLSAlertCloseNotify: | ||||
| 		return "close_notify" | ||||
| 	case TLSAlertUnexpectedMessage: | ||||
| 		return "unexpected_message" | ||||
| 	case TLSAlertBadRecordMac: | ||||
| 		return "bad_record_mac" | ||||
| 	case TLSAlertDecryptionFailedRESERVED: | ||||
| 		return "decryption_failed_RESERVED" | ||||
| 	case TLSAlertRecordOverflow: | ||||
| 		return "record_overflow" | ||||
| 	case TLSAlertDecompressionFailure: | ||||
| 		return "decompression_failure" | ||||
| 	case TLSAlertHandshakeFailure: | ||||
| 		return "handshake_failure" | ||||
| 	case TLSAlertNoCertificateRESERVED: | ||||
| 		return "no_certificate_RESERVED" | ||||
| 	case TLSAlertBadCertificate: | ||||
| 		return "bad_certificate" | ||||
| 	case TLSAlertUnsupportedCertificate: | ||||
| 		return "unsupported_certificate" | ||||
| 	case TLSAlertCertificateRevoked: | ||||
| 		return "certificate_revoked" | ||||
| 	case TLSAlertCertificateExpired: | ||||
| 		return "certificate_expired" | ||||
| 	case TLSAlertCertificateUnknown: | ||||
| 		return "certificate_unknown" | ||||
| 	case TLSAlertIllegalParameter: | ||||
| 		return "illegal_parameter" | ||||
| 	case TLSAlertUnknownCa: | ||||
| 		return "unknown_ca" | ||||
| 	case TLSAlertAccessDenied: | ||||
| 		return "access_denied" | ||||
| 	case TLSAlertDecodeError: | ||||
| 		return "decode_error" | ||||
| 	case TLSAlertDecryptError: | ||||
| 		return "decrypt_error" | ||||
| 	case TLSAlertExportRestrictionRESERVED: | ||||
| 		return "export_restriction_RESERVED" | ||||
| 	case TLSAlertProtocolVersion: | ||||
| 		return "protocol_version" | ||||
| 	case TLSAlertInsufficientSecurity: | ||||
| 		return "insufficient_security" | ||||
| 	case TLSAlertInternalError: | ||||
| 		return "internal_error" | ||||
| 	case TLSAlertUserCanceled: | ||||
| 		return "user_canceled" | ||||
| 	case TLSAlertNoRenegotiation: | ||||
| 		return "no_renegotiation" | ||||
| 	case TLSAlertUnsupportedExtension: | ||||
| 		return "unsupported_extension" | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										34
									
								
								vendor/github.com/google/gopacket/layers/tls_appdata.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/google/gopacket/layers/tls_appdata.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| // 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 ( | ||||
| 	"errors" | ||||
|  | ||||
| 	"github.com/google/gopacket" | ||||
| ) | ||||
|  | ||||
| // TLSAppDataRecord contains all the information that each AppData Record types should have | ||||
| type TLSAppDataRecord struct { | ||||
| 	TLSRecordHeader | ||||
| 	Payload []byte | ||||
| } | ||||
|  | ||||
| // DecodeFromBytes decodes the slice into the TLS struct. | ||||
| func (t *TLSAppDataRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { | ||||
| 	// TLS Record Header | ||||
| 	t.ContentType = h.ContentType | ||||
| 	t.Version = h.Version | ||||
| 	t.Length = h.Length | ||||
|  | ||||
| 	if len(data) != int(t.Length) { | ||||
| 		return errors.New("TLS Application Data length mismatch") | ||||
| 	} | ||||
|  | ||||
| 	t.Payload = data | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										64
									
								
								vendor/github.com/google/gopacket/layers/tls_cipherspec.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/google/gopacket/layers/tls_cipherspec.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| // 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 ( | ||||
| 	"errors" | ||||
|  | ||||
| 	"github.com/google/gopacket" | ||||
| ) | ||||
|  | ||||
| // TLSchangeCipherSpec defines the message value inside ChangeCipherSpec Record | ||||
| type TLSchangeCipherSpec uint8 | ||||
|  | ||||
| const ( | ||||
| 	TLSChangecipherspecMessage TLSchangeCipherSpec = 1 | ||||
| 	TLSChangecipherspecUnknown TLSchangeCipherSpec = 255 | ||||
| ) | ||||
|  | ||||
| //  TLS Change Cipher Spec | ||||
| //  0  1  2  3  4  5  6  7  8 | ||||
| //  +--+--+--+--+--+--+--+--+ | ||||
| //  |        Message        | | ||||
| //  +--+--+--+--+--+--+--+--+ | ||||
|  | ||||
| // TLSChangeCipherSpecRecord defines the type of data inside ChangeCipherSpec Record | ||||
| type TLSChangeCipherSpecRecord struct { | ||||
| 	TLSRecordHeader | ||||
|  | ||||
| 	Message TLSchangeCipherSpec | ||||
| } | ||||
|  | ||||
| // DecodeFromBytes decodes the slice into the TLS struct. | ||||
| func (t *TLSChangeCipherSpecRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { | ||||
| 	// TLS Record Header | ||||
| 	t.ContentType = h.ContentType | ||||
| 	t.Version = h.Version | ||||
| 	t.Length = h.Length | ||||
|  | ||||
| 	if len(data) != 1 { | ||||
| 		df.SetTruncated() | ||||
| 		return errors.New("TLS Change Cipher Spec record incorrect length") | ||||
| 	} | ||||
|  | ||||
| 	t.Message = TLSchangeCipherSpec(data[0]) | ||||
| 	if t.Message != TLSChangecipherspecMessage { | ||||
| 		t.Message = TLSChangecipherspecUnknown | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // String shows the message value nicely formatted | ||||
| func (ccs TLSchangeCipherSpec) String() string { | ||||
| 	switch ccs { | ||||
| 	default: | ||||
| 		return "Unknown" | ||||
| 	case TLSChangecipherspecMessage: | ||||
| 		return "Change Cipher Spec Message" | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										28
									
								
								vendor/github.com/google/gopacket/layers/tls_handshake.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/google/gopacket/layers/tls_handshake.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // 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 ( | ||||
| 	"github.com/google/gopacket" | ||||
| ) | ||||
|  | ||||
| // TLSHandshakeRecord defines the structure of a Handshare Record | ||||
| type TLSHandshakeRecord struct { | ||||
| 	TLSRecordHeader | ||||
| } | ||||
|  | ||||
| // DecodeFromBytes decodes the slice into the TLS struct. | ||||
| func (t *TLSHandshakeRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { | ||||
| 	// TLS Record Header | ||||
| 	t.ContentType = h.ContentType | ||||
| 	t.Version = h.Version | ||||
| 	t.Length = h.Length | ||||
|  | ||||
| 	// TODO | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										133
									
								
								vendor/github.com/google/gopacket/layers/udp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								vendor/github.com/google/gopacket/layers/udp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| // 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" | ||||
| ) | ||||
|  | ||||
| // UDP is the layer for UDP headers. | ||||
| type UDP struct { | ||||
| 	BaseLayer | ||||
| 	SrcPort, DstPort UDPPort | ||||
| 	Length           uint16 | ||||
| 	Checksum         uint16 | ||||
| 	sPort, dPort     []byte | ||||
| 	tcpipchecksum | ||||
| } | ||||
|  | ||||
| // LayerType returns gopacket.LayerTypeUDP | ||||
| func (u *UDP) LayerType() gopacket.LayerType { return LayerTypeUDP } | ||||
|  | ||||
| func (udp *UDP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { | ||||
| 	if len(data) < 8 { | ||||
| 		df.SetTruncated() | ||||
| 		return fmt.Errorf("Invalid UDP header. Length %d less than 8", len(data)) | ||||
| 	} | ||||
| 	udp.SrcPort = UDPPort(binary.BigEndian.Uint16(data[0:2])) | ||||
| 	udp.sPort = data[0:2] | ||||
| 	udp.DstPort = UDPPort(binary.BigEndian.Uint16(data[2:4])) | ||||
| 	udp.dPort = data[2:4] | ||||
| 	udp.Length = binary.BigEndian.Uint16(data[4:6]) | ||||
| 	udp.Checksum = binary.BigEndian.Uint16(data[6:8]) | ||||
| 	udp.BaseLayer = BaseLayer{Contents: data[:8]} | ||||
| 	switch { | ||||
| 	case udp.Length >= 8: | ||||
| 		hlen := int(udp.Length) | ||||
| 		if hlen > len(data) { | ||||
| 			df.SetTruncated() | ||||
| 			hlen = len(data) | ||||
| 		} | ||||
| 		udp.Payload = data[8:hlen] | ||||
| 	case udp.Length == 0: // Jumbogram, use entire rest of data | ||||
| 		udp.Payload = data[8:] | ||||
| 	default: | ||||
| 		return fmt.Errorf("UDP packet too small: %d bytes", udp.Length) | ||||
| 	} | ||||
| 	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 (u *UDP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { | ||||
| 	var jumbo bool | ||||
|  | ||||
| 	payload := b.Bytes() | ||||
| 	if _, ok := u.pseudoheader.(*IPv6); ok { | ||||
| 		if len(payload)+8 > 65535 { | ||||
| 			jumbo = true | ||||
| 		} | ||||
| 	} | ||||
| 	bytes, err := b.PrependBytes(8) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	binary.BigEndian.PutUint16(bytes, uint16(u.SrcPort)) | ||||
| 	binary.BigEndian.PutUint16(bytes[2:], uint16(u.DstPort)) | ||||
| 	if opts.FixLengths { | ||||
| 		if jumbo { | ||||
| 			u.Length = 0 | ||||
| 		} else { | ||||
| 			u.Length = uint16(len(payload)) + 8 | ||||
| 		} | ||||
| 	} | ||||
| 	binary.BigEndian.PutUint16(bytes[4:], u.Length) | ||||
| 	if opts.ComputeChecksums { | ||||
| 		// zero out checksum bytes | ||||
| 		bytes[6] = 0 | ||||
| 		bytes[7] = 0 | ||||
| 		csum, err := u.computeChecksum(b.Bytes(), IPProtocolUDP) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		u.Checksum = csum | ||||
| 	} | ||||
| 	binary.BigEndian.PutUint16(bytes[6:], u.Checksum) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (u *UDP) CanDecode() gopacket.LayerClass { | ||||
| 	return LayerTypeUDP | ||||
| } | ||||
|  | ||||
| // NextLayerType use the destination port to select the | ||||
| // right next decoder. It tries first to decode via the | ||||
| // destination port, then the source port. | ||||
| func (u *UDP) NextLayerType() gopacket.LayerType { | ||||
| 	if lt := u.DstPort.LayerType(); lt != gopacket.LayerTypePayload { | ||||
| 		return lt | ||||
| 	} | ||||
| 	return u.SrcPort.LayerType() | ||||
| } | ||||
|  | ||||
| func decodeUDP(data []byte, p gopacket.PacketBuilder) error { | ||||
| 	udp := &UDP{} | ||||
| 	err := udp.DecodeFromBytes(data, p) | ||||
| 	p.AddLayer(udp) | ||||
| 	p.SetTransportLayer(udp) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return p.NextDecoder(udp.NextLayerType()) | ||||
| } | ||||
|  | ||||
| func (u *UDP) TransportFlow() gopacket.Flow { | ||||
| 	return gopacket.NewFlow(EndpointUDPPort, u.sPort, u.dPort) | ||||
| } | ||||
|  | ||||
| // For testing only | ||||
| func (u *UDP) SetInternalPortsForTesting() { | ||||
| 	u.sPort = make([]byte, 2) | ||||
| 	u.dPort = make([]byte, 2) | ||||
| 	binary.BigEndian.PutUint16(u.sPort, uint16(u.SrcPort)) | ||||
| 	binary.BigEndian.PutUint16(u.dPort, uint16(u.DstPort)) | ||||
| } | ||||
							
								
								
									
										44
									
								
								vendor/github.com/google/gopacket/layers/udplite.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/google/gopacket/layers/udplite.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| // 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" | ||||
| 	"github.com/google/gopacket" | ||||
| ) | ||||
|  | ||||
| // UDPLite is the layer for UDP-Lite headers (rfc 3828). | ||||
| type UDPLite struct { | ||||
| 	BaseLayer | ||||
| 	SrcPort, DstPort UDPLitePort | ||||
| 	ChecksumCoverage uint16 | ||||
| 	Checksum         uint16 | ||||
| 	sPort, dPort     []byte | ||||
| } | ||||
|  | ||||
| // LayerType returns gopacket.LayerTypeUDPLite | ||||
| func (u *UDPLite) LayerType() gopacket.LayerType { return LayerTypeUDPLite } | ||||
|  | ||||
| func decodeUDPLite(data []byte, p gopacket.PacketBuilder) error { | ||||
| 	udp := &UDPLite{ | ||||
| 		SrcPort:          UDPLitePort(binary.BigEndian.Uint16(data[0:2])), | ||||
| 		sPort:            data[0:2], | ||||
| 		DstPort:          UDPLitePort(binary.BigEndian.Uint16(data[2:4])), | ||||
| 		dPort:            data[2:4], | ||||
| 		ChecksumCoverage: binary.BigEndian.Uint16(data[4:6]), | ||||
| 		Checksum:         binary.BigEndian.Uint16(data[6:8]), | ||||
| 		BaseLayer:        BaseLayer{data[:8], data[8:]}, | ||||
| 	} | ||||
| 	p.AddLayer(udp) | ||||
| 	p.SetTransportLayer(udp) | ||||
| 	return p.NextDecoder(gopacket.LayerTypePayload) | ||||
| } | ||||
|  | ||||
| func (u *UDPLite) TransportFlow() gopacket.Flow { | ||||
| 	return gopacket.NewFlow(EndpointUDPLitePort, u.sPort, u.dPort) | ||||
| } | ||||
							
								
								
									
										287
									
								
								vendor/github.com/google/gopacket/layers/usb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										287
									
								
								vendor/github.com/google/gopacket/layers/usb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,287 @@ | ||||
| // Copyright 2014 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" | ||||
| ) | ||||
|  | ||||
| type USBEventType uint8 | ||||
|  | ||||
| const ( | ||||
| 	USBEventTypeSubmit   USBEventType = 'S' | ||||
| 	USBEventTypeComplete USBEventType = 'C' | ||||
| 	USBEventTypeError    USBEventType = 'E' | ||||
| ) | ||||
|  | ||||
| func (a USBEventType) String() string { | ||||
| 	switch a { | ||||
| 	case USBEventTypeSubmit: | ||||
| 		return "SUBMIT" | ||||
| 	case USBEventTypeComplete: | ||||
| 		return "COMPLETE" | ||||
| 	case USBEventTypeError: | ||||
| 		return "ERROR" | ||||
| 	default: | ||||
| 		return "Unknown event type" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type USBRequestBlockSetupRequest uint8 | ||||
|  | ||||
| const ( | ||||
| 	USBRequestBlockSetupRequestGetStatus        USBRequestBlockSetupRequest = 0x00 | ||||
| 	USBRequestBlockSetupRequestClearFeature     USBRequestBlockSetupRequest = 0x01 | ||||
| 	USBRequestBlockSetupRequestSetFeature       USBRequestBlockSetupRequest = 0x03 | ||||
| 	USBRequestBlockSetupRequestSetAddress       USBRequestBlockSetupRequest = 0x05 | ||||
| 	USBRequestBlockSetupRequestGetDescriptor    USBRequestBlockSetupRequest = 0x06 | ||||
| 	USBRequestBlockSetupRequestSetDescriptor    USBRequestBlockSetupRequest = 0x07 | ||||
| 	USBRequestBlockSetupRequestGetConfiguration USBRequestBlockSetupRequest = 0x08 | ||||
| 	USBRequestBlockSetupRequestSetConfiguration USBRequestBlockSetupRequest = 0x09 | ||||
| 	USBRequestBlockSetupRequestSetIdle          USBRequestBlockSetupRequest = 0x0a | ||||
| ) | ||||
|  | ||||
| func (a USBRequestBlockSetupRequest) String() string { | ||||
| 	switch a { | ||||
| 	case USBRequestBlockSetupRequestGetStatus: | ||||
| 		return "GET_STATUS" | ||||
| 	case USBRequestBlockSetupRequestClearFeature: | ||||
| 		return "CLEAR_FEATURE" | ||||
| 	case USBRequestBlockSetupRequestSetFeature: | ||||
| 		return "SET_FEATURE" | ||||
| 	case USBRequestBlockSetupRequestSetAddress: | ||||
| 		return "SET_ADDRESS" | ||||
| 	case USBRequestBlockSetupRequestGetDescriptor: | ||||
| 		return "GET_DESCRIPTOR" | ||||
| 	case USBRequestBlockSetupRequestSetDescriptor: | ||||
| 		return "SET_DESCRIPTOR" | ||||
| 	case USBRequestBlockSetupRequestGetConfiguration: | ||||
| 		return "GET_CONFIGURATION" | ||||
| 	case USBRequestBlockSetupRequestSetConfiguration: | ||||
| 		return "SET_CONFIGURATION" | ||||
| 	case USBRequestBlockSetupRequestSetIdle: | ||||
| 		return "SET_IDLE" | ||||
| 	default: | ||||
| 		return "UNKNOWN" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type USBTransportType uint8 | ||||
|  | ||||
| const ( | ||||
| 	USBTransportTypeTransferIn  USBTransportType = 0x80 // Indicates send or receive | ||||
| 	USBTransportTypeIsochronous USBTransportType = 0x00 // Isochronous transfers occur continuously and periodically. They typically contain time sensitive information, such as an audio or video stream. | ||||
| 	USBTransportTypeInterrupt   USBTransportType = 0x01 // Interrupt transfers are typically non-periodic, small device "initiated" communication requiring bounded latency, such as pointing devices or keyboards. | ||||
| 	USBTransportTypeControl     USBTransportType = 0x02 // Control transfers are typically used for command and status operations. | ||||
| 	USBTransportTypeBulk        USBTransportType = 0x03 // Bulk transfers can be used for large bursty data, using all remaining available bandwidth, no guarantees on bandwidth or latency, such as file transfers. | ||||
| ) | ||||
|  | ||||
| type USBDirectionType uint8 | ||||
|  | ||||
| const ( | ||||
| 	USBDirectionTypeUnknown USBDirectionType = iota | ||||
| 	USBDirectionTypeIn | ||||
| 	USBDirectionTypeOut | ||||
| ) | ||||
|  | ||||
| func (a USBDirectionType) String() string { | ||||
| 	switch a { | ||||
| 	case USBDirectionTypeIn: | ||||
| 		return "In" | ||||
| 	case USBDirectionTypeOut: | ||||
| 		return "Out" | ||||
| 	default: | ||||
| 		return "Unknown direction type" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // The reference at http://www.beyondlogic.org/usbnutshell/usb1.shtml contains more information about the protocol. | ||||
| type USB struct { | ||||
| 	BaseLayer | ||||
| 	ID             uint64 | ||||
| 	EventType      USBEventType | ||||
| 	TransferType   USBTransportType | ||||
| 	Direction      USBDirectionType | ||||
| 	EndpointNumber uint8 | ||||
| 	DeviceAddress  uint8 | ||||
| 	BusID          uint16 | ||||
| 	TimestampSec   int64 | ||||
| 	TimestampUsec  int32 | ||||
| 	Setup          bool | ||||
| 	Data           bool | ||||
| 	Status         int32 | ||||
| 	UrbLength      uint32 | ||||
| 	UrbDataLength  uint32 | ||||
|  | ||||
| 	UrbInterval            uint32 | ||||
| 	UrbStartFrame          uint32 | ||||
| 	UrbCopyOfTransferFlags uint32 | ||||
| 	IsoNumDesc             uint32 | ||||
| } | ||||
|  | ||||
| func (u *USB) LayerType() gopacket.LayerType { return LayerTypeUSB } | ||||
|  | ||||
| func (m *USB) NextLayerType() gopacket.LayerType { | ||||
| 	if m.Setup { | ||||
| 		return LayerTypeUSBRequestBlockSetup | ||||
| 	} else if m.Data { | ||||
| 	} | ||||
|  | ||||
| 	return m.TransferType.LayerType() | ||||
| } | ||||
|  | ||||
| func decodeUSB(data []byte, p gopacket.PacketBuilder) error { | ||||
| 	d := &USB{} | ||||
|  | ||||
| 	return decodingLayerDecoder(d, data, p) | ||||
| } | ||||
|  | ||||
| func (m *USB) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { | ||||
| 	m.ID = binary.LittleEndian.Uint64(data[0:8]) | ||||
| 	m.EventType = USBEventType(data[8]) | ||||
| 	m.TransferType = USBTransportType(data[9]) | ||||
|  | ||||
| 	m.EndpointNumber = data[10] & 0x7f | ||||
| 	if data[10]&uint8(USBTransportTypeTransferIn) > 0 { | ||||
| 		m.Direction = USBDirectionTypeIn | ||||
| 	} else { | ||||
| 		m.Direction = USBDirectionTypeOut | ||||
| 	} | ||||
|  | ||||
| 	m.DeviceAddress = data[11] | ||||
| 	m.BusID = binary.LittleEndian.Uint16(data[12:14]) | ||||
|  | ||||
| 	if uint(data[14]) == 0 { | ||||
| 		m.Setup = true | ||||
| 	} | ||||
|  | ||||
| 	if uint(data[15]) == 0 { | ||||
| 		m.Data = true | ||||
| 	} | ||||
|  | ||||
| 	m.TimestampSec = int64(binary.LittleEndian.Uint64(data[16:24])) | ||||
| 	m.TimestampUsec = int32(binary.LittleEndian.Uint32(data[24:28])) | ||||
| 	m.Status = int32(binary.LittleEndian.Uint32(data[28:32])) | ||||
| 	m.UrbLength = binary.LittleEndian.Uint32(data[32:36]) | ||||
| 	m.UrbDataLength = binary.LittleEndian.Uint32(data[36:40]) | ||||
|  | ||||
| 	m.Contents = data[:40] | ||||
| 	m.Payload = data[40:] | ||||
|  | ||||
| 	if m.Setup { | ||||
| 		m.Payload = data[40:] | ||||
| 	} else if m.Data { | ||||
| 		m.Payload = data[uint32(len(data))-m.UrbDataLength:] | ||||
| 	} | ||||
|  | ||||
| 	// if 64 bit, dissect_linux_usb_pseudo_header_ext | ||||
| 	if false { | ||||
| 		m.UrbInterval = binary.LittleEndian.Uint32(data[40:44]) | ||||
| 		m.UrbStartFrame = binary.LittleEndian.Uint32(data[44:48]) | ||||
| 		m.UrbDataLength = binary.LittleEndian.Uint32(data[48:52]) | ||||
| 		m.IsoNumDesc = binary.LittleEndian.Uint32(data[52:56]) | ||||
| 		m.Contents = data[:56] | ||||
| 		m.Payload = data[56:] | ||||
| 	} | ||||
|  | ||||
| 	// crc5 or crc16 | ||||
| 	// eop (end of packet) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type USBRequestBlockSetup struct { | ||||
| 	BaseLayer | ||||
| 	RequestType uint8 | ||||
| 	Request     USBRequestBlockSetupRequest | ||||
| 	Value       uint16 | ||||
| 	Index       uint16 | ||||
| 	Length      uint16 | ||||
| } | ||||
|  | ||||
| func (u *USBRequestBlockSetup) LayerType() gopacket.LayerType { return LayerTypeUSBRequestBlockSetup } | ||||
|  | ||||
| func (m *USBRequestBlockSetup) NextLayerType() gopacket.LayerType { | ||||
| 	return gopacket.LayerTypePayload | ||||
| } | ||||
|  | ||||
| func (m *USBRequestBlockSetup) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { | ||||
| 	m.RequestType = data[0] | ||||
| 	m.Request = USBRequestBlockSetupRequest(data[1]) | ||||
| 	m.Value = binary.LittleEndian.Uint16(data[2:4]) | ||||
| 	m.Index = binary.LittleEndian.Uint16(data[4:6]) | ||||
| 	m.Length = binary.LittleEndian.Uint16(data[6:8]) | ||||
| 	m.Contents = data[:8] | ||||
| 	m.Payload = data[8:] | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func decodeUSBRequestBlockSetup(data []byte, p gopacket.PacketBuilder) error { | ||||
| 	d := &USBRequestBlockSetup{} | ||||
| 	return decodingLayerDecoder(d, data, p) | ||||
| } | ||||
|  | ||||
| type USBControl struct { | ||||
| 	BaseLayer | ||||
| } | ||||
|  | ||||
| func (u *USBControl) LayerType() gopacket.LayerType { return LayerTypeUSBControl } | ||||
|  | ||||
| func (m *USBControl) NextLayerType() gopacket.LayerType { | ||||
| 	return gopacket.LayerTypePayload | ||||
| } | ||||
|  | ||||
| func (m *USBControl) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { | ||||
| 	m.Contents = data | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func decodeUSBControl(data []byte, p gopacket.PacketBuilder) error { | ||||
| 	d := &USBControl{} | ||||
| 	return decodingLayerDecoder(d, data, p) | ||||
| } | ||||
|  | ||||
| type USBInterrupt struct { | ||||
| 	BaseLayer | ||||
| } | ||||
|  | ||||
| func (u *USBInterrupt) LayerType() gopacket.LayerType { return LayerTypeUSBInterrupt } | ||||
|  | ||||
| func (m *USBInterrupt) NextLayerType() gopacket.LayerType { | ||||
| 	return gopacket.LayerTypePayload | ||||
| } | ||||
|  | ||||
| func (m *USBInterrupt) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { | ||||
| 	m.Contents = data | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func decodeUSBInterrupt(data []byte, p gopacket.PacketBuilder) error { | ||||
| 	d := &USBInterrupt{} | ||||
| 	return decodingLayerDecoder(d, data, p) | ||||
| } | ||||
|  | ||||
| type USBBulk struct { | ||||
| 	BaseLayer | ||||
| } | ||||
|  | ||||
| func (u *USBBulk) LayerType() gopacket.LayerType { return LayerTypeUSBBulk } | ||||
|  | ||||
| func (m *USBBulk) NextLayerType() gopacket.LayerType { | ||||
| 	return gopacket.LayerTypePayload | ||||
| } | ||||
|  | ||||
| func (m *USBBulk) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { | ||||
| 	m.Contents = data | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func decodeUSBBulk(data []byte, p gopacket.PacketBuilder) error { | ||||
| 	d := &USBBulk{} | ||||
| 	return decodingLayerDecoder(d, data, p) | ||||
| } | ||||
							
								
								
									
										156
									
								
								vendor/github.com/google/gopacket/layers/vrrp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								vendor/github.com/google/gopacket/layers/vrrp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| // 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" | ||||
| 	"net" | ||||
|  | ||||
| 	"github.com/google/gopacket" | ||||
| ) | ||||
|  | ||||
| /* | ||||
| 	This layer provides decoding for Virtual Router Redundancy Protocol (VRRP) v2. | ||||
| 	https://tools.ietf.org/html/rfc3768#section-5 | ||||
|     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 | ||||
|    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|    |Version| Type  | Virtual Rtr ID|   Priority    | Count IP Addrs| | ||||
|    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|    |   Auth Type   |   Adver Int   |          Checksum             | | ||||
|    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|    |                         IP Address (1)                        | | ||||
|    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|    |                            .                                  | | ||||
|    |                            .                                  | | ||||
|    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|    |                         IP Address (n)                        | | ||||
|    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|    |                     Authentication Data (1)                   | | ||||
|    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|    |                     Authentication Data (2)                   | | ||||
|    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| */ | ||||
|  | ||||
| type VRRPv2Type uint8 | ||||
| type VRRPv2AuthType uint8 | ||||
|  | ||||
| const ( | ||||
| 	VRRPv2Advertisement VRRPv2Type = 0x01 // router advertisement | ||||
| ) | ||||
|  | ||||
| // String conversions for VRRP message types | ||||
| func (v VRRPv2Type) String() string { | ||||
| 	switch v { | ||||
| 	case VRRPv2Advertisement: | ||||
| 		return "VRRPv2 Advertisement" | ||||
| 	default: | ||||
| 		return "" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	VRRPv2AuthNoAuth    VRRPv2AuthType = 0x00 // No Authentication | ||||
| 	VRRPv2AuthReserved1 VRRPv2AuthType = 0x01 // Reserved field 1 | ||||
| 	VRRPv2AuthReserved2 VRRPv2AuthType = 0x02 // Reserved field 2 | ||||
| ) | ||||
|  | ||||
| func (v VRRPv2AuthType) String() string { | ||||
| 	switch v { | ||||
| 	case VRRPv2AuthNoAuth: | ||||
| 		return "No Authentication" | ||||
| 	case VRRPv2AuthReserved1: | ||||
| 		return "Reserved" | ||||
| 	case VRRPv2AuthReserved2: | ||||
| 		return "Reserved" | ||||
| 	default: | ||||
| 		return "" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // VRRPv2 represents an VRRP v2 message. | ||||
| type VRRPv2 struct { | ||||
| 	BaseLayer | ||||
| 	Version      uint8          // The version field specifies the VRRP protocol version of this packet (v2) | ||||
| 	Type         VRRPv2Type     // The type field specifies the type of this VRRP packet.  The only type defined in v2 is ADVERTISEMENT | ||||
| 	VirtualRtrID uint8          // identifies the virtual router this packet is reporting status for | ||||
| 	Priority     uint8          // specifies the sending VRRP router's priority for the virtual router (100 = default) | ||||
| 	CountIPAddr  uint8          // The number of IP addresses contained in this VRRP advertisement. | ||||
| 	AuthType     VRRPv2AuthType // identifies the authentication method being utilized | ||||
| 	AdverInt     uint8          // The Advertisement interval indicates the time interval (in seconds) between ADVERTISEMENTS.  The default is 1 second | ||||
| 	Checksum     uint16         // used to detect data corruption in the VRRP message. | ||||
| 	IPAddress    []net.IP       // one or more IP addresses associated with the virtual router. Specified in the CountIPAddr field. | ||||
| } | ||||
|  | ||||
| // LayerType returns LayerTypeVRRP for VRRP v2 message. | ||||
| func (v *VRRPv2) LayerType() gopacket.LayerType { return LayerTypeVRRP } | ||||
|  | ||||
| func (v *VRRPv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { | ||||
|  | ||||
| 	v.BaseLayer = BaseLayer{Contents: data[:len(data)]} | ||||
| 	v.Version = data[0] >> 4 // high nibble == VRRP version. We're expecting v2 | ||||
|  | ||||
| 	v.Type = VRRPv2Type(data[0] & 0x0F) // low nibble == VRRP type. Expecting 1 (advertisement) | ||||
| 	if v.Type != 1 { | ||||
| 		// rfc3768: A packet with unknown type MUST be discarded. | ||||
| 		return errors.New("Unrecognized VRRPv2 type field.") | ||||
| 	} | ||||
|  | ||||
| 	v.VirtualRtrID = data[1] | ||||
| 	v.Priority = data[2] | ||||
|  | ||||
| 	v.CountIPAddr = data[3] | ||||
| 	if v.CountIPAddr < 1 { | ||||
| 		return errors.New("VRRPv2 number of IP addresses is not valid.") | ||||
| 	} | ||||
|  | ||||
| 	v.AuthType = VRRPv2AuthType(data[4]) | ||||
| 	v.AdverInt = uint8(data[5]) | ||||
| 	v.Checksum = binary.BigEndian.Uint16(data[6:8]) | ||||
|  | ||||
| 	// populate the IPAddress field. The number of addresses is specified in the v.CountIPAddr field | ||||
| 	// offset references the starting byte containing the list of ip addresses | ||||
| 	offset := 8 | ||||
| 	for i := uint8(0); i < v.CountIPAddr; i++ { | ||||
| 		v.IPAddress = append(v.IPAddress, data[offset:offset+4]) | ||||
| 		offset += 4 | ||||
| 	} | ||||
|  | ||||
| 	//	any trailing packets here may be authentication data and *should* be ignored in v2 as per RFC | ||||
| 	// | ||||
| 	//			5.3.10.  Authentication Data | ||||
| 	// | ||||
| 	//			The authentication string is currently only used to maintain | ||||
| 	//			backwards compatibility with RFC 2338.  It SHOULD be set to zero on | ||||
| 	//	   		transmission and ignored on reception. | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // CanDecode specifies the layer type in which we are attempting to unwrap. | ||||
| func (v *VRRPv2) CanDecode() gopacket.LayerClass { | ||||
| 	return LayerTypeVRRP | ||||
| } | ||||
|  | ||||
| // NextLayerType specifies the next layer that should be decoded. VRRP does not contain any further payload, so we set to 0 | ||||
| func (v *VRRPv2) NextLayerType() gopacket.LayerType { | ||||
| 	return gopacket.LayerTypeZero | ||||
| } | ||||
|  | ||||
| // The VRRP packet does not include payload data. Setting byte slice to nil | ||||
| func (v *VRRPv2) Payload() []byte { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // decodeVRRP will parse VRRP v2 | ||||
| func decodeVRRP(data []byte, p gopacket.PacketBuilder) error { | ||||
| 	if len(data) < 8 { | ||||
| 		return errors.New("Not a valid VRRP packet. Packet length is too small.") | ||||
| 	} | ||||
| 	v := &VRRPv2{} | ||||
| 	return decodingLayerDecoder(v, data, p) | ||||
| } | ||||
							
								
								
									
										98
									
								
								vendor/github.com/google/gopacket/layers/vxlan.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								vendor/github.com/google/gopacket/layers/vxlan.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| // 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" | ||||
| 	"fmt" | ||||
| 	"github.com/google/gopacket" | ||||
| ) | ||||
|  | ||||
| //  VXLAN is specifed in RFC 7348 https://tools.ietf.org/html/rfc7348 | ||||
| //  G, D, A, Group Policy ID from https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00 | ||||
| //  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 | ||||
| //  0             8               16              24              32 | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |G|R|R|R|I|R|R|R|R|D|R|R|A|R|R|R|       Group Policy ID         | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| // |     24 bit VXLAN Network Identifier           |   Reserved    | | ||||
| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  | ||||
| // VXLAN is a VXLAN packet header | ||||
| type VXLAN struct { | ||||
| 	BaseLayer | ||||
| 	ValidIDFlag      bool   // 'I' bit per RFC 7348 | ||||
| 	VNI              uint32 // 'VXLAN Network Identifier' 24 bits per RFC 7348 | ||||
| 	GBPExtension     bool   // 'G' bit per Group Policy https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00 | ||||
| 	GBPDontLearn     bool   // 'D' bit per Group Policy | ||||
| 	GBPApplied       bool   // 'A' bit per Group Policy | ||||
| 	GBPGroupPolicyID uint16 // 'Group Policy ID' 16 bits per Group Policy | ||||
| } | ||||
|  | ||||
| // LayerType returns LayerTypeVXLAN | ||||
| func (vx *VXLAN) LayerType() gopacket.LayerType { return LayerTypeVXLAN } | ||||
|  | ||||
| func decodeVXLAN(data []byte, p gopacket.PacketBuilder) error { | ||||
| 	vx := &VXLAN{} | ||||
|  | ||||
| 	// VNI is a 24bit number, Uint32 requires 32 bits | ||||
| 	var buf [4]byte | ||||
| 	copy(buf[1:], data[4:7]) | ||||
|  | ||||
| 	// RFC 7348 https://tools.ietf.org/html/rfc7348 | ||||
| 	vx.ValidIDFlag = data[0]&0x08 > 0        // 'I' bit per RFC7348 | ||||
| 	vx.VNI = binary.BigEndian.Uint32(buf[:]) // VXLAN Network Identifier per RFC7348 | ||||
|  | ||||
| 	// Group Based Policy https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00 | ||||
| 	vx.GBPExtension = data[0]&0x80 > 0                       // 'G' bit per the group policy draft | ||||
| 	vx.GBPDontLearn = data[1]&0x40 > 0                       // 'D' bit - the egress VTEP MUST NOT learn the source address of the encapsulated frame. | ||||
| 	vx.GBPApplied = data[1]&0x80 > 0                         // 'A' bit - indicates that the group policy has already been applied to this packet. | ||||
| 	vx.GBPGroupPolicyID = binary.BigEndian.Uint16(data[2:4]) // Policy ID as per the group policy draft | ||||
|  | ||||
| 	// Layer information | ||||
| 	const vxlanLength = 8 | ||||
| 	vx.Contents = data[:vxlanLength] | ||||
| 	vx.Payload = data[vxlanLength:] | ||||
|  | ||||
| 	p.AddLayer(vx) | ||||
| 	return p.NextDecoder(LinkTypeEthernet) | ||||
| } | ||||
|  | ||||
| // SerializeTo writes the serialized form of this layer into the | ||||
| // SerializationBuffer, implementing gopacket.SerializableLayer. | ||||
| // See the docs for gopacket.SerializableLayer for more info. | ||||
| func (vx *VXLAN) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { | ||||
| 	bytes, err := b.PrependBytes(8) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// PrependBytes does not guarantee that bytes are zeroed.  Setting flags via OR requires that they start off at zero | ||||
| 	bytes[0] = 0 | ||||
| 	bytes[1] = 0 | ||||
|  | ||||
| 	if vx.ValidIDFlag { | ||||
| 		bytes[0] |= 0x08 | ||||
| 	} | ||||
| 	if vx.GBPExtension { | ||||
| 		bytes[0] |= 0x80 | ||||
| 	} | ||||
| 	if vx.GBPDontLearn { | ||||
| 		bytes[1] |= 0x40 | ||||
| 	} | ||||
| 	if vx.GBPApplied { | ||||
| 		bytes[1] |= 0x80 | ||||
| 	} | ||||
|  | ||||
| 	binary.BigEndian.PutUint16(bytes[2:4], vx.GBPGroupPolicyID) | ||||
| 	if vx.VNI >= 1<<24 { | ||||
| 		return fmt.Errorf("Virtual Network Identifier = %x exceeds max for 24-bit uint", vx.VNI) | ||||
| 	} | ||||
| 	binary.BigEndian.PutUint32(bytes[4:8], vx.VNI<<8) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										101
									
								
								vendor/github.com/google/gopacket/layers_decoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								vendor/github.com/google/gopacket/layers_decoder.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| // Copyright 2019 The GoPacket Authors. All rights reserved. | ||||
|  | ||||
| package gopacket | ||||
|  | ||||
| // Created by gen.go, don't edit manually | ||||
| // Generated at 2019-06-18 11:37:31.308731293 +0600 +06 m=+0.000842599 | ||||
|  | ||||
| // LayersDecoder returns DecodingLayerFunc for specified | ||||
| // DecodingLayerContainer, LayerType value to start decoding with and | ||||
| // some DecodeFeedback. | ||||
| func LayersDecoder(dl DecodingLayerContainer, first LayerType, df DecodeFeedback) DecodingLayerFunc { | ||||
| 	firstDec, ok := dl.Decoder(first) | ||||
| 	if !ok { | ||||
| 		return func([]byte, *[]LayerType) (LayerType, error) { | ||||
| 			return first, nil | ||||
| 		} | ||||
| 	} | ||||
| 	if dlc, ok := dl.(DecodingLayerSparse); ok { | ||||
| 		return func(data []byte, decoded *[]LayerType) (LayerType, error) { | ||||
| 			*decoded = (*decoded)[:0] // Truncated decoded layers. | ||||
| 			typ := first | ||||
| 			decoder := firstDec | ||||
| 			for { | ||||
| 				if err := decoder.DecodeFromBytes(data, df); err != nil { | ||||
| 					return LayerTypeZero, err | ||||
| 				} | ||||
| 				*decoded = append(*decoded, typ) | ||||
| 				typ = decoder.NextLayerType() | ||||
| 				if data = decoder.LayerPayload(); len(data) == 0 { | ||||
| 					break | ||||
| 				} | ||||
| 				if decoder, ok = dlc.Decoder(typ); !ok { | ||||
| 					return typ, nil | ||||
| 				} | ||||
| 			} | ||||
| 			return LayerTypeZero, nil | ||||
| 		} | ||||
| 	} | ||||
| 	if dlc, ok := dl.(DecodingLayerArray); ok { | ||||
| 		return func(data []byte, decoded *[]LayerType) (LayerType, error) { | ||||
| 			*decoded = (*decoded)[:0] // Truncated decoded layers. | ||||
| 			typ := first | ||||
| 			decoder := firstDec | ||||
| 			for { | ||||
| 				if err := decoder.DecodeFromBytes(data, df); err != nil { | ||||
| 					return LayerTypeZero, err | ||||
| 				} | ||||
| 				*decoded = append(*decoded, typ) | ||||
| 				typ = decoder.NextLayerType() | ||||
| 				if data = decoder.LayerPayload(); len(data) == 0 { | ||||
| 					break | ||||
| 				} | ||||
| 				if decoder, ok = dlc.Decoder(typ); !ok { | ||||
| 					return typ, nil | ||||
| 				} | ||||
| 			} | ||||
| 			return LayerTypeZero, nil | ||||
| 		} | ||||
| 	} | ||||
| 	if dlc, ok := dl.(DecodingLayerMap); ok { | ||||
| 		return func(data []byte, decoded *[]LayerType) (LayerType, error) { | ||||
| 			*decoded = (*decoded)[:0] // Truncated decoded layers. | ||||
| 			typ := first | ||||
| 			decoder := firstDec | ||||
| 			for { | ||||
| 				if err := decoder.DecodeFromBytes(data, df); err != nil { | ||||
| 					return LayerTypeZero, err | ||||
| 				} | ||||
| 				*decoded = append(*decoded, typ) | ||||
| 				typ = decoder.NextLayerType() | ||||
| 				if data = decoder.LayerPayload(); len(data) == 0 { | ||||
| 					break | ||||
| 				} | ||||
| 				if decoder, ok = dlc.Decoder(typ); !ok { | ||||
| 					return typ, nil | ||||
| 				} | ||||
| 			} | ||||
| 			return LayerTypeZero, nil | ||||
| 		} | ||||
| 	} | ||||
| 	dlc := dl | ||||
| 	return func(data []byte, decoded *[]LayerType) (LayerType, error) { | ||||
| 		*decoded = (*decoded)[:0] // Truncated decoded layers. | ||||
| 		typ := first | ||||
| 		decoder := firstDec | ||||
| 		for { | ||||
| 			if err := decoder.DecodeFromBytes(data, df); err != nil { | ||||
| 				return LayerTypeZero, err | ||||
| 			} | ||||
| 			*decoded = append(*decoded, typ) | ||||
| 			typ = decoder.NextLayerType() | ||||
| 			if data = decoder.LayerPayload(); len(data) == 0 { | ||||
| 				break | ||||
| 			} | ||||
| 			if decoder, ok = dlc.Decoder(typ); !ok { | ||||
| 				return typ, nil | ||||
| 			} | ||||
| 		} | ||||
| 		return LayerTypeZero, nil | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										111
									
								
								vendor/github.com/google/gopacket/layertype.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								vendor/github.com/google/gopacket/layertype.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| // 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" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| // LayerType is a unique identifier for each type of layer.  This enumeration | ||||
| // does not match with any externally available numbering scheme... it's solely | ||||
| // usable/useful within this library as a means for requesting layer types | ||||
| // (see Packet.Layer) and determining which types of layers have been decoded. | ||||
| // | ||||
| // New LayerTypes may be created by calling gopacket.RegisterLayerType. | ||||
| type LayerType int64 | ||||
|  | ||||
| // LayerTypeMetadata contains metadata associated with each LayerType. | ||||
| type LayerTypeMetadata struct { | ||||
| 	// Name is the string returned by each layer type's String method. | ||||
| 	Name string | ||||
| 	// Decoder is the decoder to use when the layer type is passed in as a | ||||
| 	// Decoder. | ||||
| 	Decoder Decoder | ||||
| } | ||||
|  | ||||
| type layerTypeMetadata struct { | ||||
| 	inUse bool | ||||
| 	LayerTypeMetadata | ||||
| } | ||||
|  | ||||
| // DecodersByLayerName maps layer names to decoders for those layers. | ||||
| // This allows users to specify decoders by name to a program and have that | ||||
| // program pick the correct decoder accordingly. | ||||
| var DecodersByLayerName = map[string]Decoder{} | ||||
|  | ||||
| const maxLayerType = 2000 | ||||
|  | ||||
| var ltMeta [maxLayerType]layerTypeMetadata | ||||
| var ltMetaMap = map[LayerType]layerTypeMetadata{} | ||||
|  | ||||
| // RegisterLayerType creates a new layer type and registers it globally. | ||||
| // The number passed in must be unique, or a runtime panic will occur.  Numbers | ||||
| // 0-999 are reserved for the gopacket library.  Numbers 1000-1999 should be | ||||
| // used for common application-specific types, and are very fast.  Any other | ||||
| // number (negative or >= 2000) may be used for uncommon application-specific | ||||
| // types, and are somewhat slower (they require a map lookup over an array | ||||
| // index). | ||||
| func RegisterLayerType(num int, meta LayerTypeMetadata) LayerType { | ||||
| 	if 0 <= num && num < maxLayerType { | ||||
| 		if ltMeta[num].inUse { | ||||
| 			panic("Layer type already exists") | ||||
| 		} | ||||
| 	} else { | ||||
| 		if ltMetaMap[LayerType(num)].inUse { | ||||
| 			panic("Layer type already exists") | ||||
| 		} | ||||
| 	} | ||||
| 	return OverrideLayerType(num, meta) | ||||
| } | ||||
|  | ||||
| // OverrideLayerType acts like RegisterLayerType, except that if the layer type | ||||
| // has already been registered, it overrides the metadata with the passed-in | ||||
| // metadata intead of panicing. | ||||
| func OverrideLayerType(num int, meta LayerTypeMetadata) LayerType { | ||||
| 	if 0 <= num && num < maxLayerType { | ||||
| 		ltMeta[num] = layerTypeMetadata{ | ||||
| 			inUse:             true, | ||||
| 			LayerTypeMetadata: meta, | ||||
| 		} | ||||
| 	} else { | ||||
| 		ltMetaMap[LayerType(num)] = layerTypeMetadata{ | ||||
| 			inUse:             true, | ||||
| 			LayerTypeMetadata: meta, | ||||
| 		} | ||||
| 	} | ||||
| 	DecodersByLayerName[meta.Name] = meta.Decoder | ||||
| 	return LayerType(num) | ||||
| } | ||||
|  | ||||
| // Decode decodes the given data using the decoder registered with the layer | ||||
| // type. | ||||
| func (t LayerType) Decode(data []byte, c PacketBuilder) error { | ||||
| 	var d Decoder | ||||
| 	if 0 <= int(t) && int(t) < maxLayerType { | ||||
| 		d = ltMeta[int(t)].Decoder | ||||
| 	} else { | ||||
| 		d = ltMetaMap[t].Decoder | ||||
| 	} | ||||
| 	if d != nil { | ||||
| 		return d.Decode(data, c) | ||||
| 	} | ||||
| 	return fmt.Errorf("Layer type %v has no associated decoder", t) | ||||
| } | ||||
|  | ||||
| // String returns the string associated with this layer type. | ||||
| func (t LayerType) String() (s string) { | ||||
| 	if 0 <= int(t) && int(t) < maxLayerType { | ||||
| 		s = ltMeta[int(t)].Name | ||||
| 	} else { | ||||
| 		s = ltMetaMap[t].Name | ||||
| 	} | ||||
| 	if s == "" { | ||||
| 		s = strconv.Itoa(int(t)) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										864
									
								
								vendor/github.com/google/gopacket/packet.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										864
									
								
								vendor/github.com/google/gopacket/packet.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,864 @@ | ||||
| // 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" | ||||
| 	"encoding/hex" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"runtime/debug" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // CaptureInfo provides standardized information about a packet captured off | ||||
| // the wire or read from a file. | ||||
| type CaptureInfo struct { | ||||
| 	// Timestamp is the time the packet was captured, if that is known. | ||||
| 	Timestamp time.Time | ||||
| 	// CaptureLength is the total number of bytes read off of the wire. | ||||
| 	CaptureLength int | ||||
| 	// Length is the size of the original packet.  Should always be >= | ||||
| 	// CaptureLength. | ||||
| 	Length int | ||||
| 	// InterfaceIndex | ||||
| 	InterfaceIndex int | ||||
| 	// The packet source can place ancillary data of various types here. | ||||
| 	// For example, the afpacket source can report the VLAN of captured | ||||
| 	// packets this way. | ||||
| 	AncillaryData []interface{} | ||||
| } | ||||
|  | ||||
| // PacketMetadata contains metadata for a packet. | ||||
| type PacketMetadata struct { | ||||
| 	CaptureInfo | ||||
| 	// Truncated is true if packet decoding logic detects that there are fewer | ||||
| 	// bytes in the packet than are detailed in various headers (for example, if | ||||
| 	// the number of bytes in the IPv4 contents/payload is less than IPv4.Length). | ||||
| 	// This is also set automatically for packets captured off the wire if | ||||
| 	// CaptureInfo.CaptureLength < CaptureInfo.Length. | ||||
| 	Truncated bool | ||||
| } | ||||
|  | ||||
| // Packet is the primary object used by gopacket.  Packets are created by a | ||||
| // Decoder's Decode call.  A packet is made up of a set of Data, which | ||||
| // is broken into a number of Layers as it is decoded. | ||||
| type Packet interface { | ||||
| 	//// Functions for outputting the packet as a human-readable string: | ||||
| 	//// ------------------------------------------------------------------ | ||||
| 	// String returns a human-readable string representation of the packet. | ||||
| 	// It uses LayerString on each layer to output the layer. | ||||
| 	String() string | ||||
| 	// Dump returns a verbose human-readable string representation of the packet, | ||||
| 	// including a hex dump of all layers.  It uses LayerDump on each layer to | ||||
| 	// output the layer. | ||||
| 	Dump() string | ||||
|  | ||||
| 	//// Functions for accessing arbitrary packet layers: | ||||
| 	//// ------------------------------------------------------------------ | ||||
| 	// Layers returns all layers in this packet, computing them as necessary | ||||
| 	Layers() []Layer | ||||
| 	// Layer returns the first layer in this packet of the given type, or nil | ||||
| 	Layer(LayerType) Layer | ||||
| 	// LayerClass returns the first layer in this packet of the given class, | ||||
| 	// or nil. | ||||
| 	LayerClass(LayerClass) Layer | ||||
|  | ||||
| 	//// Functions for accessing specific types of packet layers.  These functions | ||||
| 	//// return the first layer of each type found within the packet. | ||||
| 	//// ------------------------------------------------------------------ | ||||
| 	// LinkLayer returns the first link layer in the packet | ||||
| 	LinkLayer() LinkLayer | ||||
| 	// NetworkLayer returns the first network layer in the packet | ||||
| 	NetworkLayer() NetworkLayer | ||||
| 	// TransportLayer returns the first transport layer in the packet | ||||
| 	TransportLayer() TransportLayer | ||||
| 	// ApplicationLayer returns the first application layer in the packet | ||||
| 	ApplicationLayer() ApplicationLayer | ||||
| 	// ErrorLayer is particularly useful, since it returns nil if the packet | ||||
| 	// was fully decoded successfully, and non-nil if an error was encountered | ||||
| 	// in decoding and the packet was only partially decoded.  Thus, its output | ||||
| 	// can be used to determine if the entire packet was able to be decoded. | ||||
| 	ErrorLayer() ErrorLayer | ||||
|  | ||||
| 	//// Functions for accessing data specific to the packet: | ||||
| 	//// ------------------------------------------------------------------ | ||||
| 	// Data returns the set of bytes that make up this entire packet. | ||||
| 	Data() []byte | ||||
| 	// Metadata returns packet metadata associated with this packet. | ||||
| 	Metadata() *PacketMetadata | ||||
| } | ||||
|  | ||||
| // packet contains all the information we need to fulfill the Packet interface, | ||||
| // and its two "subclasses" (yes, no such thing in Go, bear with me), | ||||
| // eagerPacket and lazyPacket, provide eager and lazy decoding logic around the | ||||
| // various functions needed to access this information. | ||||
| type packet struct { | ||||
| 	// data contains the entire packet data for a packet | ||||
| 	data []byte | ||||
| 	// initialLayers is space for an initial set of layers already created inside | ||||
| 	// the packet. | ||||
| 	initialLayers [6]Layer | ||||
| 	// layers contains each layer we've already decoded | ||||
| 	layers []Layer | ||||
| 	// last is the last layer added to the packet | ||||
| 	last Layer | ||||
| 	// metadata is the PacketMetadata for this packet | ||||
| 	metadata PacketMetadata | ||||
|  | ||||
| 	decodeOptions DecodeOptions | ||||
|  | ||||
| 	// Pointers to the various important layers | ||||
| 	link        LinkLayer | ||||
| 	network     NetworkLayer | ||||
| 	transport   TransportLayer | ||||
| 	application ApplicationLayer | ||||
| 	failure     ErrorLayer | ||||
| } | ||||
|  | ||||
| func (p *packet) SetTruncated() { | ||||
| 	p.metadata.Truncated = true | ||||
| } | ||||
|  | ||||
| func (p *packet) SetLinkLayer(l LinkLayer) { | ||||
| 	if p.link == nil { | ||||
| 		p.link = l | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (p *packet) SetNetworkLayer(l NetworkLayer) { | ||||
| 	if p.network == nil { | ||||
| 		p.network = l | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (p *packet) SetTransportLayer(l TransportLayer) { | ||||
| 	if p.transport == nil { | ||||
| 		p.transport = l | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (p *packet) SetApplicationLayer(l ApplicationLayer) { | ||||
| 	if p.application == nil { | ||||
| 		p.application = l | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (p *packet) SetErrorLayer(l ErrorLayer) { | ||||
| 	if p.failure == nil { | ||||
| 		p.failure = l | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (p *packet) AddLayer(l Layer) { | ||||
| 	p.layers = append(p.layers, l) | ||||
| 	p.last = l | ||||
| } | ||||
|  | ||||
| func (p *packet) DumpPacketData() { | ||||
| 	fmt.Fprint(os.Stderr, p.packetDump()) | ||||
| 	os.Stderr.Sync() | ||||
| } | ||||
|  | ||||
| func (p *packet) Metadata() *PacketMetadata { | ||||
| 	return &p.metadata | ||||
| } | ||||
|  | ||||
| func (p *packet) Data() []byte { | ||||
| 	return p.data | ||||
| } | ||||
|  | ||||
| func (p *packet) DecodeOptions() *DecodeOptions { | ||||
| 	return &p.decodeOptions | ||||
| } | ||||
|  | ||||
| func (p *packet) addFinalDecodeError(err error, stack []byte) { | ||||
| 	fail := &DecodeFailure{err: err, stack: stack} | ||||
| 	if p.last == nil { | ||||
| 		fail.data = p.data | ||||
| 	} else { | ||||
| 		fail.data = p.last.LayerPayload() | ||||
| 	} | ||||
| 	p.AddLayer(fail) | ||||
| 	p.SetErrorLayer(fail) | ||||
| } | ||||
|  | ||||
| func (p *packet) recoverDecodeError() { | ||||
| 	if !p.decodeOptions.SkipDecodeRecovery { | ||||
| 		if r := recover(); r != nil { | ||||
| 			p.addFinalDecodeError(fmt.Errorf("%v", r), debug.Stack()) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // LayerString outputs an individual layer as a string.  The layer is output | ||||
| // in a single line, with no trailing newline.  This function is specifically | ||||
| // designed to do the right thing for most layers... it follows the following | ||||
| // rules: | ||||
| //  * If the Layer has a String function, just output that. | ||||
| //  * Otherwise, output all exported fields in the layer, recursing into | ||||
| //    exported slices and structs. | ||||
| // NOTE:  This is NOT THE SAME AS fmt's "%#v".  %#v will output both exported | ||||
| // and unexported fields... many times packet layers contain unexported stuff | ||||
| // that would just mess up the output of the layer, see for example the | ||||
| // Payload layer and it's internal 'data' field, which contains a large byte | ||||
| // array that would really mess up formatting. | ||||
| func LayerString(l Layer) string { | ||||
| 	return fmt.Sprintf("%v\t%s", l.LayerType(), layerString(reflect.ValueOf(l), false, false)) | ||||
| } | ||||
|  | ||||
| // Dumper dumps verbose information on a value.  If a layer type implements | ||||
| // Dumper, then its LayerDump() string will include the results in its output. | ||||
| type Dumper interface { | ||||
| 	Dump() string | ||||
| } | ||||
|  | ||||
| // LayerDump outputs a very verbose string representation of a layer.  Its | ||||
| // output is a concatenation of LayerString(l) and hex.Dump(l.LayerContents()). | ||||
| // It contains newlines and ends with a newline. | ||||
| func LayerDump(l Layer) string { | ||||
| 	var b bytes.Buffer | ||||
| 	b.WriteString(LayerString(l)) | ||||
| 	b.WriteByte('\n') | ||||
| 	if d, ok := l.(Dumper); ok { | ||||
| 		dump := d.Dump() | ||||
| 		if dump != "" { | ||||
| 			b.WriteString(dump) | ||||
| 			if dump[len(dump)-1] != '\n' { | ||||
| 				b.WriteByte('\n') | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	b.WriteString(hex.Dump(l.LayerContents())) | ||||
| 	return b.String() | ||||
| } | ||||
|  | ||||
| // layerString outputs, recursively, a layer in a "smart" way.  See docs for | ||||
| // LayerString for more details. | ||||
| // | ||||
| // Params: | ||||
| //   i - value to write out | ||||
| //   anonymous:  if we're currently recursing an anonymous member of a struct | ||||
| //   writeSpace:  if we've already written a value in a struct, and need to | ||||
| //     write a space before writing more.  This happens when we write various | ||||
| //     anonymous values, and need to keep writing more. | ||||
| func layerString(v reflect.Value, anonymous bool, writeSpace bool) string { | ||||
| 	// Let String() functions take precedence. | ||||
| 	if v.CanInterface() { | ||||
| 		if s, ok := v.Interface().(fmt.Stringer); ok { | ||||
| 			return s.String() | ||||
| 		} | ||||
| 	} | ||||
| 	// Reflect, and spit out all the exported fields as key=value. | ||||
| 	switch v.Type().Kind() { | ||||
| 	case reflect.Interface, reflect.Ptr: | ||||
| 		if v.IsNil() { | ||||
| 			return "nil" | ||||
| 		} | ||||
| 		r := v.Elem() | ||||
| 		return layerString(r, anonymous, writeSpace) | ||||
| 	case reflect.Struct: | ||||
| 		var b bytes.Buffer | ||||
| 		typ := v.Type() | ||||
| 		if !anonymous { | ||||
| 			b.WriteByte('{') | ||||
| 		} | ||||
| 		for i := 0; i < v.NumField(); i++ { | ||||
| 			// Check if this is upper-case. | ||||
| 			ftype := typ.Field(i) | ||||
| 			f := v.Field(i) | ||||
| 			if ftype.Anonymous { | ||||
| 				anonStr := layerString(f, true, writeSpace) | ||||
| 				writeSpace = writeSpace || anonStr != "" | ||||
| 				b.WriteString(anonStr) | ||||
| 			} else if ftype.PkgPath == "" { // exported | ||||
| 				if writeSpace { | ||||
| 					b.WriteByte(' ') | ||||
| 				} | ||||
| 				writeSpace = true | ||||
| 				fmt.Fprintf(&b, "%s=%s", typ.Field(i).Name, layerString(f, false, writeSpace)) | ||||
| 			} | ||||
| 		} | ||||
| 		if !anonymous { | ||||
| 			b.WriteByte('}') | ||||
| 		} | ||||
| 		return b.String() | ||||
| 	case reflect.Slice: | ||||
| 		var b bytes.Buffer | ||||
| 		b.WriteByte('[') | ||||
| 		if v.Len() > 4 { | ||||
| 			fmt.Fprintf(&b, "..%d..", v.Len()) | ||||
| 		} else { | ||||
| 			for j := 0; j < v.Len(); j++ { | ||||
| 				if j != 0 { | ||||
| 					b.WriteString(", ") | ||||
| 				} | ||||
| 				b.WriteString(layerString(v.Index(j), false, false)) | ||||
| 			} | ||||
| 		} | ||||
| 		b.WriteByte(']') | ||||
| 		return b.String() | ||||
| 	} | ||||
| 	return fmt.Sprintf("%v", v.Interface()) | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	longBytesLength = 128 | ||||
| ) | ||||
|  | ||||
| // LongBytesGoString returns a string representation of the byte slice shortened | ||||
| // using the format '<type>{<truncated slice> ... (<n> bytes)}' if it | ||||
| // exceeds a predetermined length. Can be used to avoid filling the display with | ||||
| // very long byte strings. | ||||
| func LongBytesGoString(buf []byte) string { | ||||
| 	if len(buf) < longBytesLength { | ||||
| 		return fmt.Sprintf("%#v", buf) | ||||
| 	} | ||||
| 	s := fmt.Sprintf("%#v", buf[:longBytesLength-1]) | ||||
| 	s = strings.TrimSuffix(s, "}") | ||||
| 	return fmt.Sprintf("%s ... (%d bytes)}", s, len(buf)) | ||||
| } | ||||
|  | ||||
| func baseLayerString(value reflect.Value) string { | ||||
| 	t := value.Type() | ||||
| 	content := value.Field(0) | ||||
| 	c := make([]byte, content.Len()) | ||||
| 	for i := range c { | ||||
| 		c[i] = byte(content.Index(i).Uint()) | ||||
| 	} | ||||
| 	payload := value.Field(1) | ||||
| 	p := make([]byte, payload.Len()) | ||||
| 	for i := range p { | ||||
| 		p[i] = byte(payload.Index(i).Uint()) | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s{Contents:%s, Payload:%s}", t.String(), | ||||
| 		LongBytesGoString(c), | ||||
| 		LongBytesGoString(p)) | ||||
| } | ||||
|  | ||||
| func layerGoString(i interface{}, b *bytes.Buffer) { | ||||
| 	if s, ok := i.(fmt.GoStringer); ok { | ||||
| 		b.WriteString(s.GoString()) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	var v reflect.Value | ||||
| 	var ok bool | ||||
| 	if v, ok = i.(reflect.Value); !ok { | ||||
| 		v = reflect.ValueOf(i) | ||||
| 	} | ||||
| 	switch v.Kind() { | ||||
| 	case reflect.Ptr, reflect.Interface: | ||||
| 		if v.Kind() == reflect.Ptr { | ||||
| 			b.WriteByte('&') | ||||
| 		} | ||||
| 		layerGoString(v.Elem().Interface(), b) | ||||
| 	case reflect.Struct: | ||||
| 		t := v.Type() | ||||
| 		b.WriteString(t.String()) | ||||
| 		b.WriteByte('{') | ||||
| 		for i := 0; i < v.NumField(); i++ { | ||||
| 			if i > 0 { | ||||
| 				b.WriteString(", ") | ||||
| 			} | ||||
| 			if t.Field(i).Name == "BaseLayer" { | ||||
| 				fmt.Fprintf(b, "BaseLayer:%s", baseLayerString(v.Field(i))) | ||||
| 			} else if v.Field(i).Kind() == reflect.Struct { | ||||
| 				fmt.Fprintf(b, "%s:", t.Field(i).Name) | ||||
| 				layerGoString(v.Field(i), b) | ||||
| 			} else if v.Field(i).Kind() == reflect.Ptr { | ||||
| 				b.WriteByte('&') | ||||
| 				layerGoString(v.Field(i), b) | ||||
| 			} else { | ||||
| 				fmt.Fprintf(b, "%s:%#v", t.Field(i).Name, v.Field(i)) | ||||
| 			} | ||||
| 		} | ||||
| 		b.WriteByte('}') | ||||
| 	default: | ||||
| 		fmt.Fprintf(b, "%#v", i) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // LayerGoString returns a representation of the layer in Go syntax, | ||||
| // taking care to shorten "very long" BaseLayer byte slices | ||||
| func LayerGoString(l Layer) string { | ||||
| 	b := new(bytes.Buffer) | ||||
| 	layerGoString(l, b) | ||||
| 	return b.String() | ||||
| } | ||||
|  | ||||
| func (p *packet) packetString() string { | ||||
| 	var b bytes.Buffer | ||||
| 	fmt.Fprintf(&b, "PACKET: %d bytes", len(p.Data())) | ||||
| 	if p.metadata.Truncated { | ||||
| 		b.WriteString(", truncated") | ||||
| 	} | ||||
| 	if p.metadata.Length > 0 { | ||||
| 		fmt.Fprintf(&b, ", wire length %d cap length %d", p.metadata.Length, p.metadata.CaptureLength) | ||||
| 	} | ||||
| 	if !p.metadata.Timestamp.IsZero() { | ||||
| 		fmt.Fprintf(&b, " @ %v", p.metadata.Timestamp) | ||||
| 	} | ||||
| 	b.WriteByte('\n') | ||||
| 	for i, l := range p.layers { | ||||
| 		fmt.Fprintf(&b, "- Layer %d (%02d bytes) = %s\n", i+1, len(l.LayerContents()), LayerString(l)) | ||||
| 	} | ||||
| 	return b.String() | ||||
| } | ||||
|  | ||||
| func (p *packet) packetDump() string { | ||||
| 	var b bytes.Buffer | ||||
| 	fmt.Fprintf(&b, "-- FULL PACKET DATA (%d bytes) ------------------------------------\n%s", len(p.data), hex.Dump(p.data)) | ||||
| 	for i, l := range p.layers { | ||||
| 		fmt.Fprintf(&b, "--- Layer %d ---\n%s", i+1, LayerDump(l)) | ||||
| 	} | ||||
| 	return b.String() | ||||
| } | ||||
|  | ||||
| // eagerPacket is a packet implementation that does eager decoding.  Upon | ||||
| // initial construction, it decodes all the layers it can from packet data. | ||||
| // eagerPacket implements Packet and PacketBuilder. | ||||
| type eagerPacket struct { | ||||
| 	packet | ||||
| } | ||||
|  | ||||
| var errNilDecoder = errors.New("NextDecoder passed nil decoder, probably an unsupported decode type") | ||||
|  | ||||
| func (p *eagerPacket) NextDecoder(next Decoder) error { | ||||
| 	if next == nil { | ||||
| 		return errNilDecoder | ||||
| 	} | ||||
| 	if p.last == nil { | ||||
| 		return errors.New("NextDecoder called, but no layers added yet") | ||||
| 	} | ||||
| 	d := p.last.LayerPayload() | ||||
| 	if len(d) == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	// Since we're eager, immediately call the next decoder. | ||||
| 	return next.Decode(d, p) | ||||
| } | ||||
| func (p *eagerPacket) initialDecode(dec Decoder) { | ||||
| 	defer p.recoverDecodeError() | ||||
| 	err := dec.Decode(p.data, p) | ||||
| 	if err != nil { | ||||
| 		p.addFinalDecodeError(err, nil) | ||||
| 	} | ||||
| } | ||||
| func (p *eagerPacket) LinkLayer() LinkLayer { | ||||
| 	return p.link | ||||
| } | ||||
| func (p *eagerPacket) NetworkLayer() NetworkLayer { | ||||
| 	return p.network | ||||
| } | ||||
| func (p *eagerPacket) TransportLayer() TransportLayer { | ||||
| 	return p.transport | ||||
| } | ||||
| func (p *eagerPacket) ApplicationLayer() ApplicationLayer { | ||||
| 	return p.application | ||||
| } | ||||
| func (p *eagerPacket) ErrorLayer() ErrorLayer { | ||||
| 	return p.failure | ||||
| } | ||||
| func (p *eagerPacket) Layers() []Layer { | ||||
| 	return p.layers | ||||
| } | ||||
| func (p *eagerPacket) Layer(t LayerType) Layer { | ||||
| 	for _, l := range p.layers { | ||||
| 		if l.LayerType() == t { | ||||
| 			return l | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (p *eagerPacket) LayerClass(lc LayerClass) Layer { | ||||
| 	for _, l := range p.layers { | ||||
| 		if lc.Contains(l.LayerType()) { | ||||
| 			return l | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (p *eagerPacket) String() string { return p.packetString() } | ||||
| func (p *eagerPacket) Dump() string   { return p.packetDump() } | ||||
|  | ||||
| // lazyPacket does lazy decoding on its packet data.  On construction it does | ||||
| // no initial decoding.  For each function call, it decodes only as many layers | ||||
| // as are necessary to compute the return value for that function. | ||||
| // lazyPacket implements Packet and PacketBuilder. | ||||
| type lazyPacket struct { | ||||
| 	packet | ||||
| 	next Decoder | ||||
| } | ||||
|  | ||||
| func (p *lazyPacket) NextDecoder(next Decoder) error { | ||||
| 	if next == nil { | ||||
| 		return errNilDecoder | ||||
| 	} | ||||
| 	p.next = next | ||||
| 	return nil | ||||
| } | ||||
| func (p *lazyPacket) decodeNextLayer() { | ||||
| 	if p.next == nil { | ||||
| 		return | ||||
| 	} | ||||
| 	d := p.data | ||||
| 	if p.last != nil { | ||||
| 		d = p.last.LayerPayload() | ||||
| 	} | ||||
| 	next := p.next | ||||
| 	p.next = nil | ||||
| 	// We've just set p.next to nil, so if we see we have no data, this should be | ||||
| 	// the final call we get to decodeNextLayer if we return here. | ||||
| 	if len(d) == 0 { | ||||
| 		return | ||||
| 	} | ||||
| 	defer p.recoverDecodeError() | ||||
| 	err := next.Decode(d, p) | ||||
| 	if err != nil { | ||||
| 		p.addFinalDecodeError(err, nil) | ||||
| 	} | ||||
| } | ||||
| func (p *lazyPacket) LinkLayer() LinkLayer { | ||||
| 	for p.link == nil && p.next != nil { | ||||
| 		p.decodeNextLayer() | ||||
| 	} | ||||
| 	return p.link | ||||
| } | ||||
| func (p *lazyPacket) NetworkLayer() NetworkLayer { | ||||
| 	for p.network == nil && p.next != nil { | ||||
| 		p.decodeNextLayer() | ||||
| 	} | ||||
| 	return p.network | ||||
| } | ||||
| func (p *lazyPacket) TransportLayer() TransportLayer { | ||||
| 	for p.transport == nil && p.next != nil { | ||||
| 		p.decodeNextLayer() | ||||
| 	} | ||||
| 	return p.transport | ||||
| } | ||||
| func (p *lazyPacket) ApplicationLayer() ApplicationLayer { | ||||
| 	for p.application == nil && p.next != nil { | ||||
| 		p.decodeNextLayer() | ||||
| 	} | ||||
| 	return p.application | ||||
| } | ||||
| func (p *lazyPacket) ErrorLayer() ErrorLayer { | ||||
| 	for p.failure == nil && p.next != nil { | ||||
| 		p.decodeNextLayer() | ||||
| 	} | ||||
| 	return p.failure | ||||
| } | ||||
| func (p *lazyPacket) Layers() []Layer { | ||||
| 	for p.next != nil { | ||||
| 		p.decodeNextLayer() | ||||
| 	} | ||||
| 	return p.layers | ||||
| } | ||||
| func (p *lazyPacket) Layer(t LayerType) Layer { | ||||
| 	for _, l := range p.layers { | ||||
| 		if l.LayerType() == t { | ||||
| 			return l | ||||
| 		} | ||||
| 	} | ||||
| 	numLayers := len(p.layers) | ||||
| 	for p.next != nil { | ||||
| 		p.decodeNextLayer() | ||||
| 		for _, l := range p.layers[numLayers:] { | ||||
| 			if l.LayerType() == t { | ||||
| 				return l | ||||
| 			} | ||||
| 		} | ||||
| 		numLayers = len(p.layers) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (p *lazyPacket) LayerClass(lc LayerClass) Layer { | ||||
| 	for _, l := range p.layers { | ||||
| 		if lc.Contains(l.LayerType()) { | ||||
| 			return l | ||||
| 		} | ||||
| 	} | ||||
| 	numLayers := len(p.layers) | ||||
| 	for p.next != nil { | ||||
| 		p.decodeNextLayer() | ||||
| 		for _, l := range p.layers[numLayers:] { | ||||
| 			if lc.Contains(l.LayerType()) { | ||||
| 				return l | ||||
| 			} | ||||
| 		} | ||||
| 		numLayers = len(p.layers) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| func (p *lazyPacket) String() string { p.Layers(); return p.packetString() } | ||||
| func (p *lazyPacket) Dump() string   { p.Layers(); return p.packetDump() } | ||||
|  | ||||
| // DecodeOptions tells gopacket how to decode a packet. | ||||
| type DecodeOptions struct { | ||||
| 	// Lazy decoding decodes the minimum number of layers needed to return data | ||||
| 	// for a packet at each function call.  Be careful using this with concurrent | ||||
| 	// packet processors, as each call to packet.* could mutate the packet, and | ||||
| 	// two concurrent function calls could interact poorly. | ||||
| 	Lazy bool | ||||
| 	// NoCopy decoding doesn't copy its input buffer into storage that's owned by | ||||
| 	// the packet.  If you can guarantee that the bytes underlying the slice | ||||
| 	// passed into NewPacket aren't going to be modified, this can be faster.  If | ||||
| 	// there's any chance that those bytes WILL be changed, this will invalidate | ||||
| 	// your packets. | ||||
| 	NoCopy bool | ||||
| 	// SkipDecodeRecovery skips over panic recovery during packet decoding. | ||||
| 	// Normally, when packets decode, if a panic occurs, that panic is captured | ||||
| 	// by a recover(), and a DecodeFailure layer is added to the packet detailing | ||||
| 	// the issue.  If this flag is set, panics are instead allowed to continue up | ||||
| 	// the stack. | ||||
| 	SkipDecodeRecovery bool | ||||
| 	// DecodeStreamsAsDatagrams enables routing of application-level layers in the TCP | ||||
| 	// decoder. If true, we should try to decode layers after TCP in single packets. | ||||
| 	// This is disabled by default because the reassembly package drives the decoding | ||||
| 	// of TCP payload data after reassembly. | ||||
| 	DecodeStreamsAsDatagrams bool | ||||
| } | ||||
|  | ||||
| // Default decoding provides the safest (but slowest) method for decoding | ||||
| // packets.  It eagerly processes all layers (so it's concurrency-safe) and it | ||||
| // copies its input buffer upon creation of the packet (so the packet remains | ||||
| // valid if the underlying slice is modified.  Both of these take time, | ||||
| // though, so beware.  If you can guarantee that the packet will only be used | ||||
| // by one goroutine at a time, set Lazy decoding.  If you can guarantee that | ||||
| // the underlying slice won't change, set NoCopy decoding. | ||||
| var Default = DecodeOptions{} | ||||
|  | ||||
| // Lazy is a DecodeOptions with just Lazy set. | ||||
| var Lazy = DecodeOptions{Lazy: true} | ||||
|  | ||||
| // NoCopy is a DecodeOptions with just NoCopy set. | ||||
| var NoCopy = DecodeOptions{NoCopy: true} | ||||
|  | ||||
| // DecodeStreamsAsDatagrams is a DecodeOptions with just DecodeStreamsAsDatagrams set. | ||||
| var DecodeStreamsAsDatagrams = DecodeOptions{DecodeStreamsAsDatagrams: true} | ||||
|  | ||||
| // NewPacket creates a new Packet object from a set of bytes.  The | ||||
| // firstLayerDecoder tells it how to interpret the first layer from the bytes, | ||||
| // future layers will be generated from that first layer automatically. | ||||
| func NewPacket(data []byte, firstLayerDecoder Decoder, options DecodeOptions) Packet { | ||||
| 	if !options.NoCopy { | ||||
| 		dataCopy := make([]byte, len(data)) | ||||
| 		copy(dataCopy, data) | ||||
| 		data = dataCopy | ||||
| 	} | ||||
| 	if options.Lazy { | ||||
| 		p := &lazyPacket{ | ||||
| 			packet: packet{data: data, decodeOptions: options}, | ||||
| 			next:   firstLayerDecoder, | ||||
| 		} | ||||
| 		p.layers = p.initialLayers[:0] | ||||
| 		// Crazy craziness: | ||||
| 		// If the following return statemet is REMOVED, and Lazy is FALSE, then | ||||
| 		// eager packet processing becomes 17% FASTER.  No, there is no logical | ||||
| 		// explanation for this.  However, it's such a hacky micro-optimization that | ||||
| 		// we really can't rely on it.  It appears to have to do with the size the | ||||
| 		// compiler guesses for this function's stack space, since one symptom is | ||||
| 		// that with the return statement in place, we more than double calls to | ||||
| 		// runtime.morestack/runtime.lessstack.  We'll hope the compiler gets better | ||||
| 		// over time and we get this optimization for free.  Until then, we'll have | ||||
| 		// to live with slower packet processing. | ||||
| 		return p | ||||
| 	} | ||||
| 	p := &eagerPacket{ | ||||
| 		packet: packet{data: data, decodeOptions: options}, | ||||
| 	} | ||||
| 	p.layers = p.initialLayers[:0] | ||||
| 	p.initialDecode(firstLayerDecoder) | ||||
| 	return p | ||||
| } | ||||
|  | ||||
| // PacketDataSource is an interface for some source of packet data.  Users may | ||||
| // create their own implementations, or use the existing implementations in | ||||
| // gopacket/pcap (libpcap, allows reading from live interfaces or from | ||||
| // pcap files) or gopacket/pfring (PF_RING, allows reading from live | ||||
| // interfaces). | ||||
| type PacketDataSource interface { | ||||
| 	// ReadPacketData returns the next packet available from this data source. | ||||
| 	// It returns: | ||||
| 	//  data:  The bytes of an individual packet. | ||||
| 	//  ci:  Metadata about the capture | ||||
| 	//  err:  An error encountered while reading packet data.  If err != nil, | ||||
| 	//    then data/ci will be ignored. | ||||
| 	ReadPacketData() (data []byte, ci CaptureInfo, err error) | ||||
| } | ||||
|  | ||||
| // ConcatFinitePacketDataSources returns a PacketDataSource that wraps a set | ||||
| // of internal PacketDataSources, each of which will stop with io.EOF after | ||||
| // reading a finite number of packets.  The returned PacketDataSource will | ||||
| // return all packets from the first finite source, followed by all packets from | ||||
| // the second, etc.  Once all finite sources have returned io.EOF, the returned | ||||
| // source will as well. | ||||
| func ConcatFinitePacketDataSources(pds ...PacketDataSource) PacketDataSource { | ||||
| 	c := concat(pds) | ||||
| 	return &c | ||||
| } | ||||
|  | ||||
| type concat []PacketDataSource | ||||
|  | ||||
| func (c *concat) ReadPacketData() (data []byte, ci CaptureInfo, err error) { | ||||
| 	for len(*c) > 0 { | ||||
| 		data, ci, err = (*c)[0].ReadPacketData() | ||||
| 		if err == io.EOF { | ||||
| 			*c = (*c)[1:] | ||||
| 			continue | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 	return nil, CaptureInfo{}, io.EOF | ||||
| } | ||||
|  | ||||
| // ZeroCopyPacketDataSource is an interface to pull packet data from sources | ||||
| // that allow data to be returned without copying to a user-controlled buffer. | ||||
| // It's very similar to PacketDataSource, except that the caller must be more | ||||
| // careful in how the returned buffer is handled. | ||||
| type ZeroCopyPacketDataSource interface { | ||||
| 	// ZeroCopyReadPacketData returns the next packet available from this data source. | ||||
| 	// It returns: | ||||
| 	//  data:  The bytes of an individual packet.  Unlike with | ||||
| 	//    PacketDataSource's ReadPacketData, the slice returned here points | ||||
| 	//    to a buffer owned by the data source.  In particular, the bytes in | ||||
| 	//    this buffer may be changed by future calls to | ||||
| 	//    ZeroCopyReadPacketData.  Do not use the returned buffer after | ||||
| 	//    subsequent ZeroCopyReadPacketData calls. | ||||
| 	//  ci:  Metadata about the capture | ||||
| 	//  err:  An error encountered while reading packet data.  If err != nil, | ||||
| 	//    then data/ci will be ignored. | ||||
| 	ZeroCopyReadPacketData() (data []byte, ci CaptureInfo, err error) | ||||
| } | ||||
|  | ||||
| // PacketSource reads in packets from a PacketDataSource, decodes them, and | ||||
| // returns them. | ||||
| // | ||||
| // There are currently two different methods for reading packets in through | ||||
| // a PacketSource: | ||||
| // | ||||
| // Reading With Packets Function | ||||
| // | ||||
| // This method is the most convenient and easiest to code, but lacks | ||||
| // flexibility.  Packets returns a 'chan Packet', then asynchronously writes | ||||
| // packets into that channel.  Packets uses a blocking channel, and closes | ||||
| // it if an io.EOF is returned by the underlying PacketDataSource.  All other | ||||
| // PacketDataSource errors are ignored and discarded. | ||||
| //  for packet := range packetSource.Packets() { | ||||
| //    ... | ||||
| //  } | ||||
| // | ||||
| // Reading With NextPacket Function | ||||
| // | ||||
| // This method is the most flexible, and exposes errors that may be | ||||
| // encountered by the underlying PacketDataSource.  It's also the fastest | ||||
| // in a tight loop, since it doesn't have the overhead of a channel | ||||
| // read/write.  However, it requires the user to handle errors, most | ||||
| // importantly the io.EOF error in cases where packets are being read from | ||||
| // a file. | ||||
| //  for { | ||||
| //    packet, err := packetSource.NextPacket() | ||||
| //    if err == io.EOF { | ||||
| //      break | ||||
| //    } else if err != nil { | ||||
| //      log.Println("Error:", err) | ||||
| //      continue | ||||
| //    } | ||||
| //    handlePacket(packet)  // Do something with each packet. | ||||
| //  } | ||||
| type PacketSource struct { | ||||
| 	source  PacketDataSource | ||||
| 	decoder Decoder | ||||
| 	// DecodeOptions is the set of options to use for decoding each piece | ||||
| 	// of packet data.  This can/should be changed by the user to reflect the | ||||
| 	// way packets should be decoded. | ||||
| 	DecodeOptions | ||||
| 	c chan Packet | ||||
| } | ||||
|  | ||||
| // NewPacketSource creates a packet data source. | ||||
| func NewPacketSource(source PacketDataSource, decoder Decoder) *PacketSource { | ||||
| 	return &PacketSource{ | ||||
| 		source:  source, | ||||
| 		decoder: decoder, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // NextPacket returns the next decoded packet from the PacketSource.  On error, | ||||
| // it returns a nil packet and a non-nil error. | ||||
| func (p *PacketSource) NextPacket() (Packet, error) { | ||||
| 	data, ci, err := p.source.ReadPacketData() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	packet := NewPacket(data, p.decoder, p.DecodeOptions) | ||||
| 	m := packet.Metadata() | ||||
| 	m.CaptureInfo = ci | ||||
| 	m.Truncated = m.Truncated || ci.CaptureLength < ci.Length | ||||
| 	return packet, nil | ||||
| } | ||||
|  | ||||
| // packetsToChannel reads in all packets from the packet source and sends them | ||||
| // to the given channel. This routine terminates when a non-temporary error | ||||
| // is returned by NextPacket(). | ||||
| func (p *PacketSource) packetsToChannel() { | ||||
| 	defer close(p.c) | ||||
| 	for { | ||||
| 		packet, err := p.NextPacket() | ||||
| 		if err == nil { | ||||
| 			p.c <- packet | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// Immediately retry for temporary network errors | ||||
| 		if nerr, ok := err.(net.Error); ok && nerr.Temporary() { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// Immediately retry for EAGAIN | ||||
| 		if err == syscall.EAGAIN { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// Immediately break for known unrecoverable errors | ||||
| 		if err == io.EOF || err == io.ErrUnexpectedEOF || | ||||
| 			err == io.ErrNoProgress || err == io.ErrClosedPipe || err == io.ErrShortBuffer || | ||||
| 			err == syscall.EBADF || | ||||
| 			strings.Contains(err.Error(), "use of closed file") { | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		// Sleep briefly and try again | ||||
| 		time.Sleep(time.Millisecond * time.Duration(5)) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Packets returns a channel of packets, allowing easy iterating over | ||||
| // packets.  Packets will be asynchronously read in from the underlying | ||||
| // PacketDataSource and written to the returned channel.  If the underlying | ||||
| // PacketDataSource returns an io.EOF error, the channel will be closed. | ||||
| // If any other error is encountered, it is ignored. | ||||
| // | ||||
| //  for packet := range packetSource.Packets() { | ||||
| //    handlePacket(packet)  // Do something with each packet. | ||||
| //  } | ||||
| // | ||||
| // If called more than once, returns the same channel. | ||||
| func (p *PacketSource) Packets() chan Packet { | ||||
| 	if p.c == nil { | ||||
| 		p.c = make(chan Packet, 1000) | ||||
| 		go p.packetsToChannel() | ||||
| 	} | ||||
| 	return p.c | ||||
| } | ||||
							
								
								
									
										350
									
								
								vendor/github.com/google/gopacket/parser.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										350
									
								
								vendor/github.com/google/gopacket/parser.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,350 @@ | ||||
| // 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" | ||||
| ) | ||||
|  | ||||
| // A container for single LayerType->DecodingLayer mapping. | ||||
| type decodingLayerElem struct { | ||||
| 	typ LayerType | ||||
| 	dec DecodingLayer | ||||
| } | ||||
|  | ||||
| // DecodingLayer is an interface for packet layers that can decode themselves. | ||||
| // | ||||
| // The important part of DecodingLayer is that they decode themselves in-place. | ||||
| // Calling DecodeFromBytes on a DecodingLayer totally resets the entire layer to | ||||
| // the new state defined by the data passed in.  A returned error leaves the | ||||
| // DecodingLayer in an unknown intermediate state, thus its fields should not be | ||||
| // trusted. | ||||
| // | ||||
| // Because the DecodingLayer is resetting its own fields, a call to | ||||
| // DecodeFromBytes should normally not require any memory allocation. | ||||
| type DecodingLayer interface { | ||||
| 	// DecodeFromBytes resets the internal state of this layer to the state | ||||
| 	// defined by the passed-in bytes.  Slices in the DecodingLayer may | ||||
| 	// reference the passed-in data, so care should be taken to copy it | ||||
| 	// first should later modification of data be required before the | ||||
| 	// DecodingLayer is discarded. | ||||
| 	DecodeFromBytes(data []byte, df DecodeFeedback) error | ||||
| 	// CanDecode returns the set of LayerTypes this DecodingLayer can | ||||
| 	// decode.  For Layers that are also DecodingLayers, this will most | ||||
| 	// often be that Layer's LayerType(). | ||||
| 	CanDecode() LayerClass | ||||
| 	// NextLayerType returns the LayerType which should be used to decode | ||||
| 	// the LayerPayload. | ||||
| 	NextLayerType() LayerType | ||||
| 	// LayerPayload is the set of bytes remaining to decode after a call to | ||||
| 	// DecodeFromBytes. | ||||
| 	LayerPayload() []byte | ||||
| } | ||||
|  | ||||
| // DecodingLayerFunc decodes given packet and stores decoded LayerType | ||||
| // values into specified slice. Returns either first encountered | ||||
| // unsupported LayerType value or decoding error. In case of success, | ||||
| // returns (LayerTypeZero, nil). | ||||
| type DecodingLayerFunc func([]byte, *[]LayerType) (LayerType, error) | ||||
|  | ||||
| // DecodingLayerContainer stores all DecodingLayer-s and serves as a | ||||
| // searching tool for DecodingLayerParser. | ||||
| type DecodingLayerContainer interface { | ||||
| 	// Put adds new DecodingLayer to container. The new instance of | ||||
| 	// the same DecodingLayerContainer is returned so it may be | ||||
| 	// implemented as a value receiver. | ||||
| 	Put(DecodingLayer) DecodingLayerContainer | ||||
| 	// Decoder returns DecodingLayer to decode given LayerType and | ||||
| 	// true if it was found. If no decoder found, return false. | ||||
| 	Decoder(LayerType) (DecodingLayer, bool) | ||||
| 	// LayersDecoder returns DecodingLayerFunc which decodes given | ||||
| 	// packet, starting with specified LayerType and DecodeFeedback. | ||||
| 	LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc | ||||
| } | ||||
|  | ||||
| // DecodingLayerSparse is a sparse array-based implementation of | ||||
| // DecodingLayerContainer. Each DecodingLayer is addressed in an | ||||
| // allocated slice by LayerType value itself. Though this is the | ||||
| // fastest container it may be memory-consuming if used with big | ||||
| // LayerType values. | ||||
| type DecodingLayerSparse []DecodingLayer | ||||
|  | ||||
| // Put implements DecodingLayerContainer interface. | ||||
| func (dl DecodingLayerSparse) Put(d DecodingLayer) DecodingLayerContainer { | ||||
| 	maxLayerType := LayerType(len(dl) - 1) | ||||
| 	for _, typ := range d.CanDecode().LayerTypes() { | ||||
| 		if typ > maxLayerType { | ||||
| 			maxLayerType = typ | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if extra := maxLayerType - LayerType(len(dl)) + 1; extra > 0 { | ||||
| 		dl = append(dl, make([]DecodingLayer, extra)...) | ||||
| 	} | ||||
|  | ||||
| 	for _, typ := range d.CanDecode().LayerTypes() { | ||||
| 		dl[typ] = d | ||||
| 	} | ||||
| 	return dl | ||||
| } | ||||
|  | ||||
| // LayersDecoder implements DecodingLayerContainer interface. | ||||
| func (dl DecodingLayerSparse) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc { | ||||
| 	return LayersDecoder(dl, first, df) | ||||
| } | ||||
|  | ||||
| // Decoder implements DecodingLayerContainer interface. | ||||
| func (dl DecodingLayerSparse) Decoder(typ LayerType) (DecodingLayer, bool) { | ||||
| 	if int64(typ) < int64(len(dl)) { | ||||
| 		decoder := dl[typ] | ||||
| 		return decoder, decoder != nil | ||||
| 	} | ||||
| 	return nil, false | ||||
| } | ||||
|  | ||||
| // DecodingLayerArray is an array-based implementation of | ||||
| // DecodingLayerContainer. Each DecodingLayer is searched linearly in | ||||
| // an allocated slice in one-by-one fashion. | ||||
| type DecodingLayerArray []decodingLayerElem | ||||
|  | ||||
| // Put implements DecodingLayerContainer interface. | ||||
| func (dl DecodingLayerArray) Put(d DecodingLayer) DecodingLayerContainer { | ||||
| TYPES: | ||||
| 	for _, typ := range d.CanDecode().LayerTypes() { | ||||
| 		for i := range dl { | ||||
| 			if dl[i].typ == typ { | ||||
| 				dl[i].dec = d | ||||
| 				continue TYPES | ||||
| 			} | ||||
| 		} | ||||
| 		dl = append(dl, decodingLayerElem{typ, d}) | ||||
| 	} | ||||
| 	return dl | ||||
| } | ||||
|  | ||||
| // Decoder implements DecodingLayerContainer interface. | ||||
| func (dl DecodingLayerArray) Decoder(typ LayerType) (DecodingLayer, bool) { | ||||
| 	for i := range dl { | ||||
| 		if dl[i].typ == typ { | ||||
| 			return dl[i].dec, true | ||||
| 		} | ||||
| 	} | ||||
| 	return nil, false | ||||
| } | ||||
|  | ||||
| // LayersDecoder implements DecodingLayerContainer interface. | ||||
| func (dl DecodingLayerArray) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc { | ||||
| 	return LayersDecoder(dl, first, df) | ||||
| } | ||||
|  | ||||
| // DecodingLayerMap is an map-based implementation of | ||||
| // DecodingLayerContainer. Each DecodingLayer is searched in a map | ||||
| // hashed by LayerType value. | ||||
| type DecodingLayerMap map[LayerType]DecodingLayer | ||||
|  | ||||
| // Put implements DecodingLayerContainer interface. | ||||
| func (dl DecodingLayerMap) Put(d DecodingLayer) DecodingLayerContainer { | ||||
| 	for _, typ := range d.CanDecode().LayerTypes() { | ||||
| 		if dl == nil { | ||||
| 			dl = make(map[LayerType]DecodingLayer) | ||||
| 		} | ||||
| 		dl[typ] = d | ||||
| 	} | ||||
| 	return dl | ||||
| } | ||||
|  | ||||
| // Decoder implements DecodingLayerContainer interface. | ||||
| func (dl DecodingLayerMap) Decoder(typ LayerType) (DecodingLayer, bool) { | ||||
| 	d, ok := dl[typ] | ||||
| 	return d, ok | ||||
| } | ||||
|  | ||||
| // LayersDecoder implements DecodingLayerContainer interface. | ||||
| func (dl DecodingLayerMap) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc { | ||||
| 	return LayersDecoder(dl, first, df) | ||||
| } | ||||
|  | ||||
| // Static code check. | ||||
| var ( | ||||
| 	_ = []DecodingLayerContainer{ | ||||
| 		DecodingLayerSparse(nil), | ||||
| 		DecodingLayerMap(nil), | ||||
| 		DecodingLayerArray(nil), | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // DecodingLayerParser parses a given set of layer types.  See DecodeLayers for | ||||
| // more information on how DecodingLayerParser should be used. | ||||
| type DecodingLayerParser struct { | ||||
| 	// DecodingLayerParserOptions is the set of options available to the | ||||
| 	// user to define the parser's behavior. | ||||
| 	DecodingLayerParserOptions | ||||
| 	dlc   DecodingLayerContainer | ||||
| 	first LayerType | ||||
| 	df    DecodeFeedback | ||||
|  | ||||
| 	decodeFunc DecodingLayerFunc | ||||
|  | ||||
| 	// Truncated is set when a decode layer detects that the packet has been | ||||
| 	// truncated. | ||||
| 	Truncated bool | ||||
| } | ||||
|  | ||||
| // AddDecodingLayer adds a decoding layer to the parser.  This adds support for | ||||
| // the decoding layer's CanDecode layers to the parser... should they be | ||||
| // encountered, they'll be parsed. | ||||
| func (l *DecodingLayerParser) AddDecodingLayer(d DecodingLayer) { | ||||
| 	l.SetDecodingLayerContainer(l.dlc.Put(d)) | ||||
| } | ||||
|  | ||||
| // SetTruncated is used by DecodingLayers to set the Truncated boolean in the | ||||
| // DecodingLayerParser.  Users should simply read Truncated after calling | ||||
| // DecodeLayers. | ||||
| func (l *DecodingLayerParser) SetTruncated() { | ||||
| 	l.Truncated = true | ||||
| } | ||||
|  | ||||
| // NewDecodingLayerParser creates a new DecodingLayerParser and adds in all | ||||
| // of the given DecodingLayers with AddDecodingLayer. | ||||
| // | ||||
| // Each call to DecodeLayers will attempt to decode the given bytes first by | ||||
| // treating them as a 'first'-type layer, then by using NextLayerType on | ||||
| // subsequently decoded layers to find the next relevant decoder.  Should a | ||||
| // deoder not be available for the layer type returned by NextLayerType, | ||||
| // decoding will stop. | ||||
| // | ||||
| // NewDecodingLayerParser uses DecodingLayerMap container by | ||||
| // default. | ||||
| func NewDecodingLayerParser(first LayerType, decoders ...DecodingLayer) *DecodingLayerParser { | ||||
| 	dlp := &DecodingLayerParser{first: first} | ||||
| 	dlp.df = dlp // Cast this once to the interface | ||||
| 	// default container | ||||
| 	dlc := DecodingLayerContainer(DecodingLayerMap(make(map[LayerType]DecodingLayer))) | ||||
| 	for _, d := range decoders { | ||||
| 		dlc = dlc.Put(d) | ||||
| 	} | ||||
|  | ||||
| 	dlp.SetDecodingLayerContainer(dlc) | ||||
| 	return dlp | ||||
| } | ||||
|  | ||||
| // SetDecodingLayerContainer specifies container with decoders. This | ||||
| // call replaces all decoders already registered in given instance of | ||||
| // DecodingLayerParser. | ||||
| func (l *DecodingLayerParser) SetDecodingLayerContainer(dlc DecodingLayerContainer) { | ||||
| 	l.dlc = dlc | ||||
| 	l.decodeFunc = l.dlc.LayersDecoder(l.first, l.df) | ||||
| } | ||||
|  | ||||
| // DecodeLayers decodes as many layers as possible from the given data.  It | ||||
| // initially treats the data as layer type 'typ', then uses NextLayerType on | ||||
| // each subsequent decoded layer until it gets to a layer type it doesn't know | ||||
| // how to parse. | ||||
| // | ||||
| // For each layer successfully decoded, DecodeLayers appends the layer type to | ||||
| // the decoded slice.  DecodeLayers truncates the 'decoded' slice initially, so | ||||
| // there's no need to empty it yourself. | ||||
| // | ||||
| // This decoding method is about an order of magnitude faster than packet | ||||
| // decoding, because it only decodes known layers that have already been | ||||
| // allocated.  This means it doesn't need to allocate each layer it returns... | ||||
| // instead it overwrites the layers that already exist. | ||||
| // | ||||
| // Example usage: | ||||
| //    func main() { | ||||
| //      var eth layers.Ethernet | ||||
| //      var ip4 layers.IPv4 | ||||
| //      var ip6 layers.IPv6 | ||||
| //      var tcp layers.TCP | ||||
| //      var udp layers.UDP | ||||
| //      var payload gopacket.Payload | ||||
| //      parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &ip4, &ip6, &tcp, &udp, &payload) | ||||
| //      var source gopacket.PacketDataSource = getMyDataSource() | ||||
| //      decodedLayers := make([]gopacket.LayerType, 0, 10) | ||||
| //      for { | ||||
| //        data, _, err := source.ReadPacketData() | ||||
| //        if err != nil { | ||||
| //          fmt.Println("Error reading packet data: ", err) | ||||
| //          continue | ||||
| //        } | ||||
| //        fmt.Println("Decoding packet") | ||||
| //        err = parser.DecodeLayers(data, &decodedLayers) | ||||
| //        for _, typ := range decodedLayers { | ||||
| //          fmt.Println("  Successfully decoded layer type", typ) | ||||
| //          switch typ { | ||||
| //            case layers.LayerTypeEthernet: | ||||
| //              fmt.Println("    Eth ", eth.SrcMAC, eth.DstMAC) | ||||
| //            case layers.LayerTypeIPv4: | ||||
| //              fmt.Println("    IP4 ", ip4.SrcIP, ip4.DstIP) | ||||
| //            case layers.LayerTypeIPv6: | ||||
| //              fmt.Println("    IP6 ", ip6.SrcIP, ip6.DstIP) | ||||
| //            case layers.LayerTypeTCP: | ||||
| //              fmt.Println("    TCP ", tcp.SrcPort, tcp.DstPort) | ||||
| //            case layers.LayerTypeUDP: | ||||
| //              fmt.Println("    UDP ", udp.SrcPort, udp.DstPort) | ||||
| //          } | ||||
| //        } | ||||
| //        if decodedLayers.Truncated { | ||||
| //          fmt.Println("  Packet has been truncated") | ||||
| //        } | ||||
| //        if err != nil { | ||||
| //          fmt.Println("  Error encountered:", err) | ||||
| //        } | ||||
| //      } | ||||
| //    } | ||||
| // | ||||
| // If DecodeLayers is unable to decode the next layer type, it will return the | ||||
| // error UnsupportedLayerType. | ||||
| func (l *DecodingLayerParser) DecodeLayers(data []byte, decoded *[]LayerType) (err error) { | ||||
| 	l.Truncated = false | ||||
| 	if !l.IgnorePanic { | ||||
| 		defer panicToError(&err) | ||||
| 	} | ||||
| 	typ, err := l.decodeFunc(data, decoded) | ||||
| 	if typ != LayerTypeZero { | ||||
| 		// no decoder | ||||
| 		if l.IgnoreUnsupported { | ||||
| 			return nil | ||||
| 		} | ||||
| 		return UnsupportedLayerType(typ) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // UnsupportedLayerType is returned by DecodingLayerParser if DecodeLayers | ||||
| // encounters a layer type that the DecodingLayerParser has no decoder for. | ||||
| type UnsupportedLayerType LayerType | ||||
|  | ||||
| // Error implements the error interface, returning a string to say that the | ||||
| // given layer type is unsupported. | ||||
| func (e UnsupportedLayerType) Error() string { | ||||
| 	return fmt.Sprintf("No decoder for layer type %v", LayerType(e)) | ||||
| } | ||||
|  | ||||
| func panicToError(e *error) { | ||||
| 	if r := recover(); r != nil { | ||||
| 		*e = fmt.Errorf("panic: %v", r) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // DecodingLayerParserOptions provides options to affect the behavior of a given | ||||
| // DecodingLayerParser. | ||||
| type DecodingLayerParserOptions struct { | ||||
| 	// IgnorePanic determines whether a DecodingLayerParser should stop | ||||
| 	// panics on its own (by returning them as an error from DecodeLayers) | ||||
| 	// or should allow them to raise up the stack.  Handling errors does add | ||||
| 	// latency to the process of decoding layers, but is much safer for | ||||
| 	// callers.  IgnorePanic defaults to false, thus if the caller does | ||||
| 	// nothing decode panics will be returned as errors. | ||||
| 	IgnorePanic bool | ||||
| 	// IgnoreUnsupported will stop parsing and return a nil error when it | ||||
| 	// encounters a layer it doesn't have a parser for, instead of returning an | ||||
| 	// UnsupportedLayerType error.  If this is true, it's up to the caller to make | ||||
| 	// sure that all expected layers have been parsed (by checking the decoded | ||||
| 	// slice). | ||||
| 	IgnoreUnsupported bool | ||||
| } | ||||
							
								
								
									
										74
									
								
								vendor/github.com/google/gopacket/pcap/defs_windows_386.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								vendor/github.com/google/gopacket/pcap/defs_windows_386.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| // 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. | ||||
|  | ||||
| // This file contains necessary structs/constants generated from libpcap headers with cgo -godefs | ||||
| // generated with: generate_defs.exe | ||||
| // DO NOT MODIFY | ||||
|  | ||||
| package pcap | ||||
|  | ||||
| import "syscall" | ||||
|  | ||||
| const errorBufferSize = 0x100 | ||||
|  | ||||
| const ( | ||||
| 	pcapErrorNotActivated    = -0x3 | ||||
| 	pcapErrorActivated       = -0x4 | ||||
| 	pcapWarningPromisc       = 0x2 | ||||
| 	pcapErrorNoSuchDevice    = -0x5 | ||||
| 	pcapErrorDenied          = -0x8 | ||||
| 	pcapErrorNotUp           = -0x9 | ||||
| 	pcapError                = -0x1 | ||||
| 	pcapWarning              = 0x1 | ||||
| 	pcapDIN                  = 0x1 | ||||
| 	pcapDOUT                 = 0x2 | ||||
| 	pcapDINOUT               = 0x0 | ||||
| 	pcapNetmaskUnknown       = 0xffffffff | ||||
| 	pcapTstampPrecisionMicro = 0x0 | ||||
| 	pcapTstampPrecisionNano  = 0x1 | ||||
| ) | ||||
|  | ||||
| type timeval struct { | ||||
| 	Sec  int32 | ||||
| 	Usec int32 | ||||
| } | ||||
| type pcapPkthdr struct { | ||||
| 	Ts     timeval | ||||
| 	Caplen uint32 | ||||
| 	Len    uint32 | ||||
| } | ||||
| type pcapTPtr uintptr | ||||
| type pcapBpfInstruction struct { | ||||
| 	Code uint16 | ||||
| 	Jt   uint8 | ||||
| 	Jf   uint8 | ||||
| 	K    uint32 | ||||
| } | ||||
| type pcapBpfProgram struct { | ||||
| 	Len   uint32 | ||||
| 	Insns *pcapBpfInstruction | ||||
| } | ||||
| type pcapStats struct { | ||||
| 	Recv   uint32 | ||||
| 	Drop   uint32 | ||||
| 	Ifdrop uint32 | ||||
| } | ||||
| type pcapCint int32 | ||||
| type pcapIf struct { | ||||
| 	Next        *pcapIf | ||||
| 	Name        *int8 | ||||
| 	Description *int8 | ||||
| 	Addresses   *pcapAddr | ||||
| 	Flags       uint32 | ||||
| } | ||||
|  | ||||
| type pcapAddr struct { | ||||
| 	Next      *pcapAddr | ||||
| 	Addr      *syscall.RawSockaddr | ||||
| 	Netmask   *syscall.RawSockaddr | ||||
| 	Broadaddr *syscall.RawSockaddr | ||||
| 	Dstaddr   *syscall.RawSockaddr | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user